• 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 "bridge/common/utils/engine_helper.h"
42 #include "bridge/common/utils/utils.h"
43 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
44 #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h"
45 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_on_child_touch_test_function.h"
47 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
48 #include "bridge/declarative_frontend/engine/functions/js_function.h"
49 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
50 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
51 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
52 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
53 #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h"
54 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
55 #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h"
56 #include "bridge/declarative_frontend/engine/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/js_frontend/engine/jsi/ark_js_value.h"
61 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
62 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
63 #include "bridge/declarative_frontend/engine/js_converter.h"
64 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
65 #include "bridge/declarative_frontend/engine/js_types.h"
66 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
67 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
68 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
69 #include "bridge/declarative_frontend/jsview/js_utils.h"
70 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
71 #include "bridge/declarative_frontend/jsview/js_view_context.h"
72 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
73 #include "core/event/focus_axis_event.h"
74 #include "canvas_napi/js_canvas.h"
75 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
76 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
77 #endif
78 #include "core/common/resource/resource_manager.h"
79 #include "core/common/resource/resource_object.h"
80 #include "core/components/common/layout/constants.h"
81 #include "core/components/common/layout/position_param.h"
82 #include "core/components/common/layout/screen_system_manager.h"
83 #include "core/components/common/properties/animation_option.h"
84 #include "core/components/common/properties/border_image.h"
85 #include "core/components/common/properties/color.h"
86 #include "core/components/common/properties/decoration.h"
87 #include "core/components/common/properties/shadow.h"
88 #include "core/components/common/properties/invert.h"
89 #include "core/components/common/properties/shadow_config.h"
90 #include "core/components/text_overlay/text_overlay_theme.h"
91 #include "core/components/theme/resource_adapter.h"
92 #include "core/components/theme/shadow_theme.h"
93 #include "core/components_ng/base/view_abstract.h"
94 #include "core/components_ng/base/view_abstract_model.h"
95 #include "core/components_ng/base/view_stack_processor.h"
96 #include "core/components_ng/event/focus_box.h"
97 #include "core/components_ng/gestures/base_gesture_event.h"
98 #include "core/components_ng/pattern/menu/menu_pattern.h"
99 #include "core/components_ng/pattern/overlay/modal_style.h"
100 #include "core/components_ng/pattern/overlay/sheet_style.h"
101 #include "core/components_ng/property/grid_property.h"
102 #include "core/components_ng/property/safe_area_insets.h"
103 #include "core/gestures/gesture_info.h"
104 #include "core/image/image_source_info.h"
105 #ifdef PLUGIN_COMPONENT_SUPPORTED
106 #include "core/common/plugin_manager.h"
107 #endif
108 #include "interfaces/native/node/resource.h"
109 
110 #include "core/common/card_scope.h"
111 #include "core/common/container.h"
112 #include "core/common/resource/resource_configuration.h"
113 #include "core/components/progress/progress_theme.h"
114 #include "core/components_ng/base/view_abstract_model_ng.h"
115 #include "core/components_ng/base/view_stack_model.h"
116 #include "core/components_ng/property/progress_mask_property.h"
117 #include "core/components_ng/base/inspector.h"
118 #include "core/event/key_event.h"
119 
120 namespace OHOS::Ace {
121 namespace {
122 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
123 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
124 constexpr int32_t DIRECTION_COUNT = 4;
125 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
126 constexpr int NUM1 = 1;
127 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
128     HoverModeAreaType::BOTTOM_SCREEN };
129 } // namespace
130 
131 std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr;
132 std::mutex ViewAbstractModel::mutex_;
133 using DoubleBindCallback = std::function<void(const std::string&)>;
134 
GetInstance()135 ViewAbstractModel* ViewAbstractModel::GetInstance()
136 {
137     if (!instance_) {
138         std::lock_guard<std::mutex> lock(mutex_);
139         if (!instance_) {
140 #ifdef NG_BUILD
141             instance_.reset(new NG::ViewAbstractModelNG());
142 #else
143             if (Container::IsCurrentUseNewPipeline()) {
144                 instance_.reset(new NG::ViewAbstractModelNG());
145             } else {
146                 instance_.reset(new Framework::ViewAbstractModelImpl());
147             }
148 #endif
149         }
150     }
151     return instance_.get();
152 }
153 
154 } // namespace OHOS::Ace
155 
156 namespace OHOS::Ace::Framework {
157 namespace {
158 
159 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
160 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
161 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
162 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
163 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
164 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
165 constexpr int32_t MAX_ALIGN_VALUE = 8;
166 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
167 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
168 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
169 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
170 constexpr double FULL_DIMENSION = 100.0;
171 constexpr double HALF_DIMENSION = 50.0;
172 constexpr double ROUND_UNIT = 360.0;
173 constexpr double VISIBLE_RATIO_MIN = 0.0;
174 constexpr double VISIBLE_RATIO_MAX = 1.0;
175 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
176 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
177 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
178 constexpr int32_t SECOND_INDEX = 2;
179 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
180 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
181 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
182 constexpr float MAX_ANGLE = 360.0f;
183 constexpr float DEFAULT_BIAS = 0.5f;
184 constexpr float DEFAULT_LAYOUT_WEIGHT = 0.0f;
185 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
186 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
187 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
188 const std::string SHEET_HEIGHT_MEDIUM = "medium";
189 const std::string SHEET_HEIGHT_LARGE = "large";
190 const std::string SHEET_HEIGHT_AUTO = "auto";
191 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
192 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
193 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
194 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
195 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
196 const std::vector<int32_t> LENGTH_METRICS_KEYS {
197     static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
198     static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
199 const char* START_PROPERTY = "start";
200 const char* END_PROPERTY = "end";
201 const char* TOP_PROPERTY = "top";
202 const char* BOTTOM_PROPERTY = "bottom";
203 const char* LEFT_PROPERTY = "left";
204 const char* RIGHT_PROPERTY = "right";
205 const char* TOP_START_PROPERTY = "topStart";
206 const char* TOP_END_PROPERTY = "topEnd";
207 const char* BOTTOM_START_PROPERTY = "bottomStart";
208 const char* BOTTOM_END_PROPERTY = "bottomEnd";
209 const char* DEBUG_LINE_INFO_LINE = "$line";
210 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
211 
212 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
213 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
214 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
215 
216 enum class OperationType { COPY, PASTE, CUT, SELECT_ALL, UNKNOWN };
217 
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)218 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
219     CalcDimension& centerX, CalcDimension& centerY)
220 {
221     double xVal = 1.0;
222     double yVal = 1.0;
223     double zVal = 1.0;
224     if (!jsValue->IsObject()) {
225         scaleX = static_cast<float>(xVal);
226         scaleY = static_cast<float>(yVal);
227         scaleZ = static_cast<float>(zVal);
228         CalcDimension length;
229         centerX = length;
230         centerY = length;
231         return;
232     }
233     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
234     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
235     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
236     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
237     scaleX = static_cast<float>(xVal);
238     scaleY = static_cast<float>(yVal);
239     scaleZ = static_cast<float>(zVal);
240     // if specify centerX
241     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
242     // if specify centerY
243     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
244 }
245 
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)246 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
247     CalcDimension& translateZ)
248 {
249     if (!jsValue->IsObject()) {
250         return;
251     }
252     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
253     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
254     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
255     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
256 }
257 
GetDefaultRotateVector(double & dx,double & dy,double & dz)258 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
259 {
260     dx = 0.0;
261     dy = 0.0;
262     dz = 0.0;
263     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
264         dz = 1.0;
265     }
266 }
267 
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)268 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
269 {
270     if (!jsValue->IsObject()) {
271         return;
272     }
273     // default: dx, dy, dz (0.0, 0.0, 0.0)
274     double dxVal = 0.0;
275     double dyVal = 0.0;
276     double dzVal = 0.0;
277     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
278     auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
279     auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
280     auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
281     if (jsRotateX->IsUndefined()
282         && jsRotateY->IsUndefined()
283         && jsRotateZ->IsUndefined()) {
284         GetDefaultRotateVector(dxVal, dyVal, dzVal);
285     } else {
286         JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
287         JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
288         JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
289     }
290     rotate.xDirection = static_cast<float>(dxVal);
291     rotate.yDirection = static_cast<float>(dyVal);
292     rotate.zDirection = static_cast<float>(dzVal);
293     // if specify centerX
294     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
295         rotate.centerX)) {
296         rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
297     }
298     // if specify centerY
299     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
300         rotate.centerY)) {
301         rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
302     }
303     // if specify centerZ
304     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
305         rotate.centerZ)) {
306         rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
307     }
308     // if specify angle
309     JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
310     rotate.perspective = 0.0f;
311     JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
312 }
313 
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)314 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
315 {
316     if (!jsValue->IsObject()) {
317         return false;
318     }
319 
320     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
321     auto path = jsObj->GetPropertyValue<std::string>("path", "");
322     if (path.empty()) {
323         return false;
324     }
325     option.SetPath(path);
326     double from = 0.0;
327     double to = 1.0;
328     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
329     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
330     if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
331         from = 0.0;
332     }
333     if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
334         to = 1.0;
335     } else if (to < from) {
336         to = from;
337     }
338     option.SetBegin(static_cast<float>(from));
339     option.SetEnd(static_cast<float>(to));
340     option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
341     return true;
342 }
343 
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)344 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
345 {
346     if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::AUTO)) {
347         previewOption.ResetDragPreviewMode();
348         isAuto = true;
349         return;
350     } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE)) {
351         previewOption.isScaleEnabled = false;
352     } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW)) {
353         previewOption.isDefaultShadowEnabled = true;
354     } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS)) {
355         previewOption.isDefaultRadiusEnabled = true;
356     }
357     isAuto = false;
358 }
359 
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)360 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
361     BackgroundImagePosition& bgImgPosition)
362 {
363     AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
364     bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
365     bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
366 }
367 
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)368 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
369 {
370     auto index = pos + containCount;
371     if (index < 0) {
372         return std::string();
373     }
374 
375     JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
376     if (type == "d") {
377         if (item->IsNumber()) {
378             return std::to_string(item->ToNumber<int32_t>());
379         } else if (item->IsObject()) {
380             int32_t result = 0;
381             JSViewAbstract::ParseJsInteger(item, result);
382             return std::to_string(result);
383         }
384     } else if (type == "s") {
385         if (item->IsString()) {
386             return item->ToString();
387         } else if (item->IsObject()) {
388             std::string result;
389             JSViewAbstract::ParseJsString(item, result);
390             return result;
391         }
392     } else if (type == "f") {
393         if (item->IsNumber()) {
394             return std::to_string(item->ToNumber<float>());
395         } else if (item->IsObject()) {
396             double result = 0.0;
397             JSViewAbstract::ParseJsDouble(item, result);
398             return std::to_string(result);
399         }
400     }
401     return std::string();
402 }
403 
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)404 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
405 {
406     auto size = static_cast<int32_t>(params->Length());
407     if (containCount == size) {
408         return;
409     }
410     std::string::const_iterator start = originStr.begin();
411     std::string::const_iterator end = originStr.end();
412     std::smatch matches;
413     bool shortHolderType = false;
414     bool firstMatch = true;
415     int searchTime = 0;
416     while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
417         std::string pos = matches[2];
418         std::string type = matches[4];
419         if (firstMatch) {
420             firstMatch = false;
421             shortHolderType = pos.length() == 0;
422         } else {
423             if (shortHolderType ^ (pos.length() == 0)) {
424                 return;
425             }
426         }
427 
428         std::string replaceContentStr;
429         if (shortHolderType) {
430             replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
431         } else {
432             replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
433         }
434 
435         originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
436         start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
437         end = originStr.end();
438         searchTime++;
439     }
440 }
441 
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)442 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y)
443 {
444     JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
445     JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
446     bool hasX = false;
447     bool hasY = false;
448     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
449         hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP);
450         hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP);
451     } else {
452         hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
453         hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
454     }
455     return hasX || hasY;
456 }
457 
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)458 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
459 {
460     bool useEdges = false;
461     CalcDimension top;
462     CalcDimension left;
463     CalcDimension bottom;
464     CalcDimension right;
465     JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
466     JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
467     JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
468     JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
469     if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) {
470         edges.SetTop(top);
471         useEdges = true;
472     }
473     if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) {
474         edges.SetLeft(left);
475         useEdges = true;
476     }
477     if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) {
478         edges.SetBottom(bottom);
479         useEdges = true;
480     }
481     if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) {
482         edges.SetRight(right);
483         useEdges = true;
484     }
485     return useEdges;
486 }
487 
ParseJsLengthMetrics(const JSRef<JSObject> & obj,CalcDimension & result)488 bool ParseJsLengthMetrics(const JSRef<JSObject>& obj, CalcDimension& result)
489 {
490     auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
491     if (!value->IsNumber()) {
492         return false;
493     }
494     auto unit = DimensionUnit::VP;
495     auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
496     if (jsUnit->IsNumber()) {
497         unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
498     }
499     CalcDimension dimension(value->ToNumber<double>(), unit);
500     result = dimension;
501     return true;
502 }
503 
CheckLengthMetrics(const JSRef<JSObject> & object)504 bool CheckLengthMetrics(const JSRef<JSObject>& object)
505 {
506     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
507         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
508         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
509         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
510         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
511         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
512         return true;
513     }
514     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
515     if (jsTop->IsObject()) {
516         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
517         if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
518             return true;
519         }
520     }
521     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
522     if (jsBottom->IsObject()) {
523         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
524         if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
525             return true;
526         }
527     }
528     return false;
529 }
530 
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)531 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
532 {
533     bool useLocalizedEdges = false;
534     CalcDimension start;
535     CalcDimension end;
536     CalcDimension top;
537     CalcDimension bottom;
538 
539     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
540     if (startVal->IsObject()) {
541         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
542         ParseJsLengthMetrics(startObj, start);
543         edges.SetLeft(start);
544         useLocalizedEdges = true;
545     }
546     JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
547     if (endVal->IsObject()) {
548         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
549         ParseJsLengthMetrics(endObj, end);
550         edges.SetRight(end);
551         useLocalizedEdges = true;
552     }
553     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
554     if (topVal->IsObject()) {
555         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
556         ParseJsLengthMetrics(topObj, top);
557         edges.SetTop(top);
558         useLocalizedEdges = true;
559     }
560     JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
561     if (bottomVal->IsObject()) {
562         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(bottomVal);
563         ParseJsLengthMetrics(bottomObj, bottom);
564         edges.SetBottom(bottom);
565         useLocalizedEdges = true;
566     }
567     return useLocalizedEdges;
568 }
569 
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)570 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
571 {
572     bool useMarkAnchorPosition = false;
573     CalcDimension start;
574     CalcDimension top;
575 
576     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
577     if (startVal->IsObject()) {
578         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
579         ParseJsLengthMetrics(startObj, start);
580         x = start;
581         useMarkAnchorPosition = true;
582     }
583     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
584     if (topVal->IsObject()) {
585         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
586         ParseJsLengthMetrics(topObj, top);
587         y = top;
588         useMarkAnchorPosition = true;
589     }
590     return useMarkAnchorPosition;
591 }
592 
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)593 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
594 {
595     JSRef<JSVal> builder;
596     if (info->IsObject()) {
597         auto builderObj = JSRef<JSObject>::Cast(info);
598         builder = builderObj->GetProperty("builder");
599     } else if (info->IsFunction()) {
600         builder = info;
601     } else {
602         return nullptr;
603     }
604 
605     if (!builder->IsFunction()) {
606         return nullptr;
607     }
608 
609     return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
610 }
611 
612 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
613     const JSRef<JSObject>& object, const JSExecutionContext& context);
614 
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)615 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
616     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
617 {
618     RefPtr<NG::ChainedTransitionEffect> effect;
619     if (effectOption->IsObject()) {
620         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
621         std::optional<float> angle;
622         ParseJsRotate(effectOption, rotate, angle);
623         if (angle.has_value()) {
624             rotate.angle = angle.value();
625             return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
626         }
627     }
628     return nullptr;
629 }
630 
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)631 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
632     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
633 {
634     double opacity = 1.0;
635     if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
636         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
637             if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
638                 opacity = 1.0;
639             }
640         } else {
641             opacity = std::clamp(opacity, 0.0, 1.0);
642         }
643         return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
644     }
645     return nullptr;
646 }
647 
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)648 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
649     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
650 {
651     if (effectOption->IsObject()) {
652         // default: x, y, z (0.0, 0.0, 0.0)
653         NG::TranslateOptions translate;
654         ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
655         return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
656     }
657     return nullptr;
658 }
659 
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)660 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
661     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
662 {
663     if (effectOption->IsObject()) {
664         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
665         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
666         ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
667         return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
668     }
669     return nullptr;
670 }
671 
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)672 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
673     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
674 {
675     int32_t edge = 0;
676     if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
677         if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
678             edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
679             edge = static_cast<int32_t>(NG::TransitionEdge::START);
680         }
681         return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
682     }
683     return nullptr;
684 }
685 
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)686 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
687     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
688 {
689     if (effectOption->IsObject()) {
690         auto effectObj = JSRef<JSObject>::Cast(effectOption);
691         auto appearJsVal = effectObj->GetProperty("appear");
692         auto disappearJsVal = effectObj->GetProperty("disappear");
693         RefPtr<NG::ChainedTransitionEffect> appearEffect;
694         RefPtr<NG::ChainedTransitionEffect> disappearEffect;
695         if (appearJsVal->IsObject()) {
696             auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
697             appearEffect = ParseChainedTransition(appearObj, context);
698         }
699         if (disappearJsVal->IsObject()) {
700             auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
701             disappearEffect = ParseChainedTransition(disappearObj, context);
702         }
703         return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
704     }
705     return nullptr;
706 }
707 
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)708 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
709 {
710     CHECK_NULL_RETURN(pipelineContext, 0);
711     return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
712 }
713 
714 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
715     const JSRef<JSVal>&, const JSExecutionContext&);
716 
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)717 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
718     const JSRef<JSObject>& object, const JSExecutionContext& context)
719 {
720     auto propType = object->GetProperty("type_");
721     if (!propType->IsString()) {
722         return nullptr;
723     }
724     std::string type = propType->ToString();
725     auto propEffectOption = object->GetProperty("effect_");
726     auto propAnimationOption = object->GetProperty("animation_");
727     auto propSuccessor = object->GetProperty("successor_");
728     static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
729         { "asymmetric", ParseChainedAsymmetricTransition },
730         { "identity",
731             [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
732                 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
733         { "move", ParseChainedMoveTransition },
734         { "opacity", ParseChainedOpacityTransition },
735         { "rotate", ParseChainedRotateTransition },
736         { "scale", ParseChainedScaleTransition },
737         { "slideSwitch",
738             [](const JSRef<JSVal>& effectOption,
739                 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
740                 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
741             } },
742         { "translate", ParseChainedTranslateTransition },
743     };
744     int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
745     if (index < 0) {
746         return nullptr;
747     }
748     RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
749     if (!result) {
750         return nullptr;
751     }
752     if (propAnimationOption->IsObject()) {
753         auto container = Container::Current();
754         CHECK_NULL_RETURN(container, nullptr);
755         auto pipelineContext = container->GetPipelineContext();
756         CHECK_NULL_RETURN(pipelineContext, nullptr);
757         auto animationOptionResult = std::make_shared<AnimationOption>(
758             JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRender()));
759         // The maximum of the form-animation-playback duration value is 1000 ms.
760         if (pipelineContext->IsFormRender() && pipelineContext->IsFormAnimation()) {
761             auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
762             // If the duration exceeds 1000ms, init it to 0 ms.
763             if (formAnimationTimeInterval > DEFAULT_DURATION) {
764                 animationOptionResult->SetDuration(0);
765             } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
766                 // If remaining time is less than 1000ms, check for update duration.
767                 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
768                 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation]  Form Transition SetDuration: %{public}lld ms",
769                     static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
770             }
771         }
772         auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
773         JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
774         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
775         if (onFinish->IsFunction()) {
776             RefPtr<JsFunction> jsFunc =
777                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
778             std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
779                                                       id = Container::CurrentId(), node = targetNode]() {
780                 ContainerScope scope(id);
781                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
782                 PipelineContext::SetCallBackNode(node);
783                 func->Execute();
784             };
785             animationOptionResult->SetOnFinishEvent(onFinishEvent);
786         }
787         result->SetAnimationOption(animationOptionResult);
788     }
789     if (propSuccessor->IsObject()) {
790         result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
791     }
792     return result;
793 }
794 
795 #ifndef WEARABLE_PRODUCT
796 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
797     Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP,
798     Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM };
799 
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)800 DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj)
801 {
802     JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent");
803     if (!changeEvent->IsFunction()) {
804         return {};
805     }
806     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent));
807     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
808     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
809                         const std::string& param) {
810         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
811         if (param != "true" && param != "false") {
812             return;
813         }
814         PipelineContext::SetCallBackNode(node);
815         bool newValue = StringToBool(param);
816         JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
817         func->ExecuteJS(1, &newJSVal);
818     };
819     return callback;
820 }
821 
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)822 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
823 {
824     auto colorValue = messageOptionsObj->GetProperty("textColor");
825     Color textColor;
826     if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
827         if (popupParam) {
828             popupParam->SetTextColor(textColor);
829         }
830     }
831 
832     auto font = messageOptionsObj->GetProperty("font");
833     if (!font->IsNull() && font->IsObject()) {
834         JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
835         auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
836         CalcDimension fontSize;
837         if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
838             if (popupParam && fontSize.IsValid()) {
839                 popupParam->SetFontSize(fontSize);
840             }
841         }
842         auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
843         if (fontWeightValue->IsString()) {
844             if (popupParam) {
845                 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
846             }
847         }
848         auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
849         if (fontStyleValue->IsNumber()) {
850             int32_t value = fontStyleValue->ToNumber<int32_t>();
851             if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
852                 return;
853             }
854             if (popupParam) {
855                 popupParam->SetFontStyle(FONT_STYLES[value]);
856             }
857         }
858     }
859 }
860 
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)861 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
862 {
863     JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
864     if (placementOnTopVal->IsBoolean() && popupParam) {
865         popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
866     }
867 }
868 
IsPopupCreated()869 bool IsPopupCreated()
870 {
871     auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
872     CHECK_NULL_RETURN(targetNode, false);
873     auto targetId = targetNode->GetId();
874     auto container = Container::Current();
875     CHECK_NULL_RETURN(container, false);
876     auto pipelineContext = container->GetPipelineContext();
877     CHECK_NULL_RETURN(pipelineContext, false);
878     auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
879     CHECK_NULL_RETURN(context, false);
880     auto overlayManager = context->GetOverlayManager();
881     CHECK_NULL_RETURN(overlayManager, false);
882     auto popupInfo = overlayManager->GetPopupInfo(targetId);
883     if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
884         return false;
885     }
886     return true;
887 }
888 
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)889 void ParsePopupCommonParam(
890     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
891 {
892     auto arrowOffset = popupObj->GetProperty("arrowOffset");
893     CalcDimension offset;
894     if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
895         if (popupParam) {
896             popupParam->SetArrowOffset(offset);
897         }
898     }
899 
900     auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
901     if (arrowPointPosition->IsString()) {
902         char* pEnd = nullptr;
903         auto arrowString = arrowPointPosition->ToString();
904         std::strtod(arrowString.c_str(), &pEnd);
905         if (pEnd != nullptr) {
906             if (std::strcmp(pEnd, "Start") == 0) {
907                 offset = ARROW_ZERO_PERCENT_VALUE;
908             }
909             if (std::strcmp(pEnd, "Center") == 0) {
910                 offset = ARROW_HALF_PERCENT_VALUE;
911             }
912             if (std::strcmp(pEnd, "End") == 0) {
913                 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
914             }
915             if (popupParam) {
916                 popupParam->SetArrowOffset(offset);
917             }
918         }
919     }
920 
921     auto targetSpace = popupObj->GetProperty("targetSpace");
922     if (!targetSpace->IsNull()) {
923         CalcDimension space;
924         if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
925             if (popupParam) {
926                 popupParam->SetTargetSpace(space);
927             }
928         }
929     }
930 
931     JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
932     if (showInSubWindowValue->IsBoolean()) {
933         bool showInSubBoolean = showInSubWindowValue->ToBoolean();
934 #if defined(PREVIEW)
935         if (showInSubBoolean) {
936             LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
937             showInSubBoolean = false;
938         }
939 #endif
940         if (popupParam) {
941             popupParam->SetShowInSubWindow(showInSubBoolean);
942         }
943     }
944 
945     auto placementValue = popupObj->GetProperty("placement");
946     if (placementValue->IsNumber()) {
947         auto placement = placementValue->ToNumber<int32_t>();
948         if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
949             popupParam->SetPlacement(PLACEMENT[placement]);
950         }
951     } else {
952         SetPlacementOnTopVal(popupObj, popupParam);
953     }
954 
955     auto enableArrowValue = popupObj->GetProperty("enableArrow");
956     if (enableArrowValue->IsBoolean()) {
957         popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
958     }
959 
960     auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
961     if (followTransformOfTargetValue->IsBoolean()) {
962         popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
963     }
964 
965     JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
966     if (maskValue->IsBoolean()) {
967         if (popupParam) {
968             popupParam->SetBlockEvent(maskValue->ToBoolean());
969         }
970     }
971     if (maskValue->IsObject()) {
972         auto maskObj = JSRef<JSObject>::Cast(maskValue);
973         auto colorValue = maskObj->GetProperty("color");
974         Color maskColor;
975         if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
976             popupParam->SetMaskColor(maskColor);
977         }
978     }
979 
980     JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
981     if (onStateChangeVal->IsFunction()) {
982         std::vector<std::string> keys = { "isVisible" };
983         RefPtr<JsFunction> jsFunc =
984             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
985         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
986         if (popupParam) {
987             auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
988                                              node = targetNode](const std::string& param) {
989                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
990                 ACE_SCORING_EVENT("Popup.onStateChange");
991                 PipelineContext::SetCallBackNode(node);
992                 func->Execute(keys, param);
993             };
994             popupParam->SetOnStateChange(onStateChangeCallback);
995         }
996     }
997 
998     auto offsetVal = popupObj->GetProperty("offset");
999     if (offsetVal->IsObject()) {
1000         auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
1001         auto xVal = offsetObj->GetProperty("x");
1002         auto yVal = offsetObj->GetProperty("y");
1003         Offset popupOffset;
1004         CalcDimension dx;
1005         CalcDimension dy;
1006         if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
1007             popupOffset.SetX(dx.ConvertToPx());
1008         }
1009         if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
1010             popupOffset.SetY(dy.ConvertToPx());
1011         }
1012         if (popupParam) {
1013             popupParam->SetTargetOffset(popupOffset);
1014         }
1015     }
1016 
1017     Color backgroundColor;
1018     auto popupColorVal = popupObj->GetProperty("popupColor");
1019     if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
1020         popupParam->SetBackgroundColor(backgroundColor);
1021     }
1022 
1023     auto autoCancelVal = popupObj->GetProperty("autoCancel");
1024     if (autoCancelVal->IsBoolean()) {
1025         popupParam->SetHasAction(!autoCancelVal->ToBoolean());
1026     }
1027 
1028     auto childWidthVal = popupObj->GetProperty("width");
1029     if (!childWidthVal->IsNull()) {
1030         CalcDimension width;
1031         if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
1032             if (width.Value() > 0) {
1033                 popupParam->SetChildWidth(width);
1034             }
1035         }
1036     }
1037 
1038     auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
1039     if (!arrowWidthVal->IsNull()) {
1040         bool setError = true;
1041         CalcDimension arrowWidth;
1042         if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
1043             if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
1044                 popupParam->SetArrowWidth(arrowWidth);
1045                 setError = false;
1046             }
1047         }
1048         popupParam->SetErrorArrowWidth(setError);
1049     }
1050 
1051     auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
1052     if (!arrowHeightVal->IsNull()) {
1053         bool setError = true;
1054         CalcDimension arrowHeight;
1055         if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
1056             if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
1057                 popupParam->SetArrowHeight(arrowHeight);
1058                 setError = false;
1059             }
1060         }
1061         popupParam->SetErrorArrowHeight(setError);
1062     }
1063 
1064     auto radiusVal = popupObj->GetProperty("radius");
1065     if (!radiusVal->IsNull()) {
1066         bool setError = true;
1067         CalcDimension radius;
1068         if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
1069             if (radius.Value() >= 0) {
1070                 popupParam->SetRadius(radius);
1071                 setError = false;
1072             }
1073         }
1074         popupParam->SetErrorRadius(setError);
1075     }
1076 
1077     Shadow shadow;
1078     auto shadowVal = popupObj->GetProperty("shadow");
1079     if (shadowVal->IsObject() || shadowVal->IsNumber()) {
1080         auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
1081         if (!ret) {
1082             JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1083         }
1084     } else {
1085         JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1086     }
1087     popupParam->SetShadow(shadow);
1088 
1089     auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
1090     if (blurStyleValue->IsNumber()) {
1091         auto blurStyle = blurStyleValue->ToNumber<int32_t>();
1092         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1093             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1094             popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
1095         }
1096     }
1097 
1098     auto popupTransition = popupObj->GetProperty("transition");
1099     if (popupTransition->IsObject()) {
1100         popupParam->SetHasTransition(true);
1101         auto obj = JSRef<JSObject>::Cast(popupTransition);
1102         auto effects = ParseChainedTransition(obj, info.GetExecutionContext());
1103         popupParam->SetTransitionEffects(effects);
1104     }
1105 
1106     auto keyboardAvoidMode = popupObj->GetProperty("keyboardAvoidMode");
1107     if (keyboardAvoidMode->IsNumber()) {
1108         auto popupKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
1109         if (popupKeyboardAvoidMode >= static_cast<int>(PopupKeyboardAvoidMode::DEFAULT) &&
1110             popupKeyboardAvoidMode <= static_cast<int>(PopupKeyboardAvoidMode::NONE)) {
1111             popupParam->SetKeyBoardAvoidMode(static_cast<PopupKeyboardAvoidMode>(popupKeyboardAvoidMode));
1112         }
1113     }
1114 }
1115 
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1116 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1117 {
1118     ParsePopupCommonParam(info, popupObj, popupParam);
1119     JSRef<JSVal> messageVal = popupObj->GetProperty("message");
1120     if (popupParam) {
1121         popupParam->SetMessage(messageVal->ToString());
1122     }
1123 
1124     auto messageOptions = popupObj->GetProperty("messageOptions");
1125     JSRef<JSObject> messageOptionsObj;
1126     if (!messageOptions->IsNull() && messageOptions->IsObject()) {
1127         messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
1128         SetPopupMessageOptions(messageOptionsObj, popupParam);
1129     }
1130 
1131     JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
1132     if (primaryButtonVal->IsObject()) {
1133         ButtonProperties properties;
1134         JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
1135         JSRef<JSVal> value = obj->GetProperty("value");
1136         if (value->IsString()) {
1137             properties.value = value->ToString();
1138         }
1139 
1140         JSRef<JSVal> actionValue = obj->GetProperty("action");
1141         if (actionValue->IsFunction()) {
1142             auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1143             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1144             if (popupParam) {
1145                 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1146                                          node = targetNode](GestureEvent& info) {
1147                     JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1148                     ACE_SCORING_EVENT("primaryButton.action");
1149                     PipelineContext::SetCallBackNode(node);
1150                     func->Execute(info);
1151                 };
1152                 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1153             }
1154         }
1155         properties.showButton = true;
1156         if (popupParam) {
1157             popupParam->SetPrimaryButtonProperties(properties);
1158         }
1159     }
1160 
1161     JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
1162     if (secondaryButtonVal->IsObject()) {
1163         ButtonProperties properties;
1164         JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
1165         JSRef<JSVal> value = obj->GetProperty("value");
1166         if (value->IsString()) {
1167             properties.value = value->ToString();
1168         }
1169 
1170         JSRef<JSVal> actionValue = obj->GetProperty("action");
1171         if (actionValue->IsFunction()) {
1172             auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1173             auto targetNode =
1174                 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1175             if (popupParam) {
1176                 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1177                                          node = targetNode](GestureEvent& info) {
1178                     JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1179                     ACE_SCORING_EVENT("secondaryButton.action");
1180                     PipelineContext::SetCallBackNode(node);
1181                     func->Execute(info);
1182                 };
1183                 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1184             }
1185         }
1186         properties.showButton = true;
1187         if (popupParam) {
1188             popupParam->SetSecondaryButtonProperties(properties);
1189         }
1190     }
1191 }
1192 
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1193 void ParseCustomPopupParam(
1194     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1195 {
1196     auto builderValue = popupObj->GetProperty("builder");
1197     if (!builderValue->IsObject()) {
1198         return;
1199     }
1200     if (!builderValue->IsFunction()) {
1201         JSRef<JSObject> builderObj;
1202         builderObj = JSRef<JSObject>::Cast(builderValue);
1203         auto builder = builderObj->GetProperty("builder");
1204         if (!builder->IsFunction()) {
1205             return;
1206         }
1207         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1208         if (!builderFunc) {
1209             return;
1210         }
1211     }
1212     if (popupParam) {
1213         popupParam->SetUseCustomComponent(true);
1214     }
1215 
1216     auto focusableValue = popupObj->GetProperty("focusable");
1217     if (focusableValue->IsBoolean()) {
1218         popupParam->SetFocusable(focusableValue->ToBoolean());
1219     }
1220 
1221     ParsePopupCommonParam(info, popupObj, popupParam);
1222 }
1223 #endif
1224 
GetBundleNameFromContainer()1225 std::string GetBundleNameFromContainer()
1226 {
1227     auto container = Container::Current();
1228     CHECK_NULL_RETURN(container, "");
1229     return container->GetBundleName();
1230 }
1231 
GetModuleNameFromContainer()1232 std::string GetModuleNameFromContainer()
1233 {
1234     auto container = Container::Current();
1235     CHECK_NULL_RETURN(container, "");
1236     return container->GetModuleName();
1237 }
1238 
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)1239 void CompleteResourceObjectFromParams(
1240     int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
1241 {
1242     JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
1243     int32_t typeNum = -1;
1244     if (type->IsNumber()) {
1245         typeNum = type->ToNumber<int32_t>();
1246     }
1247 
1248     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1249     if (!args->IsArray()) {
1250         return;
1251     }
1252     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1253     if (resId != UNKNOWN_RESOURCE_ID) {
1254         return;
1255     }
1256     JSRef<JSVal> identity = params->GetValueAt(0);
1257 
1258     bool isParseDollarResourceSuccess =
1259         JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
1260     if (!isParseDollarResourceSuccess) {
1261         return;
1262     }
1263 
1264     std::regex resNameRegex(RESOURCE_NAME_PATTERN);
1265     std::smatch resNameResults;
1266     if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
1267         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
1268     }
1269 
1270     if (typeNum == UNKNOWN_RESOURCE_TYPE) {
1271         jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1272     }
1273 }
1274 
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)1275 void CompleteResourceObjectFromId(
1276     JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
1277 {
1278     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1279     if (!args->IsArray()) {
1280         return;
1281     }
1282     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1283     auto paramCount = params->Length();
1284     JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
1285     if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
1286         std::vector<JSRef<JSVal>> tmpParams;
1287         for (uint32_t i = 0; i < paramCount; i++) {
1288             auto param = params->GetValueAt(i);
1289             tmpParams.insert(tmpParams.end(), param);
1290         }
1291         params->SetValueAt(0, name);
1292         uint32_t paramIndex = 1;
1293         if (!type->IsEmpty()) {
1294             params->SetValueAt(paramIndex, type);
1295             paramIndex++;
1296         }
1297         for (auto tmpParam : tmpParams) {
1298             params->SetValueAt(paramIndex, tmpParam);
1299             paramIndex++;
1300         }
1301     } else {
1302         params->SetValueAt(0, name);
1303     }
1304     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
1305     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1306     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
1307         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1308     }
1309     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
1310         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1311     }
1312 }
1313 
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)1314 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
1315 {
1316     if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
1317         checkDimension.Reset();
1318         return;
1319     }
1320     if (notNegative && checkDimension.IsNegative()) {
1321         checkDimension.Reset();
1322         return;
1323     }
1324 }
1325 
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1326 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1327 {
1328     Color left;
1329     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1330         commonColor.left = left;
1331     }
1332     Color right;
1333     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1334         commonColor.right = right;
1335     }
1336     Color top;
1337     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1338         commonColor.top = top;
1339     }
1340     Color bottom;
1341     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1342         commonColor.bottom = bottom;
1343     }
1344 }
1345 
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1346 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
1347 {
1348     Color start;
1349     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) {
1350         localizedColor.start = start;
1351     }
1352     Color end;
1353     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) {
1354         localizedColor.end = end;
1355     }
1356     Color top;
1357     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1358         localizedColor.top = top;
1359     }
1360     Color bottom;
1361     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1362         localizedColor.bottom = bottom;
1363     }
1364 }
1365 
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1366 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1367 {
1368     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
1369         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
1370         LocalizedColor localizedColor;
1371         ParseLocalizedEdgeColors(object, localizedColor);
1372         commonColor.top = localizedColor.top;
1373         commonColor.bottom = localizedColor.bottom;
1374         commonColor.left = localizedColor.start;
1375         commonColor.right = localizedColor.end;
1376         return true;
1377     }
1378     ParseEdgeColors(object, commonColor);
1379     return false;
1380 }
1381 
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1382 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1383 {
1384     CalcDimension left;
1385     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(LEFT_PROPERTY), left)) {
1386         CheckDimensionUnit(left, true, notNegative);
1387         commonCalcDimension.left = left;
1388     }
1389     CalcDimension right;
1390     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(RIGHT_PROPERTY), right)) {
1391         CheckDimensionUnit(right, true, notNegative);
1392         commonCalcDimension.right = right;
1393     }
1394     CalcDimension top;
1395     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(TOP_PROPERTY), top)) {
1396         CheckDimensionUnit(top, true, notNegative);
1397         commonCalcDimension.top = top;
1398     }
1399     CalcDimension bottom;
1400     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(BOTTOM_PROPERTY), bottom)) {
1401         CheckDimensionUnit(bottom, true, notNegative);
1402         commonCalcDimension.bottom = bottom;
1403     }
1404 }
1405 
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1406 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
1407     bool notNegative, CalcDimension defaultValue)
1408 {
1409     CalcDimension left;
1410     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) {
1411         CheckDimensionUnit(left, notPercent, notNegative);
1412         commonCalcDimension.left = left;
1413     } else {
1414         commonCalcDimension.left = defaultValue;
1415     }
1416     CalcDimension right;
1417     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) {
1418         CheckDimensionUnit(right, notPercent, notNegative);
1419         commonCalcDimension.right = right;
1420     } else {
1421         commonCalcDimension.right = defaultValue;
1422     }
1423     CalcDimension top;
1424     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) {
1425         CheckDimensionUnit(top, notPercent, notNegative);
1426         commonCalcDimension.top = top;
1427     } else {
1428         commonCalcDimension.top = defaultValue;
1429     }
1430     CalcDimension bottom;
1431     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) {
1432         CheckDimensionUnit(bottom, false, true);
1433         commonCalcDimension.bottom = bottom;
1434     } else {
1435         commonCalcDimension.bottom = defaultValue;
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         if (ParseJsLengthMetrics(startObj, calcDimension)) {
1486             CheckDimensionUnit(calcDimension, false, true);
1487             localizedCalcDimension.start = calcDimension;
1488         }
1489     }
1490     if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
1491         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
1492         CalcDimension calcDimension;
1493         if (ParseJsLengthMetrics(endObj, calcDimension)) {
1494             CheckDimensionUnit(calcDimension, false, true);
1495             localizedCalcDimension.end = calcDimension;
1496         }
1497     }
1498     if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
1499         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
1500         CalcDimension calcDimension;
1501         if (ParseJsLengthMetrics(topObj, calcDimension)) {
1502             CheckDimensionUnit(calcDimension, false, true);
1503             localizedCalcDimension.top = calcDimension;
1504         }
1505     }
1506     if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
1507         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
1508         CalcDimension calcDimension;
1509         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1510             CheckDimensionUnit(calcDimension, false, true);
1511             localizedCalcDimension.bottom = calcDimension;
1512         }
1513     }
1514 }
1515 
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1516 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1517 {
1518     if (CheckLengthMetrics(object)) {
1519         LocalizedCalcDimension localizedCalcDimension;
1520         ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
1521         commonCalcDimension.top = localizedCalcDimension.top;
1522         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1523         commonCalcDimension.left = localizedCalcDimension.start;
1524         commonCalcDimension.right = localizedCalcDimension.end;
1525         return true;
1526     }
1527     ParseEdgeWidths(object, commonCalcDimension, notNegative);
1528     return false;
1529 }
1530 
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1531 void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1532 {
1533     if (CheckLengthMetrics(object)) {
1534         LocalizedCalcDimension localizedCalcDimension;
1535         ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
1536         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1537         commonCalcDimension.top = localizedCalcDimension.top;
1538         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1539         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1540         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1541         return;
1542     }
1543     ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1544 }
1545 
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1546 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1547 {
1548     if (CheckLengthMetrics(object)) {
1549         LocalizedCalcDimension localizedCalcDimension;
1550         ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1551         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1552         commonCalcDimension.top = localizedCalcDimension.top;
1553         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1554         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1555         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1556         return;
1557     }
1558     ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1559 }
1560 
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1561 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1562 {
1563     auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1564     auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1565     auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1566         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1567         NG::PipelineContext::SetCallBackNode(targetNode);
1568         JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1569         jsFuncFinish->ExecuteJS(1, &newJSVal);
1570     };
1571     return finishCallback;
1572 }
1573 } // namespace
1574 
GetResourceObject(const JSRef<JSObject> & jsObj)1575 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1576 {
1577     auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1578     auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1579     auto args = jsObj->GetProperty("params");
1580 
1581     std::string bundleName;
1582     std::string moduleName;
1583     auto bundle = jsObj->GetProperty("bundleName");
1584     auto module = jsObj->GetProperty("moduleName");
1585     if (bundle->IsString() && module->IsString()) {
1586         bundleName = bundle->ToString();
1587         moduleName = module->ToString();
1588     }
1589     if (!args->IsArray()) {
1590         return nullptr;
1591     }
1592     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1593     std::vector<ResourceObjectParams> resObjParamsList;
1594     auto size = static_cast<int32_t>(params->Length());
1595     for (int32_t i = 0; i < size; i++) {
1596         auto item = params->GetValueAt(i);
1597         ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1598         if (item->IsString()) {
1599             resObjParams.type = ResourceObjectParamType::STRING;
1600         } else if (item->IsNumber()) {
1601             if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1602                 resObjParams.type = ResourceObjectParamType::FLOAT;
1603             } else {
1604                 resObjParams.type = ResourceObjectParamType::INT;
1605             }
1606         }
1607         resObjParamsList.push_back(resObjParams);
1608     }
1609     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName);
1610     return resourceObject;
1611 }
1612 
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1613 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1614 {
1615     auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1616     auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1617     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName);
1618     return resourceObject;
1619 }
1620 
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1621 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1622 {
1623     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1624     RefPtr<ThemeConstants> themeConstants = nullptr;
1625     if (SystemProperties::GetResourceDecoupling()) {
1626         resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1627         if (!resourceAdapter) {
1628             return nullptr;
1629         }
1630     } else {
1631         themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1632         if (!themeConstants) {
1633             return nullptr;
1634         }
1635     }
1636     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1637     return resourceWrapper;
1638 }
1639 
CreateResourceWrapper()1640 RefPtr<ResourceWrapper> CreateResourceWrapper()
1641 {
1642     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1643     RefPtr<ThemeConstants> themeConstants = nullptr;
1644     if (SystemProperties::GetResourceDecoupling()) {
1645         resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter();
1646         if (!resourceAdapter) {
1647             return nullptr;
1648         }
1649     } else {
1650         themeConstants = JSViewAbstract::GetThemeConstants();
1651         if (!themeConstants) {
1652             return nullptr;
1653         }
1654     }
1655     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1656     return resourceWrapper;
1657 }
1658 
ColorAlphaAdapt(uint32_t origin)1659 uint32_t ColorAlphaAdapt(uint32_t origin)
1660 {
1661     uint32_t result = origin;
1662     if (origin >> COLOR_ALPHA_OFFSET == 0) {
1663         result = origin | COLOR_ALPHA_VALUE;
1664     }
1665     return result;
1666 }
1667 
StringToOperationType(const std::string & id)1668 OperationType StringToOperationType(const std::string& id)
1669 {
1670     if (id == "OH_DEFAULT_COPY") {
1671         return OperationType::COPY;
1672     } else if (id == "OH_DEFAULT_PASTE") {
1673         return OperationType::PASTE;
1674     } else if (id == "OH_DEFAULT_CUT") {
1675         return OperationType::CUT;
1676     } else if (id == "OH_DEFAULT_SELECT_ALL") {
1677         return OperationType::SELECT_ALL;
1678     } else {
1679         return OperationType::UNKNOWN;
1680     }
1681 }
1682 
UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam> & params)1683 void UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam>& params)
1684 {
1685     for (auto& param : params) {
1686         auto opType = StringToOperationType(param.menuOptionsParam.id);
1687         auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1688         CHECK_NULL_VOID(pipeline);
1689         auto theme = pipeline->GetTheme<TextOverlayTheme>();
1690         CHECK_NULL_VOID(theme);
1691         switch (opType) {
1692             case OperationType::COPY:
1693                 param.menuOptionsParam.labelInfo = theme->GetCopyLabelInfo();
1694                 break;
1695             case OperationType::PASTE:
1696                 param.menuOptionsParam.labelInfo = theme->GetPasteLabelInfo();
1697                 break;
1698             case OperationType::CUT:
1699                 param.menuOptionsParam.labelInfo = theme->GetCutLabelInfo();
1700                 break;
1701             case OperationType::SELECT_ALL:
1702                 param.menuOptionsParam.labelInfo = theme->GetSelectAllLabelInfo();
1703                 break;
1704             default:
1705                 param.menuOptionsParam.labelInfo = "";
1706                 break;
1707         }
1708     }
1709 }
1710 
JsScale(const JSCallbackInfo & info)1711 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1712 {
1713     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1714     auto jsVal = info[0];
1715     if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1716         SetDefaultScale();
1717         return;
1718     }
1719 
1720     if (jsVal->IsObject()) {
1721         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1722         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1723             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1724             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1725             // default: x, y, z (1.0, 1.0, 1.0)
1726             auto scaleX = 1.0f;
1727             auto scaleY = 1.0f;
1728             auto scaleZ = 1.0f;
1729             // default centerX, centerY 50% 50%;
1730             CalcDimension centerX = 0.5_pct;
1731             CalcDimension centerY = 0.5_pct;
1732             ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1733             ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1734             ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1735             return;
1736         } else {
1737             SetDefaultScale();
1738         }
1739     }
1740     double scale = 0.0;
1741     if (ParseJsDouble(jsVal, scale)) {
1742         ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1743     }
1744 }
1745 
SetDefaultScale()1746 void JSViewAbstract::SetDefaultScale()
1747 {
1748     ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1749     ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1750 }
1751 
JsScaleX(const JSCallbackInfo & info)1752 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1753 {
1754     double scaleVal = 0.0;
1755     if (!ParseJsDouble(info[0], scaleVal)) {
1756         return;
1757     }
1758     ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1759 }
1760 
JsScaleY(const JSCallbackInfo & info)1761 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1762 {
1763     double scaleVal = 0.0;
1764     if (!ParseJsDouble(info[0], scaleVal)) {
1765         return;
1766     }
1767     ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1768 }
1769 
JsOpacity(const JSCallbackInfo & info)1770 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1771 {
1772     double opacity = 0.0;
1773     if (!ParseJsDouble(info[0], opacity)) {
1774         ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1775         return;
1776     }
1777     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1778         opacity = std::clamp(opacity, 0.0, 1.0);
1779     } else {
1780         if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1781             opacity = 1.0;
1782         }
1783     }
1784     ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1785 }
1786 
JsTranslate(const JSCallbackInfo & info)1787 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1788 {
1789     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1790         JSCallbackInfoType::OBJECT };
1791     auto jsVal = info[0];
1792     if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
1793         SetDefaultTranslate();
1794         return;
1795     }
1796 
1797     if (jsVal->IsObject()) {
1798         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1799         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1800             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1801             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1802             // default: x, y, z (0.0, 0.0, 0.0)
1803             auto translateX = CalcDimension(0.0);
1804             auto translateY = CalcDimension(0.0);
1805             auto translateZ = CalcDimension(0.0);
1806             ParseJsTranslate(jsVal, translateX, translateY, translateZ);
1807             ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1808             return;
1809         } else {
1810             SetDefaultTranslate();
1811         }
1812     }
1813     CalcDimension value;
1814     if (ParseJsDimensionVp(jsVal, value)) {
1815         ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1816     }
1817 }
1818 
SetDefaultTranslate()1819 void JSViewAbstract::SetDefaultTranslate()
1820 {
1821     ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1822 }
1823 
JsTranslateX(const JSCallbackInfo & info)1824 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1825 {
1826     CalcDimension value;
1827     if (!ParseJsDimensionVp(info[0], value)) {
1828         return;
1829     }
1830     ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1831 }
1832 
JsTranslateY(const JSCallbackInfo & info)1833 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1834 {
1835     CalcDimension value;
1836     if (!ParseJsDimensionVp(info[0], value)) {
1837         return;
1838     }
1839     ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1840 }
1841 
JsRotate(const JSCallbackInfo & info)1842 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1843 {
1844     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1845     auto jsVal = info[0];
1846     if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
1847         SetDefaultRotate();
1848         return;
1849     }
1850 
1851     if (jsVal->IsObject()) {
1852         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1853         std::optional<float> angle;
1854         ParseJsRotate(jsVal, rotate, angle);
1855         if (angle) {
1856             ViewAbstractModel::GetInstance()->SetRotate(
1857                 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1858             ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1859         } else {
1860             SetDefaultRotate();
1861         }
1862         return;
1863     }
1864     double rotateZ;
1865     if (ParseJsDouble(jsVal, rotateZ)) {
1866         ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1867     }
1868 }
1869 
SetDefaultRotate()1870 void JSViewAbstract::SetDefaultRotate()
1871 {
1872     NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1873     ViewAbstractModel::GetInstance()->SetRotate(
1874         rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1875     ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1876 }
1877 
JsRotateX(const JSCallbackInfo & info)1878 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1879 {
1880     double rotateVal = 0.0;
1881     if (!ParseJsDouble(info[0], rotateVal)) {
1882         return;
1883     }
1884     ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1885 }
1886 
JsRotateY(const JSCallbackInfo & info)1887 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1888 {
1889     double rotateVal = 0.0;
1890     if (!ParseJsDouble(info[0], rotateVal)) {
1891         return;
1892     }
1893     ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1894 }
1895 
JsTransform(const JSCallbackInfo & info)1896 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1897 {
1898     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1899     auto jsVal = info[0];
1900     if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
1901         SetDefaultTransform();
1902         return;
1903     }
1904     JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
1905     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1906     if (!array->IsArray()) {
1907         return;
1908     }
1909     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1910     if (jsArray->Length() != matrix4Len) {
1911         return;
1912     }
1913     std::vector<float> matrix(matrix4Len);
1914     for (int32_t i = 0; i < matrix4Len; i++) {
1915         double value = 0.0;
1916         ParseJsDouble(jsArray->GetValueAt(i), value);
1917         matrix[i] = static_cast<float>(value);
1918     }
1919     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1920 }
1921 
SetDefaultTransform()1922 void JSViewAbstract::SetDefaultTransform()
1923 {
1924     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1925     std::vector<float> matrix(matrix4Len);
1926     const int32_t initPosition = 5;
1927     for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1928         double value = 1.0;
1929         matrix[i] = static_cast<float>(value);
1930     }
1931     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1932 }
1933 
ParseJsTransition(const JSRef<JSObject> & jsObj)1934 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
1935 {
1936     NG::TransitionOptions transitionOption;
1937     bool hasEffect = false;
1938     transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1939     if (jsObj->HasProperty("opacity")) {
1940         double opacity = 1.0;
1941         ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1942         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1943             if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1944                 opacity = 1.0;
1945             }
1946         } else {
1947             opacity = std::clamp(opacity, 0.0, 1.0);
1948         }
1949         transitionOption.UpdateOpacity(static_cast<float>(opacity));
1950         hasEffect = true;
1951     }
1952     if (jsObj->HasProperty("translate")) {
1953         // default: x, y, z (0.0, 0.0, 0.0)
1954         NG::TranslateOptions translate;
1955         ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1956         transitionOption.UpdateTranslate(translate);
1957         hasEffect = true;
1958     }
1959     if (jsObj->HasProperty("scale")) {
1960         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1961         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1962         ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1963             scale.centerX, scale.centerY);
1964         transitionOption.UpdateScale(scale);
1965         hasEffect = true;
1966     }
1967     if (jsObj->HasProperty("rotate")) {
1968         // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1969         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1970         std::optional<float> angle;
1971         ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1972         if (angle.has_value()) {
1973             rotate.angle = angle.value();
1974             transitionOption.UpdateRotate(rotate);
1975             hasEffect = true;
1976         }
1977     }
1978     if (!hasEffect) {
1979         // default transition
1980         transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1981     }
1982     return transitionOption;
1983 }
1984 
ParseJsTransitionEffect(const JSCallbackInfo & info)1985 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
1986 {
1987     JSRef<JSVal> arg = info[0];
1988     if (!arg->IsObject()) {
1989         return nullptr;
1990     }
1991     auto obj = JSRef<JSObject>::Cast(arg);
1992     auto transitionVal = obj->GetProperty("transition");
1993 
1994     if (!transitionVal->IsObject()) {
1995         return nullptr;
1996     }
1997 
1998     auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
1999     auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
2000     return chainedEffect;
2001 }
2002 
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)2003 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
2004     const JSExecutionContext& context)
2005 {
2006     auto chainedEffect = ParseChainedTransition(object, context);
2007     return chainedEffect;
2008 }
2009 
JsTransition(const JSCallbackInfo & info)2010 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
2011 {
2012     if (info.Length() < 1 || !info[0]->IsObject()) {
2013         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
2014             ViewAbstractModel::GetInstance()->CleanTransition();
2015             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
2016         }
2017         return;
2018     }
2019     auto obj = JSRef<JSObject>::Cast(info[0]);
2020     if (!obj->GetProperty("successor_")->IsUndefined()) {
2021         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
2022         std::function<void(bool)> finishCallback;
2023         if (info.Length() > 1 && info[1]->IsFunction()) {
2024             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
2025         }
2026         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
2027         return;
2028     }
2029     auto options = ParseJsTransition(obj);
2030     ViewAbstractModel::GetInstance()->SetTransition(options);
2031 }
2032 
JsWidth(const JSCallbackInfo & info)2033 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
2034 {
2035     JsWidth(info[0]);
2036 }
2037 
JsWidth(const JSRef<JSVal> & jsValue)2038 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
2039 {
2040     CalcDimension value;
2041     if (jsValue->IsUndefined()) {
2042         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2043         return true;
2044     }
2045     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2046         if (!ParseJsDimensionVpNG(jsValue, value)) {
2047             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2048             return false;
2049         }
2050     } else if (!ParseJsDimensionVp(jsValue, value)) {
2051         return false;
2052     }
2053 
2054     if (LessNotEqual(value.Value(), 0.0)) {
2055         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2056             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2057             return true;
2058         } else {
2059             value.SetValue(0.0);
2060         }
2061     }
2062 
2063     ViewAbstractModel::GetInstance()->SetWidth(value);
2064     return true;
2065 }
2066 
JsHeight(const JSCallbackInfo & info)2067 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
2068 {
2069     JsHeight(info[0]);
2070 }
2071 
JsHeight(const JSRef<JSVal> & jsValue)2072 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
2073 {
2074     CalcDimension value;
2075     if (jsValue->IsUndefined()) {
2076         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2077         return true;
2078     }
2079     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2080         if (!ParseJsDimensionVpNG(jsValue, value)) {
2081             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2082             return false;
2083         }
2084     } else if (!ParseJsDimensionVp(jsValue, value)) {
2085         return false;
2086     }
2087 
2088     if (LessNotEqual(value.Value(), 0.0)) {
2089         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2090             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2091             return true;
2092         } else {
2093             value.SetValue(0.0);
2094         }
2095     }
2096 
2097     ViewAbstractModel::GetInstance()->SetHeight(value);
2098     return true;
2099 }
2100 
JsResponseRegion(const JSCallbackInfo & info)2101 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
2102 {
2103     std::vector<DimensionRect> result;
2104     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2105         ViewAbstractModel::GetInstance()->SetResponseRegion({});
2106         return;
2107     }
2108 
2109     ViewAbstractModel::GetInstance()->SetResponseRegion(result);
2110 }
2111 
JsMouseResponseRegion(const JSCallbackInfo & info)2112 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
2113 {
2114     std::vector<DimensionRect> result;
2115     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2116         ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
2117         return;
2118     }
2119     ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
2120 }
2121 
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2122 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
2123 {
2124     result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
2125     result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
2126     if (!jsValue->IsObject()) {
2127         return true;
2128     }
2129 
2130     JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
2131     JSRef<JSVal> x = obj->GetProperty("x");
2132     JSRef<JSVal> y = obj->GetProperty("y");
2133     JSRef<JSVal> width = obj->GetProperty("width");
2134     JSRef<JSVal> height = obj->GetProperty("height");
2135     CalcDimension xDimen = result.GetOffset().GetX();
2136     CalcDimension yDimen = result.GetOffset().GetY();
2137     CalcDimension widthDimen = result.GetWidth();
2138     CalcDimension heightDimen = result.GetHeight();
2139     auto s1 = width->ToString();
2140     auto s2 = height->ToString();
2141     if (s1.find('-') != std::string::npos) {
2142         width = JSRef<JSVal>::Make(ToJSValue("100%"));
2143     }
2144     if (s2.find('-') != std::string::npos) {
2145         height = JSRef<JSVal>::Make(ToJSValue("100%"));
2146     }
2147     if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
2148         auto offset = result.GetOffset();
2149         offset.SetX(xDimen);
2150         result.SetOffset(offset);
2151     }
2152     if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
2153         auto offset = result.GetOffset();
2154         offset.SetY(yDimen);
2155         result.SetOffset(offset);
2156     }
2157     if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
2158         if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
2159             return true;
2160         }
2161         result.SetWidth(widthDimen);
2162     }
2163     if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
2164         if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
2165             return true;
2166         }
2167         result.SetHeight(heightDimen);
2168     }
2169     return true;
2170 }
2171 
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2172 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
2173 {
2174     if (!jsValue->IsArray() && !jsValue->IsObject()) {
2175         return false;
2176     }
2177 
2178     if (jsValue->IsArray()) {
2179         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2180         for (size_t i = 0; i < array->Length(); i++) {
2181             CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2182             CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2183             CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2184             CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2185             DimensionOffset offsetDimen(xDimen, yDimen);
2186             DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2187             if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
2188                 result.emplace_back(dimenRect);
2189             } else {
2190                 return false;
2191             }
2192         }
2193         return true;
2194     }
2195 
2196     CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2197     CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2198     CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2199     CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2200     DimensionOffset offsetDimen(xDimen, yDimen);
2201     DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2202     if (ParseJsDimensionRect(jsValue, dimenRect)) {
2203         result.emplace_back(dimenRect);
2204         return true;
2205     } else {
2206         return false;
2207     }
2208 }
2209 
JsSize(const JSCallbackInfo & info)2210 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
2211 {
2212     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2213     auto jsVal = info[0];
2214     if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
2215         return;
2216     }
2217 
2218     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2219     JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
2220     JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
2221 }
2222 
JsConstraintSize(const JSCallbackInfo & info)2223 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
2224 {
2225     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2226     auto jsVal = info[0];
2227     if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
2228         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2229         ViewAbstractModel::GetInstance()->ResetMinSize(true);
2230         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2231         ViewAbstractModel::GetInstance()->ResetMinSize(false);
2232         return;
2233     }
2234 
2235     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2236 
2237     JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
2238     CalcDimension minWidth;
2239     JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
2240     CalcDimension maxWidth;
2241     JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
2242     CalcDimension minHeight;
2243     JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
2244     CalcDimension maxHeight;
2245     bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
2246     if (ParseJsDimensionVp(minWidthValue, minWidth)) {
2247         ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
2248     } else if (version10OrLarger) {
2249         ViewAbstractModel::GetInstance()->ResetMinSize(true);
2250     }
2251 
2252     if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
2253         ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
2254     } else if (version10OrLarger) {
2255         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2256     }
2257 
2258     if (ParseJsDimensionVp(minHeightValue, minHeight)) {
2259         ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
2260     } else if (version10OrLarger) {
2261         ViewAbstractModel::GetInstance()->ResetMinSize(false);
2262     }
2263 
2264     if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
2265         ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
2266     } else if (version10OrLarger) {
2267         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2268     }
2269 }
2270 
JsLayoutPriority(const JSCallbackInfo & info)2271 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
2272 {
2273     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2274     auto jsVal = info[0];
2275     if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
2276         return;
2277     }
2278 
2279     int32_t priority;
2280     if (jsVal->IsNumber()) {
2281         priority = jsVal->ToNumber<int32_t>();
2282     } else {
2283         priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
2284     }
2285     ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
2286 }
2287 
JsPixelRound(const JSCallbackInfo & info)2288 void JSViewAbstract::JsPixelRound(const JSCallbackInfo& info)
2289 {
2290     uint16_t value = 0;
2291     JSRef<JSVal> arg = info[0];
2292     if (!arg->IsObject()) {
2293         return;
2294     }
2295     JSRef<JSObject> object = JSRef<JSObject>::Cast(arg);
2296     JSRef<JSVal> jsStartValue = object->GetProperty("start");
2297     if (jsStartValue->IsNumber()) {
2298         int32_t startValue = jsStartValue->ToNumber<int32_t>();
2299         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(startValue)) {
2300             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_START);
2301         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(startValue)) {
2302             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_START);
2303         } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(startValue)) {
2304             value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_START);
2305         }
2306     }
2307     JSRef<JSVal> jsTopValue = object->GetProperty("top");
2308     if (jsTopValue->IsNumber()) {
2309         int32_t topValue = jsTopValue->ToNumber<int32_t>();
2310         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(topValue)) {
2311             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
2312         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(topValue)) {
2313             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
2314         } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(topValue)) {
2315             value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_TOP);
2316         }
2317     }
2318     JSRef<JSVal> jsEndValue = object->GetProperty("end");
2319     if (jsEndValue->IsNumber()) {
2320         int32_t endValue = jsEndValue->ToNumber<int32_t>();
2321         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(endValue)) {
2322             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_END);
2323         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(endValue)) {
2324             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_END);
2325         } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(endValue)) {
2326             value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_END);
2327         }
2328     }
2329     JSRef<JSVal> jsBottomValue = object->GetProperty("bottom");
2330     if (jsBottomValue->IsNumber()) {
2331         int32_t bottomValue = jsBottomValue->ToNumber<int32_t>();
2332         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2333             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
2334         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2335             value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
2336         } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2337             value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_BOTTOM);
2338         }
2339     }
2340     ViewAbstractModel::GetInstance()->SetPixelRound(value);
2341 }
2342 
JsLayoutWeight(const JSCallbackInfo & info)2343 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
2344 {
2345     float value = 0.0f;
2346     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2347     auto jsVal = info[0];
2348     if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
2349         if (!jsVal->IsUndefined()) {
2350             return;
2351         }
2352     }
2353 
2354     if (jsVal->IsNumber()) {
2355         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2356             value = jsVal->ToNumber<float>();
2357         } else {
2358             value = jsVal->ToNumber<int32_t>();
2359         }
2360     } else {
2361         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2362             value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
2363         } else {
2364             value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
2365         }
2366     }
2367 
2368     ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
2369 }
2370 
JsChainWeight(const JSCallbackInfo & info)2371 void JSViewAbstract::JsChainWeight(const JSCallbackInfo& info)
2372 {
2373     NG::LayoutWeightPair layoutWeightPair(DEFAULT_LAYOUT_WEIGHT, DEFAULT_LAYOUT_WEIGHT);
2374     auto jsVal = info[0];
2375     if (jsVal->IsObject()) {
2376         JSRef<JSObject> val = JSRef<JSObject>::Cast(jsVal);
2377         auto weightX = val->GetProperty("horizontal");
2378         auto weightY = val->GetProperty("vertical");
2379         if (weightX->IsNumber()) {
2380             layoutWeightPair.first = weightX->ToNumber<float>();
2381         }
2382         if (weightY->IsNumber()) {
2383             layoutWeightPair.second = weightY->ToNumber<float>();
2384         }
2385     }
2386     ViewAbstractModel::GetInstance()->SetLayoutWeight(layoutWeightPair);
2387 }
2388 
JsAlign(const JSCallbackInfo & info)2389 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
2390 {
2391     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2392     auto jsVal = info[0];
2393     if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
2394         Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2395         ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
2396         return;
2397     }
2398     auto value = jsVal->ToNumber<int32_t>();
2399     Alignment alignment = ParseAlignment(value);
2400     ViewAbstractModel::GetInstance()->SetAlign(alignment);
2401 }
2402 
JsPosition(const JSCallbackInfo & info)2403 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
2404 {
2405     CalcDimension x;
2406     CalcDimension y;
2407     OHOS::Ace::EdgesParam edges;
2408 
2409     auto jsArg = info[0];
2410     if (jsArg->IsObject()) {
2411         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2412         if (ParseLocationProps(jsObj, x, y)) {
2413             return ViewAbstractModel::GetInstance()->SetPosition(x, y);
2414         } else if (ParseLocalizedEdges(jsObj, edges)) {
2415             ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
2416             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2417         } else if (ParseLocationPropsEdges(jsObj, edges)) {
2418             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2419         }
2420     }
2421     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2422         ViewAbstractModel::GetInstance()->ResetPosition();
2423     } else {
2424         ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
2425     }
2426 }
2427 
JsMarkAnchor(const JSCallbackInfo & info)2428 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
2429 {
2430     CalcDimension x;
2431     CalcDimension y;
2432 
2433     auto jsArg = info[0];
2434     if (jsArg->IsObject()) {
2435         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2436         if (ParseMarkAnchorPosition(jsObj, x, y)) {
2437             ViewAbstractModel::GetInstance()->SetLocalizedMarkAnchor(true);
2438             return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2439         } else if (ParseLocationProps(jsObj, x, y)) {
2440             return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2441         }
2442     }
2443     ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
2444 }
2445 
JsOffset(const JSCallbackInfo & info)2446 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
2447 {
2448     CalcDimension x;
2449     CalcDimension y;
2450     OHOS::Ace::EdgesParam edges;
2451     auto jsArg = info[0];
2452     if (jsArg->IsObject()) {
2453         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2454         if (ParseLocalizedEdges(jsObj, edges)) {
2455             ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
2456             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2457         } else if (ParseLocationProps(jsObj, x, y)) {
2458             return ViewAbstractModel::GetInstance()->SetOffset(x, y);
2459         } else if (ParseLocationPropsEdges(jsObj, edges)) {
2460             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2461         }
2462     }
2463 
2464     ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
2465 }
2466 
JsEnabled(const JSCallbackInfo & info)2467 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
2468 {
2469     auto arg = info[0];
2470     if (!arg->IsBoolean()) {
2471         ViewAbstractModel::GetInstance()->SetEnabled(true);
2472     } else {
2473         ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
2474     }
2475 }
2476 
JsAspectRatio(const JSCallbackInfo & info)2477 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
2478 {
2479     double value = 0.0;
2480     auto jsAspectRatio = info[0];
2481     if (!ParseJsDouble(jsAspectRatio, value)) {
2482         // add version protection, undefined use default value
2483         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
2484             (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
2485             ViewAbstractModel::GetInstance()->ResetAspectRatio();
2486             return;
2487         } else {
2488             return;
2489         }
2490     }
2491 
2492     // negative use default value.
2493     if (LessOrEqual(value, 0.0)) {
2494         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2495             ViewAbstractModel::GetInstance()->ResetAspectRatio();
2496             return;
2497         } else {
2498             value = 1.0;
2499         }
2500     }
2501 
2502     ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
2503 }
2504 
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2505 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
2506     std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
2507 {
2508     if (info[0]->IsString()) {
2509         std::string text = info[0]->ToString();
2510         ViewAbstractModel::GetInstance()->SetOverlay(
2511             text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
2512     } else if (info[0]->IsObject()) {
2513         JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
2514         auto builder = overlayObject->GetProperty("builder");
2515         if (builder->IsFunction()) {
2516             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2517             CHECK_NULL_VOID(builderFunc);
2518             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2519             auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
2520                               node = targetNode]() {
2521                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2522                 ACE_SCORING_EVENT("Overlay");
2523                 PipelineContext::SetCallBackNode(node);
2524                 func->Execute();
2525             };
2526             ViewAbstractModel::GetInstance()->SetOverlay(
2527                 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
2528             return;
2529         }
2530 
2531         JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
2532         if (!builderNode->IsObject()) {
2533             return;
2534         }
2535         auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2536         JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2537         if (nodePtr.IsEmpty()) {
2538             return;
2539         }
2540         const auto* vm = nodePtr->GetEcmaVM();
2541         auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
2542         auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2543         CHECK_NULL_VOID(frameNode);
2544         RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2545         ViewAbstractModel::GetInstance()->SetOverlay(
2546             "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2547     }
2548 }
2549 
JsOverlay(const JSCallbackInfo & info)2550 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2551 {
2552     if (info.Length() > 0 && (info[0]->IsUndefined())) {
2553         ViewAbstractModel::GetInstance()->SetOverlay(
2554             "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2555         return;
2556     }
2557 
2558     if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2559         return;
2560     }
2561     std::optional<Alignment> align;
2562     std::optional<CalcDimension> offsetX;
2563     std::optional<CalcDimension> offsetY;
2564 
2565     if (info[1]->IsObject()) {
2566         JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2567         JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2568         auto value = alignVal->ToNumber<int32_t>();
2569         Alignment alignment = ParseAlignment(value);
2570         align = alignment;
2571 
2572         JSRef<JSVal> val = optionObj->GetProperty("offset");
2573         if (val->IsObject()) {
2574             JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2575             JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2576             CalcDimension x;
2577             if (ParseJsDimensionVp(xVal, x)) {
2578                 offsetX = x;
2579             }
2580             JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2581             CalcDimension y;
2582             if (ParseJsDimensionVp(yVal, y)) {
2583                 offsetY = y;
2584             }
2585         }
2586     }
2587 
2588     ParseOverlayFirstParam(info, align, offsetX, offsetY);
2589 }
2590 
ParseAlignment(int32_t align)2591 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2592 {
2593     Alignment alignment = Alignment::CENTER;
2594     switch (align) {
2595         case 0:
2596             alignment = Alignment::TOP_LEFT;
2597             break;
2598         case 1:
2599             alignment = Alignment::TOP_CENTER;
2600             break;
2601         case 2:
2602             alignment = Alignment::TOP_RIGHT;
2603             break;
2604         case 3:
2605             alignment = Alignment::CENTER_LEFT;
2606             break;
2607         case 4:
2608             alignment = Alignment::CENTER;
2609             break;
2610         case 5:
2611             alignment = Alignment::CENTER_RIGHT;
2612             break;
2613         case 6:
2614             alignment = Alignment::BOTTOM_LEFT;
2615             break;
2616         case 7:
2617             alignment = Alignment::BOTTOM_CENTER;
2618             break;
2619         case 8:
2620             alignment = Alignment::BOTTOM_RIGHT;
2621             break;
2622         default:
2623             break;
2624     }
2625     return alignment;
2626 }
2627 
SetVisibility(const JSCallbackInfo & info)2628 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2629 {
2630     int32_t visible = 0;
2631     JSRef<JSVal> arg = info[0];
2632     if (arg->IsNull() || arg->IsUndefined()) {
2633         // undefined value use default value.
2634         visible = 0;
2635     } else if (!arg->IsNumber()) {
2636         return;
2637     } else {
2638         visible = arg->ToNumber<int32_t>();
2639     }
2640 
2641     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2642         (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
2643         visible = 0;
2644     }
2645 
2646     if (info.Length() > 1 && info[1]->IsFunction()) {
2647         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2648         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2649         auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2650                                       int32_t visible) {
2651             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2652             ACE_SCORING_EVENT("onVisibilityChange");
2653             PipelineContext::SetCallBackNode(node);
2654             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2655             func->ExecuteJS(1, &newJSVal);
2656         };
2657         ViewAbstractModel::GetInstance()->SetVisibility(
2658             static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2659     } else {
2660         ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2661     }
2662 }
2663 
JsSetFreeze(const JSCallbackInfo & info)2664 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2665 {
2666     if (info[0]->IsBoolean()) {
2667         ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2668     }
2669 }
2670 
JsFlexBasis(const JSCallbackInfo & info)2671 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2672 {
2673     CalcDimension value;
2674     if (!ParseJsDimensionVp(info[0], value)) {
2675         value.SetUnit(DimensionUnit::AUTO);
2676     }
2677     // flexbasis don't support percent case.
2678     if (value.Unit() == DimensionUnit::PERCENT) {
2679         value.SetUnit(DimensionUnit::AUTO);
2680     }
2681     ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2682 }
2683 
JsFlexGrow(const JSCallbackInfo & info)2684 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2685 {
2686     double value = 0.0;
2687     if (!ParseJsDouble(info[0], value)) {
2688         if (info[0]->IsNull() || info[0]->IsUndefined()) {
2689             // undefined use default value.
2690             value = 0.0;
2691         } else {
2692             return;
2693         }
2694     }
2695     // negative use default value.
2696     if (value < 0.0) {
2697         value = 0.0;
2698     }
2699     ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2700 }
2701 
JsFlexShrink(const JSCallbackInfo & info)2702 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2703 {
2704     double value = 0.0;
2705     if (!ParseJsDouble(info[0], value)) {
2706         if (info[0]->IsNull() || info[0]->IsUndefined()) {
2707             // undefined use default value.
2708             ViewAbstractModel::GetInstance()->ResetFlexShrink();
2709             return;
2710         } else {
2711             return;
2712         }
2713     }
2714     // negative use default value.
2715     if (value < 0.0) {
2716         ViewAbstractModel::GetInstance()->ResetFlexShrink();
2717         return;
2718     }
2719     ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2720 }
2721 
JsDisplayPriority(const JSCallbackInfo & info)2722 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2723 {
2724     double value = 0.0;
2725     if (!ParseJsDouble(info[0], value)) {
2726         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2727             ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
2728         }
2729         return;
2730     }
2731     ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2732 }
2733 
JsSharedTransition(const JSCallbackInfo & info)2734 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2735 {
2736     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2737     auto jsVal = info[0];
2738     if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
2739         return;
2740     }
2741     // id
2742     auto id = jsVal->ToString();
2743     if (id.empty()) {
2744         return;
2745     }
2746     std::shared_ptr<SharedTransitionOption> sharedOption;
2747 
2748     // options
2749     if (info.Length() > 1 && info[1]->IsObject()) {
2750         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2751         sharedOption = std::make_shared<SharedTransitionOption>();
2752         // default: duration: 1000
2753         sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2754         if (sharedOption->duration < 0) {
2755             sharedOption->duration = DEFAULT_DURATION;
2756         }
2757         // default: delay: 0
2758         sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2759         if (sharedOption->delay < 0) {
2760             sharedOption->delay = 0;
2761         }
2762         // default: LinearCurve
2763         RefPtr<Curve> curve;
2764         JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2765         if (curveArgs->IsString()) {
2766             curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2767         } else if (curveArgs->IsObject()) {
2768             JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2769             if (!curveString->IsString()) {
2770                 return;
2771             }
2772             curve = CreateCurve(curveString->ToString(), false);
2773         }
2774         if (!curve) {
2775             curve = Curves::LINEAR;
2776         }
2777         sharedOption->curve = curve;
2778         // motionPath
2779         if (jsObj->HasProperty("motionPath")) {
2780             MotionPathOption motionPathOption;
2781             if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2782                 sharedOption->motionPathOption = motionPathOption;
2783             }
2784         }
2785         // zIndex
2786         sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2787         // type
2788         int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2789             static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2790         sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2791     }
2792     ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2793 }
2794 
JsGeometryTransition(const JSCallbackInfo & info)2795 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2796 {
2797     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2798     auto jsVal = info[0];
2799     if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
2800         return;
2801     }
2802     // id
2803     auto id = jsVal->ToString();
2804     // follow flag
2805     bool followWithOutTransition = false;
2806     // hierarchy flag
2807     bool doRegisterSharedTransition = true;
2808     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
2809         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2810         ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2811 
2812         auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
2813         ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
2814         switch (transitionHierarchyStrategy) {
2815             case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
2816                 doRegisterSharedTransition = false;
2817                 break;
2818             case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
2819                 doRegisterSharedTransition = true;
2820                 break;
2821             default:
2822                 break;
2823         }
2824     }
2825     ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
2826 }
2827 
JsAlignSelf(const JSCallbackInfo & info)2828 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2829 {
2830     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2831     auto jsVal = info[0];
2832     if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
2833         ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2834         return;
2835     }
2836     auto alignVal = jsVal->ToNumber<int32_t>();
2837 
2838     if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2839         ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2840     }
2841 }
2842 
JsBackgroundColor(const JSCallbackInfo & info)2843 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2844 {
2845     Color backgroundColor;
2846     if (!ParseJsColor(info[0], backgroundColor)) {
2847         backgroundColor = Color::TRANSPARENT;
2848     }
2849 
2850     ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2851 }
2852 
JsBackgroundImage(const JSCallbackInfo & info)2853 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2854 {
2855     int32_t resId = 0;
2856     std::string src;
2857     std::string bundle;
2858     std::string module;
2859     RefPtr<PixelMap> pixmap = nullptr;
2860     auto jsBackgroundImage = info[0];
2861     GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
2862     if (jsBackgroundImage->IsString()) {
2863         src = jsBackgroundImage->ToString();
2864         ViewAbstractModel::GetInstance()->SetBackgroundImage(
2865             ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2866     } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) {
2867         ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2868     } else {
2869 #if defined(PIXEL_MAP_SUPPORTED)
2870         if (IsDrawable(jsBackgroundImage)) {
2871             pixmap = GetDrawablePixmap(jsBackgroundImage);
2872         } else {
2873             pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
2874         }
2875 #endif
2876         ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2877     }
2878 
2879     int32_t repeatIndex = 0;
2880     if (info.Length() == 2) {
2881         auto jsImageRepeat = info[1];
2882         if (jsImageRepeat->IsNumber()) {
2883             repeatIndex = jsImageRepeat->ToNumber<int32_t>();
2884         }
2885     }
2886     auto repeat = static_cast<ImageRepeat>(repeatIndex);
2887     ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2888 }
2889 
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2890 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2891 {
2892     if (jsBlurOption->GetProperty("grayscale")->IsArray()) {
2893         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsBlurOption->GetProperty("grayscale"));
2894         auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2895         auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2896         std::vector<float> greyVec(2); // 2 number
2897         greyVec[0] = grey1;
2898         greyVec[1] = grey2;
2899         blurOption.grayscale = greyVec;
2900     }
2901 }
2902 
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)2903 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
2904 {
2905     auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2906     ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2907     if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2908         colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2909         styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2910     }
2911     auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2912     ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2913     if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2914         adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2915         styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2916     }
2917 
2918     // policy
2919     auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2920     ParseJsInt32(jsOption->GetProperty("policy"), policy);
2921     if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2922         policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2923         styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2924     }
2925 
2926     // blurType
2927     auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2928     ParseJsInt32(jsOption->GetProperty("type"), blurType);
2929     if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2930         blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2931         styleOption.blurType = static_cast<BlurType>(blurType);
2932     }
2933 
2934     // inactiveColor
2935     if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor)) {
2936         styleOption.isValidColor = true;
2937     }
2938 
2939     // scale
2940     if (jsOption->GetProperty("scale")->IsNumber()) {
2941         double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2942         styleOption.scale = std::clamp(scale, 0.0, 1.0);
2943     }
2944 
2945     if (jsOption->GetProperty("blurOptions")->IsObject()) {
2946         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2947         BlurOption blurOption;
2948         ParseBlurOption(jsBlurOption, blurOption);
2949         styleOption.blurOption = blurOption;
2950     }
2951 }
2952 
JsBackgroundBlurStyle(const JSCallbackInfo & info)2953 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2954 {
2955     if (info.Length() == 0) {
2956         return;
2957     }
2958     BlurStyleOption styleOption;
2959     if (info[0]->IsNumber()) {
2960         auto blurStyle = info[0]->ToNumber<int32_t>();
2961         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2962             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2963             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2964         }
2965     }
2966     if (info.Length() > 1 && info[1]->IsObject()) {
2967         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2968         ParseBlurStyleOption(jsOption, styleOption);
2969     }
2970     ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption);
2971 }
2972 
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2973 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
2974 {
2975     double rate = 1.0f;
2976     if (jsOption->GetProperty("rate")->IsNumber()) {
2977         rate = jsOption->GetProperty("rate")->ToNumber<double>();
2978     }
2979     double lightUpDegree = 0.0f;
2980     if (jsOption->GetProperty("lightUpDegree")->IsNumber()) {
2981         lightUpDegree = jsOption->GetProperty("lightUpDegree")->ToNumber<double>();
2982     }
2983     double cubicCoeff = 0.0f;
2984     if (jsOption->GetProperty("cubicCoeff")->IsNumber()) {
2985         cubicCoeff = jsOption->GetProperty("cubicCoeff")->ToNumber<double>();
2986     }
2987     double quadCoeff = 0.0f;
2988     if (jsOption->GetProperty("quadCoeff")->IsNumber()) {
2989         quadCoeff = jsOption->GetProperty("quadCoeff")->ToNumber<double>();
2990     }
2991     double saturation = 1.0f;
2992     if (jsOption->GetProperty("saturation")->IsNumber()) {
2993         saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2994     }
2995     std::vector<float> posRGB(3, 0.0);
2996     if (jsOption->GetProperty("posRGB")->IsArray()) {
2997         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("posRGB"));
2998         auto r = params->GetValueAt(0)->ToNumber<double>();
2999         auto g = params->GetValueAt(1)->ToNumber<double>();
3000         auto b = params->GetValueAt(2)->ToNumber<double>();
3001         posRGB[0] = r;
3002         posRGB[1] = g;
3003         posRGB[2] = b;
3004     }
3005     std::vector<float> negRGB(3, 0.0);
3006     if (jsOption->GetProperty("negRGB")->IsArray()) {
3007         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("negRGB"));
3008         auto r = params->GetValueAt(0)->ToNumber<double>();
3009         auto g = params->GetValueAt(1)->ToNumber<double>();
3010         auto b = params->GetValueAt(2)->ToNumber<double>();
3011         negRGB[0] = r;
3012         negRGB[1] = g;
3013         negRGB[2] = b;
3014     }
3015     double fraction = 1.0f;
3016     if (jsOption->GetProperty("fraction")->IsNumber()) {
3017         fraction = jsOption->GetProperty("fraction")->ToNumber<double>();
3018         fraction = std::clamp(fraction, 0.0, 1.0);
3019     }
3020     brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
3021 }
3022 
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3023 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3024 {
3025     CalcDimension radius;
3026     if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
3027         radius.SetValue(0.0f);
3028     }
3029     effectOption.radius = radius;
3030 
3031     double saturation = 1.0f;
3032     if (jsOption->GetProperty("saturation")->IsNumber()) {
3033         saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
3034         saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
3035     }
3036     effectOption.saturation = saturation;
3037 
3038     double brightness = 1.0f;
3039     if (jsOption->GetProperty("brightness")->IsNumber()) {
3040         brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
3041         brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
3042     }
3043     effectOption.brightness = brightness;
3044 
3045     ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
3046 
3047     auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3048     auto adaptiveColor = AdaptiveColor::DEFAULT;
3049     ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
3050     if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3051         adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3052         adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
3053     }
3054     effectOption.adaptiveColor = adaptiveColor;
3055 
3056     // policy
3057     auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
3058     ParseJsInt32(jsOption->GetProperty("policy"), policy);
3059     if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
3060         policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3061         effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3062     }
3063 
3064     // blurType
3065     auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3066     ParseJsInt32(jsOption->GetProperty("type"), blurType);
3067     if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3068         blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3069         effectOption.blurType = static_cast<BlurType>(blurType);
3070     }
3071 
3072     // inactiveColor
3073     if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
3074         effectOption.isValidColor = true;
3075     }
3076 
3077     BlurOption blurOption;
3078     if (jsOption->GetProperty("blurOptions")->IsObject()) {
3079         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3080         ParseBlurOption(jsBlurOption, blurOption);
3081         effectOption.blurOption = blurOption;
3082     }
3083 }
3084 
JsForegroundEffect(const JSCallbackInfo & info)3085 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
3086 {
3087     if (info.Length() == 0) {
3088         return;
3089     }
3090     float radius = 0.0;
3091     if (info[0]->IsObject()) {
3092         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3093         if (jsOption->GetProperty("radius")->IsNumber()) {
3094             radius = jsOption->GetProperty("radius")->ToNumber<float>();
3095         }
3096     }
3097     radius = std::max(radius, 0.0f);
3098     ViewAbstractModel::GetInstance()->SetForegroundEffect(radius);
3099 }
3100 
JsBackgroundEffect(const JSCallbackInfo & info)3101 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
3102 {
3103     if (info.Length() == 0) {
3104         return;
3105     }
3106     EffectOption option;
3107     if (info[0]->IsObject()) {
3108         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3109         ParseEffectOption(jsOption, option);
3110     }
3111     ViewAbstractModel::GetInstance()->SetBackgroundEffect(option);
3112 }
3113 
JsForegroundBlurStyle(const JSCallbackInfo & info)3114 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
3115 {
3116     if (info.Length() == 0) {
3117         return;
3118     }
3119     BlurStyleOption styleOption;
3120     if (info[0]->IsNumber()) {
3121         auto blurStyle = info[0]->ToNumber<int32_t>();
3122         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3123             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3124             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3125         }
3126     }
3127     if (info.Length() > 1 && info[1]->IsObject()) {
3128         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3129         auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3130         ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3131         if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3132             colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3133             styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3134         }
3135         auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3136         ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3137         if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3138             adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3139             styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3140         }
3141         if (jsOption->GetProperty("scale")->IsNumber()) {
3142             double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3143             styleOption.scale = std::clamp(scale, 0.0, 1.0);
3144         }
3145 
3146         if (jsOption->GetProperty("blurOptions")->IsObject()) {
3147             JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3148             BlurOption blurOption;
3149             ParseBlurOption(jsBlurOption, blurOption);
3150             styleOption.blurOption = blurOption;
3151         }
3152     }
3153     ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption);
3154 }
3155 
JsSphericalEffect(const JSCallbackInfo & info)3156 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
3157 {
3158     auto radio = 0.0;
3159     if (info[0]->IsNumber()) {
3160         radio = info[0]->ToNumber<double>();
3161     }
3162     ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
3163 }
3164 
JsPixelStretchEffect(const JSCallbackInfo & info)3165 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
3166 {
3167     if (!info[0]->IsObject()) {
3168         PixStretchEffectOption option;
3169         option.ResetValue();
3170         ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3171         return;
3172     }
3173     auto jsObject = JSRef<JSObject>::Cast(info[0]);
3174     CalcDimension left;
3175     ParseJsDimensionVp(jsObject->GetProperty("left"), left);
3176     CalcDimension right;
3177     ParseJsDimensionVp(jsObject->GetProperty("right"), right);
3178     CalcDimension top;
3179     ParseJsDimensionVp(jsObject->GetProperty("top"), top);
3180     CalcDimension bottom;
3181     ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
3182 
3183     PixStretchEffectOption option;
3184     bool illegalInput = false;
3185     if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
3186         top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
3187         if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
3188             (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
3189             (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
3190             (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
3191             left.SetUnit(DimensionUnit::PERCENT);
3192             top.SetUnit(DimensionUnit::PERCENT);
3193             right.SetUnit(DimensionUnit::PERCENT);
3194             bottom.SetUnit(DimensionUnit::PERCENT);
3195         } else {
3196             illegalInput = true;
3197         }
3198     }
3199     if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
3200         (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
3201         option.left = left;
3202         option.top = top;
3203         option.right = right;
3204         option.bottom = bottom;
3205     } else {
3206         illegalInput = true;
3207     }
3208     if (illegalInput) {
3209         option.ResetValue();
3210     }
3211     ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3212 }
3213 
JsLightUpEffect(const JSCallbackInfo & info)3214 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
3215 {
3216     auto radio = 1.0;
3217     if (info[0]->IsNumber()) {
3218         radio = info[0]->ToNumber<double>();
3219     }
3220     ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
3221 }
3222 
JsBackgroundImageSize(const JSCallbackInfo & info)3223 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
3224 {
3225     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3226     BackgroundImageSize bgImgSize;
3227     auto jsVal = info[0];
3228     if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
3229         bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
3230         bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
3231         ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3232         return;
3233     }
3234     if (jsVal->IsNumber()) {
3235         auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
3236         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3237             (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
3238             sizeType = BackgroundImageSizeType::AUTO;
3239         }
3240         bgImgSize.SetSizeTypeX(sizeType);
3241         bgImgSize.SetSizeTypeY(sizeType);
3242     } else {
3243         CalcDimension width;
3244         CalcDimension height;
3245         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3246         ParseJsDimensionVp(object->GetProperty("width"), width);
3247         ParseJsDimensionVp(object->GetProperty("height"), height);
3248         double valueWidth = width.ConvertToPx();
3249         double valueHeight = height.ConvertToPx();
3250         BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
3251         BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
3252         if (width.Unit() == DimensionUnit::PERCENT) {
3253             typeWidth = BackgroundImageSizeType::PERCENT;
3254             valueWidth = width.Value() * FULL_DIMENSION;
3255         }
3256         if (height.Unit() == DimensionUnit::PERCENT) {
3257             typeHeight = BackgroundImageSizeType::PERCENT;
3258             valueHeight = height.Value() * FULL_DIMENSION;
3259         }
3260         bgImgSize.SetSizeTypeX(typeWidth);
3261         bgImgSize.SetSizeValueX(valueWidth);
3262         bgImgSize.SetSizeTypeY(typeHeight);
3263         bgImgSize.SetSizeValueY(valueHeight);
3264     }
3265 
3266     ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3267 }
3268 
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3269 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
3270 {
3271     if (align > 8 || align < 0) {
3272         return;
3273     }
3274     std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
3275         { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
3276         { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
3277     SetBgImgPosition(
3278                 DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
3279 }
3280 
JsBackgroundImagePosition(const JSCallbackInfo & info)3281 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
3282 {
3283     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3284     BackgroundImagePosition bgImgPosition;
3285     auto jsVal = info[0];
3286     if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
3287         SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
3288         ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3289         return;
3290     }
3291     if (jsVal->IsNumber()) {
3292         int32_t align = jsVal->ToNumber<int32_t>();
3293         bgImgPosition.SetIsAlign(true);
3294         SetBgImgPositionWithAlign(bgImgPosition, align);
3295     } else {
3296         CalcDimension x;
3297         CalcDimension y;
3298         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3299         ParseJsDimensionVp(object->GetProperty("x"), x);
3300         ParseJsDimensionVp(object->GetProperty("y"), y);
3301         double valueX = x.Value();
3302         double valueY = y.Value();
3303         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3304             valueX = x.ConvertToPx();
3305             valueY = y.ConvertToPx();
3306         }
3307         DimensionUnit typeX = DimensionUnit::PX;
3308         DimensionUnit typeY = DimensionUnit::PX;
3309         if (x.Unit() == DimensionUnit::PERCENT) {
3310             valueX = x.Value();
3311             typeX = DimensionUnit::PERCENT;
3312         }
3313         if (y.Unit() == DimensionUnit::PERCENT) {
3314             valueY = y.Value();
3315             typeY = DimensionUnit::PERCENT;
3316         }
3317         SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
3318     }
3319 
3320     ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3321 }
3322 
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)3323 std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
3324 {
3325     JSRef<JSVal> arg = info[optionIndex];
3326     if (!arg->IsArray()) {
3327         return std::vector<NG::OptionParam>();
3328     }
3329     auto paramArray = JSRef<JSArray>::Cast(arg);
3330     auto paramArrayLength = paramArray->Length();
3331     std::vector<NG::OptionParam> params(paramArrayLength);
3332     // parse paramArray
3333     for (size_t i = 0; i < paramArrayLength; ++i) {
3334         if (!paramArray->GetValueAt(i)->IsObject()) {
3335             return std::vector<NG::OptionParam>();
3336         }
3337         auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
3338         JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
3339             params[i].value);
3340         auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
3341         if (!actionFunc->IsFunction()) {
3342             return params;
3343         }
3344         auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
3345         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3346         // set onClick function
3347         params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
3348             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
3349             ACE_SCORING_EVENT("menu.action");
3350             PipelineContext::SetCallBackNode(node);
3351             if (func) {
3352                 func->Execute();
3353             }
3354         };
3355         std::string iconPath;
3356         if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
3357             params[i].icon = iconPath;
3358         }
3359         if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
3360             std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
3361             JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
3362                 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
3363             params[i].symbol = symbolApply;
3364         }
3365         auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
3366         if (enabled->IsBoolean()) {
3367             params[i].enabled = enabled->ToBoolean();
3368         }
3369     }
3370     return params;
3371 }
3372 
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3373 void ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3374 {
3375     auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
3376     NG::BorderRadiusProperty menuBorderRadius;
3377     CalcDimension borderRadius;
3378     if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) {
3379         if (borderRadius.Unit() != DimensionUnit::PERCENT && GreatOrEqual(borderRadius.Value(), 0.0f)) {
3380             menuBorderRadius.SetRadius(borderRadius);
3381             menuBorderRadius.multiValued = false;
3382             menuParam.borderRadius = menuBorderRadius;
3383         };
3384     } else if (borderRadiusValue->IsObject()) {
3385         JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
3386         CalcDimension topLeft;
3387         CalcDimension topRight;
3388         CalcDimension bottomLeft;
3389         CalcDimension bottomRight;
3390         bool hasSetBorderRadius =
3391             JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
3392         if (LessNotEqual(topLeft.Value(), 0.0f)) {
3393             topLeft.Reset();
3394         }
3395         if (LessNotEqual(topRight.Value(), 0.0f)) {
3396             topRight.Reset();
3397         }
3398         if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
3399             bottomLeft.Reset();
3400         }
3401         if (LessNotEqual(bottomRight.Value(), 0.0f)) {
3402             bottomRight.Reset();
3403         }
3404         auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
3405         menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
3406         menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight;
3407         menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
3408         menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
3409         menuBorderRadius.multiValued = true;
3410         menuParam.borderRadius = menuBorderRadius;
3411     }
3412 }
3413 
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3414 void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3415 {
3416     auto enableArrowValue = menuOptions->GetProperty("enableArrow");
3417     if (enableArrowValue->IsBoolean()) {
3418         menuParam.enableArrow = enableArrowValue->ToBoolean();
3419     }
3420 
3421     auto arrowOffset = menuOptions->GetProperty("arrowOffset");
3422     CalcDimension offset;
3423     if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
3424         menuParam.arrowOffset = offset;
3425     }
3426 
3427     // if enableArrow is true and placement not set, set placement default value to top.
3428     if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
3429         menuParam.placement = Placement::TOP;
3430     }
3431 }
3432 
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)3433 void ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
3434 {
3435     CalcDimension dimension;
3436     if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
3437         return;
3438     }
3439 
3440     if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
3441         calcDimension = dimension;
3442     }
3443 }
3444 
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3445 void ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3446 {
3447     auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
3448     if (!marginVal->IsObject()) {
3449         return;
3450     }
3451 
3452     CommonCalcDimension commonCalcDimension;
3453     auto object = JSRef<JSObject>::Cast(marginVal);
3454     ParseLayoutRegionMargin(object->GetProperty(TOP_PROPERTY), commonCalcDimension.top);
3455     ParseLayoutRegionMargin(object->GetProperty(BOTTOM_PROPERTY), commonCalcDimension.bottom);
3456     ParseLayoutRegionMargin(object->GetProperty(LEFT_PROPERTY), commonCalcDimension.left);
3457     ParseLayoutRegionMargin(object->GetProperty(RIGHT_PROPERTY), commonCalcDimension.right);
3458 
3459     if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3460         commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3461         menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
3462             commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3463     }
3464 }
3465 
GetMenuShowInSubwindow(NG::MenuParam & menuParam)3466 void GetMenuShowInSubwindow(NG::MenuParam& menuParam)
3467 {
3468     menuParam.isShowInSubWindow = false;
3469     auto pipeline = PipelineBase::GetCurrentContext();
3470     CHECK_NULL_VOID(pipeline);
3471     auto theme = pipeline->GetTheme<SelectTheme>();
3472     CHECK_NULL_VOID(theme);
3473     menuParam.isShowInSubWindow = theme->GetExpandDisplay();
3474 }
3475 
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3476 void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3477 {
3478     auto offsetVal = menuOptions->GetProperty("offset");
3479     if (offsetVal->IsObject()) {
3480         auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
3481         JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
3482         JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
3483         CalcDimension dx;
3484         CalcDimension dy;
3485         if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
3486             menuParam.positionOffset.SetX(dx.ConvertToPx());
3487         }
3488         if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
3489             menuParam.positionOffset.SetY(dy.ConvertToPx());
3490         }
3491     }
3492 
3493     auto placementValue = menuOptions->GetProperty("placement");
3494     if (placementValue->IsNumber()) {
3495         auto placement = placementValue->ToNumber<int32_t>();
3496         if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
3497             menuParam.placement = PLACEMENT[placement];
3498         }
3499     }
3500 
3501     auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
3502     Color backgroundColor;
3503     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
3504         menuParam.backgroundColor = backgroundColor;
3505     }
3506 
3507     auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
3508     if (backgroundBlurStyle->IsNumber()) {
3509         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
3510         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3511             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3512             menuParam.backgroundBlurStyle = blurStyle;
3513         }
3514     }
3515     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3516     auto onAppearValue = menuOptions->GetProperty("onAppear");
3517     if (onAppearValue->IsFunction()) {
3518         RefPtr<JsFunction> jsOnAppearFunc =
3519             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
3520         auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
3521             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3522             ACE_SCORING_EVENT("onAppear");
3523             PipelineContext::SetCallBackNode(node);
3524             func->Execute();
3525         };
3526         menuParam.onAppear = std::move(onAppear);
3527     }
3528 
3529     auto onDisappearValue = menuOptions->GetProperty("onDisappear");
3530     if (onDisappearValue->IsFunction()) {
3531         RefPtr<JsFunction> jsOnDisAppearFunc =
3532             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
3533         auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
3534                                node = frameNode]() {
3535             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3536             ACE_SCORING_EVENT("onDisappear");
3537             PipelineContext::SetCallBackNode(node);
3538             func->Execute();
3539         };
3540         menuParam.onDisappear = std::move(onDisappear);
3541     }
3542     auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
3543     if (aboutToAppearValue->IsFunction()) {
3544         RefPtr<JsFunction> jsAboutToAppearFunc =
3545             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
3546         auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
3547                             node = frameNode]() {
3548             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3549             ACE_SCORING_EVENT("aboutToAppear");
3550             PipelineContext::SetCallBackNode(node);
3551             func->Execute();
3552         };
3553         menuParam.aboutToAppear = std::move(aboutToAppear);
3554     }
3555 
3556     auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
3557     if (aboutToDisAppearValue->IsFunction()) {
3558         RefPtr<JsFunction> jsAboutToDisAppearFunc =
3559             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
3560         auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
3561                                node = frameNode]() {
3562             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3563             ACE_SCORING_EVENT("aboutToDisappear");
3564             PipelineContext::SetCallBackNode(node);
3565             func->Execute();
3566         };
3567         menuParam.aboutToDisappear = std::move(aboutToDisappear);
3568     }
3569 
3570     auto menuTransition = menuOptions->GetProperty("transition");
3571     menuParam.hasTransitionEffect = false;
3572     if (menuTransition->IsObject()) {
3573         auto obj = JSRef<JSObject>::Cast(menuTransition);
3574         menuParam.hasTransitionEffect = true;
3575         menuParam.transition = ParseChainedTransition(obj, info.GetExecutionContext());
3576     }
3577 
3578     JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
3579     GetMenuShowInSubwindow(menuParam);
3580     if (menuParam.isShowInSubWindow) {
3581         if (showInSubWindowValue->IsBoolean()) {
3582             menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
3583         }
3584     }
3585     ParseMenuArrowParam(menuOptions, menuParam);
3586     ParseMenuBorderRadius(menuOptions, menuParam);
3587     ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
3588 }
3589 
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)3590 void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
3591 {
3592     if (!info[optionIndex]->IsObject()) {
3593         return;
3594     }
3595     auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
3596     JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
3597     ParseMenuParam(info, menuOptions, menuParam);
3598 }
3599 
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)3600 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
3601 {
3602     constexpr int scaleArraySize = 2;
3603     if (scaleArray->Length() == scaleArraySize) {
3604         auto scalePropertyFrom = scaleArray->GetValueAt(0);
3605         if (scalePropertyFrom->IsNumber()) {
3606             auto scaleFrom = scalePropertyFrom->ToNumber<float>();
3607             options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
3608         }
3609         auto scalePropertyTo = scaleArray->GetValueAt(1);
3610         if (scalePropertyTo->IsNumber()) {
3611             auto scaleTo = scalePropertyTo->ToNumber<float>();
3612             options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
3613         }
3614     }
3615 }
3616 
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)3617 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
3618     NG::MenuParam& menuParam)
3619 {
3620     menuParam.previewAnimationOptions.scaleFrom = -1.0f;
3621     menuParam.previewAnimationOptions.scaleTo = -1.0f;
3622 
3623     auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
3624     if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
3625         auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
3626         auto scaleProperty = animationOptionsObj->GetProperty("scale");
3627         if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
3628             JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
3629             ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
3630         }
3631         auto previewTransition = animationOptionsObj->GetProperty("transition");
3632         menuParam.hasPreviewTransitionEffect = false;
3633         if (previewTransition->IsObject()) {
3634             auto obj = JSRef<JSObject>::Cast(previewTransition);
3635             menuParam.hasPreviewTransitionEffect = true;
3636             menuParam.previewTransition = ParseChainedTransition(obj, info.GetExecutionContext());
3637         }
3638         if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
3639             menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect ||
3640             menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
3641             return;
3642         }
3643         auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
3644         menuParam.isShowHoverImage = false;
3645         menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
3646         menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
3647         if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
3648             JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
3649             ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
3650             menuParam.isShowHoverImage = true;
3651         }
3652     }
3653 }
3654 
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)3655 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
3656     std::function<void()>& previewBuildFunc)
3657 {
3658     if (!args->IsObject()) {
3659         return;
3660     }
3661     auto menuContentOptions = JSRef<JSObject>::Cast(args);
3662     ParseMenuParam(info, menuContentOptions, menuParam);
3663     RefPtr<JsFunction> previewBuilderFunc;
3664     auto preview = menuContentOptions->GetProperty("preview");
3665     if (!preview->IsFunction() && !preview->IsNumber()) {
3666         return;
3667     }
3668 
3669     if (preview->IsNumber()) {
3670         if (preview->ToNumber<int32_t>() == 1) {
3671             menuParam.previewMode = MenuPreviewMode::IMAGE;
3672             ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3673         }
3674     } else {
3675         previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
3676         CHECK_NULL_VOID(previewBuilderFunc);
3677         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3678         previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
3679                                node = frameNode]() {
3680             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3681             ACE_SCORING_EVENT("BuildContextMenuPreviwer");
3682             PipelineContext::SetCallBackNode(node);
3683             func->Execute();
3684         };
3685         menuParam.previewMode = MenuPreviewMode::CUSTOM;
3686         ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3687     }
3688 }
3689 
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)3690 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
3691 {
3692     size_t builderIndex = 0;
3693     if (info[0]->IsBoolean()) {
3694         menuParam.isShow = info[0]->ToBoolean();
3695         menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3696         menuParam.placement = Placement::BOTTOM_LEFT;
3697         builderIndex = 1;
3698     } else if (info[0]->IsObject()) {
3699         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
3700         menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3701         auto isShowObj = callbackObj->GetProperty("value");
3702         if (isShowObj->IsBoolean()) {
3703             menuParam.isShow = isShowObj->IsBoolean();
3704             menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3705             builderIndex = 1;
3706         }
3707     }
3708     return builderIndex;
3709 }
3710 
JsBindMenu(const JSCallbackInfo & info)3711 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
3712 {
3713     NG::MenuParam menuParam;
3714     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
3715         menuParam.placement = Placement::BOTTOM_LEFT;
3716     }
3717     size_t builderIndex = 0;
3718     GetMenuShowInSubwindow(menuParam);
3719     if (info.Length() > PARAMETER_LENGTH_FIRST) {
3720         auto jsVal = info[0];
3721         if (jsVal->IsBoolean()) {
3722             menuParam.isShow = jsVal->ToBoolean();
3723             menuParam.setShow = true;
3724             builderIndex = 1;
3725             if (info.Length() > PARAMETER_LENGTH_SECOND) {
3726                 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3727             }
3728         } else if (jsVal->IsUndefined()) {
3729             menuParam.setShow = true;
3730             menuParam.isShow = false;
3731             builderIndex = 1;
3732             if (info.Length() > PARAMETER_LENGTH_SECOND) {
3733                 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3734             }
3735         } else if (jsVal->IsObject()) {
3736             JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
3737             menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3738             auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
3739             if (isShowObj->IsBoolean()) {
3740                 menuParam.isShow = isShowObj->ToBoolean();
3741                 menuParam.setShow = true;
3742                 builderIndex = 1;
3743                 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3744                     ParseBindOptionParam(info, menuParam, builderIndex + 1);
3745                 }
3746             } else {
3747                 builderIndex = 0;
3748                 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3749             }
3750         }
3751     }
3752 
3753     if (info[builderIndex]->IsArray()) {
3754         std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info, builderIndex);
3755         ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
3756     } else if (info[builderIndex]->IsObject()) {
3757         // CustomBuilder
3758         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
3759         auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
3760         if (!builder->IsFunction()) {
3761             return;
3762         }
3763         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
3764 
3765         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3766         CHECK_NULL_VOID(builderFunc);
3767         auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
3768             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3769             ACE_SCORING_EVENT("BuildMenu");
3770             auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3771             func->Execute();
3772         };
3773         ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
3774     }
3775 }
3776 
JsPadding(const JSCallbackInfo & info)3777 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
3778 {
3779     ParseMarginOrPadding(info, EdgeType::PADDING);
3780 }
3781 
JsMargin(const JSCallbackInfo & info)3782 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
3783 {
3784     ParseMarginOrPadding(info, EdgeType::MARGIN);
3785 }
3786 
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)3787 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
3788 {
3789     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3790         JSCallbackInfoType::NUMBER };
3791     auto jsVal = info[0];
3792     if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
3793         auto resetDimension = CalcDimension(0.0);
3794         if (type == EdgeType::MARGIN) {
3795             ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
3796         } else if (type == EdgeType::PADDING) {
3797             ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
3798         } else if (type == EdgeType::SAFE_AREA_PADDING) {
3799             ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
3800         }
3801         return;
3802     }
3803 
3804     if (jsVal->IsObject()) {
3805         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
3806 
3807         CalcDimension length;
3808         if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
3809             ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
3810             return;
3811         }
3812 
3813         CommonCalcDimension commonCalcDimension;
3814         auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
3815         if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3816             commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3817             if (type == EdgeType::MARGIN)  {
3818                 if (useLengthMetrics) {
3819                     ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
3820                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3821                 } else {
3822                     ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
3823                         commonCalcDimension.left, commonCalcDimension.right);
3824                 }
3825             } else if (type == EdgeType::PADDING) {
3826                 if (useLengthMetrics) {
3827                     ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
3828                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3829                 } else {
3830                     ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
3831                         commonCalcDimension.left, commonCalcDimension.right);
3832                 }
3833             } else if (type == EdgeType::SAFE_AREA_PADDING) {
3834                 if (useLengthMetrics) {
3835                     ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
3836                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3837                 } else {
3838                     ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
3839                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3840                 }
3841             }
3842             return;
3843         }
3844     }
3845 
3846     CalcDimension length;
3847     if (!ParseJsDimensionVp(jsVal, length)) {
3848         // use default value.
3849         length.Reset();
3850     }
3851     if (type == EdgeType::MARGIN) {
3852         ViewAbstractModel::GetInstance()->SetMargin(length);
3853     } else if (type == EdgeType::PADDING) {
3854         ViewAbstractModel::GetInstance()->SetPadding(length);
3855     }
3856 }
3857 
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)3858 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
3859     const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
3860     const std::optional<CalcDimension>& end)
3861 {
3862     NG::PaddingProperty paddings;
3863     if (start.has_value()) {
3864         if (start.value().Unit() == DimensionUnit::CALC) {
3865             paddings.start = NG::CalcLength(start.value().CalcValue());
3866         } else {
3867             paddings.start = NG::CalcLength(start.value());
3868         }
3869     }
3870     if (bottom.has_value()) {
3871         if (bottom.value().Unit() == DimensionUnit::CALC) {
3872             paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
3873         } else {
3874             paddings.bottom = NG::CalcLength(bottom.value());
3875         }
3876     }
3877     if (end.has_value()) {
3878         if (end.value().Unit() == DimensionUnit::CALC) {
3879             paddings.end = NG::CalcLength(end.value().CalcValue());
3880         } else {
3881             paddings.end = NG::CalcLength(end.value());
3882         }
3883     }
3884     if (top.has_value()) {
3885         if (top.value().Unit() == DimensionUnit::CALC) {
3886             paddings.top = NG::CalcLength(top.value().CalcValue());
3887         } else {
3888             paddings.top = NG::CalcLength(top.value());
3889         }
3890     }
3891     return paddings;
3892 }
3893 
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)3894 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
3895     std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
3896 {
3897     CalcDimension leftDimen;
3898     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
3899         left = leftDimen;
3900     }
3901     CalcDimension rightDimen;
3902     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
3903         right = rightDimen;
3904     }
3905     CalcDimension topDimen;
3906     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
3907         top = topDimen;
3908     }
3909     CalcDimension bottomDimen;
3910     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
3911         bottom = bottomDimen;
3912     }
3913 }
3914 
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3915 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
3916     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3917 {
3918     auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
3919     if (jsStart->IsObject()) {
3920         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
3921         CalcDimension calcDimension;
3922         if (ParseJsLengthMetrics(startObj, calcDimension)) {
3923             localizedCalcDimension.start = calcDimension;
3924         }
3925     }
3926     auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
3927     if (jsEnd->IsObject()) {
3928         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
3929         CalcDimension calcDimension;
3930         if (ParseJsLengthMetrics(endObj, calcDimension)) {
3931             localizedCalcDimension.end = calcDimension;
3932         }
3933     }
3934     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3935     if (jsTop->IsObject()) {
3936         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
3937         CalcDimension calcDimension;
3938         if (ParseJsLengthMetrics(topObj, calcDimension)) {
3939             localizedCalcDimension.top = calcDimension;
3940         }
3941     }
3942     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3943     if (jsBottom->IsObject()) {
3944         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
3945         CalcDimension calcDimension;
3946         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
3947             localizedCalcDimension.bottom = calcDimension;
3948         }
3949     }
3950 }
3951 
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3952 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
3953     const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
3954 {
3955     if (CheckLengthMetrics(object)) {
3956         LocalizedCalcDimension localizedCalcDimension;
3957         ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
3958         commonCalcDimension.top = localizedCalcDimension.top;
3959         commonCalcDimension.bottom = localizedCalcDimension.bottom;
3960         commonCalcDimension.left = localizedCalcDimension.start;
3961         commonCalcDimension.right = localizedCalcDimension.end;
3962         return true;
3963     }
3964     ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
3965         commonCalcDimension.right);
3966     return false;
3967 }
3968 
JsOutline(const JSCallbackInfo & info)3969 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
3970 {
3971     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3972     auto jsVal = info[0];
3973     if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
3974         CalcDimension borderWidth;
3975         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3976         ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3977         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
3978         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3979         return;
3980     }
3981     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3982     auto valueOuterWidth = object->GetProperty("width");
3983     if (!valueOuterWidth->IsUndefined()) {
3984         ParseOuterBorderWidth(valueOuterWidth);
3985     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3986         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3987     }
3988 
3989     // use default value when undefined.
3990     ParseOuterBorderColor(object->GetProperty("color"));
3991 
3992     auto valueOuterRadius = object->GetProperty("radius");
3993     if (!valueOuterRadius->IsUndefined()) {
3994         ParseOuterBorderRadius(valueOuterRadius);
3995     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3996         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3997     }
3998     // use default value when undefined.
3999     ParseOuterBorderStyle(object->GetProperty("style"));
4000     info.ReturnSelf();
4001 }
4002 
JsOutlineWidth(const JSCallbackInfo & info)4003 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
4004 {
4005     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4006         JSCallbackInfoType::OBJECT };
4007     auto jsVal = info[0];
4008     if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
4009         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
4010         return;
4011     }
4012     ParseOuterBorderWidth(jsVal);
4013 }
4014 
JsOutlineColor(const JSCallbackInfo & info)4015 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
4016 {
4017     ParseOuterBorderColor(info[0]);
4018 }
4019 
JsOutlineRadius(const JSCallbackInfo & info)4020 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
4021 {
4022     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4023         JSCallbackInfoType::OBJECT };
4024     auto jsVal = info[0];
4025     if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
4026         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
4027         return;
4028     }
4029     ParseOuterBorderRadius(jsVal);
4030 }
4031 
JsOutlineStyle(const JSCallbackInfo & info)4032 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
4033 {
4034     ParseOuterBorderStyle(info[0]);
4035 }
4036 
JsBorder(const JSCallbackInfo & info)4037 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
4038 {
4039     if (!info[0]->IsObject()) {
4040         CalcDimension borderWidth;
4041         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4042         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4043         ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
4044         ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4045         ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
4046         ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
4047         return;
4048     }
4049     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
4050 
4051     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4052     if (!valueWidth->IsUndefined()) {
4053         ParseBorderWidth(valueWidth);
4054     }
4055 
4056     // use default value when undefined.
4057     ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
4058 
4059     auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
4060     if (!valueRadius->IsUndefined()) {
4061         ParseBorderRadius(valueRadius);
4062     }
4063     // use default value when undefined.
4064     ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
4065 
4066     auto dashGap = object->GetProperty("dashGap");
4067     if (!dashGap->IsUndefined()) {
4068         ParseDashGap(dashGap);
4069     }
4070     auto dashWidth = object->GetProperty("dashWidth");
4071     if (!dashWidth->IsUndefined()) {
4072         ParseDashWidth(dashWidth);
4073     }
4074 
4075     info.ReturnSelf();
4076 }
4077 
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)4078 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
4079 {
4080     if (!args->IsObject()) {
4081         return false;
4082     }
4083     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4084     if (obj->IsUndefined()) {
4085         return true;
4086     }
4087     // filter dynamic $r raw input
4088     if (obj->HasProperty("id")) {
4089         return false;
4090     }
4091     if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
4092         (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
4093         (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
4094         (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
4095         (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
4096         (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
4097         return true;
4098     }
4099 
4100     return false;
4101 }
4102 
JsBorderWidth(const JSCallbackInfo & info)4103 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
4104 {
4105     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4106         JSCallbackInfoType::OBJECT };
4107     auto jsVal = info[0];
4108     if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
4109         ViewAbstractModel::GetInstance()->SetBorderWidth({});
4110         return;
4111     }
4112     ParseBorderWidth(jsVal);
4113 }
4114 
ParseBorderWidth(const JSRef<JSVal> & args)4115 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
4116 {
4117     CalcDimension borderWidth;
4118     if (ParseJsDimensionVp(args, borderWidth)) {
4119         if (borderWidth.IsNegative()) {
4120             borderWidth.Reset();
4121         }
4122         if (borderWidth.Unit() == DimensionUnit::PERCENT) {
4123             borderWidth.Reset();
4124         }
4125         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4126     } else if (args->IsObject()) {
4127         if (IsBorderWidthObjUndefined(args)) {
4128             ViewAbstractModel::GetInstance()->SetBorderWidth({});
4129             return;
4130         }
4131         CommonCalcDimension commonCalcDimension;
4132         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4133         if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
4134             ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
4135                 commonCalcDimension.top, commonCalcDimension.bottom, true);
4136             return;
4137         }
4138         ViewAbstractModel::GetInstance()->SetBorderWidth(
4139             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4140     } else {
4141         return;
4142     }
4143 }
4144 
ParseDashGap(const JSRef<JSVal> & args)4145 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
4146 {
4147     CalcDimension dashGap;
4148     if (ParseLengthMetricsToDimension(args, dashGap)) {
4149         if (dashGap.Unit() == DimensionUnit::PERCENT) {
4150             dashGap.Reset();
4151         }
4152         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4153     } else if (args->IsObject()) {
4154         CommonCalcDimension commonCalcDimension;
4155         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4156         ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4157         ViewAbstractModel::GetInstance()->SetDashGap(
4158             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4159     } else {
4160         dashGap.Reset();
4161         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4162     }
4163 }
4164 
ParseDashWidth(const JSRef<JSVal> & args)4165 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
4166 {
4167     CalcDimension dashWidth;
4168     if (ParseLengthMetricsToDimension(args, dashWidth)) {
4169         if (dashWidth.Unit() == DimensionUnit::PERCENT) {
4170             dashWidth.Reset();
4171         }
4172         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4173     } else if (args->IsObject()) {
4174         CommonCalcDimension commonCalcDimension;
4175         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4176         ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4177         ViewAbstractModel::GetInstance()->SetDashWidth(
4178             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4179     } else {
4180         dashWidth.Reset();
4181         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4182     }
4183 }
4184 
ParseOuterBorderWidth(const JSRef<JSVal> & args)4185 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
4186 {
4187     CalcDimension borderWidth;
4188     if (ParseJsDimensionVp(args, borderWidth)) {
4189         if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4190             borderWidth.Reset();
4191         }
4192         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4193     } else if (args->IsObject()) {
4194         std::optional<CalcDimension> leftDimen;
4195         std::optional<CalcDimension> rightDimen;
4196         std::optional<CalcDimension> topDimen;
4197         std::optional<CalcDimension> bottomDimen;
4198         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4199         CalcDimension left;
4200         if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
4201             if (left.Unit() == DimensionUnit::PERCENT) {
4202                 left.Reset();
4203             }
4204             leftDimen = left;
4205         }
4206         CalcDimension right;
4207         if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
4208             if (right.Unit() == DimensionUnit::PERCENT) {
4209                 right.Reset();
4210             }
4211             rightDimen = right;
4212         }
4213         CalcDimension top;
4214         if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
4215             if (top.Unit() == DimensionUnit::PERCENT) {
4216                 top.Reset();
4217             }
4218             topDimen = top;
4219         }
4220         CalcDimension bottom;
4221         if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
4222             if (bottom.Unit() == DimensionUnit::PERCENT) {
4223                 bottom.Reset();
4224             }
4225             bottomDimen = bottom;
4226         }
4227         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
4228     } else {
4229         return;
4230     }
4231 }
4232 
JsBorderImage(const JSCallbackInfo & info)4233 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
4234 {
4235     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4236     auto jsVal = info[0];
4237     if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
4238         RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4239         uint8_t imageBorderBitsets = 0;
4240         ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4241         return;
4242     }
4243     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4244     CHECK_NULL_VOID(!object->IsEmpty());
4245 
4246     RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4247     uint8_t imageBorderBitsets = 0;
4248 
4249     auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
4250     CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
4251     std::string srcResult;
4252     std::string bundleName;
4253     std::string moduleName;
4254     GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
4255     borderImage->SetBundleName(bundleName);
4256     borderImage->SetModuleName(moduleName);
4257     if (valueSource->IsString() && !valueSource->ToString().empty()) {
4258         borderImage->SetSrc(valueSource->ToString());
4259         imageBorderBitsets |= BorderImage::SOURCE_BIT;
4260     } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
4261         borderImage->SetSrc(srcResult);
4262         imageBorderBitsets |= BorderImage::SOURCE_BIT;
4263     } else if (valueSource->IsObject()) {
4264         ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
4265     }
4266     auto valueOutset = object->GetProperty("outset");
4267     if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
4268         imageBorderBitsets |= BorderImage::OUTSET_BIT;
4269         ParseBorderImageOutset(valueOutset, borderImage);
4270     }
4271     auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
4272     if (!valueRepeat->IsNull()) {
4273         imageBorderBitsets |= BorderImage::REPEAT_BIT;
4274         ParseBorderImageRepeat(valueRepeat, borderImage);
4275     }
4276     auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
4277     if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
4278         imageBorderBitsets |= BorderImage::SLICE_BIT;
4279         ParseBorderImageSlice(valueSlice, borderImage);
4280     }
4281     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4282     if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
4283         imageBorderBitsets |= BorderImage::WIDTH_BIT;
4284         ParseBorderImageWidth(valueWidth, borderImage);
4285     }
4286     auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
4287     if (needFill->IsBoolean()) {
4288         borderImage->SetNeedFillCenter(needFill->ToBoolean());
4289     }
4290     ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4291     info.ReturnSelf();
4292 }
4293 
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4294 bool JSViewAbstract::ParseBorderImageDimension(
4295     const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
4296 {
4297     if (!args->IsObject()) {
4298         return false;
4299     }
4300     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4301     if (CheckLengthMetrics(object)) {
4302         LocalizedCalcDimension localizedCalcDimension;
4303         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4304         borderImageDimension.topDimension = localizedCalcDimension.top;
4305         borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
4306         borderImageDimension.startDimension = localizedCalcDimension.start;
4307         borderImageDimension.endDimension = localizedCalcDimension.end;
4308         return true;
4309     }
4310     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4311         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4312         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4313     for (uint32_t i = 0; i < keys.size(); i++) {
4314         CalcDimension currentDimension;
4315         auto dimensionValue = object->GetProperty(keys.at(i));
4316         if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
4317             auto direction = static_cast<BorderImageDirection>(i);
4318             switch (direction) {
4319                 case BorderImageDirection::LEFT:
4320                     borderImageDimension.leftDimension = currentDimension;
4321                     break;
4322                 case BorderImageDirection::RIGHT:
4323                     borderImageDimension.rightDimension = currentDimension;
4324                     break;
4325                 case BorderImageDirection::TOP:
4326                     borderImageDimension.topDimension = currentDimension;
4327                     break;
4328                 case BorderImageDirection::BOTTOM:
4329                     borderImageDimension.bottomDimension = currentDimension;
4330                     break;
4331                 default:
4332                     break;
4333             }
4334         }
4335     }
4336     return false;
4337 }
4338 
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4339 void JSViewAbstract::ParseBorderImageLengthMetrics(
4340     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4341 {
4342     for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
4343         auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
4344         if (!jsVal->IsObject()) {
4345             continue;
4346         }
4347         JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
4348         CalcDimension calcDimension;
4349         if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
4350             auto direction = static_cast<BorderImageDirection>(i);
4351             switch (direction) {
4352                 case BorderImageDirection::LEFT:
4353                     localizedCalcDimension.start = calcDimension;
4354                     break;
4355                 case BorderImageDirection::RIGHT:
4356                     localizedCalcDimension.end = calcDimension;
4357                     break;
4358                 case BorderImageDirection::TOP:
4359                     localizedCalcDimension.top = calcDimension;
4360                     break;
4361                 case BorderImageDirection::BOTTOM:
4362                     localizedCalcDimension.bottom = calcDimension;
4363                     break;
4364                 default:
4365                     break;
4366             }
4367         }
4368     }
4369 }
4370 
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4371 bool JSViewAbstract::CheckJSCallbackInfo(
4372     const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
4373 {
4374     bool typeVerified = false;
4375     std::string unrecognizedType;
4376     for (const auto& infoType : infoTypes) {
4377         switch (infoType) {
4378             case JSCallbackInfoType::STRING:
4379                 if (tmpInfo->IsString()) {
4380                     typeVerified = true;
4381                 } else {
4382                     unrecognizedType += "string|";
4383                 }
4384                 break;
4385             case JSCallbackInfoType::NUMBER:
4386                 if (tmpInfo->IsNumber()) {
4387                     typeVerified = true;
4388                 } else {
4389                     unrecognizedType += "number|";
4390                 }
4391                 break;
4392             case JSCallbackInfoType::OBJECT:
4393                 if (tmpInfo->IsObject()) {
4394                     typeVerified = true;
4395                 } else {
4396                     unrecognizedType += "object|";
4397                 }
4398                 break;
4399             case JSCallbackInfoType::FUNCTION:
4400                 if (tmpInfo->IsFunction()) {
4401                     typeVerified = true;
4402                 } else {
4403                     unrecognizedType += "Function|";
4404                 }
4405                 break;
4406             default:
4407                 break;
4408         }
4409     }
4410     if (!typeVerified) {
4411         LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
4412             unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
4413     }
4414     return typeVerified || infoTypes.size() == 0;
4415 }
4416 
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4417 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
4418 {
4419     switch (direction) {
4420         case NG::GradientDirection::LEFT:
4421             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4422             break;
4423         case NG::GradientDirection::RIGHT:
4424             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4425             break;
4426         case NG::GradientDirection::TOP:
4427             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4428             break;
4429         case NG::GradientDirection::BOTTOM:
4430             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4431             break;
4432         case NG::GradientDirection::LEFT_TOP:
4433             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4434             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4435             break;
4436         case NG::GradientDirection::LEFT_BOTTOM:
4437             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4438             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4439             break;
4440         case NG::GradientDirection::RIGHT_TOP:
4441             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4442             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4443             break;
4444         case NG::GradientDirection::RIGHT_BOTTOM:
4445             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4446             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4447             break;
4448         case NG::GradientDirection::NONE:
4449         case NG::GradientDirection::START_TO_END:
4450         case NG::GradientDirection::END_TO_START:
4451         default:
4452             break;
4453     }
4454 }
4455 
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)4456 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
4457 {
4458     if (!args->IsObject()) {
4459         return;
4460     }
4461     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
4462     NG::Gradient lineGradient;
4463     lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
4464     // angle
4465     std::optional<float> degree;
4466     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4467         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
4468     } else {
4469         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
4470     }
4471     if (degree) {
4472         lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
4473         degree.reset();
4474     }
4475     // direction
4476     auto direction = static_cast<NG::GradientDirection>(
4477         jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
4478         static_cast<int32_t>(NG::GradientDirection::NONE)));
4479     UpdateGradientWithDirection(lineGradient, direction);
4480     auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
4481     lineGradient.SetRepeat(repeating);
4482     NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
4483     ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
4484     bitset |= BorderImage::GRADIENT_BIT;
4485 }
4486 
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4487 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4488 {
4489     auto repeatString = args->ToString();
4490     if (repeatString == "Repeat") {
4491         borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
4492     } else if (repeatString == "Round") {
4493         borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
4494     } else if (repeatString == "Space") {
4495         borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
4496     } else {
4497         borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
4498     }
4499 }
4500 
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4501 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4502 {
4503     CalcDimension outsetDimension;
4504     if (ParseJsDimensionVp(args, outsetDimension)) {
4505         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
4506         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
4507         borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
4508         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
4509         return;
4510     }
4511     BorderImage::BorderImageOption option;
4512     ParseBorderImageDimension(args, option);
4513     if (option.startDimension.has_value()) {
4514         borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
4515     }
4516     if (option.endDimension.has_value()) {
4517         borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
4518     }
4519     if (option.leftDimension.has_value()) {
4520         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
4521     }
4522     if (option.rightDimension.has_value()) {
4523         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
4524     }
4525     if (option.topDimension.has_value()) {
4526         borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
4527     }
4528     if (option.bottomDimension.has_value()) {
4529         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4530     }
4531 }
4532 
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4533 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4534 {
4535     CalcDimension sliceDimension;
4536     if (ParseJsDimensionVp(args, sliceDimension)) {
4537         borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
4538         borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
4539         borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
4540         borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
4541         return;
4542     }
4543     if (!args->IsObject()) {
4544         return;
4545     }
4546     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4547     if (CheckLengthMetrics(object)) {
4548         LocalizedCalcDimension localizedCalcDimension;
4549         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4550         if (localizedCalcDimension.top.has_value()) {
4551             borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
4552         }
4553         if (localizedCalcDimension.bottom.has_value()) {
4554             borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
4555         }
4556         if (localizedCalcDimension.start.has_value()) {
4557             borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
4558         }
4559         if (localizedCalcDimension.end.has_value()) {
4560             borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
4561         }
4562         return;
4563     }
4564     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4565         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4566         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4567     for (uint32_t i = 0; i < keys.size(); i++) {
4568         auto dimensionValue = object->GetProperty(keys.at(i));
4569         if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
4570             borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
4571         }
4572     }
4573 }
4574 
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4575 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4576 {
4577     CalcDimension widthDimension;
4578     if (ParseJsDimensionVp(args, widthDimension)) {
4579         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
4580         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
4581         borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
4582         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
4583         return;
4584     }
4585 
4586     BorderImage::BorderImageOption option;
4587     ParseBorderImageDimension(args, option);
4588     if (option.startDimension.has_value()) {
4589         borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
4590     }
4591     if (option.endDimension.has_value()) {
4592         borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
4593     }
4594     if (option.leftDimension.has_value()) {
4595         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
4596     }
4597     if (option.rightDimension.has_value()) {
4598         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
4599     }
4600     if (option.topDimension.has_value()) {
4601         borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
4602     }
4603     if (option.bottomDimension.has_value()) {
4604         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4605     }
4606 }
4607 
JsBorderColor(const JSCallbackInfo & info)4608 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
4609 {
4610     ParseBorderColor(info[0]);
4611 }
4612 
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)4613 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
4614     const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
4615     const std::optional<Color>& colorBottom)
4616 {
4617     NG::BorderColorProperty borderColors;
4618     borderColors.startColor = colorStart;
4619     borderColors.endColor = colorEnd;
4620     borderColors.topColor = colorTop;
4621     borderColors.bottomColor = colorBottom;
4622     borderColors.multiValued = true;
4623     return borderColors;
4624 }
4625 
ParseBorderColor(const JSRef<JSVal> & args)4626 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
4627 {
4628     Color borderColor;
4629     if (ParseJsColor(args, borderColor)) {
4630         ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
4631     } else if (args->IsObject()) {
4632         CommonColor commonColor;
4633         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4634         if (ParseCommonEdgeColors(object, commonColor)) {
4635             ViewAbstractModel::GetInstance()->SetBorderColor(
4636                 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4637             return;
4638         }
4639         ViewAbstractModel::GetInstance()->SetBorderColor(
4640             commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4641     } else {
4642         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4643     }
4644 }
4645 
ParseOuterBorderColor(const JSRef<JSVal> & args)4646 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
4647 {
4648     Color borderColor;
4649     if (ParseJsColor(args, borderColor)) {
4650         ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
4651     } else if (args->IsObject()) {
4652         CommonColor commonColor;
4653         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4654         if (ParseCommonEdgeColors(object, commonColor)) {
4655             ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4656                 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4657             return;
4658         }
4659         ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4660             commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4661     } else {
4662         ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
4663     }
4664 }
4665 
JsBorderRadius(const JSCallbackInfo & info)4666 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
4667 {
4668     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4669         JSCallbackInfoType::OBJECT };
4670     auto jsVal = info[0];
4671     if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
4672         ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
4673         return;
4674     }
4675     ParseBorderRadius(jsVal);
4676 }
4677 
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)4678 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
4679     const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
4680     const std::optional<Dimension>& radiusBottomEnd)
4681 {
4682     NG::BorderRadiusProperty borderRadius;
4683     borderRadius.radiusTopStart = radiusTopStart;
4684     borderRadius.radiusTopEnd = radiusTopEnd;
4685     borderRadius.radiusBottomStart = radiusBottomStart;
4686     borderRadius.radiusBottomEnd = radiusBottomEnd;
4687     borderRadius.multiValued = true;
4688     return borderRadius;
4689 }
4690 
ParseBorderRadius(const JSRef<JSVal> & args)4691 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
4692 {
4693     CalcDimension borderRadius;
4694     if (ParseJsDimensionVp(args, borderRadius)) {
4695         ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
4696     } else if (args->IsObject()) {
4697         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4698         CalcDimension topLeft;
4699         CalcDimension topRight;
4700         CalcDimension bottomLeft;
4701         CalcDimension bottomRight;
4702         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4703             ViewAbstractModel::GetInstance()->SetBorderRadius(
4704                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4705                 return;
4706         }
4707         ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4708     }
4709 }
4710 
ParseOuterBorderRadius(const JSRef<JSVal> & args)4711 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
4712 {
4713     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
4714         return;
4715     }
4716     CalcDimension borderRadius;
4717     if (ParseJsDimensionVp(args, borderRadius)) {
4718         if (borderRadius.Unit() == DimensionUnit::PERCENT) {
4719             borderRadius.Reset();
4720         }
4721         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
4722     } else if (args->IsObject()) {
4723         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4724         CalcDimension topLeft;
4725         CalcDimension topRight;
4726         CalcDimension bottomLeft;
4727         CalcDimension bottomRight;
4728         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4729             ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
4730                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4731         }
4732         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4733     }
4734 }
4735 
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4736 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4737 {
4738     ParseJsDimensionVp(object->GetProperty(key), radius);
4739 }
4740 
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4741 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4742 {
4743     if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
4744         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
4745         ParseJsLengthMetrics(startObj, radius);
4746     }
4747 }
4748 
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)4749 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
4750     CalcDimension& bottomLeft, CalcDimension& bottomRight)
4751 {
4752     if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
4753         object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
4754         CalcDimension topStart;
4755         CalcDimension topEnd;
4756         CalcDimension bottomStart;
4757         CalcDimension bottomEnd;
4758         GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
4759         GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
4760         GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
4761         GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
4762         topLeft = topStart;
4763         topRight = topEnd;
4764         bottomLeft = bottomStart;
4765         bottomRight = bottomEnd;
4766         return true;
4767     }
4768     GetBorderRadius("topLeft", object, topLeft);
4769     GetBorderRadius("topRight", object, topRight);
4770     GetBorderRadius("bottomLeft", object, bottomLeft);
4771     GetBorderRadius("bottomRight", object, bottomRight);
4772     return false;
4773 }
4774 
JsBorderStyle(const JSCallbackInfo & info)4775 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
4776 {
4777     ParseBorderStyle(info[0]);
4778 }
4779 namespace {
ConvertBorderStyle(int32_t value)4780 BorderStyle ConvertBorderStyle(int32_t value)
4781 {
4782     auto style = static_cast<BorderStyle>(value);
4783     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4784         style = BorderStyle::SOLID;
4785     }
4786     return style;
4787 }
4788 
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)4789 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
4790 {
4791     style = static_cast<BorderStyle>(value);
4792     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4793         return false;
4794     }
4795     return true;
4796 }
4797 } // namespace
4798 
ParseBorderStyle(const JSRef<JSVal> & args)4799 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
4800 {
4801     if (args->IsObject()) {
4802         std::optional<BorderStyle> styleLeft;
4803         std::optional<BorderStyle> styleRight;
4804         std::optional<BorderStyle> styleTop;
4805         std::optional<BorderStyle> styleBottom;
4806         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4807         auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
4808         if (leftValue->IsNumber()) {
4809             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4810         }
4811         auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
4812         if (rightValue->IsNumber()) {
4813             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4814         }
4815         auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
4816         if (topValue->IsNumber()) {
4817             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4818         }
4819         auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
4820         if (bottomValue->IsNumber()) {
4821             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4822         }
4823         ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4824         return;
4825     }
4826     if (args->IsNumber()) {
4827         auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4828         ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
4829         return;
4830     }
4831     ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4832 }
4833 
ParseOuterBorderStyle(const JSRef<JSVal> & args)4834 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
4835 {
4836     if (!args->IsObject() && !args->IsNumber()) {
4837         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
4838         return;
4839     }
4840     if (args->IsObject()) {
4841         std::optional<BorderStyle> styleLeft;
4842         std::optional<BorderStyle> styleRight;
4843         std::optional<BorderStyle> styleTop;
4844         std::optional<BorderStyle> styleBottom;
4845         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4846         auto leftValue = object->GetProperty("left");
4847         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
4848             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4849         }
4850         auto rightValue = object->GetProperty("right");
4851         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
4852             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4853         }
4854         auto topValue = object->GetProperty("top");
4855         if (!topValue->IsUndefined() && topValue->IsNumber()) {
4856             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4857         }
4858         auto bottomValue = object->GetProperty("bottom");
4859         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
4860             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4861         }
4862         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4863         return;
4864     }
4865     auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4866     ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
4867 }
4868 
JsBlur(const JSCallbackInfo & info)4869 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
4870 {
4871     if (info.Length() == 0) {
4872         return;
4873     }
4874     double blur = 0.0;
4875     if (!ParseJsDouble(info[0], blur)) {
4876         return;
4877     }
4878 
4879     BlurOption blurOption;
4880     if (info.Length() > 1 && info[1]->IsObject()) {
4881         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4882         ParseBlurOption(jsBlurOption, blurOption);
4883     }
4884     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4885     ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption);
4886     info.SetReturnValue(info.This());
4887 }
4888 
JsMotionBlur(const JSCallbackInfo & info)4889 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
4890 {
4891     if (!info[0]->IsObject()) {
4892         return;
4893     }
4894     MotionBlurOption option;
4895     double x = 0.0;
4896     double y = 0.0;
4897     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4898     JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
4899     if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
4900         JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
4901         ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
4902         ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
4903     }
4904     double radius = 0.0;
4905     if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
4906         radius = 0.0;
4907     }
4908     if (LessNotEqual(x, 0.0)) {
4909         x = 0.0;
4910     }
4911     if (LessNotEqual(y, 0.0)) {
4912         y = 0.0;
4913     }
4914     option.radius = radius;
4915     option.anchor.x = std::clamp(x, 0.0, 1.0);
4916     option.anchor.y = std::clamp(y, 0.0, 1.0);
4917     ViewAbstractModel::GetInstance()->SetMotionBlur(option);
4918 }
4919 
JsColorBlend(const JSCallbackInfo & info)4920 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
4921 {
4922     Color colorBlend;
4923     if (info[0]->IsUndefined()) {
4924         colorBlend = Color::TRANSPARENT;
4925         SetColorBlend(colorBlend);
4926         return;
4927     }
4928     if (!ParseJsColor(info[0], colorBlend)) {
4929         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4930             colorBlend = Color::TRANSPARENT;
4931             SetColorBlend(colorBlend);
4932         }
4933         return;
4934     }
4935     SetColorBlend(colorBlend);
4936     info.SetReturnValue(info.This());
4937 }
4938 
JsUseEffect(const JSCallbackInfo & info)4939 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
4940 {
4941     if (info[0]->IsBoolean()) {
4942         auto effectType = EffectType::DEFAULT;
4943         if (info.Length() == 2 && info[1]->IsNumber()) {
4944             effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
4945             if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
4946                 effectType = EffectType::DEFAULT;
4947             }
4948         }
4949         ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
4950     }
4951 }
4952 
JsUseShadowBatching(const JSCallbackInfo & info)4953 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
4954 {
4955     if (info[0]->IsBoolean()) {
4956         ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
4957     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4958         ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
4959     }
4960 }
4961 
JsBackdropBlur(const JSCallbackInfo & info)4962 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
4963 {
4964     if (info.Length() == 0) {
4965         return;
4966     }
4967     double blur = 0.0;
4968     BlurOption blurOption;
4969     if (!ParseJsDouble(info[0], blur)) {
4970         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4971             return;
4972         }
4973     }
4974     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4975     if (info.Length() > 1 && info[1]->IsObject()) {
4976         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4977         ParseBlurOption(jsBlurOption, blurOption);
4978     }
4979     ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption);
4980     info.SetReturnValue(info.This());
4981 }
4982 
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4983 void JSViewAbstract::GetFractionStops(
4984     std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
4985 {
4986     if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
4987         return;
4988     }
4989     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
4990     float tmpPos = -1.0f;
4991     size_t length = jsArray->Length();
4992     for (size_t i = 0; i < length; i++) {
4993         std::pair<float, float> fractionStop;
4994         JSRef<JSVal> item = jsArray->GetValueAt(i);
4995         if (!item->IsArray()) {
4996             continue;
4997         }
4998         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
4999         if (subArray->Length() < 2) {
5000             continue;
5001         }
5002 
5003         double value = 0.0;
5004         if (ParseJsDouble(subArray->GetValueAt(0), value)) {
5005             value = std::clamp(value, 0.0, 1.0);
5006             fractionStop.first = static_cast<float>(value);
5007         }
5008         value = 0.0;
5009         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
5010             value = std::clamp(value, 0.0, 1.0);
5011             fractionStop.second = static_cast<float>(value);
5012         }
5013 
5014         if (fractionStop.second <= tmpPos) {
5015             fractionStops.clear();
5016             return;
5017         }
5018         tmpPos = fractionStop.second;
5019         fractionStops.push_back(fractionStop);
5020     }
5021 }
JsLinearGradientBlur(const JSCallbackInfo & info)5022 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
5023 {
5024     if (info.Length() < 2) { // 2 represents the least para num;
5025         return;
5026     }
5027     double blurRadius = 0.0;
5028     ParseJsDouble(info[0], blurRadius);
5029 
5030     std::vector<std::pair<float, float>> fractionStops;
5031     auto direction = GradientDirection::BOTTOM;
5032     if (info[1]->IsObject()) {
5033         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
5034         GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
5035         auto directionValue =
5036             jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
5037         if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
5038             directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
5039             directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
5040         }
5041         direction = static_cast<GradientDirection>(directionValue);
5042     }
5043     if (static_cast<int32_t>(fractionStops.size()) <= 1) {
5044         fractionStops.clear();
5045         fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
5046         fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
5047     }
5048     // Parse direction
5049     CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
5050     NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
5051     SetLinearGradientBlur(blurPara);
5052 }
5053 
JsBackgroundBrightness(const JSCallbackInfo & info)5054 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
5055 {
5056     double rate = 0.0;
5057     double lightUpDegree = 0.0;
5058     if (info[0]->IsObject()) {
5059         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5060         ParseJsDouble(jsObj->GetProperty("rate"), rate);
5061         ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
5062     }
5063     SetDynamicLightUp(rate, lightUpDegree);
5064 }
5065 
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)5066 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
5067 {
5068     if (info.Length() == 0) {
5069         return;
5070     }
5071     BrightnessOption option;
5072     if (info[0]->IsObject()) {
5073         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5074         ParseBrightnessOption(jsOption, option);
5075     }
5076     SetBgDynamicBrightness(option);
5077 }
5078 
JsForegroundBrightness(const JSCallbackInfo & info)5079 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
5080 {
5081     if (info.Length() == 0) {
5082         return;
5083     }
5084     BrightnessOption option;
5085     if (info[0]->IsObject()) {
5086         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5087         ParseBrightnessOption(jsOption, option);
5088     }
5089     SetFgDynamicBrightness(option);
5090 }
5091 
JsWindowBlur(const JSCallbackInfo & info)5092 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
5093 {
5094     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5095     auto jsVal = info[0];
5096     if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
5097         return;
5098     }
5099 
5100     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
5101     double progress = 0.0;
5102     ParseJsDouble(jsObj->GetProperty("percent"), progress);
5103     auto style = jsObj->GetPropertyValue<int32_t>("style",
5104         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
5105 
5106     progress = std::clamp(progress, 0.0, 1.0);
5107     style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
5108         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
5109 
5110     SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
5111     info.SetReturnValue(info.This());
5112 }
5113 
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)5114 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
5115     std::string& resName, bool isParseType)
5116 {
5117     if (!jsValue->IsString()) {
5118         return false;
5119     }
5120     std::string resPath = jsValue->ToString();
5121     std::smatch results;
5122     std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
5123     if (!std::regex_match(resPath, results, tokenRegex)) {
5124         return false;
5125     }
5126     targetModule = results[1];
5127     if (isParseType && !ConvertResourceType(results[2], resType)) {
5128         return false;
5129     }
5130     resName = resPath;
5131     return true;
5132 }
5133 
ConvertResourceType(const std::string & typeName,ResourceType & resType)5134 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
5135 {
5136     static const std::unordered_map<std::string, ResourceType> resTypeMap {
5137         { "color", ResourceType::COLOR },
5138         { "media", ResourceType::MEDIA },
5139         { "float", ResourceType::FLOAT },
5140         { "string", ResourceType::STRING },
5141         { "plural", ResourceType::PLURAL },
5142         { "pattern", ResourceType::PATTERN },
5143         { "boolean", ResourceType::BOOLEAN },
5144         { "integer", ResourceType::INTEGER },
5145         { "strarray", ResourceType::STRARRAY },
5146         { "intarray", ResourceType::INTARRAY },
5147     };
5148     auto it = resTypeMap.find(typeName);
5149     if (it == resTypeMap.end()) {
5150         return false;
5151     }
5152     resType = it->second;
5153     return true;
5154 }
5155 
CompleteResourceObject(JSRef<JSObject> & jsObj)5156 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
5157 {
5158     std::string bundleName;
5159     std::string moduleName;
5160     int32_t resId = -1;
5161     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5162 }
5163 
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)5164 void JSViewAbstract::CompleteResourceObjectWithBundleName(
5165     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
5166 {
5167     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5168 }
5169 
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)5170 void JSViewAbstract::CompleteResourceObjectInner(
5171     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
5172 {
5173     // dynamic $r raw input format is
5174     // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
5175     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5176     ResourceType resType;
5177 
5178     std::string targetModule;
5179     std::string resName;
5180     if (resId->IsString()) {
5181         JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
5182         int32_t typeNum = -1;
5183         if (type->IsNumber()) {
5184             typeNum = type->ToNumber<int32_t>();
5185         }
5186         if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
5187             return;
5188         }
5189         CompleteResourceObjectFromId(type, jsObj, resType, resName);
5190     } else if (resId->IsNumber()) {
5191         resIdValue = resId->ToNumber<int32_t>();
5192         if (resIdValue == -1) {
5193             CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
5194         }
5195     }
5196 
5197     JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
5198     if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
5199         bundleName = GetBundleNameFromContainer();
5200         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
5201     }
5202     if (moduleName == DEFAULT_HAR_MODULE_NAME) {
5203         moduleName = GetModuleNameFromContainer();
5204         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
5205     }
5206 }
5207 
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)5208 bool JSViewAbstract::ParseJsDimensionNG(
5209     const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
5210 {
5211     if (jsValue->IsNumber()) {
5212         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5213         return true;
5214     }
5215     if (jsValue->IsString()) {
5216         auto value = jsValue->ToString();
5217         if (!isSupportPercent && value.back() == '%') {
5218             return false;
5219         }
5220         return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5221     }
5222     if (jsValue->IsObject()) {
5223         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5224         CompleteResourceObject(jsObj);
5225         JSRef<JSVal> resId = jsObj->GetProperty("id");
5226         if (!resId->IsNumber()) {
5227             return false;
5228         }
5229         auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5230         if (resType == UNKNOWN_RESOURCE_TYPE) {
5231             return false;
5232         }
5233 
5234         auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5235         auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5236         if (!resourceWrapper) {
5237             return false;
5238         }
5239 
5240         auto resIdNum = resId->ToNumber<int32_t>();
5241         if (resIdNum == -1) {
5242             if (!IsGetResourceByName(jsObj)) {
5243                 return false;
5244             }
5245             JSRef<JSVal> args = jsObj->GetProperty("params");
5246             if (!args->IsArray()) {
5247                 return false;
5248             }
5249             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5250             auto param = params->GetValueAt(0);
5251             if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5252                 auto value = resourceWrapper->GetStringByName(param->ToString());
5253                 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5254             }
5255             if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5256                 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5257                 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5258                 return true;
5259             }
5260             result = resourceWrapper->GetDimensionByName(param->ToString());
5261             return true;
5262         }
5263 
5264         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5265             auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5266             return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5267         }
5268         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5269             auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5270             StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5271             return true;
5272         }
5273 
5274         if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5275             result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
5276             return true;
5277         }
5278     }
5279 
5280     return false;
5281 }
5282 
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)5283 bool JSViewAbstract::ParseJsLengthNG(
5284     const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
5285 {
5286     if (jsValue->IsNumber()) {
5287         if (std::isnan(jsValue->ToNumber<double>())) {
5288             return false;
5289         }
5290         result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
5291         return true;
5292     } else if (jsValue->IsObject()) {
5293         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5294         JSRef<JSVal> value = jsObj->GetProperty("value");
5295         if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
5296             return false;
5297         }
5298         DimensionUnit unit = defaultUnit;
5299         JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
5300         if (jsUnit->IsNumber()) {
5301             if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
5302                 return false;
5303             }
5304             unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
5305         }
5306         result = NG::CalcLength(value->ToNumber<double>(), unit);
5307         return true;
5308     }
5309 
5310     return false;
5311 }
5312 
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)5313 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
5314 {
5315     // 'vp' -> the value varies with pixel density of device.
5316     return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5317 }
5318 
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)5319 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
5320 {
5321     if (jsValue->IsNumber()) {
5322         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5323         return true;
5324     }
5325     if (jsValue->IsString()) {
5326         result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
5327         return true;
5328     }
5329     if (!jsValue->IsObject()) {
5330         return false;
5331     }
5332     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5333     CompleteResourceObject(jsObj);
5334     JSRef<JSVal> resId = jsObj->GetProperty("id");
5335     if (!resId->IsNumber()) {
5336         return false;
5337     }
5338 
5339     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5340     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5341     if (!resourceWrapper) {
5342         return false;
5343     }
5344 
5345     auto resIdNum = resId->ToNumber<int32_t>();
5346     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5347     if (resType == UNKNOWN_RESOURCE_TYPE) {
5348         return false;
5349     }
5350 
5351     if (resIdNum == -1) {
5352         if (!IsGetResourceByName(jsObj)) {
5353             return false;
5354         }
5355         JSRef<JSVal> args = jsObj->GetProperty("params");
5356         if (!args->IsArray()) {
5357             return false;
5358         }
5359         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5360         auto param = params->GetValueAt(0);
5361         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5362             auto value = resourceWrapper->GetStringByName(param->ToString());
5363             result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5364             return true;
5365         }
5366         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5367             auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5368             result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5369             return true;
5370         }
5371         result = resourceWrapper->GetDimensionByName(param->ToString());
5372         return true;
5373     }
5374 
5375     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5376         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5377         result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5378         return true;
5379     }
5380     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5381         auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5382         result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5383         return true;
5384     }
5385     result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
5386     return true;
5387 }
5388 
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5389 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5390 {
5391     // 'vp' -> the value varies with pixel density of device.
5392     return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5393 }
5394 
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)5395 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5396 {
5397     // 'vp' -> the value varies with pixel density of device.
5398     return ParseJsDimension(jsValue, result, DimensionUnit::VP);
5399 }
5400 
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)5401 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5402 {
5403     // the 'fp' unit is used for text scenes.
5404     return ParseJsDimension(jsValue, result, DimensionUnit::FP);
5405 }
5406 
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5407 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5408 {
5409     // the 'fp' unit is used for text scenes.
5410     return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
5411 }
5412 
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)5413 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
5414 {
5415     return ParseJsDimension(jsValue, result, DimensionUnit::PX);
5416 }
5417 
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)5418 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
5419 {
5420     if (!jsValue->IsObject()) {
5421         return false;
5422     }
5423     auto colorObj = JSRef<JSObject>::Cast(jsValue);
5424     auto toNumericProp = colorObj->GetProperty("toNumeric");
5425     if (toNumericProp->IsFunction()) {
5426         auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
5427         result.SetValue(colorVal->ToNumber<uint32_t>());
5428         return true;
5429     }
5430     return false;
5431 }
5432 
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5433 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5434 {
5435     if (jsValue->IsNumber()) {
5436         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
5437         return true;
5438     }
5439     if (jsValue->IsString()) {
5440         auto value = jsValue->ToString();
5441         return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
5442     }
5443     if (jsValue->IsObject()) {
5444         auto jsObj = JSRef<JSObject>::Cast(jsValue);
5445         auto valObj = jsObj->GetProperty("value");
5446         if (valObj->IsUndefined() || valObj->IsNull()) {
5447             return false;
5448         }
5449         double value = valObj->ToNumber<double>();
5450         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
5451         result = CalcDimension(value, unit);
5452         return true;
5453     }
5454     return false;
5455 }
5456 
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5457 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5458 {
5459     return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
5460 }
5461 
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)5462 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
5463 {
5464     if (!jsValue->IsObject()) {
5465         return false;
5466     }
5467     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5468     CompleteResourceObject(jsObj);
5469     if (jsObj->IsEmpty()) {
5470         return false;
5471     }
5472     JSRef<JSVal> id = jsObj->GetProperty("id");
5473     if (!id->IsNumber()) {
5474         return false;
5475     }
5476 
5477     auto resId = id->ToNumber<int32_t>();
5478     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5479     if (resType == UNKNOWN_RESOURCE_TYPE) {
5480         return false;
5481     }
5482 
5483     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5484     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5485     if (!resourceWrapper) {
5486         return false;
5487     }
5488 
5489     if (resId == -1) {
5490         if (!IsGetResourceByName(jsObj)) {
5491             return false;
5492         }
5493         JSRef<JSVal> args = jsObj->GetProperty("params");
5494         if (!args->IsArray()) {
5495             return false;
5496         }
5497         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5498         auto param = params->GetValueAt(0);
5499         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5500             auto numberString = resourceWrapper->GetStringByName(param->ToString());
5501             return StringUtils::StringToDouble(numberString, result);
5502         }
5503         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5504             result = resourceWrapper->GetIntByName(param->ToString());
5505             return true;
5506         }
5507         if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5508             result = resourceWrapper->GetDoubleByName(param->ToString());
5509             return true;
5510         }
5511         return false;
5512     }
5513     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5514         auto numberString = resourceWrapper->GetString(resId);
5515         return StringUtils::StringToDouble(numberString, result);
5516     }
5517     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5518         result = resourceWrapper->GetInt(resId);
5519         return true;
5520     }
5521     if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5522         result = resourceWrapper->GetDouble(resId);
5523         return true;
5524     }
5525     return false;
5526 }
5527 
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)5528 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
5529 {
5530     if (jsValue->IsNumber()) {
5531         result = jsValue->ToNumber<double>();
5532         return true;
5533     }
5534     if (jsValue->IsString()) {
5535         return StringUtils::StringToDouble(jsValue->ToString(), result);
5536     }
5537     if (jsValue->IsObject()) {
5538         return ParseResourceToDouble(jsValue, result);
5539     }
5540     return false;
5541 }
5542 
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)5543 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
5544 {
5545     if (jsValue->IsNumber()) {
5546         result = jsValue->ToNumber<int32_t>();
5547         return true;
5548     }
5549     if (jsValue->IsString()) {
5550         result = StringUtils::StringToInt(jsValue->ToString());
5551         return true;
5552     }
5553     if (!jsValue->IsObject()) {
5554         return false;
5555     }
5556     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5557     CompleteResourceObject(jsObj);
5558     JSRef<JSVal> resId = jsObj->GetProperty("id");
5559     if (!resId->IsNumber()) {
5560         return false;
5561     }
5562 
5563     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5564     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5565     if (!resourceWrapper) {
5566         return false;
5567     }
5568 
5569     auto resIdNum = resId->ToNumber<int32_t>();
5570     if (resIdNum == -1) {
5571         if (!IsGetResourceByName(jsObj)) {
5572             return false;
5573         }
5574         JSRef<JSVal> args = jsObj->GetProperty("params");
5575         if (!args->IsArray()) {
5576             return false;
5577         }
5578         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5579         auto param = params->GetValueAt(0);
5580         result = resourceWrapper->GetIntByName(param->ToString());
5581         return true;
5582     }
5583     result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5584     return true;
5585 }
5586 
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)5587 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
5588 {
5589     if (!jsValue->IsObject()) {
5590         return false;
5591     }
5592     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5593     CompleteResourceObject(jsObj);
5594 
5595     auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result);
5596     if (ok) {
5597         JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
5598         if (jsOpacityRatio->IsNumber()) {
5599             double opacityRatio = jsOpacityRatio->ToNumber<double>();
5600             result = result.BlendOpacity(opacityRatio);
5601         }
5602     }
5603     return ok;
5604 }
5605 
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)5606 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result)
5607 {
5608     JSRef<JSVal> resId = jsObj->GetProperty("id");
5609     if (!resId->IsNumber()) {
5610         return false;
5611     }
5612 
5613     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5614     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5615     if (!resourceWrapper) {
5616         return false;
5617     }
5618 
5619     auto resIdNum = resId->ToNumber<int32_t>();
5620     if (resIdNum == -1) {
5621         if (!IsGetResourceByName(jsObj)) {
5622             return false;
5623         }
5624         JSRef<JSVal> args = jsObj->GetProperty("params");
5625         if (!args->IsArray()) {
5626             return false;
5627         }
5628         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5629         auto param = params->GetValueAt(0);
5630         result = resourceWrapper->GetColorByName(param->ToString());
5631         return true;
5632     }
5633 
5634     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5635     if (type == static_cast<int32_t>(ResourceType::STRING)) {
5636         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5637         return Color::ParseColorString(value, result);
5638     }
5639     if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5640         auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5641         result = Color(ColorAlphaAdapt(value));
5642         return true;
5643     }
5644     if (type == static_cast<int32_t>(ResourceType::COLOR)) {
5645         result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
5646         result.SetResourceId(resId->ToNumber<uint32_t>());
5647         return true;
5648     }
5649     return false;
5650 }
5651 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)5652 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
5653 {
5654     if (jsValue->IsNumber()) {
5655         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5656         return true;
5657     }
5658     if (jsValue->IsString()) {
5659         return Color::ParseColorString(jsValue->ToString(), result);
5660     }
5661     if (jsValue->IsObject()) {
5662         return ParseJsColorFromResource(jsValue, result);
5663     }
5664     return false;
5665 }
5666 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)5667 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
5668 {
5669     if (jsValue->IsNumber()) {
5670         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5671         return true;
5672     }
5673     if (jsValue->IsString()) {
5674         return Color::ParseColorString(jsValue->ToString(), result, defaultColor);
5675     }
5676     if (!jsValue->IsObject()) {
5677         return false;
5678     }
5679     return ParseJsColorFromResource(jsValue, result);
5680 }
5681 
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)5682 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
5683 {
5684     if (jsValue->IsString()) {
5685         std::string colorStr = jsValue->ToString();
5686         if (colorStr.compare("invert") == 0) {
5687             strategy = ForegroundColorStrategy::INVERT;
5688             return true;
5689         }
5690     }
5691     return false;
5692 }
5693 
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)5694 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
5695 {
5696     if (jsValue->IsString()) {
5697         std::string colorStr = jsValue->ToString();
5698         if (colorStr.compare("average") == 0) {
5699             strategy = ShadowColorStrategy::AVERAGE;
5700             return true;
5701         } else if (colorStr.compare("primary") == 0) {
5702             strategy = ShadowColorStrategy::PRIMARY;
5703             return true;
5704         }
5705     }
5706     return false;
5707 }
5708 
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)5709 bool JSViewAbstract::ParseJsSymbolId(
5710     const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
5711 {
5712     if (jsValue->IsNull() || jsValue->IsUndefined()) {
5713         symbolId = 0;
5714         return false;
5715     }
5716     if (!jsValue->IsObject()) {
5717         return false;
5718     }
5719     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5720     CompleteResourceObject(jsObj);
5721     JSRef<JSVal> resId = jsObj->GetProperty("id");
5722     if (resId->IsNull() || !resId->IsNumber()) {
5723         return false;
5724     }
5725     auto resourceObject = GetResourceObject(jsObj);
5726     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5727     symbolResourceObject = resourceObject;
5728     if (!resourceWrapper) {
5729         return false;
5730     }
5731     if (!resourceObject) {
5732         return false;
5733     }
5734 
5735     auto resIdNum = resId->ToNumber<int32_t>();
5736     if (resIdNum == -1) {
5737         if (!IsGetResourceByName(jsObj)) {
5738             return false;
5739         }
5740         JSRef<JSVal> args = jsObj->GetProperty("params");
5741         if (!args->IsArray()) {
5742             return false;
5743         }
5744         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5745         auto param = params->GetValueAt(0);
5746         auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
5747         if (!symbol) {
5748             return false;
5749         }
5750         symbolId = symbol;
5751         return true;
5752     }
5753 
5754     auto symbol = resourceWrapper->GetSymbolById(resIdNum);
5755     if (!symbol) {
5756         return false;
5757     }
5758     symbolId = symbol;
5759     return true;
5760 }
5761 
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)5762 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
5763 {
5764     if (!jsValue->IsArray()) {
5765         return false;
5766     }
5767     if (jsValue->IsArray()) {
5768         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5769         for (size_t i = 0; i < array->Length(); i++) {
5770             JSRef<JSVal> value = array->GetValueAt(i);
5771             if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
5772                 return false;
5773             }
5774             if (value->IsNumber()) {
5775                 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
5776                 continue;
5777             } else if (value->IsString()) {
5778                 Color color;
5779                 Color::ParseColorString(value->ToString(), color);
5780                 result.emplace_back(color);
5781                 continue;
5782             } else {
5783                 Color color;
5784                 ParseJsColorFromResource(value, color);
5785                 result.emplace_back(color);
5786             }
5787         }
5788         return true;
5789     }
5790     return false;
5791 }
5792 
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5793 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
5794 {
5795     result.clear();
5796     if (!jsValue->IsString() && !jsValue->IsObject()) {
5797         return false;
5798     }
5799     if (jsValue->IsString()) {
5800         result = ConvertStrToFontFamilies(jsValue->ToString());
5801         return true;
5802     }
5803     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5804     CompleteResourceObject(jsObj);
5805     JSRef<JSVal> resId = jsObj->GetProperty("id");
5806     if (!resId->IsNumber()) {
5807         return false;
5808     }
5809 
5810     auto resourceObject = GetResourceObject(jsObj);
5811     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5812     if (!resourceWrapper) {
5813         return false;
5814     }
5815 
5816     auto resIdNum = resId->ToNumber<int32_t>();
5817     if (resIdNum == -1) {
5818         if (!IsGetResourceByName(jsObj)) {
5819             return false;
5820         }
5821         JSRef<JSVal> args = jsObj->GetProperty("params");
5822         if (!args->IsArray()) {
5823             return false;
5824         }
5825         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5826         auto param = params->GetValueAt(0);
5827         result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
5828         return true;
5829     }
5830     result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
5831     return true;
5832 }
5833 
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5834 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
5835 {
5836     if (jsValue->IsString()) {
5837         result = jsValue->ToString();
5838         return true;
5839     }
5840 
5841     if (!jsValue->IsObject()) {
5842         return false;
5843     }
5844 
5845     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5846     CompleteResourceObject(jsObj);
5847 
5848     JSRef<JSVal> resId = jsObj->GetProperty("id");
5849     if (!resId->IsNumber()) {
5850         return false;
5851     }
5852     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5853     if (type == UNKNOWN_RESOURCE_TYPE) {
5854         return false;
5855     }
5856 
5857     JSRef<JSVal> args = jsObj->GetProperty("params");
5858     if (!args->IsArray()) {
5859         return false;
5860     }
5861 
5862     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5863     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5864     if (!resourceWrapper) {
5865         return false;
5866     }
5867 
5868     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5869     auto resIdNum = resId->ToNumber<int32_t>();
5870     if (resIdNum == -1) {
5871         if (!IsGetResourceByName(jsObj)) {
5872             return false;
5873         }
5874         auto param = params->GetValueAt(0);
5875         if (type == static_cast<int32_t>(ResourceType::STRING)) {
5876             auto originStr = resourceWrapper->GetStringByName(param->ToString());
5877             ReplaceHolder(originStr, params, 1);
5878             result = originStr;
5879         } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5880             auto countJsVal = params->GetValueAt(1);
5881             int count = 0;
5882             if (!countJsVal->IsNumber()) {
5883                 return false;
5884             }
5885             count = countJsVal->ToNumber<int>();
5886             auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
5887             ReplaceHolder(pluralStr, params, 2);
5888             result = pluralStr;
5889         } else {
5890             return false;
5891         }
5892         return true;
5893     }
5894     if (type == static_cast<int32_t>(ResourceType::STRING)) {
5895         auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5896         ReplaceHolder(originStr, params, 0);
5897         result = originStr;
5898     } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5899         auto countJsVal = params->GetValueAt(0);
5900         int count = 0;
5901         if (!countJsVal->IsNumber()) {
5902             return false;
5903         }
5904         count = countJsVal->ToNumber<int>();
5905         auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
5906         ReplaceHolder(pluralStr, params, 1);
5907         result = pluralStr;
5908     } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
5909         result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
5910     } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5911         result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5912     } else {
5913         return false;
5914     }
5915     return true;
5916 }
5917 
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5918 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
5919 {
5920     if (!jsValue->IsObject() && !jsValue->IsString()) {
5921         return false;
5922     }
5923     if (jsValue->IsString()) {
5924         result = jsValue->ToString();
5925         return true;
5926     }
5927     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5928     CompleteResourceObject(jsObj);
5929     return ParseJSMediaInternal(jsObj, result);
5930 }
5931 
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5932 bool JSViewAbstract::ParseJsMediaWithBundleName(
5933     const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
5934 {
5935     if (!jsValue->IsObject() && !jsValue->IsString()) {
5936         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5937     }
5938     if (jsValue->IsString()) {
5939         result = jsValue->ToString();
5940         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5941     }
5942     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5943     CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
5944     return ParseJSMediaInternal(jsObj, result);
5945 }
5946 
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5947 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result)
5948 {
5949     int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5950     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5951     if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
5952         auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5953         auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5954         CHECK_NULL_RETURN(resourceWrapper, false);
5955         if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
5956             JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5957             if (!args->IsArray()) {
5958                 return false;
5959             }
5960             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5961             auto fileName = params->GetValueAt(0);
5962             if (!fileName->IsString()) {
5963                 return false;
5964             }
5965             result = resourceWrapper->GetRawfile(fileName->ToString());
5966             return true;
5967         }
5968         auto resIdNum = resId->ToNumber<int32_t>();
5969         if (resIdNum == -1) {
5970             if (!IsGetResourceByName(jsObj)) {
5971                 return false;
5972             }
5973             JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5974             if (!args->IsArray()) {
5975                 return false;
5976             }
5977             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5978             auto param = params->GetValueAt(0);
5979             if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5980                 result = resourceWrapper->GetMediaPathByName(param->ToString());
5981                 return true;
5982             }
5983             if (type == static_cast<int32_t>(ResourceType::STRING)) {
5984                 result = resourceWrapper->GetStringByName(param->ToString());
5985                 return true;
5986             }
5987             return false;
5988         } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5989             result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
5990             return true;
5991         } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
5992             result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5993             return true;
5994         }
5995     }
5996     return false;
5997 }
5998 
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5999 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
6000     const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
6001 {
6002     auto vm = info.GetVm();
6003     auto globalObj = JSNApi::GetGlobalObject(vm);
6004     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
6005     JsiValue jsiValue(globalFunc);
6006     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
6007     if (!globalFuncRef->IsFunction()) {
6008         return;
6009     }
6010     if (modifierNormalObj->IsUndefined()) {
6011         symbolApply.onApply = nullptr;
6012     } else {
6013         RefPtr<JsFunction> jsFunc =
6014             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
6015         auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
6016                             modifierNormal = std::move(modifierNormalObj),
6017                             modifierSelected = std::move(modifierSelectedObj)](
6018                             WeakPtr<NG::FrameNode> frameNode, std::string type) {
6019             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6020             auto node = frameNode.Upgrade();
6021             CHECK_NULL_VOID(node);
6022             JSRef<JSVal> params[SECOND_INDEX];
6023             if (type == "normal") {
6024                 params[0] = modifierNormal;
6025             } else if (!modifierSelected->IsUndefined()) {
6026                 params[0] = modifierSelected;
6027             }
6028             params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
6029             PipelineContext::SetCallBackNode(node);
6030             func->ExecuteJS(SECOND_INDEX, params);
6031         };
6032         symbolApply.onApply = onApply;
6033     }
6034 }
6035 
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)6036 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
6037 {
6038     if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
6039         return false;
6040     }
6041 
6042     if (jsValue->IsBoolean()) {
6043         result = jsValue->ToBoolean();
6044         return true;
6045     }
6046 
6047     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6048     CompleteResourceObject(jsObj);
6049     int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
6050     if (resType == UNKNOWN_RESOURCE_TYPE) {
6051         return false;
6052     }
6053 
6054     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
6055     if (!resId->IsNumber()) {
6056         return false;
6057     }
6058 
6059     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6060     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6061     if (!resourceWrapper) {
6062         return false;
6063     }
6064 
6065     auto resIdNum = resId->ToNumber<int32_t>();
6066     if (resIdNum == -1) {
6067         if (!IsGetResourceByName(jsObj)) {
6068             return false;
6069         }
6070         JSRef<JSVal> args = jsObj->GetProperty("params");
6071         if (!args->IsArray()) {
6072             return false;
6073         }
6074         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6075         auto param = params->GetValueAt(0);
6076         if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6077             result = resourceWrapper->GetBooleanByName(param->ToString());
6078             return true;
6079         }
6080         return false;
6081     }
6082 
6083     if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6084         result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
6085         return true;
6086     }
6087     return false;
6088 }
6089 
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)6090 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
6091 {
6092     return ParseJsInteger<uint32_t>(jsValue, result);
6093 }
6094 
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)6095 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
6096 {
6097     return ParseJsInteger<int32_t>(jsValue, result);
6098 }
6099 
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)6100 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
6101 {
6102     if (!jsValue->IsArray() && !jsValue->IsObject()) {
6103         return false;
6104     }
6105 
6106     if (jsValue->IsArray()) {
6107         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6108         for (size_t i = 0; i < array->Length(); i++) {
6109             JSRef<JSVal> value = array->GetValueAt(i);
6110             if (value->IsNumber()) {
6111                 result.emplace_back(value->ToNumber<uint32_t>());
6112             } else if (value->IsObject()) {
6113                 uint32_t singleResInt;
6114                 if (ParseJsInteger(value, singleResInt)) {
6115                     result.emplace_back(singleResInt);
6116                 } else {
6117                     return false;
6118                 }
6119             } else {
6120                 return false;
6121             }
6122         }
6123         return true;
6124     }
6125 
6126     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6127     CompleteResourceObject(jsObj);
6128     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6129     if (resType == UNKNOWN_RESOURCE_TYPE) {
6130         return false;
6131     }
6132 
6133     JSRef<JSVal> resId = jsObj->GetProperty("id");
6134     if (!resId->IsNumber()) {
6135         return false;
6136     }
6137 
6138     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6139     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6140     if (!resourceWrapper) {
6141         return false;
6142     }
6143 
6144     auto resIdNum = resId->ToNumber<int32_t>();
6145     if (resIdNum == -1) {
6146         if (!IsGetResourceByName(jsObj)) {
6147             return false;
6148         }
6149         JSRef<JSVal> args = jsObj->GetProperty("params");
6150         if (!args->IsArray()) {
6151             return false;
6152         }
6153         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6154         auto param = params->GetValueAt(0);
6155         if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6156             result = resourceWrapper->GetIntArrayByName(param->ToString());
6157             return true;
6158         }
6159         return false;
6160     }
6161 
6162     if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6163         result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
6164         return true;
6165     }
6166     return false;
6167 }
6168 
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)6169 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
6170 {
6171     if (!jsValue->IsArray() && !jsValue->IsObject()) {
6172         return false;
6173     }
6174 
6175     if (jsValue->IsArray()) {
6176         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6177         for (size_t i = 0; i < array->Length(); i++) {
6178             JSRef<JSVal> value = array->GetValueAt(i);
6179             if (value->IsString()) {
6180                 result.emplace_back(value->ToString());
6181             } else if (value->IsObject()) {
6182                 std::string singleResStr;
6183                 if (ParseJsString(value, singleResStr)) {
6184                     result.emplace_back(singleResStr);
6185                 } else {
6186                     return false;
6187                 }
6188             } else {
6189                 return false;
6190             }
6191         }
6192         return true;
6193     }
6194 
6195     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6196     CompleteResourceObject(jsObj);
6197     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6198     if (resType == UNKNOWN_RESOURCE_TYPE) {
6199         return false;
6200     }
6201 
6202     JSRef<JSVal> resId = jsObj->GetProperty("id");
6203     if (!resId->IsNumber()) {
6204         return false;
6205     }
6206 
6207     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6208     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6209     if (!resourceWrapper) {
6210         return false;
6211     }
6212 
6213     auto resIdNum = resId->ToNumber<int32_t>();
6214     if (resIdNum == -1) {
6215         if (!IsGetResourceByName(jsObj)) {
6216             return false;
6217         }
6218         JSRef<JSVal> args = jsObj->GetProperty("params");
6219         if (!args->IsArray()) {
6220             return false;
6221         }
6222         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6223         auto param = params->GetValueAt(0);
6224         if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6225             result = resourceWrapper->GetStringArrayByName(param->ToString());
6226             return true;
6227         }
6228         return false;
6229     }
6230 
6231     if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6232         result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
6233         return true;
6234     }
6235     return false;
6236 }
6237 
IsGetResourceByName(const JSRef<JSObject> & jsObj)6238 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
6239 {
6240     JSRef<JSVal> resId = jsObj->GetProperty("id");
6241     if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
6242         return false;
6243     }
6244     JSRef<JSVal> args = jsObj->GetProperty("params");
6245     if (!args->IsArray()) {
6246         return false;
6247     }
6248     JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
6249     JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
6250     if (!bundleName->IsString() || !moduleName->IsString()) {
6251         return false;
6252     }
6253     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6254     if (params->IsEmpty()) {
6255         return false;
6256     }
6257     return true;
6258 }
6259 
ParseSize(const JSCallbackInfo & info)6260 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
6261 {
6262     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6263     auto jsVal = info[0];
6264     if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
6265         return std::pair<CalcDimension, CalcDimension>();
6266     }
6267     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
6268     CalcDimension width;
6269     CalcDimension height;
6270     if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
6271         !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
6272         return std::pair<CalcDimension, CalcDimension>();
6273     }
6274     return std::pair<CalcDimension, CalcDimension>(width, height);
6275 }
6276 
JsUseAlign(const JSCallbackInfo & info)6277 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
6278 {
6279     if (info.Length() < 2) {
6280         return;
6281     }
6282 
6283     if (!info[0]->IsObject() && !info[1]->IsObject()) {
6284         return;
6285     }
6286 
6287     AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
6288     if (declaration == nullptr) {
6289         return;
6290     }
6291 
6292     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6293     JSRef<JSVal> side = obj->GetProperty("side");
6294     JSRef<JSVal> offset = obj->GetProperty("offset");
6295 
6296     if (!side->IsNumber()) {
6297         return;
6298     }
6299 
6300     auto sideValue = side->ToNumber<int32_t>();
6301 
6302     if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
6303         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
6304             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
6305             return;
6306         }
6307     } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
6308         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
6309             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
6310             return;
6311         }
6312     }
6313 
6314     std::optional<CalcDimension> optOffset;
6315     CalcDimension offsetDimension;
6316     if (ParseJsDimensionVp(offset, offsetDimension)) {
6317         optOffset = offsetDimension;
6318     }
6319     ViewAbstractModel::GetInstance()->SetUseAlign(
6320         declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
6321 }
6322 
JsGridSpan(const JSCallbackInfo & info)6323 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
6324 {
6325     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6326     auto jsVal = info[0];
6327     if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
6328         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6329             ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
6330         }
6331         return;
6332     }
6333     auto span = jsVal->ToNumber<int32_t>();
6334     ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
6335 }
6336 
JsGridOffset(const JSCallbackInfo & info)6337 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
6338 {
6339     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6340     auto jsVal = info[0];
6341     if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
6342         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6343             ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
6344         }
6345         return;
6346     }
6347     auto offset = jsVal->ToNumber<int32_t>();
6348     ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
6349 }
6350 
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)6351 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
6352 {
6353     // {lg: 4}
6354     if (val->IsNumber()) {
6355         span = val->ToNumber<uint32_t>();
6356         return true;
6357     }
6358 
6359     if (!val->IsObject()) {
6360         return false;
6361     }
6362 
6363     // {lg: {span: 1, offset: 2}}
6364     JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
6365     span = obj->GetProperty("span")->ToNumber<uint32_t>();
6366     offset = obj->GetProperty("offset")->ToNumber<int32_t>();
6367     return true;
6368 }
6369 
JsUseSizeType(const JSCallbackInfo & info)6370 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
6371 {
6372     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6373     auto jsVal = info[0];
6374     if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
6375         return;
6376     }
6377     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
6378     for (auto values : SCREEN_SIZE_VALUES) {
6379         JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
6380         if (val->IsNull() || val->IsEmpty()) {
6381             continue;
6382         }
6383         uint32_t span = 0;
6384         int32_t offset = 0;
6385         if (ParseSpanAndOffset(val, span, offset)) {
6386             ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
6387         }
6388     }
6389 }
6390 
JsZIndex(const JSCallbackInfo & info)6391 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
6392 {
6393     int zIndex = 0;
6394     if (info[0]->IsNumber()) {
6395         zIndex = info[0]->ToNumber<int>();
6396     }
6397 
6398     ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
6399 }
6400 
Pop()6401 void JSViewAbstract::Pop()
6402 {
6403     ViewStackModel::GetInstance()->Pop();
6404 }
6405 
JsSetDraggable(bool draggable)6406 void JSViewAbstract::JsSetDraggable(bool draggable)
6407 {
6408     ViewAbstractModel::GetInstance()->SetDraggable(draggable);
6409 }
6410 
ParseDragInteractionOptions(const JSCallbackInfo & info,NG::DragPreviewOption & previewOption)6411 void JSViewAbstract::ParseDragInteractionOptions(const JSCallbackInfo& info,
6412     NG::DragPreviewOption& previewOption)
6413 {
6414     if (info.Length() > 1 && info[1]->IsObject()) {
6415         JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
6416         auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
6417         if (multiSelection->IsBoolean()) {
6418             previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
6419         }
6420         auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
6421         if (defaultAnimation->IsBoolean()) {
6422             previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
6423         }
6424         auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
6425         if (dragPreview->IsBoolean()) {
6426             previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
6427         }
6428         auto isLiftingDisabled = interObj->GetProperty("isLiftingDisabled");
6429         if (isLiftingDisabled->IsBoolean()) {
6430             previewOption.isLiftingDisabled = isLiftingDisabled->ToBoolean();
6431         }
6432     }
6433 }
6434 
ParseDragPreviewOptions(const JSCallbackInfo & info)6435 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
6436 {
6437     NG::DragPreviewOption previewOption;
6438     if (!info[0]->IsObject()) {
6439         return previewOption;
6440     }
6441     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
6442     auto mode = obj->GetProperty("mode");
6443     bool isAuto = true;
6444     if (mode->IsNumber()) {
6445         ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
6446     } else if (mode->IsArray()) {
6447         JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
6448         for (size_t i = 0; i < array->Length(); i++) {
6449             JSRef<JSVal> value = array->GetValueAt(i);
6450             if (value->IsNumber()) {
6451                 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
6452             }
6453             if (isAuto) {
6454                 break;
6455             }
6456         }
6457     }
6458 
6459     JSViewAbstract::SetDragNumberBadge(info, previewOption);
6460 
6461     ParseDragInteractionOptions(info, previewOption);
6462 
6463     JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
6464 
6465     return previewOption;
6466 }
6467 
JsSetDragPreviewOptions(const JSCallbackInfo & info)6468 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
6469 {
6470     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6471     auto jsVal = info[0];
6472     if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
6473         return;
6474     }
6475     NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
6476     ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
6477 }
6478 
JsOnDragStart(const JSCallbackInfo & info)6479 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
6480 {
6481     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6482     auto jsVal = info[0];
6483     if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
6484         return;
6485     }
6486 
6487     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6488 
6489     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6490     auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
6491                            const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
6492         NG::DragDropBaseInfo dragDropInfo;
6493         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
6494         PipelineContext::SetCallBackNode(node);
6495         auto ret = func->Execute(info, extraParams);
6496         if (!ret->IsObject()) {
6497             return dragDropInfo;
6498         }
6499 
6500         dragDropInfo.node = ParseDragNode(ret);
6501         auto builderObj = JSRef<JSObject>::Cast(ret);
6502 #if defined(PIXEL_MAP_SUPPORTED)
6503         auto pixmap = builderObj->GetProperty("pixelMap");
6504         dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
6505 #endif
6506         auto extraInfo = builderObj->GetProperty("extraInfo");
6507         ParseJsString(extraInfo, dragDropInfo.extraInfo);
6508         return dragDropInfo;
6509     };
6510     ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
6511 }
6512 
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)6513 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
6514 {
6515     auto node = ParseDragNode(info);
6516     if (!node) {
6517         return false;
6518     }
6519     dragInfo.node = node;
6520     return true;
6521 }
6522 
ParseDragNode(const JSRef<JSVal> & info)6523 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
6524 {
6525     auto builderFunc = ParseDragStartBuilderFunc(info);
6526     if (!builderFunc) {
6527         return nullptr;
6528     }
6529     // use another VSP instance while executing the builder function
6530     ViewStackModel::GetInstance()->NewScope();
6531     {
6532         ACE_SCORING_EVENT("onDragStart.builder");
6533         builderFunc->Execute();
6534     }
6535 
6536     return ViewStackModel::GetInstance()->Finish();
6537 }
6538 
JsOnDragEnter(const JSCallbackInfo & info)6539 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
6540 {
6541     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6542     auto jsVal = info[0];
6543     if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
6544         return;
6545     }
6546     RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6547     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6548     auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
6549                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6550         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6551         ACE_SCORING_EVENT("onDragEnter");
6552         PipelineContext::SetCallBackNode(node);
6553         func->Execute(info, extraParams);
6554     };
6555 
6556     ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
6557 }
6558 
JsOnDragEnd(const JSCallbackInfo & info)6559 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
6560 {
6561     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6562     auto jsVal = info[0];
6563     if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
6564         return;
6565     }
6566     RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6567     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6568     auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
6569                          const RefPtr<OHOS::Ace::DragEvent>& info) {
6570         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6571         ACE_SCORING_EVENT("onDragEnd");
6572         auto extraParams = JsonUtil::Create(true);
6573         PipelineContext::SetCallBackNode(node);
6574         func->Execute(info, extraParams->ToString());
6575     };
6576 
6577     ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
6578 }
6579 
JsOnDragMove(const JSCallbackInfo & info)6580 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
6581 {
6582     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6583     auto jsVal = info[0];
6584     if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
6585         return;
6586     }
6587     RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6588     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6589     auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
6590                           const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6591         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6592         ACE_SCORING_EVENT("onDragMove");
6593         PipelineContext::SetCallBackNode(node);
6594         func->Execute(info, extraParams);
6595     };
6596 
6597     ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
6598 }
6599 
JsOnDragLeave(const JSCallbackInfo & info)6600 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
6601 {
6602     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6603     auto jsVal = info[0];
6604     if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
6605         return;
6606     }
6607     RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6608     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6609     auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
6610                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6611         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6612         ACE_SCORING_EVENT("onDragLeave");
6613         PipelineContext::SetCallBackNode(node);
6614         func->Execute(info, extraParams);
6615     };
6616 
6617     ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
6618 }
6619 
JsOnDrop(const JSCallbackInfo & info)6620 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
6621 {
6622     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6623     auto jsVal = info[0];
6624     if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
6625         return;
6626     }
6627     RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6628     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6629     auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
6630                       const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6631         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6632         ACE_SCORING_EVENT("onDrop");
6633         PipelineContext::SetCallBackNode(node);
6634         func->Execute(info, extraParams);
6635     };
6636 
6637     ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
6638 
6639     bool disableDataPrefetch = false;
6640     if (info.Length() > 1 && info[1]->IsObject()) {
6641         JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
6642         auto jsDisableDataPrefetch = interObj->GetProperty("disableDataPrefetch");
6643         if (jsDisableDataPrefetch->IsBoolean()) {
6644             disableDataPrefetch = jsDisableDataPrefetch->ToBoolean();
6645         }
6646     }
6647     ViewAbstractModel::GetInstance()->SetDisableDataPrefetch(disableDataPrefetch);
6648 }
6649 
JsOnAreaChange(const JSCallbackInfo & info)6650 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
6651 {
6652     auto jsVal = info[0];
6653     if (jsVal->IsUndefined() && IsDisableEventVersion()) {
6654         ViewAbstractModel::GetInstance()->DisableOnAreaChange();
6655         return;
6656     }
6657     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6658     if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
6659         return;
6660     }
6661     auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6662 
6663     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6664     auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
6665                              node = frameNode](
6666                              const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
6667         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6668         ACE_SCORING_EVENT("onAreaChange");
6669         PipelineContext::SetCallBackNode(node);
6670         func->Execute(oldRect, oldOrigin, rect, origin);
6671     };
6672     ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
6673 }
6674 
JsOnSizeChange(const JSCallbackInfo & info)6675 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
6676 {
6677     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6678     auto jsVal = info[0];
6679     if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
6680         return;
6681     }
6682     auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6683 
6684     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6685     auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
6686                             node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
6687         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6688         ACE_SCORING_EVENT("onSizeChange");
6689         PipelineContext::SetCallBackNode(node);
6690         func->Execute(oldRect, rect);
6691     };
6692     ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
6693 }
6694 
6695 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)6696 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
6697 {
6698     if (info.Length() < 2) {
6699         return;
6700     }
6701     if ((!info[0]->IsBoolean() && !info[0]->IsObject()) || !info[1]->IsObject()) {
6702         return;
6703     }
6704     auto popupParam = AceType::MakeRefPtr<PopupParam>();
6705     // Set IsShow to popupParam
6706     if (info[0]->IsBoolean()) {
6707         popupParam->SetIsShow(info[0]->ToBoolean());
6708     } else {
6709         JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
6710         auto callback = ParseDoubleBindCallback(info, showObj);
6711         popupParam->SetOnStateChange(std::move(callback));
6712         popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
6713     }
6714     // Set popup to popupParam
6715     auto popupObj = JSRef<JSObject>::Cast(info[1]);
6716     SetPopupDismiss(info, popupObj, popupParam);
6717     if (popupObj->GetProperty("message")->IsString()) {
6718         ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
6719         ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6720     } else if (!popupObj->GetProperty("builder").IsEmpty()) {
6721         ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
6722         auto builderValue = popupObj->GetProperty("builder");
6723         auto builder = builderValue;
6724         if (!builderValue->IsObject()) {
6725             return;
6726         }
6727         if (!builderValue->IsFunction()) {
6728             JSRef<JSObject> builderObj;
6729             builderObj = JSRef<JSObject>::Cast(builderValue);
6730             builder = builderObj->GetProperty("builder");
6731             if (!builder->IsFunction()) {
6732                 return;
6733             }
6734         }
6735         if (popupParam->IsShow() && !IsPopupCreated()) {
6736             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
6737             CHECK_NULL_VOID(builderFunc);
6738             ViewStackModel::GetInstance()->NewScope();
6739             builderFunc->Execute();
6740             auto customNode = ViewStackModel::GetInstance()->Finish();
6741             ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
6742         } else {
6743             ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6744         }
6745     } else {
6746         return;
6747     }
6748 }
6749 
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)6750 void JSViewAbstract::SetPopupDismiss(
6751     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
6752 {
6753     auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
6754     if (onWillDismissFunc->IsBoolean()) {
6755         bool onWillDismissBool = onWillDismissFunc->ToBoolean();
6756         popupParam->SetInteractiveDismiss(onWillDismissBool);
6757         popupParam->SetOnWillDismiss(nullptr);
6758         if (onWillDismissBool) {
6759             TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6760         }
6761     } else if (onWillDismissFunc->IsFunction()) {
6762         auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
6763         popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
6764         popupParam->SetInteractiveDismiss(true);
6765         if (onWillDismissCallback != nullptr) {
6766             TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6767         }
6768     }
6769 }
6770 
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)6771 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
6772 {
6773     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6774     if (!onWillDismissFunc->IsFunction()) {
6775         return PopupOnWillDismiss();
6776     }
6777     RefPtr<JsFunction> jsFunc =
6778         AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6779     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6780     auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
6781                           node = frameNode](int32_t reason) {
6782         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6783         ACE_SCORING_EVENT("Bindpopup.dismiss");
6784         PipelineContext::SetCallBackNode(node);
6785 
6786         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6787         objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6788         JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6789         dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
6790         dismissObj->SetProperty<int32_t>("reason", reason);
6791         JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6792 
6793         func->ExecuteJS(1, &newJSVal);
6794     };
6795     return onWillDismiss;
6796 }
6797 
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)6798 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6799 {
6800     ViewAbstractModel::GetInstance()->DismissPopup();
6801     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6802 }
6803 #endif
6804 
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info)> & onWillDismiss)6805 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
6806     std::function<void(const int32_t& info)>& onWillDismiss)
6807 {
6808     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6809     if (onWillDismissFunc->IsFunction()) {
6810         auto jsFunc =
6811             AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6812         onWillDismiss = [func = std::move(jsFunc)](const int32_t& info) {
6813             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6814             objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6815             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6816             dismissObj->SetPropertyObject(
6817                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
6818             dismissObj->SetProperty<int32_t>("reason", info);
6819             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6820             func->ExecuteJS(1, &newJSVal);
6821         };
6822     }
6823 }
6824 
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)6825 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6826 {
6827     ViewAbstractModel::GetInstance()->DismissDialog();
6828     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6829 }
6830 
JsLinearGradient(const JSCallbackInfo & info)6831 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
6832 {
6833     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6834     auto jsVal = info[0];
6835     if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
6836         NG::Gradient newGradient;
6837         newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6838         ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6839         return;
6840     }
6841     NG::Gradient newGradient;
6842     NewJsLinearGradient(info, newGradient);
6843     ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6844 }
6845 
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6846 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6847 {
6848     if (!info[0]->IsObject()) {
6849         return;
6850     }
6851     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
6852     newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6853     // angle
6854     std::optional<float> degree;
6855     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6856         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
6857     } else {
6858         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
6859     }
6860     if (degree) {
6861         newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
6862         degree.reset();
6863     }
6864     // direction
6865     auto direction = static_cast<GradientDirection>(
6866         jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
6867     switch (direction) {
6868         case GradientDirection::LEFT:
6869             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6870             break;
6871         case GradientDirection::RIGHT:
6872             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6873             break;
6874         case GradientDirection::TOP:
6875             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6876             break;
6877         case GradientDirection::BOTTOM:
6878             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6879             break;
6880         case GradientDirection::LEFT_TOP:
6881             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6882             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6883             break;
6884         case GradientDirection::LEFT_BOTTOM:
6885             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6886             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6887             break;
6888         case GradientDirection::RIGHT_TOP:
6889             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6890             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6891             break;
6892         case GradientDirection::RIGHT_BOTTOM:
6893             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6894             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6895             break;
6896         case GradientDirection::NONE:
6897         case GradientDirection::START_TO_END:
6898         case GradientDirection::END_TO_START:
6899         default:
6900             break;
6901     }
6902     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6903     newGradient.SetRepeat(repeating);
6904     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6905 }
6906 
JsRadialGradient(const JSCallbackInfo & info)6907 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
6908 {
6909     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6910     auto jsVal = info[0];
6911     if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
6912         NG::Gradient newGradient;
6913         newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6914         ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6915         return;
6916     }
6917     NG::Gradient newGradient;
6918     NewJsRadialGradient(info, newGradient);
6919     ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6920 }
6921 
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6922 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6923 {
6924     JSRef<JSVal> arg = info[0];
6925     if (!arg->IsObject()) {
6926         return;
6927     }
6928     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6929     newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6930     // center
6931     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6932     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6933         CalcDimension value;
6934         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6935         if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6936             newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
6937             if (value.Unit() == DimensionUnit::PERCENT) {
6938                 // [0,1] -> [0, 100]
6939                 newGradient.GetRadialGradient()->radialCenterX =
6940                     CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6941             }
6942         }
6943         if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6944             newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
6945             if (value.Unit() == DimensionUnit::PERCENT) {
6946                 // [0,1] -> [0, 100]
6947                 newGradient.GetRadialGradient()->radialCenterY =
6948                     CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6949             }
6950         }
6951     }
6952     // radius
6953     CalcDimension radius;
6954     if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) {
6955         newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
6956         newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
6957     }
6958     // repeating
6959     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6960     newGradient.SetRepeat(repeating);
6961     // color stops
6962     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6963 }
6964 
JsSweepGradient(const JSCallbackInfo & info)6965 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
6966 {
6967     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6968     auto jsVal = info[0];
6969     if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
6970         NG::Gradient newGradient;
6971         newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6972         ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6973         return;
6974     }
6975 
6976     NG::Gradient newGradient;
6977     NewJsSweepGradient(info, newGradient);
6978     ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6979 }
6980 
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6981 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6982 {
6983     JSRef<JSVal> arg = info[0];
6984     if (!arg->IsObject()) {
6985         return;
6986     }
6987     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6988     newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6989     // center
6990     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6991     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6992         CalcDimension value;
6993         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6994         if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6995             newGradient.GetSweepGradient()->centerX = CalcDimension(value);
6996             if (value.Unit() == DimensionUnit::PERCENT) {
6997                 // [0,1] -> [0, 100]
6998                 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6999             }
7000         }
7001         if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
7002             newGradient.GetSweepGradient()->centerY = CalcDimension(value);
7003             if (value.Unit() == DimensionUnit::PERCENT) {
7004                 // [0,1] -> [0, 100]
7005                 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
7006             }
7007         }
7008     }
7009     // start, end and rotation
7010     ParseSweepGradientPartly(jsObj, newGradient);
7011     // repeating
7012     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
7013     newGradient.SetRepeat(repeating);
7014     // color stops
7015     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
7016 }
7017 
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)7018 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
7019 {
7020     std::optional<float> degreeStart;
7021     std::optional<float> degreeEnd;
7022     std::optional<float> degreeRotation;
7023     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7024         GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
7025         GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
7026         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
7027     } else {
7028         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
7029         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
7030         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
7031     }
7032     if (degreeStart) {
7033         CheckAngle(degreeStart);
7034         newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
7035     }
7036     if (degreeEnd) {
7037         CheckAngle(degreeEnd);
7038         newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
7039     }
7040     if (degreeRotation) {
7041         CheckAngle(degreeRotation);
7042         newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
7043     }
7044 }
7045 
JsMotionPath(const JSCallbackInfo & info)7046 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
7047 {
7048     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7049     auto jsVal = info[0];
7050     if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
7051         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
7052         return;
7053     }
7054     MotionPathOption motionPathOption;
7055     if (ParseMotionPath(jsVal, motionPathOption)) {
7056         ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
7057     } else {
7058         TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
7059         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
7060     }
7061 }
7062 
JsShadow(const JSCallbackInfo & info)7063 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
7064 {
7065     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
7066     auto jsVal = info[0];
7067     if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
7068         Shadow shadow;
7069         std::vector<Shadow> shadows { shadow };
7070         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
7071         return;
7072     }
7073     Shadow shadow;
7074     if (!ParseShadowProps(jsVal, shadow)) {
7075         info.ReturnSelf();
7076         return;
7077     }
7078     std::vector<Shadow> shadows { shadow };
7079     ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
7080 }
7081 
JsBlendMode(const JSCallbackInfo & info)7082 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
7083 {
7084     if (info.Length() == 0) {
7085         return;
7086     }
7087     BlendMode blendMode = BlendMode::NONE;
7088     BlendApplyType blendApplyType = BlendApplyType::FAST;
7089     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7090     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7091     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7092     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7093     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7094     if (info[0]->IsNumber()) {
7095         auto blendModeNum = info[0]->ToNumber<int32_t>();
7096         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7097             blendMode = static_cast<BlendMode>(blendModeNum);
7098         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7099             // backward compatibility code, will remove soon
7100             blendMode = BlendMode::SRC_OVER;
7101             blendApplyType = BlendApplyType::OFFSCREEN;
7102         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7103             // backward compatibility code, will remove soon
7104             blendMode = BlendMode::SRC_IN;
7105             blendApplyType = BlendApplyType::OFFSCREEN;
7106         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7107             // backward compatibility code, will remove soon
7108             blendMode = BlendMode::DST_IN;
7109             blendApplyType = BlendApplyType::OFFSCREEN;
7110         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7111             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7112         }
7113     }
7114     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7115         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7116         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7117             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7118         }
7119     }
7120     ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7121     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7122 }
7123 
JsAdvancedBlendMode(const JSCallbackInfo & info)7124 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
7125 {
7126     if (info.Length() == 0) {
7127         return;
7128     }
7129     BlendMode blendMode = BlendMode::NONE;
7130     BlendApplyType blendApplyType = BlendApplyType::FAST;
7131     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7132     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7133     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7134     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7135     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7136     if (info[0]->IsNumber()) {
7137         auto blendModeNum = info[0]->ToNumber<int32_t>();
7138         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7139             blendMode = static_cast<BlendMode>(blendModeNum);
7140         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7141             // backward compatibility code, will remove soon
7142             blendMode = BlendMode::SRC_OVER;
7143             blendApplyType = BlendApplyType::OFFSCREEN;
7144         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7145             // backward compatibility code, will remove soon
7146             blendMode = BlendMode::SRC_IN;
7147             blendApplyType = BlendApplyType::OFFSCREEN;
7148         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7149             // backward compatibility code, will remove soon
7150             blendMode = BlendMode::DST_IN;
7151             blendApplyType = BlendApplyType::OFFSCREEN;
7152         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7153             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7154         }
7155     } else if (info[0]->IsObject()) {
7156         auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]);
7157         ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender);
7158     }
7159     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7160         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7161         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7162             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7163         }
7164     }
7165     if (!info[0]->IsObject()) {
7166         ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7167     }
7168     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7169 }
7170 
JsGrayScale(const JSCallbackInfo & info)7171 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
7172 {
7173     CalcDimension value;
7174     if (!ParseJsDimensionVp(info[0], value)) {
7175         value.SetValue(0.0);
7176         ViewAbstractModel::GetInstance()->SetGrayScale(value);
7177         return;
7178     }
7179 
7180     if (LessNotEqual(value.Value(), 0.0)) {
7181         value.SetValue(0.0);
7182     }
7183 
7184     if (GreatNotEqual(value.Value(), 1.0)) {
7185         value.SetValue(1.0);
7186     }
7187 
7188     ViewAbstractModel::GetInstance()->SetGrayScale(value);
7189 }
7190 
JsBrightness(const JSCallbackInfo & info)7191 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
7192 {
7193     CalcDimension value;
7194     if (!ParseJsDimensionVp(info[0], value)) {
7195         value.SetValue(1.0);
7196         ViewAbstractModel::GetInstance()->SetBrightness(value);
7197         return;
7198     }
7199 
7200     ViewAbstractModel::GetInstance()->SetBrightness(value);
7201 }
7202 
JsContrast(const JSCallbackInfo & info)7203 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
7204 {
7205     CalcDimension value;
7206     if (!ParseJsDimensionVp(info[0], value)) {
7207         value.SetValue(1.0);
7208         ViewAbstractModel::GetInstance()->SetContrast(value);
7209         return;
7210     }
7211 
7212     if (LessNotEqual(value.Value(), 0.0)) {
7213         value.SetValue(0.0);
7214     }
7215 
7216     ViewAbstractModel::GetInstance()->SetContrast(value);
7217 }
7218 
JsSaturate(const JSCallbackInfo & info)7219 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
7220 {
7221     CalcDimension value;
7222     if (!ParseJsDimensionVp(info[0], value)) {
7223         value.SetValue(1.0);
7224         ViewAbstractModel::GetInstance()->SetSaturate(value);
7225         return;
7226     }
7227 
7228     if (LessNotEqual(value.Value(), 0.0)) {
7229         value.SetValue(0.0);
7230     }
7231 
7232     ViewAbstractModel::GetInstance()->SetSaturate(value);
7233 }
7234 
JsSepia(const JSCallbackInfo & info)7235 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
7236 {
7237     CalcDimension value;
7238     if (!ParseJsDimensionVp(info[0], value)) {
7239         value.SetValue(0.0);
7240         ViewAbstractModel::GetInstance()->SetSepia(value);
7241         return;
7242     }
7243 
7244     if (LessNotEqual(value.Value(), 0.0)) {
7245         value.SetValue(0.0);
7246     }
7247 
7248     ViewAbstractModel::GetInstance()->SetSepia(value);
7249 }
7250 
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)7251 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
7252 {
7253     double invertValue = 0.0;
7254     if (ParseJsDouble(jsValue, invertValue)) {
7255         invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
7256         return true;
7257     }
7258     auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
7259     if (!argsPtrItem || argsPtrItem->IsNull()) {
7260         return false;
7261     }
7262     InvertOption option;
7263     double low = 0.0;
7264     if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
7265         option.low_ = std::clamp(low, 0.0, 1.0);
7266     }
7267     double high = 0.0;
7268     if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
7269         option.high_ = std::clamp(high, 0.0, 1.0);
7270     }
7271     double threshold = 0.0;
7272     if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
7273         option.threshold_ = std::clamp(threshold, 0.0, 1.0);
7274     }
7275     double thresholdRange = 0.0;
7276     if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
7277         option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
7278     }
7279     invert = option;
7280     return true;
7281 }
7282 
JsInvert(const JSCallbackInfo & info)7283 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
7284 {
7285     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
7286     InvertVariant invert = 0.0f;
7287     auto jsVal = info[0];
7288     if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
7289         ViewAbstractModel::GetInstance()->SetInvert(invert);
7290         return;
7291     }
7292     if (ParseInvertProps(jsVal, invert)) {
7293         ViewAbstractModel::GetInstance()->SetInvert(invert);
7294     }
7295     ViewAbstractModel::GetInstance()->SetInvert(invert);
7296 }
7297 
JsSystemBarEffect(const JSCallbackInfo & info)7298 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
7299 {
7300     ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
7301 }
7302 
JsHueRotate(const JSCallbackInfo & info)7303 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
7304 {
7305     std::optional<float> degree;
7306     JSRef<JSVal> arg = info[0];
7307     if (arg->IsString()) {
7308         degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
7309     } else if (arg->IsNumber()) {
7310         degree = static_cast<float>(arg->ToNumber<int32_t>());
7311     } else {
7312         ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
7313         return;
7314     }
7315     float deg = 0.0f;
7316     if (degree) {
7317         deg = degree.value();
7318         degree.reset();
7319     }
7320     deg = std::fmod(deg, ROUND_UNIT);
7321     if (deg < 0.0f) {
7322         deg += ROUND_UNIT;
7323     }
7324     ViewAbstractModel::GetInstance()->SetHueRotate(deg);
7325 }
7326 
JsClip(const JSCallbackInfo & info)7327 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
7328 {
7329     JSRef<JSVal> arg = info[0];
7330     if (arg->IsUndefined()) {
7331         ViewAbstractModel::GetInstance()->SetClipEdge(false);
7332         return;
7333     }
7334     if (arg->IsObject()) {
7335         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7336         if (clipShape == nullptr) {
7337             return;
7338         }
7339         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7340     } else if (arg->IsBoolean()) {
7341         ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
7342     }
7343 }
7344 
JsClipShape(const JSCallbackInfo & info)7345 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
7346 {
7347     if (info[0]->IsObject()) {
7348         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7349         if (clipShape == nullptr) {
7350             return;
7351         }
7352         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7353     }
7354 }
7355 
JsMask(const JSCallbackInfo & info)7356 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
7357 {
7358     JSRef<JSVal> arg = info[0];
7359     if (!arg->IsObject()) {
7360         ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
7361         return;
7362     }
7363     auto paramObject = JSRef<JSObject>::Cast(arg);
7364     JSRef<JSVal> typeParam = paramObject->GetProperty("type");
7365     if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
7366         typeParam->ToString() == "ProgressMask") {
7367         auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
7368         JSRef<JSVal> jValue = paramObject->GetProperty("value");
7369         auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
7370         if (value < 0.0f) {
7371             value = 0.0f;
7372         }
7373         progressMask->SetValue(value);
7374         JSRef<JSVal> jTotal = paramObject->GetProperty("total");
7375         auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
7376         if (total < 0.0f) {
7377             total = DEFAULT_PROGRESS_TOTAL;
7378         }
7379         progressMask->SetMaxValue(total);
7380         JSRef<JSVal> jColor = paramObject->GetProperty("color");
7381         Color colorVal;
7382         if (ParseJsColor(jColor, colorVal)) {
7383             progressMask->SetColor(colorVal);
7384         } else {
7385             RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
7386             progressMask->SetColor(theme->GetMaskColor());
7387         }
7388         JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
7389         if (jEnableBreathe->IsBoolean()) {
7390             progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
7391         }
7392         ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
7393     } else {
7394         JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7395         if (maskShape == nullptr) {
7396             return;
7397         };
7398         ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7399     }
7400 }
7401 
JsMaskShape(const JSCallbackInfo & info)7402 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
7403 {
7404     if (!info[0]->IsObject()) {
7405         return;
7406     }
7407 
7408     JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7409     if (maskShape == nullptr) {
7410         return;
7411     };
7412     ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7413 }
7414 
JsFocusable(const JSCallbackInfo & info)7415 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
7416 {
7417     if (!info[0]->IsBoolean()) {
7418         return;
7419     }
7420     ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
7421 }
7422 
JsTabStop(const JSCallbackInfo & info)7423 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
7424 {
7425     if (!info[0]->IsBoolean()) {
7426         ViewAbstractModel::GetInstance()->SetTabStop(false);
7427         return;
7428     }
7429     ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
7430 }
7431 
JsFocusBox(const JSCallbackInfo & info)7432 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
7433 {
7434     if (!info[0]->IsObject() || info.Length() != 1) {
7435         return;
7436     }
7437     auto obj = JSRef<JSObject>::Cast(info[0]);
7438     NG::FocusBoxStyle style;
7439 
7440     CalcDimension margin;
7441     if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) {
7442         style.margin = margin;
7443     }
7444     CalcDimension strokeWidth;
7445     if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) {
7446         style.strokeWidth = strokeWidth;
7447     }
7448     Color strokeColor;
7449     if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) {
7450         style.strokeColor = strokeColor;
7451     }
7452 
7453     ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
7454 }
7455 
JsOnFocusMove(const JSCallbackInfo & args)7456 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
7457 {
7458     JSRef<JSVal> arg = args[0];
7459     if (arg->IsFunction()) {
7460         RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7461         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7462         auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
7463                                int info) {
7464             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7465             ACE_SCORING_EVENT("onFocusMove");
7466             PipelineContext::SetCallBackNode(node);
7467             func->Execute(info);
7468         };
7469         ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
7470     }
7471 }
7472 
JsOnKeyEvent(const JSCallbackInfo & args)7473 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
7474 {
7475     JSRef<JSVal> arg = args[0];
7476     if (arg->IsUndefined() && IsDisableEventVersion()) {
7477         ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
7478         return;
7479     }
7480     if (!arg->IsFunction()) {
7481         return;
7482     }
7483     RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
7484     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7485     auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
7486                           KeyEventInfo& info) -> bool {
7487         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
7488         ACE_SCORING_EVENT("onKey");
7489         PipelineContext::SetCallBackNode(node);
7490         auto ret = func->ExecuteWithValue(info);
7491         return ret->IsBoolean() ? ret->ToBoolean() : false;
7492     };
7493     ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
7494 }
7495 
JsDispatchKeyEvent(const JSCallbackInfo & args)7496 void JSViewAbstract::JsDispatchKeyEvent(const JSCallbackInfo& args)
7497 {
7498     JSRef<JSVal> arg = args[0];
7499     if (!(arg->IsNumber() || arg->IsString())) {
7500         return;
7501     }
7502     RefPtr<NG::FrameNode> frameNode = nullptr;
7503     if (arg->IsString()) {
7504         std::string id = arg->ToString();
7505         frameNode = NG::Inspector::GetFrameNodeByKey(id);
7506     }
7507 
7508     if (arg->IsNumber()) {
7509         auto id = arg->ToNumber<int32_t>();
7510         auto node = ElementRegister::GetInstance()->GetNodeById(id);
7511         frameNode = AceType::DynamicCast<NG::FrameNode>(node);
7512     }
7513     CHECK_NULL_VOID(frameNode);
7514     auto focusHub = frameNode->GetOrCreateFocusHub();
7515     CHECK_NULL_VOID(focusHub);
7516 
7517     if (!(args[1]->IsObject())) {
7518         return;
7519     }
7520     JSRef<JSObject> jsObject = JSRef<JSObject>::Cast(args[1]);
7521     auto eventInfoPtr = jsObject->Unwrap<KeyEventInfo>();
7522     CHECK_NULL_VOID(eventInfoPtr);
7523     KeyEvent keyEvent;
7524     eventInfoPtr->ParseKeyEvent(keyEvent);
7525     auto result = focusHub->HandleEvent(keyEvent);
7526     args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
7527 }
7528 
JsOnFocus(const JSCallbackInfo & args)7529 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
7530 {
7531     JSRef<JSVal> arg = args[0];
7532     if (arg->IsUndefined() && IsDisableEventVersion()) {
7533         ViewAbstractModel::GetInstance()->DisableOnFocus();
7534         return;
7535     }
7536     if (!arg->IsFunction()) {
7537         return;
7538     }
7539     RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7540     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7541     auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
7542         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7543         ACE_SCORING_EVENT("onFocus");
7544         PipelineContext::SetCallBackNode(node);
7545         func->Execute();
7546     };
7547 
7548     ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
7549 }
7550 
JsOnBlur(const JSCallbackInfo & args)7551 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
7552 {
7553     JSRef<JSVal> arg = args[0];
7554     if (arg->IsUndefined() && IsDisableEventVersion()) {
7555         ViewAbstractModel::GetInstance()->DisableOnBlur();
7556         return;
7557     }
7558     if (!arg->IsFunction()) {
7559         return;
7560     }
7561     RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7562     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7563     auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
7564         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7565         ACE_SCORING_EVENT("onBlur");
7566         PipelineContext::SetCallBackNode(node);
7567         func->Execute();
7568     };
7569 
7570     ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
7571 }
7572 
JsTabIndex(const JSCallbackInfo & info)7573 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
7574 {
7575     JSRef<JSVal> arg = info[0];
7576     if (!arg->IsNumber()) {
7577         return;
7578     }
7579     ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
7580 }
7581 
JsFocusOnTouch(const JSCallbackInfo & info)7582 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
7583 {
7584     JSRef<JSVal> arg = info[0];
7585     if (!arg->IsBoolean()) {
7586         return;
7587     }
7588     auto isFocusOnTouch = arg->ToBoolean();
7589     ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
7590 }
7591 
JsDefaultFocus(const JSCallbackInfo & info)7592 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
7593 {
7594     JSRef<JSVal> arg = info[0];
7595     if (!arg->IsBoolean()) {
7596         return;
7597     }
7598     auto isDefaultFocus = arg->ToBoolean();
7599     ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
7600 }
7601 
JsGroupDefaultFocus(const JSCallbackInfo & info)7602 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
7603 {
7604     JSRef<JSVal> arg = info[0];
7605     if (!arg->IsBoolean()) {
7606         return;
7607     }
7608     auto isGroupDefaultFocus = arg->ToBoolean();
7609     ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
7610 }
7611 
JsKey(const std::string & key)7612 void JSViewAbstract::JsKey(const std::string& key)
7613 {
7614     ViewAbstractModel::GetInstance()->SetInspectorId(key);
7615 }
7616 
JsId(const JSCallbackInfo & info)7617 void JSViewAbstract::JsId(const JSCallbackInfo& info)
7618 {
7619     JSRef<JSVal> arg = info[0];
7620     if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
7621         return;
7622     }
7623     std::string id = arg->ToString();
7624     if (id.empty()) {
7625         return;
7626     }
7627     JsKey(id);
7628 }
7629 
JsRestoreId(int32_t restoreId)7630 void JSViewAbstract::JsRestoreId(int32_t restoreId)
7631 {
7632     ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
7633 }
7634 
JsDebugLine(const JSCallbackInfo & info)7635 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
7636 {
7637     std::string debugLine;
7638     auto length = info.Length();
7639     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
7640 
7641     if (length == 1) { // deprecated version of debug line
7642         auto jsVal = info[0];
7643         if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
7644             return;
7645         }
7646         debugLine = jsVal->ToString();
7647     } else if (length == 2) { // debug line with extra package name
7648         auto line = info[0];
7649         auto packageName = info[1];
7650         if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
7651             !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
7652             return;
7653         }
7654         auto json = JsonUtil::Create(true);
7655         json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
7656         json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
7657         debugLine = json->ToString();
7658     }
7659 
7660     ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
7661 }
7662 
JsOpacityPassThrough(const JSCallbackInfo & info)7663 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
7664 {
7665     double opacity = 1.0;
7666     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7667         if (ParseJsDouble(info[0], opacity)) {
7668             opacity = std::clamp(opacity, 0.0, 1.0);
7669         }
7670     } else {
7671         if (!ParseJsDouble(info[0], opacity)) {
7672             return;
7673         }
7674         if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
7675             opacity = 1.0;
7676         }
7677     }
7678 
7679     ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
7680 }
7681 
JsTransitionPassThrough(const JSCallbackInfo & info)7682 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
7683 {
7684     if (info.Length() == 0) {
7685         ViewAbstractModel::GetInstance()->SetTransition(
7686             NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
7687         return;
7688     }
7689     if (!info[0]->IsObject()) {
7690         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7691             ViewAbstractModel::GetInstance()->CleanTransition();
7692             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
7693         }
7694         return;
7695     }
7696     auto obj = JSRef<JSObject>::Cast(info[0]);
7697     if (!obj->GetProperty("successor_")->IsUndefined()) {
7698         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
7699         std::function<void(bool)> finishCallback;
7700         if (info.Length() > 1 && info[1]->IsFunction()) {
7701             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
7702         }
7703         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
7704         return;
7705     }
7706     auto options = ParseJsTransition(obj);
7707     ViewAbstractModel::GetInstance()->SetTransition(options, true);
7708 }
7709 
JsAccessibilityGroup(const JSCallbackInfo & info)7710 void JSViewAbstract::JsAccessibilityGroup(const JSCallbackInfo& info)
7711 {
7712     bool isGroup = false;
7713     if (info[0]->IsBoolean()) {
7714         isGroup = info[0]->ToBoolean();
7715     }
7716     ViewAbstractModel::GetInstance()->SetAccessibilityGroup(isGroup);
7717 
7718     if (info.Length() > 1 && info[1]->IsObject()) {
7719         auto obj = JSRef<JSObject>::Cast(info[1]);
7720 
7721         auto preferAccessibilityTextObj = obj->GetProperty("accessibilityPreferred");
7722         auto preferAccessibilityText = preferAccessibilityTextObj->IsBoolean() ? preferAccessibilityTextObj->ToBoolean() : false;
7723         ViewAbstractModel::GetInstance()->SetAccessibilityTextPreferred(preferAccessibilityText);
7724     }
7725 }
7726 
JsAccessibilityText(const JSCallbackInfo & info)7727 void JSViewAbstract::JsAccessibilityText(const JSCallbackInfo& info)
7728 {
7729     const JSRef<JSVal>& jsValue = info[0];
7730     std::string text;
7731     if (!ParseJsString(jsValue, text)) {
7732         return;
7733     }
7734     ViewAbstractModel::GetInstance()->SetAccessibilityText(text);
7735 }
7736 
JsAccessibilityTextHint(const std::string & text)7737 void JSViewAbstract::JsAccessibilityTextHint(const std::string& text)
7738 {
7739     ViewAbstractModel::GetInstance()->SetAccessibilityTextHint(text);
7740 }
7741 
JsAccessibilityDescription(const JSCallbackInfo & info)7742 void JSViewAbstract::JsAccessibilityDescription(const JSCallbackInfo& info)
7743 {
7744     const JSRef<JSVal>& jsValue = info[0];
7745     std::string description;
7746     if (!ParseJsString(jsValue, description)) {
7747         return;
7748     }
7749     std::pair<bool, std::string> autoEventPair(false, "");
7750     std::pair<bool, std::string> descriptionPair(false, "");
7751     ParseAccessibilityDescriptionJson(description, autoEventPair, descriptionPair);
7752     if (descriptionPair.first) {
7753         ViewAbstractModel::GetInstance()->SetAccessibilityDescription(descriptionPair.second);
7754     } else {
7755         ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description);
7756     }
7757     if (autoEventPair.first) {
7758         ViewAbstractModel::GetInstance()->SetAutoEventParam(autoEventPair.second);
7759     }
7760 }
7761 
ParseAccessibilityDescriptionJson(const std::string & description,std::pair<bool,std::string> & autoEventPair,std::pair<bool,std::string> & descriptionPair)7762 void JSViewAbstract::ParseAccessibilityDescriptionJson(const std::string& description,
7763     std::pair<bool, std::string>& autoEventPair, std::pair<bool, std::string>& descriptionPair)
7764 {
7765     if (description.empty()) {
7766         return;
7767     }
7768     if (!StartWith(description, "{") || !EndWith(description, "}")) {
7769         return;
7770     }
7771     auto jsonObj = JsonUtil::ParseJsonString(description);
7772     if (!jsonObj || !jsonObj->IsValid() || !jsonObj->IsObject()) {
7773         return;
7774     }
7775     if (jsonObj->Contains("$autoEventParam")) {
7776         auto param = jsonObj->GetValue("$autoEventParam");
7777         if (param) {
7778             autoEventPair = std::make_pair(true, param->ToString());
7779         }
7780     }
7781     if (jsonObj->Contains("$accessibilityDescription")) {
7782         descriptionPair = std::make_pair(true, jsonObj->GetString("$accessibilityDescription"));
7783     } else if (jsonObj->Contains("$autoEventParam")) {
7784         descriptionPair = std::make_pair(true, "");
7785     }
7786 }
7787 
JsAccessibilityImportance(const std::string & importance)7788 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
7789 {
7790     ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance);
7791 }
7792 
JsAccessibilityLevel(const std::string & level)7793 void JSViewAbstract::JsAccessibilityLevel(const std::string& level)
7794 {
7795     ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level);
7796 }
7797 
JsAccessibilityVirtualNode(const JSCallbackInfo & info)7798 void JSViewAbstract::JsAccessibilityVirtualNode(const JSCallbackInfo& info)
7799 {
7800     // parse builder
7801     if (!info[0]->IsObject()) {
7802         return;
7803     }
7804     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7805     auto builder = obj->GetProperty("builder");
7806     if (builder->IsFunction()) {
7807         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7808         CHECK_NULL_VOID(builderFunc);
7809         auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
7810             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7811             ACE_SCORING_EVENT("AccessibilityVirtualNode");
7812             func->Execute();
7813         };
7814         NG::ViewAbstractModelNG::GetInstance()->SetAccessibilityVirtualNode(std::move(buildFunc));
7815     }
7816 }
7817 
JsAccessibilitySelected(const JSCallbackInfo & info)7818 void JSViewAbstract::JsAccessibilitySelected(const JSCallbackInfo& info)
7819 {
7820     bool selected = false;
7821     bool resetValue = false;
7822     JSRef<JSVal> arg = info[0];
7823     if (arg->IsUndefined()) {
7824         resetValue = true;
7825     } else if (arg->IsBoolean()) {
7826         selected = arg->ToBoolean();
7827     } else {
7828         return;
7829     }
7830 
7831     ViewAbstractModel::GetInstance()->SetAccessibilitySelected(selected, resetValue);
7832 }
7833 
JsAccessibilityChecked(const JSCallbackInfo & info)7834 void JSViewAbstract::JsAccessibilityChecked(const JSCallbackInfo& info)
7835 {
7836     bool checked = false;
7837     bool resetValue = false;
7838     JSRef<JSVal> arg = info[0];
7839     if (arg->IsUndefined()) {
7840         resetValue = true;
7841     } else if (arg->IsBoolean()) {
7842         checked = arg->ToBoolean();
7843     } else {
7844         return;
7845     }
7846 
7847     ViewAbstractModel::GetInstance()->SetAccessibilityChecked(checked, resetValue);
7848 }
7849 
JsBackground(const JSCallbackInfo & info)7850 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
7851 {
7852     // Check the parameters
7853     if (info.Length() <= 0 || !info[0]->IsObject()) {
7854         return;
7855     }
7856     JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
7857     auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
7858     if (!builder->IsFunction()) {
7859         return;
7860     }
7861     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7862     CHECK_NULL_VOID(builderFunc);
7863     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7864     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7865         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7866         ACE_SCORING_EVENT("BindBackground");
7867         PipelineContext::SetCallBackNode(node);
7868         func->Execute();
7869     };
7870     Alignment alignment = Alignment::CENTER;
7871     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
7872         JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
7873         auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
7874         auto value = align->ToNumber<int32_t>();
7875         alignment = ParseAlignment(value);
7876     }
7877     ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
7878 }
7879 
JsBindContextMenu(const JSCallbackInfo & info)7880 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
7881 {
7882     NG::MenuParam menuParam;
7883     // Check the parameters
7884     if (info.Length() <= 0) {
7885         return;
7886     }
7887     size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
7888     if (!info[builderIndex]->IsObject()) {
7889         return;
7890     }
7891 
7892     JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
7893     auto builder = menuObj->GetProperty("builder");
7894     if (!builder->IsFunction()) {
7895         return;
7896     }
7897     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7898     CHECK_NULL_VOID(builderFunc);
7899 
7900     ResponseType responseType = ResponseType::LONG_PRESS;
7901     if (!info[0]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7902         auto response = info[1]->ToNumber<int32_t>();
7903         responseType = static_cast<ResponseType>(response);
7904     }
7905     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7906     std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
7907                                           node = frameNode]() {
7908         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7909         ACE_SCORING_EVENT("BuildContextMenu");
7910         PipelineContext::SetCallBackNode(node);
7911         func->Execute();
7912     };
7913 
7914     menuParam.previewMode = MenuPreviewMode::NONE;
7915     std::function<void()> previewBuildFunc = nullptr;
7916     if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) {
7917         ParseBindContentOptionParam(info, info[2], menuParam, previewBuildFunc);
7918     }
7919 
7920     if (responseType != ResponseType::LONG_PRESS) {
7921         menuParam.previewMode = MenuPreviewMode::NONE;
7922         menuParam.isShowHoverImage = false;
7923         menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
7924     }
7925     menuParam.type = NG::MenuType::CONTEXT_MENU;
7926     ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
7927     ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
7928 }
7929 
ParseBindContentCoverIsShow(const JSCallbackInfo & info)7930 bool ParseBindContentCoverIsShow(const JSCallbackInfo& info)
7931 {
7932     bool isShow = false;
7933     if (info[0]->IsBoolean()) {
7934         isShow = info[0]->ToBoolean();
7935     } else if (info[0]->IsObject()) {
7936         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7937         auto isShowObj = callbackObj->GetProperty("value");
7938         isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7939     }
7940     TAG_LOGD(AceLogTag::ACE_SHEET, "ContentCover get isShow is: %{public}d", isShow);
7941     return isShow;
7942 }
7943 
JsBindContentCover(const JSCallbackInfo & info)7944 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
7945 {
7946     // parse isShow
7947     bool isShow = ParseBindContentCoverIsShow(info);
7948     DoubleBindCallback callback = nullptr;
7949     if (info[0]->IsObject()) {
7950         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7951         callback = ParseDoubleBindCallback(info, callbackObj);
7952     }
7953 
7954     // parse builder
7955     if (!info[1]->IsObject()) {
7956         return;
7957     }
7958     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7959     auto builder = obj->GetProperty("builder");
7960     if (!builder->IsFunction()) {
7961         return;
7962     }
7963     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7964     CHECK_NULL_VOID(builderFunc);
7965     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7966     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7967         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7968         ACE_SCORING_EVENT("BindContentCover");
7969         PipelineContext::SetCallBackNode(node);
7970         func->Execute();
7971     };
7972 
7973     // parse ModalTransition
7974     NG::ModalStyle modalStyle;
7975     modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
7976     std::function<void()> onShowCallback;
7977     std::function<void()> onDismissCallback;
7978     std::function<void()> onWillShowCallback;
7979     std::function<void()> onWillDismissCallback;
7980     NG::ContentCoverParam contentCoverParam;
7981     std::function<void(const int32_t&)> onWillDismissFunc;
7982     if (info.Length() == 3) {
7983         if (info[2]->IsObject()) {
7984             ParseOverlayCallback(info[2], onShowCallback, onDismissCallback, onWillShowCallback, /* 2:args index */
7985                 onWillDismissCallback, onWillDismissFunc);
7986             ParseModalStyle(info[2], modalStyle);
7987             contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
7988             ParseModalTransitonEffect(info[2], contentCoverParam, info.GetExecutionContext()); /* 2:args index */
7989         } else if (info[2]->IsNumber()) {
7990             auto transitionNumber = info[2]->ToNumber<int32_t>();
7991             if (transitionNumber >= 0 && transitionNumber <= 2) {
7992                 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7993             }
7994         }
7995     }
7996     ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
7997         std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
7998         std::move(onWillDismissCallback), contentCoverParam);
7999 }
8000 
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)8001 void JSViewAbstract::ParseModalTransitonEffect(
8002     const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
8003 {
8004     auto transitionEffectValue = paramObj->GetProperty("transition");
8005     if (transitionEffectValue->IsObject()) {
8006         JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
8007         contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
8008     }
8009 }
8010 
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)8011 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
8012 {
8013     auto modalTransition = paramObj->GetProperty("modalTransition");
8014     auto backgroundColor = paramObj->GetProperty("backgroundColor");
8015     if (modalTransition->IsNumber()) {
8016         auto transitionNumber = modalTransition->ToNumber<int32_t>();
8017         if (transitionNumber >= 0 && transitionNumber <= 2) {
8018             modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
8019         }
8020     }
8021     Color color;
8022     if (ParseJsColor(backgroundColor, color)) {
8023         modalStyle.backgroundColor = color;
8024     }
8025 }
8026 
ParseSheetIsShow(const JSCallbackInfo & info,bool & isShow,std::function<void (const std::string &)> & callback)8027 void JSViewAbstract::ParseSheetIsShow(
8028     const JSCallbackInfo& info, bool& isShow, std::function<void(const std::string&)>& callback)
8029 {
8030     if (info[0]->IsBoolean()) {
8031         isShow = info[0]->ToBoolean();
8032     } else if (info[0]->IsObject()) {
8033         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
8034         callback = ParseDoubleBindCallback(info, callbackObj);
8035         auto isShowObj = callbackObj->GetProperty("value");
8036         isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
8037     }
8038     TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet get isShow is: %{public}d", isShow);
8039 }
8040 
JsBindSheet(const JSCallbackInfo & info)8041 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
8042 {
8043     // parse isShow and builder
8044     bool isShow = false;
8045     DoubleBindCallback callback = nullptr;
8046     ParseSheetIsShow(info, isShow, callback);
8047     if (!info[1]->IsObject())
8048         return;
8049     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8050     auto builder = obj->GetProperty("builder");
8051     if (!builder->IsFunction())
8052         return;
8053     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
8054     CHECK_NULL_VOID(builderFunc);
8055     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8056     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
8057         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8058         ACE_SCORING_EVENT("BindSheet");
8059         PipelineContext::SetCallBackNode(node);
8060         func->Execute();
8061     };
8062     // parse SheetStyle and callbacks
8063     NG::SheetStyle sheetStyle;
8064     sheetStyle.sheetHeight.sheetMode = NG::SheetMode::LARGE;
8065     sheetStyle.showDragBar = true;
8066     sheetStyle.showCloseIcon = true;
8067     sheetStyle.showInPage = false;
8068     std::function<void()> onAppearCallback;
8069     std::function<void()> onDisappearCallback;
8070     std::function<void()> onWillAppearCallback;
8071     std::function<void()> onWillDisappearCallback  ;
8072     std::function<void()> shouldDismissFunc;
8073     std::function<void(const int32_t)> onWillDismissCallback;
8074     std::function<void(const float)> onHeightDidChangeCallback;
8075     std::function<void(const float)> onDetentsDidChangeCallback;
8076     std::function<void(const float)> onWidthDidChangeCallback;
8077     std::function<void(const float)> onTypeDidChangeCallback;
8078     std::function<void()> titleBuilderFunction;
8079     std::function<void()> sheetSpringBackFunc;
8080     if (info.Length() == PARAMETER_LENGTH_THIRD && info[SECOND_INDEX]->IsObject()) {
8081         ParseSheetCallback(info[SECOND_INDEX], onAppearCallback, onDisappearCallback, shouldDismissFunc,
8082             onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
8083             onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
8084         ParseSheetStyle(info[2], sheetStyle);
8085         ParseSheetTitle(info[2], sheetStyle, titleBuilderFunction);
8086     }
8087     ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
8088         std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
8089         std::move(shouldDismissFunc), std::move(onWillDismissCallback),  std::move(onWillAppearCallback),
8090         std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
8091         std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
8092 }
8093 
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)8094 void JSViewAbstract::ParseSheetStyle(
8095     const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
8096 {
8097     auto height = paramObj->GetProperty("height");
8098     auto showDragBar = paramObj->GetProperty("dragBar");
8099     auto backgroundColor = paramObj->GetProperty("backgroundColor");
8100     auto maskColor = paramObj->GetProperty("maskColor");
8101     auto sheetDetents = paramObj->GetProperty("detents");
8102     auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
8103     auto showCloseIcon = paramObj->GetProperty("showClose");
8104     auto type = paramObj->GetProperty("preferType");
8105     auto interactive = paramObj->GetProperty("enableOutsideInteractive");
8106     auto showMode = paramObj->GetProperty("mode");
8107     auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
8108     auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
8109     auto uiContextObj = paramObj->GetProperty("uiContext");
8110     if (uiContextObj->IsObject()) {
8111         JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
8112         auto prop = obj->GetProperty("instanceId_");
8113         if (prop->IsNumber()) {
8114             sheetStyle.instanceId = prop->ToNumber<int32_t>();
8115         }
8116     }
8117     NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
8118     if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
8119         sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
8120     }
8121 
8122     std::vector<NG::SheetHeight> detents;
8123     if (ParseSheetDetents(sheetDetents, detents)) {
8124         sheetStyle.detents = detents;
8125     }
8126     BlurStyleOption styleOption;
8127     if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
8128         sheetStyle.backgroundBlurStyle = styleOption;
8129     }
8130     bool showClose = true;
8131     if (ParseJsBool(showCloseIcon, showClose)) {
8132         sheetStyle.showCloseIcon = showClose;
8133     } else if (!isPartialUpdate) {
8134         sheetStyle.showCloseIcon = true;
8135     }
8136 
8137     bool isInteractive = false;
8138     if (ParseJsBool(interactive, isInteractive)) {
8139         sheetStyle.interactive = isInteractive;
8140     }
8141 
8142     if (showDragBar->IsBoolean()) {
8143         sheetStyle.showDragBar = showDragBar->ToBoolean();
8144     } else if (isPartialUpdate) {
8145         sheetStyle.showDragBar.reset();
8146     } else {
8147         sheetStyle.showDragBar = true;
8148     }
8149 
8150     if (type->IsNull() || type->IsUndefined()) {
8151         sheetStyle.sheetType.reset();
8152     } else {
8153         if (type->IsNumber()) {
8154             auto sheetType = type->ToNumber<int32_t>();
8155             if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
8156                 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
8157                 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
8158             }
8159         }
8160     }
8161     if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
8162         sheetStyle.scrollSizeMode.reset();
8163     } else if (scrollSizeMode->IsNumber()) {
8164         auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
8165         if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
8166             sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
8167             sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
8168         }
8169     }
8170 
8171     if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
8172         sheetStyle.sheetKeyboardAvoidMode.reset();
8173     } else if (keyboardAvoidMode->IsNumber()) {
8174         auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
8175         if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
8176             sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) {
8177             sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
8178         }
8179     }
8180 
8181     Color color;
8182     if (ParseJsColor(backgroundColor, color)) {
8183         sheetStyle.backgroundColor = color;
8184     }
8185     // parse maskColor
8186     Color parseMaskColor;
8187     if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
8188         sheetStyle.maskColor = std::move(parseMaskColor);
8189     }
8190 
8191     // Parse border width
8192     auto borderWidthValue = paramObj->GetProperty("borderWidth");
8193     NG::BorderWidthProperty borderWidth;
8194     if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
8195         sheetStyle.borderWidth = borderWidth;
8196         // Parse border color
8197         auto colorValue = paramObj->GetProperty("borderColor");
8198         NG::BorderColorProperty borderColor;
8199         if (ParseBorderColorProps(colorValue, borderColor)) {
8200             sheetStyle.borderColor = borderColor;
8201         } else {
8202             sheetStyle.borderColor =
8203                 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
8204         }
8205         // Parse border style
8206         auto styleValue = paramObj->GetProperty("borderStyle");
8207         NG::BorderStyleProperty borderStyle;
8208         if (ParseBorderStyleProps(styleValue, borderStyle)) {
8209             sheetStyle.borderStyle = borderStyle;
8210         } else {
8211             sheetStyle.borderStyle = NG::BorderStyleProperty(
8212                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
8213         }
8214     }
8215     if (isPartialUpdate) {
8216         auto colorValue = paramObj->GetProperty("borderColor");
8217         NG::BorderColorProperty borderColor;
8218         if (ParseBorderColorProps(colorValue, borderColor)) {
8219             sheetStyle.borderColor = borderColor;
8220         } else {
8221             sheetStyle.borderColor.reset();
8222         }
8223         auto styleValue = paramObj->GetProperty("borderStyle");
8224         NG::BorderStyleProperty borderStyle;
8225         if (ParseBorderStyleProps(styleValue, borderStyle)) {
8226             sheetStyle.borderStyle = borderStyle;
8227         } else {
8228             sheetStyle.borderStyle.reset();
8229         }
8230     }
8231 
8232     // Parse shadow
8233     Shadow shadow;
8234     auto shadowValue = paramObj->GetProperty("shadow");
8235     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
8236         sheetStyle.shadow = shadow;
8237     }
8238 
8239     // Parse hoverMode
8240     auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode");
8241     if (enableHoverModeValue->IsBoolean()) {
8242         sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean();
8243     }
8244     auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea");
8245     if (hoverModeAreaValue->IsNumber()) {
8246         auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
8247         if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
8248             sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
8249         }
8250     }
8251 
8252     auto widthValue = paramObj->GetProperty("width");
8253     CalcDimension width;
8254     if (ParseJsDimensionVpNG(widthValue, width, true)) {
8255         sheetStyle.width = width;
8256     }
8257 
8258     auto radiusValue = paramObj->GetProperty("radius");
8259     ParseBindSheetBorderRadius(radiusValue, sheetStyle);
8260 
8261     ParseDetentSelection(paramObj, sheetStyle);
8262 
8263     NG::SheetHeight sheetStruct;
8264     bool parseResult = ParseSheetHeight(height, sheetStruct, isPartialUpdate);
8265     if (!parseResult) {
8266         TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet height in unnormal condition");
8267     }
8268     sheetStyle.sheetHeight = sheetStruct;
8269 }
8270 
ParseDetentSelection(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)8271 void JSViewAbstract::ParseDetentSelection(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
8272 {
8273     auto detentSelection = paramObj->GetProperty("detentSelection");
8274     NG::SheetHeight sheetStruct;
8275     bool parseResult = ParseSheetHeight(detentSelection, sheetStruct, true);
8276     if (!parseResult) {
8277         sheetStruct.height.reset();
8278         sheetStruct.sheetMode.reset();
8279         TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent selection in unnormal condition");
8280     }
8281     sheetStyle.detentSelection = sheetStruct;
8282 }
8283 
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle)8284 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args, NG::SheetStyle& sheetStyle)
8285 {
8286     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8287         TAG_LOGE(AceLogTag::ACE_SHEET, "radius is not correct type");
8288         return;
8289     }
8290     CalcDimension radius;
8291     NG::BorderRadiusProperty borderRadius;
8292     if (ParseJsLengthMetrics(args, radius)) {
8293         borderRadius.SetRadius(radius);
8294         sheetStyle.radius = borderRadius;
8295     } else if (ParseBindSheetBorderRadiusProps(args, borderRadius)) {
8296         sheetStyle.radius = borderRadius;
8297     } else {
8298         TAG_LOGW(AceLogTag::ACE_SHEET, "radius is not correct.");
8299         return;
8300     }
8301 }
8302 
ParseBindSheetBorderRadiusProps(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)8303 bool JSViewAbstract::ParseBindSheetBorderRadiusProps(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
8304 {
8305     if (args->IsObject()) {
8306         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
8307         if (CheckLengthMetrics(object)) {
8308             std::optional<CalcDimension> radiusTopStart = ParseBindSheetBorderRadiusProp(object, TOP_START_PROPERTY);
8309             std::optional<CalcDimension> radiusTopEnd = ParseBindSheetBorderRadiusProp(object, TOP_END_PROPERTY);
8310             std::optional<CalcDimension> radiusBottomStart = ParseBindSheetBorderRadiusProp(object, BOTTOM_START_PROPERTY);
8311             std::optional<CalcDimension> radiusBottomEnd = ParseBindSheetBorderRadiusProp(object, BOTTOM_END_PROPERTY);
8312             auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
8313             radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
8314             radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
8315             radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
8316             radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
8317             radius.multiValued = true;
8318         } else {
8319             ParseBorderRadiusProps(object, radius);
8320         }
8321         return true;
8322     }
8323     return false;
8324 }
8325 
ParseBindSheetBorderRadiusProp(const JSRef<JSObject> & object,const char * prop)8326 std::optional<CalcDimension> JSViewAbstract::ParseBindSheetBorderRadiusProp(
8327     const JSRef<JSObject>& object, const char* prop)
8328 {
8329     if (object->IsEmpty()) {
8330         return std::nullopt;
8331     }
8332     if (object->HasProperty(prop) && object->GetProperty(prop)->IsObject()) {
8333         JSRef<JSObject> propObj = JSRef<JSObject>::Cast(object->GetProperty(prop));
8334         CalcDimension calcDimension;
8335         if (ParseJsLengthMetrics(propObj, calcDimension)) {
8336             return calcDimension;
8337         }
8338     }
8339     return std::nullopt;
8340 }
8341 
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)8342 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
8343 {
8344     if (!args->IsArray()) {
8345         return false;
8346     }
8347     JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
8348     NG::SheetHeight sheetDetent;
8349     for (size_t i = 0; i < array->Length(); i++) {
8350         bool parseResult = ParseSheetHeight(array->GetValueAt(i), sheetDetent, false);
8351         if (!parseResult) {
8352             TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent in unnormal condition");
8353         }
8354         if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
8355             continue;
8356         }
8357         sheetDetents.emplace_back(sheetDetent);
8358         sheetDetent.height.reset();
8359         sheetDetent.sheetMode.reset();
8360     }
8361     return true;
8362 }
8363 
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)8364 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
8365 {
8366     if (args->IsNumber()) {
8367         auto sheetBlurStyle = args->ToNumber<int32_t>();
8368         if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
8369             sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
8370             blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
8371         } else {
8372             return false;
8373         }
8374     } else {
8375         return false;
8376     }
8377     return true;
8378 }
8379 
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)8380 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
8381 {
8382     if (!args->IsNumber()) {
8383         return false;
8384     }
8385     auto sheetMode = args->ToNumber<int32_t>();
8386     if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
8387         sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
8388         sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
8389         return true;
8390     }
8391     return false;
8392 }
8393 
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)8394 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
8395     std::function<void(const float)>& callbackDidChange, const char* prop)
8396 {
8397     auto callBack = paramObj->GetProperty(prop);
8398     if (callBack->IsFunction()) {
8399         RefPtr<JsFunction> jsFunc =
8400             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
8401         callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
8402             JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
8403             func->ExecuteJS(1, &param);
8404         };
8405     }
8406 }
8407 
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)8408 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
8409     std::function<void()>& lifeCycleCallBack, const char* prop)
8410 {
8411     auto callback = paramObj->GetProperty(prop);
8412     if (callback->IsFunction()) {
8413         RefPtr<JsFunction> jsFunc =
8414             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8415         lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
8416     }
8417 }
8418 
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)8419 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
8420     std::function<void()>& sheetSpringBack, const char* prop)
8421 {
8422     auto sheetSpringBackCallback = paramObj->GetProperty(prop);
8423     if (sheetSpringBackCallback->IsFunction()) {
8424         RefPtr<JsFunction> jsFunc =
8425             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
8426         sheetSpringBack = [func = std::move(jsFunc)]() {
8427             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8428             objectTemplate->SetInternalFieldCount(1);
8429             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8430             dismissObj->SetPropertyObject(
8431                 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
8432             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8433             func->ExecuteJS(1, &newJSVal);
8434         };
8435     }
8436 }
8437 
ParseSheetCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & shouldDismiss,std::function<void (const int32_t info)> & onWillDismiss,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const float)> & onHeightDidChange,std::function<void (const float)> & onDetentsDidChange,std::function<void (const float)> & onWidthDidChange,std::function<void (const float)> & onTypeDidChange,std::function<void ()> & sheetSpringBack)8438 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8439     std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
8440     std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
8441     std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
8442     std::function<void(const float)>& onDetentsDidChange,
8443     std::function<void(const float)>& onWidthDidChange,
8444     std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
8445 {
8446     auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
8447     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8448     ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
8449     ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
8450     ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
8451     ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
8452     if (shouldDismissFunc->IsFunction()) {
8453         RefPtr<JsFunction> jsFunc =
8454             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
8455         shouldDismiss = [func = std::move(jsFunc)]() {
8456             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8457             objectTemplate->SetInternalFieldCount(1);
8458             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8459             dismissObj->SetPropertyObject(
8460                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8461             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8462             func->ExecuteJS(1, &newJSVal);
8463         };
8464     }
8465     if (onWillDismissFunc->IsFunction()) {
8466         RefPtr<JsFunction> jsFunc =
8467             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8468         onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
8469             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8470             objectTemplate->SetInternalFieldCount(1);
8471             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8472             dismissObj->SetPropertyObject(
8473                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8474             dismissObj->SetProperty<int32_t>("reason", info);
8475             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8476             func->ExecuteJS(1, &newJSVal);
8477         };
8478     }
8479     ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
8480     ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
8481     ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
8482     ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
8483     ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
8484 }
8485 
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)8486 void JSViewAbstract::ParseSheetTitle(
8487     const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
8488 {
8489     auto title = paramObj->GetProperty("title");
8490     std::string mainTitle;
8491     std::string subtitle;
8492     if (title->IsFunction()) {
8493         sheetStyle.isTitleBuilder = true;
8494         auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
8495         CHECK_NULL_VOID(titleBuilderFunc);
8496         titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
8497             ACE_SCORING_EVENT("BindSheet");
8498             func->Execute();
8499         };
8500     } else if (title->IsObject()) {
8501         JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
8502         sheetStyle.isTitleBuilder = false;
8503         auto sheetTitle = obj->GetProperty("title");
8504         auto sheetSubtitle = obj->GetProperty("subtitle");
8505         if (ParseJsString(sheetTitle, mainTitle)) {
8506             sheetStyle.sheetTitle = mainTitle;
8507         }
8508         if (ParseJsString(sheetSubtitle, subtitle)) {
8509             sheetStyle.sheetSubtitle = subtitle;
8510         }
8511     }
8512 }
8513 
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)8514 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8515 {
8516     ViewAbstractModel::GetInstance()->DismissSheet();
8517     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8518 }
8519 
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)8520 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8521 {
8522     ViewAbstractModel::GetInstance()->DismissContentCover();
8523     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8524 }
8525 
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)8526 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8527 {
8528     ViewAbstractModel::GetInstance()->SheetSpringBack();
8529     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8530 }
8531 
ParseSheetMode(const std::string heightStr,NG::SheetHeight & detent)8532 bool JSViewAbstract::ParseSheetMode(const std::string heightStr, NG::SheetHeight& detent)
8533 {
8534     if (heightStr == SHEET_HEIGHT_MEDIUM) {
8535         detent.sheetMode = NG::SheetMode::MEDIUM;
8536         return true;
8537     }
8538 
8539     if (heightStr == SHEET_HEIGHT_LARGE) {
8540         detent.sheetMode = NG::SheetMode::LARGE;
8541         return true;
8542     }
8543     if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8544         detent.sheetMode = NG::SheetMode::AUTO;
8545         return true;
8546     }
8547     return false;
8548 }
8549 
ParseSheetHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent,bool isReset)8550 bool JSViewAbstract::ParseSheetHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent,
8551     bool isReset)
8552 {
8553     detent.height.reset();
8554     detent.sheetMode.reset();
8555     CalcDimension sheetHeight;
8556     if (args->IsString()) {
8557         std::string heightStr = args->ToString();
8558 
8559         // Remove all " ".
8560         heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8561         std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8562         if (ParseSheetMode(heightStr, detent)) {
8563             return true;
8564         }
8565         if (heightStr.find("calc") != std::string::npos) {
8566             sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8567         } else {
8568             sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8569         }
8570         if (sheetHeight.Value() < 0) {
8571             detent.sheetMode = NG::SheetMode::LARGE;
8572             return false;
8573         }
8574     }
8575     if (!ParseJsDimensionVpNG(args, sheetHeight)) {
8576         if (!isReset) {
8577             detent.sheetMode = NG::SheetMode::LARGE;
8578         }
8579         return false;
8580     }
8581     detent.height = sheetHeight;
8582     return true;
8583 }
8584 
ParseOverlayCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const int32_t & info)> & onWillDismiss)8585 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8586     std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
8587     std::function<void(const int32_t& info)>& onWillDismiss)
8588 {
8589     auto showCallback = paramObj->GetProperty("onAppear");
8590     auto dismissCallback = paramObj->GetProperty("onDisappear");
8591     auto willShowCallback = paramObj->GetProperty("onWillAppear");
8592     auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
8593     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8594     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8595     if (showCallback->IsFunction()) {
8596         RefPtr<JsFunction> jsFunc =
8597             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
8598         onAppear = [func = std::move(jsFunc), node = frameNode]() {
8599             PipelineContext::SetCallBackNode(node);
8600             func->Execute();
8601         };
8602     }
8603     if (dismissCallback->IsFunction()) {
8604         RefPtr<JsFunction> jsFunc =
8605             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
8606         onDisappear = [func = std::move(jsFunc), node = frameNode]() {
8607             PipelineContext::SetCallBackNode(node);
8608             func->Execute();
8609         };
8610     }
8611     if (willShowCallback->IsFunction()) {
8612         RefPtr<JsFunction> jsFunc =
8613             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
8614         onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
8615     }
8616     if (willDismissCallback->IsFunction()) {
8617         RefPtr<JsFunction> jsFunc =
8618             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
8619         onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
8620     }
8621     if (onWillDismissFunc->IsFunction()) {
8622         RefPtr<JsFunction> jsFunc =
8623             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8624         onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
8625             ACE_SCORING_EVENT("contentCover.dismiss");
8626             PipelineContext::SetCallBackNode(node);
8627             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8628             objectTemplate->SetInternalFieldCount(1);
8629             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8630             dismissObj->SetPropertyObject(
8631                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
8632             dismissObj->SetProperty<int32_t>("reason", info);
8633             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8634             func->ExecuteJS(1, &newJSVal);
8635         };
8636     }
8637 }
8638 
JSCreateAnimatableProperty(const JSCallbackInfo & info)8639 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
8640 {
8641     if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
8642         return;
8643     }
8644 
8645     JSRef<JSVal> callback = info[2]; /* 2:args index */
8646     if (!callback->IsFunction()) {
8647         return;
8648     }
8649     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8650     std::string propertyName = info[0]->ToString();
8651     if (info[1]->IsNumber()) {
8652         float numValue = info[1]->ToNumber<float>();
8653         std::function<void(float)> onCallbackEvent;
8654         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8655         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8656                               node = frameNode](const float val) {
8657             ContainerScope scope(id);
8658             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8659             auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
8660             PipelineContext::SetCallBackNode(node);
8661             func->ExecuteJS(1, &newJSVal);
8662         };
8663         ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
8664     } else if (info[1]->IsObject()) {
8665         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8666         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8667             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8668         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8669             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8670         std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
8671         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8672         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8673                               node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
8674             ContainerScope scope(id);
8675             RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
8676             if (!impl) {
8677                 return;
8678             }
8679             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8680             auto newJSVal = JSRef<JSVal>(impl->GetObject());
8681             PipelineContext::SetCallBackNode(node);
8682             func->ExecuteJS(1, &newJSVal);
8683         };
8684         ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
8685             propertyName, animatableArithmetic, onCallbackEvent);
8686     }
8687 }
8688 
JSUpdateAnimatableProperty(const JSCallbackInfo & info)8689 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
8690 {
8691     if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
8692         return;
8693     }
8694 
8695     std::string propertyName = info[0]->ToString();
8696     float numValue = 0.0;
8697     if (info[1]->IsNumber()) {
8698         numValue = info[1]->ToNumber<float>();
8699         ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
8700     } else if (info[1]->IsObject()) {
8701         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8702         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8703             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8704         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8705             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8706         ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
8707     }
8708 }
8709 
JsExpandSafeArea(const JSCallbackInfo & info)8710 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
8711 {
8712     NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
8713     if (info.Length() >= 1 && info[0]->IsArray()) {
8714         auto paramArray = JSRef<JSArray>::Cast(info[0]);
8715         uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
8716         for (size_t i = 0; i < paramArray->Length(); ++i) {
8717             if (!paramArray->GetValueAt(i)->IsNumber() ||
8718                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
8719                 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
8720                 break;
8721             }
8722             safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8723         }
8724         opts.type = safeAreaType;
8725     }
8726     if (info.Length() >= 2 && info[1]->IsArray()) {
8727         auto paramArray = JSRef<JSArray>::Cast(info[1]);
8728         uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
8729         for (size_t i = 0; i < paramArray->Length(); ++i) {
8730             if (!paramArray->GetValueAt(i)->IsNumber() ||
8731                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
8732                 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
8733                 break;
8734             }
8735             safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8736         }
8737         opts.edges = safeAreaEdge;
8738     }
8739 
8740     ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
8741 }
8742 
ParseJSLightSource(JSRef<JSObject> & lightSource)8743 void ParseJSLightSource(JSRef<JSObject>& lightSource)
8744 {
8745     if (lightSource->IsUndefined()) {
8746         return;
8747     }
8748     JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
8749     JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
8750     JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
8751     JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
8752     JSRef<JSVal> color = lightSource->GetProperty("color");
8753 
8754     CalcDimension dimPositionX;
8755     CalcDimension dimPositionY;
8756     CalcDimension dimPositionZ;
8757     if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
8758         JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
8759         JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
8760         ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
8761     }
8762 
8763     if (intensity->IsNumber()) {
8764         float intensityValue = intensity->ToNumber<float>();
8765         ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
8766     }
8767 
8768     Color lightColor;
8769     if (JSViewAbstract::ParseJsColor(color, lightColor)) {
8770         ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
8771     }
8772 }
8773 
JsPointLight(const JSCallbackInfo & info)8774 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
8775 {
8776 #ifdef POINT_LIGHT_ENABLE
8777     if (!info[0]->IsObject()) {
8778         return;
8779     }
8780 
8781     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
8782     JSRef<JSObject> lightSource = object->GetProperty("lightSource");
8783     ParseJSLightSource(lightSource);
8784 
8785     auto resourceWrapper = CreateResourceWrapper();
8786     if (!resourceWrapper) {
8787         return;
8788     }
8789     double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
8790     Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
8791     Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
8792 
8793     JSRef<JSVal> illuminated = object->GetProperty("illuminated");
8794     if (illuminated->IsNumber()) {
8795         uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
8796         ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
8797         ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
8798     }
8799 
8800     JSRef<JSVal> bloom = object->GetProperty("bloom");
8801     if (bloom->IsNumber()) {
8802         float bloomValue = bloom->ToNumber<float>();
8803         ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
8804 
8805         Shadow shadow;
8806         shadow.SetBlurRadius(bloomValue * bloomRadius);
8807         shadow.SetColor(bloomColor);
8808         std::vector<Shadow> shadows { shadow };
8809         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8810     }
8811 #endif
8812 }
8813 
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)8814 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
8815 {
8816     if (info[0]->IsBoolean()) {
8817         ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
8818     }
8819 }
8820 
JsCancelDataLoading(const std::string & key)8821 void JSViewAbstract::JsCancelDataLoading(const std::string& key)
8822 {
8823     auto ret = ViewAbstractModel::GetInstance()->CancelDataLoading(key);
8824     if (ret != 0) {
8825         JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Invalid input parameter.");
8826     }
8827 }
8828 
JSBind(BindingTarget globalObj)8829 void JSViewAbstract::JSBind(BindingTarget globalObj)
8830 {
8831     JSClass<JSViewAbstract>::Declare("JSViewAbstract");
8832 
8833     // static methods
8834     MethodOptions opt = MethodOptions::NONE;
8835     JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
8836 
8837     JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
8838     JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
8839     JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
8840     JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
8841     JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
8842     JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
8843     JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
8844     JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSViewAbstract::JsPixelRound);
8845     JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
8846     JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSViewAbstract::JsChainWeight);
8847 
8848     JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
8849     JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
8850     JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
8851     JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
8852     JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
8853 
8854     JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
8855     JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
8856     JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
8857     JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
8858     JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
8859     JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
8860 
8861     JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
8862     JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
8863     JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
8864     JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
8865     JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
8866     JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
8867     JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
8868     JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
8869     JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
8870     JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
8871     JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
8872     JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
8873     JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
8874     JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
8875     JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
8876     JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
8877     JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
8878     JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
8879     JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
8880     JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
8881     JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
8882     JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
8883     JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
8884     JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
8885 
8886     JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
8887     JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
8888     JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
8889     JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
8890     JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
8891     JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
8892     JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
8893     JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
8894     JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
8895     JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
8896     JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
8897     JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
8898 
8899     JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
8900     JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
8901     JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
8902     JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
8903     JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
8904     JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
8905     JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
8906 
8907     JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
8908     JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
8909     JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
8910     JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
8911     JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
8912     JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
8913     JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
8914     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
8915     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal",
8916         &JSViewAbstract::JsBackgroundBrightnessInternal);
8917     JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
8918     JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
8919     JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
8920     JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
8921     JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
8922     JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
8923     JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
8924     JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
8925     JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
8926     JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
8927     JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
8928     JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
8929 #ifndef WEARABLE_PRODUCT
8930     JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
8931 #endif
8932 
8933     JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
8934     JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
8935     JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
8936     JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
8937     JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
8938     JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
8939     JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
8940     JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
8941     JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
8942     JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
8943     JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
8944     JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
8945     JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
8946     JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
8947 
8948     JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
8949     JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
8950     JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
8951     JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
8952     JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
8953     JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
8954     JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
8955     JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
8956     JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
8957     JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
8958     JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
8959     JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
8960     JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
8961     JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
8962     JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
8963     JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
8964     JSClass<JSViewAbstract>::StaticMethod("onKeyEventDispatch", &JSInteractableView::JsOnKeyEventDispatch);
8965     JSClass<JSViewAbstract>::StaticMethod("dispatchKeyEvent", &JSViewAbstract::JsDispatchKeyEvent);
8966     JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
8967     JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
8968     JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
8969     JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
8970     JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
8971     JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
8972     JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
8973     JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
8974     JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
8975     JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
8976     JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
8977     JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
8978     JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
8979     JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
8980     JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
8981     JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
8982     JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
8983     JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
8984     JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
8985     JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
8986     JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
8987     JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
8988     JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
8989     JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
8990     JSClass<JSViewAbstract>::StaticMethod("onHoverMove", &JSViewAbstract::JsOnHoverMove);
8991     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
8992     JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
8993     JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
8994     JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
8995     JSClass<JSViewAbstract>::StaticMethod(
8996         "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
8997     JSClass<JSViewAbstract>::StaticMethod(
8998         "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
8999     JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
9000     JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
9001     JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
9002     JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
9003     JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
9004     JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
9005     JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
9006     JSClass<JSViewAbstract>::StaticMethod("onFocusAxisEvent", &JSViewAbstract::JsOnFocusAxisEvent);
9007 
9008     JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
9009     JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
9010     JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
9011     JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
9012     JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
9013     JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
9014     JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
9015     JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
9016     JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
9017 
9018     JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
9019     JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
9020     JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
9021     JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
9022     JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
9023     JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
9024     JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
9025     JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
9026     JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
9027     JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
9028     JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
9029 
9030     JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
9031     JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
9032     JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
9033     JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
9034 
9035     JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
9036 
9037     JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
9038 
9039     JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
9040     JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
9041     JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
9042 
9043     JSClass<JSViewAbstract>::StaticMethod(
9044         "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
9045     JSClass<JSViewAbstract>::StaticMethod("cancelDataLoading", &JSViewAbstract::JsCancelDataLoading);
9046 
9047     JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
9048     JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
9049 
9050     JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
9051     JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
9052     JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
9053     JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
9054 
9055     JSClass<JSViewAbstract>::Bind(globalObj);
9056 }
9057 
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)9058 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
9059 {
9060     auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
9061         auto vm = info->GetVM();
9062         CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
9063         Local<JSValueRef> thisObj = info->GetFunctionRef();
9064         auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
9065         if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
9066             return panda::JSValueRef::Undefined(vm);
9067         }
9068 
9069         auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
9070         if (weak->Invalid()) {
9071             return panda::JSValueRef::Undefined(vm);
9072         }
9073 
9074         auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
9075         if (frameNode) {
9076             const auto& extensionHandler = frameNode->GetExtensionHandler();
9077             if (extensionHandler) {
9078                 extensionHandler->InvalidateRender();
9079             } else {
9080                 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9081             }
9082         }
9083 
9084         return panda::JSValueRef::Undefined(vm);
9085     };
9086     auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
9087     if (frameNode) {
9088         const auto& extensionHandler = frameNode->GetExtensionHandler();
9089         if (extensionHandler) {
9090             extensionHandler->InvalidateRender();
9091         } else {
9092             frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9093         }
9094     }
9095     auto vm = jsInvalidate->GetEcmaVM();
9096     auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
9097     jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
9098     jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
9099     jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
9100 }
9101 
JsDrawModifier(const JSCallbackInfo & info)9102 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
9103 {
9104     if (!info[0]->IsObject()) {
9105         return;
9106     }
9107 
9108     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9109     bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
9110     if (!IsSupportDrawModifier) {
9111         return;
9112     }
9113     auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
9114     RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
9115     auto execCtx = info.GetExecutionContext();
9116     auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
9117         JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
9118         if (!drawMethod->IsFunction()) {
9119             return nullptr;
9120         }
9121 
9122         auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
9123             JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
9124 
9125         return GetDrawCallback(jsDrawFunc, execCtx);
9126     };
9127 
9128     drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
9129     drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
9130     drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
9131 
9132     ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
9133     AddInvalidateFunc(jsDrawModifier, frameNode);
9134 }
9135 
JsAllowDrop(const JSCallbackInfo & info)9136 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
9137 {
9138     std::set<std::string> allowDropSet;
9139     allowDropSet.clear();
9140     if (!info[0]->IsUndefined() && info[0]->IsArray()) {
9141         auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
9142         std::string allowDrop;
9143         for (size_t i = 0; i < allowDropArray->Length(); i++) {
9144             allowDrop = allowDropArray->GetValueAt(i)->ToString();
9145             allowDropSet.insert(allowDrop);
9146         }
9147         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9148     } else if (info[0]->IsNull()) {
9149         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
9150     } else {
9151         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9152     }
9153     ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
9154 }
9155 
JsOnPreDrag(const JSCallbackInfo & info)9156 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
9157 {
9158     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
9159     auto jsVal = info[0];
9160     if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
9161         return;
9162     }
9163     RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
9164     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9165     auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
9166                          const PreDragStatus preDragStatus) {
9167         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9168         ACE_SCORING_EVENT("onPreDrag");
9169         PipelineContext::SetCallBackNode(node);
9170         func->PreDragExecute(preDragStatus);
9171     };
9172     ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
9173 }
9174 
ParseDragPreviewConfig(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9175 void JSViewAbstract::ParseDragPreviewConfig(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9176 {
9177     if (info.Length() <= 1) {
9178         return;
9179     }
9180     auto jsVal = info[1];
9181     if (!jsVal->IsObject()) {
9182         return;
9183     }
9184     auto config = JSRef<JSObject>::Cast(jsVal);
9185     ParseJsBool(config->GetProperty("onlyForLifting"), dragPreviewInfo.onlyForLifting);
9186     ParseJsBool(config->GetProperty("delayCreating"), dragPreviewInfo.delayCreating);
9187 }
9188 
ParseDragPreviewValue(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9189 void JSViewAbstract::ParseDragPreviewValue(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9190 {
9191     auto jsVal = info[0];
9192     JSRef<JSVal> builder;
9193     JSRef<JSVal> pixelMap;
9194     JSRef<JSVal> extraInfo;
9195     if (jsVal->IsFunction()) {
9196         builder = jsVal;
9197     } else if (jsVal->IsObject()) {
9198         auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
9199         builder = dragItemInfo->GetProperty("builder");
9200 #if defined(PIXEL_MAP_SUPPORTED)
9201         pixelMap = dragItemInfo->GetProperty("pixelMap");
9202         dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
9203 #endif
9204         extraInfo = dragItemInfo->GetProperty("extraInfo");
9205         ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
9206     } else if (jsVal->IsString()) {
9207         auto inspectorId = jsVal;
9208         ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
9209     } else {
9210         return;
9211     }
9212     ParseDragPreviewBuilderNode(info, dragPreviewInfo, builder);
9213 }
9214 
ParseDragPreviewBuilderNode(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo,const JSRef<JSVal> & builder)9215 void JSViewAbstract::ParseDragPreviewBuilderNode(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo,
9216     const JSRef<JSVal>& builder)
9217 {
9218     if (!builder->IsFunction()) {
9219         return;
9220     }
9221     RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9222     CHECK_NULL_VOID(builderFunc);
9223     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9224     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
9225                          node = frameNode]() -> RefPtr<NG::UINode> {
9226         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
9227         ACE_SCORING_EVENT("dragPreview.builder");
9228         PipelineContext::SetCallBackNode(node);
9229         func->Execute();
9230         auto customNode = ViewStackModel::GetInstance()->Finish();
9231         return AceType::DynamicCast<NG::UINode>(customNode);
9232     };
9233     if (!dragPreviewInfo.delayCreating) {
9234         ViewStackModel::GetInstance()->NewScope();
9235         {
9236             dragPreviewInfo.customNode = buildFunc();
9237         }
9238     } else {
9239         dragPreviewInfo.buildFunc = buildFunc;
9240     }
9241 }
9242 
JsDragPreview(const JSCallbackInfo & info)9243 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
9244 {
9245     auto jsVal = info[0];
9246     if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
9247         return;
9248     }
9249     NG::DragDropInfo dragPreviewInfo;
9250     ParseDragPreviewConfig(info, dragPreviewInfo);
9251     ParseDragPreviewValue(info, dragPreviewInfo);
9252     ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
9253 }
9254 
JsAlignRules(const JSCallbackInfo & info)9255 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
9256 {
9257     if (!info[0]->IsObject()) {
9258         return;
9259     }
9260 
9261     JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
9262     if (valueObj->IsEmpty()) {
9263         return;
9264     }
9265     const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
9266     std::map<AlignDirection, AlignRule> alignRules;
9267     BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
9268     for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
9269         auto rule = valueObj->GetProperty(keys[i]);
9270         if (rule->IsObject()) {
9271             JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
9272             JSRef<JSVal> align = val->GetProperty("align");
9273             AlignRule alignRule;
9274             alignRule.anchor = val->GetProperty("anchor")->ToString();
9275             if (i < HORIZONTAL_DIRECTION_RANGE) {
9276                 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9277             } else {
9278                 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9279             }
9280             if (i < VERTICAL_DIRECTION_RANGE) {
9281                 alignRules[static_cast<AlignDirection>(i)] = alignRule;
9282             } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
9283                 alignRules[AlignDirection::LEFT] = alignRule;
9284             } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
9285                 alignRules[AlignDirection::RIGHT] = alignRule;
9286             }
9287             auto biasX = val->GetProperty("horizontal");
9288             if (biasX->IsNumber()) {
9289                 biasPair.first = biasX->ToNumber<float>();
9290             }
9291             auto biasY = val->GetProperty("vertical");
9292             if (biasY->IsNumber()) {
9293                 biasPair.second = biasY->ToNumber<float>();
9294             }
9295         }
9296     }
9297 
9298     ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
9299     ViewAbstractModel::GetInstance()->SetBias(biasPair);
9300 }
9301 
JsChainMode(const JSCallbackInfo & info)9302 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
9303 {
9304     ChainInfo chainInfo;
9305     if (info.Length() >= 1) {
9306         auto tmpDirection = info[0];
9307         if (tmpDirection->IsUndefined()) {
9308             chainInfo.direction = std::nullopt;
9309         } else if (tmpDirection->IsNumber()) {
9310             auto direction = tmpDirection->ToNumber<int32_t>();
9311             chainInfo.direction = static_cast<LineDirection>(direction);
9312         }
9313     }
9314 
9315     if (info.Length() >= 2) { // 2 : two args
9316         auto tmpStyle = info[1];
9317         if (tmpStyle->IsUndefined()) {
9318             chainInfo.style = std::nullopt;
9319         } else if (tmpStyle->IsNumber()) {
9320             auto style = tmpStyle->ToNumber<int32_t>();
9321             chainInfo.style = static_cast<ChainStyle>(style);
9322         }
9323     }
9324     ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
9325 }
9326 
SetMarginTop(const JSCallbackInfo & info)9327 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
9328 {
9329     CalcDimension value;
9330     if (!ParseJsDimensionVp(info[0], value)) {
9331         return;
9332     }
9333     ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
9334 }
9335 
SetMarginBottom(const JSCallbackInfo & info)9336 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
9337 {
9338     CalcDimension value;
9339     if (!ParseJsDimensionVp(info[0], value)) {
9340         return;
9341     }
9342     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
9343 }
9344 
SetMarginLeft(const JSCallbackInfo & info)9345 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
9346 {
9347     CalcDimension value;
9348     if (!ParseJsDimensionVp(info[0], value)) {
9349         return;
9350     }
9351     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
9352 }
9353 
SetMarginRight(const JSCallbackInfo & info)9354 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
9355 {
9356     CalcDimension value;
9357     if (!ParseJsDimensionVp(info[0], value)) {
9358         return;
9359     }
9360     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
9361 }
9362 
SetPaddingTop(const JSCallbackInfo & info)9363 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
9364 {
9365     CalcDimension value;
9366     if (!ParseJsDimensionVp(info[0], value)) {
9367         return;
9368     }
9369     ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
9370 }
9371 
SetPaddingBottom(const JSCallbackInfo & info)9372 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
9373 {
9374     CalcDimension value;
9375     if (!ParseJsDimensionVp(info[0], value)) {
9376         return;
9377     }
9378     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
9379 }
9380 
SetPaddingLeft(const JSCallbackInfo & info)9381 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
9382 {
9383     CalcDimension value;
9384     if (!ParseJsDimensionVp(info[0], value)) {
9385         return;
9386     }
9387     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
9388 }
9389 
SetPaddingRight(const JSCallbackInfo & info)9390 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
9391 {
9392     CalcDimension value;
9393     if (!ParseJsDimensionVp(info[0], value)) {
9394         return;
9395     }
9396     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
9397 }
9398 
SetSafeAreaPadding(const JSCallbackInfo & info)9399 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
9400 {
9401     ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
9402 }
9403 
SetColorBlend(Color color)9404 void JSViewAbstract::SetColorBlend(Color color)
9405 {
9406     ViewAbstractModel::GetInstance()->SetColorBlend(color);
9407 }
9408 
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)9409 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
9410 {
9411     ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
9412 }
9413 
SetDynamicLightUp(float rate,float lightUpDegree)9414 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
9415 {
9416     ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
9417 }
9418 
SetBgDynamicBrightness(BrightnessOption brightnessOption)9419 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
9420 {
9421     ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
9422 }
9423 
SetFgDynamicBrightness(BrightnessOption brightnessOption)9424 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
9425 {
9426     ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
9427 }
9428 
SetWindowBlur(float progress,WindowBlurStyle blurStyle)9429 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
9430 {
9431     ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
9432 }
9433 
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)9434 bool JSViewAbstract::ParseJsonDimension(
9435     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
9436 {
9437     if (!jsonValue || jsonValue->IsNull()) {
9438         return false;
9439     }
9440     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9441         return false;
9442     }
9443     if (jsonValue->IsNumber()) {
9444         result = Dimension(jsonValue->GetDouble(), defaultUnit);
9445         return true;
9446     }
9447     if (jsonValue->IsString()) {
9448         if (checkIllegal) {
9449             return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
9450         }
9451         result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
9452         return true;
9453     }
9454     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9455     auto resId = resVal->GetValue("id");
9456     if (!resId || !resId->IsNumber()) {
9457         return false;
9458     }
9459 
9460     auto resourceWrapper = CreateResourceWrapper();
9461     if (!resourceWrapper) {
9462         return false;
9463     }
9464     result = resourceWrapper->GetDimension(resId->GetUInt());
9465     return true;
9466 }
9467 
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)9468 bool JSViewAbstract::ParseJsonDimensionVp(
9469     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
9470 {
9471     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9472         return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
9473     }
9474     return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
9475 }
9476 
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)9477 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
9478 {
9479     if (!jsonValue || jsonValue->IsNull()) {
9480         return false;
9481     }
9482     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9483         return false;
9484     }
9485     if (jsonValue->IsNumber()) {
9486         result = jsonValue->GetDouble();
9487         return true;
9488     }
9489     if (jsonValue->IsString()) {
9490         result = StringUtils::StringToDouble(jsonValue->GetString());
9491         return true;
9492     }
9493     // parse json Resource
9494     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9495     auto resId = resVal->GetValue("id");
9496     CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
9497     auto id = resId->GetUInt();
9498     auto resType = resVal->GetValue("type");
9499     CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
9500     auto type = resType->GetUInt();
9501 
9502     auto resourceWrapper = CreateResourceWrapper();
9503     if (!resourceWrapper) {
9504         return false;
9505     }
9506     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9507         auto numberString = resourceWrapper->GetString(id);
9508         return StringUtils::StringToDouble(numberString, result);
9509     }
9510     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9511         result = resourceWrapper->GetInt(id);
9512         return true;
9513     }
9514     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9515         result = resourceWrapper->GetDouble(id);
9516         return true;
9517     }
9518     return false;
9519 }
9520 
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)9521 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
9522 {
9523     if (!jsonValue || jsonValue->IsNull()) {
9524         return false;
9525     }
9526     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9527         return false;
9528     }
9529     if (jsonValue->IsNumber()) {
9530         result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
9531         return true;
9532     }
9533 
9534     bool isSetColor = false;
9535     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
9536         isSetColor = jsonValue->IsString();
9537     } else {
9538         isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
9539     }
9540     if (isSetColor) {
9541         result = Color::FromString(jsonValue->GetString());
9542         return true;
9543     }
9544     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9545     auto resId = resVal->GetValue("id");
9546     if (!resId || !resId->IsNumber()) {
9547         return false;
9548     }
9549     auto resourceWrapper = CreateResourceWrapper();
9550     if (!resourceWrapper) {
9551         return false;
9552     }
9553     result = resourceWrapper->GetColor(resId->GetUInt());
9554     return true;
9555 }
9556 
ParseShadowOffsetX(const JSRef<JSObject> & jsObj,CalcDimension & offsetX,Shadow & shadow)9557 void JSViewAbstract::ParseShadowOffsetX(const JSRef<JSObject>& jsObj, CalcDimension& offsetX, Shadow& shadow)
9558 {
9559     auto jsOffsetX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_X));
9560     bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
9561     if (ParseJsResource(jsOffsetX, offsetX)) {
9562         double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9563         shadow.SetOffsetX(xValue);
9564     } else {
9565         if (ParseJsDimensionVp(jsOffsetX, offsetX)) {
9566             double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9567             shadow.SetOffsetX(xValue);
9568         }
9569     }
9570 }
9571 
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)9572 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
9573 {
9574     int32_t shadowStyle = 0;
9575     if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
9576         auto style = static_cast<ShadowStyle>(shadowStyle);
9577         return GetShadowFromTheme(style, shadow);
9578     }
9579     if (!jsValue->IsObject()) {
9580         return false;
9581     }
9582     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9583     double radius = 0.0;
9584     ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius);
9585     if (LessNotEqual(radius, 0.0)) {
9586         radius = 0.0;
9587     }
9588     shadow.SetBlurRadius(radius);
9589     CalcDimension offsetX;
9590     ParseShadowOffsetX(jsObj, offsetX, shadow);
9591     CalcDimension offsetY;
9592     auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
9593     if (ParseJsResource(jsOffsetY, offsetY)) {
9594         shadow.SetOffsetY(offsetY.Value());
9595     } else {
9596         if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
9597             shadow.SetOffsetY(offsetY.Value());
9598         }
9599     }
9600     Color color;
9601     ShadowColorStrategy shadowColorStrategy;
9602     auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
9603     if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
9604         shadow.SetShadowColorStrategy(shadowColorStrategy);
9605     } else if (ParseJsColor(jsColor, color)) {
9606         shadow.SetColor(color);
9607     }
9608     int32_t type = static_cast<int32_t>(ShadowType::COLOR);
9609     JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
9610     if (type != static_cast<int32_t>(ShadowType::BLUR)) {
9611         type = static_cast<int32_t>(ShadowType::COLOR);
9612     }
9613     shadow.SetShadowType(static_cast<ShadowType>(type));
9614     bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
9615     shadow.SetIsFilled(isFilled);
9616     return true;
9617 }
9618 
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)9619 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
9620 {
9621     auto colorMode = SystemProperties::GetColorMode();
9622     if (shadowStyle == ShadowStyle::None) {
9623         return true;
9624     }
9625 
9626     auto container = Container::Current();
9627     CHECK_NULL_RETURN(container, false);
9628     auto pipelineContext = container->GetPipelineContext();
9629     CHECK_NULL_RETURN(pipelineContext, false);
9630 
9631     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
9632     if (!shadowTheme) {
9633         return false;
9634     }
9635 
9636     shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
9637     return true;
9638 }
9639 
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)9640 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
9641 {
9642     if (!jsValue->IsObject()) {
9643         return false;
9644     }
9645     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9646     uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
9647     if (type == 0) {
9648         return false;
9649     }
9650     auto resourceWrapper = CreateResourceWrapper();
9651     CHECK_NULL_RETURN(resourceWrapper, false);
9652     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9653         auto value = resourceWrapper->GetString(
9654             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9655         return StringUtils::StringToCalcDimensionNG(value, result, false);
9656     }
9657     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9658         auto value = std::to_string(
9659             resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
9660         StringUtils::StringToDimensionWithUnitNG(value, result);
9661         return true;
9662     }
9663 
9664     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9665         result = resourceWrapper->GetDimension(
9666             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9667         return true;
9668     }
9669     return false;
9670 }
9671 
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)9672 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
9673 {
9674     JSRef<JSVal> arg = info[0];
9675     if (!arg->IsObject()) {
9676         return false;
9677     }
9678     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
9679     JSRef<JSVal> typeValue = obj->GetProperty("types");
9680     if (!typeValue->IsArray()) {
9681         return false;
9682     }
9683     JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
9684     for (size_t i = 0; i < array->Length(); i++) {
9685         JSRef<JSVal> value = array->GetValueAt(i);
9686         auto index = value->ToNumber<int32_t>();
9687         if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
9688             return false;
9689         }
9690         if (i != 0) {
9691             textDetectConfig.types.append(",");
9692         }
9693         textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
9694     }
9695     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9696     JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
9697     if (resultCallback->IsFunction()) {
9698         auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
9699         textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
9700                        const std::string& result) {
9701             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9702             PipelineContext::SetCallBackNode(node);
9703             func->Execute(result);
9704         };
9705     }
9706 
9707     return ParseAIEntityColor(obj, textDetectConfig);
9708 }
9709 
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)9710 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
9711 {
9712     JSRef<JSVal> entityColorValue = obj->GetProperty("color");
9713     ParseJsColor(entityColorValue, textDetectConfig.entityColor);
9714 
9715     JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
9716     if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
9717         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9718         return true;
9719     }
9720     JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
9721     JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
9722     JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
9723     JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
9724 
9725     if (typeValue->IsNumber()) {
9726         textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
9727     } else {
9728         textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
9729     }
9730     if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) {
9731         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9732     }
9733     if (styleValue->IsNumber()) {
9734          textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
9735     } else {
9736         textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
9737     }
9738 
9739     return true;
9740 }
9741 
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)9742 void JSViewAbstract::GetAngle(
9743     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
9744 {
9745     auto value = jsonValue->GetValue(key);
9746     if (value && value->IsString()) {
9747         angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
9748     } else if (value && value->IsNumber()) {
9749         angle = static_cast<float>(value->GetDouble());
9750     }
9751 }
9752 
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)9753 void JSViewAbstract::GetJsAngle(
9754     int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
9755 {
9756     if (!jsValue->IsObject()) {
9757         return;
9758     }
9759     JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
9760     if (value->IsString()) {
9761         angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
9762     } else if (value->IsNumber()) {
9763         angle = value->ToNumber<float>();
9764     }
9765 }
9766 
9767 // 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)9768 void JSViewAbstract::GetJsAngleWithDefault(
9769     int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
9770 {
9771     JSRef<JSVal> value = jsObj->GetProperty(key);
9772     if (value->IsString()) {
9773         double temp = 0.0;
9774         if (StringUtils::StringToDegree(value->ToString(), temp)) {
9775             angle = static_cast<float>(temp);
9776         } else {
9777             angle = defaultValue;
9778         }
9779     } else if (value->IsNumber()) {
9780         angle = value->ToNumber<float>();
9781     }
9782 }
9783 
CheckAngle(std::optional<float> & angle)9784 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
9785 {
9786     angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
9787 }
9788 
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)9789 void JSViewAbstract::GetPerspective(
9790     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
9791 {
9792     auto value = jsonValue->GetValue(key);
9793     if (value && value->IsNumber()) {
9794         perspective = static_cast<float>(value->GetDouble());
9795     }
9796 }
9797 
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)9798 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
9799 {
9800     auto value = jsValue->GetProperty(key);
9801     if (value->IsNumber()) {
9802         perspective = value->ToNumber<float>();
9803     }
9804 }
9805 
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9806 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9807 {
9808     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9809         return;
9810     }
9811 
9812     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9813         GradientColor gradientColor;
9814         auto item = colorStops->GetArrayItem(i);
9815         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9816             auto colorParams = item->GetArrayItem(0);
9817             // color
9818             Color color;
9819             if (!ParseJsonColor(colorParams, color)) {
9820                 continue;
9821             }
9822             gradientColor.SetColor(color);
9823             gradientColor.SetHasValue(false);
9824             // stop value
9825             if (item->GetArraySize() <= 1) {
9826                 continue;
9827             }
9828             auto stopValue = item->GetArrayItem(1);
9829             double value = 0.0;
9830             if (ParseJsonDouble(stopValue, value)) {
9831                 value = std::clamp(value, 0.0, 1.0);
9832                 gradientColor.SetHasValue(true);
9833                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9834             }
9835             gradient.AddColor(gradientColor);
9836         }
9837     }
9838 }
9839 
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9840 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9841 {
9842     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9843         return;
9844     }
9845 
9846     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9847         NG::GradientColor gradientColor;
9848         auto item = colorStops->GetArrayItem(i);
9849         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9850             auto colorParams = item->GetArrayItem(0);
9851             // color
9852             Color color;
9853             if (!ParseJsonColor(colorParams, color)) {
9854                 continue;
9855             }
9856             gradientColor.SetColor(color);
9857             gradientColor.SetHasValue(false);
9858             // stop value
9859             if (item->GetArraySize() <= 1) {
9860                 continue;
9861             }
9862             auto stopValue = item->GetArrayItem(1);
9863             double value = 0.0;
9864             if (ParseJsonDouble(stopValue, value)) {
9865                 value = std::clamp(value, 0.0, 1.0);
9866                 gradientColor.SetHasValue(true);
9867                 //  [0, 1] -> [0, 100.0];
9868                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9869             }
9870             gradient.AddColor(gradientColor);
9871         }
9872     }
9873 }
9874 
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)9875 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
9876 {
9877     if (!colorStops->IsArray()) {
9878         return;
9879     }
9880 
9881     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
9882     size_t length = jsArray->Length();
9883     for (size_t i = 0; i < length; i++) {
9884         NG::GradientColor gradientColor;
9885         JSRef<JSVal> item = jsArray->GetValueAt(i);
9886         if (!item->IsArray()) {
9887             continue;
9888         }
9889         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
9890         if (subArray->Length() < 2) {
9891             continue;
9892         }
9893         // color
9894         Color color;
9895         if (!ParseJsColor(subArray->GetValueAt(0), color)) {
9896             continue;
9897         }
9898         gradientColor.SetColor(color);
9899         gradientColor.SetHasValue(false);
9900         // stop value
9901         double value = 0.0;
9902         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
9903             value = std::clamp(value, 0.0, 1.0);
9904             gradientColor.SetHasValue(true);
9905         }
9906         //  [0, 1] -> [0, 100.0];
9907         gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9908         gradient.AddColor(gradientColor);
9909     }
9910 }
9911 
SetDirection(const std::string & dir)9912 void JSViewAbstract::SetDirection(const std::string& dir)
9913 {
9914     TextDirection direction = TextDirection::AUTO;
9915     if (dir == "Ltr") {
9916         direction = TextDirection::LTR;
9917     } else if (dir == "Rtl") {
9918         direction = TextDirection::RTL;
9919     } else if (dir == "Auto") {
9920         direction = TextDirection::AUTO;
9921     } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9922         direction = TextDirection::AUTO;
9923     }
9924     ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
9925 }
9926 
GetThemeConstants(const JSRef<JSObject> & jsObj)9927 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
9928 {
9929     std::string bundleName;
9930     std::string moduleName;
9931     if (!jsObj->IsUndefined()) {
9932         JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
9933         JSRef<JSVal> module = jsObj->GetProperty("moduleName");
9934         if (bundle->IsString() && module->IsString()) {
9935             bundleName = bundle->ToString();
9936             moduleName = module->ToString();
9937         }
9938     }
9939 
9940     auto cardId = CardScope::CurrentId();
9941     if (cardId != INVALID_CARD_ID) {
9942         auto container = Container::Current();
9943         auto weak = container->GetCardPipeline(cardId);
9944         auto cardPipelineContext = weak.Upgrade();
9945         CHECK_NULL_RETURN(cardPipelineContext, nullptr);
9946         auto cardThemeManager = cardPipelineContext->GetThemeManager();
9947         CHECK_NULL_RETURN(cardThemeManager, nullptr);
9948         return cardThemeManager->GetThemeConstants(bundleName, moduleName);
9949     }
9950 
9951 #ifdef PLUGIN_COMPONENT_SUPPORTED
9952     if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
9953         auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
9954         if (!pluginContainer) {
9955             return nullptr;
9956         }
9957         auto pluginPipelineContext = pluginContainer->GetPipelineContext();
9958         if (!pluginPipelineContext) {
9959             return nullptr;
9960         }
9961         auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
9962         if (!pluginThemeManager) {
9963             return nullptr;
9964         }
9965         return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
9966     }
9967 #endif
9968     auto container = Container::Current();
9969     CHECK_NULL_RETURN(container, nullptr);
9970     auto pipelineContext = container->GetPipelineContext();
9971     CHECK_NULL_RETURN(pipelineContext, nullptr);
9972     auto themeManager = pipelineContext->GetThemeManager();
9973     CHECK_NULL_RETURN(themeManager, nullptr);
9974     return themeManager->GetThemeConstants(bundleName, moduleName);
9975 }
9976 
JsHoverEffect(const JSCallbackInfo & info)9977 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
9978 {
9979     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
9980     auto jsVal = info[0];
9981     if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
9982         ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
9983         return;
9984     }
9985     if (!jsVal->IsNumber()) {
9986         return;
9987     }
9988     ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
9989 }
9990 
JsOnMouse(const JSCallbackInfo & info)9991 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
9992 {
9993     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9994         ViewAbstractModel::GetInstance()->DisableOnMouse();
9995         return;
9996     }
9997     if (!info[0]->IsFunction()) {
9998         return;
9999     }
10000 
10001     RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
10002     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10003     auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
10004                        MouseInfo& mouseInfo) {
10005         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10006         ACE_SCORING_EVENT("onMouse");
10007         PipelineContext::SetCallBackNode(node);
10008         func->Execute(mouseInfo);
10009     };
10010     ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
10011 }
10012 
JsOnHover(const JSCallbackInfo & info)10013 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
10014 {
10015     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10016         ViewAbstractModel::GetInstance()->DisableOnHover();
10017         return;
10018     }
10019     if (!info[0]->IsFunction()) {
10020         return;
10021     }
10022 
10023     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10024     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10025     auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
10026                        bool isHover, HoverInfo& hoverInfo) {
10027         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10028         ACE_SCORING_EVENT("onHover");
10029         PipelineContext::SetCallBackNode(node);
10030         func->HoverExecute(isHover, hoverInfo);
10031     };
10032     ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
10033 }
10034 
JsOnHoverMove(const JSCallbackInfo & info)10035 void JSViewAbstract::JsOnHoverMove(const JSCallbackInfo& info)
10036 {
10037     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10038         ViewAbstractModel::GetInstance()->DisableOnHoverMove();
10039         return;
10040     }
10041     if (!info[0]->IsFunction()) {
10042         return;
10043     }
10044 
10045     RefPtr<JsHoverFunction> jsOnHoverMoveFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10046     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10047     auto onHoverMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverMoveFunc), node = frameNode](
10048                        HoverInfo& hoverInfo) {
10049         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10050         ACE_SCORING_EVENT("onHoverMove");
10051         PipelineContext::SetCallBackNode(node);
10052         func->HoverMoveExecute(hoverInfo);
10053     };
10054     ViewAbstractModel::GetInstance()->SetOnHoverMove(std::move(onHoverMove));
10055 }
10056 
JsOnAccessibilityHover(const JSCallbackInfo & info)10057 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
10058 {
10059     if (info[0]->IsUndefined()) {
10060         ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
10061         return;
10062     }
10063     if (!info[0]->IsFunction()) {
10064         return;
10065     }
10066 
10067     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10068     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10069     auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
10070                                     node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
10071         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10072         ACE_SCORING_EVENT("onAccessibilityHover");
10073         PipelineContext::SetCallBackNode(node);
10074         func->AccessibilityHoverExecute(isHover, hoverInfo);
10075     };
10076     ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
10077 }
10078 
JsOnClick(const JSCallbackInfo & info)10079 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
10080 {
10081     auto arg = info[0];
10082     if (arg->IsUndefined() && IsDisableEventVersion()) {
10083         ViewAbstractModel::GetInstance()->DisableOnClick();
10084         return;
10085     }
10086     if (!arg->IsFunction()) {
10087         return;
10088     }
10089 
10090     auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
10091     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10092     auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
10093                      BaseEventInfo* info) {
10094         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10095         auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
10096         ACE_SCORING_EVENT("onClick");
10097         PipelineContext::SetCallBackNode(node);
10098         func->Execute(*tapInfo);
10099 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
10100         JSInteractableView::ReportClickEvent(node);
10101 #endif
10102     };
10103     auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
10104     auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
10105                        const ClickInfo* info) {
10106         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10107         ACE_SCORING_EVENT("onClick");
10108         PipelineContext::SetCallBackNode(node);
10109         func->Execute(*info);
10110 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
10111         JSInteractableView::ReportClickEvent(node);
10112 #endif
10113     };
10114 
10115     double distanceThreshold = std::numeric_limits<double>::infinity();
10116     if (info.Length() > 1 && info[1]->IsNumber()) {
10117         distanceThreshold = info[1]->ToNumber<double>();
10118         if (distanceThreshold < 0) {
10119             distanceThreshold = std::numeric_limits<double>::infinity();
10120         }
10121     }
10122     distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
10123     ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
10124 }
10125 
JsOnGestureJudgeBegin(const JSCallbackInfo & info)10126 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
10127 {
10128     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10129         ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
10130         return;
10131     }
10132 
10133     auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
10134     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10135     auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
10136                                   const RefPtr<NG::GestureInfo>& gestureInfo,
10137                                   const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
10138         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
10139         ACE_SCORING_EVENT("onGestureJudgeBegin");
10140         return func->Execute(gestureInfo, info);
10141     };
10142     ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
10143 }
10144 
JsOnTouchIntercept(const JSCallbackInfo & info)10145 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
10146 {
10147     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10148         ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
10149         return;
10150     }
10151 
10152     auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
10153     auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10154     auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
10155                                     TouchEventInfo& info) -> NG::HitTestMode {
10156         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
10157         ACE_SCORING_EVENT("onTouchIntercept");
10158         PipelineContext::SetCallBackNode(node);
10159         return func->Execute(info);
10160     };
10161     ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
10162 }
10163 
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)10164 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
10165 {
10166     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10167         ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
10168         return;
10169     }
10170 
10171     auto jsParallelInnerGestureToFunc =
10172         AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
10173     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10174     auto shouldBuiltInRecognizerParallelWithFunc =
10175         [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
10176             const RefPtr<NG::NGGestureRecognizer>& current,
10177             const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
10178         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
10179         ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
10180         PipelineContext::SetCallBackNode(node);
10181         return func->Execute(current, others);
10182     };
10183     ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
10184         std::move(shouldBuiltInRecognizerParallelWithFunc));
10185 }
10186 
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)10187 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
10188 {
10189     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10190         ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
10191         return;
10192     }
10193 
10194     auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
10195     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10196     auto onGestureRecognizerJudgefunc =
10197         [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
10198             const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
10199             const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
10200         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
10201         ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
10202         PipelineContext::SetCallBackNode(node);
10203         return func->Execute(info, current, others);
10204     };
10205 
10206     bool exposeInnerGestureFlag = false;
10207     if (info.Length() > 1 && info[1]->IsBoolean()) {
10208         exposeInnerGestureFlag = info[1]->ToBoolean();
10209     }
10210     ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
10211         std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
10212 }
10213 
JsClickEffect(const JSCallbackInfo & info)10214 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
10215 {
10216     JSRef<JSVal> arg = info[0];
10217     if (arg->IsUndefined() || arg->IsNull()) {
10218         ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
10219         return;
10220     }
10221     if (!arg->IsObject()) {
10222         return;
10223     }
10224     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
10225     JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
10226     int32_t clickEffectLevelValue = 0;
10227     if (clickEffectLevel->IsNumber()) {
10228         clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
10229         if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
10230             clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
10231             clickEffectLevelValue = 0;
10232         }
10233     }
10234 
10235     JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
10236     float scaleNumberValue = DEFAULT_SCALE_LIGHT;
10237     if (!scaleNumber->IsNumber()) {
10238         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10239             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10240             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10241         }
10242         ViewAbstractModel::GetInstance()->SetClickEffectLevel(
10243             (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10244         return;
10245     }
10246 
10247     scaleNumberValue = scaleNumber->ToNumber<float>();
10248     if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
10249         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10250             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10251             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10252         } else {
10253             scaleNumberValue = DEFAULT_SCALE_LIGHT;
10254         }
10255     }
10256 
10257     ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10258 }
10259 
JsOnVisibleAreaChange(const JSCallbackInfo & info)10260 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
10261 {
10262     if (info.Length() != 2) {
10263         return;
10264     }
10265 
10266     if (!info[0]->IsArray() || !info[1]->IsFunction()) {
10267         return;
10268     }
10269 
10270     auto ratioArray = JSRef<JSArray>::Cast(info[0]);
10271     size_t size = ratioArray->Length();
10272     std::vector<double> ratioVec(size);
10273     ratioVec.clear();
10274     for (size_t i = 0; i < size; i++) {
10275         double ratio = 0.0;
10276         ParseJsDouble(ratioArray->GetValueAt(i), ratio);
10277         if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
10278             ratio = VISIBLE_RATIO_MIN;
10279         }
10280 
10281         if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
10282             ratio = VISIBLE_RATIO_MAX;
10283         }
10284         ratioVec.push_back(ratio);
10285     }
10286 
10287     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
10288     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10289     auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
10290                                bool visible, double ratio) {
10291         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10292         ACE_SCORING_EVENT("onVisibleAreaChange");
10293 
10294         JSRef<JSVal> params[2];
10295         params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
10296         params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
10297         PipelineContext::SetCallBackNode(node);
10298         func->ExecuteJS(2, params);
10299     };
10300     ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
10301 }
10302 
JsHitTestBehavior(const JSCallbackInfo & info)10303 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
10304 {
10305     if (info.Length() != 1 || !info[0]->IsNumber()) {
10306         return;
10307     }
10308 
10309     NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
10310     hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
10311     ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
10312 }
10313 
JsOnChildTouchTest(const JSCallbackInfo & info)10314 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
10315 {
10316     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
10317     auto jsVal = info[0];
10318     if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
10319         return;
10320     }
10321 
10322     RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
10323         AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
10324 
10325     auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
10326                                const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
10327         NG::TouchResult touchRes;
10328         NG::TouchResult defaultRes;
10329         defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
10330         defaultRes.id = "";
10331         auto ret = func->Execute(touchInfo);
10332         if (!ret->IsObject()) {
10333             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
10334             return defaultRes;
10335         }
10336 
10337         auto retObj = JSRef<JSObject>::Cast(ret);
10338         auto strategy = retObj->GetProperty("strategy");
10339         if (!strategy->IsNumber()) {
10340             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
10341             return defaultRes;
10342         }
10343         touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
10344         auto id = retObj->GetProperty("id");
10345         if (!id->IsString()) {
10346             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
10347             return defaultRes;
10348         }
10349         touchRes.id = id->ToString();
10350         return touchRes;
10351     };
10352     ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
10353 }
10354 
JsForegroundColor(const JSCallbackInfo & info)10355 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
10356 {
10357     Color foregroundColor = Color::TRANSPARENT;
10358     ForegroundColorStrategy strategy;
10359     if (ParseJsColorStrategy(info[0], strategy)) {
10360         ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
10361         return;
10362     }
10363     ParseJsColor(info[0], foregroundColor);
10364     ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
10365 }
10366 
JsKeyboardShortcut(const JSCallbackInfo & info)10367 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
10368 {
10369     // KeyboardShortcut only allows 2 or 3 params.
10370     if (info.Length() < 2 || info.Length() > 3) {
10371         return;
10372     }
10373     if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
10374         // clear shortcut key
10375         ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10376         return;
10377     }
10378 
10379     std::string value;
10380     if (info[0]->IsString()) {
10381         // common letter/number/symbol
10382         value = info[0]->ToString();
10383         if (value.size() != 1) {
10384             // clear shortcut key
10385             ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10386             return;
10387         }
10388     } else {
10389         // function keys such as F1-F10/ESC
10390         FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
10391         value = GetFunctionKeyName(functionkey);
10392     }
10393 
10394     auto keysArray = JSRef<JSArray>::Cast(info[1]);
10395     size_t size = keysArray->Length();
10396     std::vector<ModifierKey> keys(size);
10397     keys.clear();
10398     for (size_t i = 0; i < size; i++) {
10399         JSRef<JSVal> key = keysArray->GetValueAt(i);
10400         if (key->IsNumber()) {
10401             keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
10402         }
10403     }
10404 
10405     // KeyboardShortcut allows 3 params, the third param is function callback.
10406     if (info.Length() == 3 && info[2]->IsFunction()) {
10407         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
10408         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10409         auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10410                                             node = frameNode]() {
10411             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10412             ACE_SCORING_EVENT("onKeyboardShortcutAction");
10413             PipelineContext::SetCallBackNode(node);
10414             func->ExecuteJS();
10415         };
10416         ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
10417         return;
10418     }
10419     ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
10420 }
10421 
JsOnFocusAxisEvent(const JSCallbackInfo & args)10422 void JSViewAbstract::JsOnFocusAxisEvent(const JSCallbackInfo& args)
10423 {
10424     JSRef<JSVal> arg = args[0];
10425     if (arg->IsUndefined() && IsDisableEventVersion()) {
10426         ViewAbstractModel::GetInstance()->DisableOnFocusAxisEvent();
10427         return;
10428     }
10429     if (!arg->IsFunction()) {
10430         return;
10431     }
10432     EcmaVM* vm = args.GetVm();
10433     CHECK_NULL_VOID(vm);
10434     auto jsOnFocusAxisEventFunc = JSRef<JSFunc>::Cast(arg);
10435     if (jsOnFocusAxisEventFunc->IsEmpty()) {
10436         return;
10437     }
10438     auto jsOnFocusAxisFuncLocalHandle = jsOnFocusAxisEventFunc->GetLocalHandle();
10439     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10440     auto onFocusAxisEvent = [vm, execCtx = args.GetExecutionContext(),
10441                        func = panda::CopyableGlobal(vm, jsOnFocusAxisFuncLocalHandle),
10442                        node = frameNode](NG::FocusAxisEventInfo& info) {
10443         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10444         ACE_SCORING_EVENT("onFocusAxis");
10445         PipelineContext::SetCallBackNode(node);
10446         auto eventObj = NG::CommonBridge::CreateFocusAxisEventInfo(vm, info);
10447         panda::Local<panda::JSValueRef> params[1] = { eventObj };
10448         func->Call(vm, func.ToLocal(), params, 1);
10449     };
10450     ViewAbstractModel::GetInstance()->SetOnFocusAxisEvent(std::move(onFocusAxisEvent));
10451 }
10452 
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)10453 bool JSViewAbstract::CheckColor(
10454     const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
10455 {
10456     // Color is undefined or null
10457     if (jsValue->IsUndefined() || jsValue->IsNull()) {
10458         return false;
10459     }
10460     // input type is not in [number, string, Resource]
10461     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10462         return false;
10463     }
10464     // Correct type, incorrect value parsing
10465     if (!ParseJsColor(jsValue, result)) {
10466         return false;
10467     }
10468     return true;
10469 }
10470 
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)10471 bool JSViewAbstract::CheckLength(
10472     const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
10473 {
10474     // Length is undefined or null
10475     if (jsValue->IsUndefined() || jsValue->IsNull()) {
10476         return false;
10477     }
10478     // input type is not in [number, string, Resource]
10479     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10480         return false;
10481     }
10482     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10483         return ParseJsDimensionVpNG(jsValue, result);
10484     }
10485     // Correct type, incorrect value parsing
10486     if (!ParseJsDimensionVp(jsValue, result)) {
10487         return false;
10488     }
10489     return true;
10490 }
10491 
10492 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)10493 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
10494 {
10495     JSRef<JSVal> arg = info[0];
10496     if (arg->IsUndefined() || arg->IsNull()) {
10497         std::vector<ObscuredReasons> reasons(0);
10498         ViewAbstractModel::GetInstance()->SetObscured(reasons);
10499         return;
10500     }
10501     if (!arg->IsArray()) {
10502         return;
10503     }
10504 
10505     auto obscuredArray = JSRef<JSArray>::Cast(arg);
10506     size_t size = obscuredArray->Length();
10507     std::vector<ObscuredReasons> reasons(size);
10508     reasons.clear();
10509     for (size_t i = 0; i < size; i++) {
10510         JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
10511         if (reason->IsNumber()) {
10512             reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
10513         }
10514     }
10515 
10516     ViewAbstractModel::GetInstance()->SetObscured(reasons);
10517 }
10518 
10519 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)10520 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
10521 {
10522     auto sensitiveInfo = info[0];
10523     if (sensitiveInfo->IsUndefined()) {
10524         ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
10525         return;
10526     }
10527     bool sensitive = false;
10528     if (sensitiveInfo->IsBoolean()) {
10529         sensitive = sensitiveInfo->ToBoolean();
10530     }
10531     ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
10532 }
10533 
JSRenderGroup(const JSCallbackInfo & info)10534 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
10535 {
10536     if (info.Length() != 1) {
10537         return;
10538     }
10539     bool isRenderGroup = false;
10540     if (info[0]->IsBoolean()) {
10541         isRenderGroup = info[0]->ToBoolean();
10542     }
10543     ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
10544 }
10545 
JSRenderFit(const JSCallbackInfo & info)10546 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
10547 {
10548     if (info.Length() != 1) {
10549         return;
10550     }
10551     RenderFit renderFit = RenderFit::TOP_LEFT;
10552     if (info[0]->IsNumber()) {
10553         int32_t fitNumber = info[0]->ToNumber<int32_t>();
10554         if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
10555             fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
10556             renderFit = static_cast<RenderFit>(fitNumber);
10557         }
10558     }
10559     // how content fills the node duration implicit animation
10560     ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
10561 }
10562 
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)10563 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
10564 {
10565     if (!jsValue->IsObject() || jsValue->IsString()) {
10566         return false;
10567     }
10568     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10569     if (!jsObj->IsUndefined()) {
10570         JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
10571         JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
10572         if (bundle->IsString() && module->IsString()) {
10573             bundleName = bundle->ToString();
10574             moduleName = module->ToString();
10575             return true;
10576         }
10577     }
10578     return false;
10579 }
10580 
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)10581 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
10582     const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
10583 {
10584     std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx](
10585                                                                          NG::DrawingContext& context) -> void {
10586         JAVASCRIPT_EXECUTION_SCOPE(execCtx);
10587 
10588         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
10589         objectTemplate->SetInternalFieldCount(1);
10590         JSRef<JSObject> contextObj = objectTemplate->NewInstance();
10591         JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
10592         sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
10593         sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
10594         contextObj->SetPropertyObject("size", sizeObj);
10595 
10596         JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
10597         sizeInPxObj->SetProperty<float>("height", context.height);
10598         sizeInPxObj->SetProperty<float>("width", context.width);
10599         contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
10600 
10601         auto engine = EngineHelper::GetCurrentEngine();
10602         CHECK_NULL_VOID(engine);
10603         NativeEngine* nativeEngine = engine->GetNativeEngine();
10604         napi_env env = reinterpret_cast<napi_env>(nativeEngine);
10605         ScopeRAII scope(env);
10606 
10607         auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
10608         OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
10609         napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
10610         if (unwrapCanvas) {
10611             unwrapCanvas->SaveCanvas();
10612             unwrapCanvas->ClipCanvas(context.width, context.height);
10613         }
10614         JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
10615         contextObj->SetPropertyObject("canvas", jsCanvasVal);
10616 
10617         auto jsVal = JSRef<JSVal>::Cast(contextObj);
10618         panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
10619         JSValueWrapper valueWrapper = value;
10620         napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
10621 
10622         napi_wrap(
10623             env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
10624 
10625         JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
10626         if (unwrapCanvas) {
10627             unwrapCanvas->RestoreCanvas();
10628             unwrapCanvas->ResetCanvas();
10629         }
10630     };
10631     return drawCallback;
10632 }
10633 
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)10634 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
10635 {
10636     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10637         return false;
10638     }
10639     Color borderColor;
10640     if (ParseJsColor(args, borderColor)) {
10641         colorProperty.SetColor(borderColor);
10642         return true;
10643     } else if (args->IsObject()) {
10644         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10645         CommonColor commonColor;
10646         ParseCommonEdgeColors(obj, commonColor);
10647         colorProperty.topColor = commonColor.top;
10648         colorProperty.bottomColor = commonColor.bottom;
10649         colorProperty.leftColor = commonColor.left;
10650         colorProperty.rightColor = commonColor.right;
10651         colorProperty.multiValued = true;
10652         return true;
10653     }
10654     return false;
10655 }
10656 
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)10657 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
10658 {
10659     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10660         return false;
10661     }
10662     CalcDimension borderWidth;
10663     if (ParseJsDimensionVpNG(args, borderWidth, true)) {
10664         if (borderWidth.IsNegative()) {
10665             borderWidth.Reset();
10666         }
10667         borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth });
10668         return true;
10669     } else if (args->IsObject()) {
10670         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10671         CommonCalcDimension commonCalcDimension;
10672         ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
10673         borderWidthProperty.topDimen = commonCalcDimension.top;
10674         borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
10675         borderWidthProperty.leftDimen = commonCalcDimension.left;
10676         borderWidthProperty.rightDimen = commonCalcDimension.right;
10677         borderWidthProperty.multiValued = true;
10678         return true;
10679     }
10680     return false;
10681 }
10682 
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)10683 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
10684 {
10685     if (!args->IsObject() && !args->IsNumber()) {
10686         return false;
10687     }
10688     if (args->IsObject()) {
10689         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10690         auto leftValue = obj->GetProperty("left");
10691         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
10692             ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
10693         }
10694         auto rightValue = obj->GetProperty("right");
10695         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
10696             ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
10697         }
10698         auto topValue = obj->GetProperty("top");
10699         if (!topValue->IsUndefined() && topValue->IsNumber()) {
10700             ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
10701         }
10702         auto bottomValue = obj->GetProperty("bottom");
10703         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
10704             ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
10705         }
10706         borderStyleProperty.multiValued = true;
10707         return true;
10708     }
10709     std::optional<BorderStyle> borderStyle;
10710     if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
10711         borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
10712         return true;
10713     }
10714     return false;
10715 }
10716 
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10717 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10718 {
10719     std::optional<CalcDimension> radiusTopLeft;
10720     std::optional<CalcDimension> radiusTopRight;
10721     std::optional<CalcDimension> radiusBottomLeft;
10722     std::optional<CalcDimension> radiusBottomRight;
10723     CalcDimension topLeft;
10724     if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) {
10725         radiusTopLeft = topLeft;
10726     }
10727     CalcDimension topRight;
10728     if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) {
10729         radiusTopRight = topRight;
10730     }
10731     CalcDimension bottomLeft;
10732     if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) {
10733         radiusBottomLeft = bottomLeft;
10734     }
10735     CalcDimension bottomRight;
10736     if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) {
10737         radiusBottomRight = bottomRight;
10738     }
10739     CheckLengthMetrics(object);
10740     radius.radiusTopLeft = radiusTopLeft;
10741     radius.radiusTopRight = radiusTopRight;
10742     radius.radiusBottomLeft = radiusBottomLeft;
10743     radius.radiusBottomRight = radiusBottomRight;
10744     radius.multiValued = true;
10745     return;
10746 }
10747 
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10748 void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10749 {
10750     if (CheckLengthMetrics(object)) {
10751         std::optional<CalcDimension> radiusTopStart;
10752         std::optional<CalcDimension> radiusTopEnd;
10753         std::optional<CalcDimension> radiusBottomStart;
10754         std::optional<CalcDimension> radiusBottomEnd;
10755         if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
10756             JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
10757             CalcDimension calcDimension;
10758             if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
10759                 CheckDimensionUnit(calcDimension, false, true);
10760                 radiusTopStart = calcDimension;
10761             }
10762         }
10763         if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
10764             JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
10765             CalcDimension calcDimension;
10766             if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
10767                 CheckDimensionUnit(calcDimension, false, true);
10768                 radiusTopEnd = calcDimension;
10769             }
10770         }
10771         if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
10772             JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
10773             CalcDimension calcDimension;
10774             if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
10775                 CheckDimensionUnit(calcDimension, false, true);
10776                 radiusBottomStart = calcDimension;
10777             }
10778         }
10779         if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
10780             JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
10781             CalcDimension calcDimension;
10782             if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
10783                 CheckDimensionUnit(calcDimension, false, true);
10784                 radiusBottomEnd = calcDimension;
10785             }
10786         }
10787         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
10788         radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
10789         radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
10790         radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
10791         radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
10792         radius.multiValued = true;
10793         return;
10794     }
10795     ParseBorderRadiusProps(object, radius);
10796 }
10797 
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)10798 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
10799 {
10800     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10801         return false;
10802     }
10803     CalcDimension borderRadius;
10804     if (ParseJsDimensionVpNG(args, borderRadius, true)) {
10805         radius = NG::BorderRadiusProperty(borderRadius);
10806         radius.multiValued = false;
10807     } else if (args->IsObject()) {
10808         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
10809         ParseCommonBorderRadiusProps(object, radius);
10810     } else {
10811         return false;
10812     }
10813     return true;
10814 }
10815 
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)10816 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10817 {
10818     JSRef<JSVal> arg = info[0];
10819     if (!arg->IsObject()) {
10820         return;
10821     }
10822     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
10823     auto vm = info.GetVm();
10824     auto globalObj = JSNApi::GetGlobalObject(vm);
10825     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
10826     JsiValue jsiValue(globalFunc);
10827     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
10828     if (globalFuncRef->IsFunction()) {
10829         auto modifierObj = obj->GetProperty("modifier");
10830         if (modifierObj->IsUndefined()) {
10831             option.onApply = nullptr;
10832         } else {
10833             RefPtr<JsFunction> jsFunc =
10834                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
10835             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10836                                modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
10837                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10838                 auto node = frameNode.Upgrade();
10839                 JSRef<JSVal> params[PARAMETER_LENGTH_SECOND];
10840                 params[0] = modifier;
10841                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
10842                 PipelineContext::SetCallBackNode(node);
10843                 func->ExecuteJS(PARAMETER_LENGTH_SECOND, params);
10844             };
10845             option.onApply = onApply;
10846         }
10847     }
10848 }
10849 
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)10850 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10851 {
10852     if (!info[0]->IsObject()) {
10853         return;
10854     }
10855     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
10856     auto numberBadge = obj->GetProperty("numberBadge");
10857     if (!numberBadge->IsEmpty()) {
10858         if (numberBadge->IsNumber()) {
10859             int64_t number = numberBadge->ToNumber<int64_t>();
10860             if (number < 0 || number > INT_MAX) {
10861                 option.isNumber = false;
10862                 option.isShowBadge = true;
10863             } else {
10864                 option.isNumber = true;
10865                 option.badgeNumber = numberBadge->ToNumber<int>();
10866             }
10867         } else if (numberBadge->IsBoolean()) {
10868             option.isNumber = false;
10869             option.isShowBadge = numberBadge->ToBoolean();
10870         }
10871     } else {
10872         option.isNumber = false;
10873         option.isShowBadge = true;
10874     }
10875 }
10876 
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10877 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10878 {
10879     // Parse cornerRadius.
10880     auto cornerRadiusValue = obj->GetProperty("cornerRadius");
10881     NG::BorderRadiusProperty radius;
10882     if (ParseBorderRadius(cornerRadiusValue, radius)) {
10883         properties.borderRadius = radius;
10884     }
10885     // Parse border width
10886     auto borderWidthValue = obj->GetProperty("borderWidth");
10887     NG::BorderWidthProperty borderWidth;
10888     if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
10889         properties.borderWidth = borderWidth;
10890         auto colorValue = obj->GetProperty("borderColor");
10891         NG::BorderColorProperty borderColor;
10892         if (ParseBorderColorProps(colorValue, borderColor)) {
10893             properties.borderColor = borderColor;
10894         } else {
10895             borderColor.SetColor(Color::BLACK);
10896             properties.borderColor = borderColor;
10897         }
10898         // Parse border style
10899         auto styleValue = obj->GetProperty("borderStyle");
10900         NG::BorderStyleProperty borderStyle;
10901         if (ParseBorderStyleProps(styleValue, borderStyle)) {
10902             properties.borderStyle = borderStyle;
10903         } else {
10904             properties.borderStyle = NG::BorderStyleProperty(
10905                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
10906         }
10907     }
10908     auto shadowValue = obj->GetProperty("shadow");
10909     Shadow shadow;
10910     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
10911         properties.shadow = shadow;
10912     }
10913     auto widthValue = obj->GetProperty("width");
10914     CalcDimension width;
10915     if (ParseJsDimensionVpNG(widthValue, width, true)) {
10916         properties.width = width;
10917     }
10918     auto heightValue = obj->GetProperty("height");
10919     CalcDimension height;
10920     if (ParseJsDimensionVpNG(heightValue, height, true)) {
10921         properties.height = height;
10922     }
10923 }
10924 
SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10925 void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10926 {
10927     auto enableHoverModeValue = obj->GetProperty("enableHoverMode");
10928     if (enableHoverModeValue->IsBoolean()) {
10929         properties.enableHoverMode = enableHoverModeValue->ToBoolean();
10930     }
10931 
10932     // Parse hoverModeArea
10933     auto hoverModeAreaValue = obj->GetProperty("hoverModeArea");
10934     if (hoverModeAreaValue->IsNumber()) {
10935         auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
10936         if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
10937             properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
10938         }
10939     }
10940 }
10941 
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)10942 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
10943 {
10944     auto* vm = info.GetVm();
10945     return [vm, nodeId](const std::string& key) -> std::string {
10946         std::string resultString = std::string();
10947         CHECK_NULL_RETURN(vm, resultString);
10948         panda::LocalScope scope(vm);
10949         auto global = JSNApi::GetGlobalObject(vm);
10950         auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
10951         if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
10952             return resultString;
10953         }
10954         auto obj = getCustomProperty->ToObject(vm);
10955         panda::Local<panda::FunctionRef> func = obj;
10956         panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
10957             panda::StringRef::NewFromUtf8(vm, key.c_str()) };
10958         auto function = panda::CopyableGlobal(vm, func);
10959         auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
10960         if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
10961             return resultString;
10962         }
10963         auto value = callValue->ToString(vm)->ToString(vm);
10964         return value;
10965     };
10966 }
10967 
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)10968 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
10969 {
10970     auto* vm = info.GetVm();
10971     panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
10972         info[1]->GetLocalHandle() };
10973     return [vm, params3]() -> bool {
10974         CHECK_NULL_RETURN(vm, false);
10975         panda::LocalScope scope(vm);
10976         auto global = JSNApi::GetGlobalObject(vm);
10977         auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
10978         if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
10979             return false;
10980         }
10981         auto obj = setCustomProperty->ToObject(vm);
10982         panda::Local<panda::FunctionRef> func = obj;
10983         auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10984         auto nodeId = frameNode->GetId();
10985         auto function = panda::CopyableGlobal(vm, func);
10986         auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
10987         if (customPropertyExisted) {
10988             frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
10989                 CHECK_NULL_VOID(vm);
10990                 panda::LocalScope scope(vm);
10991                 auto global = JSNApi::GetGlobalObject(vm);
10992                 auto removeCustomProperty =
10993                     global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
10994                 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
10995                     return;
10996                 }
10997                 auto obj = removeCustomProperty->ToObject(vm);
10998                 panda::Local<panda::FunctionRef> func = obj;
10999                 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
11000                 auto function = panda::CopyableGlobal(vm, func);
11001                 function->Call(vm, function.ToLocal(), params, 1);
11002             });
11003         }
11004         return true;
11005     };
11006 }
11007 
JsCustomProperty(const JSCallbackInfo & info)11008 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
11009 {
11010     if (info[0]->GetLocalHandle()->IsUndefined()) {
11011         return;
11012     }
11013     auto* vm = info.GetVm();
11014     CHECK_NULL_VOID(vm);
11015     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
11016     auto nodeId = frameNode->GetId();
11017     auto getFunc = ParseJsGetFunc(info, nodeId);
11018     auto func = ParseJsFunc(info, nodeId);
11019     frameNode->SetJSCustomProperty(func, getFunc);
11020 }
11021 
JsGestureModifier(const JSCallbackInfo & info)11022 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
11023 {
11024     auto* vm = info.GetExecutionContext().vm_;
11025     CHECK_NULL_VOID(vm);
11026     auto global = JSNApi::GetGlobalObject(vm);
11027     auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
11028     if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
11029         return;
11030     }
11031     auto obj = gestureModifier->ToObject(vm);
11032     panda::Local<panda::FunctionRef> func = obj;
11033     auto thisObj = info.This()->GetLocalHandle();
11034     panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
11035     func->Call(vm, thisObj, params, 1);
11036 }
11037 
JsBackgroundImageResizable(const JSCallbackInfo & info)11038 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
11039 {
11040     auto infoObj = info[0];
11041     ImageResizableSlice sliceResult;
11042     if (!infoObj->IsObject()) {
11043         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11044         return;
11045     }
11046     JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
11047     if (resizableObject->IsEmpty()) {
11048         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11049         return;
11050     }
11051     auto sliceValue = resizableObject->GetProperty("slice");
11052     if (!sliceValue->IsObject()) {
11053         return;
11054     }
11055     JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
11056     if (sliceObj->IsEmpty()) {
11057         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11058         return;
11059     }
11060     for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
11061         auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
11062         CalcDimension sliceDimension;
11063         if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
11064             continue;
11065         }
11066         if (!sliceDimension.IsValid()) {
11067             continue;
11068         }
11069         switch (static_cast<BorderImageDirection>(i)) {
11070             case BorderImageDirection::LEFT:
11071                 sliceResult.left = sliceDimension;
11072                 break;
11073             case BorderImageDirection::RIGHT:
11074                 sliceResult.right = sliceDimension;
11075                 break;
11076             case BorderImageDirection::TOP:
11077                 sliceResult.top = sliceDimension;
11078                 break;
11079             case BorderImageDirection::BOTTOM:
11080                 sliceResult.bottom = sliceDimension;
11081                 break;
11082             default:
11083                 break;
11084         }
11085     }
11086     ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11087 }
11088 
JsFocusScopeId(const JSCallbackInfo & info)11089 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
11090 {
11091     if (info.Length() == 0) {
11092         return;
11093     }
11094 
11095     std::string focusScopeId;
11096     if (info[0]->IsString()) {
11097         focusScopeId = info[0]->ToString();
11098     }
11099 
11100     bool isGroup = false;
11101     if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
11102         info[1]->IsBoolean()) {
11103         isGroup = info[1]->ToBoolean();
11104     }
11105     bool arrowKeyStepOut = true;
11106     if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() &&
11107         info[2]->IsBoolean()) {
11108         arrowKeyStepOut = info[2]->ToBoolean();
11109     }
11110     ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
11111 }
11112 
JsFocusScopePriority(const JSCallbackInfo & info)11113 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
11114 {
11115     if (info.Length() == 0) {
11116         return;
11117     }
11118 
11119     if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
11120         return;
11121     }
11122     std::string focusScopeId = info[0]->ToString();
11123 
11124     int32_t focusPriority = 0;
11125     if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
11126         info[1]->IsNumber()) {
11127         focusPriority = info[1]->ToNumber<int32_t>();
11128     }
11129     ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
11130 }
11131 
ParseJsPropertyId(const JSRef<JSVal> & jsValue)11132 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
11133 {
11134     int32_t resId = 0;
11135     if (jsValue->IsObject()) {
11136         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
11137         JSRef<JSVal> tmp = jsObj->GetProperty("id");
11138         if (!tmp->IsNull() && tmp->IsNumber()) {
11139             resId = tmp->ToNumber<int32_t>();
11140         }
11141     }
11142     return resId;
11143 }
11144 
JsVisualEffect(const JSCallbackInfo & info)11145 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
11146 {
11147     if (!info[0]->IsObject()) {
11148         return;
11149     }
11150     auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
11151     ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
11152 }
11153 
JsBackgroundFilter(const JSCallbackInfo & info)11154 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
11155 {
11156     if (!info[0]->IsObject()) {
11157         return;
11158     }
11159     auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
11160     ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
11161 }
11162 
JsForegroundFilter(const JSCallbackInfo & info)11163 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
11164 {
11165     if (!info[0]->IsObject()) {
11166         return;
11167     }
11168     auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
11169     ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
11170 }
11171 
JsCompositingFilter(const JSCallbackInfo & info)11172 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
11173 {
11174     if (!info[0]->IsObject()) {
11175         return;
11176     }
11177     auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
11178     ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
11179 }
11180 
ParseMenuItems(const JSRef<JSArray> & menuItemsArray)11181 std::vector<NG::MenuOptionsParam> JSViewAbstract::ParseMenuItems(const JSRef<JSArray>& menuItemsArray)
11182 {
11183     std::vector<NG::MenuOptionsParam> menuParams;
11184     for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
11185         auto menuItem = menuItemsArray->GetValueAt(i);
11186         if (!menuItem->IsObject()) {
11187             continue;
11188         }
11189         auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
11190         NG::MenuOptionsParam menuOptionsParam;
11191         auto jsContent = menuItemObject->GetProperty("content");
11192         std::string content;
11193         ParseJsString(jsContent, content);
11194         menuOptionsParam.content = content;
11195         auto jsStartIcon = menuItemObject->GetProperty("icon");
11196         std::string icon;
11197         ParseJsMedia(jsStartIcon, icon);
11198         menuOptionsParam.icon = icon;
11199         auto jsTextMenuId = menuItemObject->GetProperty("id");
11200         std::string id;
11201         if (jsTextMenuId->IsObject()) {
11202             auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
11203             auto jsId = textMenuIdObject->GetProperty("id_");
11204             ParseJsString(jsId, id);
11205         }
11206         menuOptionsParam.id = id;
11207         auto jsLabelInfo = menuItemObject->GetProperty("labelInfo");
11208         std::string labelInfo;
11209         ParseJsString(jsLabelInfo, labelInfo);
11210         if (jsLabelInfo->IsString() || jsLabelInfo->IsObject()) {
11211             menuOptionsParam.labelInfo = labelInfo;
11212         }
11213         menuParams.emplace_back(menuOptionsParam);
11214     }
11215     return menuParams;
11216 }
11217 
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)11218 void JSViewAbstract::ParseOnCreateMenu(
11219     const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
11220 {
11221     if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
11222         return;
11223     }
11224     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11225     auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
11226         JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
11227     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
11228                           instanceId = Container::CurrentId(), node = frameNode](
11229                           const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
11230         ContainerScope scope(instanceId);
11231         std::vector<NG::MenuOptionsParam> menuParams;
11232         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
11233         auto pipelineContext = PipelineContext::GetCurrentContext();
11234         CHECK_NULL_RETURN(pipelineContext, menuParams);
11235 
11236         pipelineContext->UpdateCurrentActiveNode(node);
11237         auto modifiedSystemMenuItems = systemMenuItems;
11238         UpdateOptionsLabelInfo(modifiedSystemMenuItems);
11239         auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
11240         if (!menuItem->IsArray()) {
11241             return menuParams;
11242         }
11243         auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
11244         menuParams = ParseMenuItems(menuItemsArray);
11245         return menuParams;
11246     };
11247     onCreateMenuCallback = jsCallback;
11248 }
11249 
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)11250 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
11251 {
11252     JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
11253     uint32_t idx = 0;
11254     for (const auto& item : systemMenuItems) {
11255         systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
11256     }
11257     return systemMenuItemsArray;
11258 }
11259 
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)11260 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
11261     NG::OnMenuItemClickCallback& onMenuItemClick)
11262 {
11263     auto tmpInfo = info[0];
11264     if (info.Length() != 1 || !tmpInfo->IsObject()) {
11265         return false;
11266     }
11267     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11268     auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
11269     auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
11270     ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
11271 
11272     auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
11273     if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
11274         return false;
11275     }
11276     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
11277     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11278                           onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
11279                           node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
11280         ContainerScope scope(instanceId);
11281         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
11282         auto pipelineContext = PipelineContext::GetCurrentContext();
11283         CHECK_NULL_RETURN(pipelineContext, false);
11284         pipelineContext->UpdateCurrentActiveNode(node);
11285         auto paramArray = onMenuItemCallback(menuOptionsParam);
11286         if (paramArray->Length() != 2) {
11287             return false;
11288         }
11289         JSRef<JSVal> params[2];
11290         params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
11291         params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
11292         auto ret = func->ExecuteJS(2, params);
11293         if (ret->IsBoolean()) {
11294             return ret->ToBoolean();
11295         }
11296         return false;
11297     };
11298     onMenuItemClick = jsCallback;
11299     return true;
11300 }
11301 
CreateJsTextMenuId(const std::string & id)11302 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
11303 {
11304     JSRef<JSObject> empty;
11305     auto engine = EngineHelper::GetCurrentEngine();
11306     CHECK_NULL_RETURN(engine, empty);
11307     NativeEngine* nativeEngine = engine->GetNativeEngine();
11308     CHECK_NULL_RETURN(nativeEngine, empty);
11309     auto env = reinterpret_cast<napi_env>(nativeEngine);
11310 
11311     napi_value global;
11312     napi_status ret = napi_get_global(env, &global);
11313     if (ret != napi_ok) {
11314         return empty;
11315     }
11316     napi_value constructor;
11317     ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
11318     if (ret != napi_ok) {
11319         return empty;
11320     }
11321 
11322     napi_value obj;
11323     napi_value menuId = nullptr;
11324 
11325     ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
11326     if (ret != napi_ok) {
11327         return empty;
11328     }
11329     ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
11330     if (ret != napi_ok) {
11331         return empty;
11332     }
11333 
11334     JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
11335     if (!value->IsObject()) {
11336         return empty;
11337     }
11338 
11339     return JSRef<JSObject>::Cast(value);
11340 }
11341 
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)11342 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
11343 {
11344     JSRef<JSArray> params = JSRef<JSArray>::New();
11345     params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
11346     params->SetValueAt(1, CreateJsTextRange(menuItemParam));
11347     return params;
11348 }
11349 
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)11350 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
11351 {
11352     JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
11353     TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
11354     JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
11355     TextMenuItem->SetPropertyObject("id", obj);
11356     TextMenuItem->SetProperty<std::string>("labelInfo", menuItemParam.menuOptionsParam.labelInfo.value_or(""));
11357     return JSRef<JSVal>::Cast(TextMenuItem);
11358 }
11359 
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)11360 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
11361 {
11362     JSRef<JSObject> textRange = JSRef<JSObject>::New();
11363     textRange->SetProperty<int32_t>("start", menuItemParam.start);
11364     textRange->SetProperty<int32_t>("end", menuItemParam.end);
11365     return JSRef<JSVal>::Cast(textRange);
11366 }
11367 
OHOS_ACE_ParseJsMedia(void * value,void * resource)11368 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
11369 {
11370     napi_value napiValue = reinterpret_cast<napi_value>(value);
11371     ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
11372     if (!napiValue || !res) {
11373         return;
11374     }
11375     JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
11376     std::string src;
11377     std::string bundleName;
11378     std::string moduleName;
11379     JSViewAbstract::ParseJsMedia(jsVal, src);
11380     JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
11381     res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
11382     res->src = src;
11383     res->bundleName = bundleName;
11384     res->moduleName = moduleName;
11385 }
11386 
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)11387 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
11388     std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
11389 {
11390     if (!modifierObj->IsObject()) {
11391         textStyleApply = nullptr;
11392         return;
11393     }
11394     auto vm = info.GetVm();
11395     auto globalObj = JSNApi::GetGlobalObject(vm);
11396     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
11397     JsiValue jsiValue(globalFunc);
11398     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11399     if (!globalFuncRef->IsFunction()) {
11400         textStyleApply = nullptr;
11401         return;
11402     }
11403     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11404     auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11405                     modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11406         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11407         auto node = frameNode.Upgrade();
11408         CHECK_NULL_VOID(node);
11409         JSRef<JSVal> params[2];
11410         params[0] = modifierParam;
11411         params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11412         PipelineContext::SetCallBackNode(node);
11413         func->ExecuteJS(2, params);
11414     };
11415     textStyleApply = onApply;
11416 }
11417 
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)11418 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
11419     std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
11420 {
11421     auto vm = info.GetVm();
11422     auto globalObj = JSNApi::GetGlobalObject(vm);
11423     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
11424     JsiValue jsiValue(globalFunc);
11425     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11426     if (globalFuncRef->IsFunction()) {
11427         RefPtr<JsFunction> jsFunc =
11428             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11429         if (!modifierObj->IsObject()) {
11430             symbolApply = nullptr;
11431         } else {
11432             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11433                                modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11434                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11435                 auto node = frameNode.Upgrade();
11436                 CHECK_NULL_VOID(node);
11437                 JSRef<JSVal> params[2];
11438                 params[0] = modifierParam;
11439                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11440                 PipelineContext::SetCallBackNode(node);
11441                 func->ExecuteJS(2, params);
11442             };
11443             symbolApply = onApply;
11444         }
11445     }
11446 }
11447 } // namespace OHOS::Ace::Framework
11448