• 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_event_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_on_child_touch_test_function.h"
47 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
48 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
49 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
50 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
51 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
52 #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h"
53 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
54 #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h"
55 #include "bridge/declarative_frontend/engine/functions/js_touch_test_done_function.h"
56 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
57 #include "bridge/declarative_frontend/engine/js_types.h"
58 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h"
59 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
60 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
61 #include "bridge/declarative_frontend/engine/js_converter.h"
62 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
63 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
64 #include "bridge/declarative_frontend/jsview/js_utils.h"
65 #include "bridge/declarative_frontend/jsview/js_view_context.h"
66 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
67 #include "bridge/declarative_frontend/jsview/js_layoutable_view.h"
68 #include "core/event/focus_axis_event.h"
69 #include "canvas_napi/js_canvas.h"
70 #ifdef SUPPORT_DIGITAL_CROWN
71 #include "bridge/declarative_frontend/engine/functions/js_crown_function.h"
72 #endif
73 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
74 #include "core/components/text_overlay/text_overlay_theme.h"
75 #include "core/components/theme/shadow_theme.h"
76 #ifdef PLUGIN_COMPONENT_SUPPORTED
77 #include "core/common/plugin_manager.h"
78 #endif
79 #include "interfaces/native/node/resource.h"
80 
81 #include "core/common/card_scope.h"
82 #include "core/common/resource/resource_manager.h"
83 #include "core/common/resource/resource_wrapper.h"
84 #include "core/common/resource/resource_parse_utils.h"
85 #include "core/common/resource/resource_configuration.h"
86 #include "core/components_ng/base/view_abstract_model_ng.h"
87 #include "core/components_ng/base/view_stack_model.h"
88 #include "core/components_ng/base/inspector.h"
89 #include "core/components_ng/pattern/toolbaritem/toolbaritem_model.h"
90 #include "core/event/key_event.h"
91 
92 #include "interfaces/inner_api/ace_kit/include/ui/properties/safe_area_insets.h"
93 
94 namespace OHOS::Ace::NG {
95 constexpr uint32_t DEFAULT_GRID_SPAN = 1;
96 constexpr int32_t DEFAULT_GRID_OFFSET = 0;
97 }
98 
99 namespace OHOS::Ace {
100 namespace {
101 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
102 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
103 constexpr int32_t DIRECTION_COUNT = 4;
104 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
105 constexpr int NUM1 = 1;
106 constexpr int NUM2 = 2;
107 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
108     HoverModeAreaType::BOTTOM_SCREEN };
109 const std::string CUSTOM_SYMBOL_SUFFIX = "_CustomSymbol";
110 } // namespace
111 
GetInstance()112 ViewAbstractModel* ViewAbstractModel::GetInstance()
113 {
114 #ifdef NG_BUILD
115     static NG::ViewAbstractModelNG instance;
116     return &instance;
117 #else
118     if (Container::IsCurrentUseNewPipeline()) {
119         static NG::ViewAbstractModelNG instance;
120         return &instance;
121     } else {
122         static Framework::ViewAbstractModelImpl instance;
123         return &instance;
124     }
125 #endif
126 }
127 } // namespace OHOS::Ace
128 
129 namespace OHOS::Ace::Framework {
130 namespace {
131 
132 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
133 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
134 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
135 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
136 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
137 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
138 constexpr uint32_t LAYOUT_SAFE_AREA_TYPE_LIMIT = 2;
139 constexpr uint32_t LAYOUT_SAFE_AREA_EDGE_LIMIT = 6;
140 constexpr int32_t MAX_ALIGN_VALUE = 8;
141 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
142 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
143 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
144 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
145 constexpr double FULL_DIMENSION = 100.0;
146 constexpr double HALF_DIMENSION = 50.0;
147 constexpr double ROUND_UNIT = 360.0;
148 constexpr double VISIBLE_RATIO_MIN = 0.0;
149 constexpr double VISIBLE_RATIO_MAX = 1.0;
150 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
151 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
152 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
153 constexpr int32_t SECOND_INDEX = 2;
154 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
155 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
156 constexpr float MAX_ANGLE = 360.0f;
157 constexpr float DEFAULT_BIAS = 0.5f;
158 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
159 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
160 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
161 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
162 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
163 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
164 const std::vector<int32_t> LENGTH_METRICS_KEYS {
165     static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
166     static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
167 const char* START_PROPERTY = "start";
168 const char* END_PROPERTY = "end";
169 const char* TOP_PROPERTY = "top";
170 const char* BOTTOM_PROPERTY = "bottom";
171 const char* LEFT_PROPERTY = "left";
172 const char* RIGHT_PROPERTY = "right";
173 const char* TOP_START_PROPERTY = "topStart";
174 const char* TOP_END_PROPERTY = "topEnd";
175 const char* BOTTOM_START_PROPERTY = "bottomStart";
176 const char* BOTTOM_END_PROPERTY = "bottomEnd";
177 const char* DEBUG_LINE_INFO_LINE = "$line";
178 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
179 
180 enum class MenuItemType { COPY, PASTE, CUT, SELECT_ALL, UNKNOWN, CAMERA_INPUT,
181     AI_WRITER, TRANSLATE, SHARE, SEARCH, ASK_CELIA };
182 enum class BackgroundType { CUSTOM_BUILDER, COLOR };
183 
184 const int32_t NUM_0 = 0;
185 const int32_t NUM_1 = 1;
186 const int32_t NUM_2 = 2;
187 
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)188 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
189     CalcDimension& centerX, CalcDimension& centerY)
190 {
191     double xVal = 1.0;
192     double yVal = 1.0;
193     double zVal = 1.0;
194     if (!jsValue->IsObject()) {
195         scaleX = static_cast<float>(xVal);
196         scaleY = static_cast<float>(yVal);
197         scaleZ = static_cast<float>(zVal);
198         CalcDimension length;
199         centerX = length;
200         centerY = length;
201         return;
202     }
203     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
204     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
205     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
206     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
207     scaleX = static_cast<float>(xVal);
208     scaleY = static_cast<float>(yVal);
209     scaleZ = static_cast<float>(zVal);
210     // if specify centerX
211     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
212     // if specify centerY
213     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
214 }
215 
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)216 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
217     CalcDimension& translateZ)
218 {
219     if (!jsValue->IsObject()) {
220         return;
221     }
222     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
223     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
224     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
225     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
226 }
227 
GetDefaultRotateVector(double & dx,double & dy,double & dz)228 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
229 {
230     dx = 0.0;
231     dy = 0.0;
232     dz = 0.0;
233     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
234         dz = 1.0;
235     }
236 }
237 
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)238 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
239 {
240     if (!jsValue->IsObject()) {
241         return;
242     }
243     // default: dx, dy, dz (0.0, 0.0, 0.0)
244     double dxVal = 0.0;
245     double dyVal = 0.0;
246     double dzVal = 0.0;
247     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
248     auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
249     auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
250     auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
251     if (jsRotateX->IsUndefined()
252         && jsRotateY->IsUndefined()
253         && jsRotateZ->IsUndefined()) {
254         GetDefaultRotateVector(dxVal, dyVal, dzVal);
255     } else {
256         JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
257         JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
258         JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
259     }
260     rotate.xDirection = static_cast<float>(dxVal);
261     rotate.yDirection = static_cast<float>(dyVal);
262     rotate.zDirection = static_cast<float>(dzVal);
263     // if specify centerX
264     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
265         rotate.centerX)) {
266         rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
267     }
268     // if specify centerY
269     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
270         rotate.centerY)) {
271         rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
272     }
273     // if specify centerZ
274     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
275         rotate.centerZ)) {
276         rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
277     }
278     // if specify angle
279     JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
280     rotate.perspective = 0.0f;
281     JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
282 }
283 
ParseJsRotateAngle(const JSRef<JSVal> & jsValue,NG::RotateAngleOptions & rotateAngle)284 void ParseJsRotateAngle(const JSRef<JSVal>& jsValue, NG::RotateAngleOptions& rotateAngle)
285 {
286     if (!jsValue->IsObject()) {
287         return;
288     }
289 
290     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
291 
292     std::optional<float> angleX = 0.0;
293     std::optional<float> angleY = 0.0;
294     std::optional<float> angleZ = 0.0;
295 
296     JSViewAbstract::GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE_X), jsObj, angleX, 0.0f);
297     JSViewAbstract::GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE_Y), jsObj, angleY, 0.0f);
298     JSViewAbstract::GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE_Z), jsObj, angleZ, 0.0f);
299 
300     rotateAngle.angleX = angleX.value_or(0.0f);
301     rotateAngle.angleY = angleY.value_or(0.0f);
302     rotateAngle.angleZ = angleZ.value_or(0.0f);
303 
304     // if specify centerX
305     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
306     rotateAngle.centerX)) {
307         rotateAngle.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
308     }
309     // if specify centerY
310     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
311     rotateAngle.centerY)) {
312         rotateAngle.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
313     }
314     // if specify centerZ
315     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
316     rotateAngle.centerZ)) {
317         rotateAngle.centerZ = Dimension(0.0f, DimensionUnit::VP);
318     }
319     rotateAngle.perspective = 0.0f;
320     JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotateAngle.perspective);
321 }
322 
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)323 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
324 {
325     if (!jsValue->IsObject()) {
326         return false;
327     }
328 
329     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
330     auto path = jsObj->GetPropertyValue<std::string>("path", "");
331     if (path.empty()) {
332         return false;
333     }
334     option.SetPath(path);
335     double from = 0.0;
336     double to = 1.0;
337     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
338     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
339     if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
340         from = 0.0;
341     }
342     if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
343         to = 1.0;
344     } else if (to < from) {
345         to = from;
346     }
347     option.SetBegin(static_cast<float>(from));
348     option.SetEnd(static_cast<float>(to));
349     option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
350     return true;
351 }
352 
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)353 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
354 {
355     isAuto = false;
356     switch (modeValue) {
357         case static_cast<int32_t>(NG::DragPreviewMode::AUTO):
358             previewOption.ResetDragPreviewMode();
359             isAuto = true;
360             break;
361         case static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE):
362             previewOption.isScaleEnabled = false;
363             break;
364         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW):
365             previewOption.isDefaultShadowEnabled = true;
366             break;
367         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS):
368             previewOption.isDefaultRadiusEnabled = true;
369             break;
370         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DRAG_ITEM_GRAY_EFFECT):
371             previewOption.isDefaultDragItemGrayEffectEnabled = true;
372             break;
373         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_MULTI_TILE_EFFECT):
374             previewOption.isMultiTiled = true;
375             break;
376         case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW):
377             previewOption.isTouchPointCalculationBasedOnFinalPreviewEnable = true;
378             break;
379         default:
380             break;
381     }
382 }
383 
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)384 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
385     BackgroundImagePosition& bgImgPosition)
386 {
387     AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
388     bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
389     bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
390 }
391 
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)392 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
393 {
394     auto index = pos + containCount;
395     if (index < 0) {
396         return std::string();
397     }
398 
399     JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
400     if (type == "d") {
401         if (item->IsNumber()) {
402             return std::to_string(item->ToNumber<int32_t>());
403         } else if (item->IsObject()) {
404             int32_t result = 0;
405             JSViewAbstract::ParseJsInteger(item, result);
406             return std::to_string(result);
407         }
408     } else if (type == "s") {
409         if (item->IsString()) {
410             return item->ToString();
411         } else if (item->IsObject()) {
412             std::string result;
413             JSViewAbstract::ParseJsString(item, result);
414             return result;
415         }
416     } else if (type == "f") {
417         if (item->IsNumber()) {
418             return std::to_string(item->ToNumber<float>());
419         } else if (item->IsObject()) {
420             double result = 0.0;
421             JSViewAbstract::ParseJsDouble(item, result);
422             return std::to_string(result);
423         }
424     }
425     return std::string();
426 }
427 
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)428 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
429 {
430     auto size = static_cast<int32_t>(params->Length());
431     if (containCount == size) {
432         return;
433     }
434     std::string::const_iterator start = originStr.begin();
435     std::string::const_iterator end = originStr.end();
436     std::smatch matches;
437     bool shortHolderType = false;
438     bool firstMatch = true;
439     int searchTime = 0;
440     while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
441         std::string pos = matches[2];
442         std::string type = matches[4];
443         if (firstMatch) {
444             firstMatch = false;
445             shortHolderType = pos.length() == 0;
446         } else {
447             if (shortHolderType ^ (pos.length() == 0)) {
448                 return;
449             }
450         }
451 
452         std::string replaceContentStr;
453         if (shortHolderType) {
454             replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
455         } else {
456             replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
457         }
458 
459         originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
460         start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
461         end = originStr.end();
462         searchTime++;
463     }
464 }
465 
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y,RefPtr<ResourceObject> & xresObj,RefPtr<ResourceObject> & yresObj)466 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y,
467     RefPtr<ResourceObject>& xresObj, RefPtr<ResourceObject>& yresObj)
468 {
469     JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
470     JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
471     bool hasX = false;
472     bool hasY = false;
473     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
474         hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP, xresObj);
475         hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP, yresObj);
476     } else {
477         hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP, xresObj);
478         hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP, yresObj);
479     }
480     return hasX || hasY;
481 }
482 
ParseLocationPropsEdgesResObj(EdgesParam & edges,const RefPtr<ResourceObject> & topResObj,const RefPtr<ResourceObject> & leftResObj,const RefPtr<ResourceObject> & bottomResObj,const RefPtr<ResourceObject> & rightResObj)483 void ParseLocationPropsEdgesResObj(EdgesParam& edges, const RefPtr<ResourceObject>& topResObj,
484     const RefPtr<ResourceObject>& leftResObj, const RefPtr<ResourceObject>& bottomResObj,
485     const RefPtr<ResourceObject>& rightResObj)
486 {
487     if (!SystemProperties::ConfigChangePerform()) {
488         return;
489     }
490     edges.resMap_.clear();
491     if (topResObj) {
492         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
493             CalcDimension result;
494             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
495             edges.SetTop(result);
496         };
497         edges.AddResource("edges.top", topResObj, std::move(updateFunc));
498     }
499     if (leftResObj) {
500         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
501             CalcDimension result;
502             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
503             edges.SetLeft(result);
504         };
505         edges.AddResource("edges.left", leftResObj, std::move(updateFunc));
506     }
507     if (bottomResObj) {
508         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
509             CalcDimension result;
510             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
511             edges.SetBottom(result);
512         };
513         edges.AddResource("edges.bottom", bottomResObj, std::move(updateFunc));
514     }
515     if (rightResObj) {
516         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
517             CalcDimension result;
518             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
519             edges.SetRight(result);
520         };
521         edges.AddResource("edges.right", rightResObj, std::move(updateFunc));
522     }
523 }
524 
ParseAllBorderRadiusesResObj(NG::BorderRadiusProperty & borderRadius,const RefPtr<ResourceObject> & topLeftResObj,const RefPtr<ResourceObject> & topRightResObj,const RefPtr<ResourceObject> & bottomLeftResObj,const RefPtr<ResourceObject> & bottomRightResObj)525 void ParseAllBorderRadiusesResObj(NG::BorderRadiusProperty& borderRadius, const RefPtr<ResourceObject>& topLeftResObj,
526     const RefPtr<ResourceObject>& topRightResObj, const RefPtr<ResourceObject>& bottomLeftResObj,
527     const RefPtr<ResourceObject>& bottomRightResObj)
528 {
529     if (!SystemProperties::ConfigChangePerform()) {
530         return;
531     }
532     borderRadius.resMap_.clear();
533     if (topLeftResObj) {
534         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
535             CalcDimension result;
536             ResourceParseUtils::ParseResDimensionVp(resObj, result);
537             borderRadius.radiusTopLeft = result;
538         };
539         borderRadius.AddResource("borderRadius.topLeft", topLeftResObj, std::move(updateFunc));
540     }
541     if (topRightResObj) {
542         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
543             CalcDimension result;
544             ResourceParseUtils::ParseResDimensionVp(resObj, result);
545             borderRadius.radiusTopRight = result;
546         };
547         borderRadius.AddResource("borderRadius.topRight", topRightResObj, std::move(updateFunc));
548     }
549     if (bottomLeftResObj) {
550         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
551             CalcDimension result;
552             ResourceParseUtils::ParseResDimensionVp(resObj, result);
553             borderRadius.radiusBottomLeft = result;
554         };
555         borderRadius.AddResource("borderRadius.bottomLeft", bottomLeftResObj, std::move(updateFunc));
556     }
557     if (bottomRightResObj) {
558         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
559             CalcDimension result;
560             ResourceParseUtils::ParseResDimensionVp(resObj, result);
561             borderRadius.radiusBottomRight = result;
562         };
563         borderRadius.AddResource("borderRadius.bottomRight", bottomRightResObj, std::move(updateFunc));
564     }
565 }
566 
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)567 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
568 {
569     bool useEdges = false;
570     CalcDimension top;
571     CalcDimension left;
572     CalcDimension bottom;
573     CalcDimension right;
574     RefPtr<ResourceObject> topResObj;
575     RefPtr<ResourceObject> leftResObj;
576     RefPtr<ResourceObject> bottomResObj;
577     RefPtr<ResourceObject> rightResObj;
578     JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
579     JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
580     JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
581     JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
582     if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP, topResObj)) {
583         edges.SetTop(top);
584         useEdges = true;
585     }
586     if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP, leftResObj)) {
587         edges.SetLeft(left);
588         useEdges = true;
589     }
590     if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP, bottomResObj)) {
591         edges.SetBottom(bottom);
592         useEdges = true;
593     }
594     if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP, rightResObj)) {
595         edges.SetRight(right);
596         useEdges = true;
597     }
598     ParseLocationPropsEdgesResObj(edges, topResObj, leftResObj, bottomResObj, rightResObj);
599     return useEdges;
600 }
601 
602 decltype(JSViewAbstract::ParseJsLengthMetricsVp)* ParseJsLengthMetrics = JSViewAbstract::ParseJsLengthMetricsVp;
603 
ParseJsLengthMetricsToDimension(const JSRef<JSObject> & obj,Dimension & result,RefPtr<ResourceObject> & resourceObj)604 void ParseJsLengthMetricsToDimension(const JSRef<JSObject>& obj, Dimension& result, RefPtr<ResourceObject>& resourceObj)
605 {
606     auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
607     if (!value->IsNumber()) {
608         return;
609     }
610     auto unit = DimensionUnit::VP;
611     auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
612     if (jsUnit->IsNumber()) {
613         unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
614     }
615     CalcDimension dimension(value->ToNumber<double>(), unit);
616     result = dimension;
617     auto jsRes = obj->GetProperty("res");
618     if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
619         !jsRes->IsNull() && jsRes->IsObject()) {
620         JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
621         JSViewAbstract::CompleteResourceObject(resObj);
622         resourceObj = JSViewAbstract::GetResourceObject(resObj);
623     }
624     return;
625 }
626 
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)627 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
628 {
629     bool useLocalizedEdges = false;
630     CalcDimension start;
631     CalcDimension end;
632     CalcDimension top;
633     CalcDimension bottom;
634 
635     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
636     if (startVal->IsObject()) {
637         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
638         ParseJsLengthMetrics(startObj, start);
639         edges.start = start;
640         useLocalizedEdges = true;
641     }
642     JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
643     if (endVal->IsObject()) {
644         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
645         ParseJsLengthMetrics(endObj, end);
646         edges.end = end;
647         useLocalizedEdges = true;
648     }
649     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
650     if (topVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(topVal), top)) {
651         edges.SetTop(top);
652         useLocalizedEdges = true;
653     }
654     JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
655     if (bottomVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(bottomVal), bottom)) {
656         edges.SetBottom(bottom);
657         useLocalizedEdges = true;
658     }
659     return useLocalizedEdges;
660 }
661 
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)662 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
663 {
664     bool useMarkAnchorPosition = false;
665     CalcDimension start;
666     CalcDimension top;
667 
668     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
669     if (startVal->IsObject()) {
670         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
671         ParseJsLengthMetrics(startObj, start);
672         x = start;
673         useMarkAnchorPosition = true;
674     }
675     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
676     if (topVal->IsObject()) {
677         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
678         ParseJsLengthMetrics(topObj, top);
679         y = top;
680         useMarkAnchorPosition = true;
681     }
682     return useMarkAnchorPosition;
683 }
684 
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)685 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
686 {
687     JSRef<JSVal> builder;
688     if (info->IsObject()) {
689         auto builderObj = JSRef<JSObject>::Cast(info);
690         builder = builderObj->GetProperty("builder");
691     } else if (info->IsFunction()) {
692         builder = info;
693     } else {
694         return nullptr;
695     }
696 
697     if (!builder->IsFunction()) {
698         return nullptr;
699     }
700 
701     return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
702 }
703 
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)704 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
705     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
706 {
707     RefPtr<NG::ChainedTransitionEffect> effect;
708     if (effectOption->IsObject()) {
709         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
710         std::optional<float> angle;
711         ParseJsRotate(effectOption, rotate, angle);
712         if (angle.has_value()) {
713             rotate.angle = angle.value();
714             return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
715         }
716     }
717     return nullptr;
718 }
719 
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)720 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
721     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
722 {
723     double opacity = 1.0;
724     if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
725         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
726             if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
727                 opacity = 1.0;
728             }
729         } else {
730             opacity = std::clamp(opacity, 0.0, 1.0);
731         }
732         return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
733     }
734     return nullptr;
735 }
736 
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)737 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
738     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
739 {
740     if (effectOption->IsObject()) {
741         // default: x, y, z (0.0, 0.0, 0.0)
742         NG::TranslateOptions translate;
743         ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
744         return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
745     }
746     return nullptr;
747 }
748 
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)749 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
750     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
751 {
752     if (effectOption->IsObject()) {
753         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
754         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
755         ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
756         return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
757     }
758     return nullptr;
759 }
760 
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)761 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
762     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
763 {
764     int32_t edge = 0;
765     if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
766         if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
767             edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
768             edge = static_cast<int32_t>(NG::TransitionEdge::START);
769         }
770         return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
771     }
772     return nullptr;
773 }
774 
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)775 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
776     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
777 {
778     if (effectOption->IsObject()) {
779         auto effectObj = JSRef<JSObject>::Cast(effectOption);
780         auto appearJsVal = effectObj->GetProperty("appear");
781         auto disappearJsVal = effectObj->GetProperty("disappear");
782         RefPtr<NG::ChainedTransitionEffect> appearEffect;
783         RefPtr<NG::ChainedTransitionEffect> disappearEffect;
784         if (appearJsVal->IsObject()) {
785             auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
786             appearEffect = JSViewAbstract::ParseChainedTransition(appearObj, context);
787         }
788         if (disappearJsVal->IsObject()) {
789             auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
790             disappearEffect = JSViewAbstract::ParseChainedTransition(disappearObj, context);
791         }
792         return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
793     }
794     return nullptr;
795 }
796 
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)797 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
798 {
799     CHECK_NULL_RETURN(pipelineContext, 0);
800     return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
801 }
802 
803 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
804     const JSRef<JSVal>&, const JSExecutionContext&);
805 
GetBundleNameFromContainer()806 std::string GetBundleNameFromContainer()
807 {
808     auto container = Container::Current();
809     CHECK_NULL_RETURN(container, "");
810     return container->GetBundleName();
811 }
812 
GetModuleNameFromContainer()813 std::string GetModuleNameFromContainer()
814 {
815     auto container = Container::Current();
816     CHECK_NULL_RETURN(container, "");
817     return container->GetModuleName();
818 }
819 
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)820 void CompleteResourceObjectFromParams(
821     int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
822 {
823     JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
824     int32_t typeNum = -1;
825     if (type->IsNumber()) {
826         typeNum = type->ToNumber<int32_t>();
827     }
828 
829     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
830     if (!args->IsArray()) {
831         return;
832     }
833     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
834     if (resId != UNKNOWN_RESOURCE_ID) {
835         return;
836     }
837     JSRef<JSVal> identity = params->GetValueAt(0);
838 
839     bool isParseDollarResourceSuccess =
840         JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
841     if (!isParseDollarResourceSuccess) {
842         return;
843     }
844 
845     std::regex resNameRegex(RESOURCE_NAME_PATTERN);
846     std::smatch resNameResults;
847     if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
848         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
849     }
850 
851     if (typeNum == UNKNOWN_RESOURCE_TYPE) {
852         jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
853     }
854 }
855 
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)856 void CompleteResourceObjectFromId(
857     JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
858 {
859     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
860     if (!args->IsArray()) {
861         return;
862     }
863     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
864     auto paramCount = params->Length();
865     JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
866     if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
867         std::vector<JSRef<JSVal>> tmpParams;
868         for (uint32_t i = 0; i < paramCount; i++) {
869             auto param = params->GetValueAt(i);
870             tmpParams.insert(tmpParams.end(), param);
871         }
872         params->SetValueAt(0, name);
873         uint32_t paramIndex = 1;
874         if (!type->IsEmpty()) {
875             params->SetValueAt(paramIndex, type);
876             paramIndex++;
877         }
878         for (auto tmpParam : tmpParams) {
879             params->SetValueAt(paramIndex, tmpParam);
880             paramIndex++;
881         }
882     } else {
883         params->SetValueAt(0, name);
884     }
885     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
886     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
887     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
888         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
889     }
890     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
891         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
892     }
893 }
894 
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)895 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
896 {
897     if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
898         checkDimension.Reset();
899         return;
900     }
901     if (notNegative && checkDimension.IsNegative()) {
902         checkDimension.Reset();
903         return;
904     }
905 }
906 
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)907 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
908 {
909     Color left;
910     RefPtr<ResourceObject> leftResObj;
911     if (JSViewAbstract::ParseJsColor(
912         object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left, leftResObj)) {
913         commonColor.left = left;
914     }
915     Color right;
916     RefPtr<ResourceObject> rightResObj;
917     if (JSViewAbstract::ParseJsColor(
918         object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right, rightResObj)) {
919         commonColor.right = right;
920     }
921     Color top;
922     RefPtr<ResourceObject> topResObj;
923     if (JSViewAbstract::ParseJsColor(
924         object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
925         commonColor.top = top;
926     }
927     Color bottom;
928     RefPtr<ResourceObject> bottomResObj;
929     if (JSViewAbstract::ParseJsColor(
930         object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
931         commonColor.bottom = bottom;
932     }
933     if (!SystemProperties::ConfigChangePerform()) {
934         return;
935     }
936     if (leftResObj) {
937         commonColor.leftResObj = leftResObj;
938     }
939     if (rightResObj) {
940         commonColor.rightResObj = rightResObj;
941     }
942     if (topResObj) {
943         commonColor.topResObj = topResObj;
944     }
945     if (bottomResObj) {
946         commonColor.bottomResObj = bottomResObj;
947     }
948 }
949 
ParseLocalizedEdgeStartColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)950 void ParseLocalizedEdgeStartColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
951 {
952     if (object->IsUndefined()) {
953         return;
954     }
955     RefPtr<ResourceObject> startResObj;
956     Color start;
957     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start, startResObj)) {
958         borderColors.leftColor = start;
959     }
960     if (startResObj) {
961         auto&& updateFunc = [](const RefPtr<ResourceObject>& startResObj, NG::BorderColorProperty& borderColors) {
962             Color color;
963             ResourceParseUtils::ParseResColor(startResObj, color);
964             borderColors.leftColor = color;
965         };
966         borderColors.AddResource("localizedEdgeColor.start", startResObj, std::move(updateFunc));
967     }
968 }
969 
ParseLocalizedEdgeEndColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)970 void ParseLocalizedEdgeEndColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
971 {
972     if (object->IsUndefined()) {
973         return;
974     }
975     RefPtr<ResourceObject> endResObj;
976     Color end;
977     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end, endResObj)) {
978         borderColors.rightColor = end;
979     }
980     if (endResObj) {
981         auto&& updateFunc = [](const RefPtr<ResourceObject>& endResObj, NG::BorderColorProperty& borderColors) {
982             Color color;
983             ResourceParseUtils::ParseResColor(endResObj, color);
984             borderColors.rightColor = color;
985         };
986         borderColors.AddResource("localizedEdgeColor.end", endResObj, std::move(updateFunc));
987     }
988 }
989 
ParseLocalizedEdgeTopColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)990 void ParseLocalizedEdgeTopColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
991 {
992     if (object->IsUndefined()) {
993         return;
994     }
995     RefPtr<ResourceObject> topResObj;
996     Color top;
997     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
998         borderColors.topColor = top;
999     }
1000     if (topResObj) {
1001         auto&& updateFunc = [](const RefPtr<ResourceObject>& topResObj, NG::BorderColorProperty& borderColors) {
1002             Color color;
1003             ResourceParseUtils::ParseResColor(topResObj, color);
1004             borderColors.topColor = color;
1005         };
1006         borderColors.AddResource("localizedEdgeColor.top", topResObj, std::move(updateFunc));
1007     }
1008 }
1009 
ParseLocalizedEdgeBottomColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1010 void ParseLocalizedEdgeBottomColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1011 {
1012     if (object->IsUndefined()) {
1013         return;
1014     }
1015     RefPtr<ResourceObject> bottomResObj;
1016     Color bottom;
1017     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1018         borderColors.bottomColor = bottom;
1019     }
1020     if (bottomResObj) {
1021         auto&& updateFunc = [](const RefPtr<ResourceObject>& bottomResObj, NG::BorderColorProperty& borderColors) {
1022             Color color;
1023             ResourceParseUtils::ParseResColor(bottomResObj, color);
1024             borderColors.bottomColor = color;
1025         };
1026         borderColors.AddResource("localizedEdgeColor.bottom", bottomResObj, std::move(updateFunc));
1027     }
1028 }
1029 
ParseLocalizedEdgeColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1030 void ParseLocalizedEdgeColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1031 {
1032     ParseLocalizedEdgeStartColorsForOutLineColor(object, borderColors);
1033     ParseLocalizedEdgeEndColorsForOutLineColor(object, borderColors);
1034     ParseLocalizedEdgeTopColorsForOutLineColor(object, borderColors);
1035     ParseLocalizedEdgeBottomColorsForOutLineColor(object, borderColors);
1036 }
1037 
ParseEdgeLeftColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1038 void ParseEdgeLeftColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1039 {
1040     if (object->IsUndefined()) {
1041         return;
1042     }
1043     RefPtr<ResourceObject> leftResObj;
1044     Color left;
1045     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left, leftResObj)) {
1046         borderColors.leftColor = left;
1047     }
1048     if (leftResObj) {
1049         auto&& updateFunc = [](const RefPtr<ResourceObject>& leftResObj, NG::BorderColorProperty& borderColors) {
1050             Color color;
1051             ResourceParseUtils::ParseResColor(leftResObj, color);
1052             borderColors.leftColor = color;
1053         };
1054         borderColors.AddResource("outLineColor.edgeColor.left", leftResObj, std::move(updateFunc));
1055     }
1056 }
1057 
ParseEdgeRightColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1058 void ParseEdgeRightColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1059 {
1060     if (object->IsUndefined()) {
1061         return;
1062     }
1063     RefPtr<ResourceObject> rightResObj;
1064     Color right;
1065     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right, rightResObj)) {
1066         borderColors.rightColor = right;
1067     }
1068     if (rightResObj) {
1069         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1070             Color color;
1071             ResourceParseUtils::ParseResColor(resObj, color);
1072             borderColors.rightColor = color;
1073         };
1074         borderColors.AddResource("outLineColor.edgeColor.right", rightResObj, std::move(updateFunc));
1075     }
1076 }
1077 
ParseEdgeTopColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1078 void ParseEdgeTopColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1079 {
1080     if (object->IsUndefined()) {
1081         return;
1082     }
1083     RefPtr<ResourceObject> topResObj;
1084     Color top;
1085     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
1086         borderColors.topColor = top;
1087     }
1088     if (topResObj) {
1089         auto&& updateFunc = [](const RefPtr<ResourceObject>& topResObj, NG::BorderColorProperty& borderColors) {
1090             Color color;
1091             ResourceParseUtils::ParseResColor(topResObj, color);
1092             borderColors.topColor = color;
1093         };
1094         borderColors.AddResource("outLineColor.edgeColor.top", topResObj, std::move(updateFunc));
1095     }
1096 }
1097 
ParseEdgeBottomColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1098 void ParseEdgeBottomColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1099 {
1100     if (object->IsUndefined()) {
1101         return;
1102     }
1103     RefPtr<ResourceObject> bottomResObj;
1104     Color bottom;
1105     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1106         borderColors.bottomColor = bottom;
1107     }
1108     if (bottomResObj) {
1109         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1110             Color color;
1111             ResourceParseUtils::ParseResColor(resObj, color);
1112             borderColors.bottomColor = color;
1113         };
1114         borderColors.AddResource("outLineColor.edgeColor.bottom", bottomResObj, std::move(updateFunc));
1115     }
1116 }
1117 
ParseEdgeColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1118 void ParseEdgeColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1119 {
1120     ParseEdgeLeftColorsForOutLineColor(object, borderColors);
1121     ParseEdgeRightColorsForOutLineColor(object, borderColors);
1122     ParseEdgeTopColorsForOutLineColor(object, borderColors);
1123     ParseEdgeBottomColorsForOutLineColor(object, borderColors);
1124 }
1125 
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1126 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
1127 {
1128     Color start;
1129     RefPtr<ResourceObject> startResObj;
1130     if (JSViewAbstract::ParseJsColor(
1131         object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start, startResObj)) {
1132         localizedColor.start = start;
1133     }
1134     Color end;
1135     RefPtr<ResourceObject> endResObj;
1136     if (JSViewAbstract::ParseJsColor(
1137         object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end, endResObj)) {
1138         localizedColor.end = end;
1139     }
1140     Color top;
1141     RefPtr<ResourceObject> topResObj;
1142     if (JSViewAbstract::ParseJsColor(
1143         object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
1144         localizedColor.top = top;
1145     }
1146     Color bottom;
1147     RefPtr<ResourceObject> bottomResObj;
1148     if (JSViewAbstract::ParseJsColor(
1149         object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1150         localizedColor.bottom = bottom;
1151     }
1152     if (!SystemProperties::ConfigChangePerform()) {
1153         return;
1154     }
1155     if (startResObj) {
1156         localizedColor.startResObj = startResObj;
1157     }
1158     if (endResObj) {
1159         localizedColor.endResObj = endResObj;
1160     }
1161     if (topResObj) {
1162         localizedColor.topResObj = topResObj;
1163     }
1164     if (bottomResObj) {
1165         localizedColor.bottomResObj = bottomResObj;
1166     }
1167 }
1168 
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1169 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1170 {
1171     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
1172         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
1173         LocalizedColor localizedColor;
1174         ParseLocalizedEdgeColors(object, localizedColor);
1175         commonColor.top = localizedColor.top;
1176         commonColor.bottom = localizedColor.bottom;
1177         commonColor.left = localizedColor.start;
1178         commonColor.right = localizedColor.end;
1179         commonColor.topResObj = localizedColor.topResObj;
1180         commonColor.bottomResObj = localizedColor.bottomResObj;
1181         commonColor.leftResObj = localizedColor.startResObj;
1182         commonColor.rightResObj = localizedColor.endResObj;
1183         return true;
1184     }
1185     ParseEdgeColors(object, commonColor);
1186     return false;
1187 }
1188 
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1189 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1190 {
1191     CalcDimension left;
1192     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1193         CheckDimensionUnit(left, true, notNegative);
1194         commonCalcDimension.left = left;
1195     }
1196     CalcDimension right;
1197     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1198         CheckDimensionUnit(right, true, notNegative);
1199         commonCalcDimension.right = right;
1200     }
1201     CalcDimension top;
1202     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1203         CheckDimensionUnit(top, true, notNegative);
1204         commonCalcDimension.top = top;
1205     }
1206     CalcDimension bottom;
1207     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1208         CheckDimensionUnit(bottom, true, notNegative);
1209         commonCalcDimension.bottom = bottom;
1210     }
1211 }
1212 
ParseEdgeWidthsResObjFunc(NG::BorderWidthProperty & borderWidth,RefPtr<ResourceObject> leftResObj,RefPtr<ResourceObject> rightResObj,RefPtr<ResourceObject> topResObj,RefPtr<ResourceObject> bottomResObj)1213 void ParseEdgeWidthsResObjFunc(NG::BorderWidthProperty& borderWidth, RefPtr<ResourceObject> leftResObj,
1214     RefPtr<ResourceObject> rightResObj, RefPtr<ResourceObject> topResObj, RefPtr<ResourceObject> bottomResObj)
1215 {
1216     if (!SystemProperties::ConfigChangePerform()) {
1217         return;
1218     }
1219     borderWidth.resMap_.clear();
1220     if (leftResObj) {
1221         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1222             CalcDimension result;
1223             ResourceParseUtils::ParseResDimensionVp(resObj, result);
1224             borderWidth.leftDimen = result;
1225             borderWidth.multiValued = true;
1226         };
1227         borderWidth.AddResource("borderWidth.left", leftResObj, std::move(updateFunc));
1228     }
1229     if (rightResObj) {
1230         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1231             CalcDimension result;
1232             ResourceParseUtils::ParseResDimensionVp(resObj, result);
1233             borderWidth.rightDimen = result;
1234             borderWidth.multiValued = true;
1235         };
1236         borderWidth.AddResource("borderWidth.right", rightResObj, std::move(updateFunc));
1237     }
1238     if (topResObj) {
1239         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1240             CalcDimension result;
1241             ResourceParseUtils::ParseResDimensionVp(resObj, result);
1242             borderWidth.topDimen = result;
1243             borderWidth.multiValued = true;
1244         };
1245         borderWidth.AddResource("borderWidth.top", topResObj, std::move(updateFunc));
1246     }
1247     if (bottomResObj) {
1248         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1249             CalcDimension result;
1250             ResourceParseUtils::ParseResDimensionVp(resObj, result);
1251             borderWidth.bottomDimen = result;
1252             borderWidth.multiValued = true;
1253         };
1254         borderWidth.AddResource("borderWidth.bottom", bottomResObj, std::move(updateFunc));
1255     }
1256 }
1257 
ParseEdgeWidthsForDashParamsResObj(NG::BorderWidthProperty & borderWidth,RefPtr<ResourceObject> topResObj,RefPtr<ResourceObject> rightResObj,RefPtr<ResourceObject> bottomResObj,RefPtr<ResourceObject> leftResObj)1258 void ParseEdgeWidthsForDashParamsResObj(NG::BorderWidthProperty& borderWidth, RefPtr<ResourceObject> topResObj,
1259     RefPtr<ResourceObject> rightResObj, RefPtr<ResourceObject> bottomResObj, RefPtr<ResourceObject> leftResObj)
1260 {
1261     if (!SystemProperties::ConfigChangePerform()) {
1262         return;
1263     }
1264     borderWidth.resMap_.clear();
1265     if (leftResObj) {
1266         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1267             CalcDimension result;
1268             if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1269                 CheckDimensionUnit(result, true, false);
1270                 borderWidth.leftDimen = result;
1271             } else {
1272                 borderWidth.leftDimen = static_cast<CalcDimension>(-1);
1273             }
1274         };
1275         borderWidth.AddResource("borderWidth.left", leftResObj, std::move(updateFunc));
1276     }
1277     if (rightResObj) {
1278         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1279             CalcDimension result;
1280             if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1281                 CheckDimensionUnit(result, true, false);
1282                 borderWidth.rightDimen = result;
1283             } else {
1284                 borderWidth.rightDimen = static_cast<CalcDimension>(-1);
1285             }
1286         };
1287         borderWidth.AddResource("borderWidth.right", rightResObj, std::move(updateFunc));
1288     }
1289     if (topResObj) {
1290         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1291             CalcDimension result;
1292             if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1293                 CheckDimensionUnit(result, true, false);
1294                 borderWidth.topDimen = result;
1295             } else {
1296                 borderWidth.topDimen = static_cast<CalcDimension>(-1);
1297             }
1298         };
1299         borderWidth.AddResource("borderWidth.top", topResObj, std::move(updateFunc));
1300     }
1301     if (bottomResObj) {
1302         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1303             CalcDimension result;
1304             if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1305                 CheckDimensionUnit(result, true, false);
1306                 borderWidth.bottomDimen = result;
1307             } else {
1308                 borderWidth.bottomDimen = static_cast<CalcDimension>(-1);
1309             }
1310         };
1311         borderWidth.AddResource("borderWidth.bottom", bottomResObj, std::move(updateFunc));
1312     }
1313 }
1314 
ParseEdgeWidthsResObj(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth,bool notNegative)1315 void ParseEdgeWidthsResObj(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth, bool notNegative)
1316 {
1317     CalcDimension left;
1318     RefPtr<ResourceObject> leftResObj;
1319     if (JSViewAbstract::ParseJsDimensionVp(
1320             object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left, leftResObj)) {
1321         CheckDimensionUnit(left, true, notNegative);
1322         borderWidth.leftDimen = left;
1323         borderWidth.multiValued = true;
1324     }
1325     CalcDimension right;
1326     RefPtr<ResourceObject> rightResObj;
1327     if (JSViewAbstract::ParseJsDimensionVp(
1328             object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right, rightResObj)) {
1329         CheckDimensionUnit(right, true, notNegative);
1330         borderWidth.rightDimen = right;
1331         borderWidth.multiValued = true;
1332     }
1333     CalcDimension top;
1334     RefPtr<ResourceObject> topResObj;
1335     if (JSViewAbstract::ParseJsDimensionVp(
1336             object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
1337         CheckDimensionUnit(top, true, notNegative);
1338         borderWidth.topDimen = top;
1339         borderWidth.multiValued = true;
1340     }
1341     CalcDimension bottom;
1342     RefPtr<ResourceObject> bottomResObj;
1343     if (JSViewAbstract::ParseJsDimensionVp(
1344             object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1345         CheckDimensionUnit(bottom, true, notNegative);
1346         borderWidth.bottomDimen = bottom;
1347         borderWidth.multiValued = true;
1348     }
1349     ParseEdgeWidthsResObjFunc(borderWidth, leftResObj, rightResObj, topResObj, bottomResObj);
1350 }
1351 
ParseEdgeWidthsForDashParamsResObj(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth,CalcDimension defaultValue)1352 void ParseEdgeWidthsForDashParamsResObj(
1353     const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth, CalcDimension defaultValue)
1354 {
1355     CalcDimension left;
1356     RefPtr<ResourceObject> leftResObj;
1357     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, leftResObj, true)) {
1358         CheckDimensionUnit(left, true, false);
1359         borderWidth.leftDimen = left;
1360     } else {
1361         borderWidth.leftDimen = defaultValue;
1362     }
1363     CalcDimension right;
1364     RefPtr<ResourceObject> rightResObj;
1365     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, rightResObj, true)) {
1366         CheckDimensionUnit(right, true, false);
1367         borderWidth.rightDimen = right;
1368     } else {
1369         borderWidth.rightDimen = defaultValue;
1370     }
1371     CalcDimension top;
1372     RefPtr<ResourceObject> topResObj;
1373     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, topResObj, true)) {
1374         CheckDimensionUnit(top, true, false);
1375         borderWidth.topDimen = top;
1376     } else {
1377         borderWidth.topDimen = defaultValue;
1378     }
1379     CalcDimension bottom;
1380     RefPtr<ResourceObject> bottomResObj;
1381     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, bottomResObj, true)) {
1382         CheckDimensionUnit(bottom, false, true);
1383         borderWidth.bottomDimen = bottom;
1384     } else {
1385         borderWidth.bottomDimen = defaultValue;
1386     }
1387     ParseEdgeWidthsForDashParamsResObj(borderWidth, leftResObj, rightResObj, topResObj, bottomResObj);
1388 }
1389 
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1390 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
1391     bool notNegative, CalcDimension defaultValue)
1392 {
1393     CalcDimension left;
1394     RefPtr<ResourceObject> leftResObj;
1395     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, leftResObj, true)) {
1396         CheckDimensionUnit(left, notPercent, notNegative);
1397         commonCalcDimension.left = left;
1398     } else {
1399         commonCalcDimension.left = defaultValue;
1400     }
1401     CalcDimension right;
1402     RefPtr<ResourceObject> rightResObj;
1403     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, rightResObj, true)) {
1404         CheckDimensionUnit(right, notPercent, notNegative);
1405         commonCalcDimension.right = right;
1406     } else {
1407         commonCalcDimension.right = defaultValue;
1408     }
1409     CalcDimension top;
1410     RefPtr<ResourceObject> topResObj;
1411     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, topResObj, true)) {
1412         CheckDimensionUnit(top, notPercent, notNegative);
1413         commonCalcDimension.top = top;
1414     } else {
1415         commonCalcDimension.top = defaultValue;
1416     }
1417     CalcDimension bottom;
1418     RefPtr<ResourceObject> bottomResObj;
1419     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, bottomResObj, true)) {
1420         CheckDimensionUnit(bottom, false, true);
1421         commonCalcDimension.bottom = bottom;
1422     } else {
1423         commonCalcDimension.bottom = defaultValue;
1424     }
1425     if (leftResObj) {
1426         commonCalcDimension.leftResObj = leftResObj;
1427     }
1428     if (rightResObj) {
1429         commonCalcDimension.rightResObj = rightResObj;
1430     }
1431     if (topResObj) {
1432         commonCalcDimension.topResObj = topResObj;
1433     }
1434     if (bottomResObj) {
1435         commonCalcDimension.bottomResObj = bottomResObj;
1436     }
1437 }
1438 
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)1439 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
1440                               bool notNegative)
1441 {
1442     auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
1443     if (jsStart->IsObject()) {
1444         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
1445         CalcDimension calcDimension;
1446         if (ParseJsLengthMetrics(startObj, calcDimension)) {
1447             CheckDimensionUnit(calcDimension, true, notNegative);
1448             localizedCalcDimension.start = calcDimension;
1449         }
1450     }
1451     auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
1452     if (jsEnd->IsObject()) {
1453         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
1454         CalcDimension calcDimension;
1455         if (ParseJsLengthMetrics(endObj, calcDimension)) {
1456             CheckDimensionUnit(calcDimension, true, notNegative);
1457             localizedCalcDimension.end = calcDimension;
1458         }
1459     }
1460     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
1461     if (jsTop->IsObject()) {
1462         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
1463         CalcDimension calcDimension;
1464         if (ParseJsLengthMetrics(topObj, calcDimension)) {
1465             CheckDimensionUnit(calcDimension, true, notNegative);
1466             localizedCalcDimension.top = calcDimension;
1467         }
1468     }
1469     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
1470     if (jsBottom->IsObject()) {
1471         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
1472         CalcDimension calcDimension;
1473         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1474             CheckDimensionUnit(calcDimension, true, notNegative);
1475             localizedCalcDimension.bottom = calcDimension;
1476         }
1477     }
1478 }
1479 
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)1480 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
1481 {
1482     if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
1483         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
1484         CalcDimension calcDimension;
1485         RefPtr<ResourceObject> leftResObj;
1486         if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(startObj, calcDimension, leftResObj)) {
1487             CheckDimensionUnit(calcDimension, false, true);
1488             localizedCalcDimension.start = calcDimension;
1489             localizedCalcDimension.leftResObj = leftResObj;
1490         }
1491     }
1492     if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
1493         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
1494         CalcDimension calcDimension;
1495         RefPtr<ResourceObject> rightResObj;
1496         if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(endObj, calcDimension, rightResObj)) {
1497             CheckDimensionUnit(calcDimension, false, true);
1498             localizedCalcDimension.end = calcDimension;
1499             localizedCalcDimension.rightResObj = rightResObj;
1500         }
1501     }
1502     if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
1503         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
1504         CalcDimension calcDimension;
1505         RefPtr<ResourceObject> topResObj;
1506         if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(topObj, calcDimension, topResObj)) {
1507             CheckDimensionUnit(calcDimension, false, true);
1508             localizedCalcDimension.top = calcDimension;
1509             localizedCalcDimension.topResObj = topResObj;
1510         }
1511     }
1512     if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
1513         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
1514         CalcDimension calcDimension;
1515         RefPtr<ResourceObject> bottomResObj;
1516         if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(bottomObj, calcDimension, bottomResObj)) {
1517             CheckDimensionUnit(calcDimension, false, true);
1518             localizedCalcDimension.bottom = calcDimension;
1519             localizedCalcDimension.bottomResObj = bottomResObj;
1520         }
1521     }
1522 }
1523 
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1524 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1525 {
1526     if (JSViewAbstract::CheckLengthMetrics(object)) {
1527         LocalizedCalcDimension localizedCalcDimension;
1528         ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
1529         commonCalcDimension.top = localizedCalcDimension.top;
1530         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1531         commonCalcDimension.left = localizedCalcDimension.start;
1532         commonCalcDimension.right = localizedCalcDimension.end;
1533         return true;
1534     }
1535     if (!SystemProperties::ConfigChangePerform()) {
1536         ParseEdgeWidths(object, commonCalcDimension, notNegative);
1537     }
1538     return false;
1539 }
1540 
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1541 bool ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1542 {
1543     if (JSViewAbstract::CheckLengthMetrics(object)) {
1544         LocalizedCalcDimension localizedCalcDimension;
1545         ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
1546         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1547         commonCalcDimension.top = localizedCalcDimension.top;
1548         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1549         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1550         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1551         return true;
1552     }
1553     ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1554     return false;
1555 }
1556 
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1557 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1558 {
1559     if (JSViewAbstract::CheckLengthMetrics(object)) {
1560         LocalizedCalcDimension localizedCalcDimension;
1561         ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1562         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1563         commonCalcDimension.top = localizedCalcDimension.top;
1564         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1565         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1566         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1567         commonCalcDimension.leftResObj = isRightToLeft ? localizedCalcDimension.rightResObj : localizedCalcDimension.leftResObj;
1568         commonCalcDimension.rightResObj = isRightToLeft ? localizedCalcDimension.leftResObj : localizedCalcDimension.rightResObj;
1569         commonCalcDimension.topResObj = localizedCalcDimension.topResObj;
1570         commonCalcDimension.bottomResObj = localizedCalcDimension.bottomResObj;
1571         return;
1572     }
1573     ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1574 }
1575 
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1576 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1577 {
1578     auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1579     auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1580     auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1581         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1582         NG::PipelineContext::SetCallBackNode(targetNode);
1583         JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1584         jsFuncFinish->ExecuteJS(1, &newJSVal);
1585     };
1586     return finishCallback;
1587 }
1588 
ConvertCalcLength(CalcDimension & target)1589 NG::CalcLength ConvertCalcLength(CalcDimension& target)
1590 {
1591     NG::CalcLength targetLength = (target.Unit() == DimensionUnit::CALC) ?
1592         NG::CalcLength(target.IsNonNegative() ? target.CalcValue() : CalcDimension().CalcValue()) :
1593         NG::CalcLength(target.IsNonNegative() ? target : CalcDimension());
1594     return targetLength;
1595 }
1596 
SetConstraintSize(const RefPtr<ResourceObject> & minWidthResObj,const RefPtr<ResourceObject> & maxWidthResObj,const RefPtr<ResourceObject> & minHeightResObj,const RefPtr<ResourceObject> & maxHeightResObj)1597 void SetConstraintSize(const RefPtr<ResourceObject>& minWidthResObj, const RefPtr<ResourceObject>& maxWidthResObj,
1598     const RefPtr<ResourceObject>& minHeightResObj, const RefPtr<ResourceObject>& maxHeightResObj)
1599 {
1600     if (!SystemProperties::ConfigChangePerform()) {
1601         return;
1602     }
1603     if (minWidthResObj) {
1604         ViewAbstractModel::GetInstance()->SetMinWidth(minWidthResObj);
1605     }
1606     if (maxWidthResObj) {
1607         ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidthResObj);
1608     }
1609     if (minHeightResObj) {
1610         ViewAbstractModel::GetInstance()->SetMinHeight(minHeightResObj);
1611     }
1612     if (maxHeightResObj) {
1613         ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeightResObj);
1614     }
1615 }
1616 
RegisterBorderColorRes(NG::BorderColorProperty & colorProperty,const CommonColor & commonColor,bool isLocalizedEdgeColor)1617 void RegisterBorderColorRes(NG::BorderColorProperty& colorProperty,
1618     const CommonColor& commonColor, bool isLocalizedEdgeColor)
1619 {
1620     if (!SystemProperties::ConfigChangePerform()) {
1621        return;
1622     }
1623     if (commonColor.leftResObj) {
1624         auto&& updateFunc = [isLocalizedEdgeColor](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1625             Color result;
1626             ResourceParseUtils::ParseResColor(resObj, result);
1627             isLocalizedEdgeColor ? (borderColors.startColor = result) : (borderColors.leftColor = result);
1628         };
1629         colorProperty.AddResource("borderColor.start", commonColor.leftResObj, std::move(updateFunc));
1630     } else {
1631         colorProperty.RemoveResource("borderColor.start");
1632     }
1633     if (commonColor.rightResObj) {
1634         auto&& updateFunc = [isLocalizedEdgeColor](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1635             Color result;
1636             ResourceParseUtils::ParseResColor(resObj, result);
1637             isLocalizedEdgeColor ? (borderColors.endColor = result) : (borderColors.rightColor = result);
1638         };
1639         colorProperty.AddResource("borderColor.end", commonColor.rightResObj, std::move(updateFunc));
1640     } else {
1641         colorProperty.RemoveResource("borderColor.end");
1642     }
1643     if (commonColor.topResObj) {
1644         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1645             Color result;
1646             ResourceParseUtils::ParseResColor(resObj, result);
1647             borderColors.topColor = result;
1648         };
1649         colorProperty.AddResource("borderColor.top", commonColor.topResObj, std::move(updateFunc));
1650     } else {
1651         colorProperty.RemoveResource("borderColor.top");
1652     }
1653     if (commonColor.bottomResObj) {
1654         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1655             Color result;
1656             ResourceParseUtils::ParseResColor(resObj, result);
1657             borderColors.bottomColor = result;
1658         };
1659         colorProperty.AddResource("borderColor.bottom", commonColor.bottomResObj, std::move(updateFunc));
1660     } else {
1661         colorProperty.RemoveResource("borderColor.bottom");
1662     }
1663 }
1664 
RegisterRadiusRes(NG::BorderRadiusProperty & radius,RefPtr<ResourceObject> topStartResObj,RefPtr<ResourceObject> topEndResObj,RefPtr<ResourceObject> bottomStartResObj,RefPtr<ResourceObject> bottomEndResObj)1665 void RegisterRadiusRes(NG::BorderRadiusProperty& radius,
1666     RefPtr<ResourceObject> topStartResObj, RefPtr<ResourceObject> topEndResObj,
1667     RefPtr<ResourceObject> bottomStartResObj, RefPtr<ResourceObject> bottomEndResObj)
1668 {
1669     if (!SystemProperties::ConfigChangePerform()) {
1670         return;
1671     }
1672     if (topStartResObj) {
1673         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1674             CalcDimension result;
1675             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1676             radius.radiusTopLeft = result;
1677             radius.multiValued = true;
1678         };
1679         radius.AddResource("radius.topStart", topStartResObj, std::move(updateFunc));
1680     } else {
1681         radius.RemoveResource("radius.topStart");
1682     }
1683     if (topEndResObj) {
1684         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1685             CalcDimension result;
1686             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1687             radius.radiusTopRight = result;
1688             radius.multiValued = true;
1689         };
1690         radius.AddResource("radius.topEnd", topEndResObj, std::move(updateFunc));
1691     } else {
1692         radius.RemoveResource("radius.topEnd");
1693     }
1694     if (bottomStartResObj) {
1695         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1696             CalcDimension result;
1697             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1698             radius.radiusBottomRight = result;
1699             radius.multiValued = true;
1700         };
1701         radius.AddResource("radius.bottomStart", bottomStartResObj, std::move(updateFunc));
1702     } else {
1703         radius.RemoveResource("radius.bottomStart");
1704     }
1705     if (bottomEndResObj) {
1706         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1707             CalcDimension result;
1708             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1709             radius.radiusBottomLeft = result;
1710             radius.multiValued = true;
1711         };
1712         radius.AddResource("radius.bottomEnd", bottomEndResObj, std::move(updateFunc));
1713     } else {
1714         radius.RemoveResource("radius.bottomEnd");
1715     }
1716 }
1717 } // namespace
1718 
GetResourceObject(const JSRef<JSObject> & jsObj)1719 RefPtr<ResourceObject> JSViewAbstract::GetResourceObject(const JSRef<JSObject>& jsObj)
1720 {
1721     auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1722     auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1723     auto args = jsObj->GetProperty("params");
1724 
1725     std::string bundleName;
1726     std::string moduleName;
1727     auto bundle = jsObj->GetProperty("bundleName");
1728     auto module = jsObj->GetProperty("moduleName");
1729     if (bundle->IsString() && module->IsString()) {
1730         bundleName = bundle->ToString();
1731         moduleName = module->ToString();
1732     }
1733     if (!args->IsArray()) {
1734         return nullptr;
1735     }
1736     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1737     std::vector<ResourceObjectParams> resObjParamsList;
1738     auto size = static_cast<int32_t>(params->Length());
1739     for (int32_t i = 0; i < size; i++) {
1740         auto item = params->GetValueAt(i);
1741         ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1742         if (item->IsString()) {
1743             resObjParams.type = ResourceObjectParamType::STRING;
1744         } else if (item->IsNumber()) {
1745             if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1746                 resObjParams.type = ResourceObjectParamType::FLOAT;
1747             } else {
1748                 resObjParams.type = ResourceObjectParamType::INT;
1749             }
1750         }
1751         resObjParamsList.push_back(resObjParams);
1752     }
1753     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(
1754         id, type, resObjParamsList, bundleName, moduleName, Container::CurrentIdSafely());
1755     return resourceObject;
1756 }
1757 
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1758 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1759 {
1760     auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1761     auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1762     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName, Container::CurrentIdSafely());
1763     return resourceObject;
1764 }
1765 
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1766 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1767 {
1768     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1769     RefPtr<ThemeConstants> themeConstants = nullptr;
1770     if (SystemProperties::GetResourceDecoupling()) {
1771         resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1772         if (!resourceAdapter) {
1773             return nullptr;
1774         }
1775     } else {
1776         themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1777         if (!themeConstants) {
1778             return nullptr;
1779         }
1780     }
1781     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1782     return resourceWrapper;
1783 }
1784 
CreateResourceWrapper()1785 RefPtr<ResourceWrapper> CreateResourceWrapper()
1786 {
1787     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1788     RefPtr<ThemeConstants> themeConstants = nullptr;
1789     if (SystemProperties::GetResourceDecoupling()) {
1790         resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(Container::CurrentIdSafely());
1791         if (!resourceAdapter) {
1792             return nullptr;
1793         }
1794     } else {
1795         themeConstants = JSViewAbstract::GetThemeConstants();
1796         if (!themeConstants) {
1797             return nullptr;
1798         }
1799     }
1800     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1801     return resourceWrapper;
1802 }
1803 
ColorAlphaAdapt(uint32_t origin)1804 uint32_t ColorAlphaAdapt(uint32_t origin)
1805 {
1806     uint32_t result = origin;
1807     if (origin >> COLOR_ALPHA_OFFSET == 0) {
1808         result = origin | COLOR_ALPHA_VALUE;
1809     }
1810     return result;
1811 }
1812 
StringToMenuItemType(std::string_view id)1813 MenuItemType StringToMenuItemType(std::string_view id)
1814 {
1815     static const std::unordered_map<std::string_view, MenuItemType> keyMenuItemMap = {
1816         { "OH_DEFAULT_COPY", MenuItemType::COPY },
1817         { "OH_DEFAULT_PASTE", MenuItemType::PASTE },
1818         { "OH_DEFAULT_CUT", MenuItemType::CUT },
1819         { "OH_DEFAULT_SELECT_ALL", MenuItemType::SELECT_ALL },
1820         { "OH_DEFAULT_CAMERA_INPUT", MenuItemType::CAMERA_INPUT },
1821         { "OH_DEFAULT_AI_WRITE", MenuItemType::AI_WRITER },
1822         { "OH_DEFAULT_TRANSLATE", MenuItemType::TRANSLATE },
1823         { "OH_DEFAULT_SHARE", MenuItemType::SHARE },
1824         { "OH_DEFAULT_SEARCH", MenuItemType::SEARCH },
1825         { "OH_DEFAULT_ASK_CELIA", MenuItemType::ASK_CELIA },
1826     };
1827 
1828     auto item = keyMenuItemMap.find(id);
1829     return item != keyMenuItemMap.end() ? item->second : MenuItemType::UNKNOWN;
1830 }
1831 
UpdateInfoById(NG::MenuOptionsParam & menuOptionsParam,std::string_view id)1832 void UpdateInfoById(NG::MenuOptionsParam& menuOptionsParam, std::string_view id)
1833 {
1834     auto opType = StringToMenuItemType(id);
1835     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1836     CHECK_NULL_VOID(pipeline);
1837     auto theme = pipeline->GetTheme<TextOverlayTheme>();
1838     CHECK_NULL_VOID(theme);
1839     switch (opType) {
1840         case MenuItemType::COPY:
1841             menuOptionsParam.labelInfo = theme->GetCopyLabelInfo();
1842             menuOptionsParam.symbolId = theme->GetCopySymbolId();
1843             break;
1844         case MenuItemType::PASTE:
1845             menuOptionsParam.labelInfo = theme->GetPasteLabelInfo();
1846             menuOptionsParam.symbolId = theme->GetPasteSymbolId();
1847             break;
1848         case MenuItemType::CUT:
1849             menuOptionsParam.labelInfo = theme->GetCutLabelInfo();
1850             menuOptionsParam.symbolId = theme->GetCutSymbolId();
1851             break;
1852         case MenuItemType::SELECT_ALL:
1853             menuOptionsParam.labelInfo = theme->GetSelectAllLabelInfo();
1854             menuOptionsParam.symbolId = theme->GetCopyAllSymbolId();
1855             break;
1856         case MenuItemType::CAMERA_INPUT:
1857             menuOptionsParam.symbolId = theme->GetCameraInputSymbolId();
1858             break;
1859         case MenuItemType::AI_WRITER:
1860             menuOptionsParam.symbolId = theme->GetAIWriteSymbolId();
1861             break;
1862         case MenuItemType::TRANSLATE:
1863             menuOptionsParam.symbolId = theme->GetTranslateSymbolId();
1864             break;
1865         case MenuItemType::SHARE:
1866             menuOptionsParam.symbolId = theme->GetShareSymbolId();
1867             break;
1868         case MenuItemType::SEARCH:
1869             menuOptionsParam.symbolId = theme->GetSearchSymbolId();
1870             break;
1871         case MenuItemType::ASK_CELIA:
1872             menuOptionsParam.symbolId = theme->GetAskCeliaSymbolId();
1873             break;
1874         default:
1875             menuOptionsParam.labelInfo = menuOptionsParam.labelInfo.value_or("");
1876             menuOptionsParam.symbolId = menuOptionsParam.symbolId.value_or(0);
1877             break;
1878     }
1879 }
1880 
UpdateOptionsInfo(std::vector<NG::MenuItemParam> & params)1881 void UpdateOptionsInfo(std::vector<NG::MenuItemParam>& params)
1882 {
1883     for (auto& param : params) {
1884         UpdateInfoById(param.menuOptionsParam, param.menuOptionsParam.id);
1885     }
1886 }
1887 
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context,const RefPtr<NG::FrameNode> node)1888 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseChainedTransition(
1889     const JSRef<JSObject>& object, const JSExecutionContext& context, const RefPtr<NG::FrameNode> node)
1890 {
1891     auto propType = object->GetProperty("type_");
1892     if (!propType->IsString()) {
1893         return nullptr;
1894     }
1895     std::string type = propType->ToString();
1896     auto propEffectOption = object->GetProperty("effect_");
1897     auto propAnimationOption = object->GetProperty("animation_");
1898     auto propSuccessor = object->GetProperty("successor_");
1899     static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
1900         { "asymmetric", ParseChainedAsymmetricTransition },
1901         { "identity",
1902             [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
1903                 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
1904         { "move", ParseChainedMoveTransition },
1905         { "opacity", ParseChainedOpacityTransition },
1906         { "rotate", ParseChainedRotateTransition },
1907         { "scale", ParseChainedScaleTransition },
1908         { "slideSwitch",
1909             [](const JSRef<JSVal>& effectOption,
1910                 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
1911                 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
1912             } },
1913         { "translate", ParseChainedTranslateTransition },
1914     };
1915     int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
1916     if (index < 0) {
1917         return nullptr;
1918     }
1919     RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
1920     if (!result) {
1921         return nullptr;
1922     }
1923     if (propAnimationOption->IsObject()) {
1924         auto container = Container::Current();
1925         CHECK_NULL_RETURN(container, nullptr);
1926         auto pipelineContext = container->GetPipelineContext();
1927         CHECK_NULL_RETURN(pipelineContext, nullptr);
1928         auto animationOptionResult = std::make_shared<AnimationOption>(
1929             JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRenderExceptDynamicComponent()));
1930         // The maximum of the form-animation-playback duration value is 1000 ms.
1931         if (pipelineContext->IsFormRenderExceptDynamicComponent() && pipelineContext->IsFormAnimation()) {
1932             auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
1933             // If the duration exceeds 1000ms, init it to 0 ms.
1934             if (formAnimationTimeInterval > DEFAULT_DURATION) {
1935                 animationOptionResult->SetDuration(0);
1936             } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
1937                 // If remaining time is less than 1000ms, check for update duration.
1938                 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
1939                 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation]  Form Transition SetDuration: %{public}lld ms",
1940                     static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
1941             }
1942         }
1943         auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
1944         JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
1945         WeakPtr<NG::FrameNode> targetNode = nullptr;
1946         if (node) {
1947             targetNode = AceType::WeakClaim(AceType::RawPtr(node));
1948         } else {
1949             targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1950         }
1951         if (onFinish->IsFunction()) {
1952             RefPtr<JsFunction> jsFunc =
1953                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
1954             std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
1955                                                       id = Container::CurrentId(), node = targetNode]() {
1956                 ContainerScope scope(id);
1957                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1958                 PipelineContext::SetCallBackNode(node);
1959                 func->Execute();
1960             };
1961             animationOptionResult->SetOnFinishEvent(onFinishEvent);
1962         }
1963         result->SetAnimationOption(animationOptionResult);
1964     }
1965     if (propSuccessor->IsObject()) {
1966         result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
1967     }
1968     return result;
1969 }
1970 
JsScale(const JSCallbackInfo & info)1971 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1972 {
1973     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1974     auto jsVal = info[0];
1975     if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1976         SetDefaultScale();
1977         return;
1978     }
1979 
1980     if (jsVal->IsObject()) {
1981         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1982         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1983             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1984             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1985             // default: x, y, z (1.0, 1.0, 1.0)
1986             auto scaleX = 1.0f;
1987             auto scaleY = 1.0f;
1988             auto scaleZ = 1.0f;
1989             // default centerX, centerY 50% 50%;
1990             CalcDimension centerX = 0.5_pct;
1991             CalcDimension centerY = 0.5_pct;
1992             ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1993             ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1994             ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1995             return;
1996         } else {
1997             SetDefaultScale();
1998         }
1999     }
2000     double scale = 0.0;
2001     if (ParseJsDouble(jsVal, scale)) {
2002         ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
2003     }
2004 }
2005 
SetDefaultScale()2006 void JSViewAbstract::SetDefaultScale()
2007 {
2008     ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
2009     ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
2010 }
2011 
JsScaleX(const JSCallbackInfo & info)2012 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
2013 {
2014     double scaleVal = 0.0;
2015     if (!ParseJsDouble(info[0], scaleVal)) {
2016         return;
2017     }
2018     ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
2019 }
2020 
JsScaleY(const JSCallbackInfo & info)2021 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
2022 {
2023     double scaleVal = 0.0;
2024     if (!ParseJsDouble(info[0], scaleVal)) {
2025         return;
2026     }
2027     ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
2028 }
2029 
JsOpacity(const JSCallbackInfo & info)2030 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
2031 {
2032     ViewAbstractModel::GetInstance()->RemoveResObj("viewAbstract.opacity");
2033     double opacity = 0.0;
2034     RefPtr<ResourceObject> opacityResObj;
2035     if (!ParseJsDouble(info[0], opacity, opacityResObj)) {
2036         ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
2037         return;
2038     }
2039     if (SystemProperties::ConfigChangePerform() && opacityResObj) {
2040         ViewAbstractModel::GetInstance()->CreateWithOpacityResourceObj(opacityResObj);
2041         return;
2042     }
2043     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2044         opacity = std::clamp(opacity, 0.0, 1.0);
2045     } else {
2046         if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
2047             opacity = 1.0;
2048         }
2049     }
2050     ViewAbstractModel::GetInstance()->SetOpacity(opacity);
2051 }
2052 
JsTranslate(const JSCallbackInfo & info)2053 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
2054 {
2055     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
2056         JSCallbackInfoType::OBJECT };
2057     auto jsVal = info[0];
2058     if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
2059         SetDefaultTranslate();
2060         return;
2061     }
2062 
2063     if (jsVal->IsObject()) {
2064         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
2065         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
2066             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
2067             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
2068             // default: x, y, z (0.0, 0.0, 0.0)
2069             auto translateX = CalcDimension(0.0);
2070             auto translateY = CalcDimension(0.0);
2071             auto translateZ = CalcDimension(0.0);
2072             ParseJsTranslate(jsVal, translateX, translateY, translateZ);
2073             ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
2074             return;
2075         } else {
2076             SetDefaultTranslate();
2077         }
2078     }
2079     CalcDimension value;
2080     if (ParseJsDimensionVp(jsVal, value)) {
2081         ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
2082     }
2083 }
2084 
SetDefaultTranslate()2085 void JSViewAbstract::SetDefaultTranslate()
2086 {
2087     ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
2088 }
2089 
JsTranslateX(const JSCallbackInfo & info)2090 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
2091 {
2092     CalcDimension value;
2093     if (!ParseJsDimensionVp(info[0], value)) {
2094         return;
2095     }
2096     ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
2097 }
2098 
JsTranslateY(const JSCallbackInfo & info)2099 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
2100 {
2101     CalcDimension value;
2102     if (!ParseJsDimensionVp(info[0], value)) {
2103         return;
2104     }
2105     ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
2106 }
2107 
JsRotate(const JSCallbackInfo & info)2108 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
2109 {
2110     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2111     auto jsVal = info[0];
2112     if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
2113         SetDefaultRotate();
2114         return;
2115     }
2116 
2117     if (jsVal->IsObject()) {
2118         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
2119         NG::RotateAngleOptions rotateAngle(0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
2120         std::optional<float> angle;
2121         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
2122         bool hasAngleProp = jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::ANGLE));
2123         if (hasAngleProp) {
2124             ParseJsRotate(jsVal, rotate, angle);
2125             if (angle) {
2126                 ViewAbstractModel::GetInstance()->SetRotate(
2127                     rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
2128                 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
2129             } else {
2130                 SetDefaultRotate();
2131             }
2132         } else {
2133             ParseJsRotateAngle(jsVal, rotateAngle);
2134             ViewAbstractModel::GetInstance()->SetRotateAngle(
2135                 rotateAngle.angleX, rotateAngle.angleY, rotateAngle.angleZ, rotateAngle.perspective);
2136             ViewAbstractModel::GetInstance()->SetPivot(rotateAngle.centerX, rotateAngle.centerY, rotateAngle.centerZ);
2137         }
2138         return;
2139     }
2140     double rotateZ;
2141     if (ParseJsDouble(jsVal, rotateZ)) {
2142         ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
2143     }
2144 }
2145 
SetDefaultRotate()2146 void JSViewAbstract::SetDefaultRotate()
2147 {
2148     NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
2149     ViewAbstractModel::GetInstance()->SetRotate(
2150         rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
2151     ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
2152 }
2153 
JsRotateX(const JSCallbackInfo & info)2154 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
2155 {
2156     double rotateVal = 0.0;
2157     if (!ParseJsDouble(info[0], rotateVal)) {
2158         return;
2159     }
2160     ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
2161 }
2162 
JsRotateY(const JSCallbackInfo & info)2163 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
2164 {
2165     double rotateVal = 0.0;
2166     if (!ParseJsDouble(info[0], rotateVal)) {
2167         return;
2168     }
2169     ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
2170 }
2171 
JsTransform(const JSCallbackInfo & info)2172 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
2173 {
2174     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2175     auto jsVal = info[0];
2176     if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
2177         SetDefaultTransform();
2178         return;
2179     }
2180     JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
2181     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2182     if (!array->IsArray()) {
2183         return;
2184     }
2185     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
2186     if (jsArray->Length() != matrix4Len) {
2187         return;
2188     }
2189     std::vector<float> matrix(matrix4Len);
2190     for (int32_t i = 0; i < matrix4Len; i++) {
2191         double value = 0.0;
2192         ParseJsDouble(jsArray->GetValueAt(i), value);
2193         matrix[i] = static_cast<float>(value);
2194     }
2195     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
2196 }
2197 
JsTransform3D(const JSCallbackInfo & info)2198 void JSViewAbstract::JsTransform3D(const JSCallbackInfo& info)
2199 {
2200     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2201     auto jsVal = info[0];
2202     if (!CheckJSCallbackInfo("JsTransform3D", jsVal, checkList)) {
2203         SetDefaultTransform3D();
2204         return;
2205     }
2206     JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
2207     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2208     if (!array->IsArray()) {
2209         TAG_LOGW(AceLogTag::ACE_VISUAL_EFFECT, "[JSI] Type check failed in %{public}s: expected array", __FUNCTION__);
2210         SetDefaultTransform3D();
2211         return;
2212     }
2213     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
2214     if (jsArray->Length() != matrix4Len) {
2215         TAG_LOGW(AceLogTag::ACE_VISUAL_EFFECT,
2216             "Invalid matrix parameter: Expected %{public}d elements, but JS array has %{public}zu elements", matrix4Len,
2217             jsArray->Length());
2218         SetDefaultTransform3D();
2219         return;
2220     }
2221     std::vector<float> matrix(matrix4Len);
2222     for (int32_t i = 0; i < matrix4Len; i++) {
2223         double value = 0.0;
2224         if (!ParseJsDouble(jsArray->GetValueAt(i), value)) {
2225             TAG_LOGW(AceLogTag::ACE_VISUAL_EFFECT,"[JSView] Failed to parse double");
2226             value = 0.0;
2227         }
2228         matrix[i] = static_cast<float>(value);
2229     }
2230     ViewAbstractModel::GetInstance()->SetTransform3DMatrix(matrix);
2231 }
2232 
SetDefaultTransform()2233 void JSViewAbstract::SetDefaultTransform()
2234 {
2235     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2236     std::vector<float> matrix(matrix4Len);
2237     const int32_t initPosition = 5;
2238     for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
2239         double value = 1.0;
2240         matrix[i] = static_cast<float>(value);
2241     }
2242     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
2243 }
2244 
SetDefaultTransform3D()2245 void JSViewAbstract::SetDefaultTransform3D()
2246 {
2247     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2248     std::vector<float> matrix(matrix4Len);
2249     const int32_t initPosition = 5;
2250     for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
2251         double value = 1.0;
2252         matrix[i] = static_cast<float>(value);
2253     }
2254     ViewAbstractModel::GetInstance()->SetTransform3DMatrix(matrix);
2255 }
2256 
ParseJsTransition(const JSRef<JSObject> & jsObj)2257 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
2258 {
2259     NG::TransitionOptions transitionOption;
2260     bool hasEffect = false;
2261     transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
2262     if (jsObj->HasProperty("opacity")) {
2263         double opacity = 1.0;
2264         ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
2265         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2266             if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
2267                 opacity = 1.0;
2268             }
2269         } else {
2270             opacity = std::clamp(opacity, 0.0, 1.0);
2271         }
2272         transitionOption.UpdateOpacity(static_cast<float>(opacity));
2273         hasEffect = true;
2274     }
2275     if (jsObj->HasProperty("translate")) {
2276         // default: x, y, z (0.0, 0.0, 0.0)
2277         NG::TranslateOptions translate;
2278         ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
2279         transitionOption.UpdateTranslate(translate);
2280         hasEffect = true;
2281     }
2282     if (jsObj->HasProperty("scale")) {
2283         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
2284         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
2285         ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
2286             scale.centerX, scale.centerY);
2287         transitionOption.UpdateScale(scale);
2288         hasEffect = true;
2289     }
2290     if (jsObj->HasProperty("rotate")) {
2291         // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
2292         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
2293         std::optional<float> angle;
2294         ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
2295         if (angle.has_value()) {
2296             rotate.angle = angle.value();
2297             transitionOption.UpdateRotate(rotate);
2298             hasEffect = true;
2299         }
2300     }
2301     if (!hasEffect) {
2302         // default transition
2303         transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
2304     }
2305     return transitionOption;
2306 }
2307 
ParseJsTransitionEffect(const JSCallbackInfo & info)2308 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
2309 {
2310     JSRef<JSVal> arg = info[0];
2311     if (!arg->IsObject()) {
2312         return nullptr;
2313     }
2314     auto obj = JSRef<JSObject>::Cast(arg);
2315     auto transitionVal = obj->GetProperty("transition");
2316     if (!transitionVal->IsObject()) {
2317         return nullptr;
2318     }
2319     auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
2320     auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
2321     return chainedEffect;
2322 }
2323 
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)2324 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
2325     const JSExecutionContext& context)
2326 {
2327     auto chainedEffect = ParseChainedTransition(object, context);
2328     return chainedEffect;
2329 }
2330 
JsTransition(const JSCallbackInfo & info)2331 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
2332 {
2333     if (info.Length() < 1 || !info[0]->IsObject()) {
2334         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
2335             ViewAbstractModel::GetInstance()->CleanTransition();
2336             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
2337         }
2338         return;
2339     }
2340     auto obj = JSRef<JSObject>::Cast(info[0]);
2341     if (!obj->GetProperty("successor_")->IsUndefined()) {
2342         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
2343         std::function<void(bool)> finishCallback;
2344         if (info.Length() > 1 && info[1]->IsFunction()) {
2345             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
2346         }
2347         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
2348         return;
2349     }
2350     auto options = ParseJsTransition(obj);
2351     ViewAbstractModel::GetInstance()->SetTransition(options);
2352 }
2353 
JsWidth(const JSCallbackInfo & info)2354 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
2355 {
2356     JsWidth(info[0]);
2357 }
2358 
JsWidth(const JSRef<JSVal> & jsValue)2359 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
2360 {
2361     ViewAbstractModel::GetInstance()->ResetResObj("width");
2362     CalcDimension value;
2363     RefPtr<ResourceObject> valueResObj;
2364     if (jsValue->IsUndefined()) {
2365         ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, true);
2366         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2367         return true;
2368     }
2369     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2370         if (!ParseJsDimensionVpNG(jsValue, value, valueResObj)) {
2371             // JsWidth return false, check if set LayoutPolicy before return.
2372             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2373             if (jsValue->IsObject()) {
2374                 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
2375                 JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
2376                 if (layoutPolicy->IsString()) {
2377                     auto policy = ParseLayoutPolicy(layoutPolicy->ToString());
2378                     ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, true);
2379                     return true;
2380                 }
2381             }
2382             ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, true);
2383             return false;
2384         }
2385     } else if (!ParseJsDimensionVp(jsValue, value, valueResObj)) {
2386         return false;
2387     }
2388 
2389     ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, true);
2390     if (!SystemProperties::ConfigChangePerform() ? LessNotEqual(value.Value(), 0.0) :
2391         (LessNotEqual(value.Value(), 0.0) && !valueResObj)) {
2392         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2393             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2394             return true;
2395         } else {
2396             value.SetValue(0.0);
2397         }
2398     }
2399 
2400     if (SystemProperties::ConfigChangePerform() && valueResObj) {
2401         ViewAbstractModel::GetInstance()->SetWidth(valueResObj);
2402     } else {
2403         ViewAbstractModel::GetInstance()->SetWidth(value);
2404     }
2405     return true;
2406 }
2407 
JsHeight(const JSCallbackInfo & info)2408 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
2409 {
2410     JsHeight(info[0]);
2411 }
2412 
JsToolbar(const JSCallbackInfo & info)2413 void JSViewAbstract::JsToolbar(const JSCallbackInfo& info)
2414 {
2415     // Check the parameters
2416     if (info.Length() <= 0) {
2417         return;
2418     }
2419     if (info[0]->IsNull() || info[0]->IsUndefined()) {
2420         ViewAbstractModel::GetInstance()->SetToolbarBuilder(nullptr);
2421     } else if (info[0]->IsObject()) {
2422         JSRef<JSObject> toolbarObj = JSRef<JSObject>::Cast(info[0]);
2423         auto builder = toolbarObj->GetProperty("builder");
2424         if (!builder->IsFunction()) {
2425             return;
2426         }
2427         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2428         CHECK_NULL_VOID(builderFunc);
2429         auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
2430             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2431             ACE_SCORING_EVENT("CrateToolbarItems");
2432             ToolBarItemModel::GetInstance()->SetIsFirstCreate(true);
2433             func->Execute();
2434         };
2435         ViewAbstractModel::GetInstance()->SetToolbarBuilder(std::move(buildFunc));
2436     }
2437 }
2438 
JsHeight(const JSRef<JSVal> & jsValue)2439 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
2440 {
2441     ViewAbstractModel::GetInstance()->ResetResObj("height");
2442     CalcDimension value;
2443     RefPtr<ResourceObject> valueResObj;
2444     if (jsValue->IsUndefined()) {
2445         ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, false);
2446         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2447         return true;
2448     }
2449     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2450         if (!ParseJsDimensionVpNG(jsValue, value, valueResObj)) {
2451             // JsHeight return false, check if set LayoutPolicy before return.
2452             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2453             if (jsValue->IsObject()) {
2454                 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
2455                 JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
2456                 if (layoutPolicy->IsString()) {
2457                     auto policy = ParseLayoutPolicy(layoutPolicy->ToString());
2458                     ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, false);
2459                     return true;
2460                 }
2461             }
2462             ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, false);
2463             return false;
2464         }
2465     } else if (!ParseJsDimensionVp(jsValue, value, valueResObj)) {
2466         return false;
2467     }
2468 
2469     ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, false);
2470     if (!SystemProperties::ConfigChangePerform() ? LessNotEqual(value.Value(), 0.0) :
2471         (LessNotEqual(value.Value(), 0.0) && !valueResObj)) {
2472         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2473             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2474             return true;
2475         } else {
2476             value.SetValue(0.0);
2477         }
2478     }
2479 
2480     if (SystemProperties::ConfigChangePerform() && valueResObj) {
2481         ViewAbstractModel::GetInstance()->SetHeight(valueResObj);
2482     } else {
2483         ViewAbstractModel::GetInstance()->SetHeight(value);
2484     }
2485     return true;
2486 }
2487 
JsResponseRegion(const JSCallbackInfo & info)2488 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
2489 {
2490     std::vector<DimensionRect> result;
2491     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2492         ViewAbstractModel::GetInstance()->SetResponseRegion({});
2493         return;
2494     }
2495 
2496     ViewAbstractModel::GetInstance()->SetResponseRegion(result);
2497 }
2498 
JsMouseResponseRegion(const JSCallbackInfo & info)2499 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
2500 {
2501     std::vector<DimensionRect> result;
2502     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2503         ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
2504         return;
2505     }
2506     ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
2507 }
2508 
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2509 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
2510 {
2511     result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
2512     result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
2513     if (!jsValue->IsObject()) {
2514         return true;
2515     }
2516     JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
2517     JSRef<JSVal> x = obj->GetProperty("x");
2518     JSRef<JSVal> y = obj->GetProperty("y");
2519     JSRef<JSVal> width = obj->GetProperty("width");
2520     JSRef<JSVal> height = obj->GetProperty("height");
2521     CalcDimension xDimen = result.GetOffset().GetX();
2522     CalcDimension yDimen = result.GetOffset().GetY();
2523     CalcDimension widthDimen = result.GetWidth();
2524     CalcDimension heightDimen = result.GetHeight();
2525     auto s1 = width->ToString();
2526     auto s2 = height->ToString();
2527     if (s1.find('-') != std::string::npos) {
2528         width = JSRef<JSVal>::Make(ToJSValue("100%"));
2529     }
2530     if (s2.find('-') != std::string::npos) {
2531         height = JSRef<JSVal>::Make(ToJSValue("100%"));
2532     }
2533     if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
2534         auto offset = result.GetOffset();
2535         offset.SetX(xDimen);
2536         result.SetOffset(offset);
2537     }
2538     if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
2539         auto offset = result.GetOffset();
2540         offset.SetY(yDimen);
2541         result.SetOffset(offset);
2542     }
2543     if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
2544         if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
2545             return true;
2546         }
2547         result.SetWidth(widthDimen);
2548     }
2549     if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
2550         if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
2551             return true;
2552         }
2553         result.SetHeight(heightDimen);
2554     }
2555     return true;
2556 }
2557 
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2558 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
2559 {
2560     if (!jsValue->IsArray() && !jsValue->IsObject()) {
2561         return false;
2562     }
2563 
2564     if (jsValue->IsArray()) {
2565         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2566         for (size_t i = 0; i < array->Length(); i++) {
2567             CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2568             CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2569             CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2570             CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2571             DimensionOffset offsetDimen(xDimen, yDimen);
2572             DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2573             if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
2574                 result.emplace_back(dimenRect);
2575             } else {
2576                 return false;
2577             }
2578         }
2579         return true;
2580     }
2581 
2582     CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2583     CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2584     CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2585     CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2586     DimensionOffset offsetDimen(xDimen, yDimen);
2587     DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2588     if (ParseJsDimensionRect(jsValue, dimenRect)) {
2589         result.emplace_back(dimenRect);
2590         return true;
2591     } else {
2592         return false;
2593     }
2594 }
2595 
JsSize(const JSCallbackInfo & info)2596 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
2597 {
2598     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2599     auto jsVal = info[0];
2600     if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
2601         return;
2602     }
2603 
2604     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2605     JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
2606     JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
2607 }
2608 
JsConstraintSize(const JSCallbackInfo & info)2609 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
2610 {
2611     ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.minWidth");
2612     ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.maxWidth");
2613     ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.minHeight");
2614     ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.maxHeight");
2615     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2616     auto jsVal = info[0];
2617     if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
2618         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2619         ViewAbstractModel::GetInstance()->ResetMinSize(true);
2620         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2621         ViewAbstractModel::GetInstance()->ResetMinSize(false);
2622         return;
2623     }
2624 
2625     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2626 
2627     JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
2628     CalcDimension minWidth;
2629     RefPtr<ResourceObject> minWidthResObj;
2630     JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
2631     CalcDimension maxWidth;
2632     RefPtr<ResourceObject> maxWidthResObj;
2633     JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
2634     CalcDimension minHeight;
2635     RefPtr<ResourceObject> minHeightResObj;
2636     JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
2637     CalcDimension maxHeight;
2638     RefPtr<ResourceObject> maxHeightResObj;
2639     bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
2640     if (ParseJsDimensionVp(minWidthValue, minWidth, minWidthResObj)) {
2641         ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
2642     } else if (version10OrLarger) {
2643         ViewAbstractModel::GetInstance()->ResetMinSize(true);
2644     }
2645 
2646     if (ParseJsDimensionVp(maxWidthValue, maxWidth, maxWidthResObj)) {
2647         ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
2648     } else if (version10OrLarger) {
2649         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2650     }
2651 
2652     if (ParseJsDimensionVp(minHeightValue, minHeight, minHeightResObj)) {
2653         ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
2654     } else if (version10OrLarger) {
2655         ViewAbstractModel::GetInstance()->ResetMinSize(false);
2656     }
2657 
2658     if (ParseJsDimensionVp(maxHeightValue, maxHeight, maxHeightResObj)) {
2659         ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
2660     } else if (version10OrLarger) {
2661         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2662     }
2663     SetConstraintSize(minWidthResObj, maxWidthResObj, minHeightResObj, maxHeightResObj);
2664 }
2665 
JsLayoutPriority(const JSCallbackInfo & info)2666 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
2667 {
2668     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2669     auto jsVal = info[0];
2670     if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
2671         return;
2672     }
2673 
2674     int32_t priority;
2675     if (jsVal->IsNumber()) {
2676         priority = jsVal->ToNumber<int32_t>();
2677     } else {
2678         priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
2679     }
2680     ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
2681 }
2682 
JsLayoutWeight(const JSCallbackInfo & info)2683 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
2684 {
2685     float value = 0.0f;
2686     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2687     auto jsVal = info[0];
2688     if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
2689         if (!jsVal->IsUndefined()) {
2690             return;
2691         }
2692     }
2693 
2694     if (jsVal->IsNumber()) {
2695         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2696             value = jsVal->ToNumber<float>();
2697         } else {
2698             value = jsVal->ToNumber<int32_t>();
2699         }
2700     } else {
2701         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2702             value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
2703         } else {
2704             value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
2705         }
2706     }
2707 
2708     ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
2709 }
2710 
JsAlign(const JSCallbackInfo & info)2711 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
2712 {
2713     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::STRING };
2714     auto jsVal = info[0];
2715     if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
2716         Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2717         ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
2718         return;
2719     }
2720     if (jsVal->IsNumber()) {
2721         auto value = jsVal->ToNumber<int32_t>();
2722         Alignment alignment = ParseAlignment(value);
2723         ViewAbstractModel::GetInstance()->SetAlign(alignment);
2724         ViewAbstractModel::GetInstance()->SetIsMirrorable(false);
2725     } else {
2726         std::string localizedAlignment = jsVal->ToString();
2727         ViewAbstractModel::GetInstance()->SetAlign(localizedAlignment);
2728         ViewAbstractModel::GetInstance()->SetIsMirrorable(true);
2729     }
2730 }
2731 
JsLayoutGravity(const JSCallbackInfo & info)2732 void JSViewAbstract::JsLayoutGravity(const JSCallbackInfo& info)
2733 {
2734     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2735     auto jsVal = info[0];
2736     if (!CheckJSCallbackInfo("JsLayoutGravity", jsVal, checkList)) {
2737         ViewAbstractModel::GetInstance()->SetLayoutGravity(Alignment::CENTER);
2738         return;
2739     }
2740 
2741     if (jsVal->IsString()) {
2742         std::string value = jsVal->ToString();
2743         Alignment layoutGravityAlignment = NG::BoxLayoutAlgorithm::MapLocalizedToAlignment(value);
2744         ViewAbstractModel::GetInstance()->SetLayoutGravity(layoutGravityAlignment);
2745     }
2746 }
2747 
JsPosition(const JSCallbackInfo & info)2748 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
2749 {
2750     ViewAbstractModel::GetInstance()->ResetResObj("position.x");
2751     ViewAbstractModel::GetInstance()->ResetResObj("position.y");
2752     ViewAbstractModel::GetInstance()->ResetResObj("position.edges");
2753     CalcDimension x;
2754     CalcDimension y;
2755     RefPtr<ResourceObject> xResObj;
2756     RefPtr<ResourceObject> yResObj;
2757     OHOS::Ace::EdgesParam edges;
2758 
2759     auto jsArg = info[0];
2760     if (jsArg->IsObject()) {
2761         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2762         if (ParseLocationProps(jsObj, x, y, xResObj, yResObj)) {
2763             if (SystemProperties::ConfigChangePerform()) {
2764                 return ViewAbstractModel::GetInstance()->SetPosition(x, y, xResObj, yResObj);
2765             } else {
2766                 return ViewAbstractModel::GetInstance()->SetPosition(x, y);
2767             }
2768         } else if (ParseLocalizedEdges(jsObj, edges)) {
2769             ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
2770             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2771         } else if (ParseLocationPropsEdges(jsObj, edges)) {
2772             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2773         }
2774     }
2775     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2776         ViewAbstractModel::GetInstance()->ResetPosition();
2777     } else {
2778         ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
2779     }
2780 }
2781 
JsMarkAnchor(const JSCallbackInfo & info)2782 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
2783 {
2784     ViewAbstractModel::GetInstance()->ResetResObj("markAnchor.x");
2785     ViewAbstractModel::GetInstance()->ResetResObj("markAnchor.y");
2786     CalcDimension x;
2787     CalcDimension y;
2788     RefPtr<ResourceObject> xResObj;
2789     RefPtr<ResourceObject> yResObj;
2790 
2791     auto jsArg = info[0];
2792     if (jsArg->IsObject()) {
2793         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2794         if (ParseMarkAnchorPosition(jsObj, x, y)) {
2795             ViewAbstractModel::GetInstance()->SetMarkAnchorStart(x);
2796             return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2797         }
2798         if (ParseLocationProps(jsObj, x, y, xResObj, yResObj)) {
2799             ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
2800             if (SystemProperties::ConfigChangePerform()) {
2801                 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y, xResObj, yResObj);
2802             } else {
2803                 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2804             }
2805         }
2806     }
2807     ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
2808     ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
2809 }
2810 
JsOffset(const JSCallbackInfo & info)2811 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
2812 {
2813     ViewAbstractModel::GetInstance()->ResetResObj("offset.x");
2814     ViewAbstractModel::GetInstance()->ResetResObj("offset.y");
2815     ViewAbstractModel::GetInstance()->ResetResObj("offset.edges");
2816     CalcDimension x;
2817     CalcDimension y;
2818     RefPtr<ResourceObject> xResObj;
2819     RefPtr<ResourceObject> yResObj;
2820     OHOS::Ace::EdgesParam edges;
2821     auto jsArg = info[0];
2822     if (jsArg->IsObject()) {
2823         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2824         if (ParseLocalizedEdges(jsObj, edges)) {
2825             ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
2826             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2827         } else if (ParseLocationProps(jsObj, x, y, xResObj, yResObj)) {
2828             if (SystemProperties::ConfigChangePerform()) {
2829                 return ViewAbstractModel::GetInstance()->SetOffset(x, y, xResObj, yResObj);
2830             } else {
2831                 return ViewAbstractModel::GetInstance()->SetOffset(x, y);
2832             }
2833         } else if (ParseLocationPropsEdges(jsObj, edges)) {
2834             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2835         }
2836     }
2837 
2838     ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
2839 }
2840 
JsEnabled(const JSCallbackInfo & info)2841 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
2842 {
2843     auto arg = info[0];
2844     if (!arg->IsBoolean()) {
2845         ViewAbstractModel::GetInstance()->SetEnabled(true);
2846     } else {
2847         ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
2848     }
2849 }
2850 
JsAspectRatio(const JSCallbackInfo & info)2851 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
2852 {
2853     double value = 0.0;
2854     auto jsAspectRatio = info[0];
2855     if (!ParseJsDouble(jsAspectRatio, value)) {
2856         // add version protection, undefined use default value
2857         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
2858             (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
2859             ViewAbstractModel::GetInstance()->ResetAspectRatio();
2860             return;
2861         } else {
2862             return;
2863         }
2864     }
2865 
2866     // negative use default value.
2867     if (LessOrEqual(value, 0.0)) {
2868         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2869             ViewAbstractModel::GetInstance()->ResetAspectRatio();
2870             return;
2871         } else {
2872             value = 1.0;
2873         }
2874     }
2875 
2876     ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
2877 }
2878 
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2879 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
2880     std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
2881 {
2882     if (info[0]->IsString()) {
2883         std::string text = info[0]->ToString();
2884         ViewAbstractModel::GetInstance()->SetOverlay(
2885             text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
2886     } else if (info[0]->IsObject()) {
2887         JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
2888         auto builder = overlayObject->GetProperty("builder");
2889         if (builder->IsFunction()) {
2890             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2891             CHECK_NULL_VOID(builderFunc);
2892             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2893             auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
2894                                  node = targetNode]() {
2895                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2896                 ACE_SCORING_EVENT("Overlay");
2897                 PipelineContext::SetCallBackNode(node);
2898                 func->Execute();
2899             };
2900             ViewAbstractModel::GetInstance()->SetOverlay(
2901                 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
2902             return;
2903         }
2904 
2905         JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
2906         if (!builderNode->IsObject()) {
2907             return;
2908         }
2909         auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2910         JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2911         if (nodePtr.IsEmpty()) {
2912             return;
2913         }
2914         const auto* vm = nodePtr->GetEcmaVM();
2915         auto localHandle = nodePtr->GetLocalHandle();
2916         if (!localHandle->IsNativePointer(vm)) {
2917             return;
2918         }
2919         auto* node = localHandle->ToNativePointer(vm)->Value();
2920         auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2921         CHECK_NULL_VOID(frameNode);
2922         RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2923         ViewAbstractModel::GetInstance()->SetOverlay(
2924             "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2925     }
2926 }
2927 
JsOverlay(const JSCallbackInfo & info)2928 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2929 {
2930     if (info.Length() > 0 && (info[0]->IsUndefined())) {
2931         ViewAbstractModel::GetInstance()->SetOverlay(
2932             "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2933         return;
2934     }
2935 
2936     if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2937         return;
2938     }
2939     std::optional<Alignment> align;
2940     std::optional<CalcDimension> offsetX;
2941     std::optional<CalcDimension> offsetY;
2942 
2943     if (info[1]->IsObject()) {
2944         JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2945         JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2946         auto value = alignVal->ToNumber<int32_t>();
2947         Alignment alignment = ParseAlignment(value);
2948         align = alignment;
2949 
2950         JSRef<JSVal> val = optionObj->GetProperty("offset");
2951         if (val->IsObject()) {
2952             JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2953             JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2954             CalcDimension x;
2955             if (ParseJsDimensionVp(xVal, x)) {
2956                 offsetX = x;
2957             }
2958             JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2959             CalcDimension y;
2960             if (ParseJsDimensionVp(yVal, y)) {
2961                 offsetY = y;
2962             }
2963         }
2964     }
2965 
2966     ParseOverlayFirstParam(info, align, offsetX, offsetY);
2967 }
2968 
ParseAlignment(int32_t align)2969 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2970 {
2971     Alignment alignment = Alignment::CENTER;
2972     switch (align) {
2973         case 0:
2974             alignment = Alignment::TOP_LEFT;
2975             break;
2976         case 1:
2977             alignment = Alignment::TOP_CENTER;
2978             break;
2979         case 2:
2980             alignment = Alignment::TOP_RIGHT;
2981             break;
2982         case 3:
2983             alignment = Alignment::CENTER_LEFT;
2984             break;
2985         case 4:
2986             alignment = Alignment::CENTER;
2987             break;
2988         case 5:
2989             alignment = Alignment::CENTER_RIGHT;
2990             break;
2991         case 6:
2992             alignment = Alignment::BOTTOM_LEFT;
2993             break;
2994         case 7:
2995             alignment = Alignment::BOTTOM_CENTER;
2996             break;
2997         case 8:
2998             alignment = Alignment::BOTTOM_RIGHT;
2999             break;
3000         default:
3001             break;
3002     }
3003     return alignment;
3004 }
3005 
ParseLayoutPolicy(const std::string & layoutPolicy)3006 LayoutCalPolicy JSViewAbstract::ParseLayoutPolicy(const std::string& layoutPolicy)
3007 {
3008     if (layoutPolicy == "matchParent") {
3009         return LayoutCalPolicy::MATCH_PARENT;
3010     }
3011     if (layoutPolicy == "wrapContent") {
3012         return LayoutCalPolicy::WRAP_CONTENT;
3013     }
3014     if (layoutPolicy == "fixAtIdealSize") {
3015         return LayoutCalPolicy::FIX_AT_IDEAL_SIZE;
3016     }
3017     return LayoutCalPolicy::NO_MATCH;
3018 }
3019 
SetVisibility(const JSCallbackInfo & info)3020 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
3021 {
3022     int32_t visible = 0;
3023     JSRef<JSVal> arg = info[0];
3024     if (arg->IsNull() || arg->IsUndefined()) {
3025         // undefined value use default value.
3026         visible = 0;
3027     } else if (!arg->IsNumber()) {
3028         return;
3029     } else {
3030         visible = arg->ToNumber<int32_t>();
3031     }
3032 
3033     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3034         (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
3035         visible = 0;
3036     }
3037 
3038     if (info.Length() > 1 && info[1]->IsFunction()) {
3039         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
3040         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3041         auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
3042                                       int32_t visible) {
3043             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3044             ACE_SCORING_EVENT("onVisibilityChange");
3045             PipelineContext::SetCallBackNode(node);
3046             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
3047             func->ExecuteJS(1, &newJSVal);
3048         };
3049         ViewAbstractModel::GetInstance()->SetVisibility(
3050             static_cast<VisibleType>(visible), std::move(onVisibilityChange));
3051     } else {
3052         ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
3053     }
3054 }
3055 
JsSetFreeze(const JSCallbackInfo & info)3056 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
3057 {
3058     if (info[0]->IsBoolean()) {
3059         ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
3060     }
3061 }
3062 
JsFlexBasis(const JSCallbackInfo & info)3063 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
3064 {
3065     CalcDimension value;
3066     if (!ParseJsDimensionVp(info[0], value)) {
3067         value.SetUnit(DimensionUnit::AUTO);
3068     }
3069     // flexbasis don't support percent case.
3070     if (value.Unit() == DimensionUnit::PERCENT) {
3071         value.SetUnit(DimensionUnit::AUTO);
3072     }
3073     ViewAbstractModel::GetInstance()->SetFlexBasis(value);
3074 }
3075 
JsFlexGrow(const JSCallbackInfo & info)3076 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
3077 {
3078     double value = 0.0;
3079     if (!ParseJsDouble(info[0], value)) {
3080         if (info[0]->IsNull() || info[0]->IsUndefined()) {
3081             // undefined use default value.
3082             value = 0.0;
3083         } else {
3084             return;
3085         }
3086     }
3087     // negative use default value.
3088     if (value < 0.0) {
3089         value = 0.0;
3090     }
3091     ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
3092 }
3093 
JsFlexShrink(const JSCallbackInfo & info)3094 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
3095 {
3096     double value = 0.0;
3097     if (!ParseJsDouble(info[0], value)) {
3098         if (info[0]->IsNull() || info[0]->IsUndefined()) {
3099             // undefined use default value.
3100             ViewAbstractModel::GetInstance()->ResetFlexShrink();
3101             return;
3102         } else {
3103             return;
3104         }
3105     }
3106     // negative use default value.
3107     if (value < 0.0) {
3108         ViewAbstractModel::GetInstance()->ResetFlexShrink();
3109         return;
3110     }
3111     ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
3112 }
3113 
JsDisplayPriority(const JSCallbackInfo & info)3114 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
3115 {
3116     double value = 0.0;
3117     if (!ParseJsDouble(info[0], value)) {
3118         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
3119             ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
3120         }
3121         return;
3122     }
3123     ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
3124 }
3125 
JsSharedTransition(const JSCallbackInfo & info)3126 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
3127 {
3128     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
3129     auto jsVal = info[0];
3130     if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
3131         return;
3132     }
3133     // id
3134     auto id = jsVal->ToString();
3135     if (id.empty()) {
3136         return;
3137     }
3138     std::shared_ptr<SharedTransitionOption> sharedOption;
3139 
3140     // options
3141     if (info.Length() > 1 && info[1]->IsObject()) {
3142         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
3143         sharedOption = std::make_shared<SharedTransitionOption>();
3144         // default: duration: 1000
3145         sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
3146         if (sharedOption->duration < 0) {
3147             sharedOption->duration = DEFAULT_DURATION;
3148         }
3149         // default: delay: 0
3150         sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
3151         if (sharedOption->delay < 0) {
3152             sharedOption->delay = 0;
3153         }
3154         // default: LinearCurve
3155         RefPtr<Curve> curve;
3156         JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
3157         if (curveArgs->IsString()) {
3158             curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
3159         } else if (curveArgs->IsObject()) {
3160             JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
3161             if (!curveString->IsString()) {
3162                 return;
3163             }
3164             curve = CreateCurve(curveString->ToString(), false);
3165         }
3166         if (!curve) {
3167             curve = Curves::LINEAR;
3168         }
3169         sharedOption->curve = curve;
3170         // motionPath
3171         if (jsObj->HasProperty("motionPath")) {
3172             MotionPathOption motionPathOption;
3173             if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
3174                 sharedOption->motionPathOption = motionPathOption;
3175             }
3176         }
3177         // zIndex
3178         sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
3179         // type
3180         int32_t type = jsObj->GetPropertyValue<int32_t>("type",
3181             static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
3182         sharedOption->type = static_cast<SharedTransitionEffectType>(type);
3183     }
3184     ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
3185 }
3186 
JsGeometryTransition(const JSCallbackInfo & info)3187 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
3188 {
3189     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
3190     auto jsVal = info[0];
3191     if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
3192         return;
3193     }
3194     // id
3195     auto id = jsVal->ToString();
3196     // follow flag
3197     bool followWithOutTransition = false;
3198     // hierarchy flag
3199     bool doRegisterSharedTransition = true;
3200     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
3201         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3202         ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
3203 
3204         auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
3205         ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
3206         switch (transitionHierarchyStrategy) {
3207             case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
3208                 doRegisterSharedTransition = false;
3209                 break;
3210             case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
3211                 doRegisterSharedTransition = true;
3212                 break;
3213             default:
3214                 break;
3215         }
3216     }
3217     ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
3218 }
3219 
JsAlignSelf(const JSCallbackInfo & info)3220 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
3221 {
3222     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
3223     auto jsVal = info[0];
3224     if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
3225         ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
3226         return;
3227     }
3228     auto alignVal = jsVal->ToNumber<int32_t>();
3229 
3230     if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
3231         ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
3232     }
3233 }
3234 
JsBackgroundColor(const JSCallbackInfo & info)3235 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
3236 {
3237     Color backgroundColor;
3238     if (SystemProperties::ConfigChangePerform()) {
3239         RefPtr<ResourceObject> backgroundColorResObj;
3240         if (!ParseJsColor(info[0], backgroundColor, backgroundColorResObj)) {
3241             backgroundColor = Color::TRANSPARENT;
3242         }
3243         ViewAbstractModel::GetInstance()->SetBackgroundColorWithResourceObj(backgroundColor, backgroundColorResObj);
3244         return;
3245     } else {
3246         if (!ParseJsColor(info[0], backgroundColor)) {
3247             backgroundColor = Color::TRANSPARENT;
3248         }
3249     }
3250 
3251     ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
3252 }
3253 
JsBackgroundImage(const JSCallbackInfo & info)3254 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
3255 {
3256     int32_t resId = 0;
3257     std::string src;
3258     std::string bundle;
3259     std::string module;
3260     RefPtr<PixelMap> pixmap = nullptr;
3261     auto jsBackgroundImage = info[0];
3262     GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
3263     int32_t repeatIndex = 0;
3264     bool syncMode = false;
3265     ParseBackgroundImageOption(info, repeatIndex, syncMode);
3266     ViewAbstractModel::GetInstance()->SetBackgroundImageSyncMode(syncMode);
3267     RefPtr<ResourceObject> backgroundImageResObj;
3268     if (jsBackgroundImage->IsString()) {
3269         src = jsBackgroundImage->ToString();
3270         ViewAbstractModel::GetInstance()->SetBackgroundImage(
3271             ImageSourceInfo { src, bundle, module }, GetThemeConstants());
3272         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSrc");
3273     } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId, backgroundImageResObj)) {
3274         if (!SystemProperties::ConfigChangePerform()) {
3275             ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo{src, bundle, module}, nullptr);
3276         } else {
3277             ViewAbstractModel::GetInstance()->SetBackgroundImageWithResourceObj(
3278                 backgroundImageResObj, ImageSourceInfo { src, bundle, module }, nullptr);
3279         }
3280     } else {
3281 #if defined(PIXEL_MAP_SUPPORTED)
3282         if (IsDrawable(jsBackgroundImage)) {
3283             pixmap = GetDrawablePixmap(jsBackgroundImage);
3284         } else {
3285             pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
3286         }
3287 #endif
3288         ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
3289         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSrc");
3290     }
3291     if (info.Length() == 2) { // 2 is background image info length
3292         auto jsImageRepeat = info[1];
3293         if (jsImageRepeat->IsNumber()) {
3294             repeatIndex = jsImageRepeat->ToNumber<int32_t>();
3295         }
3296     }
3297     auto repeat = static_cast<ImageRepeat>(repeatIndex);
3298     ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
3299 }
3300 
ParseBackgroundImageOption(const JSCallbackInfo & info,int32_t & repeatIndex,bool & syncMode)3301 void JSViewAbstract::ParseBackgroundImageOption(const JSCallbackInfo& info, int32_t& repeatIndex, bool& syncMode)
3302 {
3303     if (info.Length() < 2) { // 2 represents the least para num;
3304         return;
3305     }
3306     if (!info[1]->IsObject()) {
3307         return;
3308     }
3309     JSRef<JSObject> jsOption  = JSRef<JSObject>::Cast(info[1]);
3310     if (jsOption->GetProperty("syncLoad")->IsBoolean()) {
3311         syncMode = jsOption->GetProperty("syncLoad")->ToBoolean();
3312     }
3313     if (jsOption->GetProperty("repeat")->IsNumber()) {
3314         repeatIndex = jsOption->GetProperty("repeat")->ToNumber<int32_t>();
3315     }
3316 }
3317 
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)3318 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
3319 {
3320     auto blurOptionProperty = jsBlurOption->GetProperty("grayscale");
3321     if (blurOptionProperty->IsArray()) {
3322         JSRef<JSArray> params = JSRef<JSArray>::Cast(blurOptionProperty);
3323         auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
3324         auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
3325         std::vector<float> greyVec(2); // 2 number
3326         greyVec[0] = grey1;
3327         greyVec[1] = grey2;
3328         blurOption.grayscale = greyVec;
3329     }
3330 }
3331 
ParseSysOptions(const JSRef<JSObject> & jsSysOptions,SysOptions & sysOptions)3332 void JSViewAbstract::ParseSysOptions(const JSRef<JSObject>& jsSysOptions, SysOptions& sysOptions)
3333 {
3334     auto disableAdaptation = jsSysOptions->GetProperty("disableSystemAdaptation");
3335     if (disableAdaptation->IsBoolean()) {
3336         sysOptions.disableSystemAdaptation = disableAdaptation->ToBoolean();
3337     }
3338 }
3339 
ParseInactiveColor(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)3340 void JSViewAbstract::ParseInactiveColor(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
3341 {
3342     RefPtr<ResourceObject> inactiveColorResObj;
3343     if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor, inactiveColorResObj)) {
3344         styleOption.isValidColor = true;
3345     }
3346     if (SystemProperties::ConfigChangePerform() && inactiveColorResObj) {
3347         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, BlurStyleOption& styleOption) {
3348             Color inactiveColorValue;
3349             ResourceParseUtils::ParseResColor(resObj, inactiveColorValue);
3350             styleOption.inactiveColor = inactiveColorValue;
3351             styleOption.isValidColor = true;
3352         };
3353         styleOption.AddResource("backgroundBlurStyle.backgroundBlurStyleOptions.inactiveColor",
3354             inactiveColorResObj, std::move(updateFunc));
3355     }
3356 }
3357 
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)3358 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
3359 {
3360     if (jsOption->IsUndefined()) {
3361         return;
3362     }
3363     auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3364     ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3365     if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3366         colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3367         styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3368     }
3369     auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3370     ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3371     if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3372         adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3373         styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3374     }
3375 
3376     // policy
3377     auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
3378     ParseJsInt32(jsOption->GetProperty("policy"), policy);
3379     if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
3380         policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3381         styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3382     }
3383 
3384     // blurType
3385     auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3386     ParseJsInt32(jsOption->GetProperty("type"), blurType);
3387     if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3388         blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3389         styleOption.blurType = static_cast<BlurType>(blurType);
3390     }
3391 
3392     // inactiveColor
3393     ParseInactiveColor(jsOption, styleOption);
3394 
3395     // scale
3396     if (jsOption->GetProperty("scale")->IsNumber()) {
3397         double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3398         styleOption.scale = std::clamp(scale, 0.0, 1.0);
3399     }
3400 
3401     if (jsOption->GetProperty("blurOptions")->IsObject()) {
3402         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3403         BlurOption blurOption;
3404         ParseBlurOption(jsBlurOption, blurOption);
3405         styleOption.blurOption = blurOption;
3406     }
3407 }
3408 
JsBackgroundBlurStyle(const JSCallbackInfo & info)3409 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
3410 {
3411     if (info.Length() == 0) {
3412         return;
3413     }
3414     ViewAbstractModel::GetInstance()->RemoveResObj("backgroundBlurStyle.backgroundBlurStyleOptions");
3415     BlurStyleOption styleOption;
3416     if (info[0]->IsNumber()) {
3417         auto blurStyle = info[0]->ToNumber<int32_t>();
3418         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3419             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3420             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3421         }
3422     }
3423     if (info.Length() > 1 && info[1]->IsObject()) {
3424         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3425         ParseBlurStyleOption(jsOption, styleOption);
3426     }
3427     SysOptions sysOptions;
3428     sysOptions.disableSystemAdaptation = false;
3429     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
3430         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
3431         ParseSysOptions(jsSysOptions, sysOptions);
3432     }
3433     ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption, sysOptions);
3434 }
3435 
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)3436 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
3437 {
3438     double rate = 1.0f;
3439     auto jsRate = jsOption->GetProperty("rate");
3440     if (jsRate->IsNumber()) {
3441         rate = jsRate->ToNumber<double>();
3442     }
3443     double lightUpDegree = 0.0f;
3444     auto jslightUpDegree = jsOption->GetProperty("lightUpDegree");
3445     if (jslightUpDegree->IsNumber()) {
3446         lightUpDegree = jslightUpDegree->ToNumber<double>();
3447     }
3448     double cubicCoeff = 0.0f;
3449     auto jsCubicCoeff = jsOption->GetProperty("cubicCoeff");
3450     if (jsCubicCoeff->IsNumber()) {
3451         cubicCoeff = jsCubicCoeff->ToNumber<double>();
3452     }
3453     double quadCoeff = 0.0f;
3454     auto jsQuadCoeff = jsOption->GetProperty("quadCoeff");
3455     if (jsQuadCoeff->IsNumber()) {
3456         quadCoeff = jsQuadCoeff->ToNumber<double>();
3457     }
3458     double saturation = 1.0f;
3459     auto jsSaturation = jsOption->GetProperty("saturation");
3460     if (jsSaturation->IsNumber()) {
3461         saturation = jsSaturation->ToNumber<double>();
3462     }
3463     std::vector<float> posRGB(3, 0.0);
3464     auto jsPosRGB = jsOption->GetProperty("posRGB");
3465     if (jsPosRGB->IsArray()) {
3466         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsPosRGB);
3467         auto r = params->GetValueAt(0)->ToNumber<double>();
3468         auto g = params->GetValueAt(1)->ToNumber<double>();
3469         auto b = params->GetValueAt(2)->ToNumber<double>();
3470         posRGB[0] = r;
3471         posRGB[1] = g;
3472         posRGB[2] = b;
3473     }
3474     std::vector<float> negRGB(3, 0.0);
3475     auto jsNegRGB = jsOption->GetProperty("negRGB");
3476     if (jsNegRGB->IsArray()) {
3477         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsNegRGB);
3478         auto r = params->GetValueAt(0)->ToNumber<double>();
3479         auto g = params->GetValueAt(1)->ToNumber<double>();
3480         auto b = params->GetValueAt(2)->ToNumber<double>();
3481         negRGB[0] = r;
3482         negRGB[1] = g;
3483         negRGB[2] = b;
3484     }
3485     double fraction = 1.0f;
3486     auto jsFraction = jsOption->GetProperty("fraction");
3487     if (jsFraction->IsNumber()) {
3488         fraction = jsFraction->ToNumber<double>();
3489         fraction = std::clamp(fraction, 0.0, 1.0);
3490     }
3491     brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
3492 }
3493 
GetEffectOptionColor(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3494 void JSViewAbstract::GetEffectOptionColor(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3495 {
3496     if (!SystemProperties::ConfigChangePerform()) {
3497         ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
3498     } else {
3499         RefPtr<ResourceObject> colorResObj;
3500         ParseJsColor(jsOption->GetProperty("color"), effectOption.color, colorResObj);
3501         if (colorResObj) {
3502             auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, EffectOption& effectOption) {
3503                 Color effectOptionColor;
3504                 ResourceParseUtils::ParseResColor(colorResObj, effectOptionColor);
3505                 effectOption.color = effectOptionColor;
3506             };
3507             effectOption.AddResource("backgroundEffect.color", colorResObj, std::move(updateFunc));
3508         }
3509     }
3510 }
3511 
GetEffectOptionInactiveColorUpdate(const RefPtr<ResourceObject> & inactiveColorObj,EffectOption & effectOption)3512 void JSViewAbstract::GetEffectOptionInactiveColorUpdate(const RefPtr<ResourceObject>& inactiveColorObj,
3513     EffectOption& effectOption)
3514 {
3515     if (inactiveColorObj) {
3516         auto&& updateFunc = [](const RefPtr<ResourceObject>& inactiveColorObj, EffectOption& effectOption) {
3517             Color effectOptionInactiveColor;
3518             ResourceParseUtils::ParseResColor(inactiveColorObj, effectOptionInactiveColor);
3519             effectOption.inactiveColor = effectOptionInactiveColor;
3520         };
3521         effectOption.AddResource("backgroundEffect.inactiveColor", inactiveColorObj, std::move(updateFunc));
3522     }
3523 }
3524 
GetEffectOptionInactiveColor(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3525 void JSViewAbstract::GetEffectOptionInactiveColor(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3526 {
3527     if (!SystemProperties::ConfigChangePerform()) {
3528         if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
3529             effectOption.isValidColor = true;
3530         }
3531     } else {
3532         RefPtr<ResourceObject> inactiveColorObj;
3533         if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor, inactiveColorObj)) {
3534             GetEffectOptionInactiveColorUpdate(inactiveColorObj, effectOption);
3535             effectOption.isValidColor = true;
3536         }
3537     }
3538 }
3539 
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3540 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3541 {
3542     CalcDimension radius;
3543     if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
3544         radius.SetValue(0.0f);
3545     }
3546     effectOption.radius = radius;
3547 
3548     double saturation = 1.0f;
3549     if (jsOption->GetProperty("saturation")->IsNumber()) {
3550         saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
3551         saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
3552     }
3553     effectOption.saturation = saturation;
3554 
3555     double brightness = 1.0f;
3556     if (jsOption->GetProperty("brightness")->IsNumber()) {
3557         brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
3558         brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
3559     }
3560     effectOption.brightness = brightness;
3561 
3562     GetEffectOptionColor(jsOption, effectOption);
3563 
3564     auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3565     auto adaptiveColor = AdaptiveColor::DEFAULT;
3566     ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
3567     if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3568         adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3569         adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
3570     }
3571     effectOption.adaptiveColor = adaptiveColor;
3572 
3573     // policy
3574     auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
3575     ParseJsInt32(jsOption->GetProperty("policy"), policy);
3576     if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
3577         policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3578         effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3579     }
3580 
3581     // blurType
3582     auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3583     ParseJsInt32(jsOption->GetProperty("type"), blurType);
3584     if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3585         blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3586         effectOption.blurType = static_cast<BlurType>(blurType);
3587     }
3588 
3589     // inactiveColor
3590     GetEffectOptionInactiveColor(jsOption, effectOption);
3591 
3592     BlurOption blurOption;
3593     if (jsOption->GetProperty("blurOptions")->IsObject()) {
3594         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3595         ParseBlurOption(jsBlurOption, blurOption);
3596         effectOption.blurOption = blurOption;
3597     }
3598 }
3599 
JsForegroundEffect(const JSCallbackInfo & info)3600 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
3601 {
3602     if (info.Length() == 0) {
3603         return;
3604     }
3605     float radius = 0.0;
3606     if (info[0]->IsObject()) {
3607         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3608         if (jsOption->GetProperty("radius")->IsNumber()) {
3609             radius = jsOption->GetProperty("radius")->ToNumber<float>();
3610         }
3611     }
3612     radius = std::max(radius, 0.0f);
3613     ViewAbstractModel::GetInstance()->SetForegroundEffect(radius);
3614 }
3615 
JsBackgroundEffect(const JSCallbackInfo & info)3616 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
3617 {
3618     if (info.Length() == 0) {
3619         return;
3620     }
3621     ViewAbstractModel::GetInstance()->RemoveResObj("backgroundEffect");
3622     EffectOption option;
3623     if (info[0]->IsObject()) {
3624         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3625         ParseEffectOption(jsOption, option);
3626     }
3627     SysOptions sysOptions;
3628     sysOptions.disableSystemAdaptation = false;
3629     if (info.Length() > NUM1 && info[NUM1]->IsObject()) {
3630         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM1]);
3631         ParseSysOptions(jsSysOptions, sysOptions);
3632     }
3633     ViewAbstractModel::GetInstance()->SetBackgroundEffect(option, sysOptions);
3634 }
3635 
JsForegroundBlurStyle(const JSCallbackInfo & info)3636 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
3637 {
3638     if (info.Length() == 0) {
3639         return;
3640     }
3641     BlurStyleOption styleOption;
3642     if (info[0]->IsNumber()) {
3643         auto blurStyle = info[0]->ToNumber<int32_t>();
3644         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3645             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3646             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3647         }
3648     }
3649     if (info.Length() > 1 && info[1]->IsObject()) {
3650         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3651         auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3652         ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3653         if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3654             colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3655             styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3656         }
3657         auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3658         ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3659         if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3660             adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3661             styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3662         }
3663         if (jsOption->GetProperty("scale")->IsNumber()) {
3664             double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3665             styleOption.scale = std::clamp(scale, 0.0, 1.0);
3666         }
3667 
3668         if (jsOption->GetProperty("blurOptions")->IsObject()) {
3669             JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3670             BlurOption blurOption;
3671             ParseBlurOption(jsBlurOption, blurOption);
3672             styleOption.blurOption = blurOption;
3673         }
3674     }
3675     SysOptions sysOptions;
3676     sysOptions.disableSystemAdaptation = false;
3677     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
3678         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
3679         ParseSysOptions(jsSysOptions, sysOptions);
3680     }
3681     ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption, sysOptions);
3682 }
3683 
JsSphericalEffect(const JSCallbackInfo & info)3684 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
3685 {
3686     auto radio = 0.0;
3687     if (info[0]->IsNumber()) {
3688         radio = info[0]->ToNumber<double>();
3689     }
3690     ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
3691 }
3692 
GetPixelStretchEffectLeftObj(const JSRef<JSObject> & jsObject,CalcDimension & left,PixStretchEffectOption & option)3693 void JSViewAbstract::GetPixelStretchEffectLeftObj(const JSRef<JSObject>& jsObject, CalcDimension& left, PixStretchEffectOption& option)
3694 {
3695     RefPtr<ResourceObject> leftObj;
3696     ParseJsDimensionVp(jsObject->GetProperty("left"), left, leftObj);
3697     if (leftObj) {
3698         auto&& updateFunc = [](const RefPtr<ResourceObject>& leftObj, PixStretchEffectOption& effectOption) {
3699             CalcDimension left;
3700             ResourceParseUtils::ParseResDimensionVp(leftObj, left);
3701             effectOption.left = left;
3702         };
3703         option.AddResource("pixelStretchEffect.left", leftObj, std::move(updateFunc));
3704     }
3705 }
3706 
GetPixelStretchEffectRightObj(const JSRef<JSObject> & jsObject,CalcDimension & right,PixStretchEffectOption & option)3707 void JSViewAbstract::GetPixelStretchEffectRightObj(const JSRef<JSObject>& jsObject, CalcDimension& right, PixStretchEffectOption& option)
3708 {
3709     RefPtr<ResourceObject> rightObj;
3710     ParseJsDimensionVp(jsObject->GetProperty("right"), right, rightObj);
3711     if (rightObj) {
3712         auto&& updateFunc = [](const RefPtr<ResourceObject>& rightObj, PixStretchEffectOption& effectOption) {
3713             CalcDimension right;
3714             ResourceParseUtils::ParseResDimensionVp(rightObj, right);
3715             effectOption.right = right;
3716         };
3717         option.AddResource("pixelStretchEffect.right", rightObj, std::move(updateFunc));
3718     }
3719 }
3720 
GetPixelStretchEffectTopObj(const JSRef<JSObject> & jsObject,CalcDimension & top,PixStretchEffectOption & option)3721 void JSViewAbstract::GetPixelStretchEffectTopObj(const JSRef<JSObject>& jsObject, CalcDimension& top, PixStretchEffectOption& option)
3722 {
3723     RefPtr<ResourceObject> topObj;
3724     ParseJsDimensionVp(jsObject->GetProperty("top"), top, topObj);
3725     if (topObj) {
3726         auto&& updateFunc = [](const RefPtr<ResourceObject>& topObj, PixStretchEffectOption& effectOption) {
3727             CalcDimension top;
3728             ResourceParseUtils::ParseResDimensionVp(topObj, top);
3729             effectOption.top = top;
3730         };
3731         option.AddResource("pixelStretchEffect.top", topObj, std::move(updateFunc));
3732     }
3733 }
3734 
GetPixelStretchEffectBottomObj(const JSRef<JSObject> & jsObject,CalcDimension & bottom,PixStretchEffectOption & option)3735 void JSViewAbstract::GetPixelStretchEffectBottomObj(const JSRef<JSObject>& jsObject, CalcDimension& bottom, PixStretchEffectOption& option)
3736 {
3737     RefPtr<ResourceObject> bottomObj;
3738     ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom, bottomObj);
3739     if (bottomObj) {
3740         auto&& updateFunc = [](const RefPtr<ResourceObject>& bottomObj, PixStretchEffectOption& effectOption) {
3741             CalcDimension bottom;
3742             ResourceParseUtils::ParseResDimensionVp(bottomObj, bottom);
3743             effectOption.bottom = bottom;
3744         };
3745         option.AddResource("pixelStretchEffect.bottom", bottomObj, std::move(updateFunc));
3746     }
3747 }
3748 
JsPixelStretchEffect(const JSCallbackInfo & info)3749 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
3750 {
3751     ViewAbstractModel::GetInstance()->RemoveResObj("pixelStretchEffect");
3752     if (!info[0]->IsObject()) {
3753         PixStretchEffectOption option;
3754         option.ResetValue();
3755         ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3756         return;
3757     }
3758     auto jsObject = JSRef<JSObject>::Cast(info[0]);
3759     CalcDimension left;
3760     CalcDimension right;
3761     CalcDimension top;
3762     CalcDimension bottom;
3763     PixStretchEffectOption option;
3764     if (!SystemProperties::ConfigChangePerform()) {
3765         ParseJsDimensionVp(jsObject->GetProperty("left"), left);
3766         ParseJsDimensionVp(jsObject->GetProperty("right"), right);
3767         ParseJsDimensionVp(jsObject->GetProperty("top"), top);
3768         ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
3769     } else {
3770         GetPixelStretchEffectLeftObj(jsObject, left, option);
3771         GetPixelStretchEffectRightObj(jsObject, right, option);
3772         GetPixelStretchEffectTopObj(jsObject, top, option);
3773         GetPixelStretchEffectBottomObj(jsObject, bottom, option);
3774     }
3775 
3776     bool illegalInput = InitPixStretchEffect(left, right, top, bottom);
3777     if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
3778         (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
3779         option.left = left;
3780         option.top = top;
3781         option.right = right;
3782         option.bottom = bottom;
3783     } else {
3784         illegalInput = true;
3785     }
3786     if (illegalInput) {
3787         option.ResetValue();
3788     }
3789     ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3790 }
3791 
InitPixStretchEffect(CalcDimension & left,CalcDimension & right,CalcDimension & top,CalcDimension bottom)3792 bool JSViewAbstract::InitPixStretchEffect(
3793     CalcDimension& left, CalcDimension& right, CalcDimension& top, CalcDimension bottom)
3794 {
3795     bool illegalInput = false;
3796     if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
3797         top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
3798         if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
3799             (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
3800             (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
3801             (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
3802             left.SetUnit(DimensionUnit::PERCENT);
3803             top.SetUnit(DimensionUnit::PERCENT);
3804             right.SetUnit(DimensionUnit::PERCENT);
3805             bottom.SetUnit(DimensionUnit::PERCENT);
3806         } else {
3807             illegalInput = true;
3808         }
3809     }
3810     return illegalInput;
3811 }
3812 
JsLightUpEffect(const JSCallbackInfo & info)3813 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
3814 {
3815     auto radio = 1.0;
3816     if (info[0]->IsNumber()) {
3817         radio = info[0]->ToNumber<double>();
3818     }
3819     ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
3820 }
3821 
JsBackgroundImageSize(const JSCallbackInfo & info)3822 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
3823 {
3824     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3825     BackgroundImageSize bgImgSize;
3826     auto jsVal = info[0];
3827     if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
3828         bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
3829         bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
3830         ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3831         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSize");
3832         return;
3833     }
3834     if (jsVal->IsNumber()) {
3835         auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
3836         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3837             (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
3838             sizeType = BackgroundImageSizeType::AUTO;
3839         }
3840         bgImgSize.SetSizeTypeX(sizeType);
3841         bgImgSize.SetSizeTypeY(sizeType);
3842         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSize");
3843     } else {
3844         CalcDimension width;
3845         CalcDimension height;
3846         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3847         RefPtr<ResourceObject> resObjWidth;
3848         RefPtr<ResourceObject> resObjHeight;
3849         ParseJsDimensionVp(object->GetProperty("width"), width, resObjWidth);
3850         ParseJsDimensionVp(object->GetProperty("height"), height, resObjHeight);
3851         ViewAbstractModel::GetInstance()->SetBackgroundImageSizeUpdateFunc(bgImgSize, resObjWidth, "width");
3852         ViewAbstractModel::GetInstance()->SetBackgroundImageSizeUpdateFunc(bgImgSize, resObjHeight, "height");
3853         double valueWidth = width.ConvertToPx();
3854         double valueHeight = height.ConvertToPx();
3855         BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
3856         BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
3857         if (width.Unit() == DimensionUnit::PERCENT) {
3858             typeWidth = BackgroundImageSizeType::PERCENT;
3859             valueWidth = width.Value() * FULL_DIMENSION;
3860         }
3861         if (height.Unit() == DimensionUnit::PERCENT) {
3862             typeHeight = BackgroundImageSizeType::PERCENT;
3863             valueHeight = height.Value() * FULL_DIMENSION;
3864         }
3865         bgImgSize.SetSizeTypeX(typeWidth);
3866         bgImgSize.SetSizeValueX(valueWidth);
3867         bgImgSize.SetSizeTypeY(typeHeight);
3868         bgImgSize.SetSizeValueY(valueHeight);
3869     }
3870 
3871     ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3872 }
3873 
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3874 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
3875 {
3876     if (align > 8 || align < 0) { // align ranges from [0, 8].
3877         return;
3878     }
3879     std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
3880         { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
3881         { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
3882     SetBgImgPosition(
3883         DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
3884 }
3885 
SetBackgroundImagePositionUpdateFunc(BackgroundImagePosition & bgImgPosition,const RefPtr<ResourceObject> & resObj,const std::string direction)3886 void SetBackgroundImagePositionUpdateFunc(
3887     BackgroundImagePosition& bgImgPosition, const RefPtr<ResourceObject>& resObj, const std::string direction)
3888 {
3889     if (direction.empty()) {
3890         return;
3891     }
3892     if (!resObj) {
3893         (direction == "x") ? bgImgPosition.RemoveResource("backgroundImagePositionX")
3894                         : bgImgPosition.RemoveResource("backgroundImagePositionY");
3895         return;
3896     }
3897     auto&& updateFunc = [direction](const RefPtr<ResourceObject>& resObj, BackgroundImagePosition& position) {
3898         CalcDimension dimension;
3899         ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
3900         double value = dimension.Value();
3901         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3902             value = dimension.ConvertToPx();
3903         }
3904         DimensionUnit type = DimensionUnit::PX;
3905         if (dimension.Unit() == DimensionUnit::PERCENT) {
3906             value = dimension.Value();
3907             type = DimensionUnit::PERCENT;
3908         }
3909         AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
3910         (direction == "x") ? position.SetSizeX(AnimatableDimension(value, type, option))
3911                         : position.SetSizeY(AnimatableDimension(value, type, option));
3912     };
3913     (direction == "x") ? bgImgPosition.AddResource("backgroundImagePositionX", resObj, std::move(updateFunc))
3914                     : bgImgPosition.AddResource("backgroundImagePositionY", resObj, std::move(updateFunc));
3915 }
3916 
JsBackgroundImagePosition(const JSCallbackInfo & info)3917 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
3918 {
3919     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3920     BackgroundImagePosition bgImgPosition;
3921     auto jsVal = info[0];
3922     if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
3923         SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
3924         ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3925         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImagePosition");
3926         return;
3927     }
3928     if (jsVal->IsNumber()) {
3929         int32_t align = jsVal->ToNumber<int32_t>();
3930         bgImgPosition.SetIsAlign(true);
3931         SetBgImgPositionWithAlign(bgImgPosition, align);
3932         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImagePosition");
3933     } else {
3934         CalcDimension x;
3935         CalcDimension y;
3936         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3937         RefPtr<ResourceObject> resObjX;
3938         RefPtr<ResourceObject> resObjY;
3939         ParseJsDimensionVp(object->GetProperty("x"), x, resObjX);
3940         ParseJsDimensionVp(object->GetProperty("y"), y, resObjY);
3941         SetBackgroundImagePositionUpdateFunc(bgImgPosition, resObjX, "x");
3942         SetBackgroundImagePositionUpdateFunc(bgImgPosition, resObjY, "y");
3943         double valueX = x.Value();
3944         double valueY = y.Value();
3945         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3946             valueX = x.ConvertToPx();
3947             valueY = y.ConvertToPx();
3948         }
3949         DimensionUnit typeX = DimensionUnit::PX;
3950         DimensionUnit typeY = DimensionUnit::PX;
3951         if (x.Unit() == DimensionUnit::PERCENT) {
3952             valueX = x.Value();
3953             typeX = DimensionUnit::PERCENT;
3954         }
3955         if (y.Unit() == DimensionUnit::PERCENT) {
3956             valueY = y.Value();
3957             typeY = DimensionUnit::PERCENT;
3958         }
3959         SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
3960     }
3961 
3962     ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3963 }
3964 
JsPadding(const JSCallbackInfo & info)3965 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
3966 {
3967     ParseMarginOrPadding(info, EdgeType::PADDING);
3968 }
3969 
JsMargin(const JSCallbackInfo & info)3970 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
3971 {
3972     ParseMarginOrPadding(info, EdgeType::MARGIN);
3973 }
3974 
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)3975 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
3976 {
3977     ViewAbstractModel::GetInstance()->ResetResObj("margin");
3978     ViewAbstractModel::GetInstance()->ResetResObj("padding");
3979     ViewAbstractModel::GetInstance()->ResetResObj("safeAreaPadding");
3980     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3981         JSCallbackInfoType::NUMBER };
3982     auto jsVal = info[0];
3983     if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
3984         auto resetDimension = CalcDimension(0.0);
3985         if (type == EdgeType::MARGIN) {
3986             ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
3987         } else if (type == EdgeType::PADDING) {
3988             ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
3989         } else if (type == EdgeType::SAFE_AREA_PADDING) {
3990             ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
3991         }
3992         return;
3993     }
3994 
3995     if (jsVal->IsObject()) {
3996         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
3997 
3998         CalcDimension length;
3999         if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
4000             ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
4001             return;
4002         }
4003 
4004         CommonCalcDimension commonCalcDimension;
4005         auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
4006         if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
4007             commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
4008             if (type == EdgeType::MARGIN) {
4009                 if (useLengthMetrics) {
4010                     ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
4011                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
4012                 } else {
4013                     if (SystemProperties::ConfigChangePerform()) {
4014                         ViewAbstractModel::GetInstance()->SetMargins(GetEdgeMargins(commonCalcDimension));
4015                     } else {
4016                         ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
4017                             commonCalcDimension.left, commonCalcDimension.right);
4018                     }
4019                 }
4020             } else if (type == EdgeType::PADDING) {
4021                 if (useLengthMetrics) {
4022                     ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
4023                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
4024                 } else {
4025                     if (SystemProperties::ConfigChangePerform()) {
4026                         ViewAbstractModel::GetInstance()->SetPaddings(
4027                             GetEdgePaddingsOrSafeAreaPaddings(commonCalcDimension));
4028                     } else {
4029                         ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top,
4030                             commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
4031                     }
4032                 }
4033             } else if (type == EdgeType::SAFE_AREA_PADDING) {
4034                 if (useLengthMetrics) {
4035                     ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
4036                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
4037                 } else {
4038                     if (SystemProperties::ConfigChangePerform()) {
4039                         ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(
4040                             GetEdgePaddingsOrSafeAreaPaddings(commonCalcDimension));
4041                     } else {
4042                         ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
4043                             commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
4044                     }
4045                 }
4046             }
4047             return;
4048         }
4049     }
4050 
4051     CalcDimension length;
4052     RefPtr<ResourceObject> lengthResObj;
4053     if (!ParseJsDimensionVp(jsVal, length, lengthResObj)) {
4054         // use default value.
4055         length.Reset();
4056     }
4057     if (type == EdgeType::MARGIN) {
4058         if (SystemProperties::ConfigChangePerform() && lengthResObj) {
4059             ViewAbstractModel::GetInstance()->SetMargin(lengthResObj);
4060         } else {
4061             ViewAbstractModel::GetInstance()->SetMargin(length);
4062         }
4063     } else if (type == EdgeType::PADDING) {
4064         if (SystemProperties::ConfigChangePerform() && lengthResObj) {
4065             ViewAbstractModel::GetInstance()->SetPadding(lengthResObj);
4066         } else {
4067             ViewAbstractModel::GetInstance()->SetPadding(length);
4068         }
4069     }
4070 }
4071 
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)4072 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
4073     const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
4074     const std::optional<CalcDimension>& end)
4075 {
4076     NG::PaddingProperty paddings;
4077     if (start.has_value()) {
4078         if (start.value().Unit() == DimensionUnit::CALC) {
4079             paddings.start = NG::CalcLength(start.value().CalcValue());
4080         } else {
4081             paddings.start = NG::CalcLength(start.value());
4082         }
4083     }
4084     if (bottom.has_value()) {
4085         if (bottom.value().Unit() == DimensionUnit::CALC) {
4086             paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
4087         } else {
4088             paddings.bottom = NG::CalcLength(bottom.value());
4089         }
4090     }
4091     if (end.has_value()) {
4092         if (end.value().Unit() == DimensionUnit::CALC) {
4093             paddings.end = NG::CalcLength(end.value().CalcValue());
4094         } else {
4095             paddings.end = NG::CalcLength(end.value());
4096         }
4097     }
4098     if (top.has_value()) {
4099         if (top.value().Unit() == DimensionUnit::CALC) {
4100             paddings.top = NG::CalcLength(top.value().CalcValue());
4101         } else {
4102             paddings.top = NG::CalcLength(top.value());
4103         }
4104     }
4105     return paddings;
4106 }
4107 
GetEdgeMargins(const CommonCalcDimension & commonCalcDimension)4108 NG::MarginProperty JSViewAbstract::GetEdgeMargins(const CommonCalcDimension& commonCalcDimension)
4109 {
4110     NG::MarginProperty margins;
4111     if (commonCalcDimension.top.has_value()) {
4112         if (commonCalcDimension.top.value().Unit() == DimensionUnit::CALC) {
4113             margins.top = NG::CalcLength(commonCalcDimension.top.value().CalcValue());
4114         } else {
4115             margins.top = NG::CalcLength(commonCalcDimension.top.value());
4116         }
4117     }
4118     if (commonCalcDimension.bottom.has_value()) {
4119         if (commonCalcDimension.bottom.value().Unit() == DimensionUnit::CALC) {
4120             margins.bottom = NG::CalcLength(commonCalcDimension.bottom.value().CalcValue());
4121         } else {
4122             margins.bottom = NG::CalcLength(commonCalcDimension.bottom.value());
4123         }
4124     }
4125     if (commonCalcDimension.left.has_value()) {
4126         if (commonCalcDimension.left.value().Unit() == DimensionUnit::CALC) {
4127             margins.left = NG::CalcLength(commonCalcDimension.left.value().CalcValue());
4128         } else {
4129             margins.left = NG::CalcLength(commonCalcDimension.left.value());
4130         }
4131     }
4132     if (commonCalcDimension.right.has_value()) {
4133         if (commonCalcDimension.right.value().Unit() == DimensionUnit::CALC) {
4134             margins.right = NG::CalcLength(commonCalcDimension.right.value().CalcValue());
4135         } else {
4136             margins.right = NG::CalcLength(commonCalcDimension.right.value());
4137         }
4138     }
4139     GetEdgeMarginsResObj(margins, commonCalcDimension);
4140     return margins;
4141 }
4142 
GetEdgeMarginsResObj(NG::MarginProperty & margins,const CommonCalcDimension & commonCalcDimension)4143 void JSViewAbstract::GetEdgeMarginsResObj(NG::MarginProperty& margins, const CommonCalcDimension& commonCalcDimension)
4144 {
4145     if (!SystemProperties::ConfigChangePerform()) {
4146         return;
4147     }
4148     margins.resMap_.clear();
4149     if (commonCalcDimension.topResObj) {
4150         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4151             CalcDimension result;
4152             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4153             NG::CalcLength resultLength;
4154             resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4155                 NG::CalcLength(result);
4156             margins.top = resultLength;
4157         };
4158         margins.AddResource("margin.top", commonCalcDimension.topResObj, std::move(updateFunc));
4159     }
4160     if (commonCalcDimension.bottomResObj) {
4161         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4162             CalcDimension result;
4163             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4164             NG::CalcLength resultLength;
4165             resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4166                 NG::CalcLength(result);
4167             margins.bottom = resultLength;
4168         };
4169         margins.AddResource("margin.bottom", commonCalcDimension.bottomResObj, std::move(updateFunc));
4170     }
4171     if (commonCalcDimension.leftResObj) {
4172         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4173             CalcDimension result;
4174             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4175             NG::CalcLength resultLength;
4176             resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4177                 NG::CalcLength(result);
4178             margins.left = resultLength;
4179         };
4180         margins.AddResource("margin.left", commonCalcDimension.leftResObj, std::move(updateFunc));
4181     }
4182     if (commonCalcDimension.rightResObj) {
4183         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4184             CalcDimension result;
4185             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4186             NG::CalcLength resultLength;
4187             resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4188                 NG::CalcLength(result);
4189             margins.right = resultLength;
4190         };
4191         margins.AddResource("margin.right", commonCalcDimension.rightResObj, std::move(updateFunc));
4192     }
4193 }
4194 
GetEdgePaddingsOrSafeAreaPaddings(const CommonCalcDimension & commonCalcDimension)4195 NG::PaddingProperty JSViewAbstract::GetEdgePaddingsOrSafeAreaPaddings(const CommonCalcDimension& commonCalcDimension)
4196 {
4197     NG::PaddingProperty paddings = NG::ConvertToCalcPaddingProperty(
4198         commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
4199     if (!SystemProperties::ConfigChangePerform()) {
4200         return paddings;
4201     }
4202     if (commonCalcDimension.topResObj) {
4203         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4204             CalcDimension result;
4205             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4206             NG::CalcLength resultLength = ConvertCalcLength(result);
4207             paddings.top = resultLength;
4208         };
4209         paddings.AddResource("top", commonCalcDimension.topResObj, std::move(updateFunc));
4210     }
4211     if (commonCalcDimension.bottomResObj) {
4212         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4213             CalcDimension result;
4214             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4215             NG::CalcLength resultLength = ConvertCalcLength(result);
4216             paddings.bottom = resultLength;
4217         };
4218         paddings.AddResource("bottom", commonCalcDimension.bottomResObj, std::move(updateFunc));
4219     }
4220     if (commonCalcDimension.leftResObj) {
4221         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4222             CalcDimension result;
4223             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4224             NG::CalcLength resultLength = ConvertCalcLength(result);
4225             paddings.left = resultLength;
4226         };
4227         paddings.AddResource("left", commonCalcDimension.leftResObj, std::move(updateFunc));
4228     }
4229     if (commonCalcDimension.rightResObj) {
4230         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4231             CalcDimension result;
4232             ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4233             NG::CalcLength resultLength = ConvertCalcLength(result);
4234             paddings.right = resultLength;
4235         };
4236         paddings.AddResource("right", commonCalcDimension.rightResObj, std::move(updateFunc));
4237     }
4238     return paddings;
4239 }
4240 
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)4241 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
4242     std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
4243 {
4244     CalcDimension leftDimen;
4245     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
4246         left = leftDimen;
4247     }
4248     CalcDimension rightDimen;
4249     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
4250         right = rightDimen;
4251     }
4252     CalcDimension topDimen;
4253     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
4254         top = topDimen;
4255     }
4256     CalcDimension bottomDimen;
4257     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
4258         bottom = bottomDimen;
4259     }
4260 }
4261 
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,CommonCalcDimension & commonCalcDimension)4262 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, CommonCalcDimension& commonCalcDimension)
4263 {
4264     CalcDimension leftDimen;
4265     RefPtr<ResourceObject> leftResObj;
4266     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen, leftResObj)) {
4267         commonCalcDimension.left = leftDimen;
4268     }
4269     CalcDimension rightDimen;
4270     RefPtr<ResourceObject> rightResObj;
4271     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen, rightResObj)) {
4272         commonCalcDimension.right = rightDimen;
4273     }
4274     CalcDimension topDimen;
4275     RefPtr<ResourceObject> topResObj;
4276     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen, topResObj)) {
4277         commonCalcDimension.top = topDimen;
4278     }
4279     CalcDimension bottomDimen;
4280     RefPtr<ResourceObject> bottomResObj;
4281     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen, bottomResObj)) {
4282         commonCalcDimension.bottom = bottomDimen;
4283     }
4284     if (!SystemProperties::ConfigChangePerform()) {
4285         return;
4286     }
4287     if (leftResObj) {
4288         commonCalcDimension.leftResObj = leftResObj;
4289     }
4290     if (rightResObj) {
4291         commonCalcDimension.rightResObj = rightResObj;
4292     }
4293     if (topResObj) {
4294         commonCalcDimension.topResObj = topResObj;
4295     }
4296     if (bottomResObj) {
4297         commonCalcDimension.bottomResObj = bottomResObj;
4298     }
4299 }
4300 
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4301 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
4302     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4303 {
4304     auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
4305     if (jsStart->IsObject()) {
4306         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
4307         CalcDimension calcDimension;
4308         if (ParseJsLengthMetrics(startObj, calcDimension)) {
4309             localizedCalcDimension.start = calcDimension;
4310         }
4311     }
4312     auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
4313     if (jsEnd->IsObject()) {
4314         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
4315         CalcDimension calcDimension;
4316         if (ParseJsLengthMetrics(endObj, calcDimension)) {
4317             localizedCalcDimension.end = calcDimension;
4318         }
4319     }
4320     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
4321     if (jsTop->IsObject()) {
4322         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
4323         CalcDimension calcDimension;
4324         if (ParseJsLengthMetrics(topObj, calcDimension)) {
4325             localizedCalcDimension.top = calcDimension;
4326         }
4327     }
4328     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
4329     if (jsBottom->IsObject()) {
4330         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
4331         CalcDimension calcDimension;
4332         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
4333             localizedCalcDimension.bottom = calcDimension;
4334         }
4335     }
4336 }
4337 
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)4338 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
4339     const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
4340 {
4341     if (CheckLengthMetrics(object)) {
4342         LocalizedCalcDimension localizedCalcDimension;
4343         ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
4344         commonCalcDimension.top = localizedCalcDimension.top;
4345         commonCalcDimension.bottom = localizedCalcDimension.bottom;
4346         commonCalcDimension.left = localizedCalcDimension.start;
4347         commonCalcDimension.right = localizedCalcDimension.end;
4348         return true;
4349     }
4350     if (SystemProperties::ConfigChangePerform()) {
4351         ParseMarginOrPaddingCorner(object, commonCalcDimension);
4352     } else {
4353         ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
4354             commonCalcDimension.right);
4355     }
4356         return false;
4357 }
4358 
JsOutline(const JSCallbackInfo & info)4359 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
4360 {
4361     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidthRes");
4362     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColorRes");
4363     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadiusRes");
4364     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidth");
4365     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColor");
4366     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadius");
4367     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4368     auto jsVal = info[0];
4369     if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
4370         CalcDimension borderWidth;
4371         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4372         ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
4373         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
4374         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
4375         return;
4376     }
4377     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4378     auto valueOuterWidth = object->GetProperty("width");
4379     if (!valueOuterWidth->IsUndefined()) {
4380         ParseOuterBorderWidth(valueOuterWidth);
4381     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4382         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
4383     }
4384 
4385     // use default value when undefined.
4386     ParseOuterBorderColor(object->GetProperty("color"));
4387 
4388     auto valueOuterRadius = object->GetProperty("radius");
4389     if (!valueOuterRadius->IsUndefined()) {
4390         ParseOuterBorderRadius(valueOuterRadius);
4391     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4392         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
4393     }
4394     // use default value when undefined.
4395     ParseOuterBorderStyle(object->GetProperty("style"));
4396     info.ReturnSelf();
4397 }
4398 
JsOutlineWidth(const JSCallbackInfo & info)4399 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
4400 {
4401     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidth");
4402     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidthRes");
4403     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4404         JSCallbackInfoType::OBJECT };
4405     auto jsVal = info[0];
4406     if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
4407         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
4408         return;
4409     }
4410     ParseOuterBorderWidth(jsVal);
4411 }
4412 
JsOutlineColor(const JSCallbackInfo & info)4413 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
4414 {
4415     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColorRes");
4416     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColor");
4417     ParseOuterBorderColor(info[0]);
4418 }
4419 
JsOutlineRadius(const JSCallbackInfo & info)4420 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
4421 {
4422     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadius");
4423     ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadiusRes");
4424     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4425         JSCallbackInfoType::OBJECT };
4426     auto jsVal = info[0];
4427     if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
4428         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
4429         return;
4430     }
4431     ParseOuterBorderRadius(jsVal);
4432 }
4433 
JsOutlineStyle(const JSCallbackInfo & info)4434 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
4435 {
4436     ParseOuterBorderStyle(info[0]);
4437 }
4438 
JsBorder(const JSCallbackInfo & info)4439 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
4440 {
4441     ViewAbstractModel::GetInstance()->ResetResObj("borderWidth");
4442     ViewAbstractModel::GetInstance()->ResetResObj("borderColor");
4443     ViewAbstractModel::GetInstance()->ResetResObj("borderRadius");
4444     ViewAbstractModel::GetInstance()->ResetResObj("border.dashGap");
4445     ViewAbstractModel::GetInstance()->ResetResObj("border.dashWidth");
4446     if (!info[0]->IsObject()) {
4447         CalcDimension borderWidth;
4448         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4449         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4450         ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
4451         ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4452         ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
4453         ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
4454         return;
4455     }
4456     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
4457 
4458     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4459     if (!valueWidth->IsUndefined()) {
4460         ParseBorderWidth(valueWidth);
4461     }
4462 
4463     // use default value when undefined.
4464     ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
4465 
4466     auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
4467     if (!valueRadius->IsUndefined()) {
4468         ParseBorderRadius(valueRadius);
4469     }
4470     // use default value when undefined.
4471     ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
4472 
4473     auto dashGap = object->GetProperty("dashGap");
4474     if (!dashGap->IsUndefined()) {
4475         ParseDashGap(dashGap);
4476     }
4477     auto dashWidth = object->GetProperty("dashWidth");
4478     if (!dashWidth->IsUndefined()) {
4479         ParseDashWidth(dashWidth);
4480     }
4481 
4482     info.ReturnSelf();
4483 }
4484 
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)4485 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
4486 {
4487     if (!args->IsObject()) {
4488         return false;
4489     }
4490     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4491     if (obj->IsUndefined()) {
4492         return true;
4493     }
4494     // filter dynamic $r raw input
4495     if (obj->HasProperty("id")) {
4496         return false;
4497     }
4498     if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
4499         (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
4500         (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
4501         (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
4502         (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
4503         (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
4504         return true;
4505     }
4506 
4507     return false;
4508 }
4509 
JsBorderWidth(const JSCallbackInfo & info)4510 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
4511 {
4512     ViewAbstractModel::GetInstance()->ResetResObj("borderWidth");
4513     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4514         JSCallbackInfoType::OBJECT };
4515     auto jsVal = info[0];
4516     if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
4517         CalcDimension value = {};
4518         ViewAbstractModel::GetInstance()->SetBorderWidth(value);
4519         return;
4520     }
4521 
4522     ParseBorderWidth(jsVal);
4523 }
4524 
ParseBorderWidth(const JSRef<JSVal> & args)4525 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
4526 {
4527     CalcDimension borderWidth;
4528     RefPtr<ResourceObject> borderWidthResObj;
4529     if (ParseJsDimensionVp(args, borderWidth, borderWidthResObj)) {
4530         if (borderWidth.IsNegative()) {
4531             borderWidth.Reset();
4532         }
4533         if (borderWidth.Unit() == DimensionUnit::PERCENT) {
4534             borderWidth.Reset();
4535         }
4536         if (SystemProperties::ConfigChangePerform() && borderWidthResObj) {
4537             ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidthResObj);
4538         } else {
4539             ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4540         }
4541     } else if (args->IsObject()) {
4542         if (IsBorderWidthObjUndefined(args)) {
4543             CalcDimension value = {};
4544             ViewAbstractModel::GetInstance()->SetBorderWidth(value);
4545             return;
4546         }
4547         CommonCalcDimension commonCalcDimension;
4548         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4549         if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
4550             ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
4551                 commonCalcDimension.top, commonCalcDimension.bottom, true);
4552             return;
4553         }
4554         if (SystemProperties::ConfigChangePerform()) {
4555             NG::BorderWidthProperty borderWidth;
4556             ParseEdgeWidthsResObj(obj, borderWidth, true);
4557             ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4558         } else {
4559             ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left,
4560                 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4561         }
4562     } else {
4563         return;
4564     }
4565 }
4566 
ParseDashGap(const JSRef<JSVal> & args)4567 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
4568 {
4569     CalcDimension dashGap;
4570     if (ParseLengthMetricsToDimension(args, dashGap)) {
4571         if (dashGap.Unit() == DimensionUnit::PERCENT) {
4572             dashGap.Reset();
4573         }
4574         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4575     } else if (args->IsObject()) {
4576         CommonCalcDimension commonCalcDimension;
4577         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4578         if (ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension)) {
4579             ViewAbstractModel::GetInstance()->SetDashGap(commonCalcDimension.left,
4580                 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4581             return;
4582         }
4583         if (SystemProperties::ConfigChangePerform()) {
4584             NG::BorderWidthProperty dashGap;
4585             ParseEdgeWidthsForDashParamsResObj(obj, dashGap, static_cast<CalcDimension>(-1));
4586             ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4587         } else {
4588             ViewAbstractModel::GetInstance()->SetDashGap(commonCalcDimension.left,
4589                 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4590         }
4591     } else {
4592         dashGap.Reset();
4593         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4594     }
4595 }
4596 
ParseDashWidth(const JSRef<JSVal> & args)4597 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
4598 {
4599     CalcDimension dashWidth;
4600     if (ParseLengthMetricsToDimension(args, dashWidth)) {
4601         if (dashWidth.Unit() == DimensionUnit::PERCENT) {
4602             dashWidth.Reset();
4603         }
4604         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4605     } else if (args->IsObject()) {
4606         CommonCalcDimension commonCalcDimension;
4607         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4608         if (ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension)) {
4609             ViewAbstractModel::GetInstance()->SetDashWidth(commonCalcDimension.left,
4610                 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4611             return;
4612         }
4613         if (SystemProperties::ConfigChangePerform()) {
4614             NG::BorderWidthProperty dashWidth;
4615             ParseEdgeWidthsForDashParamsResObj(obj, dashWidth, static_cast<CalcDimension>(-1));
4616             ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4617         } else {
4618             ViewAbstractModel::GetInstance()->SetDashWidth(commonCalcDimension.left,
4619                 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4620         }
4621     } else {
4622         dashWidth.Reset();
4623         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4624     }
4625 }
4626 
ParseEdgeOutlineWidthLeft(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4627 void JSViewAbstract::ParseEdgeOutlineWidthLeft(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4628 {
4629     if (object->IsUndefined()) {
4630         return;
4631     }
4632     RefPtr<ResourceObject> resObj;
4633     CalcDimension calcDim;
4634     bool ret = ParseJsDimensionVp(object->GetProperty("left"), calcDim, resObj);
4635     if (ret && calcDim.IsNonNegative()) {
4636         if (calcDim.Unit() == DimensionUnit::PERCENT) {
4637             calcDim.Reset();
4638         }
4639         borderWidth.leftDimen = calcDim;
4640     }
4641     if (resObj) {
4642         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4643             CalcDimension dimension;
4644             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4645             borderWidth.leftDimen = dimension;
4646         };
4647         borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.left", resObj, std::move(updateFunc));
4648     }
4649 }
4650 
ParseEdgeOutlineWidthRight(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4651 void JSViewAbstract::ParseEdgeOutlineWidthRight(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4652 {
4653     if (object->IsUndefined()) {
4654         return;
4655     }
4656     RefPtr<ResourceObject> resObj;
4657     CalcDimension calcDim;
4658     bool ret = ParseJsDimensionVp(object->GetProperty("right"), calcDim, resObj);
4659     if (ret && calcDim.IsNonNegative()) {
4660         if (calcDim.Unit() == DimensionUnit::PERCENT) {
4661             calcDim.Reset();
4662         }
4663         borderWidth.rightDimen = calcDim;
4664     }
4665     if (resObj) {
4666         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4667             CalcDimension dimension;
4668             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4669             borderWidth.rightDimen = dimension;
4670         };
4671         borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.right", resObj, std::move(updateFunc));
4672     }
4673 }
4674 
ParseEdgeOutlineWidthTop(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4675 void JSViewAbstract::ParseEdgeOutlineWidthTop(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4676 {
4677     if (object->IsUndefined()) {
4678         return;
4679     }
4680     RefPtr<ResourceObject> resObj;
4681     CalcDimension calcDim;
4682     bool ret = ParseJsDimensionVp(object->GetProperty("top"), calcDim, resObj);
4683     if (ret && calcDim.IsNonNegative()) {
4684         if (calcDim.Unit() == DimensionUnit::PERCENT) {
4685             calcDim.Reset();
4686         }
4687         borderWidth.topDimen = calcDim;
4688     }
4689     if (resObj) {
4690         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4691             CalcDimension dimension;
4692             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4693             borderWidth.topDimen = dimension;
4694         };
4695         borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.top", resObj, std::move(updateFunc));
4696     }
4697 }
4698 
ParseEdgeOutlineWidthBottom(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4699 void JSViewAbstract::ParseEdgeOutlineWidthBottom(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4700 {
4701     if (object->IsUndefined()) {
4702         return;
4703     }
4704     RefPtr<ResourceObject> resObj;
4705     CalcDimension calcDim;
4706     bool ret = ParseJsDimensionVp(object->GetProperty("bottom"), calcDim, resObj);
4707     if (ret && calcDim.IsNonNegative()) {
4708         if (calcDim.Unit() == DimensionUnit::PERCENT) {
4709             calcDim.Reset();
4710         }
4711         borderWidth.bottomDimen = calcDim;
4712     }
4713     if (resObj) {
4714         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4715             CalcDimension dimension;
4716             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4717             borderWidth.bottomDimen = dimension;
4718         };
4719         borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.bottom", resObj, std::move(updateFunc));
4720     }
4721 }
4722 
ParseOuterBorderWidthNew(const JSRef<JSVal> & args)4723 void JSViewAbstract::ParseOuterBorderWidthNew(const JSRef<JSVal>& args)
4724 {
4725     CalcDimension borderWidth;
4726     RefPtr<ResourceObject> borderResObj;
4727     bool ret = ParseJsDimensionVp(args, borderWidth, borderResObj);
4728     if (borderResObj) {
4729         // Dimension
4730         ViewAbstractModel::GetInstance()->CreateWithOuterBorderWidthResourceObj(borderResObj);
4731     } else if (ret) {
4732         if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4733             borderWidth.Reset();
4734         }
4735         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4736     } else if (args->IsObject()) {
4737         // obj
4738         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4739         NG::BorderWidthProperty borderWidthProperty;
4740         borderWidthProperty.multiValued = true;
4741         borderWidthProperty.resMap_.clear();
4742         ParseEdgeOutlineWidthLeft(object, borderWidthProperty);
4743         ParseEdgeOutlineWidthRight(object, borderWidthProperty);
4744         ParseEdgeOutlineWidthTop(object, borderWidthProperty);
4745         ParseEdgeOutlineWidthBottom(object, borderWidthProperty);
4746         ViewAbstractModel::GetInstance()->SetOuterBorderWidthNew(borderWidthProperty);
4747     } else {
4748         return;
4749     }
4750 }
4751 
ParseOuterBorderWidth(const JSRef<JSVal> & args)4752 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
4753 {
4754     if (SystemProperties::ConfigChangePerform()) {
4755         ParseOuterBorderWidthNew(args);
4756         return;
4757     }
4758     CalcDimension borderWidth;
4759     if (ParseJsDimensionVp(args, borderWidth)) {
4760         if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4761             borderWidth.Reset();
4762         }
4763         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4764     } else if (args->IsObject()) {
4765         std::optional<CalcDimension> leftDimen;
4766         std::optional<CalcDimension> rightDimen;
4767         std::optional<CalcDimension> topDimen;
4768         std::optional<CalcDimension> bottomDimen;
4769         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4770         CalcDimension left;
4771         if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
4772             if (left.Unit() == DimensionUnit::PERCENT) {
4773                 left.Reset();
4774             }
4775             leftDimen = left;
4776         }
4777         CalcDimension right;
4778         if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
4779             if (right.Unit() == DimensionUnit::PERCENT) {
4780                 right.Reset();
4781             }
4782             rightDimen = right;
4783         }
4784         CalcDimension top;
4785         if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
4786             if (top.Unit() == DimensionUnit::PERCENT) {
4787                 top.Reset();
4788             }
4789             topDimen = top;
4790         }
4791         CalcDimension bottom;
4792         if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
4793             if (bottom.Unit() == DimensionUnit::PERCENT) {
4794                 bottom.Reset();
4795             }
4796             bottomDimen = bottom;
4797         }
4798         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
4799     } else {
4800         return;
4801     }
4802 }
4803 
JsBorderImage(const JSCallbackInfo & info)4804 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
4805 {
4806     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4807     auto jsVal = info[0];
4808     if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
4809         RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4810         uint8_t imageBorderBitsets = 0;
4811         ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4812         return;
4813     }
4814     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4815     CHECK_NULL_VOID(!object->IsEmpty());
4816 
4817     RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4818     uint8_t imageBorderBitsets = 0;
4819 
4820     auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
4821     CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
4822     std::string srcResult;
4823     std::string bundleName;
4824     std::string moduleName;
4825     GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
4826     borderImage->SetBundleName(bundleName);
4827     borderImage->SetModuleName(moduleName);
4828     if (valueSource->IsString() && !valueSource->ToString().empty()) {
4829         borderImage->SetSrc(valueSource->ToString());
4830         imageBorderBitsets |= BorderImage::SOURCE_BIT;
4831     } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
4832         borderImage->SetSrc(srcResult);
4833         imageBorderBitsets |= BorderImage::SOURCE_BIT;
4834     } else if (valueSource->IsObject()) {
4835         ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
4836     }
4837     auto valueOutset = object->GetProperty("outset");
4838     if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
4839         imageBorderBitsets |= BorderImage::OUTSET_BIT;
4840         ParseBorderImageOutset(valueOutset, borderImage);
4841     }
4842     auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
4843     if (!valueRepeat->IsNull()) {
4844         imageBorderBitsets |= BorderImage::REPEAT_BIT;
4845         ParseBorderImageRepeat(valueRepeat, borderImage);
4846     }
4847     auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
4848     if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
4849         imageBorderBitsets |= BorderImage::SLICE_BIT;
4850         ParseBorderImageSlice(valueSlice, borderImage);
4851     }
4852     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4853     if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
4854         imageBorderBitsets |= BorderImage::WIDTH_BIT;
4855         ParseBorderImageWidth(valueWidth, borderImage);
4856     }
4857     auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
4858     if (needFill->IsBoolean()) {
4859         borderImage->SetNeedFillCenter(needFill->ToBoolean());
4860     }
4861     ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4862     info.ReturnSelf();
4863 }
4864 
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4865 bool JSViewAbstract::ParseBorderImageDimension(
4866     const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
4867 {
4868     if (!args->IsObject()) {
4869         return false;
4870     }
4871     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4872     if (CheckLengthMetrics(object)) {
4873         LocalizedCalcDimension localizedCalcDimension;
4874         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4875         borderImageDimension.topDimension = localizedCalcDimension.top;
4876         borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
4877         borderImageDimension.startDimension = localizedCalcDimension.start;
4878         borderImageDimension.endDimension = localizedCalcDimension.end;
4879         return true;
4880     }
4881     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4882         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4883         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4884     for (uint32_t i = 0; i < keys.size(); i++) {
4885         CalcDimension currentDimension;
4886         auto dimensionValue = object->GetProperty(keys.at(i));
4887         if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
4888             auto direction = static_cast<BorderImageDirection>(i);
4889             switch (direction) {
4890                 case BorderImageDirection::LEFT:
4891                     borderImageDimension.leftDimension = currentDimension;
4892                     break;
4893                 case BorderImageDirection::RIGHT:
4894                     borderImageDimension.rightDimension = currentDimension;
4895                     break;
4896                 case BorderImageDirection::TOP:
4897                     borderImageDimension.topDimension = currentDimension;
4898                     break;
4899                 case BorderImageDirection::BOTTOM:
4900                     borderImageDimension.bottomDimension = currentDimension;
4901                     break;
4902                 default:
4903                     break;
4904             }
4905         }
4906     }
4907     return false;
4908 }
4909 
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4910 void JSViewAbstract::ParseBorderImageLengthMetrics(
4911     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4912 {
4913     for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
4914         auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
4915         if (!jsVal->IsObject()) {
4916             continue;
4917         }
4918         JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
4919         CalcDimension calcDimension;
4920         if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
4921             auto direction = static_cast<BorderImageDirection>(i);
4922             switch (direction) {
4923                 case BorderImageDirection::LEFT:
4924                     localizedCalcDimension.start = calcDimension;
4925                     break;
4926                 case BorderImageDirection::RIGHT:
4927                     localizedCalcDimension.end = calcDimension;
4928                     break;
4929                 case BorderImageDirection::TOP:
4930                     localizedCalcDimension.top = calcDimension;
4931                     break;
4932                 case BorderImageDirection::BOTTOM:
4933                     localizedCalcDimension.bottom = calcDimension;
4934                     break;
4935                 default:
4936                     break;
4937             }
4938         }
4939     }
4940 }
4941 
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4942 bool JSViewAbstract::CheckJSCallbackInfo(
4943     const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
4944 {
4945     bool typeVerified = false;
4946     std::string unrecognizedType;
4947     for (const auto& infoType : infoTypes) {
4948         switch (infoType) {
4949             case JSCallbackInfoType::STRING:
4950                 if (tmpInfo->IsString()) {
4951                     typeVerified = true;
4952                 } else {
4953                     unrecognizedType += "string|";
4954                 }
4955                 break;
4956             case JSCallbackInfoType::NUMBER:
4957                 if (tmpInfo->IsNumber()) {
4958                     typeVerified = true;
4959                 } else {
4960                     unrecognizedType += "number|";
4961                 }
4962                 break;
4963             case JSCallbackInfoType::OBJECT:
4964                 if (tmpInfo->IsObject()) {
4965                     typeVerified = true;
4966                 } else {
4967                     unrecognizedType += "object|";
4968                 }
4969                 break;
4970             case JSCallbackInfoType::FUNCTION:
4971                 if (tmpInfo->IsFunction()) {
4972                     typeVerified = true;
4973                 } else {
4974                     unrecognizedType += "Function|";
4975                 }
4976                 break;
4977             default:
4978                 break;
4979         }
4980     }
4981     if (!typeVerified) {
4982         LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
4983             unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
4984     }
4985     return typeVerified || infoTypes.size() == 0;
4986 }
4987 
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4988 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
4989 {
4990     switch (direction) {
4991         case NG::GradientDirection::LEFT:
4992             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4993             break;
4994         case NG::GradientDirection::RIGHT:
4995             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4996             break;
4997         case NG::GradientDirection::TOP:
4998             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4999             break;
5000         case NG::GradientDirection::BOTTOM:
5001             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5002             break;
5003         case NG::GradientDirection::LEFT_TOP:
5004             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5005             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5006             break;
5007         case NG::GradientDirection::LEFT_BOTTOM:
5008             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5009             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5010             break;
5011         case NG::GradientDirection::RIGHT_TOP:
5012             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5013             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5014             break;
5015         case NG::GradientDirection::RIGHT_BOTTOM:
5016             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5017             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5018             break;
5019         case NG::GradientDirection::NONE:
5020         case NG::GradientDirection::START_TO_END:
5021         case NG::GradientDirection::END_TO_START:
5022         default:
5023             break;
5024     }
5025 }
5026 
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)5027 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
5028 {
5029     if (!args->IsObject()) {
5030         return;
5031     }
5032     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
5033     NG::Gradient lineGradient;
5034     lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
5035     // angle
5036     std::optional<float> degree;
5037     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5038         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
5039     } else {
5040         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
5041     }
5042     if (degree) {
5043         lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
5044         degree.reset();
5045     }
5046     // direction
5047     auto direction = static_cast<NG::GradientDirection>(
5048         jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
5049         static_cast<int32_t>(NG::GradientDirection::NONE)));
5050     UpdateGradientWithDirection(lineGradient, direction);
5051     auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
5052     lineGradient.SetRepeat(repeating);
5053     NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
5054     ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
5055     bitset |= BorderImage::GRADIENT_BIT;
5056 }
5057 
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5058 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5059 {
5060     auto repeatString = args->ToString();
5061     if (repeatString == "Repeat") {
5062         borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
5063     } else if (repeatString == "Round") {
5064         borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
5065     } else if (repeatString == "Space") {
5066         borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
5067     } else {
5068         borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
5069     }
5070 }
5071 
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5072 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5073 {
5074     CalcDimension outsetDimension;
5075     if (ParseJsDimensionVp(args, outsetDimension)) {
5076         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
5077         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
5078         borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
5079         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
5080         return;
5081     }
5082     BorderImage::BorderImageOption option;
5083     ParseBorderImageDimension(args, option);
5084     if (option.startDimension.has_value()) {
5085         borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
5086     }
5087     if (option.endDimension.has_value()) {
5088         borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
5089     }
5090     if (option.leftDimension.has_value()) {
5091         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
5092     }
5093     if (option.rightDimension.has_value()) {
5094         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
5095     }
5096     if (option.topDimension.has_value()) {
5097         borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
5098     }
5099     if (option.bottomDimension.has_value()) {
5100         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
5101     }
5102 }
5103 
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5104 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5105 {
5106     CalcDimension sliceDimension;
5107     if (ParseJsDimensionVp(args, sliceDimension)) {
5108         borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
5109         borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
5110         borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
5111         borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
5112         return;
5113     }
5114     if (!args->IsObject()) {
5115         return;
5116     }
5117     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5118     if (CheckLengthMetrics(object)) {
5119         LocalizedCalcDimension localizedCalcDimension;
5120         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
5121         if (localizedCalcDimension.top.has_value()) {
5122             borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
5123         }
5124         if (localizedCalcDimension.bottom.has_value()) {
5125             borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
5126         }
5127         if (localizedCalcDimension.start.has_value()) {
5128             borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
5129         }
5130         if (localizedCalcDimension.end.has_value()) {
5131             borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
5132         }
5133         return;
5134     }
5135     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
5136         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
5137         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
5138     for (uint32_t i = 0; i < keys.size(); i++) {
5139         auto dimensionValue = object->GetProperty(keys.at(i));
5140         if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
5141             borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
5142         }
5143     }
5144 }
5145 
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5146 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5147 {
5148     CalcDimension widthDimension;
5149     if (ParseJsDimensionVp(args, widthDimension)) {
5150         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
5151         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
5152         borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
5153         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
5154         return;
5155     }
5156 
5157     BorderImage::BorderImageOption option;
5158     ParseBorderImageDimension(args, option);
5159     if (option.startDimension.has_value()) {
5160         borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
5161     }
5162     if (option.endDimension.has_value()) {
5163         borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
5164     }
5165     if (option.leftDimension.has_value()) {
5166         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
5167     }
5168     if (option.rightDimension.has_value()) {
5169         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
5170     }
5171     if (option.topDimension.has_value()) {
5172         borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
5173     }
5174     if (option.bottomDimension.has_value()) {
5175         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
5176     }
5177 }
5178 
JsBorderColor(const JSCallbackInfo & info)5179 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
5180 {
5181     ViewAbstractModel::GetInstance()->ResetResObj("borderColor");
5182     ParseBorderColor(info[0]);
5183 }
5184 
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)5185 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
5186     const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
5187     const std::optional<Color>& colorBottom)
5188 {
5189     NG::BorderColorProperty borderColors;
5190     borderColors.startColor = colorStart;
5191     borderColors.endColor = colorEnd;
5192     borderColors.topColor = colorTop;
5193     borderColors.bottomColor = colorBottom;
5194     borderColors.multiValued = true;
5195     return borderColors;
5196 }
5197 
GetLocalizedBorderColor(const CommonColor & commonColor)5198 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const CommonColor& commonColor)
5199 {
5200     NG::BorderColorProperty borderColors;
5201     borderColors.startColor = commonColor.left;
5202     borderColors.endColor = commonColor.right;
5203     borderColors.topColor = commonColor.top;
5204     borderColors.bottomColor = commonColor.bottom;
5205     if (!SystemProperties::ConfigChangePerform()) {
5206         return borderColors;
5207     }
5208     if (commonColor.leftResObj) {
5209         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5210             Color result;
5211             ResourceParseUtils::ParseResColor(resObj, result);
5212             borderColors.startColor = result;
5213         };
5214         borderColors.AddResource("borderColor.start", commonColor.leftResObj, std::move(updateFunc));
5215     }
5216     if (commonColor.rightResObj) {
5217         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5218             Color result;
5219             ResourceParseUtils::ParseResColor(resObj, result);
5220             borderColors.endColor = result;
5221         };
5222         borderColors.AddResource("borderColor.end", commonColor.rightResObj, std::move(updateFunc));
5223     }
5224     if (commonColor.topResObj) {
5225         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5226             Color result;
5227             ResourceParseUtils::ParseResColor(resObj, result);
5228             borderColors.topColor = result;
5229         };
5230         borderColors.AddResource("borderColor.top", commonColor.topResObj, std::move(updateFunc));
5231     }
5232     if (commonColor.bottomResObj) {
5233         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5234             Color result;
5235             ResourceParseUtils::ParseResColor(resObj, result);
5236             borderColors.bottomColor = result;
5237         };
5238         borderColors.AddResource("borderColor.bottom", commonColor.bottomResObj, std::move(updateFunc));
5239     }
5240     borderColors.multiValued = true;
5241     return borderColors;
5242 }
5243 
GetBorderColor(const CommonColor & commonColor)5244 NG::BorderColorProperty JSViewAbstract::GetBorderColor(const CommonColor& commonColor)
5245 {
5246     NG::BorderColorProperty borderColors;
5247     borderColors.leftColor = commonColor.left;
5248     borderColors.rightColor = commonColor.right;
5249     borderColors.topColor = commonColor.top;
5250     borderColors.bottomColor = commonColor.bottom;
5251     if (!SystemProperties::ConfigChangePerform()) {
5252         return borderColors;
5253     }
5254     if (commonColor.leftResObj) {
5255         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5256             Color result;
5257             ResourceParseUtils::ParseResColor(resObj, result);
5258             borderColors.leftColor = result;
5259         };
5260         borderColors.AddResource("borderColor.left", commonColor.leftResObj, std::move(updateFunc));
5261     }
5262     if (commonColor.rightResObj) {
5263         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5264             Color result;
5265             ResourceParseUtils::ParseResColor(resObj, result);
5266             borderColors.rightColor = result;
5267         };
5268         borderColors.AddResource("borderColor.right", commonColor.rightResObj, std::move(updateFunc));
5269     }
5270     if (commonColor.topResObj) {
5271         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5272             Color result;
5273             ResourceParseUtils::ParseResColor(resObj, result);
5274             borderColors.topColor = result;
5275         };
5276         borderColors.AddResource("borderColor.top", commonColor.topResObj, std::move(updateFunc));
5277     }
5278     if (commonColor.bottomResObj) {
5279         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5280             Color result;
5281             ResourceParseUtils::ParseResColor(resObj, result);
5282             borderColors.bottomColor = result;
5283         };
5284         borderColors.AddResource("borderColor.bottom", commonColor.bottomResObj, std::move(updateFunc));
5285     }
5286     borderColors.multiValued = true;
5287     return borderColors;
5288 }
5289 
ParseBorderColor(const JSRef<JSVal> & args)5290 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
5291 {
5292     Color borderColor;
5293     RefPtr<ResourceObject> borderColorResObj;
5294     if (ParseJsColor(args, borderColor, borderColorResObj)) {
5295         if (SystemProperties::ConfigChangePerform() && borderColorResObj) {
5296             ViewAbstractModel::GetInstance()->SetBorderColor(borderColorResObj);
5297         } else {
5298             ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
5299         }
5300     } else if (args->IsObject()) {
5301         CommonColor commonColor;
5302         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5303         if (ParseCommonEdgeColors(object, commonColor)) {
5304             ViewAbstractModel::GetInstance()->SetBorderColor(GetLocalizedBorderColor(commonColor));
5305             return;
5306         }
5307         ViewAbstractModel::GetInstance()->SetBorderColor(GetBorderColor(commonColor));
5308     } else {
5309         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
5310     }
5311 }
5312 
ParseOuterBorderColor(const JSRef<JSVal> & args)5313 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
5314 {
5315     Color borderColor;
5316     if (!SystemProperties::ConfigChangePerform()) {
5317         if (ParseJsColor(args, borderColor)) {
5318             ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
5319         } else if (args->IsObject()) {
5320             CommonColor commonColor;
5321             JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5322             if (ParseCommonEdgeColors(object, commonColor)) {
5323                 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
5324                     GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
5325                 return;
5326             }
5327             ViewAbstractModel::GetInstance()->SetOuterBorderColor(
5328                 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
5329         } else {
5330             ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
5331         }
5332     } else {
5333         RefPtr<ResourceObject> borderResObj;
5334         bool ret = ParseJsColor(args, borderColor, borderResObj);
5335         if (borderResObj) {
5336             ViewAbstractModel::GetInstance()->CreateWithOuterBorderColorResourceObj(borderResObj);
5337         } else if (ret) {
5338             ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
5339         } else if (args->IsObject()) {
5340             JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5341             NG::BorderColorProperty borderColors;
5342             borderColors.resMap_.clear();
5343             if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
5344                 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
5345                 ParseLocalizedEdgeColorsForOutLineColor(object, borderColors);
5346                 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColors);
5347             } else {
5348                 ParseEdgeColorsForOutLineColor(object, borderColors);
5349                 borderColors.multiValued = true;
5350                 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColors);
5351             }
5352         } else {
5353             ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
5354         }
5355     }
5356 }
5357 
JsBorderRadius(const JSCallbackInfo & info)5358 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
5359 {
5360     ViewAbstractModel::GetInstance()->ResetResObj("borderRadius");
5361     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
5362         JSCallbackInfoType::OBJECT };
5363     auto jsVal = info[0];
5364     if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
5365         ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
5366         return;
5367     }
5368     ParseBorderRadius(jsVal);
5369 }
5370 
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)5371 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
5372     const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
5373     const std::optional<Dimension>& radiusBottomEnd)
5374 {
5375     NG::BorderRadiusProperty borderRadius;
5376     borderRadius.radiusTopStart = radiusTopStart;
5377     borderRadius.radiusTopEnd = radiusTopEnd;
5378     borderRadius.radiusBottomStart = radiusBottomStart;
5379     borderRadius.radiusBottomEnd = radiusBottomEnd;
5380     borderRadius.multiValued = true;
5381     return borderRadius;
5382 }
5383 
ParseBorderRadius(const JSRef<JSVal> & args)5384 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
5385 {
5386     CalcDimension borderRadius;
5387     RefPtr<ResourceObject> borderRadiusResObj;
5388     if (ParseJsDimensionVp(args, borderRadius, borderRadiusResObj)) {
5389         if (SystemProperties::ConfigChangePerform() && borderRadiusResObj) {
5390             ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadiusResObj);
5391         } else {
5392             ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
5393         }
5394     } else if (args->IsObject()) {
5395         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5396         CalcDimension topLeft;
5397         CalcDimension topRight;
5398         CalcDimension bottomLeft;
5399         CalcDimension bottomRight;
5400         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
5401             ViewAbstractModel::GetInstance()->SetBorderRadius(
5402                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
5403                 return;
5404         }
5405         if (SystemProperties::ConfigChangePerform()) {
5406             NG::BorderRadiusProperty borderRadius;
5407             RefPtr<ResourceObject> topLeftResObj;
5408             RefPtr<ResourceObject> topRightResObj;
5409             RefPtr<ResourceObject> bottomLeftResObj;
5410             RefPtr<ResourceObject> bottomRightResObj;
5411             GetBorderRadiusResObj("topLeft", object, topLeft, topLeftResObj);
5412             GetBorderRadiusResObj("topRight", object, topRight, topRightResObj);
5413             GetBorderRadiusResObj("bottomLeft", object, bottomLeft, bottomLeftResObj);
5414             GetBorderRadiusResObj("bottomRight", object, bottomRight, bottomRightResObj);
5415             borderRadius.radiusTopLeft = topLeft;
5416             borderRadius.radiusTopRight = topRight;
5417             borderRadius.radiusBottomLeft = bottomLeft;
5418             borderRadius.radiusBottomRight = bottomRight;
5419             borderRadius.multiValued = true;
5420             ParseAllBorderRadiusesResObj(
5421                 borderRadius, topLeftResObj, topRightResObj, bottomLeftResObj, bottomRightResObj);
5422             ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
5423         } else {
5424             ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
5425         }
5426     }
5427 }
5428 
ParseOuterBorderRadius(const JSRef<JSVal> & args)5429 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
5430 {
5431     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
5432         return;
5433     }
5434     CalcDimension borderRadius;
5435     if (!SystemProperties::ConfigChangePerform()) {
5436         if (ParseJsDimensionVp(args, borderRadius)) {
5437             if (borderRadius.Unit() == DimensionUnit::PERCENT) {
5438                 borderRadius.Reset();
5439             }
5440             ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
5441         } else if (args->IsObject()) {
5442             JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5443             CalcDimension topLeft;
5444             CalcDimension topRight;
5445             CalcDimension bottomLeft;
5446             CalcDimension bottomRight;
5447             if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
5448                 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
5449                     GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
5450             }
5451             ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
5452         }
5453     } else {
5454         RefPtr<ResourceObject> resObj;
5455         bool ret = ParseJsDimensionVp(args, borderRadius, resObj);
5456         if (resObj) {
5457             ViewAbstractModel::GetInstance()->CreateWithOuterBorderRadiusResourceObj(resObj);
5458         } else if (ret) {
5459             if (borderRadius.Unit() == DimensionUnit::PERCENT) {
5460                 borderRadius.Reset();
5461             }
5462             ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
5463         } else if (args->IsObject()) {
5464             JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5465             NG::BorderRadiusProperty borderRadius;
5466             if (!ParseAllBorderRadiusesForOutLine(object, borderRadius)) {
5467                 borderRadius.multiValued = true;
5468             }
5469             ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
5470         }
5471     }
5472 }
5473 
GetBorderRadiusTopLeft(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5474 void JSViewAbstract::GetBorderRadiusTopLeft(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5475 {
5476     RefPtr<ResourceObject> topLeftResObj;
5477     CalcDimension dim;
5478     if (ParseJsDimensionVp(jsValue, dim, topLeftResObj)) {
5479         borderRadius.radiusTopLeft = dim;
5480     }
5481     if (topLeftResObj) {
5482         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5483             CalcDimension dimension;
5484             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5485             borderRadius.radiusTopLeft = dimension;
5486         };
5487         borderRadius.AddResource("outLineRadius.radius.radiusTopLft", topLeftResObj, std::move(updateFunc));
5488     }
5489 }
5490 
GetBorderRadiusTopRight(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5491 void JSViewAbstract::GetBorderRadiusTopRight(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5492 {
5493     RefPtr<ResourceObject> topRightResObj;
5494     CalcDimension dim;
5495     if (ParseJsDimensionVp(jsValue, dim, topRightResObj)) {
5496         borderRadius.radiusTopRight = dim;
5497     }
5498     if (topRightResObj) {
5499         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5500             CalcDimension dimension;
5501             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5502             borderRadius.radiusTopRight = dimension;
5503         };
5504         borderRadius.AddResource("outLineRadius.radius.radiusTopRight", topRightResObj, std::move(updateFunc));
5505     }
5506 }
5507 
GetBorderRadiusBottomLeft(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5508 void JSViewAbstract::GetBorderRadiusBottomLeft(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5509 {
5510     RefPtr<ResourceObject> bottomLeftResObj;
5511     CalcDimension dim;
5512     if (ParseJsDimensionVp(jsValue, dim, bottomLeftResObj)) {
5513         borderRadius.radiusBottomLeft = dim;
5514     }
5515     if (bottomLeftResObj) {
5516         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5517             CalcDimension dimension;
5518             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5519             borderRadius.radiusBottomLeft = dimension;
5520         };
5521         borderRadius.AddResource("outLineRadius.radius.radiusBottomLeft", bottomLeftResObj, std::move(updateFunc));
5522     }
5523 }
5524 
GetBorderRadiusBottomRight(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5525 void JSViewAbstract::GetBorderRadiusBottomRight(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5526 {
5527     RefPtr<ResourceObject> bottomRightResObj;
5528     CalcDimension dim;
5529     if (ParseJsDimensionVp(jsValue, dim, bottomRightResObj)) {
5530         borderRadius.radiusBottomRight = dim;
5531     }
5532     if (bottomRightResObj) {
5533         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5534             CalcDimension dimension;
5535             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5536             borderRadius.radiusBottomRight = dimension;
5537         };
5538         borderRadius.AddResource("outLineRadius.radius.radiusBottomRight", bottomRightResObj, std::move(updateFunc));
5539     }
5540 }
5541 
ParseAllBorderRadiusesForOutLine(JSRef<JSObject> & object,NG::BorderRadiusProperty & borderRadius)5542 bool JSViewAbstract::ParseAllBorderRadiusesForOutLine(JSRef<JSObject>& object, NG::BorderRadiusProperty& borderRadius)
5543 {
5544     if (object->IsUndefined()) {
5545         return false;
5546     }
5547     borderRadius.resMap_.clear();
5548     if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
5549         object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
5550         CalcDimension topStart;
5551         CalcDimension topEnd;
5552         CalcDimension bottomStart;
5553         CalcDimension bottomEnd;
5554         GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
5555         GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
5556         GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
5557         GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
5558         borderRadius.radiusTopStart = topStart;
5559         borderRadius.radiusTopEnd = topEnd;
5560         borderRadius.radiusBottomEnd = bottomStart;
5561         borderRadius.radiusBottomStart = bottomEnd;
5562         return true;
5563     }
5564     GetBorderRadiusTopLeft(object->GetProperty("topLeft"), borderRadius);
5565     GetBorderRadiusTopRight(object->GetProperty("topRight"), borderRadius);
5566     GetBorderRadiusBottomLeft(object->GetProperty("bottomLeft"), borderRadius);
5567     GetBorderRadiusBottomRight(object->GetProperty("bottomRight"), borderRadius);
5568     return false;
5569 }
5570 
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)5571 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
5572 {
5573     ParseJsDimensionVp(object->GetProperty(key), radius);
5574 }
5575 
GetBorderRadiusResObj(const char * key,JSRef<JSObject> & object,CalcDimension & radius,RefPtr<ResourceObject> & resObj)5576 void JSViewAbstract::GetBorderRadiusResObj(
5577     const char* key, JSRef<JSObject>& object, CalcDimension& radius, RefPtr<ResourceObject>& resObj)
5578 {
5579     ParseJsDimensionVp(object->GetProperty(key), radius, resObj);
5580 }
5581 
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)5582 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
5583 {
5584     if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
5585         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
5586         ParseJsLengthMetrics(startObj, radius);
5587     }
5588 }
5589 
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)5590 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
5591     CalcDimension& bottomLeft, CalcDimension& bottomRight)
5592 {
5593     TextBackgroundStyle textBackgroundStyle;
5594     return ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight, textBackgroundStyle);
5595 }
5596 
RegisterTextBackgroundStyleResource(TextBackgroundStyle & textBackgroundStyle,RefPtr<ResourceObject> & resObjTopLeft,RefPtr<ResourceObject> & resObjTopRight,RefPtr<ResourceObject> & resObjBottomLeft,RefPtr<ResourceObject> & resObjBottomRight)5597 void JSViewAbstract::RegisterTextBackgroundStyleResource(TextBackgroundStyle& textBackgroundStyle,
5598     RefPtr<ResourceObject>& resObjTopLeft, RefPtr<ResourceObject>& resObjTopRight,
5599     RefPtr<ResourceObject>& resObjBottomLeft, RefPtr<ResourceObject>& resObjBottomRight)
5600 {
5601     if (!SystemProperties::ConfigChangePerform()) {
5602         return;
5603     }
5604     if (resObjTopLeft) {
5605         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjTopLeft,
5606             TextBackgroundStyle& textBackgroundStyle) {
5607             CalcDimension radius;
5608             ResourceParseUtils::ParseResDimensionVp(resObjTopLeft, radius);
5609             textBackgroundStyle.backgroundRadius->radiusTopLeft = radius;
5610             textBackgroundStyle.backgroundRadius->multiValued = true;
5611         };
5612         textBackgroundStyle.AddResource("textBackgroundStyle.radiusTopLeft", resObjTopLeft,
5613             std::move(updateFunc));
5614     }
5615     if (resObjTopRight) {
5616         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjTopRight,
5617             TextBackgroundStyle& textBackgroundStyle) {
5618             CalcDimension radius;
5619             ResourceParseUtils::ParseResDimensionVp(resObjTopRight, radius);
5620             textBackgroundStyle.backgroundRadius->radiusTopRight = radius;
5621             textBackgroundStyle.backgroundRadius->multiValued = true;
5622         };
5623         textBackgroundStyle.AddResource("textBackgroundStyle.radiusTopRight", resObjTopRight,
5624             std::move(updateFunc));
5625     }
5626     if (resObjBottomLeft) {
5627         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjBottomLeft,
5628             TextBackgroundStyle& textBackgroundStyle) {
5629             CalcDimension radius;
5630             ResourceParseUtils::ParseResDimensionVp(resObjBottomLeft, radius);
5631             textBackgroundStyle.backgroundRadius->radiusBottomLeft = radius;
5632             textBackgroundStyle.backgroundRadius->multiValued = true;
5633         };
5634         textBackgroundStyle.AddResource("textBackgroundStyle.radiusBottomLeft", resObjBottomLeft,
5635             std::move(updateFunc));
5636     }
5637     if (resObjBottomRight) {
5638         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjBottomRight,
5639             TextBackgroundStyle& textBackgroundStyle) {
5640             CalcDimension radius;
5641             ResourceParseUtils::ParseResDimensionVp(resObjBottomRight, radius);
5642             textBackgroundStyle.backgroundRadius->radiusBottomRight = radius;
5643             textBackgroundStyle.backgroundRadius->multiValued = true;
5644         };
5645         textBackgroundStyle.AddResource("textBackgroundStyle.radiusBottomRight", resObjBottomRight,
5646             std::move(updateFunc));
5647     }
5648 }
5649 
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight,TextBackgroundStyle & textBackgroundStyle)5650 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
5651     CalcDimension& bottomLeft, CalcDimension& bottomRight, TextBackgroundStyle& textBackgroundStyle)
5652 {
5653     if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
5654         object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
5655         CalcDimension topStart;
5656         CalcDimension topEnd;
5657         CalcDimension bottomStart;
5658         CalcDimension bottomEnd;
5659         GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
5660         GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
5661         GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
5662         GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
5663         topLeft = topStart;
5664         topRight = topEnd;
5665         bottomLeft = bottomStart;
5666         bottomRight = bottomEnd;
5667         return true;
5668     }
5669     RefPtr<ResourceObject> resObjTopLeft;
5670     RefPtr<ResourceObject> resObjTopRight;
5671     RefPtr<ResourceObject> resObjBottomLeft;
5672     RefPtr<ResourceObject> resObjBottomRight;
5673     GetBorderRadiusResObj("topLeft", object, topLeft, resObjTopLeft);
5674     GetBorderRadiusResObj("topRight", object, topRight, resObjTopRight);
5675     GetBorderRadiusResObj("bottomLeft", object, bottomLeft, resObjBottomLeft);
5676     GetBorderRadiusResObj("bottomRight", object, bottomRight, resObjBottomRight);
5677 
5678     RegisterTextBackgroundStyleResource(textBackgroundStyle, resObjTopLeft, resObjTopRight, resObjBottomLeft,
5679         resObjBottomRight);
5680     return false;
5681 }
5682 
5683 #define ADDRESOURCE_UPDATE_FUNC(property, resObj, radiusMember, resourceName) \
5684     RefPtr<ResourceObject> resObj; \
5685     ParseJsDimensionVp(object->GetProperty(#property), property, resObj); \
5686     if (resObj) { \
5687         auto&& updateFunc = [](const RefPtr<ResourceObject>& (resObj), NG::BorderRadiusProperty& borderRadiusProperty) { \
5688             CalcDimension property; \
5689             ResourceParseUtils::ParseResDimensionVp(resObj, property); \
5690             if (LessNotEqual((property).Value(), 0.0f)) { \
5691                 (property).Reset(); \
5692             } \
5693             borderRadiusProperty.radiusMember = property; \
5694         }; \
5695         borderRadius.AddResource(resourceName, resObj, std::move(updateFunc)); \
5696     }
5697 
ParseAllBorderRadiuses(JSRef<JSObject> & object,NG::BorderRadiusProperty & borderRadius)5698 void JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, NG::BorderRadiusProperty& borderRadius)
5699 {
5700     CalcDimension topLeft;
5701     CalcDimension topRight;
5702     CalcDimension bottomLeft;
5703     CalcDimension bottomRight;
5704     bool hasSetBorderRadius = false;
5705     if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
5706         object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
5707         CalcDimension topStart;
5708         CalcDimension topEnd;
5709         CalcDimension bottomStart;
5710         CalcDimension bottomEnd;
5711         GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
5712         GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
5713         GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
5714         GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
5715         topLeft = topStart;
5716         topRight = topEnd;
5717         bottomLeft = bottomStart;
5718         bottomRight = bottomEnd;
5719         hasSetBorderRadius = true;
5720     }
5721     else {
5722         ADDRESOURCE_UPDATE_FUNC(topLeft, topLeftResObj, radiusTopLeft, "borderRadius.topLeft")
5723         ADDRESOURCE_UPDATE_FUNC(topRight, topRightResObj, radiusTopRight, "borderRadius.topRight")
5724         ADDRESOURCE_UPDATE_FUNC(bottomLeft, bottomLeftResObj, radiusBottomLeft, "borderRadius.bottomLeft")
5725         ADDRESOURCE_UPDATE_FUNC(bottomRight, bottomRightResObj, radiusBottomRight, "borderRadius.bottomRight")
5726     }
5727     if (LessNotEqual(topLeft.Value(), 0.0f)) {
5728         topLeft.Reset();
5729     }
5730     if (LessNotEqual(topRight.Value(), 0.0f)) {
5731         topRight.Reset();
5732     }
5733     if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
5734         bottomLeft.Reset();
5735     }
5736     if (LessNotEqual(bottomRight.Value(), 0.0f)) {
5737         bottomRight.Reset();
5738     }
5739     auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
5740     borderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
5741     borderRadius.radiusTopRight = isRtl ? topLeft : topRight;
5742     borderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
5743     borderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
5744     borderRadius.multiValued = true;
5745 }
5746 
JsBorderStyle(const JSCallbackInfo & info)5747 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
5748 {
5749     ParseBorderStyle(info[0]);
5750 }
5751 namespace {
ConvertBorderStyle(int32_t value)5752 BorderStyle ConvertBorderStyle(int32_t value)
5753 {
5754     auto style = static_cast<BorderStyle>(value);
5755     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
5756         style = BorderStyle::SOLID;
5757     }
5758     return style;
5759 }
5760 
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)5761 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
5762 {
5763     style = static_cast<BorderStyle>(value);
5764     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
5765         return false;
5766     }
5767     return true;
5768 }
5769 } // namespace
5770 
ParseBorderStyle(const JSRef<JSVal> & args)5771 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
5772 {
5773     if (args->IsObject()) {
5774         std::optional<BorderStyle> styleLeft;
5775         std::optional<BorderStyle> styleRight;
5776         std::optional<BorderStyle> styleTop;
5777         std::optional<BorderStyle> styleBottom;
5778         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5779         auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
5780         if (leftValue->IsNumber()) {
5781             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
5782         }
5783         auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
5784         if (rightValue->IsNumber()) {
5785             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
5786         }
5787         auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
5788         if (topValue->IsNumber()) {
5789             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
5790         }
5791         auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
5792         if (bottomValue->IsNumber()) {
5793             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
5794         }
5795         ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
5796         return;
5797     }
5798     if (args->IsNumber()) {
5799         auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
5800         ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
5801         return;
5802     }
5803     ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
5804 }
5805 
ParseOuterBorderStyle(const JSRef<JSVal> & args)5806 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
5807 {
5808     if (!args->IsObject() && !args->IsNumber()) {
5809         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
5810         return;
5811     }
5812     if (args->IsObject()) {
5813         std::optional<BorderStyle> styleLeft;
5814         std::optional<BorderStyle> styleRight;
5815         std::optional<BorderStyle> styleTop;
5816         std::optional<BorderStyle> styleBottom;
5817         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5818         auto leftValue = object->GetProperty("left");
5819         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
5820             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
5821         }
5822         auto rightValue = object->GetProperty("right");
5823         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
5824             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
5825         }
5826         auto topValue = object->GetProperty("top");
5827         if (!topValue->IsUndefined() && topValue->IsNumber()) {
5828             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
5829         }
5830         auto bottomValue = object->GetProperty("bottom");
5831         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
5832             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
5833         }
5834         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
5835         return;
5836     }
5837     auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
5838     ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
5839 }
5840 
JsBlur(const JSCallbackInfo & info)5841 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
5842 {
5843     if (info.Length() == 0) {
5844         return;
5845     }
5846     double blur = 0.0;
5847     if (!ParseJsDouble(info[0], blur)) {
5848         return;
5849     }
5850 
5851     BlurOption blurOption;
5852     if (info.Length() > 1 && info[1]->IsObject()) {
5853         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
5854         ParseBlurOption(jsBlurOption, blurOption);
5855     }
5856     SysOptions sysOptions;
5857     sysOptions.disableSystemAdaptation = false;
5858     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
5859         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
5860         ParseSysOptions(jsSysOptions, sysOptions);
5861     }
5862     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
5863     ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption, sysOptions);
5864     info.SetReturnValue(info.This());
5865 }
5866 
JsMotionBlur(const JSCallbackInfo & info)5867 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
5868 {
5869     if (!info[0]->IsObject()) {
5870         return;
5871     }
5872     MotionBlurOption option;
5873     double x = 0.0;
5874     double y = 0.0;
5875     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5876     JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
5877     if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
5878         JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
5879         ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
5880         ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
5881     }
5882     double radius = 0.0;
5883     if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
5884         radius = 0.0;
5885     }
5886     if (LessNotEqual(x, 0.0)) {
5887         x = 0.0;
5888     }
5889     if (LessNotEqual(y, 0.0)) {
5890         y = 0.0;
5891     }
5892     option.radius = radius;
5893     option.anchor.x = std::clamp(x, 0.0, 1.0);
5894     option.anchor.y = std::clamp(y, 0.0, 1.0);
5895     ViewAbstractModel::GetInstance()->SetMotionBlur(option);
5896 }
5897 
JsColorBlend(const JSCallbackInfo & info)5898 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
5899 {
5900     ViewAbstractModel::GetInstance()->RemoveResObj("viewAbstract.colorBlend");
5901     Color colorBlend;
5902     if (info[0]->IsUndefined()) {
5903         colorBlend = Color::TRANSPARENT;
5904         SetColorBlend(colorBlend);
5905         return;
5906     }
5907     if (!SystemProperties::ConfigChangePerform()) {
5908         if (!ParseJsColor(info[0], colorBlend)) {
5909             if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5910                 colorBlend = Color::TRANSPARENT;
5911                 SetColorBlend(colorBlend);
5912             }
5913             return;
5914         }
5915         SetColorBlend(colorBlend);
5916         info.SetReturnValue(info.This());
5917     } else {
5918         RefPtr<ResourceObject> colorBlendResObj;
5919         if (ParseJsColor(info[0], colorBlend, colorBlendResObj) && !colorBlendResObj) {
5920             SetColorBlend(colorBlend);
5921             info.SetReturnValue(info.This());
5922             return;
5923         }
5924         if (colorBlendResObj) {
5925             ViewAbstractModel::GetInstance()->CreateWithColorBlendResourceObj(colorBlendResObj);
5926             info.SetReturnValue(info.This());
5927         } else {
5928             if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5929                 colorBlend = Color::TRANSPARENT;
5930                 SetColorBlend(colorBlend);
5931             }
5932         }
5933     }
5934 }
5935 
JsUseEffect(const JSCallbackInfo & info)5936 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
5937 {
5938     if (info[0]->IsBoolean()) {
5939         auto effectType = EffectType::DEFAULT;
5940         if (info.Length() == 2 && info[1]->IsNumber()) {
5941             effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
5942             if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
5943                 effectType = EffectType::DEFAULT;
5944             }
5945         }
5946         ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
5947     }
5948 }
5949 
JsUseShadowBatching(const JSCallbackInfo & info)5950 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
5951 {
5952     if (info[0]->IsBoolean()) {
5953         ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
5954     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5955         ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
5956     }
5957 }
5958 
JsBackdropBlur(const JSCallbackInfo & info)5959 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
5960 {
5961     if (info.Length() == 0) {
5962         return;
5963     }
5964     double blur = 0.0;
5965     BlurOption blurOption;
5966     if (!ParseJsDouble(info[0], blur)) {
5967         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5968             return;
5969         }
5970     }
5971     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
5972     if (info.Length() > 1 && info[1]->IsObject()) {
5973         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
5974         ParseBlurOption(jsBlurOption, blurOption);
5975     }
5976     SysOptions sysOptions;
5977     sysOptions.disableSystemAdaptation = false;
5978     if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
5979         JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
5980         ParseSysOptions(jsSysOptions, sysOptions);
5981     }
5982     ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption, sysOptions);
5983     info.SetReturnValue(info.This());
5984 }
5985 
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)5986 void JSViewAbstract::GetFractionStops(
5987     std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
5988 {
5989     if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
5990         return;
5991     }
5992     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
5993     float tmpPos = -1.0f;
5994     size_t length = jsArray->Length();
5995     for (size_t i = 0; i < length; i++) {
5996         std::pair<float, float> fractionStop;
5997         JSRef<JSVal> item = jsArray->GetValueAt(i);
5998         if (!item->IsArray()) {
5999             continue;
6000         }
6001         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
6002         if (subArray->Length() < 2) {
6003             continue;
6004         }
6005 
6006         double value = 0.0;
6007         if (ParseJsDouble(subArray->GetValueAt(0), value)) {
6008             value = std::clamp(value, 0.0, 1.0);
6009             fractionStop.first = static_cast<float>(value);
6010         }
6011         value = 0.0;
6012         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
6013             value = std::clamp(value, 0.0, 1.0);
6014             fractionStop.second = static_cast<float>(value);
6015         }
6016 
6017         if (fractionStop.second <= tmpPos) {
6018             fractionStops.clear();
6019             return;
6020         }
6021         tmpPos = fractionStop.second;
6022         fractionStops.push_back(fractionStop);
6023     }
6024 }
JsLinearGradientBlur(const JSCallbackInfo & info)6025 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
6026 {
6027     if (info.Length() < 2) { // 2 represents the least para num;
6028         return;
6029     }
6030     double blurRadius = 0.0;
6031     ParseJsDouble(info[0], blurRadius);
6032 
6033     std::vector<std::pair<float, float>> fractionStops;
6034     auto direction = GradientDirection::BOTTOM;
6035     if (info[1]->IsObject()) {
6036         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
6037         GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
6038         auto directionValue =
6039             jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
6040         if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
6041             directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
6042             directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
6043         }
6044         direction = static_cast<GradientDirection>(directionValue);
6045     }
6046     if (static_cast<int32_t>(fractionStops.size()) <= 1) {
6047         fractionStops.clear();
6048         fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
6049         fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
6050     }
6051     // Parse direction
6052     CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
6053     NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
6054     SetLinearGradientBlur(blurPara);
6055 }
6056 
JsBackgroundBrightness(const JSCallbackInfo & info)6057 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
6058 {
6059     double rate = 0.0;
6060     double lightUpDegree = 0.0;
6061     if (info[0]->IsObject()) {
6062         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
6063         ParseJsDouble(jsObj->GetProperty("rate"), rate);
6064         ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
6065     }
6066     SetDynamicLightUp(rate, lightUpDegree);
6067 }
6068 
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)6069 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
6070 {
6071     if (info.Length() == 0) {
6072         return;
6073     }
6074     BrightnessOption option;
6075     if (info[0]->IsObject()) {
6076         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
6077         ParseBrightnessOption(jsOption, option);
6078     }
6079     SetBgDynamicBrightness(option);
6080 }
6081 
JsForegroundBrightness(const JSCallbackInfo & info)6082 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
6083 {
6084     if (info.Length() == 0) {
6085         return;
6086     }
6087     BrightnessOption option;
6088     if (info[0]->IsObject()) {
6089         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
6090         ParseBrightnessOption(jsOption, option);
6091     }
6092     SetFgDynamicBrightness(option);
6093 }
6094 
JsWindowBlur(const JSCallbackInfo & info)6095 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
6096 {
6097     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6098     auto jsVal = info[0];
6099     if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
6100         return;
6101     }
6102 
6103     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
6104     double progress = 0.0;
6105     ParseJsDouble(jsObj->GetProperty("percent"), progress);
6106     auto style = jsObj->GetPropertyValue<int32_t>("style",
6107         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
6108 
6109     progress = std::clamp(progress, 0.0, 1.0);
6110     style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
6111         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
6112 
6113     SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
6114     info.SetReturnValue(info.This());
6115 }
6116 
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)6117 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
6118     std::string& resName, bool isParseType)
6119 {
6120     if (!jsValue->IsString()) {
6121         return false;
6122     }
6123     std::string resPath = jsValue->ToString();
6124     std::smatch results;
6125     std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
6126     if (!std::regex_match(resPath, results, tokenRegex)) {
6127         return false;
6128     }
6129     targetModule = results[1];
6130     if (isParseType && !ConvertResourceType(results[2], resType)) {
6131         return false;
6132     }
6133     resName = resPath;
6134     return true;
6135 }
6136 
ConvertResourceType(const std::string & typeName,ResourceType & resType)6137 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
6138 {
6139     static const std::unordered_map<std::string, ResourceType> resTypeMap {
6140         { "color", ResourceType::COLOR },
6141         { "media", ResourceType::MEDIA },
6142         { "float", ResourceType::FLOAT },
6143         { "string", ResourceType::STRING },
6144         { "plural", ResourceType::PLURAL },
6145         { "pattern", ResourceType::PATTERN },
6146         { "boolean", ResourceType::BOOLEAN },
6147         { "integer", ResourceType::INTEGER },
6148         { "strarray", ResourceType::STRARRAY },
6149         { "intarray", ResourceType::INTARRAY },
6150     };
6151     auto it = resTypeMap.find(typeName);
6152     if (it == resTypeMap.end()) {
6153         return false;
6154     }
6155     resType = it->second;
6156     return true;
6157 }
6158 
CompleteResourceObject(JSRef<JSObject> & jsObj)6159 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
6160 {
6161     std::string bundleName;
6162     std::string moduleName;
6163     int32_t resId = -1;
6164     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
6165 }
6166 
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)6167 void JSViewAbstract::CompleteResourceObjectWithBundleName(
6168     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
6169 {
6170     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
6171 }
6172 
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)6173 void JSViewAbstract::CompleteResourceObjectInner(
6174     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
6175 {
6176     // dynamic $r raw input format is
6177     // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
6178     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
6179     ResourceType resType;
6180 
6181     std::string targetModule;
6182     std::string resName;
6183     if (resId->IsString()) {
6184         JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
6185         int32_t typeNum = -1;
6186         if (type->IsNumber()) {
6187             typeNum = type->ToNumber<int32_t>();
6188         }
6189         if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
6190             return;
6191         }
6192         CompleteResourceObjectFromId(type, jsObj, resType, resName);
6193     } else if (resId->IsNumber()) {
6194         resIdValue = resId->ToNumber<int32_t>();
6195         if (resIdValue == -1) {
6196             CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
6197         }
6198     }
6199 
6200     JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
6201     if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
6202         bundleName = GetBundleNameFromContainer();
6203         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
6204     }
6205     if (moduleName == DEFAULT_HAR_MODULE_NAME) {
6206         moduleName = GetModuleNameFromContainer();
6207         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
6208     }
6209 }
6210 
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)6211 bool JSViewAbstract::ParseJsDimensionNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6212     DimensionUnit defaultUnit, bool isSupportPercent)
6213 {
6214     RefPtr<ResourceObject> resObj;
6215     return ParseJsDimensionNG(jsValue, result, defaultUnit, resObj, isSupportPercent);
6216 }
6217 
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6218 bool JSViewAbstract::ParseJsDimensionNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6219     DimensionUnit defaultUnit, RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6220 {
6221     if (jsValue->IsNumber()) {
6222         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
6223         return true;
6224     }
6225     if (jsValue->IsString()) {
6226         auto value = jsValue->ToString();
6227         if (!isSupportPercent && value.back() == '%') {
6228             return false;
6229         }
6230         return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
6231     }
6232     if (jsValue->IsObject()) {
6233         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6234         CompleteResourceObject(jsObj);
6235         JSRef<JSVal> resId = jsObj->GetProperty("id");
6236         if (!resId->IsNumber()) {
6237             return false;
6238         }
6239         auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6240         if (resType == UNKNOWN_RESOURCE_TYPE) {
6241             return false;
6242         }
6243         resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6244             GetResourceObjectByBundleAndModule(jsObj);
6245         auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6246         if (!resourceWrapper) {
6247             return false;
6248         }
6249         auto resIdNum = resId->ToNumber<int32_t>();
6250         if (resIdNum == -1) {
6251             if (!IsGetResourceByName(jsObj)) {
6252                 return false;
6253             }
6254             JSRef<JSVal> args = jsObj->GetProperty("params");
6255             if (!args->IsArray()) {
6256                 return false;
6257             }
6258             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6259             auto param = params->GetValueAt(0);
6260             if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6261                 auto value = resourceWrapper->GetStringByName(param->ToString());
6262                 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
6263             }
6264             if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6265                 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
6266                 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
6267                 return true;
6268             }
6269             result = resourceWrapper->GetDimensionByName(param->ToString());
6270             return true;
6271         }
6272         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6273             auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
6274             return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
6275         }
6276         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6277             auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
6278             StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
6279             return true;
6280         }
6281         if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
6282             result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
6283             return true;
6284         }
6285     }
6286     return false;
6287 }
6288 
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)6289 bool JSViewAbstract::ParseJsLengthNG(
6290     const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
6291 {
6292     RefPtr<ResourceObject> resourceObj;
6293     return ParseJsLengthNG(jsValue, result, defaultUnit, resourceObj, isSupportPercent);
6294 }
6295 
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resourceObj,bool isSupportPercent)6296 bool JSViewAbstract::ParseJsLengthNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit,
6297     RefPtr<ResourceObject>& resourceObj, bool isSupportPercent)
6298 {
6299     if (jsValue->IsNumber()) {
6300         if (std::isnan(jsValue->ToNumber<double>())) {
6301             return false;
6302         }
6303         result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
6304         return true;
6305     } else if (jsValue->IsObject()) {
6306         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6307         JSRef<JSVal> value = jsObj->GetProperty("value");
6308         if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
6309             return false;
6310         }
6311         DimensionUnit unit = defaultUnit;
6312         JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
6313         if (jsUnit->IsNumber()) {
6314             if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
6315                 return false;
6316             }
6317             unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
6318         }
6319         result = NG::CalcLength(value->ToNumber<double>(), unit);
6320         auto jsRes = jsObj->GetProperty("res");
6321         if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
6322             !jsRes->IsNull() && jsRes->IsObject()) {
6323             JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
6324             JSViewAbstract::CompleteResourceObject(resObj);
6325             resourceObj = JSViewAbstract::GetResourceObject(resObj);
6326         }
6327         return true;
6328     }
6329 
6330     return false;
6331 }
6332 
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)6333 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
6334 {
6335     RefPtr<ResourceObject> resObj;
6336     return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, resObj, isSupportPercent);
6337 }
6338 
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6339 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result,
6340     RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6341 {
6342     // 'vp' -> the value varies with pixel density of device.
6343     return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, resObj, isSupportPercent);
6344 }
6345 
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)6346 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
6347 {
6348     RefPtr<ResourceObject> resObj;
6349     return ParseJsDimension(jsValue, result, defaultUnit, resObj);
6350 }
6351 
ParseJsDimensionByNameInternal(const JSRef<JSObject> & jsObj,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceWrapper> & resourceWrapper,int32_t resType)6352 bool JSViewAbstract::ParseJsDimensionByNameInternal(const JSRef<JSObject>& jsObj, CalcDimension& result,
6353     DimensionUnit defaultUnit, RefPtr<ResourceWrapper>& resourceWrapper, int32_t resType)
6354 {
6355     if (!IsGetResourceByName(jsObj)) {
6356         return false;
6357     }
6358     JSRef<JSVal> args = jsObj->GetProperty("params");
6359     if (!args->IsArray()) {
6360         return false;
6361     }
6362     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6363     auto param = params->GetValueAt(0);
6364     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6365         auto value = resourceWrapper->GetStringByName(param->ToString());
6366         result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
6367         return true;
6368     }
6369     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6370         auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
6371         result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
6372         return true;
6373     }
6374     result = resourceWrapper->GetDimensionByName(param->ToString());
6375     return true;
6376 }
6377 
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resObj)6378 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit,
6379     RefPtr<ResourceObject>& resObj)
6380 {
6381     if (jsValue->IsNumber()) {
6382         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
6383         return true;
6384     }
6385     if (jsValue->IsString()) {
6386         result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
6387         return true;
6388     }
6389     if (!jsValue->IsObject()) {
6390         return false;
6391     }
6392     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6393     CompleteResourceObject(jsObj);
6394     JSRef<JSVal> resId = jsObj->GetProperty("id");
6395     if (!resId->IsNumber()) {
6396         return false;
6397     }
6398     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6399         GetResourceObjectByBundleAndModule(jsObj);
6400     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6401     if (!resourceWrapper) {
6402         return false;
6403     }
6404     auto resIdNum = resId->ToNumber<int32_t>();
6405     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6406     if (resType == UNKNOWN_RESOURCE_TYPE) {
6407         return false;
6408     }
6409     if (resIdNum == -1) {
6410         return ParseJsDimensionByNameInternal(jsObj, result, defaultUnit, resourceWrapper, resType);
6411     }
6412     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6413         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
6414         result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
6415         return true;
6416     }
6417     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6418         auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
6419         result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
6420         return true;
6421     }
6422     result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
6423     return true;
6424 }
6425 
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)6426 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
6427 {
6428     // 'vp' -> the value varies with pixel density of device.
6429     return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
6430 }
6431 
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6432 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6433     RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6434 {
6435     // 'vp' -> the value varies with pixel density of device.
6436     return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, resObj, isSupportPercent);
6437 }
6438 
ParseJsLengthMetricsVp(const JSRef<JSObject> & jsObj,CalcDimension & result)6439 bool JSViewAbstract::ParseJsLengthMetricsVp(const JSRef<JSObject>& jsObj, CalcDimension& result)
6440 {
6441     RefPtr<ResourceObject> resourceObj;
6442     return ParseJsLengthMetricsVpWithResObj(jsObj, result, resourceObj);
6443 }
6444 
ParseJsLengthMetricsVpWithResObj(const JSRef<JSObject> & jsObj,CalcDimension & result,RefPtr<ResourceObject> & resourceObj)6445 bool JSViewAbstract::ParseJsLengthMetricsVpWithResObj(const JSRef<JSObject>& jsObj, CalcDimension& result,
6446     RefPtr<ResourceObject>& resourceObj)
6447 {
6448     auto value = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
6449     if (!value->IsNumber()) {
6450         return false;
6451     }
6452     auto unit = DimensionUnit::VP;
6453     auto jsUnit = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
6454     if (jsUnit->IsNumber()) {
6455         unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
6456     }
6457     CalcDimension dimension(value->ToNumber<double>(), unit);
6458     result = dimension;
6459     auto jsRes = jsObj->GetProperty("res");
6460     if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
6461         !jsRes->IsNull() && jsRes->IsObject()) {
6462         JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
6463         JSViewAbstract::CompleteResourceObject(resObj);
6464         resourceObj = JSViewAbstract::GetResourceObject(resObj);
6465     }
6466     return true;
6467 }
6468 
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)6469 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
6470 {
6471     RefPtr<ResourceObject> resObj;
6472     // 'vp' -> the value varies with pixel density of device.
6473     return ParseJsDimension(jsValue, result, DimensionUnit::VP, resObj);
6474 }
6475 
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6476 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result,
6477     RefPtr<ResourceObject>& resObj)
6478 {
6479     // 'vp' -> the value varies with pixel density of device.
6480     return ParseJsDimension(jsValue, result, DimensionUnit::VP, resObj);
6481 }
6482 
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)6483 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
6484 {
6485     RefPtr<ResourceObject> resObj;
6486     // the 'fp' unit is used for text scenes.
6487     return ParseJsDimension(jsValue, result, DimensionUnit::FP, resObj);
6488 }
6489 
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6490 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result,
6491     RefPtr<ResourceObject>& resObj)
6492 {
6493     // the 'fp' unit is used for text scenes.
6494     return ParseJsDimension(jsValue, result, DimensionUnit::FP, resObj);
6495 }
6496 
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)6497 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
6498 {
6499     // the 'fp' unit is used for text scenes.
6500     return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
6501 }
6502 
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6503 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6504     RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6505 {
6506     // the 'fp' unit is used for text scenes.
6507     return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, resObj, isSupportPercent);
6508 }
6509 
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)6510 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
6511 {
6512     RefPtr<ResourceObject> resObj;
6513     return ParseJsDimension(jsValue, result, DimensionUnit::PX, resObj);
6514 }
6515 
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6516 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result,
6517     RefPtr<ResourceObject>& resObj)
6518 {
6519     return ParseJsDimension(jsValue, result, DimensionUnit::PX, resObj);
6520 }
6521 
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)6522 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
6523 {
6524     RefPtr<ResourceObject> resObj;
6525     return ParseColorMetricsToColor(jsValue, result, resObj);
6526 }
6527 
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result,RefPtr<ResourceObject> & resObj)6528 bool JSViewAbstract::ParseColorMetricsToColor(
6529     const JSRef<JSVal>& jsValue, Color& result, RefPtr<ResourceObject>& resObj)
6530 {
6531     if (!jsValue->IsObject()) {
6532         return false;
6533     }
6534     auto colorObj = JSRef<JSObject>::Cast(jsValue);
6535     auto toNumericProp = colorObj->GetProperty("toNumeric");
6536     auto colorSpaceProp = colorObj->GetProperty("getColorSpace");
6537     auto jsRes = colorObj->GetProperty("res_");
6538     if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() && !jsRes->IsNull() && jsRes->IsObject()) {
6539         JSRef<JSObject> jsResObj = JSRef<JSObject>::Cast(jsRes);
6540         JSViewAbstract::CompleteResourceObject(jsResObj);
6541         resObj = JSViewAbstract::GetResourceObject(jsResObj);
6542     }
6543     if (toNumericProp->IsFunction() && colorSpaceProp->IsFunction()) {
6544         auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
6545         result.SetValue(colorVal->ToNumber<uint32_t>());
6546 
6547         auto resourceIdProp = colorObj->GetProperty("getResourceId");
6548         if (resourceIdProp->IsFunction()) {
6549             auto resourceIdVal = JSRef<JSFunc>::Cast(resourceIdProp)->Call(colorObj, 0, nullptr);
6550             result.SetResourceId(resourceIdVal->ToNumber<uint32_t>());
6551         }
6552 
6553         auto colorSpaceVal = JSRef<JSFunc>::Cast(colorSpaceProp)->Call(colorObj, 0, nullptr);
6554         if (colorSpaceVal->IsNumber() &&
6555             colorSpaceVal->ToNumber<uint32_t>() == static_cast<uint32_t>(ColorSpace::DISPLAY_P3)) {
6556             result.SetColorSpace(ColorSpace::DISPLAY_P3);
6557         } else {
6558             result.SetColorSpace(ColorSpace::SRGB);
6559         }
6560 
6561         return true;
6562     }
6563     return false;
6564 }
6565 
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)6566 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
6567 {
6568     RefPtr<ResourceObject> resObj;
6569     return ParseLengthMetricsToDimension(jsValue, result, resObj);
6570 }
6571 
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObj)6572 bool JSViewAbstract::ParseLengthMetricsToDimension(
6573     const JSRef<JSVal>& jsValue, CalcDimension& result, RefPtr<ResourceObject>& resourceObj)
6574 {
6575     if (jsValue->IsNumber()) {
6576         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
6577         return true;
6578     }
6579     if (jsValue->IsString()) {
6580         auto value = jsValue->ToString();
6581         return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
6582     }
6583     if (jsValue->IsObject()) {
6584         auto jsObj = JSRef<JSObject>::Cast(jsValue);
6585         auto valObj = jsObj->GetProperty("value");
6586         if (valObj->IsUndefined() || valObj->IsNull()) {
6587             return false;
6588         }
6589         double value = valObj->ToNumber<double>();
6590         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
6591         result = CalcDimension(value, unit);
6592         auto jsRes = jsObj->GetProperty("res");
6593         if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
6594             !jsRes->IsNull() && jsRes->IsObject()) {
6595             JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
6596             JSViewAbstract::CompleteResourceObject(resObj);
6597             resourceObj = JSViewAbstract::GetResourceObject(resObj);
6598         }
6599         return true;
6600     }
6601     return false;
6602 }
6603 
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)6604 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
6605 {
6606     return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
6607 }
6608 
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6609 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(
6610     const JSRef<JSVal>& jsValue, CalcDimension& result, RefPtr<ResourceObject>& resObj)
6611 {
6612     return ParseLengthMetricsToDimension(jsValue, result, resObj) ? GreatOrEqual(result.Value(), 0.0f) : false;
6613 }
6614 
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result,RefPtr<ResourceObject> & resObj)6615 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result,
6616     RefPtr<ResourceObject>& resObj)
6617 {
6618     if (!jsValue->IsObject()) {
6619         return false;
6620     }
6621     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6622     CompleteResourceObject(jsObj);
6623     if (jsObj->IsEmpty()) {
6624         return false;
6625     }
6626     JSRef<JSVal> id = jsObj->GetProperty("id");
6627     if (!id->IsNumber()) {
6628         return false;
6629     }
6630 
6631     auto resId = id->ToNumber<int32_t>();
6632     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6633     if (resType == UNKNOWN_RESOURCE_TYPE) {
6634         return false;
6635     }
6636 
6637     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6638         GetResourceObjectByBundleAndModule(jsObj);
6639     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6640     if (!resourceWrapper) {
6641         return false;
6642     }
6643 
6644     if (resId == -1) {
6645         return ParseResourceToDoubleByName(jsObj, resType, resourceWrapper, result);
6646     }
6647     return ParseResourceToDoubleById(resId, resType, resourceWrapper, result);
6648 }
6649 
ParseResourceToDoubleByName(const JSRef<JSObject> & jsObj,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)6650 bool JSViewAbstract::ParseResourceToDoubleByName(
6651     const JSRef<JSObject>& jsObj, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
6652 {
6653     if (!IsGetResourceByName(jsObj)) {
6654         return false;
6655     }
6656     JSRef<JSVal> args = jsObj->GetProperty("params");
6657     if (!args->IsArray()) {
6658         return false;
6659     }
6660     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6661     auto param = params->GetValueAt(0);
6662     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6663         auto numberString = resourceWrapper->GetStringByName(param->ToString());
6664         return StringUtils::StringToDouble(numberString, result);
6665     }
6666     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6667         result = resourceWrapper->GetIntByName(param->ToString());
6668         return true;
6669     }
6670     if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
6671         result = resourceWrapper->GetDoubleByName(param->ToString());
6672         return true;
6673     }
6674     return false;
6675 }
6676 
ParseResourceToDoubleById(int32_t resId,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)6677 bool JSViewAbstract::ParseResourceToDoubleById(
6678     int32_t resId, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
6679 {
6680     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6681         auto numberString = resourceWrapper->GetString(resId);
6682         return StringUtils::StringToDouble(numberString, result);
6683     }
6684     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6685         result = resourceWrapper->GetInt(resId);
6686         return true;
6687     }
6688     if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
6689         result = resourceWrapper->GetDouble(resId);
6690         return true;
6691     }
6692     return false;
6693 }
6694 
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)6695 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
6696 {
6697     RefPtr<ResourceObject> resObj;
6698     return ParseJsDouble(jsValue, result, resObj);
6699 }
6700 
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result,RefPtr<ResourceObject> & resObj)6701 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result,
6702     RefPtr<ResourceObject>& resObj)
6703 {
6704     if (jsValue->IsNumber()) {
6705         result = jsValue->ToNumber<double>();
6706         return true;
6707     }
6708     if (jsValue->IsString()) {
6709         return StringUtils::StringToDouble(jsValue->ToString(), result);
6710     }
6711     if (jsValue->IsObject()) {
6712         return ParseResourceToDouble(jsValue, result, resObj);
6713     }
6714     return false;
6715 }
6716 
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)6717 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
6718 {
6719     if (jsValue->IsNumber()) {
6720         result = jsValue->ToNumber<int32_t>();
6721         return true;
6722     }
6723     if (jsValue->IsString()) {
6724         result = StringUtils::StringToInt(jsValue->ToString());
6725         return true;
6726     }
6727     if (!jsValue->IsObject()) {
6728         return false;
6729     }
6730     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6731     CompleteResourceObject(jsObj);
6732     JSRef<JSVal> resId = jsObj->GetProperty("id");
6733     if (!resId->IsNumber()) {
6734         return false;
6735     }
6736 
6737     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6738     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6739     if (!resourceWrapper) {
6740         return false;
6741     }
6742 
6743     auto resIdNum = resId->ToNumber<int32_t>();
6744     if (resIdNum == -1) {
6745         if (!IsGetResourceByName(jsObj)) {
6746             return false;
6747         }
6748         JSRef<JSVal> args = jsObj->GetProperty("params");
6749         if (!args->IsArray()) {
6750             return false;
6751         }
6752         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6753         auto param = params->GetValueAt(0);
6754         result = resourceWrapper->GetIntByName(param->ToString());
6755         return true;
6756     }
6757     result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
6758     return true;
6759 }
6760 
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result,RefPtr<ResourceObject> & resObj)6761 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result,
6762     RefPtr<ResourceObject>& resObj)
6763 {
6764     if (!jsValue->IsObject()) {
6765         return false;
6766     }
6767     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6768     CompleteResourceObject(jsObj);
6769 
6770     auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result, resObj);
6771     if (ok) {
6772         JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
6773         if (jsOpacityRatio->IsNumber()) {
6774             double opacityRatio = jsOpacityRatio->ToNumber<double>();
6775             result = result.BlendOpacity(opacityRatio);
6776         }
6777     }
6778     return ok;
6779 }
6780 
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result,RefPtr<ResourceObject> & resObj)6781 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result,
6782     RefPtr<ResourceObject>& resObj)
6783 {
6784     JSRef<JSVal> resId = jsObj->GetProperty("id");
6785     if (!resId->IsNumber()) {
6786         return false;
6787     }
6788 
6789     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6790         GetResourceObjectByBundleAndModule(jsObj);
6791     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6792     if (!resourceWrapper) {
6793         return false;
6794     }
6795 
6796     auto resIdNum = resId->ToNumber<int32_t>();
6797     if (resIdNum == -1) {
6798         if (!IsGetResourceByName(jsObj)) {
6799             return false;
6800         }
6801         JSRef<JSVal> args = jsObj->GetProperty("params");
6802         if (!args->IsArray()) {
6803             return false;
6804         }
6805         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6806         auto param = params->GetValueAt(0);
6807         result = resourceWrapper->GetColorByName(param->ToString());
6808         return true;
6809     }
6810 
6811     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6812     if (type == static_cast<int32_t>(ResourceType::STRING)) {
6813         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
6814         return Color::ParseColorString(value, result);
6815     }
6816     if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
6817         auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
6818         result = Color(ColorAlphaAdapt(value));
6819         return true;
6820     }
6821     if (type == static_cast<int32_t>(ResourceType::COLOR)) {
6822         result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
6823         result.SetResourceId(resId->ToNumber<uint32_t>());
6824         return true;
6825     }
6826     return false;
6827 }
6828 
CheckDarkResource(const RefPtr<ResourceObject> & resObj)6829 bool JSViewAbstract::CheckDarkResource(const RefPtr<ResourceObject>& resObj)
6830 {
6831     if (!SystemProperties::GetResourceDecoupling() || !resObj) {
6832         return false;
6833     }
6834     auto resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resObj);
6835     CHECK_NULL_RETURN(resourceAdapter, false);
6836 
6837     int32_t resId = resObj->GetId();
6838     bool hasDarkRes = false;
6839     auto params = resObj->GetParams();
6840     if (resId == -1 && !params.empty() && params.back().value.has_value()) {
6841         hasDarkRes = resourceAdapter->ExistDarkResByName(params.back().value.value(),
6842             std::to_string(resObj->GetType()));
6843     } else {
6844         hasDarkRes = resourceAdapter->ExistDarkResById(std::to_string(resId));
6845     }
6846     return hasDarkRes;
6847 }
6848 
CompleteResourceObjectFromColor(RefPtr<ResourceObject> & resObj,Color & color,bool state)6849 void JSViewAbstract::CompleteResourceObjectFromColor(RefPtr<ResourceObject>& resObj,
6850     Color& color, bool state)
6851 {
6852     if (!state || !SystemProperties::ConfigChangePerform()) {
6853         return;
6854     }
6855 
6856     auto node = NG::ViewStackProcessor::GetInstance()->GetMainElementNode();
6857     CHECK_NULL_VOID(node);
6858 
6859     auto instanceId = Container::CurrentIdSafely();
6860     auto nodeTag = node->GetTag();
6861     auto invertFunc = ColorInverter::GetInstance().GetInvertFunc(instanceId, nodeTag);
6862     CHECK_NULL_VOID(invertFunc);
6863 
6864     auto localColorMode = node->GetLocalColorMode();
6865     if (localColorMode == ColorMode::LIGHT) {
6866         resObj = nullptr;
6867         return;
6868     }
6869     bool hasDarkRes = CheckDarkResource(resObj);
6870     if (localColorMode == ColorMode::DARK) {
6871         if (!hasDarkRes) {
6872             color = Color(invertFunc(color.GetValue()));
6873         }
6874         resObj = nullptr;
6875         return;
6876     }
6877     auto colorMode = Container::CurrentColorMode();
6878     Color curColor = color;
6879     if ((colorMode == ColorMode::DARK) && !hasDarkRes) {
6880         color = Color(invertFunc(color.GetValue()));
6881     }
6882     if (!resObj) {
6883         resObj = AceType::MakeRefPtr<ResourceObject>();
6884         resObj->SetIsResource(false);
6885         resObj->SetInstanceId(instanceId);
6886     }
6887     resObj->SetNodeTag(nodeTag);
6888     resObj->SetColorMode(colorMode);
6889     resObj->SetHasDarkRes(hasDarkRes);
6890     resObj->SetColor(((colorMode == ColorMode::DARK) ? curColor : color));
6891 }
6892 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)6893 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
6894 {
6895     RefPtr<ResourceObject> resObj;
6896     return ParseJsColor(jsValue, result, resObj);
6897 }
6898 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,RefPtr<ResourceObject> & resObj)6899 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result,
6900     RefPtr<ResourceObject>& resObj)
6901 {
6902     bool state = false;
6903     if (jsValue->IsNumber()) {
6904         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
6905         CompleteResourceObjectFromColor(resObj, result, true);
6906         return true;
6907     }
6908     if (jsValue->IsString()) {
6909         state = Color::ParseColorString(jsValue->ToString(), result);
6910         CompleteResourceObjectFromColor(resObj, result, state);
6911         return state;
6912     }
6913     if (jsValue->IsObject()) {
6914         if (ParseColorMetricsToColor(jsValue, result, resObj)) {
6915             CompleteResourceObjectFromColor(resObj, result, true);
6916             return true;
6917         }
6918         state = ParseJsColorFromResource(jsValue, result, resObj);
6919         CompleteResourceObjectFromColor(resObj, result, state);
6920         return state;
6921     }
6922     return state;
6923 }
6924 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)6925 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
6926 {
6927     RefPtr<ResourceObject> resObj;
6928     return ParseJsColor(jsValue, result, defaultColor, resObj);
6929 }
6930 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor,RefPtr<ResourceObject> & resObj)6931 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result,
6932     const Color& defaultColor, RefPtr<ResourceObject>& resObj)
6933 {
6934     bool state = false;
6935     if (jsValue->IsNumber()) {
6936         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
6937         CompleteResourceObjectFromColor(resObj, result, true);
6938         return true;
6939     }
6940     if (jsValue->IsString()) {
6941         state = Color::ParseColorString(jsValue->ToString(), result, defaultColor);
6942         CompleteResourceObjectFromColor(resObj, result, state);
6943         return state;
6944     }
6945     if (!jsValue->IsObject()) {
6946         return state;
6947     }
6948     state = ParseJsColorFromResource(jsValue, result, resObj);
6949     CompleteResourceObjectFromColor(resObj, result, state);
6950     return state;
6951 }
6952 
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)6953 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
6954 {
6955     if (jsValue->IsString()) {
6956         std::string colorStr = jsValue->ToString();
6957         if (colorStr.compare("invert") == 0) {
6958             strategy = ForegroundColorStrategy::INVERT;
6959             return true;
6960         }
6961     }
6962     return false;
6963 }
6964 
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)6965 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
6966 {
6967     if (jsValue->IsString()) {
6968         std::string colorStr = jsValue->ToString();
6969         if (colorStr.compare("average") == 0) {
6970             strategy = ShadowColorStrategy::AVERAGE;
6971             return true;
6972         } else if (colorStr.compare("primary") == 0) {
6973             strategy = ShadowColorStrategy::PRIMARY;
6974             return true;
6975         }
6976     }
6977     return false;
6978 }
6979 
ParseJsSymbolCustomFamilyNames(std::vector<std::string> & customFamilyNames,const JSRef<JSVal> & jsValue)6980 void JSViewAbstract::ParseJsSymbolCustomFamilyNames(std::vector<std::string>& customFamilyNames,
6981     const JSRef<JSVal>& jsValue)
6982 {
6983     if (jsValue->IsNull() || jsValue->IsUndefined()) {
6984         return;
6985     }
6986     if (!jsValue->IsObject()) {
6987         return;
6988     }
6989     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6990     CompleteResourceObject(jsObj);
6991     JSRef<JSVal> resId = jsObj->GetProperty("id");
6992     if (resId->IsNull() || !resId->IsNumber()) {
6993         return;
6994     }
6995     auto resourceObject = GetResourceObject(jsObj);
6996     std::string bundleName = resourceObject->GetBundleName();
6997     std::string moduleName = resourceObject->GetModuleName();
6998     auto customSymbolFamilyName = bundleName + "_" + moduleName + CUSTOM_SYMBOL_SUFFIX;
6999     std::replace(customSymbolFamilyName.begin(), customSymbolFamilyName.end(), '.', '_');
7000     customFamilyNames.push_back(customSymbolFamilyName);
7001 }
7002 
CheckResource(RefPtr<ResourceObject> resourceObject,RefPtr<ResourceWrapper> resourceWrapper)7003 bool JSViewAbstract::CheckResource(RefPtr<ResourceObject> resourceObject, RefPtr<ResourceWrapper> resourceWrapper)
7004 {
7005     if (!resourceWrapper) {
7006         return false;
7007     }
7008     if (!resourceObject) {
7009         return false;
7010     }
7011     return true;
7012 }
7013 
CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper,JSRef<JSVal> & resId,std::uint32_t & symbolId)7014 bool JSViewAbstract::CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper, JSRef<JSVal>& resId,
7015     std::uint32_t& symbolId)
7016 {
7017     auto strValue = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
7018     if (!strValue.empty()) {
7019         auto customSymbolId = static_cast<uint32_t>(strtol(strValue.c_str(), nullptr, 16));
7020         symbolId = customSymbolId;
7021         return true;
7022     }
7023     return false;
7024 }
7025 
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)7026 bool JSViewAbstract::ParseJsSymbolId(
7027     const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
7028 {
7029     if (jsValue->IsNull() || jsValue->IsUndefined()) {
7030         symbolId = 0;
7031         return false;
7032     }
7033     if (jsValue->IsNumber()) {
7034         symbolId = jsValue->ToNumber<uint32_t>();
7035         return true;
7036     }
7037     if (!jsValue->IsObject()) {
7038         return false;
7039     }
7040     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7041     CompleteResourceObject(jsObj);
7042     JSRef<JSVal> resId = jsObj->GetProperty("id");
7043     if (resId->IsNull() || !resId->IsNumber()) {
7044         return false;
7045     }
7046     auto resourceObject = GetResourceObject(jsObj);
7047     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
7048     symbolResourceObject = resourceObject;
7049     int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
7050     if (type == static_cast<int32_t>(ResourceType::STRING) && CheckCustomSymbolId(resourceWrapper, resId, symbolId)) {
7051         return true;
7052     }
7053     if (!CheckResource(resourceObject, resourceWrapper)) {
7054         return false;
7055     }
7056     auto resIdNum = resId->ToNumber<int32_t>();
7057     if (resIdNum == -1) {
7058         if (!IsGetResourceByName(jsObj)) {
7059             return false;
7060         }
7061         JSRef<JSVal> args = jsObj->GetProperty("params");
7062         if (!args->IsArray()) {
7063             return false;
7064         }
7065         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7066         auto param = params->GetValueAt(0);
7067         auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
7068         if (!symbol) {
7069             return false;
7070         }
7071         symbolId = symbol;
7072         return true;
7073     }
7074 
7075     auto symbol = resourceWrapper->GetSymbolById(resIdNum);
7076     if (!symbol) {
7077         return false;
7078     }
7079     symbolId = symbol;
7080     return true;
7081 }
7082 
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result,bool enableResourceUpdate,std::vector<std::pair<int32_t,RefPtr<ResourceObject>>> & resObjArr)7083 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result,
7084     bool enableResourceUpdate, std::vector<std::pair<int32_t, RefPtr<ResourceObject>>>& resObjArr)
7085 {
7086     if (!jsValue->IsArray()) {
7087         return false;
7088     }
7089     JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
7090     for (size_t i = 0; i < array->Length(); i++) {
7091         JSRef<JSVal> value = array->GetValueAt(i);
7092         if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
7093             return false;
7094         }
7095         RefPtr<ResourceObject> resObj;
7096         Color color;
7097         if (value->IsNumber()) {
7098             color = Color(ColorAlphaAdapt(value->ToNumber<uint32_t>()));
7099         } else if (value->IsString()) {
7100             Color::ParseColorString(value->ToString(), color);
7101         } else {
7102             ParseJsColorFromResource(value, color, resObj);
7103         }
7104 
7105         result.emplace_back(color);
7106         CompleteResourceObjectFromColor(resObj, color, true);
7107         if (enableResourceUpdate && resObj) {
7108             std::pair<int32_t, RefPtr<ResourceObject>> pair(i, resObj);
7109             resObjArr.push_back(pair);
7110         }
7111     }
7112     return true;
7113 }
7114 
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)7115 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
7116 {
7117     RefPtr<ResourceObject> resObj;
7118     return ParseJsFontFamilies(jsValue, result, resObj);
7119 }
7120 
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result,RefPtr<ResourceObject> & resObj)7121 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result,
7122     RefPtr<ResourceObject>& resObj)
7123 {
7124     result.clear();
7125     if (!jsValue->IsString() && !jsValue->IsObject()) {
7126         return false;
7127     }
7128     if (jsValue->IsString()) {
7129         result = ConvertStrToFontFamilies(jsValue->ToString());
7130         return true;
7131     }
7132     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7133     CompleteResourceObject(jsObj);
7134     JSRef<JSVal> resId = jsObj->GetProperty("id");
7135     if (!resId->IsNumber()) {
7136         return false;
7137     }
7138 
7139     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7140         GetResourceObjectByBundleAndModule(jsObj);
7141     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7142     if (!resourceWrapper) {
7143         return false;
7144     }
7145 
7146     auto resIdNum = resId->ToNumber<int32_t>();
7147     if (resIdNum == -1) {
7148         if (!IsGetResourceByName(jsObj)) {
7149             return false;
7150         }
7151         JSRef<JSVal> args = jsObj->GetProperty("params");
7152         if (!args->IsArray()) {
7153             return false;
7154         }
7155         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7156         auto param = params->GetValueAt(0);
7157         result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
7158         return true;
7159     }
7160     result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
7161     return true;
7162 }
7163 
ParseJsStringObj(const JSRef<JSVal> & jsValue,std::string & result,RefPtr<ResourceObject> & resObj)7164 bool JSViewAbstract::ParseJsStringObj(const JSRef<JSVal>& jsValue, std::string& result,
7165     RefPtr<ResourceObject>& resObj)
7166 {
7167     if (!jsValue->IsObject()) {
7168         return false;
7169     }
7170     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7171     CompleteResourceObject(jsObj);
7172     JSRef<JSVal> resId = jsObj->GetProperty("id");
7173     if (!resId->IsNumber()) {
7174         return false;
7175     }
7176     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
7177     if (type == UNKNOWN_RESOURCE_TYPE) {
7178         return false;
7179     }
7180     JSRef<JSVal> args = jsObj->GetProperty("params");
7181     if (!args->IsArray()) {
7182         return false;
7183     }
7184     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7185         GetResourceObjectByBundleAndModule(jsObj);
7186     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7187     if (!resourceWrapper) {
7188         return false;
7189     }
7190     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7191     auto resIdNum = resId->ToNumber<int32_t>();
7192     if (resIdNum == -1) {
7193         if (!IsGetResourceByName(jsObj)) {
7194             return false;
7195         }
7196         auto param = params->GetValueAt(0);
7197         if (type == static_cast<int32_t>(ResourceType::STRING)) {
7198             auto originStr = resourceWrapper->GetStringByName(param->ToString());
7199             ReplaceHolder(originStr, params, 1);
7200             result = originStr;
7201         } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
7202             auto countJsVal = params->GetValueAt(1);
7203             int count = 0;
7204             if (!countJsVal->IsNumber()) {
7205                 return false;
7206             }
7207             count = countJsVal->ToNumber<int>();
7208             auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
7209             ReplaceHolder(pluralStr, params, 2); // params[2] applys pluralStr.
7210             result = pluralStr;
7211         } else {
7212             return false;
7213         }
7214         return true;
7215     }
7216     if (type == static_cast<int32_t>(ResourceType::STRING)) {
7217         auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
7218         ReplaceHolder(originStr, params, 0);
7219         result = originStr;
7220     } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
7221         auto countJsVal = params->GetValueAt(0);
7222         int count = 0;
7223         if (!countJsVal->IsNumber()) {
7224             return false;
7225         }
7226         count = countJsVal->ToNumber<int>();
7227         auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
7228         ReplaceHolder(pluralStr, params, 1);
7229         result = pluralStr;
7230     } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
7231         result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
7232     } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
7233         result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
7234     } else {
7235         return false;
7236     }
7237     return true;
7238 }
7239 
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)7240 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
7241 {
7242     RefPtr<ResourceObject> resObj;
7243     return ParseJsString(jsValue, result, resObj);
7244 }
7245 
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result,RefPtr<ResourceObject> & resObj)7246 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result,
7247     RefPtr<ResourceObject>& resObj)
7248 {
7249     if (jsValue->IsString()) {
7250         result = jsValue->ToString();
7251         return true;
7252     }
7253     return ParseJsStringObj(jsValue, result, resObj);
7254 }
7255 
ParseJsString(const JSRef<JSVal> & jsValue,std::u16string & result)7256 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::u16string& result)
7257 {
7258     RefPtr<ResourceObject> resObj;
7259     return ParseJsString(jsValue, result, resObj);
7260 }
7261 
ParseJsString(const JSRef<JSVal> & jsValue,std::u16string & result,RefPtr<ResourceObject> & resObj)7262 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::u16string& result,
7263     RefPtr<ResourceObject>& resObj)
7264 {
7265     std::string u8Result;
7266     if (jsValue->IsString()) {
7267         result = jsValue->ToU16String();
7268         return true;
7269     }
7270     bool ret = ParseJsStringObj(jsValue, u8Result, resObj);
7271     if (ret) {
7272         result = UtfUtils::Str8DebugToStr16(u8Result);
7273         return true;
7274     }
7275     return false;
7276 }
7277 
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result,RefPtr<ResourceObject> & resObj)7278 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result,
7279     RefPtr<ResourceObject>& resObj)
7280 {
7281     if (!jsValue->IsObject() && !jsValue->IsString()) {
7282         return false;
7283     }
7284     if (jsValue->IsString()) {
7285         result = jsValue->ToString();
7286         return true;
7287     }
7288     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7289     CompleteResourceObject(jsObj);
7290     return ParseJSMediaInternal(jsObj, result, resObj);
7291 }
7292 
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)7293 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
7294 {
7295     RefPtr<ResourceObject> resObj;
7296     return ParseJsMedia(jsValue, result, resObj);
7297 }
7298 
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)7299 bool JSViewAbstract::ParseJsMediaWithBundleName(
7300     const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
7301 {
7302     RefPtr<ResourceObject> resObj;
7303     return ParseJsMediaWithBundleName(jsValue, result, bundleName, moduleName, resId, resObj);
7304 }
7305 
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId,RefPtr<ResourceObject> & resObj)7306 bool JSViewAbstract::ParseJsMediaWithBundleName(
7307     const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName,
7308     int32_t& resId, RefPtr<ResourceObject>& resObj)
7309 {
7310     if (!jsValue->IsObject() && !jsValue->IsString()) {
7311         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
7312     }
7313     if (jsValue->IsString()) {
7314         result = jsValue->ToString();
7315         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
7316     }
7317     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7318     CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
7319     return ParseJSMediaInternal(jsObj, result, resObj);
7320 }
7321 
ParseJSMediaWithRawFile(const JSRef<JSObject> & jsObj,std::string & result,RefPtr<ResourceWrapper> & resourceWrapper)7322 bool JSViewAbstract::ParseJSMediaWithRawFile(const JSRef<JSObject>& jsObj, std::string& result,
7323     RefPtr<ResourceWrapper>& resourceWrapper)
7324 {
7325     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
7326     if (!args->IsArray()) {
7327         return false;
7328     }
7329     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7330     auto fileName = params->GetValueAt(0);
7331     if (!fileName->IsString()) {
7332         return false;
7333     }
7334     result = resourceWrapper->GetRawfile(fileName->ToString());
7335     return true;
7336 }
7337 
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result,RefPtr<ResourceObject> & resObj)7338 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result,
7339     RefPtr<ResourceObject>& resObj)
7340 {
7341     int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
7342     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
7343     if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
7344         resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7345             GetResourceObjectByBundleAndModule(jsObj);
7346         auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7347         CHECK_NULL_RETURN(resourceWrapper, false);
7348         if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
7349             return JSViewAbstract::ParseJSMediaWithRawFile(jsObj, result, resourceWrapper);
7350         }
7351         auto resIdNum = resId->ToNumber<int32_t>();
7352         if (resIdNum == -1) {
7353             if (!IsGetResourceByName(jsObj)) {
7354                 return false;
7355             }
7356             JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
7357             if (!args->IsArray()) {
7358                 return false;
7359             }
7360             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7361             auto param = params->GetValueAt(0);
7362             if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
7363                 result = resourceWrapper->GetMediaPathByName(param->ToString());
7364                 return true;
7365             }
7366             if (type == static_cast<int32_t>(ResourceType::STRING)) {
7367                 result = resourceWrapper->GetStringByName(param->ToString());
7368                 return true;
7369             }
7370             return false;
7371         } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
7372             result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
7373             return true;
7374         } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
7375             result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
7376             return true;
7377         }
7378     }
7379     return false;
7380 }
7381 
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)7382 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
7383     const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
7384 {
7385     auto vm = info.GetVm();
7386     auto globalObj = JSNApi::GetGlobalObject(vm);
7387     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
7388     JsiValue jsiValue(globalFunc);
7389     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
7390     if (!globalFuncRef->IsFunction()) {
7391         return;
7392     }
7393     if (modifierNormalObj->IsUndefined()) {
7394         symbolApply.onApply = nullptr;
7395     } else {
7396         RefPtr<JsFunction> jsFunc =
7397             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
7398         auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
7399                            modifierNormal = std::move(modifierNormalObj),
7400                            modifierSelected = std::move(modifierSelectedObj)](
7401                            WeakPtr<NG::FrameNode> frameNode, std::string type) {
7402             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7403             auto node = frameNode.Upgrade();
7404             CHECK_NULL_VOID(node);
7405             JSRef<JSVal> params[SECOND_INDEX];
7406             if (type == "normal") {
7407                 params[0] = modifierNormal;
7408             } else if (!modifierSelected->IsUndefined()) {
7409                 params[0] = modifierSelected;
7410             }
7411             params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
7412             PipelineContext::SetCallBackNode(node);
7413             func->ExecuteJS(SECOND_INDEX, params);
7414         };
7415         symbolApply.onApply = onApply;
7416     }
7417 }
7418 
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)7419 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
7420 {
7421     RefPtr<ResourceObject> resObj;
7422     return ParseJsBool(jsValue, result, resObj);
7423 }
7424 
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result,RefPtr<ResourceObject> & resObj)7425 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result,
7426     RefPtr<ResourceObject>& resObj)
7427 {
7428     if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
7429         return false;
7430     }
7431 
7432     if (jsValue->IsBoolean()) {
7433         result = jsValue->ToBoolean();
7434         return true;
7435     }
7436 
7437     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7438     CompleteResourceObject(jsObj);
7439     int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
7440     if (resType == UNKNOWN_RESOURCE_TYPE) {
7441         return false;
7442     }
7443 
7444     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
7445     if (!resId->IsNumber()) {
7446         return false;
7447     }
7448 
7449     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7450         GetResourceObjectByBundleAndModule(jsObj);
7451     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7452     if (!resourceWrapper) {
7453         return false;
7454     }
7455 
7456     auto resIdNum = resId->ToNumber<int32_t>();
7457     if (resIdNum == -1) {
7458         if (!IsGetResourceByName(jsObj)) {
7459             return false;
7460         }
7461         JSRef<JSVal> args = jsObj->GetProperty("params");
7462         if (!args->IsArray()) {
7463             return false;
7464         }
7465         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7466         auto param = params->GetValueAt(0);
7467         if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
7468             result = resourceWrapper->GetBooleanByName(param->ToString());
7469             return true;
7470         }
7471         return false;
7472     }
7473 
7474     if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
7475         result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
7476         return true;
7477     }
7478     return false;
7479 }
7480 
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)7481 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
7482 {
7483     return ParseJsInteger<uint32_t>(jsValue, result);
7484 }
7485 
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)7486 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
7487 {
7488     return ParseJsInteger<int32_t>(jsValue, result);
7489 }
7490 
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)7491 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
7492 {
7493     RefPtr<ResourceObject> resObj;
7494     std::vector<RefPtr<ResourceObject>> resObjArray;
7495     return ParseJsIntegerArray(jsValue, result, resObj, resObjArray);
7496 }
7497 
ParseJsIntegerArrayInternal(const JSRef<JSArray> & jsArray,std::vector<uint32_t> & result,std::vector<RefPtr<ResourceObject>> & resObjArray)7498 bool JSViewAbstract::ParseJsIntegerArrayInternal(const JSRef<JSArray>& jsArray, std::vector<uint32_t>& result,
7499     std::vector<RefPtr<ResourceObject>>& resObjArray)
7500 {
7501     for (size_t i = 0; i < jsArray->Length(); i++) {
7502         RefPtr<ResourceObject> resObj;
7503         JSRef<JSVal> value = jsArray->GetValueAt(i);
7504         if (value->IsNumber()) {
7505             result.emplace_back(value->ToNumber<uint32_t>());
7506         } else if (value->IsObject()) {
7507             uint32_t singleResInt;
7508             if (ParseJsInteger(value, singleResInt, resObj)) {
7509                 result.emplace_back(singleResInt);
7510             } else {
7511                 resObjArray.clear();
7512                 return false;
7513             }
7514         } else {
7515             resObjArray.clear();
7516             return false;
7517         }
7518         resObjArray.emplace_back(resObj);
7519     }
7520     return true;
7521 }
7522 
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result,RefPtr<ResourceObject> & resObj,std::vector<RefPtr<ResourceObject>> & resObjArray)7523 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result,
7524     RefPtr<ResourceObject>& resObj, std::vector<RefPtr<ResourceObject>>& resObjArray)
7525 {
7526     if (!jsValue->IsArray() && !jsValue->IsObject()) {
7527         return false;
7528     }
7529     if (jsValue->IsArray()) {
7530         JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(jsValue);
7531         return ParseJsIntegerArrayInternal(jsArray, result, resObjArray);
7532     }
7533     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7534     CompleteResourceObject(jsObj);
7535     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
7536     if (resType == UNKNOWN_RESOURCE_TYPE) {
7537         return false;
7538     }
7539     JSRef<JSVal> resId = jsObj->GetProperty("id");
7540     if (!resId->IsNumber()) {
7541         return false;
7542     }
7543     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7544         GetResourceObjectByBundleAndModule(jsObj);
7545     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7546     if (!resourceWrapper) {
7547         return false;
7548     }
7549     auto resIdNum = resId->ToNumber<int32_t>();
7550     if (resIdNum == -1) {
7551         if (!IsGetResourceByName(jsObj)) {
7552             return false;
7553         }
7554         JSRef<JSVal> args = jsObj->GetProperty("params");
7555         if (!args->IsArray()) {
7556             return false;
7557         }
7558         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7559         auto param = params->GetValueAt(0);
7560         if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
7561             result = resourceWrapper->GetIntArrayByName(param->ToString());
7562             return true;
7563         }
7564         return false;
7565     }
7566     if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
7567         result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
7568         return true;
7569     }
7570     return false;
7571 }
7572 
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)7573 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
7574 {
7575     RefPtr<ResourceObject> resObj;
7576     std::vector<RefPtr<ResourceObject>> resObjArray;
7577     return ParseJsStrArray(jsValue, result, resObj, resObjArray);
7578 }
7579 
ParseJsStrArrayInternal(const JSRef<JSArray> & jsArray,std::vector<std::string> & result,std::vector<RefPtr<ResourceObject>> & resObjArray)7580 bool JSViewAbstract::ParseJsStrArrayInternal(const JSRef<JSArray>& jsArray, std::vector<std::string>& result,
7581     std::vector<RefPtr<ResourceObject>>& resObjArray)
7582 {
7583     for (size_t i = 0; i < jsArray->Length(); i++) {
7584         RefPtr<ResourceObject> resObj;
7585         JSRef<JSVal> value = jsArray->GetValueAt(i);
7586         if (value->IsString()) {
7587             result.emplace_back(value->ToString());
7588         } else if (value->IsObject()) {
7589             std::string singleResStr;
7590             if (ParseJsString(value, singleResStr, resObj)) {
7591                 result.emplace_back(singleResStr);
7592             } else {
7593                 resObjArray.clear();
7594                 return false;
7595             }
7596         } else {
7597             resObjArray.clear();
7598             return false;
7599         }
7600         resObjArray.emplace_back(resObj);
7601     }
7602     return true;
7603 }
7604 
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result,RefPtr<ResourceObject> & resObj,std::vector<RefPtr<ResourceObject>> & resObjArray)7605 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result,
7606     RefPtr<ResourceObject>& resObj, std::vector<RefPtr<ResourceObject>>& resObjArray)
7607 {
7608     if (!jsValue->IsArray() && !jsValue->IsObject()) {
7609         return false;
7610     }
7611     if (jsValue->IsArray()) {
7612         JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(jsValue);
7613         return ParseJsStrArrayInternal(jsArray, result, resObjArray);
7614     }
7615     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7616     CompleteResourceObject(jsObj);
7617     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
7618     if (resType == UNKNOWN_RESOURCE_TYPE) {
7619         return false;
7620     }
7621     JSRef<JSVal> resId = jsObj->GetProperty("id");
7622     if (!resId->IsNumber()) {
7623         return false;
7624     }
7625     resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7626         GetResourceObjectByBundleAndModule(jsObj);
7627     auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7628     if (!resourceWrapper) {
7629         return false;
7630     }
7631     auto resIdNum = resId->ToNumber<int32_t>();
7632     if (resIdNum == -1) {
7633         if (!IsGetResourceByName(jsObj)) {
7634             return false;
7635         }
7636         JSRef<JSVal> args = jsObj->GetProperty("params");
7637         if (!args->IsArray()) {
7638             return false;
7639         }
7640         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7641         auto param = params->GetValueAt(0);
7642         if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
7643             result = resourceWrapper->GetStringArrayByName(param->ToString());
7644             return true;
7645         }
7646         return false;
7647     }
7648     if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
7649         result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
7650         return true;
7651     }
7652     return false;
7653 }
7654 
ParseJsLengthMetricsArray(const JSRef<JSVal> & jsValue,std::vector<Dimension> & result)7655 bool JSViewAbstract::ParseJsLengthMetricsArray(const JSRef<JSVal>& jsValue, std::vector<Dimension>& result)
7656 {
7657     std::vector<RefPtr<ResourceObject>> resObjArray;
7658     return ParseJsLengthMetricsArray(jsValue, result, resObjArray);
7659 }
7660 
ParseJsLengthMetricsArray(const JSRef<JSVal> & jsValue,std::vector<Dimension> & result,std::vector<RefPtr<ResourceObject>> & resObjArray)7661 bool JSViewAbstract::ParseJsLengthMetricsArray(const JSRef<JSVal>& jsValue, std::vector<Dimension>& result,
7662     std::vector<RefPtr<ResourceObject>>& resObjArray)
7663 {
7664     if (jsValue->IsArray()) {
7665         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
7666         for (size_t i = 0; i < array->Length(); i++) {
7667             RefPtr<ResourceObject> resObj;
7668             JSRef<JSVal> value = array->GetValueAt(i);
7669             Dimension calc;
7670             ParseJsLengthMetricsToDimension(value, calc, resObj);
7671             result.emplace_back(calc);
7672             resObjArray.emplace_back(resObj);
7673         }
7674         return true;
7675     }
7676 
7677     return false;
7678 }
7679 
IsGetResourceByName(const JSRef<JSObject> & jsObj)7680 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
7681 {
7682     JSRef<JSVal> resId = jsObj->GetProperty("id");
7683     if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
7684         return false;
7685     }
7686     JSRef<JSVal> args = jsObj->GetProperty("params");
7687     if (!args->IsArray()) {
7688         return false;
7689     }
7690     JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
7691     JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
7692     if (!bundleName->IsString() || !moduleName->IsString()) {
7693         return false;
7694     }
7695     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7696     if (params->IsEmpty()) {
7697         return false;
7698     }
7699     return true;
7700 }
7701 
ParseSize(const JSCallbackInfo & info)7702 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
7703 {
7704     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7705     auto jsVal = info[0];
7706     if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
7707         return std::pair<CalcDimension, CalcDimension>();
7708     }
7709     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
7710     CalcDimension width;
7711     CalcDimension height;
7712     if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
7713         !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
7714         return std::pair<CalcDimension, CalcDimension>();
7715     }
7716     return std::pair<CalcDimension, CalcDimension>(width, height);
7717 }
7718 
JsUseAlign(const JSCallbackInfo & info)7719 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
7720 {
7721     if (info.Length() < 2) {
7722         return;
7723     }
7724 
7725     if (!info[0]->IsObject() && !info[1]->IsObject()) {
7726         return;
7727     }
7728 
7729     AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
7730     if (declaration == nullptr) {
7731         return;
7732     }
7733 
7734     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7735     JSRef<JSVal> side = obj->GetProperty("side");
7736     JSRef<JSVal> offset = obj->GetProperty("offset");
7737 
7738     if (!side->IsNumber()) {
7739         return;
7740     }
7741 
7742     auto sideValue = side->ToNumber<int32_t>();
7743 
7744     if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
7745         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
7746             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
7747             return;
7748         }
7749     } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
7750         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
7751             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
7752             return;
7753         }
7754     }
7755 
7756     std::optional<CalcDimension> optOffset;
7757     CalcDimension offsetDimension;
7758     if (ParseJsDimensionVp(offset, offsetDimension)) {
7759         optOffset = offsetDimension;
7760     }
7761     ViewAbstractModel::GetInstance()->SetUseAlign(
7762         declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
7763 }
7764 
JsGridSpan(const JSCallbackInfo & info)7765 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
7766 {
7767     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
7768     auto jsVal = info[0];
7769     if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
7770         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
7771             ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
7772         }
7773         return;
7774     }
7775     auto span = jsVal->ToNumber<int32_t>();
7776     ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
7777 }
7778 
JsGridOffset(const JSCallbackInfo & info)7779 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
7780 {
7781     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
7782     auto jsVal = info[0];
7783     if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
7784         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
7785             ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
7786         }
7787         return;
7788     }
7789     auto offset = jsVal->ToNumber<int32_t>();
7790     ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
7791 }
7792 
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)7793 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
7794 {
7795     // {lg: 4}
7796     if (val->IsNumber()) {
7797         span = val->ToNumber<uint32_t>();
7798         return true;
7799     }
7800 
7801     if (!val->IsObject()) {
7802         return false;
7803     }
7804 
7805     // {lg: {span: 1, offset: 2}}
7806     JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
7807     span = obj->GetProperty("span")->ToNumber<uint32_t>();
7808     offset = obj->GetProperty("offset")->ToNumber<int32_t>();
7809     return true;
7810 }
7811 
JsUseSizeType(const JSCallbackInfo & info)7812 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
7813 {
7814     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7815     auto jsVal = info[0];
7816     if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
7817         return;
7818     }
7819     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
7820     for (auto values : SCREEN_SIZE_VALUES) {
7821         JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
7822         if (val->IsNull() || val->IsEmpty()) {
7823             continue;
7824         }
7825         uint32_t span = 0;
7826         int32_t offset = 0;
7827         if (ParseSpanAndOffset(val, span, offset)) {
7828             ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
7829         }
7830     }
7831 }
7832 
JsZIndex(const JSCallbackInfo & info)7833 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
7834 {
7835     int zIndex = 0;
7836     if (info[0]->IsNumber()) {
7837         zIndex = info[0]->ToNumber<int>();
7838     }
7839 
7840     ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
7841 }
7842 
Pop()7843 void JSViewAbstract::Pop()
7844 {
7845     if (ViewStackModel::GetInstance()->IsPrebuilding()) {
7846         return ViewStackModel::GetInstance()->PushPrebuildCompCmd("[JSViewAbstract][pop]", &JSViewAbstract::Pop);
7847     }
7848     ViewStackModel::GetInstance()->Pop();
7849 }
7850 
JsSetDraggable(bool draggable)7851 void JSViewAbstract::JsSetDraggable(bool draggable)
7852 {
7853     ViewAbstractModel::GetInstance()->SetDraggable(draggable);
7854 }
7855 
ParseDragInteractionOptions(const JSCallbackInfo & info,NG::DragPreviewOption & previewOption)7856 void JSViewAbstract::ParseDragInteractionOptions(const JSCallbackInfo& info,
7857     NG::DragPreviewOption& previewOption)
7858 {
7859     if (info.Length() > 1 && info[1]->IsObject()) {
7860         JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
7861         auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
7862         if (multiSelection->IsBoolean()) {
7863             previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
7864         }
7865         auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
7866         if (defaultAnimation->IsBoolean()) {
7867             previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
7868         }
7869         auto hapicFeedback = interObj->GetProperty("enableHapticFeedback");
7870         if (hapicFeedback->IsBoolean()) {
7871             previewOption.enableHapticFeedback = hapicFeedback->ToBoolean();
7872         }
7873         auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
7874         if (dragPreview->IsBoolean()) {
7875             previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
7876         }
7877         auto enableEdgeAutoScroll = interObj->GetProperty("enableEdgeAutoScroll");
7878         if (enableEdgeAutoScroll->IsBoolean()) {
7879             previewOption.enableEdgeAutoScroll = enableEdgeAutoScroll->ToBoolean();
7880         }
7881         auto isLiftingDisabled = interObj->GetProperty("isLiftingDisabled");
7882         if (isLiftingDisabled->IsBoolean()) {
7883             previewOption.isLiftingDisabled = isLiftingDisabled->ToBoolean();
7884         }
7885     }
7886 }
7887 
ParseDragPreviewOptions(const JSCallbackInfo & info)7888 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
7889 {
7890     NG::DragPreviewOption previewOption;
7891     if (!info[0]->IsObject()) {
7892         return previewOption;
7893     }
7894     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7895     auto mode = obj->GetProperty("mode");
7896     bool isAuto = true;
7897     if (mode->IsNumber()) {
7898         ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
7899     } else if (mode->IsArray()) {
7900         JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
7901         for (size_t i = 0; i < array->Length(); i++) {
7902             JSRef<JSVal> value = array->GetValueAt(i);
7903             if (value->IsNumber()) {
7904                 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
7905             }
7906             if (isAuto) {
7907                 break;
7908             }
7909         }
7910     }
7911 
7912     auto sizeChangeEffect = obj->GetProperty("sizeChangeEffect");
7913     if (sizeChangeEffect->IsNumber()) {
7914         previewOption.sizeChangeEffect = static_cast<NG::DraggingSizeChangeEffect>(sizeChangeEffect->ToNumber<int>());
7915     }
7916 
7917     JSViewAbstract::SetDragNumberBadge(info, previewOption);
7918 
7919     ParseDragInteractionOptions(info, previewOption);
7920 
7921     JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
7922 
7923     return previewOption;
7924 }
7925 
JsSetDragPreviewOptions(const JSCallbackInfo & info)7926 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
7927 {
7928     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7929     auto jsVal = info[0];
7930     if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
7931         return;
7932     }
7933     NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
7934     ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
7935 }
7936 
JsOnDragStart(const JSCallbackInfo & info)7937 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
7938 {
7939     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
7940     auto jsVal = info[0];
7941     if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
7942         return;
7943     }
7944 
7945     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
7946 
7947     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7948     auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
7949                            const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
7950         NG::DragDropBaseInfo dragDropInfo;
7951         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
7952         PipelineContext::SetCallBackNode(node);
7953         auto ret = func->Execute(info, extraParams);
7954         if (!ret->IsObject()) {
7955             return dragDropInfo;
7956         }
7957 
7958         dragDropInfo.node = ParseDragNode(ret);
7959         auto builderObj = JSRef<JSObject>::Cast(ret);
7960 #if defined(PIXEL_MAP_SUPPORTED)
7961         auto pixmap = builderObj->GetProperty("pixelMap");
7962         dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
7963 #endif
7964         auto extraInfo = builderObj->GetProperty("extraInfo");
7965         ParseJsString(extraInfo, dragDropInfo.extraInfo);
7966         return dragDropInfo;
7967     };
7968     ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
7969 }
7970 
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)7971 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
7972 {
7973     auto node = ParseDragNode(info);
7974     if (!node) {
7975         return false;
7976     }
7977     dragInfo.node = node;
7978     return true;
7979 }
7980 
ParseDragNode(const JSRef<JSVal> & info)7981 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
7982 {
7983     auto builderFunc = ParseDragStartBuilderFunc(info);
7984     if (!builderFunc) {
7985         return nullptr;
7986     }
7987     // use another VSP instance while executing the builder function
7988     ViewStackModel::GetInstance()->NewScope();
7989     {
7990         ACE_SCORING_EVENT("onDragStart.builder");
7991         builderFunc->Execute();
7992     }
7993 
7994     return ViewStackModel::GetInstance()->Finish();
7995 }
7996 
JsOnDragEnter(const JSCallbackInfo & info)7997 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
7998 {
7999     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8000     auto jsVal = info[0];
8001     if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
8002         return;
8003     }
8004     RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8005     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8006     auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
8007                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8008         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8009         ACE_SCORING_EVENT("onDragEnter");
8010         PipelineContext::SetCallBackNode(node);
8011         func->Execute(info, extraParams);
8012     };
8013 
8014     ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
8015 }
8016 
JsOnDragSpringLoading(const JSCallbackInfo & info)8017 void JSViewAbstract::JsOnDragSpringLoading(const JSCallbackInfo& info)
8018 {
8019     if (info.Length() > 0) {
8020         static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION, JSCallbackInfoType::OBJECT };
8021         auto jsVal = info[0];
8022         if (!CheckJSCallbackInfo("JsOnDragSpringLoading", jsVal, checkList)) {
8023             return;
8024         }
8025         NG::OnDragDropSpringLoadingFunc onDragSpringLoading = nullptr;
8026         WeakPtr<NG::FrameNode> frameNode =
8027             AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8028         if (jsVal->IsFunction()) {
8029             RefPtr<JsDragFunction> jsOnDragSpringLoadingFunc =
8030                 AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8031             onDragSpringLoading = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragSpringLoadingFunc),
8032                                       node = frameNode](const RefPtr<DragSpringLoadingContext>& info) {
8033                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8034                 ACE_SCORING_EVENT("JsOnDragSpringLoading");
8035                 PipelineContext::SetCallBackNode(node);
8036                 func->DragSpringLoadingExecute(info);
8037             };
8038         }
8039         ViewAbstractModel::GetInstance()->SetOnDragSpringLoading(std::move(onDragSpringLoading));
8040     }
8041     if (info.Length() == NUM2 && info[NUM1]->IsObject()) {
8042         auto dragSpringLoadingConfiguration = AceType::MakeRefPtr<NG::DragSpringLoadingConfiguration>();
8043         ParseDragSpringLoadingConfiguration(info[NUM1], dragSpringLoadingConfiguration);
8044         ViewAbstractModel::GetInstance()->SetOnDragSpringLoadingConfiguration(
8045             std::move(dragSpringLoadingConfiguration));
8046     }
8047 }
8048 
JsOnDragEnd(const JSCallbackInfo & info)8049 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
8050 {
8051     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8052     auto jsVal = info[0];
8053     if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
8054         return;
8055     }
8056     RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8057     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8058     auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
8059                          const RefPtr<OHOS::Ace::DragEvent>& info) {
8060         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8061         ACE_SCORING_EVENT("onDragEnd");
8062         auto extraParams = JsonUtil::Create(true);
8063         PipelineContext::SetCallBackNode(node);
8064         func->Execute(info, extraParams->ToString());
8065     };
8066 
8067     ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
8068 }
8069 
JsOnDragMove(const JSCallbackInfo & info)8070 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
8071 {
8072     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8073     auto jsVal = info[0];
8074     if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
8075         return;
8076     }
8077     RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8078     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8079     auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
8080                           const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8081         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8082         ACE_SCORING_EVENT("onDragMove");
8083         PipelineContext::SetCallBackNode(node);
8084         func->Execute(info, extraParams);
8085     };
8086 
8087     ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
8088 }
8089 
JsOnDragLeave(const JSCallbackInfo & info)8090 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
8091 {
8092     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8093     auto jsVal = info[0];
8094     if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
8095         return;
8096     }
8097     RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8098     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8099     auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
8100                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8101         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8102         ACE_SCORING_EVENT("onDragLeave");
8103         PipelineContext::SetCallBackNode(node);
8104         func->Execute(info, extraParams);
8105     };
8106 
8107     ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
8108 }
8109 
JsOnDrop(const JSCallbackInfo & info)8110 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
8111 {
8112     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8113     auto jsVal = info[0];
8114     if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
8115         return;
8116     }
8117     RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8118     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8119     auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
8120                       const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8121         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8122         ACE_SCORING_EVENT("onDrop");
8123         PipelineContext::SetCallBackNode(node);
8124         func->Execute(info, extraParams);
8125     };
8126 
8127     ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
8128 
8129     bool disableDataPrefetch = false;
8130     if (info.Length() > 1 && info[1]->IsObject()) {
8131         JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
8132         auto jsDisableDataPrefetch = interObj->GetProperty("disableDataPrefetch");
8133         if (jsDisableDataPrefetch->IsBoolean()) {
8134             disableDataPrefetch = jsDisableDataPrefetch->ToBoolean();
8135         }
8136     }
8137     ViewAbstractModel::GetInstance()->SetDisableDataPrefetch(disableDataPrefetch);
8138 }
8139 
JsOnAreaChange(const JSCallbackInfo & info)8140 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
8141 {
8142     auto jsVal = info[0];
8143     if (jsVal->IsUndefined() && IsDisableEventVersion()) {
8144         ViewAbstractModel::GetInstance()->DisableOnAreaChange();
8145         return;
8146     }
8147     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8148     if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
8149         return;
8150     }
8151     auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
8152 
8153     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8154     auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
8155                              node = frameNode](
8156                              const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
8157         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8158         ACE_SCORING_EVENT("onAreaChange");
8159         PipelineContext::SetCallBackNode(node);
8160         func->Execute(oldRect, oldOrigin, rect, origin);
8161     };
8162     ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
8163 }
8164 
JsOnSizeChange(const JSCallbackInfo & info)8165 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
8166 {
8167     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8168     auto jsVal = info[0];
8169     if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
8170         return;
8171     }
8172     auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
8173 
8174     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8175     auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
8176                              node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
8177         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8178         ACE_SCORING_EVENT("onSizeChange");
8179         PipelineContext::SetCallBackNode(node);
8180         func->Execute(oldRect, rect);
8181     };
8182     ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
8183 }
8184 
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)8185 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
8186 {
8187     if (!info[0]->IsObject()) {
8188         return;
8189     }
8190     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
8191     NewLinearGradient(jsObj, newGradient);
8192 }
8193 
NewLinearGradient(const JSRef<JSObject> & jsObj,NG::Gradient & newGradient)8194 void JSViewAbstract::NewLinearGradient(const JSRef<JSObject>& jsObj, NG::Gradient& newGradient)
8195 {
8196     newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
8197     // angle
8198     std::optional<float> degree;
8199     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
8200         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
8201     } else {
8202         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
8203     }
8204     if (degree) {
8205         newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
8206         degree.reset();
8207     }
8208     // direction
8209     auto direction = static_cast<GradientDirection>(
8210         jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
8211     SetGradientDirection(newGradient, direction);
8212     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
8213     newGradient.SetRepeat(repeating);
8214     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)), NUM_0);
8215 }
8216 
SetGradientDirection(NG::Gradient & newGradient,const GradientDirection & direction)8217 void JSViewAbstract::SetGradientDirection(NG::Gradient& newGradient, const GradientDirection& direction)
8218 {
8219     switch (direction) {
8220         case GradientDirection::LEFT:
8221             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
8222             break;
8223         case GradientDirection::RIGHT:
8224             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
8225             break;
8226         case GradientDirection::TOP:
8227             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
8228             break;
8229         case GradientDirection::BOTTOM:
8230             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
8231             break;
8232         case GradientDirection::LEFT_TOP:
8233             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
8234             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
8235             break;
8236         case GradientDirection::LEFT_BOTTOM:
8237             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
8238             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
8239             break;
8240         case GradientDirection::RIGHT_TOP:
8241             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
8242             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
8243             break;
8244         case GradientDirection::RIGHT_BOTTOM:
8245             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
8246             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
8247             break;
8248         default:
8249             break;
8250     }
8251 }
8252 
JsRadialGradient(const JSCallbackInfo & info)8253 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
8254 {
8255     ViewAbstractModel::GetInstance()->RemoveResObj("RadialGradient.gradient");
8256     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
8257     auto jsVal = info[0];
8258     if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
8259         NG::Gradient newGradient;
8260         newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
8261         ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
8262         return;
8263     }
8264     NG::Gradient newGradient;
8265     NewJsRadialGradient(info, newGradient);
8266     ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
8267 }
8268 
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)8269 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
8270 {
8271     JSRef<JSVal> arg = info[0];
8272     if (!arg->IsObject()) {
8273         return;
8274     }
8275     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
8276     NewRadialGradient(jsObj, newGradient);
8277 }
8278 
NewRadialGradient(const JSRef<JSObject> & jsObj,NG::Gradient & newGradient)8279 void JSViewAbstract::NewRadialGradient(const JSRef<JSObject>& jsObj, NG::Gradient& newGradient)
8280 {
8281     newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
8282     // center
8283     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
8284     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
8285         CalcDimension value;
8286         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
8287         ParseRadialGradientCenter(newGradient, center);
8288     }
8289     // radius
8290     CalcDimension radius;
8291     RefPtr<ResourceObject> resObj;
8292     if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius, resObj)) {
8293         newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
8294         newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
8295     }
8296     if (SystemProperties::ConfigChangePerform() && resObj) {
8297         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8298             CalcDimension dimension;
8299             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8300             gradient.GetRadialGradient()->radialVerticalSize = CalcDimension(dimension);
8301             gradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(dimension);
8302         };
8303         newGradient.AddResource("RadialGradient.radius", resObj, std::move(updateFunc));
8304     }
8305 
8306     // repeating
8307     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
8308     newGradient.SetRepeat(repeating);
8309     // color stops
8310     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)), NUM_2);
8311 }
8312 
ParseRadialGradientCenter(NG::Gradient & newGradient,JSRef<JSArray> centerArray)8313 void JSViewAbstract::ParseRadialGradientCenter(NG::Gradient& newGradient, JSRef<JSArray> centerArray)
8314 {
8315     RefPtr<ResourceObject> resObjX;
8316     RefPtr<ResourceObject> resObjY;
8317     CalcDimension value;
8318 
8319     if (ParseJsDimensionVp(centerArray->GetValueAt(0), value, resObjX)) {
8320         newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
8321         if (value.Unit() == DimensionUnit::PERCENT) {
8322             // [0,1] -> [0, 100]
8323             newGradient.GetRadialGradient()->radialCenterX =
8324                 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8325         }
8326     }
8327     if (SystemProperties::ConfigChangePerform() && resObjX) {
8328         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8329             CalcDimension dimension;
8330             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8331             gradient.GetRadialGradient()->radialCenterX = CalcDimension(dimension);
8332             if (dimension.Unit() == DimensionUnit::PERCENT) {
8333                 // [0,1] -> [0, 100]
8334                 gradient.GetRadialGradient()->radialCenterX =
8335                     CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8336             }
8337         };
8338         newGradient.AddResource("RadialGradient.center.centerX", resObjX, std::move(updateFunc));
8339     }
8340     if (ParseJsDimensionVp(centerArray->GetValueAt(1), value, resObjY)) {
8341         newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
8342         if (value.Unit() == DimensionUnit::PERCENT) {
8343             // [0,1] -> [0, 100]
8344             newGradient.GetRadialGradient()->radialCenterY =
8345                 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8346         }
8347     }
8348     if (SystemProperties::ConfigChangePerform() && resObjY) {
8349         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8350             CalcDimension dimension;
8351             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8352             gradient.GetRadialGradient()->radialCenterY = CalcDimension(dimension);
8353             if (dimension.Unit() == DimensionUnit::PERCENT) {
8354                 // [0,1] -> [0, 100]
8355                 gradient.GetRadialGradient()->radialCenterY =
8356                     CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8357             }
8358         };
8359         newGradient.AddResource("RadialGradient.center.centerY", resObjY, std::move(updateFunc));
8360     }
8361 }
8362 
JsSweepGradient(const JSCallbackInfo & info)8363 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
8364 {
8365     ViewAbstractModel::GetInstance()->RemoveResObj("SweepGradient.gradient");
8366     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
8367     auto jsVal = info[0];
8368     if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
8369         NG::Gradient newGradient;
8370         newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
8371         ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
8372         return;
8373     }
8374 
8375     NG::Gradient newGradient;
8376     NewJsSweepGradient(info, newGradient);
8377     ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
8378 }
8379 
ParseSweepGradientCenter(NG::Gradient & newGradient,JSRef<JSArray> centerArray)8380 void JSViewAbstract::ParseSweepGradientCenter(NG::Gradient& newGradient, JSRef<JSArray> centerArray)
8381 {
8382     RefPtr<ResourceObject> resObjX;
8383     RefPtr<ResourceObject> resObjY;
8384     CalcDimension value;
8385     if (ParseJsDimensionVp(centerArray->GetValueAt(0), value, resObjX)) {
8386         newGradient.GetSweepGradient()->centerX = CalcDimension(value);
8387         if (value.Unit() == DimensionUnit::PERCENT) {
8388             // [0,1] -> [0, 100]
8389             newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8390         }
8391     }
8392     if (SystemProperties::ConfigChangePerform() && resObjX) {
8393         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8394             CalcDimension dimension;
8395             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8396             gradient.GetSweepGradient()->centerX = CalcDimension(dimension);
8397             if (dimension.Unit() == DimensionUnit::PERCENT) {
8398                 // [0,1] -> [0, 100]
8399                 gradient.GetSweepGradient()->centerX = CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8400             }
8401         };
8402         newGradient.AddResource("SweepGradient.center.centerX", resObjX, std::move(updateFunc));
8403     }
8404     if (ParseJsDimensionVp(centerArray->GetValueAt(1), value, resObjY)) {
8405         newGradient.GetSweepGradient()->centerY = CalcDimension(value);
8406         if (value.Unit() == DimensionUnit::PERCENT) {
8407             // [0,1] -> [0, 100]
8408             newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8409         }
8410     }
8411     if (SystemProperties::ConfigChangePerform() && resObjY) {
8412         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8413             CalcDimension dimension;
8414             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8415             gradient.GetSweepGradient()->centerY = CalcDimension(dimension);
8416             if (dimension.Unit() == DimensionUnit::PERCENT) {
8417                 // [0,1] -> [0, 100]
8418                 gradient.GetSweepGradient()->centerY = CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8419             }
8420         };
8421         newGradient.AddResource("SweepGradient.center.centerY", resObjY, std::move(updateFunc));
8422     }
8423 }
8424 
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)8425 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
8426 {
8427     JSRef<JSVal> arg = info[0];
8428     if (!arg->IsObject()) {
8429         return;
8430     }
8431     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
8432     newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
8433     // center
8434     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
8435     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
8436         CalcDimension value;
8437         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
8438         ParseSweepGradientCenter(newGradient, centerArray);
8439     }
8440     // start, end and rotation
8441     ParseSweepGradientPartly(jsObj, newGradient);
8442     // repeating
8443     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
8444     newGradient.SetRepeat(repeating);
8445     // color stops
8446     JSRef<JSVal> metricColors = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::METRICS_COLORS));
8447     if (metricColors->IsArray()) {
8448         NewGetJsGradientColorStopsCheck(newGradient, metricColors);
8449     } else {
8450         NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)), NUM_1);
8451     }
8452 }
8453 
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)8454 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
8455 {
8456     std::optional<float> degreeStart;
8457     std::optional<float> degreeEnd;
8458     std::optional<float> degreeRotation;
8459     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
8460         GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
8461         GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
8462         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
8463     } else {
8464         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
8465         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
8466         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
8467     }
8468     if (degreeStart) {
8469         CheckAngle(degreeStart);
8470         newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
8471     }
8472     if (degreeEnd) {
8473         CheckAngle(degreeEnd);
8474         newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
8475     }
8476     if (degreeRotation) {
8477         CheckAngle(degreeRotation);
8478         newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
8479     }
8480 }
8481 
JsMotionPath(const JSCallbackInfo & info)8482 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
8483 {
8484     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
8485     auto jsVal = info[0];
8486     if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
8487         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
8488         return;
8489     }
8490     MotionPathOption motionPathOption;
8491     if (ParseMotionPath(jsVal, motionPathOption)) {
8492         ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
8493     } else {
8494         TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
8495         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
8496     }
8497 }
8498 
JsShadow(const JSCallbackInfo & info)8499 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
8500 {
8501     ViewAbstractModel::GetInstance()->RemoveResObj("shadow");
8502     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
8503     auto jsVal = info[0];
8504     if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
8505         Shadow shadow;
8506         std::vector<Shadow> shadows { shadow };
8507         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8508         return;
8509     }
8510     Shadow shadow;
8511     if (!ParseShadowProps(jsVal, shadow, SystemProperties::ConfigChangePerform())) {
8512         info.ReturnSelf();
8513         return;
8514     }
8515     std::vector<Shadow> shadows { shadow };
8516     ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8517 }
8518 
JsBlendMode(const JSCallbackInfo & info)8519 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
8520 {
8521     if (info.Length() == 0) {
8522         return;
8523     }
8524     BlendMode blendMode = BlendMode::NONE;
8525     BlendApplyType blendApplyType = BlendApplyType::FAST;
8526     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
8527     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
8528     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
8529     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
8530     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
8531     if (info[0]->IsNumber()) {
8532         auto blendModeNum = info[0]->ToNumber<int32_t>();
8533         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
8534             blendMode = static_cast<BlendMode>(blendModeNum);
8535         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
8536             // backward compatibility code, will remove soon
8537             blendMode = BlendMode::SRC_OVER;
8538             blendApplyType = BlendApplyType::OFFSCREEN;
8539         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
8540             // backward compatibility code, will remove soon
8541             blendMode = BlendMode::SRC_IN;
8542             blendApplyType = BlendApplyType::OFFSCREEN;
8543         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
8544             // backward compatibility code, will remove soon
8545             blendMode = BlendMode::DST_IN;
8546             blendApplyType = BlendApplyType::OFFSCREEN;
8547         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
8548             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
8549         }
8550     }
8551     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
8552         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
8553         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
8554             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
8555         }
8556     }
8557     ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
8558     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
8559 }
8560 
JsAdvancedBlendMode(const JSCallbackInfo & info)8561 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
8562 {
8563     if (info.Length() == 0) {
8564         return;
8565     }
8566     BlendMode blendMode = BlendMode::NONE;
8567     BlendApplyType blendApplyType = BlendApplyType::FAST;
8568     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
8569     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
8570     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
8571     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
8572     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
8573     if (info[0]->IsNumber()) {
8574         auto blendModeNum = info[0]->ToNumber<int32_t>();
8575         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
8576             blendMode = static_cast<BlendMode>(blendModeNum);
8577         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
8578             // backward compatibility code, will remove soon
8579             blendMode = BlendMode::SRC_OVER;
8580             blendApplyType = BlendApplyType::OFFSCREEN;
8581         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
8582             // backward compatibility code, will remove soon
8583             blendMode = BlendMode::SRC_IN;
8584             blendApplyType = BlendApplyType::OFFSCREEN;
8585         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
8586             // backward compatibility code, will remove soon
8587             blendMode = BlendMode::DST_IN;
8588             blendApplyType = BlendApplyType::OFFSCREEN;
8589         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
8590             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
8591         }
8592     } else if (info[0]->IsObject()) {
8593         auto blender = CreateRSBlenderFromNapiValue(info[0]);
8594         ViewAbstractModel::GetInstance()->SetBlender(blender);
8595     }
8596     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
8597         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
8598         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
8599             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
8600         }
8601     }
8602     if (!info[0]->IsObject()) {
8603         ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
8604     }
8605     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
8606 }
8607 
JsGrayScale(const JSCallbackInfo & info)8608 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
8609 {
8610     CalcDimension value;
8611     if (!ParseJsDimensionVp(info[0], value)) {
8612         value.SetValue(0.0);
8613         ViewAbstractModel::GetInstance()->SetGrayScale(value);
8614         return;
8615     }
8616 
8617     if (LessNotEqual(value.Value(), 0.0)) {
8618         value.SetValue(0.0);
8619     }
8620 
8621     if (GreatNotEqual(value.Value(), 1.0)) {
8622         value.SetValue(1.0);
8623     }
8624 
8625     ViewAbstractModel::GetInstance()->SetGrayScale(value);
8626 }
8627 
JsBrightness(const JSCallbackInfo & info)8628 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
8629 {
8630     CalcDimension value;
8631     if (!ParseJsDimensionVp(info[0], value)) {
8632         value.SetValue(1.0);
8633         ViewAbstractModel::GetInstance()->SetBrightness(value);
8634         return;
8635     }
8636 
8637     ViewAbstractModel::GetInstance()->SetBrightness(value);
8638 }
8639 
JsContrast(const JSCallbackInfo & info)8640 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
8641 {
8642     CalcDimension value;
8643     if (!ParseJsDimensionVp(info[0], value)) {
8644         value.SetValue(1.0);
8645         ViewAbstractModel::GetInstance()->SetContrast(value);
8646         return;
8647     }
8648 
8649     if (LessNotEqual(value.Value(), 0.0)) {
8650         value.SetValue(0.0);
8651     }
8652 
8653     ViewAbstractModel::GetInstance()->SetContrast(value);
8654 }
8655 
JsSaturate(const JSCallbackInfo & info)8656 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
8657 {
8658     CalcDimension value;
8659     if (!ParseJsDimensionVp(info[0], value)) {
8660         value.SetValue(1.0);
8661         ViewAbstractModel::GetInstance()->SetSaturate(value);
8662         return;
8663     }
8664 
8665     if (LessNotEqual(value.Value(), 0.0)) {
8666         value.SetValue(0.0);
8667     }
8668 
8669     ViewAbstractModel::GetInstance()->SetSaturate(value);
8670 }
8671 
JsSepia(const JSCallbackInfo & info)8672 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
8673 {
8674     CalcDimension value;
8675     if (!ParseJsDimensionVp(info[0], value)) {
8676         value.SetValue(0.0);
8677         ViewAbstractModel::GetInstance()->SetSepia(value);
8678         return;
8679     }
8680 
8681     if (LessNotEqual(value.Value(), 0.0)) {
8682         value.SetValue(0.0);
8683     }
8684 
8685     ViewAbstractModel::GetInstance()->SetSepia(value);
8686 }
8687 
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)8688 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
8689 {
8690     double invertValue = 0.0;
8691     if (ParseJsDouble(jsValue, invertValue)) {
8692         invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
8693         return true;
8694     }
8695     auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
8696     if (!argsPtrItem || argsPtrItem->IsNull()) {
8697         return false;
8698     }
8699     InvertOption option;
8700     double low = 0.0;
8701     if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
8702         option.low_ = std::clamp(low, 0.0, 1.0);
8703     }
8704     double high = 0.0;
8705     if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
8706         option.high_ = std::clamp(high, 0.0, 1.0);
8707     }
8708     double threshold = 0.0;
8709     if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
8710         option.threshold_ = std::clamp(threshold, 0.0, 1.0);
8711     }
8712     double thresholdRange = 0.0;
8713     if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
8714         option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
8715     }
8716     invert = option;
8717     return true;
8718 }
8719 
JsInvert(const JSCallbackInfo & info)8720 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
8721 {
8722     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
8723     InvertVariant invert = 0.0f;
8724     auto jsVal = info[0];
8725     if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
8726         ViewAbstractModel::GetInstance()->SetInvert(invert);
8727         return;
8728     }
8729     if (ParseInvertProps(jsVal, invert)) {
8730         ViewAbstractModel::GetInstance()->SetInvert(invert);
8731     }
8732     ViewAbstractModel::GetInstance()->SetInvert(invert);
8733 }
8734 
JsSystemBarEffect(const JSCallbackInfo & info)8735 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
8736 {
8737     ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
8738 }
8739 
JsHueRotate(const JSCallbackInfo & info)8740 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
8741 {
8742     std::optional<float> degree;
8743     JSRef<JSVal> arg = info[0];
8744     if (arg->IsString()) {
8745         degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
8746     } else if (arg->IsNumber()) {
8747         degree = static_cast<float>(arg->ToNumber<int32_t>());
8748     } else {
8749         ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
8750         return;
8751     }
8752     float deg = 0.0f;
8753     if (degree) {
8754         deg = degree.value();
8755         degree.reset();
8756     }
8757     deg = std::fmod(deg, ROUND_UNIT);
8758     if (deg < 0.0f) {
8759         deg += ROUND_UNIT;
8760     }
8761     ViewAbstractModel::GetInstance()->SetHueRotate(deg);
8762 }
8763 
JsClip(const JSCallbackInfo & info)8764 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
8765 {
8766     JSRef<JSVal> arg = info[0];
8767     if (arg->IsUndefined()) {
8768         ViewAbstractModel::GetInstance()->SetClipEdge(false);
8769         return;
8770     }
8771     if (arg->IsObject()) {
8772         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
8773         if (clipShape == nullptr) {
8774             return;
8775         }
8776         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
8777     } else if (arg->IsBoolean()) {
8778         ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
8779     }
8780 }
8781 
JsClipShape(const JSCallbackInfo & info)8782 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
8783 {
8784     ViewAbstractModel::GetInstance()->RemoveResObj("clipShape");
8785     if (info[0]->IsObject()) {
8786         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
8787         if (clipShape == nullptr) {
8788             return;
8789         }
8790         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
8791     }
8792 }
8793 
ParseProgressMaskResObj(const JSRef<JSVal> & jColor,Color & colorVal,RefPtr<NG::ProgressMaskProperty> & progressMask)8794 void JSViewAbstract::ParseProgressMaskResObj(const JSRef<JSVal>& jColor, Color& colorVal,
8795     RefPtr<NG::ProgressMaskProperty>& progressMask)
8796 {
8797     RefPtr<ResourceObject> colorResObj;
8798     auto ret = ParseJsColor(jColor, colorVal, colorResObj);
8799     if (colorResObj) {
8800         progressMask->SetColor(colorVal);
8801         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::ProgressMaskProperty& progressMask) {
8802             Color color;
8803             ResourceParseUtils::ParseResColor(resObj, color);
8804             progressMask.SetColor(color);
8805         };
8806         progressMask->AddResource("progressMask.color", colorResObj, std::move(updateFunc));
8807     } else if (ret) {
8808         progressMask->SetColor(colorVal);
8809     } else {
8810         RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
8811         progressMask->SetColor(theme->GetMaskColor());
8812         RefPtr<ResourceObject> resObj = AceType::MakeRefPtr<ResourceObject>("", "", -1);
8813         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::ProgressMaskProperty& progressMask) {
8814             RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
8815             progressMask.SetColor(theme->GetMaskColor());
8816         };
8817         progressMask->AddResource("progressMask.color", resObj, std::move(updateFunc));
8818     }
8819 }
8820 
ParseJsMaskProperty(const JSRef<JSObject> & paramObject)8821 void JSViewAbstract::ParseJsMaskProperty(const JSRef<JSObject>& paramObject)
8822 {
8823     auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
8824     JSRef<JSVal> jValue = paramObject->GetProperty("value");
8825     auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
8826     if (value < 0.0f) {
8827         value = 0.0f;
8828     }
8829     progressMask->SetValue(value);
8830     JSRef<JSVal> jTotal = paramObject->GetProperty("total");
8831     auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
8832     if (total < 0.0f) {
8833         total = DEFAULT_PROGRESS_TOTAL;
8834     }
8835     progressMask->SetMaxValue(total);
8836     JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
8837     if (jEnableBreathe->IsBoolean()) {
8838         progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
8839     }
8840     JSRef<JSVal> jColor = paramObject->GetProperty("color");
8841     Color colorVal;
8842     if (!SystemProperties::ConfigChangePerform()) {
8843         if (ParseJsColor(jColor, colorVal)) {
8844             progressMask->SetColor(colorVal);
8845         } else {
8846             RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
8847             progressMask->SetColor(theme->GetMaskColor());
8848         }
8849         ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
8850     } else {
8851         ParseProgressMaskResObj(jColor, colorVal, progressMask);
8852         ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
8853     }
8854 }
8855 
JsMask(const JSCallbackInfo & info)8856 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
8857 {
8858     JSRef<JSVal> arg = info[0];
8859     if (!arg->IsObject()) {
8860         ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
8861         return;
8862     }
8863     auto paramObject = JSRef<JSObject>::Cast(arg);
8864     JSRef<JSVal> typeParam = paramObject->GetProperty("type");
8865     if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
8866         typeParam->ToString() == "ProgressMask") {
8867             ViewAbstractModel::GetInstance()->RemoveResObj("ProgressMask");
8868             ParseJsMaskProperty(paramObject);
8869     } else {
8870         ViewAbstractModel::GetInstance()->RemoveResObj("maskShape");
8871         JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
8872         if (maskShape == nullptr) {
8873             return;
8874         };
8875         ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
8876     }
8877 }
8878 
JsMaskShape(const JSCallbackInfo & info)8879 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
8880 {
8881     if (!info[0]->IsObject()) {
8882         return;
8883     }
8884 
8885     JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
8886     if (maskShape == nullptr) {
8887         return;
8888     };
8889     ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
8890 }
8891 
JsFocusable(const JSCallbackInfo & info)8892 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
8893 {
8894     if (!info[0]->IsBoolean()) {
8895         return;
8896     }
8897     ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
8898 }
8899 
JsTabStop(const JSCallbackInfo & info)8900 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
8901 {
8902     if (!info[0]->IsBoolean()) {
8903         ViewAbstractModel::GetInstance()->SetTabStop(false);
8904         return;
8905     }
8906     ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
8907 }
8908 
JsNextFocus(const JSCallbackInfo & info)8909 void JSViewAbstract::JsNextFocus(const JSCallbackInfo& info)
8910 {
8911     ViewAbstractModel::GetInstance()->ResetNextFocus();
8912     if (info.Length() == 1 && info[0]->IsObject()) {
8913         auto obj = JSRef<JSObject>::Cast(info[0]);
8914         auto forward = obj->GetPropertyValue<std::string>("forward", "");
8915         if (!forward.empty()) {
8916             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::TAB, forward);
8917         }
8918         auto backward = obj->GetPropertyValue<std::string>("backward", "");
8919         if (!backward.empty()) {
8920             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::SHIFT_TAB, backward);
8921         }
8922         auto up = obj->GetPropertyValue<std::string>("up", "");
8923         if (!up.empty()) {
8924             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::UP, up);
8925         }
8926         auto down = obj->GetPropertyValue<std::string>("down", "");
8927         if (!down.empty()) {
8928             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::DOWN, down);
8929         }
8930         auto left = obj->GetPropertyValue<std::string>("left", "");
8931         if (!left.empty()) {
8932             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::LEFT, left);
8933         }
8934         auto right = obj->GetPropertyValue<std::string>("right", "");
8935         if (!right.empty()) {
8936             ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::RIGHT, right);
8937         }
8938     }
8939 }
8940 
JsFocusBox(const JSCallbackInfo & info)8941 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
8942 {
8943     if (!info[0]->IsObject() || info.Length() != 1) {
8944         return;
8945     }
8946     auto obj = JSRef<JSObject>::Cast(info[0]);
8947     NG::FocusBoxStyle style;
8948 
8949     CalcDimension margin;
8950     RefPtr<ResourceObject> resObjMargin;
8951     if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin, resObjMargin)) {
8952         ViewAbstractModel::GetInstance()->SetFocusBoxStyleUpdateFunc(style, resObjMargin, "focusBoxStyleMargin");
8953         style.margin = margin;
8954     }
8955     CalcDimension strokeWidth;
8956     RefPtr<ResourceObject> resObjWidth;
8957     if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth, resObjWidth)) {
8958         ViewAbstractModel::GetInstance()->SetFocusBoxStyleUpdateFunc(style, resObjWidth, "focusBoxStyleWidth");
8959         style.strokeWidth = strokeWidth;
8960     }
8961     Color strokeColor;
8962     RefPtr<ResourceObject> resObjColor;
8963     if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor, resObjColor)) {
8964         CompleteResourceObjectFromColor(resObjColor, strokeColor, true);
8965         ViewAbstractModel::GetInstance()->SetFocusBoxStyleUpdateFunc(style, resObjColor, "focusBoxStyleColor");
8966         style.strokeColor = strokeColor;
8967     }
8968 
8969     ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
8970 }
8971 
JsOnFocusMove(const JSCallbackInfo & args)8972 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
8973 {
8974     JSRef<JSVal> arg = args[0];
8975     if (arg->IsFunction()) {
8976         RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
8977         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8978         auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
8979                                int info) {
8980             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8981             ACE_SCORING_EVENT("onFocusMove");
8982             PipelineContext::SetCallBackNode(node);
8983             func->Execute(info);
8984         };
8985         ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
8986     }
8987 }
8988 
JsOnKeyEvent(const JSCallbackInfo & args)8989 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
8990 {
8991     JSRef<JSVal> arg = args[0];
8992     if (arg->IsUndefined() && IsDisableEventVersion()) {
8993         ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
8994         return;
8995     }
8996     if (!arg->IsFunction()) {
8997         return;
8998     }
8999     RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
9000     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9001     auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
9002                           KeyEventInfo& info) -> bool {
9003         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
9004         ACE_SCORING_EVENT("onKey");
9005         PipelineContext::SetCallBackNode(node);
9006         auto ret = func->ExecuteWithValue(info);
9007         return ret->IsBoolean() ? ret->ToBoolean() : false;
9008     };
9009     ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
9010 }
9011 
JsDispatchKeyEvent(const JSCallbackInfo & args)9012 void JSViewAbstract::JsDispatchKeyEvent(const JSCallbackInfo& args)
9013 {
9014     JSRef<JSVal> arg = args[0];
9015     if (!(arg->IsNumber() || arg->IsString())) {
9016         return;
9017     }
9018     RefPtr<NG::FrameNode> frameNode = nullptr;
9019     if (arg->IsString()) {
9020         std::string id = arg->ToString();
9021         frameNode = NG::Inspector::GetFrameNodeByKey(id);
9022     }
9023 
9024     if (arg->IsNumber()) {
9025         auto id = arg->ToNumber<int32_t>();
9026         auto node = ElementRegister::GetInstance()->GetNodeById(id);
9027         frameNode = AceType::DynamicCast<NG::FrameNode>(node);
9028     }
9029     CHECK_NULL_VOID(frameNode);
9030     auto focusHub = frameNode->GetOrCreateFocusHub();
9031     CHECK_NULL_VOID(focusHub);
9032 
9033     if (!(args[1]->IsObject())) {
9034         return;
9035     }
9036     JSRef<JSObject> jsObject = JSRef<JSObject>::Cast(args[1]);
9037     auto eventInfoPtr = jsObject->Unwrap<KeyEventInfo>();
9038     CHECK_NULL_VOID(eventInfoPtr);
9039     KeyEvent keyEvent;
9040     eventInfoPtr->ParseKeyEvent(keyEvent);
9041     auto result = focusHub->HandleEvent(keyEvent);
9042     args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
9043 }
9044 
JsOnCrownEvent(const JSCallbackInfo & args)9045 void JSViewAbstract::JsOnCrownEvent(const JSCallbackInfo& args)
9046 {
9047 #ifdef SUPPORT_DIGITAL_CROWN
9048     if (args.Length() <= 0) {
9049         return;
9050     }
9051     if (args[0]->IsFunction()) {
9052         RefPtr<JsCrownFunction> JsOnCrownEventfunc = AceType::MakeRefPtr<JsCrownFunction>(JSRef<JSFunc>::Cast(args[0]));
9053         WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->
9054             GetMainFrameNode());
9055         auto onCrownEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnCrownEventfunc),
9056             node = frameNode](CrownEventInfo& info) {
9057                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9058                 ACE_SCORING_EVENT("onCrown");
9059                 PipelineContext::SetCallBackNode(node);
9060                 func->Execute(info);
9061             };
9062         ViewAbstractModel::GetInstance()->SetOnCrownEvent(std::move(onCrownEvent));
9063     } else {
9064         ViewAbstractModel::GetInstance()->DisableOnCrownEvent();
9065     }
9066 #endif
9067 }
9068 
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle)9069 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args, NG::SheetStyle& sheetStyle)
9070 {
9071     RefPtr<ResourceObject> resObj;
9072     ParseBindSheetBorderRadius(args, sheetStyle, resObj);
9073 }
9074 
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle,RefPtr<ResourceObject> & resourceObj)9075 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args,
9076     NG::SheetStyle& sheetStyle, RefPtr<ResourceObject>& resourceObj)
9077 {
9078     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
9079         TAG_LOGE(AceLogTag::ACE_SHEET, "radius is not correct type");
9080         return;
9081     }
9082     CalcDimension radius;
9083     NG::BorderRadiusProperty borderRadius;
9084     if (ParseJsLengthMetricsVpWithResObj(args, radius, resourceObj)) {
9085         borderRadius.SetRadius(radius);
9086 
9087         // multiValued: indicates whether to set multiple directions. The default value is false.
9088         borderRadius.multiValued = false;
9089         sheetStyle.radius = borderRadius;
9090     } else if (ParseBindSheetBorderRadiusProps(args, borderRadius)) {
9091         sheetStyle.radius = borderRadius;
9092     } else {
9093         TAG_LOGW(AceLogTag::ACE_SHEET, "radius is not correct.");
9094         return;
9095     }
9096 }
9097 
ParseBindSheetBorderRadiusProps(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)9098 bool JSViewAbstract::ParseBindSheetBorderRadiusProps(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
9099 {
9100     if (args->IsObject()) {
9101         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
9102         if (CheckLengthMetrics(object)) {
9103             RefPtr<ResourceObject> topStartResObj;
9104             std::optional<CalcDimension> radiusTopStart =
9105                 ParseBindSheetBorderRadiusProp(object, TOP_START_PROPERTY, topStartResObj);
9106             RefPtr<ResourceObject> topEndResObj;
9107             std::optional<CalcDimension> radiusTopEnd =
9108                 ParseBindSheetBorderRadiusProp(object, TOP_END_PROPERTY, topEndResObj);
9109             RefPtr<ResourceObject> bottomStartResObj;
9110             std::optional<CalcDimension> radiusBottomStart =
9111                 ParseBindSheetBorderRadiusProp(object, BOTTOM_START_PROPERTY, bottomStartResObj);
9112             RefPtr<ResourceObject> bottomEndResObj;
9113             std::optional<CalcDimension> radiusBottomEnd =
9114                 ParseBindSheetBorderRadiusProp(object, BOTTOM_END_PROPERTY, bottomEndResObj);
9115             auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
9116             radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
9117             radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
9118             radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
9119             radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
9120             radius.multiValued = true;
9121             if (isRightToLeft) {
9122                 RegisterRadiusRes(radius, topEndResObj, topStartResObj, bottomEndResObj, bottomStartResObj);
9123             } else {
9124                 RegisterRadiusRes(radius, topStartResObj, topEndResObj, bottomStartResObj, bottomEndResObj);
9125             }
9126         } else {
9127             ParseBorderRadiusProps(object, radius);
9128         }
9129         return true;
9130     }
9131     return false;
9132 }
9133 
ParseBindSheetBorderRadiusProp(const JSRef<JSObject> & object,const char * prop,RefPtr<ResourceObject> & resourceObj)9134 std::optional<CalcDimension> JSViewAbstract::ParseBindSheetBorderRadiusProp(
9135     const JSRef<JSObject>& object, const char* prop, RefPtr<ResourceObject>& resourceObj)
9136 {
9137     if (object->IsEmpty()) {
9138         return std::nullopt;
9139     }
9140     if (object->HasProperty(prop) && object->GetProperty(prop)->IsObject()) {
9141         JSRef<JSObject> propObj = JSRef<JSObject>::Cast(object->GetProperty(prop));
9142         CalcDimension calcDimension;
9143         if (ParseJsLengthMetricsVpWithResObj(propObj, calcDimension, resourceObj)) {
9144             return calcDimension;
9145         }
9146     }
9147     return std::nullopt;
9148 }
9149 
JSCreateAnimatableProperty(const JSCallbackInfo & info)9150 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
9151 {
9152     if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
9153         return;
9154     }
9155 
9156     JSRef<JSVal> callback = info[2]; /* 2:args index */
9157     if (!callback->IsFunction()) {
9158         return;
9159     }
9160     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9161     std::string propertyName = info[0]->ToString();
9162     if (info[1]->IsNumber()) {
9163         float numValue = info[1]->ToNumber<float>();
9164         std::function<void(float)> onCallbackEvent;
9165         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
9166         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
9167                               node = frameNode](const float val) {
9168             ContainerScope scope(id);
9169             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9170             auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
9171             PipelineContext::SetCallBackNode(node);
9172             func->ExecuteJS(1, &newJSVal);
9173         };
9174         ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
9175     } else if (info[1]->IsObject()) {
9176         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
9177         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
9178             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
9179         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
9180             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
9181         std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
9182         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
9183         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
9184                               node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
9185             ContainerScope scope(id);
9186             RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
9187             if (!impl) {
9188                 return;
9189             }
9190             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9191             auto newJSVal = JSRef<JSVal>(impl->GetObject());
9192             PipelineContext::SetCallBackNode(node);
9193             func->ExecuteJS(1, &newJSVal);
9194         };
9195         ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
9196             propertyName, animatableArithmetic, onCallbackEvent);
9197     }
9198 }
9199 
JSUpdateAnimatableProperty(const JSCallbackInfo & info)9200 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
9201 {
9202     if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
9203         return;
9204     }
9205 
9206     std::string propertyName = info[0]->ToString();
9207     float numValue = 0.0;
9208     if (info[1]->IsNumber()) {
9209         numValue = info[1]->ToNumber<float>();
9210         ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
9211     } else if (info[1]->IsObject()) {
9212         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
9213         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
9214             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
9215         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
9216             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
9217         ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
9218     }
9219 }
9220 
JsExpandSafeArea(const JSCallbackInfo & info)9221 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
9222 {
9223     NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
9224     if (info.Length() >= PARAMETER_LENGTH_FIRST && info[0]->IsArray()) {
9225         auto paramArray = JSRef<JSArray>::Cast(info[0]);
9226         uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
9227         for (size_t i = 0; i < paramArray->Length(); ++i) {
9228             if (!paramArray->GetValueAt(i)->IsNumber() ||
9229                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
9230                 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
9231                 break;
9232             }
9233             safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9234         }
9235         opts.type = safeAreaType;
9236     }
9237     if (info.Length() >= 2 && info[1]->IsArray()) {
9238         auto paramArray = JSRef<JSArray>::Cast(info[1]);
9239         uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
9240         for (size_t i = 0; i < paramArray->Length(); ++i) {
9241             if (!paramArray->GetValueAt(i)->IsNumber() ||
9242                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
9243                 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
9244                 break;
9245             }
9246             safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9247         }
9248         opts.edges = safeAreaEdge;
9249     }
9250 
9251     ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
9252 }
9253 
JsIgnoreLayoutSafeArea(const JSCallbackInfo & info)9254 void JSViewAbstract::JsIgnoreLayoutSafeArea(const JSCallbackInfo& info)
9255 {
9256     NG::IgnoreLayoutSafeAreaOpts opts { .type = NG::LAYOUT_SAFE_AREA_TYPE_SYSTEM, .rawEdges = NG::LAYOUT_SAFE_AREA_EDGE_ALL };
9257     if (info.Length() >= PARAMETER_LENGTH_FIRST && info[0]->IsArray()) {
9258         auto paramArray = JSRef<JSArray>::Cast(info[0]);
9259         uint32_t layoutSafeAreaType = NG::LAYOUT_SAFE_AREA_TYPE_NONE;
9260         for (size_t i = 0; i < paramArray->Length(); ++i) {
9261             if (!paramArray->GetValueAt(i)->IsNumber() ||
9262                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_TYPE_LIMIT) {
9263                 layoutSafeAreaType = NG::SAFE_AREA_TYPE_SYSTEM;
9264                 break;
9265             }
9266             layoutSafeAreaType |= NG::IgnoreLayoutSafeAreaOpts::TypeToMask(paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9267         }
9268         opts.type = layoutSafeAreaType;
9269     }
9270     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsArray()) {
9271         auto paramArray = JSRef<JSArray>::Cast(info[1]);
9272         uint32_t layoutSafeAreaEdge = NG::LAYOUT_SAFE_AREA_EDGE_NONE;
9273         for (size_t i = 0; i < paramArray->Length(); ++i) {
9274             if (!paramArray->GetValueAt(i)->IsNumber() ||
9275                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_EDGE_LIMIT) {
9276                 layoutSafeAreaEdge = NG::LAYOUT_SAFE_AREA_EDGE_ALL;
9277                 break;
9278             }
9279             layoutSafeAreaEdge |=
9280                 NG::IgnoreLayoutSafeAreaOpts::EdgeToMask(paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9281         }
9282         opts.rawEdges = layoutSafeAreaEdge;
9283     }
9284 
9285     ViewAbstractModel::GetInstance()->UpdateIgnoreLayoutSafeAreaOpts(opts);
9286 }
9287 
ParseJSLightSource(JSRef<JSObject> & lightSource)9288 void ParseJSLightSource(JSRef<JSObject>& lightSource)
9289 {
9290     if (lightSource->IsUndefined()) {
9291         return;
9292     }
9293     JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
9294     JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
9295     JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
9296     JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
9297     JSRef<JSVal> color = lightSource->GetProperty("color");
9298 
9299     CalcDimension dimPositionX;
9300     CalcDimension dimPositionY;
9301     CalcDimension dimPositionZ;
9302     if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
9303         JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
9304         JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
9305         ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
9306     }
9307 
9308     if (intensity->IsNumber()) {
9309         float intensityValue = intensity->ToNumber<float>();
9310         ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
9311     }
9312 
9313     Color lightColor;
9314     if (JSViewAbstract::ParseJsColor(color, lightColor)) {
9315         ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
9316     }
9317 }
9318 
ParseJSLightSourcePositionX(const JSRef<JSObject> & lightSource,NG::TranslateOptions & option)9319 void ParseJSLightSourcePositionX(const JSRef<JSObject>& lightSource, NG::TranslateOptions& option)
9320 {
9321     JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
9322     CalcDimension dimPositionX;
9323     RefPtr<ResourceObject> dimPositionXResObj;
9324     if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX, dimPositionXResObj)) {
9325         option.x = dimPositionX;
9326     }
9327     if (dimPositionXResObj) {
9328         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::TranslateOptions& option) {
9329             CalcDimension dimension;
9330             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
9331             option.x = dimension;
9332         };
9333         option.AddResource("pointLight.LightSource.PositionX", dimPositionXResObj, std::move(updateFunc));
9334     }
9335 }
9336 
ParseJSLightSourcePositionY(const JSRef<JSObject> & lightSource,NG::TranslateOptions & option)9337 void ParseJSLightSourcePositionY(const JSRef<JSObject>& lightSource, NG::TranslateOptions& option)
9338 {
9339     JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
9340     CalcDimension dimPositionY;
9341     RefPtr<ResourceObject> dimPositionYResObj;
9342     if (JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY, dimPositionYResObj)) {
9343         option.y = dimPositionY;
9344     }
9345     if (dimPositionYResObj) {
9346         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::TranslateOptions& option) {
9347             CalcDimension dimension;
9348             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
9349             option.y = dimension;
9350         };
9351         option.AddResource("pointLight.LightSource.PositionY", dimPositionYResObj, std::move(updateFunc));
9352     }
9353 }
9354 
ParseJSLightSourcePositionZ(const JSRef<JSObject> & lightSource,NG::TranslateOptions & option)9355 void ParseJSLightSourcePositionZ(const JSRef<JSObject>& lightSource, NG::TranslateOptions& option)
9356 {
9357     JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
9358     CalcDimension dimPositionZ;
9359     RefPtr<ResourceObject> dimPositionZResObj;
9360     if (JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ, dimPositionZResObj)) {
9361         option.z = dimPositionZ;
9362     }
9363     if (dimPositionZResObj) {
9364         auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::TranslateOptions& option) {
9365             CalcDimension dimension;
9366             ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
9367             option.z = dimension;
9368         };
9369         option.AddResource("pointLight.LightSource.PositionZ", dimPositionZResObj, std::move(updateFunc));
9370     }
9371 
9372 }
9373 
ParseJSLightSourceNew(JSRef<JSObject> & lightSource)9374 void ParseJSLightSourceNew(JSRef<JSObject>& lightSource)
9375 {
9376     if (lightSource->IsUndefined()) {
9377         return;
9378     }
9379     JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
9380     JSRef<JSVal> color = lightSource->GetProperty("color");
9381 
9382     NG::TranslateOptions option;
9383     ParseJSLightSourcePositionX(lightSource, option);
9384     ParseJSLightSourcePositionY(lightSource, option);
9385     ParseJSLightSourcePositionZ(lightSource, option);
9386     ViewAbstractModel::GetInstance()->SetLightPosition(option);
9387 
9388     if (intensity->IsNumber()) {
9389         float intensityValue = intensity->ToNumber<float>();
9390         ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
9391     }
9392 
9393     Color lightColor;
9394     RefPtr<ResourceObject> lightColorResObj;
9395     bool ret = JSViewAbstract::ParseJsColor(color, lightColor, lightColorResObj);
9396     if (lightColorResObj) {
9397         ViewAbstractModel::GetInstance()->CreateWithLightColorResourceObj(lightColorResObj);
9398     } else if (ret) {
9399         ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
9400     }
9401 }
9402 
JsPointLight(const JSCallbackInfo & info)9403 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
9404 {
9405 #ifdef POINT_LIGHT_ENABLE
9406     if (!info[0]->IsObject()) {
9407         return;
9408     }
9409 
9410     ViewAbstractModel::GetInstance()->RemoveResObj("LightColorRes");
9411     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
9412     JSRef<JSObject> lightSource = object->GetProperty("lightSource");
9413     if (!SystemProperties::ConfigChangePerform()) {
9414         ParseJSLightSource(lightSource);
9415     } else {
9416         ParseJSLightSourceNew(lightSource);
9417     }
9418 
9419     auto resourceWrapper = CreateResourceWrapper();
9420     if (!resourceWrapper) {
9421         return;
9422     }
9423     double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
9424     Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
9425     Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
9426 
9427     JSRef<JSVal> illuminated = object->GetProperty("illuminated");
9428     if (illuminated->IsNumber()) {
9429         uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
9430         ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
9431         ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
9432     }
9433 
9434     JSRef<JSVal> bloom = object->GetProperty("bloom");
9435     if (bloom->IsNumber()) {
9436         float bloomValue = bloom->ToNumber<float>();
9437         ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
9438 
9439         Shadow shadow;
9440         shadow.SetBlurRadius(bloomValue * bloomRadius);
9441         shadow.SetColor(bloomColor);
9442         std::vector<Shadow> shadows { shadow };
9443         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
9444     }
9445 #endif
9446 }
9447 
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)9448 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
9449 {
9450     if (info[0]->IsBoolean()) {
9451         ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
9452     }
9453 }
9454 
JsEnableDropDisallowedBadge(const JSCallbackInfo & info)9455 void JSViewAbstract::JsEnableDropDisallowedBadge(const JSCallbackInfo& info)
9456 {
9457     if (info[0]->IsBoolean()) {
9458         ViewAbstractModel::GetInstance()->EnableDropDisallowedBadge(info[0]->ToBoolean());
9459     }
9460 }
9461 
JsNotifyDragStartRequest(const JSCallbackInfo & info)9462 void JSViewAbstract::JsNotifyDragStartRequest(const JSCallbackInfo& info)
9463 {
9464     if (info[0]->IsNumber()) {
9465         int32_t dragStatus = info[0]->ToNumber<int32_t>();
9466         ViewAbstractModel::GetInstance()->NotifyDragStartRequest(
9467             static_cast<DragStartRequestStatus>(dragStatus));
9468     }
9469 }
9470 
JsCancelDataLoading(const std::string & key)9471 void JSViewAbstract::JsCancelDataLoading(const std::string& key)
9472 {
9473     if (key.empty()) {
9474         JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Invalid input parameter.");
9475         return;
9476     }
9477     auto ret = ViewAbstractModel::GetInstance()->CancelDataLoading(key);
9478     if (ret != 0) {
9479         JSException::Throw(ERROR_CODE_DRAG_OPERATION_FAILED, "%s", "Operation failed.");
9480     }
9481 }
9482 
JSBind(BindingTarget globalObj)9483 void JSViewAbstract::JSBind(BindingTarget globalObj)
9484 {
9485     JSClass<JSViewAbstract>::Declare("JSViewAbstract");
9486 
9487     // static methods
9488     MethodOptions opt = MethodOptions::NONE;
9489     JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
9490 
9491     JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
9492     JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
9493     JSClass<JSViewAbstract>::StaticMethod("toolbar", &JSViewAbstract::JsToolbar);
9494     JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
9495     JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
9496     JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
9497     JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
9498     JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
9499     JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSLayoutableView::JsPixelRound);
9500     JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
9501     JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSLayoutableView::JsChainWeight);
9502 
9503     JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
9504     JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
9505     JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
9506     JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
9507     JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
9508 
9509     JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
9510     JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
9511     JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
9512     JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
9513     JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
9514     JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
9515 
9516     JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
9517     JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
9518     JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
9519     JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
9520     JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
9521     JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
9522     JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
9523     JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
9524     JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
9525     JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
9526     JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
9527     JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
9528     JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
9529     JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
9530     JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
9531     JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
9532     JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
9533     JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
9534     JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
9535     JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
9536     JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
9537     JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
9538     JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
9539     JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
9540 
9541     JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
9542     JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
9543     JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
9544     JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
9545     JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
9546     JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
9547     JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
9548     JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
9549     JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
9550     JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
9551     JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
9552     JSClass<JSViewAbstract>::StaticMethod("transform3D", &JSViewAbstract::JsTransform3D);
9553     JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
9554 
9555     JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
9556     JSClass<JSViewAbstract>::StaticMethod("layoutGravity", &JSViewAbstract::JsLayoutGravity);
9557     JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
9558     JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
9559     JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
9560     JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
9561     JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
9562     JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
9563 
9564     JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
9565     JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
9566     JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
9567     JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
9568     JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
9569     JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
9570     JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
9571     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
9572     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal", &JSViewAbstract::JsBackgroundBrightnessInternal);
9573     JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
9574     JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
9575     JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
9576     JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
9577     JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
9578     JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
9579     JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
9580     JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
9581     JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
9582     JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
9583     JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
9584     JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
9585 #ifndef WEARABLE_PRODUCT
9586     JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
9587     JSClass<JSViewAbstract>::StaticMethod("bindTips", &JSViewAbstract::JsBindTips);
9588 #endif
9589 
9590     JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
9591     JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
9592     JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
9593     JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
9594     JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
9595     JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
9596     JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
9597     JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
9598     JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
9599     JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
9600     JSClass<JSViewAbstract>::StaticMethod("onDragSpringLoading", &JSViewAbstract::JsOnDragSpringLoading);
9601     JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
9602     JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
9603     JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
9604     JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
9605 
9606     JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
9607     JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
9608     JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
9609     JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
9610     JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
9611     JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
9612     JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
9613     JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
9614     JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
9615     JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
9616     JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
9617     JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
9618     JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
9619     JSClass<JSViewAbstract>::StaticMethod("nextFocus", &JSViewAbstract::JsNextFocus);
9620     JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
9621     JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
9622     JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
9623     JSClass<JSViewAbstract>::StaticMethod("onKeyEventDispatch", &JSInteractableView::JsOnKeyEventDispatch);
9624     JSClass<JSViewAbstract>::StaticMethod("dispatchKeyEvent", &JSViewAbstract::JsDispatchKeyEvent);
9625     JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
9626     JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
9627     JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
9628     JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
9629     JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
9630     JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
9631     JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
9632     JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
9633     JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
9634     JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
9635     JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
9636     JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
9637     JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
9638     JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
9639     JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
9640     JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
9641     JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
9642     JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
9643     JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
9644     JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
9645     JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
9646     JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
9647     JSClass<JSViewAbstract>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
9648     JSClass<JSViewAbstract>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
9649     JSClass<JSViewAbstract>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
9650     JSClass<JSViewAbstract>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
9651     JSClass<JSViewAbstract>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
9652     JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
9653     JSClass<JSViewAbstract>::StaticMethod("onAxisEvent", &JSViewAbstract::JsOnAxisEvent);
9654     JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
9655     JSClass<JSViewAbstract>::StaticMethod("onHoverMove", &JSViewAbstract::JsOnHoverMove);
9656     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
9657     JSClass<JSViewAbstract>::StaticMethod("onDigitalCrown", &JSViewAbstract::JsOnCrownEvent);
9658     JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
9659     JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
9660     JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
9661     JSClass<JSViewAbstract>::StaticMethod(
9662         "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
9663     JSClass<JSViewAbstract>::StaticMethod(
9664         "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
9665     JSClass<JSViewAbstract>::StaticMethod("onTouchTestDone", &JSViewAbstract::JsOnTouchTestDone);
9666     JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
9667     JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
9668     JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
9669     JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
9670     JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
9671     JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
9672     JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
9673     JSClass<JSViewAbstract>::StaticMethod("onFocusAxisEvent", &JSViewAbstract::JsOnFocusAxisEvent);
9674 
9675     JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
9676     JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
9677     JSClass<JSViewAbstract>::StaticMethod("accessibilityNextFocusId", &JSViewAbstract::JsAccessibilityNextFocusId);
9678     JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
9679     JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
9680     JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
9681     JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
9682     JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
9683     JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
9684     JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
9685     JSClass<JSViewAbstract>::StaticMethod("accessibilityRole", &JSViewAbstract::JsAccessibilityRole);
9686     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityFocus", &JSViewAbstract::JsOnAccessibilityFocus);
9687     JSClass<JSViewAbstract>::StaticMethod("accessibilityDefaultFocus", &JSViewAbstract::JsAccessibilityDefaultFocus);
9688     JSClass<JSViewAbstract>::StaticMethod("accessibilityUseSamePage", &JSViewAbstract::JsAccessibilityUseSamePage);
9689     JSClass<JSViewAbstract>::StaticMethod("accessibilityScrollTriggerable",
9690                                           &JSViewAbstract::JsAccessibilityScrollTriggerable);
9691     JSClass<JSViewAbstract>::StaticMethod("accessibilityFocusDrawLevel",
9692                                           &JSViewAbstract::JsAccessibilityFocusDrawLevel);
9693     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityActionIntercept",
9694                                           &JSViewAbstract::JsOnAccessibilityActionIntercept);
9695     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHoverTransparent",
9696                                           &JSViewAbstract::JsOnAccessibilityHoverTransparent);
9697 
9698     JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
9699     JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
9700     JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
9701     JSClass<JSViewAbstract>::StaticMethod(
9702         "onVisibleAreaApproximateChange", &JSViewAbstract::JsOnVisibleAreaApproximateChange);
9703     JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
9704     JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
9705     JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
9706     JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
9707     JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
9708     JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
9709     JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
9710     JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
9711 
9712     JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
9713     JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
9714     JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
9715     JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
9716 
9717     JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
9718 
9719     JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
9720     JSClass<JSViewAbstract>::StaticMethod("ignoreLayoutSafeArea", &JSViewAbstract::JsIgnoreLayoutSafeArea);
9721 
9722     JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
9723     JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
9724     JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
9725     JSClass<JSViewAbstract>::StaticMethod("notifyDragStartRequest", &JSViewAbstract::JsNotifyDragStartRequest);
9726     JSClass<JSViewAbstract>::StaticMethod(
9727         "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
9728     JSClass<JSViewAbstract>::StaticMethod(
9729         "enableDropDisallowedBadge", &JSViewAbstract::JsEnableDropDisallowedBadge);
9730     JSClass<JSViewAbstract>::StaticMethod("cancelDataLoading", &JSViewAbstract::JsCancelDataLoading);
9731 
9732     JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
9733     JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
9734 
9735     JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
9736     JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
9737     JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
9738     JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
9739 
9740     JSClass<JSViewAbstract>::StaticMethod("setPixelRoundMode", &JSViewAbstract::SetPixelRoundMode);
9741     JSClass<JSViewAbstract>::StaticMethod("getPixelRoundMode", &JSViewAbstract::GetPixelRoundMode);
9742 
9743     JSClass<JSViewAbstract>::Bind(globalObj);
9744 }
9745 
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)9746 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
9747 {
9748     auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
9749         auto vm = info->GetVM();
9750         CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
9751         Local<JSValueRef> thisObj = info->GetFunctionRef();
9752         auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
9753         if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
9754             return panda::JSValueRef::Undefined(vm);
9755         }
9756 
9757         auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
9758         if (weak->Invalid()) {
9759             return panda::JSValueRef::Undefined(vm);
9760         }
9761 
9762         auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
9763         if (frameNode) {
9764             const auto& extensionHandler = frameNode->GetExtensionHandler();
9765             if (extensionHandler) {
9766                 extensionHandler->InvalidateRender();
9767                 extensionHandler->ForegroundRender();
9768             } else {
9769                 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9770             }
9771         }
9772 
9773         return panda::JSValueRef::Undefined(vm);
9774     };
9775     auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
9776     if (frameNode) {
9777         const auto& extensionHandler = frameNode->GetExtensionHandler();
9778         if (extensionHandler) {
9779             extensionHandler->InvalidateRender();
9780             extensionHandler->ForegroundRender();
9781         } else {
9782             frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9783         }
9784     }
9785     auto vm = jsInvalidate->GetEcmaVM();
9786     auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
9787     jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
9788     jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
9789     jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
9790 }
9791 
JsDrawModifier(const JSCallbackInfo & info)9792 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
9793 {
9794     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWENTY) && !info[0]->IsObject()) {
9795         return;
9796     }
9797 
9798     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9799     bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
9800     if (!IsSupportDrawModifier) {
9801         return;
9802     }
9803     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWENTY) && !info[0]->IsObject()) {
9804         ViewAbstractModel::GetInstance()->SetDrawModifier(nullptr);
9805         if (frameNode) {
9806             const auto& extensionHandler = frameNode->GetExtensionHandler();
9807             if (extensionHandler) {
9808                 extensionHandler->InvalidateRender();
9809                 extensionHandler->ForegroundRender();
9810             } else {
9811                 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9812             }
9813         }
9814         return;
9815     }
9816     auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
9817     RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
9818     auto execCtx = info.GetExecutionContext();
9819     auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
9820         JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
9821         if (!drawMethod->IsFunction()) {
9822             return nullptr;
9823         }
9824 
9825         auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
9826             JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
9827 
9828         return GetDrawCallback(jsDrawFunc, execCtx, jsDrawModifier);
9829     };
9830 
9831     drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
9832     drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
9833     drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
9834     drawModifier->drawForegroundFunc = getDrawModifierFunc("drawForeground");
9835 
9836     ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
9837     AddInvalidateFunc(jsDrawModifier, frameNode);
9838 }
9839 
JsAllowDrop(const JSCallbackInfo & info)9840 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
9841 {
9842     std::set<std::string> allowDropSet;
9843     allowDropSet.clear();
9844     if (!info[0]->IsUndefined() && info[0]->IsArray()) {
9845         auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
9846         std::string allowDrop;
9847         for (size_t i = 0; i < allowDropArray->Length(); i++) {
9848             allowDrop = allowDropArray->GetValueAt(i)->ToString();
9849             allowDropSet.insert(allowDrop);
9850         }
9851         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9852     } else if (info[0]->IsNull()) {
9853         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
9854     } else {
9855         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9856     }
9857     ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
9858 }
9859 
JsOnPreDrag(const JSCallbackInfo & info)9860 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
9861 {
9862     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
9863     auto jsVal = info[0];
9864     if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
9865         return;
9866     }
9867 
9868     RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
9869     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9870     auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
9871                          const PreDragStatus preDragStatus) {
9872         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9873         ACE_SCORING_EVENT("onPreDrag");
9874         PipelineContext::SetCallBackNode(node);
9875         func->PreDragExecute(preDragStatus);
9876     };
9877     ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
9878 }
9879 
ParseDragPreviewConfig(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9880 void JSViewAbstract::ParseDragPreviewConfig(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9881 {
9882     if (info.Length() <= 1) {
9883         return;
9884     }
9885     auto jsVal = info[1];
9886     if (!jsVal->IsObject()) {
9887         return;
9888     }
9889     auto config = JSRef<JSObject>::Cast(jsVal);
9890     ParseJsBool(config->GetProperty("onlyForLifting"), dragPreviewInfo.onlyForLifting);
9891     ParseJsBool(config->GetProperty("delayCreating"), dragPreviewInfo.delayCreating);
9892 }
9893 
ParseDragPreviewValue(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9894 void JSViewAbstract::ParseDragPreviewValue(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9895 {
9896     auto jsVal = info[0];
9897     JSRef<JSVal> builder;
9898     JSRef<JSVal> pixelMap;
9899     JSRef<JSVal> extraInfo;
9900     if (jsVal->IsFunction()) {
9901         builder = jsVal;
9902     } else if (jsVal->IsObject()) {
9903         auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
9904         builder = dragItemInfo->GetProperty("builder");
9905 #if defined(PIXEL_MAP_SUPPORTED)
9906         pixelMap = dragItemInfo->GetProperty("pixelMap");
9907         dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
9908 #endif
9909         extraInfo = dragItemInfo->GetProperty("extraInfo");
9910         ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
9911     } else if (jsVal->IsString()) {
9912         auto inspectorId = jsVal;
9913         ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
9914     } else {
9915         return;
9916     }
9917     ParseDragPreviewBuilderNode(info, dragPreviewInfo, builder);
9918 }
9919 
ParseDragPreviewBuilderNode(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo,const JSRef<JSVal> & builder)9920 void JSViewAbstract::ParseDragPreviewBuilderNode(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo,
9921     const JSRef<JSVal>& builder)
9922 {
9923     if (!builder->IsFunction()) {
9924         return;
9925     }
9926     RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9927     CHECK_NULL_VOID(builderFunc);
9928     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9929     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
9930                          node = frameNode]() -> RefPtr<NG::UINode> {
9931         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
9932         ACE_SCORING_EVENT("dragPreview.builder");
9933         PipelineContext::SetCallBackNode(node);
9934         func->Execute();
9935         auto customNode = ViewStackModel::GetInstance()->Finish();
9936         return AceType::DynamicCast<NG::UINode>(customNode);
9937     };
9938     if (!dragPreviewInfo.delayCreating) {
9939         ViewStackModel::GetInstance()->NewScope();
9940         {
9941             dragPreviewInfo.customNode = buildFunc();
9942         }
9943     } else {
9944         dragPreviewInfo.buildFunc = buildFunc;
9945     }
9946 }
9947 
JsDragPreview(const JSCallbackInfo & info)9948 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
9949 {
9950     auto jsVal = info[0];
9951     if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
9952         return;
9953     }
9954     NG::DragDropInfo dragPreviewInfo;
9955     ParseDragPreviewConfig(info, dragPreviewInfo);
9956     ParseDragPreviewValue(info, dragPreviewInfo);
9957     ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
9958 }
9959 
JsAlignRules(const JSCallbackInfo & info)9960 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
9961 {
9962     if (!info[0]->IsObject()) {
9963         return;
9964     }
9965 
9966     JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
9967     if (valueObj->IsEmpty()) {
9968         return;
9969     }
9970     const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
9971     std::map<AlignDirection, AlignRule> alignRules;
9972     BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
9973     for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
9974         auto rule = valueObj->GetProperty(keys[i]);
9975         if (rule->IsObject()) {
9976             JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
9977             JSRef<JSVal> align = val->GetProperty("align");
9978             AlignRule alignRule;
9979             alignRule.anchor = val->GetProperty("anchor")->ToString();
9980             if (i < HORIZONTAL_DIRECTION_RANGE) {
9981                 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9982             } else {
9983                 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9984             }
9985             if (i < VERTICAL_DIRECTION_RANGE) {
9986                 alignRules[static_cast<AlignDirection>(i)] = alignRule;
9987             } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
9988                 alignRules[AlignDirection::LEFT] = alignRule;
9989             } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
9990                 alignRules[AlignDirection::RIGHT] = alignRule;
9991             }
9992             auto biasX = val->GetProperty("horizontal");
9993             if (biasX->IsNumber()) {
9994                 biasPair.first = biasX->ToNumber<float>();
9995             }
9996             auto biasY = val->GetProperty("vertical");
9997             if (biasY->IsNumber()) {
9998                 biasPair.second = biasY->ToNumber<float>();
9999             }
10000         }
10001     }
10002 
10003     ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
10004     ViewAbstractModel::GetInstance()->SetBias(biasPair);
10005 }
10006 
JsChainMode(const JSCallbackInfo & info)10007 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
10008 {
10009     ChainInfo chainInfo;
10010     if (info.Length() >= 1) {
10011         auto tmpDirection = info[0];
10012         if (tmpDirection->IsUndefined()) {
10013             chainInfo.direction = std::nullopt;
10014         } else if (tmpDirection->IsNumber()) {
10015             auto direction = tmpDirection->ToNumber<int32_t>();
10016             chainInfo.direction = static_cast<LineDirection>(direction);
10017         }
10018     }
10019 
10020     if (info.Length() >= 2) { // 2 : two args
10021         auto tmpStyle = info[1];
10022         if (tmpStyle->IsUndefined()) {
10023             chainInfo.style = std::nullopt;
10024         } else if (tmpStyle->IsNumber()) {
10025             auto style = tmpStyle->ToNumber<int32_t>();
10026             chainInfo.style = static_cast<ChainStyle>(style);
10027         }
10028     }
10029     ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
10030 }
10031 
SetMarginTop(const JSCallbackInfo & info)10032 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
10033 {
10034     CalcDimension value;
10035     if (!ParseJsDimensionVp(info[0], value)) {
10036         return;
10037     }
10038     ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
10039 }
10040 
SetMarginBottom(const JSCallbackInfo & info)10041 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
10042 {
10043     CalcDimension value;
10044     if (!ParseJsDimensionVp(info[0], value)) {
10045         return;
10046     }
10047     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
10048 }
10049 
SetMarginLeft(const JSCallbackInfo & info)10050 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
10051 {
10052     CalcDimension value;
10053     if (!ParseJsDimensionVp(info[0], value)) {
10054         return;
10055     }
10056     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
10057 }
10058 
SetMarginRight(const JSCallbackInfo & info)10059 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
10060 {
10061     CalcDimension value;
10062     if (!ParseJsDimensionVp(info[0], value)) {
10063         return;
10064     }
10065     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
10066 }
10067 
SetPaddingTop(const JSCallbackInfo & info)10068 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
10069 {
10070     CalcDimension value;
10071     if (!ParseJsDimensionVp(info[0], value)) {
10072         return;
10073     }
10074     ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
10075 }
10076 
SetPaddingBottom(const JSCallbackInfo & info)10077 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
10078 {
10079     CalcDimension value;
10080     if (!ParseJsDimensionVp(info[0], value)) {
10081         return;
10082     }
10083     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
10084 }
10085 
SetPaddingLeft(const JSCallbackInfo & info)10086 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
10087 {
10088     CalcDimension value;
10089     if (!ParseJsDimensionVp(info[0], value)) {
10090         return;
10091     }
10092     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
10093 }
10094 
SetPaddingRight(const JSCallbackInfo & info)10095 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
10096 {
10097     CalcDimension value;
10098     if (!ParseJsDimensionVp(info[0], value)) {
10099         return;
10100     }
10101     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
10102 }
10103 
SetSafeAreaPadding(const JSCallbackInfo & info)10104 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
10105 {
10106     ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
10107 }
10108 
SetColorBlend(Color color)10109 void JSViewAbstract::SetColorBlend(Color color)
10110 {
10111     ViewAbstractModel::GetInstance()->SetColorBlend(color);
10112 }
10113 
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)10114 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
10115 {
10116     ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
10117 }
10118 
SetDynamicLightUp(float rate,float lightUpDegree)10119 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
10120 {
10121     ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
10122 }
10123 
SetBgDynamicBrightness(BrightnessOption brightnessOption)10124 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
10125 {
10126     ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
10127 }
10128 
SetFgDynamicBrightness(BrightnessOption brightnessOption)10129 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
10130 {
10131     ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
10132 }
10133 
SetWindowBlur(float progress,WindowBlurStyle blurStyle)10134 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
10135 {
10136     ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
10137 }
10138 
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)10139 bool JSViewAbstract::ParseJsonDimension(
10140     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
10141 {
10142     if (!jsonValue || jsonValue->IsNull()) {
10143         return false;
10144     }
10145     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
10146         return false;
10147     }
10148     if (jsonValue->IsNumber()) {
10149         result = Dimension(jsonValue->GetDouble(), defaultUnit);
10150         return true;
10151     }
10152     if (jsonValue->IsString()) {
10153         if (checkIllegal) {
10154             return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
10155         }
10156         result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
10157         return true;
10158     }
10159     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
10160     auto resId = resVal->GetValue("id");
10161     if (!resId || !resId->IsNumber()) {
10162         return false;
10163     }
10164 
10165     auto resourceWrapper = CreateResourceWrapper();
10166     if (!resourceWrapper) {
10167         return false;
10168     }
10169     result = resourceWrapper->GetDimension(resId->GetUInt());
10170     return true;
10171 }
10172 
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)10173 bool JSViewAbstract::ParseJsonDimensionVp(
10174     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
10175 {
10176     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10177         return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
10178     }
10179     return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
10180 }
10181 
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)10182 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
10183 {
10184     if (!jsonValue || jsonValue->IsNull()) {
10185         return false;
10186     }
10187     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
10188         return false;
10189     }
10190     if (jsonValue->IsNumber()) {
10191         result = jsonValue->GetDouble();
10192         return true;
10193     }
10194     if (jsonValue->IsString()) {
10195         result = StringUtils::StringToDouble(jsonValue->GetString());
10196         return true;
10197     }
10198     // parse json Resource
10199     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
10200     auto resId = resVal->GetValue("id");
10201     CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
10202     auto id = resId->GetUInt();
10203     auto resType = resVal->GetValue("type");
10204     CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
10205     auto type = resType->GetUInt();
10206 
10207     auto resourceWrapper = CreateResourceWrapper();
10208     if (!resourceWrapper) {
10209         return false;
10210     }
10211     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
10212         auto numberString = resourceWrapper->GetString(id);
10213         return StringUtils::StringToDouble(numberString, result);
10214     }
10215     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
10216         result = resourceWrapper->GetInt(id);
10217         return true;
10218     }
10219     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
10220         result = resourceWrapper->GetDouble(id);
10221         return true;
10222     }
10223     return false;
10224 }
10225 
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)10226 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
10227 {
10228     if (!jsonValue || jsonValue->IsNull()) {
10229         return false;
10230     }
10231     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
10232         return false;
10233     }
10234     if (jsonValue->IsNumber()) {
10235         result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
10236         return true;
10237     }
10238 
10239     bool isSetColor = false;
10240     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
10241         isSetColor = jsonValue->IsString();
10242     } else {
10243         isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
10244     }
10245     if (isSetColor) {
10246         result = Color::FromString(jsonValue->GetString());
10247         return true;
10248     }
10249     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
10250     auto resId = resVal->GetValue("id");
10251     if (!resId || !resId->IsNumber()) {
10252         return false;
10253     }
10254     auto resourceWrapper = CreateResourceWrapper();
10255     if (!resourceWrapper) {
10256         return false;
10257     }
10258     result = resourceWrapper->GetColor(resId->GetUInt());
10259     return true;
10260 }
10261 
ParseShadowOffsetXY(const JSRef<JSObject> & jsObj,Shadow & shadow)10262 void JSViewAbstract::ParseShadowOffsetXY(const JSRef<JSObject>& jsObj, Shadow& shadow)
10263 {
10264     CalcDimension offsetX;
10265     RefPtr<ResourceObject> xResObj;
10266     if (ParseJsResource(jsObj->GetProperty("offsetX"), offsetX, xResObj)) {
10267         if (SystemProperties::ConfigChangePerform() && xResObj) {
10268             auto&& updateFunc = [](const RefPtr<ResourceObject>& xResObj, Shadow& shadow) {
10269                 CalcDimension xValue;
10270                 ResourceParseUtils::ParseResResource(xResObj, xValue);
10271                 shadow.SetOffsetX(xValue.Value());
10272             };
10273             shadow.AddResource("shadow.offsetX", xResObj, std::move(updateFunc));
10274         }
10275         shadow.SetOffsetX(offsetX.Value());
10276     } else {
10277         if (ParseJsDimensionVp(jsObj->GetProperty("offsetX"), offsetX)) {
10278             shadow.SetOffsetX(offsetX.Value());
10279         }
10280     }
10281     CalcDimension offsetY;
10282     RefPtr<ResourceObject> yResObj;
10283     auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
10284     if (ParseJsResource(jsOffsetY, offsetY, yResObj)) {
10285         if (yResObj) {
10286             auto&& updateFunc = [](const RefPtr<ResourceObject>& yResObj, Shadow& shadow) {
10287                 CalcDimension yValue;
10288                 ResourceParseUtils::ParseResResource(yResObj, yValue);
10289                 shadow.SetOffsetY(yValue.Value());
10290             };
10291             shadow.AddResource("shadow.offsetY", yResObj, std::move(updateFunc));
10292         }
10293         shadow.SetOffsetY(offsetY.Value());
10294     } else {
10295         if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
10296             shadow.SetOffsetY(offsetY.Value());
10297         }
10298     }
10299 }
10300 
ParseShadowPropsUpdate(const JSRef<JSObject> & jsObj,double & radius,Shadow & shadow)10301 void JSViewAbstract::ParseShadowPropsUpdate(const JSRef<JSObject>& jsObj, double& radius, Shadow& shadow)
10302 {
10303     if (jsObj->IsUndefined()) {
10304         return;
10305     }
10306     RefPtr<ResourceObject> radiusResObj;
10307     ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius, radiusResObj);
10308     if (SystemProperties::ConfigChangePerform() && radiusResObj) {
10309         auto&& updateFunc = [](const RefPtr<ResourceObject>& radiusResObj, Shadow& shadow) {
10310             double radius = 0.0;
10311             ResourceParseUtils::ParseResDouble(radiusResObj, radius);
10312             if (LessNotEqual(radius, 0.0)) {
10313                 radius = 0.0;
10314             }
10315             shadow.SetBlurRadius(radius);
10316         };
10317         shadow.AddResource("shadow.radius", radiusResObj, std::move(updateFunc));
10318     }
10319 }
10320 
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow,const bool configChangePerform)10321 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow, const bool configChangePerform)
10322 {
10323     int32_t shadowStyle = 0;
10324     if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
10325         auto style = static_cast<ShadowStyle>(shadowStyle);
10326         return GetShadowFromTheme(style, shadow, configChangePerform);
10327     }
10328     if (!jsValue->IsObject()) {
10329         return false;
10330     }
10331     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10332     double radius = 0.0;
10333     ParseShadowPropsUpdate(jsObj, radius, shadow);
10334     if (LessNotEqual(radius, 0.0)) {
10335         radius = 0.0;
10336     }
10337     shadow.SetBlurRadius(radius);
10338     ParseShadowOffsetXY(jsObj, shadow);
10339 
10340     Color color;
10341     ShadowColorStrategy shadowColorStrategy;
10342     auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
10343     RefPtr<ResourceObject> colorResObj;
10344     if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
10345         shadow.SetShadowColorStrategy(shadowColorStrategy);
10346     } else if (ParseJsColor(jsColor, color, colorResObj)) {
10347         if (SystemProperties::ConfigChangePerform() && colorResObj) {
10348             auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, Shadow& shadow) {
10349                 Color colorValue;
10350                 ResourceParseUtils::ParseResColor(colorResObj, colorValue);
10351                 shadow.SetColor(colorValue);
10352             };
10353             shadow.AddResource("shadow.colorValue", colorResObj, std::move(updateFunc));
10354         }
10355         shadow.SetColor(color);
10356     }
10357 
10358     int32_t type = static_cast<int32_t>(ShadowType::COLOR);
10359     JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
10360     if (type != static_cast<int32_t>(ShadowType::BLUR)) {
10361         type = static_cast<int32_t>(ShadowType::COLOR);
10362     }
10363     shadow.SetShadowType(static_cast<ShadowType>(type));
10364     bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
10365     shadow.SetIsFilled(isFilled);
10366     return true;
10367 }
10368 
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow,const bool configChangePerform)10369 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow, const bool configChangePerform)
10370 {
10371     ViewAbstractModel::GetInstance()->RemoveResObj("shadowStyle");
10372     auto colorMode = Container::CurrentColorMode();
10373     if (shadowStyle == ShadowStyle::None) {
10374         return true;
10375     }
10376 
10377     auto container = Container::Current();
10378     CHECK_NULL_RETURN(container, false);
10379     auto pipelineContext = container->GetPipelineContext();
10380     CHECK_NULL_RETURN(pipelineContext, false);
10381 
10382     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
10383     if (!shadowTheme) {
10384         return false;
10385     }
10386     shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
10387     if (configChangePerform) {
10388         auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
10389         CHECK_NULL_RETURN(frameNode, false);
10390         auto pattern = frameNode->GetPattern();
10391         CHECK_NULL_RETURN(pattern, false);
10392         RefPtr<ResourceObject> resObj = AceType::MakeRefPtr<ResourceObject>("", "", -1);
10393         auto&& updateFunc = [shadowStyle, weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
10394             auto frameNode = weak.Upgrade();
10395             CHECK_NULL_VOID(frameNode);
10396             auto colorMode = Container::CurrentColorMode();
10397             auto container = Container::Current();
10398             CHECK_NULL_VOID(container);
10399             auto pipelineContext = container->GetPipelineContext();
10400             CHECK_NULL_VOID(pipelineContext);
10401             auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
10402             if (!shadowTheme) {
10403                 return;
10404             }
10405             Shadow shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
10406             ACE_UPDATE_NODE_RENDER_CONTEXT(BackShadow, shadow, frameNode);
10407         };
10408         updateFunc(resObj);
10409         pattern->AddResObj("shadowStyle", resObj, std::move(updateFunc));
10410         return false;
10411     }
10412     return true;
10413 }
10414 
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)10415 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
10416 {
10417     RefPtr<ResourceObject> resObj;
10418     return ParseJsResource(jsValue, result, resObj);
10419 }
10420 
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)10421 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result,
10422     RefPtr<ResourceObject>& resObj)
10423 {
10424     if (!jsValue->IsObject()) {
10425         return false;
10426     }
10427     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10428     uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
10429     if (type == 0) {
10430         return false;
10431     }
10432     if (SystemProperties::ConfigChangePerform()) {
10433         resObj = GetResourceObject(jsObj);
10434     }
10435     auto resourceWrapper = CreateResourceWrapper();
10436     CHECK_NULL_RETURN(resourceWrapper, false);
10437     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
10438         auto value = resourceWrapper->GetString(
10439             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
10440         return StringUtils::StringToCalcDimensionNG(value, result, false);
10441     }
10442     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
10443         auto value = std::to_string(
10444             resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
10445         StringUtils::StringToDimensionWithUnitNG(value, result);
10446         return true;
10447     }
10448 
10449     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
10450         result = resourceWrapper->GetDimension(
10451             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
10452         return true;
10453     }
10454     return false;
10455 }
10456 
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)10457 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
10458 {
10459     JSRef<JSVal> arg = info[0];
10460     if (!arg->IsObject()) {
10461         return false;
10462     }
10463     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
10464     JSRef<JSVal> typeValue = obj->GetProperty("types");
10465     if (!typeValue->IsArray()) {
10466         return false;
10467     }
10468     JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
10469     for (size_t i = 0; i < array->Length(); i++) {
10470         JSRef<JSVal> value = array->GetValueAt(i);
10471         auto index = value->ToNumber<int32_t>();
10472         if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
10473             return false;
10474         }
10475         if (i != 0) {
10476             textDetectConfig.types.append(",");
10477         }
10478         textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
10479     }
10480     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10481     JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
10482     if (resultCallback->IsFunction()) {
10483         auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
10484         textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
10485                        const std::string& result) {
10486             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10487             PipelineContext::SetCallBackNode(node);
10488             func->Execute(result);
10489         };
10490     }
10491     auto enablePreviewMenuValue = obj->GetProperty("enablePreviewMenu");
10492     if (enablePreviewMenuValue->IsBoolean()) {
10493         textDetectConfig.enablePreviewMenu = enablePreviewMenuValue->ToBoolean();
10494     }
10495     return ParseAIEntityColor(obj, textDetectConfig);
10496 }
10497 
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)10498 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
10499 {
10500     RefPtr<ResourceObject> resObj;
10501     JSRef<JSVal> entityColorValue = obj->GetProperty("color");
10502     ParseJsColor(entityColorValue, textDetectConfig.entityColor, resObj);
10503     TextDetectConfig::RegisterColorResource(textDetectConfig, resObj);
10504 
10505     JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
10506     if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
10507         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
10508         return true;
10509     }
10510     JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
10511     JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
10512     JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
10513     JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
10514 
10515     if (typeValue->IsNumber()) {
10516         textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
10517     } else {
10518         textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
10519     }
10520     RefPtr<ResourceObject> decoColorResObj;
10521     if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor, decoColorResObj)) {
10522         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
10523     }
10524     TextDetectConfig::RegisterDecoColorResource(textDetectConfig, decoColorResObj);
10525     if (styleValue->IsNumber()) {
10526         textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
10527     } else {
10528         textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
10529     }
10530     return true;
10531 }
10532 
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)10533 void JSViewAbstract::GetAngle(
10534     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
10535 {
10536     auto value = jsonValue->GetValue(key);
10537     if (value && value->IsString()) {
10538         angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
10539     } else if (value && value->IsNumber()) {
10540         angle = static_cast<float>(value->GetDouble());
10541     }
10542 }
10543 
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)10544 void JSViewAbstract::GetJsAngle(
10545     int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
10546 {
10547     if (!jsValue->IsObject()) {
10548         return;
10549     }
10550     JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
10551     if (value->IsString()) {
10552         angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
10553     } else if (value->IsNumber()) {
10554         angle = value->ToNumber<float>();
10555     }
10556 }
10557 
10558 // 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)10559 void JSViewAbstract::GetJsAngleWithDefault(
10560     int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
10561 {
10562     JSRef<JSVal> value = jsObj->GetProperty(key);
10563     if (value->IsString()) {
10564         double temp = 0.0;
10565         if (StringUtils::StringToDegree(value->ToString(), temp)) {
10566             angle = static_cast<float>(temp);
10567         } else {
10568             angle = defaultValue;
10569         }
10570     } else if (value->IsNumber()) {
10571         angle = value->ToNumber<float>();
10572     }
10573 }
10574 
CheckAngle(std::optional<float> & angle)10575 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
10576 {
10577     if (angle.has_value()) {
10578         angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
10579     }
10580 }
10581 
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)10582 void JSViewAbstract::GetPerspective(
10583     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
10584 {
10585     auto value = jsonValue->GetValue(key);
10586     if (value && value->IsNumber()) {
10587         perspective = static_cast<float>(value->GetDouble());
10588     }
10589 }
10590 
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)10591 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
10592 {
10593     auto value = jsValue->GetProperty(key);
10594     if (value->IsNumber()) {
10595         perspective = value->ToNumber<float>();
10596     }
10597 }
10598 
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)10599 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
10600 {
10601     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
10602         return;
10603     }
10604 
10605     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
10606         GradientColor gradientColor;
10607         auto item = colorStops->GetArrayItem(i);
10608         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
10609             auto colorParams = item->GetArrayItem(0);
10610             // color
10611             Color color;
10612             if (!ParseJsonColor(colorParams, color)) {
10613                 continue;
10614             }
10615             gradientColor.SetColor(color);
10616             gradientColor.SetHasValue(false);
10617             // stop value
10618             if (item->GetArraySize() <= 1) {
10619                 continue;
10620             }
10621             auto stopValue = item->GetArrayItem(1);
10622             double value = 0.0;
10623             if (ParseJsonDouble(stopValue, value)) {
10624                 value = std::clamp(value, 0.0, 1.0);
10625                 gradientColor.SetHasValue(true);
10626                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10627             }
10628             gradient.AddColor(gradientColor);
10629         }
10630     }
10631 }
10632 
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)10633 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
10634 {
10635     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
10636         return;
10637     }
10638 
10639     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
10640         NG::GradientColor gradientColor;
10641         auto item = colorStops->GetArrayItem(i);
10642         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
10643             auto colorParams = item->GetArrayItem(0);
10644             // color
10645             Color color;
10646             if (!ParseJsonColor(colorParams, color)) {
10647                 continue;
10648             }
10649             gradientColor.SetColor(color);
10650             gradientColor.SetHasValue(false);
10651             // stop value
10652             if (item->GetArraySize() <= 1) {
10653                 continue;
10654             }
10655             auto stopValue = item->GetArrayItem(1);
10656             double value = 0.0;
10657             if (ParseJsonDouble(stopValue, value)) {
10658                 value = std::clamp(value, 0.0, 1.0);
10659                 gradientColor.SetHasValue(true);
10660                 //  [0, 1] -> [0, 100.0];
10661                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10662             }
10663             gradient.AddColor(gradientColor);
10664         }
10665     }
10666 }
10667 
NewParseSweepGradientColor(NG::Gradient & gradient,RefPtr<ResourceObject> & resObj,NG::GradientColor & gradientColor,int32_t & indx)10668 void JSViewAbstract::NewParseSweepGradientColor(NG::Gradient& gradient, RefPtr<ResourceObject>& resObj,
10669     NG::GradientColor& gradientColor, int32_t& indx)
10670 {
10671     auto&& updateFunc = [gradientColor, indx](const RefPtr<ResourceObject>& resObj,
10672         NG::Gradient& gradient) {
10673         std::vector<NG::GradientColor> colorVector = gradient.GetColors();
10674         int32_t colorLength = static_cast<int32_t>(colorVector.size());
10675         gradient.ClearColors();
10676         for (int32_t index = 0; index < colorLength; index++) {
10677             NG::GradientColor gradColor = colorVector[index];
10678             if (index == indx) {
10679                 Color color;
10680                 ResourceParseUtils::ParseResColor(resObj, color);
10681                 gradColor.SetColor(color);
10682             }
10683             gradient.AddColor(gradColor);
10684         }
10685     };
10686     std::string key = "SweepGradient.gradient.color" + std::to_string(indx);
10687     gradient.AddResource(key, resObj, std::move(updateFunc));
10688 }
10689 
NewParseRadialGradientColor(NG::Gradient & gradient,RefPtr<ResourceObject> & resObj,NG::GradientColor & gradientColor,int32_t & indx)10690 void JSViewAbstract::NewParseRadialGradientColor(NG::Gradient& gradient, RefPtr<ResourceObject>& resObj,
10691     NG::GradientColor& gradientColor, int32_t& indx)
10692 {
10693     auto&& updateFunc = [gradientColor, indx](const RefPtr<ResourceObject>& resObj,
10694         NG::Gradient& gradient) {
10695         std::vector<NG::GradientColor> colorVector = gradient.GetColors();
10696         int32_t colorLength = static_cast<int32_t>(colorVector.size());
10697         gradient.ClearColors();
10698         for (int32_t index = 0; index < colorLength; index++) {
10699             NG::GradientColor gradColor = colorVector[index];
10700             if (index == indx) {
10701                 Color color;
10702                 ResourceParseUtils::ParseResColor(resObj, color);
10703                 gradColor.SetColor(color);
10704             }
10705             gradient.AddColor(gradColor);
10706         }
10707     };
10708     std::string key = "RadialGradient.gradient.color" + std::to_string(indx);
10709     gradient.AddResource(key, resObj, std::move(updateFunc));
10710 }
10711 
NewParseGradientColor(NG::Gradient & gradient,RefPtr<ResourceObject> & resObj,NG::GradientColor & gradientColor,int32_t & indx)10712 void JSViewAbstract::NewParseGradientColor(NG::Gradient& gradient, RefPtr<ResourceObject>& resObj,
10713     NG::GradientColor& gradientColor, int32_t& indx)
10714 {
10715     auto&& updateFunc = [gradientColor, indx](const RefPtr<ResourceObject>& resObj,
10716         NG::Gradient& gradient) {
10717         std::vector<NG::GradientColor> colorVector = gradient.GetColors();
10718         int32_t colorLength = static_cast<int32_t>(colorVector.size());
10719         gradient.ClearColors();
10720         for (int32_t index = 0; index < colorLength; index++) {
10721             NG::GradientColor gradColor = colorVector[index];
10722             if (index == indx) {
10723                 Color color;
10724                 ResourceParseUtils::ParseResColor(resObj, color);
10725                 gradColor.SetColor(color);
10726             }
10727             gradient.AddColor(gradColor);
10728         }
10729     };
10730     std::string key = "LinearGradient.gradient.color" + std::to_string(indx);
10731     gradient.AddResource(key, resObj, std::move(updateFunc));
10732 }
10733 
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops,const int32_t mapIdx)10734 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops,
10735     const int32_t mapIdx)
10736 {
10737     if (!colorStops->IsArray()) {
10738         return;
10739     }
10740     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
10741     size_t length = jsArray->Length();
10742     int32_t nullNum = 0;
10743     for (size_t i = 0; i < length; i++) {
10744         NG::GradientColor gradientColor;
10745         JSRef<JSVal> item = jsArray->GetValueAt(i);
10746         if (!item->IsArray()) {
10747             continue;
10748         }
10749         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
10750         if (subArray->Length() < 2) {
10751             continue;
10752         }
10753         // color
10754         Color color;
10755         RefPtr<ResourceObject> resObj;
10756         if (!ParseJsColor(subArray->GetValueAt(0), color, resObj)) {
10757             nullNum++;
10758             continue;
10759         }
10760         gradientColor.SetColor(color);
10761         gradientColor.SetHasValue(false);
10762         // stop value
10763         double value = 0.0;
10764         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
10765             value = std::clamp(value, 0.0, 1.0);
10766             gradientColor.SetHasValue(true);
10767         }
10768         //  [0, 1] -> [0, 100.0];
10769         gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10770         gradient.AddColor(gradientColor);
10771         if (SystemProperties::ConfigChangePerform() && resObj) {
10772             int32_t indx = static_cast<int32_t>(i) - nullNum;
10773             if (mapIdx == NUM_1) {
10774                 NewParseSweepGradientColor(gradient, resObj, gradientColor, indx);
10775             } else if (mapIdx == NUM_2) {
10776                 NewParseRadialGradientColor(gradient, resObj, gradientColor, indx);
10777             } else {
10778                 NewParseGradientColor(gradient, resObj, gradientColor, indx);
10779             }
10780         }
10781     }
10782 }
10783 
NewGetJsGradientColorStopsCheck(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)10784 void JSViewAbstract::NewGetJsGradientColorStopsCheck(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
10785 {
10786     if (!colorStops->IsArray()) {
10787         return;
10788     }
10789 
10790     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
10791     size_t length = jsArray->Length();
10792     bool isValid = true;
10793     for (size_t i = 0; i < length; i++) {
10794         NG::GradientColor gradientColor;
10795         JSRef<JSVal> item = jsArray->GetValueAt(i);
10796         if (!item->IsArray()) {
10797             continue;
10798         }
10799         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
10800         if (subArray->Length() < 2) {
10801             continue;
10802         }
10803         // color
10804         Color color;
10805         if (!ParseJsColor(subArray->GetValueAt(0), color)) {
10806             continue;
10807         }
10808         // is valid
10809         if (gradient.GetColors().size()) {
10810             if (color.GetColorSpace() != gradient.GetColors().back().GetColor().GetColorSpace()) {
10811                 isValid = false;
10812                 gradient.ClearColors();
10813                 break;
10814             }
10815         }
10816         gradientColor.SetColor(color);
10817         gradientColor.SetHasValue(false);
10818         // stop value
10819         double value = 0.0;
10820         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
10821             value = std::clamp(value, 0.0, 1.0);
10822             gradientColor.SetHasValue(true);
10823         }
10824         //  [0, 1] -> [0, 100.0];
10825         gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10826         gradient.AddColor(gradientColor);
10827     }
10828 }
10829 
SetDirection(const std::string & dir)10830 void JSViewAbstract::SetDirection(const std::string& dir)
10831 {
10832     TextDirection direction = TextDirection::AUTO;
10833     if (dir == "Ltr") {
10834         direction = TextDirection::LTR;
10835     } else if (dir == "Rtl") {
10836         direction = TextDirection::RTL;
10837     } else if (dir == "Auto") {
10838         direction = TextDirection::AUTO;
10839     } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10840         direction = TextDirection::AUTO;
10841     }
10842     ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
10843 }
10844 
GetThemeConstants(const JSRef<JSObject> & jsObj)10845 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
10846 {
10847     std::string bundleName;
10848     std::string moduleName;
10849     if (!jsObj->IsUndefined()) {
10850         JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
10851         JSRef<JSVal> module = jsObj->GetProperty("moduleName");
10852         if (bundle->IsString() && module->IsString()) {
10853             bundleName = bundle->ToString();
10854             moduleName = module->ToString();
10855         }
10856     }
10857 
10858     auto cardId = CardScope::CurrentId();
10859     if (cardId != INVALID_CARD_ID) {
10860         auto container = Container::Current();
10861         CHECK_NULL_RETURN(container, nullptr);
10862         auto weak = container->GetCardPipeline(cardId);
10863         auto cardPipelineContext = weak.Upgrade();
10864         CHECK_NULL_RETURN(cardPipelineContext, nullptr);
10865         auto cardThemeManager = cardPipelineContext->GetThemeManager();
10866         CHECK_NULL_RETURN(cardThemeManager, nullptr);
10867         return cardThemeManager->GetThemeConstants(bundleName, moduleName);
10868     }
10869 
10870 #ifdef PLUGIN_COMPONENT_SUPPORTED
10871     if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
10872         auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
10873         if (!pluginContainer) {
10874             return nullptr;
10875         }
10876         auto pluginPipelineContext = pluginContainer->GetPipelineContext();
10877         if (!pluginPipelineContext) {
10878             return nullptr;
10879         }
10880         auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
10881         if (!pluginThemeManager) {
10882             return nullptr;
10883         }
10884         return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
10885     }
10886 #endif
10887     auto container = Container::Current();
10888     CHECK_NULL_RETURN(container, nullptr);
10889     auto pipelineContext = container->GetPipelineContext();
10890     CHECK_NULL_RETURN(pipelineContext, nullptr);
10891     auto themeManager = pipelineContext->GetThemeManager();
10892     CHECK_NULL_RETURN(themeManager, nullptr);
10893     return themeManager->GetThemeConstants(bundleName, moduleName);
10894 }
10895 
JsHoverEffect(const JSCallbackInfo & info)10896 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
10897 {
10898     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
10899     auto jsVal = info[0];
10900     if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
10901         ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
10902         return;
10903     }
10904     if (!jsVal->IsNumber()) {
10905         return;
10906     }
10907     ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
10908 }
10909 
JsOnMouse(const JSCallbackInfo & info)10910 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
10911 {
10912     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10913         ViewAbstractModel::GetInstance()->DisableOnMouse();
10914         return;
10915     }
10916     if (!info[0]->IsFunction()) {
10917         return;
10918     }
10919 
10920     RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
10921     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10922     auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
10923                        MouseInfo& mouseInfo) {
10924         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10925         ACE_SCORING_EVENT("onMouse");
10926         PipelineContext::SetCallBackNode(node);
10927         func->Execute(mouseInfo);
10928     };
10929     ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
10930 }
10931 
JsOnAxisEvent(const JSCallbackInfo & args)10932 void JSViewAbstract::JsOnAxisEvent(const JSCallbackInfo& args)
10933 {
10934     JSRef<JSVal> arg = args[0];
10935     if (arg->IsUndefined() && IsDisableEventVersion()) {
10936         ViewAbstractModel::GetInstance()->DisableOnAxisEvent();
10937         return;
10938     }
10939     if (!arg->IsFunction()) {
10940         return;
10941     }
10942     EcmaVM* vm = args.GetVm();
10943     CHECK_NULL_VOID(vm);
10944     auto jsOnAxisEventFunc = JSRef<JSFunc>::Cast(args[0]);
10945     if (jsOnAxisEventFunc->IsEmpty()) {
10946         return;
10947     }
10948     auto jsOnAxisFuncLocalHandle = jsOnAxisEventFunc->GetLocalHandle();
10949     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10950     auto onAxisEvent = [vm, execCtx = args.GetExecutionContext(),
10951                        func = panda::CopyableGlobal(vm, jsOnAxisFuncLocalHandle),
10952                        node = frameNode](Ace::AxisInfo& info) {
10953         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10954         ACE_SCORING_EVENT("onAxis");
10955         PipelineContext::SetCallBackNode(node);
10956         auto eventObj = NG::CommonBridge::CreateAxisEventInfo(vm, info);
10957         panda::Local<panda::JSValueRef> params[1] = { eventObj };
10958         func->Call(vm, func.ToLocal(), params, 1);
10959     };
10960     ViewAbstractModel::GetInstance()->SetOnAxisEvent(std::move(onAxisEvent));
10961 }
10962 
JsOnHover(const JSCallbackInfo & info)10963 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
10964 {
10965     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10966         ViewAbstractModel::GetInstance()->DisableOnHover();
10967         return;
10968     }
10969     if (!info[0]->IsFunction()) {
10970         return;
10971     }
10972 
10973     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10974     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10975     auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
10976                        bool isHover, HoverInfo& hoverInfo) {
10977         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10978         ACE_SCORING_EVENT("onHover");
10979         PipelineContext::SetCallBackNode(node);
10980         func->HoverExecute(isHover, hoverInfo);
10981     };
10982     ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
10983 }
10984 
JsOnHoverMove(const JSCallbackInfo & info)10985 void JSViewAbstract::JsOnHoverMove(const JSCallbackInfo& info)
10986 {
10987     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10988         ViewAbstractModel::GetInstance()->DisableOnHoverMove();
10989         return;
10990     }
10991     if (!info[0]->IsFunction()) {
10992         return;
10993     }
10994 
10995     RefPtr<JsHoverFunction> jsOnHoverMoveFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10996     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10997     auto onHoverMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverMoveFunc), node = frameNode](
10998                        HoverInfo& hoverInfo) {
10999         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11000         ACE_SCORING_EVENT("onHoverMove");
11001         PipelineContext::SetCallBackNode(node);
11002         func->HoverMoveExecute(hoverInfo);
11003     };
11004     ViewAbstractModel::GetInstance()->SetOnHoverMove(std::move(onHoverMove));
11005 }
11006 
JsOnAccessibilityHover(const JSCallbackInfo & info)11007 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
11008 {
11009     if (info[0]->IsUndefined()) {
11010         ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
11011         return;
11012     }
11013     if (!info[0]->IsFunction()) {
11014         return;
11015     }
11016 
11017     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
11018     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11019     auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
11020                                     node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
11021         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11022         ACE_SCORING_EVENT("onAccessibilityHover");
11023         PipelineContext::SetCallBackNode(node);
11024         func->AccessibilityHoverExecute(isHover, hoverInfo);
11025     };
11026     ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
11027 }
11028 
JsOnClick(const JSCallbackInfo & info)11029 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
11030 {
11031     auto arg = info[0];
11032     if (arg->IsUndefined() && IsDisableEventVersion()) {
11033         ViewAbstractModel::GetInstance()->DisableOnClick();
11034         return;
11035     }
11036     if (!arg->IsFunction()) {
11037         return;
11038     }
11039 
11040     auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
11041     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11042     auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
11043                      BaseEventInfo* info) {
11044         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11045         auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
11046         ACE_SCORING_EVENT("onClick");
11047         PipelineContext::SetCallBackNode(node);
11048         func->Execute(*tapInfo);
11049 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
11050         JSInteractableView::ReportClickEvent(node);
11051 #endif
11052     };
11053     auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
11054     auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
11055                        const ClickInfo* info) {
11056         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11057         ACE_SCORING_EVENT("onClick");
11058         PipelineContext::SetCallBackNode(node);
11059         func->Execute(*info);
11060 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
11061         JSInteractableView::ReportClickEvent(node);
11062 #endif
11063     };
11064 
11065     Dimension distanceThreshold = Dimension(std::numeric_limits<double>::infinity(), DimensionUnit::PX);
11066     if (info.Length() > 1 && info[1]->IsNumber()) {
11067         double jsDistanceThreshold = info[1]->ToNumber<double>();
11068         if (jsDistanceThreshold < 0) {
11069             distanceThreshold = Dimension(std::numeric_limits<double>::infinity(), DimensionUnit::PX);
11070         }
11071         distanceThreshold = Dimension(jsDistanceThreshold, DimensionUnit::VP);
11072     }
11073     ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
11074 }
11075 
JsOnGestureJudgeBegin(const JSCallbackInfo & info)11076 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
11077 {
11078     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11079         ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
11080         return;
11081     }
11082 
11083     auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
11084     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11085     auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
11086                                   const RefPtr<NG::GestureInfo>& gestureInfo,
11087                                   const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
11088         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
11089         ACE_SCORING_EVENT("onGestureJudgeBegin");
11090         PipelineContext::SetCallBackNode(node);
11091         return func->Execute(gestureInfo, info);
11092     };
11093     ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
11094 }
11095 
JsOnTouchIntercept(const JSCallbackInfo & info)11096 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
11097 {
11098     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11099         ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
11100         return;
11101     }
11102 
11103     auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
11104     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11105     auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
11106                                     TouchEventInfo& info) -> NG::HitTestMode {
11107         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
11108         ACE_SCORING_EVENT("onTouchIntercept");
11109         PipelineContext::SetCallBackNode(node);
11110         return func->Execute(info);
11111     };
11112     ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
11113 }
11114 
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)11115 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
11116 {
11117     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11118         ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
11119         return;
11120     }
11121 
11122     auto jsParallelInnerGestureToFunc =
11123         AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
11124     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11125     auto shouldBuiltInRecognizerParallelWithFunc =
11126         [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
11127             const RefPtr<NG::NGGestureRecognizer>& current,
11128             const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
11129         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
11130         ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
11131         PipelineContext::SetCallBackNode(node);
11132         return func->Execute(current, others);
11133     };
11134     ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
11135         std::move(shouldBuiltInRecognizerParallelWithFunc));
11136 }
11137 
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)11138 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
11139 {
11140     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11141         ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
11142         return;
11143     }
11144 
11145     auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
11146     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11147     auto onGestureRecognizerJudgefunc =
11148         [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
11149             const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
11150             const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
11151         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
11152         ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
11153         PipelineContext::SetCallBackNode(node);
11154         return func->Execute(info, current, others);
11155     };
11156 
11157     bool exposeInnerGestureFlag = false;
11158     if (info.Length() > 1 && info[1]->IsBoolean()) {
11159         exposeInnerGestureFlag = info[1]->ToBoolean();
11160     }
11161     ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
11162         std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
11163 }
11164 
JsOnTouchTestDone(const JSCallbackInfo & info)11165 void JSViewAbstract::JsOnTouchTestDone(const JSCallbackInfo& info)
11166 {
11167     if (info.Length() < 1 || info[0]->IsUndefined() || !info[0]->IsFunction()) {
11168         ViewAbstractModel::GetInstance()->SetOnTouchTestDone(nullptr);
11169         return;
11170     }
11171     auto JsOnTouchTestDoneFunc = AceType::MakeRefPtr<JsTouchTestDoneFunction>(JSRef<JSFunc>::Cast(info[0]));
11172     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11173     auto onTouchTestDoneFunc = [execCtx = info.GetExecutionContext(), func = JsOnTouchTestDoneFunc, node = frameNode](
11174                                    const std::shared_ptr<BaseGestureEvent>& info,
11175                                    const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> bool {
11176         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
11177         ACE_SCORING_EVENT("onTouchTestDone");
11178         PipelineContext::SetCallBackNode(node);
11179         return func->Execute(info, others);
11180     };
11181     ViewAbstractModel::GetInstance()->SetOnTouchTestDone(std::move(onTouchTestDoneFunc));
11182 }
11183 
JsClickEffect(const JSCallbackInfo & info)11184 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
11185 {
11186     JSRef<JSVal> arg = info[0];
11187     if (arg->IsUndefined() || arg->IsNull()) {
11188         ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
11189         return;
11190     }
11191     if (!arg->IsObject()) {
11192         return;
11193     }
11194     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
11195     JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
11196     int32_t clickEffectLevelValue = 0;
11197     if (clickEffectLevel->IsNumber()) {
11198         clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
11199         if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
11200             clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
11201             clickEffectLevelValue = 0;
11202         }
11203     }
11204 
11205     JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
11206     float scaleNumberValue = DEFAULT_SCALE_LIGHT;
11207     if (!scaleNumber->IsNumber()) {
11208         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
11209             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
11210             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
11211         }
11212         ViewAbstractModel::GetInstance()->SetClickEffectLevel(
11213             (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
11214         return;
11215     }
11216 
11217     scaleNumberValue = scaleNumber->ToNumber<float>();
11218     if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
11219         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
11220             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
11221             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
11222         } else {
11223             scaleNumberValue = DEFAULT_SCALE_LIGHT;
11224         }
11225     }
11226 
11227     ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
11228 }
11229 
JsOnVisibleAreaChange(const JSCallbackInfo & info)11230 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
11231 {
11232     if (info.Length() < 2 || info.Length() > 3) {
11233         return;
11234     }
11235 
11236     if (!info[0]->IsArray() || !info[1]->IsFunction()) {
11237         return;
11238     }
11239 
11240     auto ratioArray = JSRef<JSArray>::Cast(info[0]);
11241     size_t size = ratioArray->Length();
11242     std::vector<double> ratioVec(size);
11243     ratioVec.clear();
11244     for (size_t i = 0; i < size; i++) {
11245         double ratio = 0.0;
11246         ParseJsDouble(ratioArray->GetValueAt(i), ratio);
11247         if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
11248             ratio = VISIBLE_RATIO_MIN;
11249         }
11250 
11251         if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
11252             ratio = VISIBLE_RATIO_MAX;
11253         }
11254         ratioVec.push_back(ratio);
11255     }
11256 
11257     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
11258     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11259     auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
11260                                bool visible, double ratio) {
11261         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11262         ACE_SCORING_EVENT("onVisibleAreaChange");
11263 
11264         JSRef<JSVal> params[2];
11265         params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
11266         params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
11267         PipelineContext::SetCallBackNode(node);
11268         func->ExecuteJS(2, params);
11269     };
11270 
11271     bool isOutOfBoundsAllowed = false;
11272     if (info.Length() == 3 && info[2]->IsBoolean()) {
11273         isOutOfBoundsAllowed = info[2]->ToBoolean();
11274     }
11275     ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec, isOutOfBoundsAllowed);
11276 }
11277 
JsOnVisibleAreaApproximateChange(const JSCallbackInfo & info)11278 void JSViewAbstract::JsOnVisibleAreaApproximateChange(const JSCallbackInfo& info)
11279 {
11280     if (info.Length() != PARAMETER_LENGTH_SECOND) {
11281         return;
11282     }
11283 
11284     if (!info[0]->IsObject() || !info[1]->IsFunction()) {
11285         return;
11286     }
11287 
11288     const auto& options = info[0];
11289     JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(options);
11290     JSRef<JSVal> ratios = optionObj->GetProperty("ratios");
11291     if (!ratios->IsArray()) {
11292         return;
11293     }
11294     auto ratioArray = JSRef<JSArray>::Cast(ratios);
11295     size_t size = ratioArray->Length();
11296     std::vector<double> ratioVec(size);
11297     for (size_t i = 0; i < size; i++) {
11298         double ratio = 0.0;
11299         ParseJsDouble(ratioArray->GetValueAt(i), ratio);
11300         ratio = std::clamp(ratio, VISIBLE_RATIO_MIN, VISIBLE_RATIO_MAX);
11301         ratioVec.push_back(ratio);
11302     }
11303     int32_t expectedUpdateInterval = DEFAULT_DURATION;
11304     JSRef<JSVal> expectedUpdateIntervalVal = optionObj->GetProperty("expectedUpdateInterval");
11305     if (expectedUpdateIntervalVal->IsNumber()) {
11306         JSViewAbstract::ParseJsInteger(expectedUpdateIntervalVal, expectedUpdateInterval);
11307     }
11308     if (expectedUpdateInterval < 0) {
11309         expectedUpdateInterval = DEFAULT_DURATION;
11310     }
11311 
11312     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
11313     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11314     auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
11315                                bool visible, double ratio) {
11316         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11317         ACE_SCORING_EVENT("onVisibleAreaApproximateChange");
11318 
11319         JSRef<JSVal> params[2];
11320         params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
11321         params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
11322         PipelineContext::SetCallBackNode(node);
11323         func->ExecuteJS(2, params);
11324     };
11325     ViewAbstractModel::GetInstance()->SetOnVisibleAreaApproximateChange(
11326         std::move(onVisibleChange), ratioVec, expectedUpdateInterval);
11327 }
11328 
JsHitTestBehavior(const JSCallbackInfo & info)11329 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
11330 {
11331     if (info.Length() != 1 || !info[0]->IsNumber()) {
11332         return;
11333     }
11334 
11335     NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
11336     hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
11337     ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
11338 }
11339 
JsOnChildTouchTest(const JSCallbackInfo & info)11340 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
11341 {
11342     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
11343     auto jsVal = info[0];
11344     if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
11345         return;
11346     }
11347 
11348     RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
11349         AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
11350 
11351     auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
11352                                const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
11353         NG::TouchResult touchRes;
11354         NG::TouchResult defaultRes;
11355         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, defaultRes);
11356         defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
11357         defaultRes.id = "";
11358         auto ret = func->Execute(touchInfo);
11359         if (!ret->IsObject()) {
11360             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
11361             return defaultRes;
11362         }
11363 
11364         auto retObj = JSRef<JSObject>::Cast(ret);
11365         auto strategy = retObj->GetProperty("strategy");
11366         if (!strategy->IsNumber()) {
11367             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
11368             return defaultRes;
11369         }
11370         touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
11371         auto id = retObj->GetProperty("id");
11372         if (!id->IsString()) {
11373             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
11374             return defaultRes;
11375         }
11376         touchRes.id = id->ToString();
11377         return touchRes;
11378     };
11379     ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
11380 }
11381 
JsForegroundColor(const JSCallbackInfo & info)11382 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
11383 {
11384     ViewAbstractModel::GetInstance()->RemoveResObj("foregroundColor");
11385     ViewAbstractModel::GetInstance()->RemoveResObj("foregroundColorStrategy");
11386     Color foregroundColor = Color::TRANSPARENT;
11387     ForegroundColorStrategy strategy;
11388     if (ParseJsColorStrategy(info[0], strategy)) {
11389         ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
11390         return;
11391     }
11392     if (!SystemProperties::ConfigChangePerform()) {
11393         ParseJsColor(info[0], foregroundColor);
11394         ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
11395     } else {
11396         RefPtr<ResourceObject> foregroundResObj;
11397         ParseJsColor(info[0], foregroundColor, foregroundResObj);
11398         if (foregroundResObj) {
11399             ViewAbstractModel::GetInstance()->CreateWithForegroundColorResourceObj(foregroundResObj);
11400         } else {
11401             ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
11402         }
11403     }
11404 }
11405 
JsKeyboardShortcut(const JSCallbackInfo & info)11406 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
11407 {
11408     // KeyboardShortcut only allows 2 or 3 params.
11409     if (info.Length() < 2 || info.Length() > 3) {
11410         return;
11411     }
11412     if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
11413         // clear shortcut key
11414         ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
11415         return;
11416     }
11417 
11418     std::string value;
11419     if (info[0]->IsString()) {
11420         // common letter/number/symbol
11421         value = info[0]->ToString();
11422         if (value.size() != 1) {
11423             // clear shortcut key
11424             ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
11425             return;
11426         }
11427     } else {
11428         // function keys such as F1-F10/ESC
11429         FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
11430         value = GetFunctionKeyName(functionkey);
11431     }
11432 
11433     auto keysArray = JSRef<JSArray>::Cast(info[1]);
11434     size_t size = keysArray->Length();
11435     std::vector<ModifierKey> keys(size);
11436     keys.clear();
11437     for (size_t i = 0; i < size; i++) {
11438         JSRef<JSVal> key = keysArray->GetValueAt(i);
11439         if (key->IsNumber()) {
11440             keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
11441         }
11442     }
11443 
11444     // KeyboardShortcut allows 3 params, the third param is function callback.
11445     if (info.Length() == 3 && info[2]->IsFunction()) {
11446         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
11447         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11448         auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11449                                             node = frameNode]() {
11450             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11451             ACE_SCORING_EVENT("onKeyboardShortcutAction");
11452             PipelineContext::SetCallBackNode(node);
11453             func->ExecuteJS();
11454         };
11455         ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
11456         return;
11457     }
11458     ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
11459 }
11460 
JsOnFocusAxisEvent(const JSCallbackInfo & args)11461 void JSViewAbstract::JsOnFocusAxisEvent(const JSCallbackInfo& args)
11462 {
11463     JSRef<JSVal> arg = args[0];
11464     if (arg->IsUndefined() && IsDisableEventVersion()) {
11465         ViewAbstractModel::GetInstance()->DisableOnFocusAxisEvent();
11466         return;
11467     }
11468     if (!arg->IsFunction()) {
11469         return;
11470     }
11471     EcmaVM* vm = args.GetVm();
11472     CHECK_NULL_VOID(vm);
11473     auto jsOnFocusAxisEventFunc = JSRef<JSFunc>::Cast(arg);
11474     if (jsOnFocusAxisEventFunc->IsEmpty()) {
11475         return;
11476     }
11477     auto jsOnFocusAxisFuncLocalHandle = jsOnFocusAxisEventFunc->GetLocalHandle();
11478     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11479     auto onFocusAxisEvent = [vm, execCtx = args.GetExecutionContext(),
11480                        func = panda::CopyableGlobal(vm, jsOnFocusAxisFuncLocalHandle),
11481                        node = frameNode](NG::FocusAxisEventInfo& info) {
11482         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11483         ACE_SCORING_EVENT("onFocusAxis");
11484         PipelineContext::SetCallBackNode(node);
11485         auto eventObj = NG::CommonBridge::CreateFocusAxisEventInfo(vm, info);
11486         panda::Local<panda::JSValueRef> params[1] = { eventObj };
11487         func->Call(vm, func.ToLocal(), params, 1);
11488     };
11489     ViewAbstractModel::GetInstance()->SetOnFocusAxisEvent(std::move(onFocusAxisEvent));
11490 }
11491 
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)11492 bool JSViewAbstract::CheckColor(
11493     const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
11494 {
11495     RefPtr<ResourceObject> resourceObject;
11496     return CheckColor(jsValue, result, componentName, propName, resourceObject);
11497 }
11498 
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName,RefPtr<ResourceObject> & resourceObject)11499 bool JSViewAbstract::CheckColor(
11500     const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName,
11501     RefPtr<ResourceObject>& resourceObject)
11502 {
11503     // Color is undefined or null
11504     if (jsValue->IsUndefined() || jsValue->IsNull()) {
11505         return false;
11506     }
11507     // input type is not in [number, string, Resource]
11508     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
11509         return false;
11510     }
11511     // Correct type, incorrect value parsing
11512     if (!ParseJsColor(jsValue, result, resourceObject)) {
11513         return false;
11514     }
11515     return true;
11516 }
11517 
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)11518 bool JSViewAbstract::CheckLength(
11519     const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
11520 {
11521     RefPtr<ResourceObject> resourceObject;
11522     return CheckLength(jsValue, result, componentName, propName, resourceObject);
11523 }
11524 
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName,RefPtr<ResourceObject> & resourceObject)11525 bool JSViewAbstract::CheckLength(
11526     const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName,
11527     RefPtr<ResourceObject>& resourceObject)
11528 {
11529     // Length is undefined or null
11530     if (jsValue->IsUndefined() || jsValue->IsNull()) {
11531         return false;
11532     }
11533     // input type is not in [number, string, Resource]
11534     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
11535         return false;
11536     }
11537     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
11538         return ParseJsDimensionVpNG(jsValue, result, resourceObject);
11539     }
11540     // Correct type, incorrect value parsing
11541     if (!ParseJsDimensionVp(jsValue, result, resourceObject)) {
11542         return false;
11543     }
11544     return true;
11545 }
11546 
11547 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)11548 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
11549 {
11550     JSRef<JSVal> arg = info[0];
11551     if (arg->IsUndefined() || arg->IsNull()) {
11552         std::vector<ObscuredReasons> reasons(0);
11553         ViewAbstractModel::GetInstance()->SetObscured(reasons);
11554         return;
11555     }
11556     if (!arg->IsArray()) {
11557         return;
11558     }
11559 
11560     auto obscuredArray = JSRef<JSArray>::Cast(arg);
11561     size_t size = obscuredArray->Length();
11562     std::vector<ObscuredReasons> reasons(size);
11563     reasons.clear();
11564     for (size_t i = 0; i < size; i++) {
11565         JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
11566         if (reason->IsNumber()) {
11567             reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
11568         }
11569     }
11570 
11571     ViewAbstractModel::GetInstance()->SetObscured(reasons);
11572 }
11573 
11574 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)11575 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
11576 {
11577     auto sensitiveInfo = info[0];
11578     if (sensitiveInfo->IsUndefined()) {
11579         ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
11580         return;
11581     }
11582     bool sensitive = false;
11583     if (sensitiveInfo->IsBoolean()) {
11584         sensitive = sensitiveInfo->ToBoolean();
11585     }
11586     ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
11587 }
11588 
JSRenderGroup(const JSCallbackInfo & info)11589 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
11590 {
11591     if (info.Length() != 1) {
11592         return;
11593     }
11594     bool isRenderGroup = false;
11595     if (info[0]->IsBoolean()) {
11596         isRenderGroup = info[0]->ToBoolean();
11597     }
11598     ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
11599 }
11600 
JSRenderFit(const JSCallbackInfo & info)11601 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
11602 {
11603     if (info.Length() != 1) {
11604         return;
11605     }
11606     RenderFit renderFit = RenderFit::TOP_LEFT;
11607     if (info[0]->IsNumber()) {
11608         int32_t fitNumber = info[0]->ToNumber<int32_t>();
11609         if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
11610             fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
11611             renderFit = static_cast<RenderFit>(fitNumber);
11612         }
11613     }
11614     // how content fills the node duration implicit animation
11615     ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
11616 }
11617 
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)11618 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
11619 {
11620     if (!jsValue->IsObject() || jsValue->IsString()) {
11621         return false;
11622     }
11623     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
11624     if (!jsObj->IsUndefined()) {
11625         JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
11626         JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
11627         if (bundle->IsString() && module->IsString()) {
11628             bundleName = bundle->ToString();
11629             moduleName = module->ToString();
11630             return true;
11631         }
11632     }
11633     return false;
11634 }
11635 
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)11636 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
11637 {
11638     RefPtr<ResourceObject> resourceObj;
11639     return ParseBorderColorProps(args, colorProperty, resourceObj);
11640 }
11641 
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty,RefPtr<ResourceObject> & resourceObj)11642 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args,
11643     NG::BorderColorProperty& colorProperty, RefPtr<ResourceObject>& resourceObj)
11644 {
11645     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
11646         return false;
11647     }
11648     Color borderColor;
11649     if (ParseJsColor(args, borderColor, resourceObj)) {
11650         colorProperty.SetColor(borderColor);
11651         return true;
11652     } else if (args->IsObject()) {
11653         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
11654         CommonColor commonColor;
11655         auto isLocalizedEdgeColor = ParseCommonEdgeColors(obj, commonColor);
11656         colorProperty.topColor = commonColor.top;
11657         colorProperty.bottomColor = commonColor.bottom;
11658         if (isLocalizedEdgeColor) {
11659             colorProperty.startColor = commonColor.left;
11660             colorProperty.endColor = commonColor.right;
11661         } else {
11662             colorProperty.leftColor = commonColor.left;
11663             colorProperty.rightColor = commonColor.right;
11664         }
11665         colorProperty.multiValued = true;
11666         RegisterBorderColorRes(colorProperty, commonColor, isLocalizedEdgeColor);
11667         return true;
11668     }
11669     return false;
11670 }
11671 
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)11672 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
11673 {
11674     RefPtr<ResourceObject> resourceObj;
11675     return ParseBorderWidthProps(args, borderWidthProperty, resourceObj);
11676 }
11677 
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty,RefPtr<ResourceObject> & resourceObj)11678 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args,
11679     NG::BorderWidthProperty& borderWidthProperty, RefPtr<ResourceObject>& resourceObj)
11680 {
11681     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
11682         return false;
11683     }
11684     CalcDimension borderWidth;
11685     if (ParseJsDimensionVpNG(args, borderWidth, resourceObj, true)) {
11686         if (borderWidth.IsNegative()) {
11687             borderWidth.Reset();
11688         }
11689         borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth,
11690             std::nullopt, std::nullopt});
11691         return true;
11692     } else if (args->IsObject()) {
11693         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
11694         CommonCalcDimension commonCalcDimension;
11695         ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
11696         borderWidthProperty.topDimen = commonCalcDimension.top;
11697         borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
11698         borderWidthProperty.leftDimen = commonCalcDimension.left;
11699         borderWidthProperty.rightDimen = commonCalcDimension.right;
11700         borderWidthProperty.multiValued = true;
11701         if (SystemProperties::ConfigChangePerform()) {
11702             ParseEdgeWidthsResObjFunc(borderWidthProperty,
11703                 commonCalcDimension.leftResObj, commonCalcDimension.rightResObj,
11704                 commonCalcDimension.topResObj, commonCalcDimension.bottomResObj);
11705         }
11706         return true;
11707     }
11708     return false;
11709 }
11710 
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)11711 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
11712 {
11713     if (!args->IsObject() && !args->IsNumber()) {
11714         return false;
11715     }
11716     if (args->IsObject()) {
11717         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
11718         auto leftValue = obj->GetProperty("left");
11719         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
11720             ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
11721         }
11722         auto rightValue = obj->GetProperty("right");
11723         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
11724             ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
11725         }
11726         auto topValue = obj->GetProperty("top");
11727         if (!topValue->IsUndefined() && topValue->IsNumber()) {
11728             ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
11729         }
11730         auto bottomValue = obj->GetProperty("bottom");
11731         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
11732             ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
11733         }
11734         borderStyleProperty.multiValued = true;
11735         return true;
11736     }
11737     std::optional<BorderStyle> borderStyle;
11738     if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
11739         borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
11740         return true;
11741     }
11742     return false;
11743 }
11744 
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)11745 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
11746 {
11747     std::optional<CalcDimension> radiusTopLeft;
11748     std::optional<CalcDimension> radiusTopRight;
11749     std::optional<CalcDimension> radiusBottomLeft;
11750     std::optional<CalcDimension> radiusBottomRight;
11751     CalcDimension topLeft;
11752     RefPtr<ResourceObject> topStartResObj;
11753     if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, topStartResObj, true)) {
11754         radiusTopLeft = topLeft;
11755     }
11756     CalcDimension topRight;
11757     RefPtr<ResourceObject> topEndResObj;
11758     if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, topEndResObj, true)) {
11759         radiusTopRight = topRight;
11760     }
11761     CalcDimension bottomLeft;
11762     RefPtr<ResourceObject> bottomStartResObj;
11763     if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, bottomStartResObj, true)) {
11764         radiusBottomLeft = bottomLeft;
11765     }
11766     CalcDimension bottomRight;
11767     RefPtr<ResourceObject> bottomEndResObj;
11768     if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, bottomEndResObj, true)) {
11769         radiusBottomRight = bottomRight;
11770     }
11771     CheckLengthMetrics(object);
11772     radius.radiusTopLeft = radiusTopLeft;
11773     radius.radiusTopRight = radiusTopRight;
11774     radius.radiusBottomLeft = radiusBottomLeft;
11775     radius.radiusBottomRight = radiusBottomRight;
11776     radius.multiValued = true;
11777     RegisterRadiusRes(radius, topStartResObj, topEndResObj, bottomStartResObj, bottomEndResObj);
11778     return;
11779 }
11780 
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius,bool notNegative)11781 void JSViewAbstract::ParseCommonBorderRadiusProps(
11782     const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius, bool notNegative)
11783 {
11784     if (CheckLengthMetrics(object)) {
11785         std::optional<CalcDimension> radiusTopStart;
11786         std::optional<CalcDimension> radiusTopEnd;
11787         std::optional<CalcDimension> radiusBottomStart;
11788         std::optional<CalcDimension> radiusBottomEnd;
11789         if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
11790             JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
11791             CalcDimension calcDimension;
11792             if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
11793                 CheckDimensionUnit(calcDimension, false, notNegative);
11794                 radiusTopStart = calcDimension;
11795             }
11796         }
11797         if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
11798             JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
11799             CalcDimension calcDimension;
11800             if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
11801                 CheckDimensionUnit(calcDimension, false, notNegative);
11802                 radiusTopEnd = calcDimension;
11803             }
11804         }
11805         if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
11806             JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
11807             CalcDimension calcDimension;
11808             if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
11809                 CheckDimensionUnit(calcDimension, false, notNegative);
11810                 radiusBottomStart = calcDimension;
11811             }
11812         }
11813         if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
11814             JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
11815             CalcDimension calcDimension;
11816             if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
11817                 CheckDimensionUnit(calcDimension, false, notNegative);
11818                 radiusBottomEnd = calcDimension;
11819             }
11820         }
11821         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
11822         radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
11823         radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
11824         radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
11825         radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
11826         radius.multiValued = true;
11827         return;
11828     }
11829     ParseBorderRadiusProps(object, radius);
11830 }
11831 
11832 
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius,bool notNegative)11833 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius, bool notNegative)
11834 {
11835     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
11836         return false;
11837     }
11838     CalcDimension borderRadius;
11839     if (ParseJsDimensionVpNG(args, borderRadius, true)) {
11840         radius = NG::BorderRadiusProperty(borderRadius);
11841         radius.multiValued = false;
11842     } else if (args->IsObject()) {
11843         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
11844         ParseCommonBorderRadiusProps(object, radius, notNegative);
11845     } else {
11846         return false;
11847     }
11848     return true;
11849 }
11850 
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)11851 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
11852 {
11853     JSRef<JSVal> arg = info[0];
11854     if (!arg->IsObject()) {
11855         return;
11856     }
11857     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
11858     auto vm = info.GetVm();
11859     auto globalObj = JSNApi::GetGlobalObject(vm);
11860     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
11861     JsiValue jsiValue(globalFunc);
11862     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11863     if (globalFuncRef->IsFunction()) {
11864         auto modifierObj = obj->GetProperty("modifier");
11865         if (modifierObj->IsUndefined()) {
11866             option.onApply = nullptr;
11867         } else {
11868             RefPtr<JsFunction> jsFunc =
11869                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11870             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11871                                modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11872                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11873                 auto node = frameNode.Upgrade();
11874                 JSRef<JSVal> params[SECOND_INDEX];
11875                 params[0] = modifier;
11876                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11877                 PipelineContext::SetCallBackNode(node);
11878                 func->ExecuteJS(SECOND_INDEX, params);
11879             };
11880             option.onApply = onApply;
11881         }
11882     }
11883 }
11884 
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)11885 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
11886 {
11887     if (!info[0]->IsObject()) {
11888         return;
11889     }
11890     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
11891     auto numberBadge = obj->GetProperty("numberBadge");
11892     if (!numberBadge->IsEmpty()) {
11893         if (numberBadge->IsNumber()) {
11894             int64_t number = numberBadge->ToNumber<int64_t>();
11895             if (number < 0 || number > INT_MAX) {
11896                 option.isNumber = false;
11897                 option.isShowBadge = true;
11898             } else {
11899                 option.isNumber = true;
11900                 option.badgeNumber = numberBadge->ToNumber<int>();
11901             }
11902         } else if (numberBadge->IsBoolean()) {
11903             option.isNumber = false;
11904             option.isShowBadge = numberBadge->ToBoolean();
11905         }
11906     } else {
11907         option.isNumber = false;
11908         option.isShowBadge = true;
11909     }
11910 }
11911 
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)11912 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
11913 {
11914     // Parse cornerRadius.
11915     auto cornerRadiusValue = obj->GetProperty("cornerRadius");
11916     NG::BorderRadiusProperty radius;
11917     if (ParseBorderRadius(cornerRadiusValue, radius)) {
11918         properties.borderRadius = radius;
11919     }
11920     // Parse border width
11921     auto borderWidthValue = obj->GetProperty("borderWidth");
11922     NG::BorderWidthProperty borderWidth;
11923     if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
11924         properties.borderWidth = borderWidth;
11925         auto colorValue = obj->GetProperty("borderColor");
11926         NG::BorderColorProperty borderColor;
11927         if (ParseBorderColorProps(colorValue, borderColor)) {
11928             properties.borderColor = borderColor;
11929         } else {
11930             borderColor.SetColor(Color::BLACK);
11931             properties.borderColor = borderColor;
11932         }
11933         // Parse border style
11934         auto styleValue = obj->GetProperty("borderStyle");
11935         NG::BorderStyleProperty borderStyle;
11936         if (ParseBorderStyleProps(styleValue, borderStyle)) {
11937             properties.borderStyle = borderStyle;
11938         } else {
11939             properties.borderStyle = NG::BorderStyleProperty(
11940                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
11941         }
11942     }
11943     auto shadowValue = obj->GetProperty("shadow");
11944     Shadow shadow;
11945     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
11946         properties.shadow = shadow;
11947     }
11948     auto widthValue = obj->GetProperty("width");
11949     CalcDimension width;
11950     if (ParseJsDimensionVpNG(widthValue, width, true)) {
11951         properties.width = width;
11952     }
11953     auto heightValue = obj->GetProperty("height");
11954     CalcDimension height;
11955     if (ParseJsDimensionVpNG(heightValue, height, true)) {
11956         properties.height = height;
11957     }
11958 }
11959 
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx,JSRef<JSObject> modifier)11960 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
11961     const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx, JSRef<JSObject> modifier)
11962 {
11963     std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx, modifier](
11964                                                                          NG::DrawingContext& context) -> void {
11965         JAVASCRIPT_EXECUTION_SCOPE(execCtx);
11966         if (modifier->IsEmpty()) {
11967             return;
11968         }
11969         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
11970         objectTemplate->SetInternalFieldCount(1);
11971         JSRef<JSObject> contextObj = objectTemplate->NewInstance();
11972         JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
11973         sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
11974         sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
11975         contextObj->SetPropertyObject("size", sizeObj);
11976 
11977         JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
11978         sizeInPxObj->SetProperty<float>("height", context.height);
11979         sizeInPxObj->SetProperty<float>("width", context.width);
11980         contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
11981 
11982         auto engine = EngineHelper::GetCurrentEngine();
11983         CHECK_NULL_VOID(engine);
11984         NativeEngine* nativeEngine = engine->GetNativeEngine();
11985         napi_env env = reinterpret_cast<napi_env>(nativeEngine);
11986         ScopeRAII scope(env);
11987 
11988         auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
11989         OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
11990         napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
11991         if (unwrapCanvas) {
11992             unwrapCanvas->SaveCanvas();
11993             unwrapCanvas->ClipCanvas(context.width, context.height);
11994         }
11995         JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
11996         contextObj->SetPropertyObject("canvas", jsCanvasVal);
11997 
11998         auto jsVal = JSRef<JSVal>::Cast(contextObj);
11999         panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
12000         JSValueWrapper valueWrapper = value;
12001         napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
12002 
12003         napi_wrap(
12004             env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
12005 
12006         JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
12007         if (unwrapCanvas) {
12008             unwrapCanvas->RestoreCanvas();
12009             unwrapCanvas->ResetCanvas();
12010         }
12011     };
12012     return drawCallback;
12013 }
12014 
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)12015 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
12016 {
12017     auto* vm = info.GetVm();
12018     return [vm, nodeId](const std::string& key) -> std::string {
12019         std::string resultString = std::string();
12020         CHECK_NULL_RETURN(vm, resultString);
12021         panda::LocalScope scope(vm);
12022         auto global = JSNApi::GetGlobalObject(vm);
12023         auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
12024         if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
12025             return resultString;
12026         }
12027         auto obj = getCustomProperty->ToObject(vm);
12028         panda::Local<panda::FunctionRef> func = obj;
12029         panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
12030             panda::StringRef::NewFromUtf8(vm, key.c_str()) };
12031         auto function = panda::CopyableGlobal(vm, func);
12032         auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
12033         if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
12034             return resultString;
12035         }
12036         auto value = callValue->ToString(vm)->ToString(vm);
12037         return value;
12038     };
12039 }
12040 
JsGetCustomMapFunc(const JSCallbackInfo & info,int32_t nodeId)12041 std::function<std::string()> JsGetCustomMapFunc(const JSCallbackInfo& info, int32_t nodeId)
12042 {
12043     auto* vm = info.GetVm();
12044     return [vm, nodeId]() -> std::string {
12045         std::string resultString = std::string();
12046         CHECK_NULL_RETURN(vm, resultString);
12047         panda::LocalScope scope(vm);
12048         auto global = JSNApi::GetGlobalObject(vm);
12049         auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyMapString__"));
12050         if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
12051             return resultString;
12052         }
12053         auto obj = getCustomProperty->ToObject(vm);
12054         panda::Local<panda::FunctionRef> func = obj;
12055         panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
12056         auto function = panda::CopyableGlobal(vm, func);
12057         auto callValue = function->Call(vm, function.ToLocal(), params, 1);
12058         if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
12059             return resultString;
12060         }
12061         auto value = callValue->ToString(vm)->ToString(vm);
12062         return value;
12063     };
12064 }
12065 
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)12066 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
12067 {
12068     auto* vm = info.GetVm();
12069     panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
12070         info[1]->GetLocalHandle() };
12071     return [vm, params3]() -> bool {
12072         CHECK_NULL_RETURN(vm, false);
12073         panda::LocalScope scope(vm);
12074         auto global = JSNApi::GetGlobalObject(vm);
12075         auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
12076         if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
12077             return false;
12078         }
12079         auto obj = setCustomProperty->ToObject(vm);
12080         panda::Local<panda::FunctionRef> func = obj;
12081         auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
12082         auto nodeId = frameNode->GetId();
12083         auto function = panda::CopyableGlobal(vm, func);
12084         auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
12085         if (customPropertyExisted) {
12086             frameNode->SetCustomPropertyMapFlagByKey(params3[1]->ToString(vm)->ToString(vm));
12087             frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
12088                 CHECK_NULL_VOID(vm);
12089                 panda::LocalScope scope(vm);
12090                 auto global = JSNApi::GetGlobalObject(vm);
12091                 auto removeCustomProperty =
12092                     global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
12093                 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
12094                     return;
12095                 }
12096                 auto obj = removeCustomProperty->ToObject(vm);
12097                 panda::Local<panda::FunctionRef> func = obj;
12098                 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
12099                 auto function = panda::CopyableGlobal(vm, func);
12100                 function->Call(vm, function.ToLocal(), params, 1);
12101             });
12102         }
12103         return true;
12104     };
12105 }
12106 
JsCustomProperty(const JSCallbackInfo & info)12107 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
12108 {
12109     if (info[0]->GetLocalHandle()->IsUndefined()) {
12110         return;
12111     }
12112     auto* vm = info.GetVm();
12113     CHECK_NULL_VOID(vm);
12114     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
12115     auto nodeId = frameNode->GetId();
12116     auto getFunc = ParseJsGetFunc(info, nodeId);
12117     auto func = ParseJsFunc(info, nodeId);
12118     auto getMapFunc = JsGetCustomMapFunc(info, nodeId);
12119     frameNode->SetJSCustomProperty(func, getFunc, std::move(getMapFunc));
12120 }
12121 
JsLinearGradient(const JSCallbackInfo & info)12122 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
12123 {
12124     ViewAbstractModel::GetInstance()->RemoveResObj("LinearGradient.gradient");
12125     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
12126     auto jsVal = info[0];
12127     if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
12128         NG::Gradient newGradient;
12129         newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
12130         ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
12131         return;
12132     }
12133     NG::Gradient newGradient;
12134     NewJsLinearGradient(info, newGradient);
12135     ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
12136 }
12137 
JsGestureModifier(const JSCallbackInfo & info)12138 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
12139 {
12140     auto* vm = info.GetExecutionContext().vm_;
12141     CHECK_NULL_VOID(vm);
12142     auto global = JSNApi::GetGlobalObject(vm);
12143     auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
12144     if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
12145         return;
12146     }
12147     auto obj = gestureModifier->ToObject(vm);
12148     panda::Local<panda::FunctionRef> func = obj;
12149     auto thisObj = info.This()->GetLocalHandle();
12150     panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
12151     func->Call(vm, thisObj, params, 1);
12152 }
12153 
SetBackgroundImageResizableUpdateFunc(ImageResizableSlice & sliceResult,const RefPtr<ResourceObject> & resObj,std::string direction)12154 void SetBackgroundImageResizableUpdateFunc(
12155     ImageResizableSlice& sliceResult, const RefPtr<ResourceObject>& resObj, std::string direction)
12156 {
12157     if (direction.empty()) {
12158         return;
12159     }
12160     if (!resObj) {
12161         sliceResult.RemoveResource("backgroundImageResizable");
12162         return;
12163     }
12164     auto&& updateFunc = [direction](const RefPtr<ResourceObject>& resObj, ImageResizableSlice& sliceResult) {
12165         CHECK_NULL_VOID(resObj);
12166         CalcDimension sliceDimension;
12167         ResourceParseUtils::ParseResDimensionVp(resObj, sliceDimension);
12168         if (direction == "Left") {
12169             sliceResult.left = sliceDimension;
12170         } else if (direction == "Right") {
12171             sliceResult.right = sliceDimension;
12172         } else if (direction == "Top") {
12173             sliceResult.top = sliceDimension;
12174         } else if (direction == "Bottom") {
12175             sliceResult.bottom = sliceDimension;
12176         }
12177     };
12178     sliceResult.AddResource("backgroundImageResizable" + direction, resObj, std::move(updateFunc));
12179 }
12180 
JsBackgroundImageResizable(const JSCallbackInfo & info)12181 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
12182 {
12183     auto infoObj = info[0];
12184     ImageResizableSlice sliceResult;
12185     if (!infoObj->IsObject()) {
12186         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12187         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageResizableSlice");
12188         return;
12189     }
12190     JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
12191     if (resizableObject->IsEmpty()) {
12192         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12193         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageResizableSlice");
12194         return;
12195     }
12196     auto sliceValue = resizableObject->GetProperty("slice");
12197     if (!sliceValue->IsObject()) {
12198         return;
12199     }
12200     JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
12201     if (sliceObj->IsEmpty()) {
12202         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12203         ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageResizableSlice");
12204         return;
12205     }
12206     for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
12207         auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
12208         CalcDimension sliceDimension;
12209         RefPtr<ResourceObject> resObj;
12210         if (!ParseJsDimensionVp(sliceSize, sliceDimension, resObj)) {
12211             continue;
12212         }
12213         if (!sliceDimension.IsValid()) {
12214             continue;
12215         }
12216         switch (static_cast<BorderImageDirection>(i)) {
12217             case BorderImageDirection::LEFT:
12218                 sliceResult.left = sliceDimension;
12219                 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Left");
12220                 break;
12221             case BorderImageDirection::RIGHT:
12222                 sliceResult.right = sliceDimension;
12223                 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Right");
12224                 break;
12225             case BorderImageDirection::TOP:
12226                 sliceResult.top = sliceDimension;
12227                 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Top");
12228                 break;
12229             case BorderImageDirection::BOTTOM:
12230                 sliceResult.bottom = sliceDimension;
12231                 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Bottom");
12232                 break;
12233             default:
12234                 break;
12235         }
12236     }
12237     ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12238 }
12239 
JsOnFocus(const JSCallbackInfo & args)12240 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
12241 {
12242     JSRef<JSVal> arg = args[0];
12243     if (arg->IsUndefined() && IsDisableEventVersion()) {
12244         ViewAbstractModel::GetInstance()->DisableOnFocus();
12245         return;
12246     }
12247     if (!arg->IsFunction()) {
12248         return;
12249     }
12250     RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
12251     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12252     auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
12253         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12254         ACE_SCORING_EVENT("onFocus");
12255         PipelineContext::SetCallBackNode(node);
12256         func->Execute();
12257     };
12258 
12259     ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
12260 }
12261 
JsOnBlur(const JSCallbackInfo & args)12262 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
12263 {
12264     JSRef<JSVal> arg = args[0];
12265     if (arg->IsUndefined() && IsDisableEventVersion()) {
12266         ViewAbstractModel::GetInstance()->DisableOnBlur();
12267         return;
12268     }
12269     if (!arg->IsFunction()) {
12270         return;
12271     }
12272     RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
12273     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12274     auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
12275         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12276         ACE_SCORING_EVENT("onBlur");
12277         PipelineContext::SetCallBackNode(node);
12278         func->Execute();
12279     };
12280 
12281     ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
12282 }
12283 
JsTabIndex(const JSCallbackInfo & info)12284 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
12285 {
12286     JSRef<JSVal> arg = info[0];
12287     if (!arg->IsNumber()) {
12288         return;
12289     }
12290     ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
12291 }
12292 
JsFocusOnTouch(const JSCallbackInfo & info)12293 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
12294 {
12295     JSRef<JSVal> arg = info[0];
12296     if (!arg->IsBoolean()) {
12297         return;
12298     }
12299     auto isFocusOnTouch = arg->ToBoolean();
12300     ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
12301 }
12302 
JsDefaultFocus(const JSCallbackInfo & info)12303 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
12304 {
12305     JSRef<JSVal> arg = info[0];
12306     if (!arg->IsBoolean()) {
12307         return;
12308     }
12309     auto isDefaultFocus = arg->ToBoolean();
12310     ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
12311 }
12312 
JsGroupDefaultFocus(const JSCallbackInfo & info)12313 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
12314 {
12315     JSRef<JSVal> arg = info[0];
12316     if (!arg->IsBoolean()) {
12317         return;
12318     }
12319     auto isGroupDefaultFocus = arg->ToBoolean();
12320     ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
12321 }
12322 
JsKey(const std::string & key)12323 void JSViewAbstract::JsKey(const std::string& key)
12324 {
12325     ViewAbstractModel::GetInstance()->SetInspectorId(key);
12326 }
12327 
JsId(const JSCallbackInfo & info)12328 void JSViewAbstract::JsId(const JSCallbackInfo& info)
12329 {
12330     JSRef<JSVal> arg = info[0];
12331     if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
12332         return;
12333     }
12334     std::string id = arg->ToString();
12335     if (id.empty()) {
12336         return;
12337     }
12338     JsKey(id);
12339 }
12340 
JsRestoreId(int32_t restoreId)12341 void JSViewAbstract::JsRestoreId(int32_t restoreId)
12342 {
12343     ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
12344 }
12345 
JsDebugLine(const JSCallbackInfo & info)12346 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
12347 {
12348     std::string debugLine;
12349     auto length = info.Length();
12350     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
12351 
12352     if (length == 1) { // deprecated version of debug line
12353         auto jsVal = info[0];
12354         if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
12355             return;
12356         }
12357         debugLine = jsVal->ToString();
12358     } else if (length == 2) { // debug line with extra package name
12359         auto line = info[0];
12360         auto packageName = info[1];
12361         if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
12362             !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
12363             return;
12364         }
12365         auto json = JsonUtil::Create(true);
12366         json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
12367         json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
12368         debugLine = json->ToString();
12369     }
12370 
12371     ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
12372 }
12373 
JsOpacityPassThrough(const JSCallbackInfo & info)12374 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
12375 {
12376     double opacity = 1.0;
12377     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
12378         if (ParseJsDouble(info[0], opacity)) {
12379             opacity = std::clamp(opacity, 0.0, 1.0);
12380         }
12381     } else {
12382         if (!ParseJsDouble(info[0], opacity)) {
12383             return;
12384         }
12385         if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
12386             opacity = 1.0;
12387         }
12388     }
12389 
12390     ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
12391 }
12392 
JsTransitionPassThrough(const JSCallbackInfo & info)12393 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
12394 {
12395     if (info.Length() == 0) {
12396         ViewAbstractModel::GetInstance()->SetTransition(
12397             NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
12398         return;
12399     }
12400     if (!info[0]->IsObject()) {
12401         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
12402             ViewAbstractModel::GetInstance()->CleanTransition();
12403             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
12404         }
12405         return;
12406     }
12407     auto obj = JSRef<JSObject>::Cast(info[0]);
12408     if (!obj->GetProperty("successor_")->IsUndefined()) {
12409         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
12410         std::function<void(bool)> finishCallback;
12411         if (info.Length() > 1 && info[1]->IsFunction()) {
12412             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
12413         }
12414         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
12415         return;
12416     }
12417     auto options = ParseJsTransition(obj);
12418     ViewAbstractModel::GetInstance()->SetTransition(options, true);
12419 }
12420 
JsFocusScopeId(const JSCallbackInfo & info)12421 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
12422 {
12423     if (info.Length() == 0) {
12424         return;
12425     }
12426 
12427     std::string focusScopeId;
12428     if (info[0]->IsString()) {
12429         focusScopeId = info[0]->ToString();
12430     }
12431 
12432     bool isGroup = false;
12433     if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
12434         info[1]->IsBoolean()) {
12435         isGroup = info[1]->ToBoolean();
12436     }
12437     bool arrowKeyStepOut = true;
12438     if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() && // 2:args index.
12439         info[2]->IsBoolean()) { // 2:args index.
12440         arrowKeyStepOut = info[2]->ToBoolean(); // 2:args index.
12441     }
12442     ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
12443 }
12444 
JsFocusScopePriority(const JSCallbackInfo & info)12445 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
12446 {
12447     if (info.Length() == 0) {
12448         return;
12449     }
12450 
12451     if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
12452         return;
12453     }
12454     std::string focusScopeId = info[0]->ToString();
12455 
12456     int32_t focusPriority = 0;
12457     if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
12458         info[1]->IsNumber()) {
12459         focusPriority = info[1]->ToNumber<int32_t>();
12460     }
12461     ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
12462 }
12463 
JsBackground(const JSCallbackInfo & info)12464 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
12465 {
12466     if (info.Length() <= 0) {
12467         return;
12468     }
12469 
12470     // parse custom background
12471     Color color = Color::TRANSPARENT;
12472     RefPtr<ResourceObject> backgroundColorResObj;
12473     std::function<void()> builderFunc;
12474     BackgroundType backgroundType = BackgroundType::COLOR;
12475     if (!ParseJsColor(info[0], color, backgroundColorResObj)) {
12476         ViewAbstractModel::GetInstance()->ClearResObj("customBackgroundColor");
12477         if (ParseBackgroundBuilder(info, info[0], builderFunc)) {
12478             backgroundType = BackgroundType::CUSTOM_BUILDER;
12479         } else {
12480             return;
12481         }
12482     }
12483 
12484     // parse background options
12485     Alignment alignment = Alignment::CENTER;
12486     NG::LayoutSafeAreaEdge ignoreLayoutSafeAreaEdges =
12487         (BackgroundType::COLOR == backgroundType) ? NG::LAYOUT_SAFE_AREA_EDGE_ALL : NG::LAYOUT_SAFE_AREA_EDGE_NONE;
12488     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
12489         JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
12490         if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::ALIGN))) {
12491             auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
12492             auto value = align->ToNumber<int32_t>();
12493             alignment = ParseAlignment(value);
12494         }
12495         if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::IGNORES_LAYOUT_SAFE_AREA_EDGES))) {
12496             auto safeAreaEdgesArray =
12497                 object->GetProperty(static_cast<int32_t>(ArkUIIndex::IGNORES_LAYOUT_SAFE_AREA_EDGES));
12498             ignoreLayoutSafeAreaEdges = ParseJsLayoutSafeAreaEdgeArray(safeAreaEdgesArray, ignoreLayoutSafeAreaEdges);
12499         }
12500     }
12501 
12502     // parameters parsed, set the properties parsed above
12503     if (BackgroundType::CUSTOM_BUILDER == backgroundType &&
12504         NG::LAYOUT_SAFE_AREA_EDGE_NONE == ignoreLayoutSafeAreaEdges) {
12505         ViewAbstractModel::GetInstance()->SetIsTransitionBackground(false);
12506     } else {
12507         ViewAbstractModel::GetInstance()->SetIsTransitionBackground(true);
12508     }
12509 
12510     ViewAbstractModel::GetInstance()->SetIsBuilderBackground(BackgroundType::CUSTOM_BUILDER == backgroundType);
12511     ViewAbstractModel::GetInstance()->SetBackground(std::move(builderFunc));
12512     ViewAbstractModel::GetInstance()->SetBackgroundIgnoresLayoutSafeAreaEdges(ignoreLayoutSafeAreaEdges);
12513     ViewAbstractModel::GetInstance()->SetBackgroundAlign(alignment);
12514     if (SystemProperties::ConfigChangePerform()) {
12515         ViewAbstractModel::GetInstance()->SetCustomBackgroundColorWithResourceObj(color, backgroundColorResObj);
12516     } else {
12517         ViewAbstractModel::GetInstance()->SetCustomBackgroundColor(color);
12518     }
12519 }
12520 
ParseBackgroundBuilder(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,std::function<void ()> & builderFunc)12521 bool JSViewAbstract::ParseBackgroundBuilder(
12522     const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, std::function<void()>& builderFunc)
12523 {
12524     if (!jsFunc->IsObject()) {
12525         return false;
12526     }
12527 
12528     JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(jsFunc);
12529     auto contentObj = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
12530     if (!contentObj->IsFunction()) {
12531         return false;
12532     }
12533     auto jsBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(contentObj));
12534     CHECK_NULL_RETURN(jsBuilderFunc, false);
12535     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12536     builderFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsBuilderFunc), node = frameNode]() {
12537         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12538         ACE_SCORING_EVENT("BindBackground");
12539         PipelineContext::SetCallBackNode(node);
12540         func->Execute();
12541     };
12542 
12543     return true;
12544 }
12545 
ParseJsLayoutSafeAreaEdgeArray(const JSRef<JSArray> & jsSafeAreaEdges,NG::LayoutSafeAreaEdge defaultVal)12546 NG::LayoutSafeAreaEdge JSViewAbstract::ParseJsLayoutSafeAreaEdgeArray(
12547     const JSRef<JSArray>& jsSafeAreaEdges, NG::LayoutSafeAreaEdge defaultVal)
12548 {
12549     if (!jsSafeAreaEdges->IsArray()) {
12550         return defaultVal;
12551     }
12552 
12553     static std::vector<uint32_t> layoutEdgeEnum {
12554         NG::LAYOUT_SAFE_AREA_EDGE_TOP,
12555         NG::LAYOUT_SAFE_AREA_EDGE_BOTTOM,
12556         NG::LAYOUT_SAFE_AREA_EDGE_START,
12557         NG::LAYOUT_SAFE_AREA_EDGE_END,
12558         NG::LAYOUT_SAFE_AREA_EDGE_VERTICAL,
12559         NG::LAYOUT_SAFE_AREA_EDGE_HORIZONTAL,
12560         NG::LAYOUT_SAFE_AREA_EDGE_ALL
12561     };
12562 
12563     NG::LayoutSafeAreaEdge edges = NG::LAYOUT_SAFE_AREA_EDGE_NONE;
12564     for (size_t i = 0; i < jsSafeAreaEdges->Length(); ++i) {
12565         if (!jsSafeAreaEdges->GetValueAt(i)->IsNumber() ||
12566             jsSafeAreaEdges->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_EDGE_LIMIT) {
12567             return defaultVal;
12568         }
12569         edges |= layoutEdgeEnum[jsSafeAreaEdges->GetValueAt(i)->ToNumber<uint32_t>()];
12570     }
12571 
12572     return edges;
12573 }
12574 
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)12575 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
12576     std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
12577 {
12578     auto vm = info.GetVm();
12579     auto globalObj = JSNApi::GetGlobalObject(vm);
12580     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
12581     JsiValue jsiValue(globalFunc);
12582     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
12583     if (globalFuncRef->IsFunction()) {
12584         RefPtr<JsFunction> jsFunc =
12585             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
12586         if (!modifierObj->IsObject()) {
12587             symbolApply = nullptr;
12588         } else {
12589             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
12590                                modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
12591                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12592                 auto node = frameNode.Upgrade();
12593                 CHECK_NULL_VOID(node);
12594                 JSRef<JSVal> params[2];
12595                 params[0] = modifierParam;
12596                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
12597                 PipelineContext::SetCallBackNode(node);
12598                 func->ExecuteJS(2, params);
12599             };
12600             symbolApply = onApply;
12601         }
12602     }
12603 }
12604 
ParseJsPropertyId(const JSRef<JSVal> & jsValue)12605 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
12606 {
12607     int32_t resId = 0;
12608     if (jsValue->IsObject()) {
12609         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
12610         JSRef<JSVal> tmp = jsObj->GetProperty("id");
12611         if (!tmp->IsNull() && tmp->IsNumber()) {
12612             resId = tmp->ToNumber<int32_t>();
12613         }
12614     }
12615     return resId;
12616 }
12617 
JsVisualEffect(const JSCallbackInfo & info)12618 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
12619 {
12620     if (!info[0]->IsObject()) {
12621         return;
12622     }
12623     auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
12624     ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
12625 }
12626 
JsBackgroundFilter(const JSCallbackInfo & info)12627 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
12628 {
12629     if (!info[0]->IsObject()) {
12630         return;
12631     }
12632     auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
12633     ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
12634 }
12635 
JsForegroundFilter(const JSCallbackInfo & info)12636 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
12637 {
12638     if (!info[0]->IsObject()) {
12639         return;
12640     }
12641     auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
12642     ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
12643 }
12644 
JsCompositingFilter(const JSCallbackInfo & info)12645 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
12646 {
12647     if (!info[0]->IsObject()) {
12648         return;
12649     }
12650     auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
12651     ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
12652 }
12653 
ParseMenuItemsSymbolId(const JSRef<JSVal> & jsStartIcon,NG::MenuOptionsParam menuOptionsParam)12654 void JSViewAbstract::ParseMenuItemsSymbolId(const JSRef<JSVal>& jsStartIcon, NG::MenuOptionsParam menuOptionsParam)
12655 {
12656      if (StringToMenuItemType(menuOptionsParam.id) == MenuItemType::UNKNOWN) {
12657         uint32_t symbolId = 0;
12658         RefPtr<ResourceObject> resourceObject;
12659         if (ParseJsSymbolId(jsStartIcon, symbolId, resourceObject)) {
12660             menuOptionsParam.symbolId = symbolId;
12661         }
12662     } else {
12663         UpdateInfoById(menuOptionsParam, menuOptionsParam.id);
12664     }
12665 }
12666 
ParseMenuItems(const JSRef<JSArray> & menuItemsArray,bool showShortcut)12667 std::vector<NG::MenuOptionsParam> JSViewAbstract::ParseMenuItems(const JSRef<JSArray>& menuItemsArray, bool showShortcut)
12668 {
12669     std::vector<NG::MenuOptionsParam> menuParams;
12670     for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
12671         auto menuItem = menuItemsArray->GetValueAt(i);
12672         if (!menuItem->IsObject()) {
12673             continue;
12674         }
12675         auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
12676         NG::MenuOptionsParam menuOptionsParam;
12677         auto jsContent = menuItemObject->GetProperty("content");
12678         std::string content;
12679         ParseJsString(jsContent, content);
12680         menuOptionsParam.content = content;
12681         auto jsTextMenuId = menuItemObject->GetProperty("id");
12682         std::string id;
12683         if (jsTextMenuId->IsObject()) {
12684             auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
12685             auto jsId = textMenuIdObject->GetProperty("id_");
12686             ParseJsString(jsId, id);
12687         }
12688         menuOptionsParam.id = id;
12689         auto jsLabelInfo = menuItemObject->GetProperty("labelInfo");
12690         std::string labelInfo;
12691         ParseJsString(jsLabelInfo, labelInfo);
12692         if (jsLabelInfo->IsString() || jsLabelInfo->IsObject()) {
12693             menuOptionsParam.labelInfo = labelInfo;
12694         }
12695         auto jsStartIcon = menuItemObject->GetProperty("icon");
12696         std::string icon;
12697         ParseJsMedia(jsStartIcon, icon);
12698         menuOptionsParam.icon = icon;
12699         ParseMenuItemsSymbolId(jsStartIcon, menuOptionsParam);
12700         menuParams.emplace_back(menuOptionsParam);
12701     }
12702     return menuParams;
12703 }
12704 
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)12705 void JSViewAbstract::ParseOnCreateMenu(
12706     const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
12707 {
12708     if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
12709         return;
12710     }
12711     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12712     auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
12713         JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
12714     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
12715                           instanceId = Container::CurrentId(), node = frameNode](
12716                           const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
12717         ContainerScope scope(instanceId);
12718         std::vector<NG::MenuOptionsParam> menuParams;
12719         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
12720         auto pipelineContext = PipelineContext::GetCurrentContext();
12721         CHECK_NULL_RETURN(pipelineContext, menuParams);
12722         pipelineContext->UpdateCurrentActiveNode(node);
12723         auto textOverlayTheme = pipelineContext->GetTheme<TextOverlayTheme>();
12724         CHECK_NULL_RETURN(textOverlayTheme, menuParams);
12725         bool showShortcut = textOverlayTheme->GetShowShortcut();
12726         auto modifiedSystemMenuItems = systemMenuItems;
12727         UpdateOptionsInfo(modifiedSystemMenuItems);
12728         auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
12729         if (!menuItem->IsArray()) {
12730             return menuParams;
12731         }
12732         auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
12733         menuParams = ParseMenuItems(menuItemsArray, showShortcut);
12734         return menuParams;
12735     };
12736     onCreateMenuCallback = jsCallback;
12737 }
12738 
ParseOnPrepareMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnPrepareMenuCallback & onPrepareMenuCallback)12739 void JSViewAbstract::ParseOnPrepareMenu(
12740     const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnPrepareMenuCallback& onPrepareMenuCallback)
12741 {
12742     if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
12743         return;
12744     }
12745     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12746     auto jsOnPrepareMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
12747         JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
12748     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnPrepareMenu),
12749                           instanceId = Container::CurrentId(), node = frameNode](
12750                           const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
12751         ContainerScope scope(instanceId);
12752         std::vector<NG::MenuOptionsParam> menuParams;
12753         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
12754         auto pipelineContext = PipelineContext::GetCurrentContext();
12755         CHECK_NULL_RETURN(pipelineContext, menuParams);
12756         auto textOverlayTheme = pipelineContext->GetTheme<TextOverlayTheme>();
12757         CHECK_NULL_RETURN(textOverlayTheme, menuParams);
12758         bool showShortcut = textOverlayTheme->GetShowShortcut();
12759 
12760         pipelineContext->UpdateCurrentActiveNode(node);
12761         auto modifiedSystemMenuItems = systemMenuItems;
12762         UpdateOptionsInfo(modifiedSystemMenuItems);
12763         auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
12764         if (!menuItem->IsArray()) {
12765             return menuParams;
12766         }
12767         auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
12768         menuParams = ParseMenuItems(menuItemsArray, showShortcut);
12769         return menuParams;
12770     };
12771     onPrepareMenuCallback = jsCallback;
12772 }
12773 
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)12774 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
12775 {
12776     JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
12777     uint32_t idx = 0;
12778     for (const auto& item : systemMenuItems) {
12779         systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
12780     }
12781     return systemMenuItemsArray;
12782 }
12783 
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick,NG::OnPrepareMenuCallback & onPrepareMenuCallback)12784 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
12785     NG::OnMenuItemClickCallback& onMenuItemClick, NG::OnPrepareMenuCallback& onPrepareMenuCallback)
12786 {
12787     auto tmpInfo = info[0];
12788     if (info.Length() != 1 || !tmpInfo->IsObject()) {
12789         return false;
12790     }
12791     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12792     auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
12793     auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
12794     ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
12795     auto jsValueOnPrepareMenu = menuOptionsObject->GetProperty("onPrepareMenu");
12796     ParseOnPrepareMenu(info, jsValueOnPrepareMenu, onPrepareMenuCallback);
12797 
12798     auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
12799     if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
12800         return false;
12801     }
12802     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
12803     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
12804                           onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
12805                           node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
12806         ContainerScope scope(instanceId);
12807         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
12808         auto pipelineContext = PipelineContext::GetCurrentContext();
12809         CHECK_NULL_RETURN(pipelineContext, false);
12810         pipelineContext->UpdateCurrentActiveNode(node);
12811         auto paramArray = onMenuItemCallback(menuOptionsParam);
12812         if (paramArray->Length() != 2) {
12813             return false;
12814         }
12815         JSRef<JSVal> params[2];
12816         params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
12817         params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
12818         auto ret = func->ExecuteJS(2, params);
12819         if (ret->IsBoolean()) {
12820             return ret->ToBoolean();
12821         }
12822         return false;
12823     };
12824     onMenuItemClick = jsCallback;
12825     return true;
12826 }
12827 
CreateJsTextMenuId(const std::string & id)12828 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
12829 {
12830     JSRef<JSObject> empty;
12831     auto engine = EngineHelper::GetCurrentEngine();
12832     CHECK_NULL_RETURN(engine, empty);
12833     NativeEngine* nativeEngine = engine->GetNativeEngine();
12834     CHECK_NULL_RETURN(nativeEngine, empty);
12835     auto env = reinterpret_cast<napi_env>(nativeEngine);
12836 
12837     napi_value global;
12838     napi_status ret = napi_get_global(env, &global);
12839     if (ret != napi_ok) {
12840         return empty;
12841     }
12842     napi_value constructor;
12843     ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
12844     if (ret != napi_ok) {
12845         return empty;
12846     }
12847 
12848     napi_value obj;
12849     napi_value menuId = nullptr;
12850 
12851     ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
12852     if (ret != napi_ok) {
12853         return empty;
12854     }
12855     ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
12856     if (ret != napi_ok) {
12857         return empty;
12858     }
12859 
12860     JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
12861     if (!value->IsObject()) {
12862         return empty;
12863     }
12864 
12865     return JSRef<JSObject>::Cast(value);
12866 }
12867 
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)12868 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
12869 {
12870     JSRef<JSArray> params = JSRef<JSArray>::New();
12871     params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
12872     params->SetValueAt(1, CreateJsTextRange(menuItemParam));
12873     return params;
12874 }
12875 
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)12876 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
12877 {
12878     JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
12879     TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
12880     JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
12881     TextMenuItem->SetPropertyObject("id", obj);
12882     TextMenuItem->SetProperty<std::string>("labelInfo", menuItemParam.menuOptionsParam.labelInfo.value_or(""));
12883     if (menuItemParam.menuOptionsParam.symbolId.has_value() && menuItemParam.menuOptionsParam.symbolId.value() != 0) {
12884         TextMenuItem->SetProperty<uint32_t>("icon", menuItemParam.menuOptionsParam.symbolId.value());
12885     } else {
12886         TextMenuItem->SetProperty<std::string>("icon", menuItemParam.menuOptionsParam.icon.value_or(""));
12887     }
12888     return JSRef<JSVal>::Cast(TextMenuItem);
12889 }
12890 
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)12891 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
12892 {
12893     JSRef<JSObject> textRange = JSRef<JSObject>::New();
12894     textRange->SetProperty<int32_t>("start", menuItemParam.start);
12895     textRange->SetProperty<int32_t>("end", menuItemParam.end);
12896     return JSRef<JSVal>::Cast(textRange);
12897 }
12898 
OHOS_ACE_ParseJsMedia(void * value,void * resource)12899 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
12900 {
12901     napi_value napiValue = reinterpret_cast<napi_value>(value);
12902     ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
12903     if (!napiValue || !res) {
12904         return;
12905     }
12906     JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
12907     std::string src;
12908     std::string bundleName;
12909     std::string moduleName;
12910     JSViewAbstract::ParseJsMedia(jsVal, src);
12911     JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
12912     res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
12913     res->src = src;
12914     res->bundleName = bundleName;
12915     res->moduleName = moduleName;
12916 }
12917 
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)12918 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
12919     std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
12920 {
12921     if (!modifierObj->IsObject()) {
12922         textStyleApply = nullptr;
12923         return;
12924     }
12925     auto vm = info.GetVm();
12926     auto globalObj = JSNApi::GetGlobalObject(vm);
12927     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
12928     JsiValue jsiValue(globalFunc);
12929     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
12930     if (!globalFuncRef->IsFunction()) {
12931         textStyleApply = nullptr;
12932         return;
12933     }
12934     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
12935     auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
12936                     modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
12937         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12938         auto node = frameNode.Upgrade();
12939         CHECK_NULL_VOID(node);
12940         JSRef<JSVal> params[2];
12941         params[0] = modifierParam;
12942         params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
12943         PipelineContext::SetCallBackNode(node);
12944         func->ExecuteJS(2, params);
12945     };
12946     textStyleApply = onApply;
12947 }
12948 
SetPixelRoundMode(const JSCallbackInfo & info)12949 void JSViewAbstract::SetPixelRoundMode(const JSCallbackInfo& info)
12950 {
12951     if (info.Length() < 1) {
12952         return;
12953     }
12954     if (!info[0]->IsNumber()) {
12955         return;
12956     }
12957     auto index = info[0]->ToNumber<uint8_t>();
12958     auto size = sizeof(PixelRoundMode) / sizeof(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
12959     if (index < 0 || index > size) {
12960         return;
12961     }
12962     PixelRoundMode pixelRoundMode = static_cast<PixelRoundMode>(index);
12963     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
12964     CHECK_NULL_VOID(pipeline);
12965     pipeline->SetPixelRoundMode(pixelRoundMode);
12966 }
12967 
GetPixelRoundMode()12968 uint8_t JSViewAbstract::GetPixelRoundMode()
12969 {
12970     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
12971     return pipeline ? static_cast<uint8_t>(pipeline->GetPixelRoundMode())
12972                     : static_cast<uint8_t>(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
12973 }
12974 
UnRegisterResource(const std::string & key)12975 void JSViewAbstract::UnRegisterResource(const std::string& key)
12976 {
12977     auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
12978     CHECK_NULL_VOID(frameNode);
12979     auto pattern = frameNode->GetPattern();
12980     CHECK_NULL_VOID(pattern);
12981     pattern->UnRegisterResource(key);
12982 }
12983 
ParseDragSpringLoadingConfiguration(const JSRef<JSObject> & paramObj,const RefPtr<NG::DragSpringLoadingConfiguration> & config)12984 void JSViewAbstract::ParseDragSpringLoadingConfiguration(
12985     const JSRef<JSObject>& paramObj, const RefPtr<NG::DragSpringLoadingConfiguration>& config)
12986 {
12987     JSRef<JSObject> configuration = paramObj;
12988     auto setConfigurationPropertyIfValid =
12989         [&configuration, &config](const char* propName,
12990             std::function<void(const RefPtr<NG::DragSpringLoadingConfiguration>&, int32_t)> setter) {
12991             CHECK_NULL_VOID(propName);
12992             CHECK_NULL_VOID(config);
12993             CHECK_NULL_VOID(setter);
12994             auto propObj = configuration->GetProperty(propName);
12995             if (propObj->IsNumber()) {
12996                 auto value = propObj->ToNumber<double>();
12997                 if (!std::isnan(value) && value <= INT32_MAX && value >= 0) {
12998                     setter(config, static_cast<int32_t>(value));
12999                 }
13000             }
13001         };
13002     setConfigurationPropertyIfValid("stillTimeLimit", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config,
13003                                                           int32_t value) { config->stillTimeLimit = value; });
13004     setConfigurationPropertyIfValid("updateInterval", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config,
13005                                                           int32_t value) { config->updateInterval = value; });
13006     setConfigurationPropertyIfValid("updateNotifyCount", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config,
13007                                                              int32_t value) { config->updateNotifyCount = value; });
13008     setConfigurationPropertyIfValid(
13009         "updateToFinishInterval", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config, int32_t value) {
13010             config->updateToFinishInterval = value;
13011         });
13012 }
13013 
SetBorderRadiusWithCheck(std::optional<NG::BorderRadiusProperty> & result,NG::BorderRadiusProperty & borderRadius)13014 void JSViewAbstract::SetBorderRadiusWithCheck(std::optional<NG::BorderRadiusProperty>& result,
13015     NG::BorderRadiusProperty& borderRadius)
13016 {
13017     if (borderRadius.radiusTopLeft.has_value() && !borderRadius.radiusTopLeft->IsNegative() &&
13018         borderRadius.radiusTopRight.has_value() && !borderRadius.radiusTopRight->IsNegative() &&
13019         borderRadius.radiusBottomLeft.has_value() && !borderRadius.radiusBottomLeft->IsNegative() &&
13020         borderRadius.radiusBottomRight.has_value() && !borderRadius.radiusBottomRight->IsNegative()) {
13021         result = borderRadius;
13022     }
13023 }
13024 
CheckLengthMetrics(const JSRef<JSObject> & object)13025 bool JSViewAbstract::CheckLengthMetrics(const JSRef<JSObject>& object)
13026 {
13027     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
13028         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
13029         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
13030         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
13031         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
13032         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
13033         return true;
13034     }
13035     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
13036     if (jsTop->IsObject()) {
13037         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
13038         if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
13039             return true;
13040         }
13041     }
13042     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
13043     if (jsBottom->IsObject()) {
13044         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
13045         if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
13046             return true;
13047         }
13048     }
13049     return false;
13050 }
13051 
13052 } // namespace OHOS::Ace::Framework
13053