• 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/jsi/nativeModule/arkts_native_utils_bridge.h"
57 #include "bridge/js_frontend/engine/jsi/ark_js_value.h"
58 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
59 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
60 #include "bridge/declarative_frontend/engine/js_converter.h"
61 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
62 #include "bridge/declarative_frontend/engine/js_types.h"
63 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
64 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
65 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
66 #include "bridge/declarative_frontend/jsview/js_utils.h"
67 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
68 #include "bridge/declarative_frontend/jsview/js_view_context.h"
69 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
70 #include "canvas_napi/js_canvas.h"
71 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
72 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
73 #endif
74 #include "core/common/resource/resource_manager.h"
75 #include "core/common/resource/resource_object.h"
76 #include "core/components/common/layout/constants.h"
77 #include "core/components/common/layout/position_param.h"
78 #include "core/components/common/layout/screen_system_manager.h"
79 #include "core/components/common/properties/animation_option.h"
80 #include "core/components/common/properties/border_image.h"
81 #include "core/components/common/properties/color.h"
82 #include "core/components/common/properties/decoration.h"
83 #include "core/components/common/properties/shadow.h"
84 #include "core/components/common/properties/invert.h"
85 #include "core/components/common/properties/shadow_config.h"
86 #include "core/components/theme/resource_adapter.h"
87 #include "core/components/theme/shadow_theme.h"
88 #include "core/components_ng/base/view_abstract.h"
89 #include "core/components_ng/base/view_abstract_model.h"
90 #include "core/components_ng/base/view_stack_processor.h"
91 #include "core/components_ng/event/focus_box.h"
92 #include "core/components_ng/gestures/base_gesture_event.h"
93 #include "core/components_ng/pattern/menu/menu_pattern.h"
94 #include "core/components_ng/pattern/overlay/modal_style.h"
95 #include "core/components_ng/pattern/overlay/sheet_style.h"
96 #include "core/components_ng/property/grid_property.h"
97 #include "core/components_ng/property/safe_area_insets.h"
98 #include "core/gestures/gesture_info.h"
99 #include "core/image/image_source_info.h"
100 #ifdef PLUGIN_COMPONENT_SUPPORTED
101 #include "core/common/plugin_manager.h"
102 #endif
103 #include "interfaces/native/node/resource.h"
104 
105 #include "core/common/card_scope.h"
106 #include "core/common/container.h"
107 #include "core/common/resource/resource_configuration.h"
108 #include "core/components/progress/progress_theme.h"
109 #include "core/components_ng/base/view_abstract_model_ng.h"
110 #include "core/components_ng/base/view_stack_model.h"
111 #include "core/components_ng/property/progress_mask_property.h"
112 
113 namespace OHOS::Ace {
114 namespace {
115 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
116 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
117 constexpr int32_t DIRECTION_COUNT = 4;
118 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
119 constexpr int NUM1 = 1;
120 } // namespace
121 
122 std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr;
123 std::mutex ViewAbstractModel::mutex_;
124 using DoubleBindCallback = std::function<void(const std::string&)>;
125 
GetInstance()126 ViewAbstractModel* ViewAbstractModel::GetInstance()
127 {
128     if (!instance_) {
129         std::lock_guard<std::mutex> lock(mutex_);
130         if (!instance_) {
131 #ifdef NG_BUILD
132             instance_.reset(new NG::ViewAbstractModelNG());
133 #else
134             if (Container::IsCurrentUseNewPipeline()) {
135                 instance_.reset(new NG::ViewAbstractModelNG());
136             } else {
137                 instance_.reset(new Framework::ViewAbstractModelImpl());
138             }
139 #endif
140         }
141     }
142     return instance_.get();
143 }
144 
145 } // namespace OHOS::Ace
146 
147 namespace OHOS::Ace::Framework {
148 namespace {
149 
150 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
151 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
152 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
153 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
154 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
155 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
156 constexpr int32_t MAX_ALIGN_VALUE = 8;
157 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
158 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
159 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
160 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
161 constexpr double FULL_DIMENSION = 100.0;
162 constexpr double HALF_DIMENSION = 50.0;
163 constexpr double ROUND_UNIT = 360.0;
164 constexpr double VISIBLE_RATIO_MIN = 0.0;
165 constexpr double VISIBLE_RATIO_MAX = 1.0;
166 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
167 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
168 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
169 constexpr int32_t SECOND_INDEX = 2;
170 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
171 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
172 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
173 constexpr float MAX_ANGLE = 360.0f;
174 constexpr float DEFAULT_BIAS = 0.5f;
175 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
176 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
177 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
178 const std::string SHEET_HEIGHT_MEDIUM = "medium";
179 const std::string SHEET_HEIGHT_LARGE = "large";
180 const std::string SHEET_HEIGHT_AUTO = "auto";
181 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
182 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
183 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
184 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
185 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
186 const std::vector<int32_t> LENGTH_METRICS_KEYS {
187     static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
188     static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
189 const char* START_PROPERTY = "start";
190 const char* END_PROPERTY = "end";
191 const char* TOP_PROPERTY = "top";
192 const char* BOTTOM_PROPERTY = "bottom";
193 const char* LEFT_PROPERTY = "left";
194 const char* RIGHT_PROPERTY = "right";
195 const char* TOP_START_PROPERTY = "topStart";
196 const char* TOP_END_PROPERTY = "topEnd";
197 const char* BOTTOM_START_PROPERTY = "bottomStart";
198 const char* BOTTOM_END_PROPERTY = "bottomEnd";
199 const char* DEBUG_LINE_INFO_LINE = "$line";
200 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
201 
202 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
203 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
204 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
205 
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)206 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
207     CalcDimension& centerX, CalcDimension& centerY)
208 {
209     double xVal = 1.0;
210     double yVal = 1.0;
211     double zVal = 1.0;
212     if (!jsValue->IsObject()) {
213         scaleX = static_cast<float>(xVal);
214         scaleY = static_cast<float>(yVal);
215         scaleZ = static_cast<float>(zVal);
216         CalcDimension length;
217         centerX = length;
218         centerY = length;
219         return;
220     }
221     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
222     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
223     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
224     JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
225     scaleX = static_cast<float>(xVal);
226     scaleY = static_cast<float>(yVal);
227     scaleZ = static_cast<float>(zVal);
228     // if specify centerX
229     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
230     // if specify centerY
231     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
232 }
233 
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)234 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
235     CalcDimension& translateZ)
236 {
237     if (!jsValue->IsObject()) {
238         return;
239     }
240     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
241     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
242     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
243     JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
244 }
245 
GetDefaultRotateVector(double & dx,double & dy,double & dz)246 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
247 {
248     dx = 0.0;
249     dy = 0.0;
250     dz = 0.0;
251     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
252         dz = 1.0;
253     }
254 }
255 
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)256 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
257 {
258     if (!jsValue->IsObject()) {
259         return;
260     }
261     // default: dx, dy, dz (0.0, 0.0, 0.0)
262     double dxVal = 0.0;
263     double dyVal = 0.0;
264     double dzVal = 0.0;
265     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
266     auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
267     auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
268     auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
269     if (jsRotateX->IsUndefined()
270         && jsRotateY->IsUndefined()
271         && jsRotateZ->IsUndefined()) {
272         GetDefaultRotateVector(dxVal, dyVal, dzVal);
273     } else {
274         JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
275         JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
276         JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
277     }
278     rotate.xDirection = static_cast<float>(dxVal);
279     rotate.yDirection = static_cast<float>(dyVal);
280     rotate.zDirection = static_cast<float>(dzVal);
281     // if specify centerX
282     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
283         rotate.centerX)) {
284         rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
285     }
286     // if specify centerY
287     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
288         rotate.centerY)) {
289         rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
290     }
291     // if specify centerZ
292     if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
293         rotate.centerZ)) {
294         rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
295     }
296     // if specify angle
297     JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
298     rotate.perspective = 0.0f;
299     JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
300 }
301 
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)302 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
303 {
304     if (!jsValue->IsObject()) {
305         return false;
306     }
307 
308     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
309     auto path = jsObj->GetPropertyValue<std::string>("path", "");
310     if (path.empty()) {
311         return false;
312     }
313     option.SetPath(path);
314     double from = 0.0;
315     double to = 1.0;
316     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
317     JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
318     if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
319         from = 0.0;
320     }
321     if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
322         to = 1.0;
323     } else if (to < from) {
324         to = from;
325     }
326     option.SetBegin(static_cast<float>(from));
327     option.SetEnd(static_cast<float>(to));
328     option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
329     return true;
330 }
331 
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)332 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
333 {
334     if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::AUTO)) {
335         previewOption.ResetDragPreviewMode();
336         isAuto = true;
337         return;
338     } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE)) {
339         previewOption.isScaleEnabled = false;
340     } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW)) {
341         previewOption.isDefaultShadowEnabled = true;
342     } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS)) {
343         previewOption.isDefaultRadiusEnabled = true;
344     }
345     isAuto = false;
346 }
347 
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)348 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
349     BackgroundImagePosition& bgImgPosition)
350 {
351     AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
352     bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
353     bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
354 }
355 
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)356 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
357 {
358     auto index = pos + containCount;
359     if (index < 0) {
360         return std::string();
361     }
362 
363     JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
364     if (type == "d") {
365         if (item->IsNumber()) {
366             return std::to_string(item->ToNumber<int32_t>());
367         } else if (item->IsObject()) {
368             int32_t result = 0;
369             JSViewAbstract::ParseJsInteger(item, result);
370             return std::to_string(result);
371         }
372     } else if (type == "s") {
373         if (item->IsString()) {
374             return item->ToString();
375         } else if (item->IsObject()) {
376             std::string result;
377             JSViewAbstract::ParseJsString(item, result);
378             return result;
379         }
380     } else if (type == "f") {
381         if (item->IsNumber()) {
382             return std::to_string(item->ToNumber<float>());
383         } else if (item->IsObject()) {
384             double result = 0.0;
385             JSViewAbstract::ParseJsDouble(item, result);
386             return std::to_string(result);
387         }
388     }
389     return std::string();
390 }
391 
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)392 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
393 {
394     auto size = static_cast<int32_t>(params->Length());
395     if (containCount == size) {
396         return;
397     }
398     std::string::const_iterator start = originStr.begin();
399     std::string::const_iterator end = originStr.end();
400     std::smatch matches;
401     bool shortHolderType = false;
402     bool firstMatch = true;
403     int searchTime = 0;
404     while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
405         std::string pos = matches[2];
406         std::string type = matches[4];
407         if (firstMatch) {
408             firstMatch = false;
409             shortHolderType = pos.length() == 0;
410         } else {
411             if (shortHolderType ^ (pos.length() == 0)) {
412                 return;
413             }
414         }
415 
416         std::string replaceContentStr;
417         if (shortHolderType) {
418             replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
419         } else {
420             replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
421         }
422 
423         originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
424         start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
425         end = originStr.end();
426         searchTime++;
427     }
428 }
429 
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)430 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y)
431 {
432     JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
433     JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
434     bool hasX = false;
435     bool hasY = false;
436     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
437         hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP);
438         hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP);
439     } else {
440         hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
441         hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
442     }
443     return hasX || hasY;
444 }
445 
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)446 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
447 {
448     bool useEdges = false;
449     CalcDimension top;
450     CalcDimension left;
451     CalcDimension bottom;
452     CalcDimension right;
453     JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
454     JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
455     JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
456     JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
457     if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) {
458         edges.SetTop(top);
459         useEdges = true;
460     }
461     if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) {
462         edges.SetLeft(left);
463         useEdges = true;
464     }
465     if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) {
466         edges.SetBottom(bottom);
467         useEdges = true;
468     }
469     if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) {
470         edges.SetRight(right);
471         useEdges = true;
472     }
473     return useEdges;
474 }
475 
ParseJsLengthMetrics(const JSRef<JSObject> & obj,CalcDimension & result)476 bool ParseJsLengthMetrics(const JSRef<JSObject>& obj, CalcDimension& result)
477 {
478     auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
479     if (!value->IsNumber()) {
480         return false;
481     }
482     auto unit = DimensionUnit::VP;
483     auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
484     if (jsUnit->IsNumber()) {
485         unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
486     }
487     CalcDimension dimension(value->ToNumber<double>(), unit);
488     result = dimension;
489     return true;
490 }
491 
CheckLengthMetrics(const JSRef<JSObject> & object)492 bool CheckLengthMetrics(const JSRef<JSObject>& object)
493 {
494     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
495         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
496         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
497         object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
498         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
499         object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
500         return true;
501     }
502     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
503     if (jsTop->IsObject()) {
504         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
505         if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
506             return true;
507         }
508     }
509     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
510     if (jsBottom->IsObject()) {
511         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
512         if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
513             return true;
514         }
515     }
516     return false;
517 }
518 
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)519 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
520 {
521     bool useLocalizedEdges = false;
522     CalcDimension start;
523     CalcDimension end;
524     CalcDimension top;
525     CalcDimension bottom;
526 
527     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
528     if (startVal->IsObject()) {
529         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
530         ParseJsLengthMetrics(startObj, start);
531         edges.SetLeft(start);
532         useLocalizedEdges = true;
533     }
534     JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
535     if (endVal->IsObject()) {
536         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
537         ParseJsLengthMetrics(endObj, end);
538         edges.SetRight(end);
539         useLocalizedEdges = true;
540     }
541     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
542     if (topVal->IsObject()) {
543         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
544         ParseJsLengthMetrics(topObj, top);
545         edges.SetTop(top);
546         useLocalizedEdges = true;
547     }
548     JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
549     if (bottomVal->IsObject()) {
550         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(bottomVal);
551         ParseJsLengthMetrics(bottomObj, bottom);
552         edges.SetBottom(bottom);
553         useLocalizedEdges = true;
554     }
555     return useLocalizedEdges;
556 }
557 
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)558 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
559 {
560     bool useMarkAnchorPosition = false;
561     CalcDimension start;
562     CalcDimension top;
563 
564     JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
565     if (startVal->IsObject()) {
566         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
567         ParseJsLengthMetrics(startObj, start);
568         x = start;
569         useMarkAnchorPosition = true;
570     }
571     JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
572     if (topVal->IsObject()) {
573         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
574         ParseJsLengthMetrics(topObj, top);
575         y = top;
576         useMarkAnchorPosition = true;
577     }
578     return useMarkAnchorPosition;
579 }
580 
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)581 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
582 {
583     JSRef<JSVal> builder;
584     if (info->IsObject()) {
585         auto builderObj = JSRef<JSObject>::Cast(info);
586         builder = builderObj->GetProperty("builder");
587     } else if (info->IsFunction()) {
588         builder = info;
589     } else {
590         return nullptr;
591     }
592 
593     if (!builder->IsFunction()) {
594         return nullptr;
595     }
596 
597     return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
598 }
599 
600 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
601     const JSRef<JSObject>& object, const JSExecutionContext& context);
602 
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)603 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
604     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
605 {
606     RefPtr<NG::ChainedTransitionEffect> effect;
607     if (effectOption->IsObject()) {
608         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
609         std::optional<float> angle;
610         ParseJsRotate(effectOption, rotate, angle);
611         if (angle.has_value()) {
612             rotate.angle = angle.value();
613             return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
614         }
615     }
616     return nullptr;
617 }
618 
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)619 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
620     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
621 {
622     double opacity = 1.0;
623     if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
624         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
625             if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
626                 opacity = 1.0;
627             }
628         } else {
629             opacity = std::clamp(opacity, 0.0, 1.0);
630         }
631         return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
632     }
633     return nullptr;
634 }
635 
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)636 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
637     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
638 {
639     if (effectOption->IsObject()) {
640         // default: x, y, z (0.0, 0.0, 0.0)
641         NG::TranslateOptions translate;
642         ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
643         return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
644     }
645     return nullptr;
646 }
647 
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)648 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
649     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
650 {
651     if (effectOption->IsObject()) {
652         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
653         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
654         ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
655         return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
656     }
657     return nullptr;
658 }
659 
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)660 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
661     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
662 {
663     int32_t edge = 0;
664     if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
665         if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
666             edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
667             edge = static_cast<int32_t>(NG::TransitionEdge::START);
668         }
669         return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
670     }
671     return nullptr;
672 }
673 
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)674 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
675     const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
676 {
677     if (effectOption->IsObject()) {
678         auto effectObj = JSRef<JSObject>::Cast(effectOption);
679         auto appearJsVal = effectObj->GetProperty("appear");
680         auto disappearJsVal = effectObj->GetProperty("disappear");
681         RefPtr<NG::ChainedTransitionEffect> appearEffect;
682         RefPtr<NG::ChainedTransitionEffect> disappearEffect;
683         if (appearJsVal->IsObject()) {
684             auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
685             appearEffect = ParseChainedTransition(appearObj, context);
686         }
687         if (disappearJsVal->IsObject()) {
688             auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
689             disappearEffect = ParseChainedTransition(disappearObj, context);
690         }
691         return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
692     }
693     return nullptr;
694 }
695 
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)696 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
697 {
698     CHECK_NULL_RETURN(pipelineContext, 0);
699     return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
700 }
701 
702 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
703     const JSRef<JSVal>&, const JSExecutionContext&);
704 
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)705 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
706     const JSRef<JSObject>& object, const JSExecutionContext& context)
707 {
708     auto propType = object->GetProperty("type_");
709     if (!propType->IsString()) {
710         return nullptr;
711     }
712     std::string type = propType->ToString();
713     auto propEffectOption = object->GetProperty("effect_");
714     auto propAnimationOption = object->GetProperty("animation_");
715     auto propSuccessor = object->GetProperty("successor_");
716     static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
717         { "asymmetric", ParseChainedAsymmetricTransition },
718         { "identity",
719             [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
720                 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
721         { "move", ParseChainedMoveTransition },
722         { "opacity", ParseChainedOpacityTransition },
723         { "rotate", ParseChainedRotateTransition },
724         { "scale", ParseChainedScaleTransition },
725         { "slideSwitch",
726             [](const JSRef<JSVal>& effectOption,
727                 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
728                 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
729             } },
730         { "translate", ParseChainedTranslateTransition },
731     };
732     int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
733     if (index < 0) {
734         return nullptr;
735     }
736     RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
737     if (!result) {
738         return nullptr;
739     }
740     if (propAnimationOption->IsObject()) {
741         auto container = Container::Current();
742         CHECK_NULL_RETURN(container, nullptr);
743         auto pipelineContext = container->GetPipelineContext();
744         CHECK_NULL_RETURN(pipelineContext, nullptr);
745         auto animationOptionResult = std::make_shared<AnimationOption>(
746             JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRender()));
747         // The maximum of the form-animation-playback duration value is 1000 ms.
748         if (pipelineContext->IsFormRender() && pipelineContext->IsFormAnimation()) {
749             auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
750             // If the duration exceeds 1000ms, init it to 0 ms.
751             if (formAnimationTimeInterval > DEFAULT_DURATION) {
752                 animationOptionResult->SetDuration(0);
753             } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
754                 // If remaining time is less than 1000ms, check for update duration.
755                 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
756                 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation]  Form Transition SetDuration: %{public}lld ms",
757                     static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
758             }
759         }
760         auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
761         JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
762         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
763         if (onFinish->IsFunction()) {
764             RefPtr<JsFunction> jsFunc =
765                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
766             std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
767                                                       id = Container::CurrentId(), node = targetNode]() {
768                 ContainerScope scope(id);
769                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
770                 PipelineContext::SetCallBackNode(node);
771                 func->Execute();
772             };
773             animationOptionResult->SetOnFinishEvent(onFinishEvent);
774         }
775         result->SetAnimationOption(animationOptionResult);
776     }
777     if (propSuccessor->IsObject()) {
778         result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
779     }
780     return result;
781 }
782 
783 #ifndef WEARABLE_PRODUCT
784 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
785     Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP,
786     Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM };
787 
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)788 DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj)
789 {
790     JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent");
791     if (!changeEvent->IsFunction()) {
792         return {};
793     }
794     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent));
795     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
796     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
797                         const std::string& param) {
798         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
799         if (param != "true" && param != "false") {
800             return;
801         }
802         PipelineContext::SetCallBackNode(node);
803         bool newValue = StringToBool(param);
804         JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
805         func->ExecuteJS(1, &newJSVal);
806     };
807     return callback;
808 }
809 
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)810 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
811 {
812     auto colorValue = messageOptionsObj->GetProperty("textColor");
813     Color textColor;
814     if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
815         if (popupParam) {
816             popupParam->SetTextColor(textColor);
817         }
818     }
819 
820     auto font = messageOptionsObj->GetProperty("font");
821     if (!font->IsNull() && font->IsObject()) {
822         JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
823         auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
824         CalcDimension fontSize;
825         if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
826             if (popupParam && fontSize.IsValid()) {
827                 popupParam->SetFontSize(fontSize);
828             }
829         }
830         auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
831         if (fontWeightValue->IsString()) {
832             if (popupParam) {
833                 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
834             }
835         }
836         auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
837         if (fontStyleValue->IsNumber()) {
838             int32_t value = fontStyleValue->ToNumber<int32_t>();
839             if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
840                 return;
841             }
842             if (popupParam) {
843                 popupParam->SetFontStyle(FONT_STYLES[value]);
844             }
845         }
846     }
847 }
848 
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)849 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
850 {
851     JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
852     if (placementOnTopVal->IsBoolean() && popupParam) {
853         popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
854     }
855 }
856 
IsPopupCreated()857 bool IsPopupCreated()
858 {
859     auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
860     CHECK_NULL_RETURN(targetNode, false);
861     auto targetId = targetNode->GetId();
862     auto container = Container::Current();
863     CHECK_NULL_RETURN(container, false);
864     auto pipelineContext = container->GetPipelineContext();
865     CHECK_NULL_RETURN(pipelineContext, false);
866     auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
867     CHECK_NULL_RETURN(context, false);
868     auto overlayManager = context->GetOverlayManager();
869     CHECK_NULL_RETURN(overlayManager, false);
870     auto popupInfo = overlayManager->GetPopupInfo(targetId);
871     if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
872         return false;
873     }
874     return true;
875 }
876 
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)877 void ParsePopupCommonParam(
878     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
879 {
880     auto arrowOffset = popupObj->GetProperty("arrowOffset");
881     CalcDimension offset;
882     if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
883         if (popupParam) {
884             popupParam->SetArrowOffset(offset);
885         }
886     }
887 
888     auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
889     if (arrowPointPosition->IsString()) {
890         char* pEnd = nullptr;
891         auto arrowString = arrowPointPosition->ToString();
892         std::strtod(arrowString.c_str(), &pEnd);
893         if (pEnd != nullptr) {
894             if (std::strcmp(pEnd, "Start") == 0) {
895                 offset = ARROW_ZERO_PERCENT_VALUE;
896             }
897             if (std::strcmp(pEnd, "Center") == 0) {
898                 offset = ARROW_HALF_PERCENT_VALUE;
899             }
900             if (std::strcmp(pEnd, "End") == 0) {
901                 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
902             }
903             if (popupParam) {
904                 popupParam->SetArrowOffset(offset);
905             }
906         }
907     }
908 
909     auto targetSpace = popupObj->GetProperty("targetSpace");
910     if (!targetSpace->IsNull()) {
911         CalcDimension space;
912         if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
913             if (popupParam) {
914                 popupParam->SetTargetSpace(space);
915             }
916         }
917     }
918 
919     JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
920     if (showInSubWindowValue->IsBoolean()) {
921         bool showInSubBoolean = showInSubWindowValue->ToBoolean();
922 #if defined(PREVIEW)
923         if (showInSubBoolean) {
924             LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
925             showInSubBoolean = false;
926         }
927 #endif
928         if (popupParam) {
929             popupParam->SetShowInSubWindow(showInSubBoolean);
930         }
931     }
932 
933     auto placementValue = popupObj->GetProperty("placement");
934     if (placementValue->IsNumber()) {
935         auto placement = placementValue->ToNumber<int32_t>();
936         if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
937             popupParam->SetPlacement(PLACEMENT[placement]);
938         }
939     } else {
940         SetPlacementOnTopVal(popupObj, popupParam);
941     }
942 
943     auto enableArrowValue = popupObj->GetProperty("enableArrow");
944     if (enableArrowValue->IsBoolean()) {
945         popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
946     }
947 
948     auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
949     if (followTransformOfTargetValue->IsBoolean()) {
950         popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
951     }
952 
953     JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
954     if (maskValue->IsBoolean()) {
955         if (popupParam) {
956             popupParam->SetBlockEvent(maskValue->ToBoolean());
957         }
958     }
959     if (maskValue->IsObject()) {
960         auto maskObj = JSRef<JSObject>::Cast(maskValue);
961         auto colorValue = maskObj->GetProperty("color");
962         Color maskColor;
963         if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
964             popupParam->SetMaskColor(maskColor);
965         }
966     }
967 
968     JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
969     if (onStateChangeVal->IsFunction()) {
970         std::vector<std::string> keys = { "isVisible" };
971         RefPtr<JsFunction> jsFunc =
972             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
973         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
974         if (popupParam) {
975             auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
976                                              node = targetNode](const std::string& param) {
977                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
978                 ACE_SCORING_EVENT("Popup.onStateChange");
979                 PipelineContext::SetCallBackNode(node);
980                 func->Execute(keys, param);
981             };
982             popupParam->SetOnStateChange(onStateChangeCallback);
983         }
984     }
985 
986     auto offsetVal = popupObj->GetProperty("offset");
987     if (offsetVal->IsObject()) {
988         auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
989         auto xVal = offsetObj->GetProperty("x");
990         auto yVal = offsetObj->GetProperty("y");
991         Offset popupOffset;
992         CalcDimension dx;
993         CalcDimension dy;
994         if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
995             popupOffset.SetX(dx.ConvertToPx());
996         }
997         if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
998             popupOffset.SetY(dy.ConvertToPx());
999         }
1000         if (popupParam) {
1001             popupParam->SetTargetOffset(popupOffset);
1002         }
1003     }
1004 
1005     Color backgroundColor;
1006     auto popupColorVal = popupObj->GetProperty("popupColor");
1007     if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
1008         popupParam->SetBackgroundColor(backgroundColor);
1009     }
1010 
1011     auto autoCancelVal = popupObj->GetProperty("autoCancel");
1012     if (autoCancelVal->IsBoolean()) {
1013         popupParam->SetHasAction(!autoCancelVal->ToBoolean());
1014     }
1015 
1016     auto childWidthVal = popupObj->GetProperty("width");
1017     if (!childWidthVal->IsNull()) {
1018         CalcDimension width;
1019         if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
1020             if (width.Value() > 0) {
1021                 popupParam->SetChildWidth(width);
1022             }
1023         }
1024     }
1025 
1026     auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
1027     if (!arrowWidthVal->IsNull()) {
1028         bool setError = true;
1029         CalcDimension arrowWidth;
1030         if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
1031             if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
1032                 popupParam->SetArrowWidth(arrowWidth);
1033                 setError = false;
1034             }
1035         }
1036         popupParam->SetErrorArrowWidth(setError);
1037     }
1038 
1039     auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
1040     if (!arrowHeightVal->IsNull()) {
1041         bool setError = true;
1042         CalcDimension arrowHeight;
1043         if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
1044             if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
1045                 popupParam->SetArrowHeight(arrowHeight);
1046                 setError = false;
1047             }
1048         }
1049         popupParam->SetErrorArrowHeight(setError);
1050     }
1051 
1052     auto radiusVal = popupObj->GetProperty("radius");
1053     if (!radiusVal->IsNull()) {
1054         bool setError = true;
1055         CalcDimension radius;
1056         if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
1057             if (radius.Value() >= 0) {
1058                 popupParam->SetRadius(radius);
1059                 setError = false;
1060             }
1061         }
1062         popupParam->SetErrorRadius(setError);
1063     }
1064 
1065     Shadow shadow;
1066     auto shadowVal = popupObj->GetProperty("shadow");
1067     if (shadowVal->IsObject() || shadowVal->IsNumber()) {
1068         auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
1069         if (!ret) {
1070             JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1071         }
1072     } else {
1073         JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1074     }
1075     popupParam->SetShadow(shadow);
1076 
1077     auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
1078     if (blurStyleValue->IsNumber()) {
1079         auto blurStyle = blurStyleValue->ToNumber<int32_t>();
1080         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1081             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1082             popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
1083         }
1084     }
1085 
1086     auto popupTransition = popupObj->GetProperty("transition");
1087     if (popupTransition->IsObject()) {
1088         popupParam->SetHasTransition(true);
1089         auto obj = JSRef<JSObject>::Cast(popupTransition);
1090         auto effects = ParseChainedTransition(obj, info.GetExecutionContext());
1091         popupParam->SetTransitionEffects(effects);
1092     }
1093 }
1094 
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1095 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1096 {
1097     ParsePopupCommonParam(info, popupObj, popupParam);
1098     JSRef<JSVal> messageVal = popupObj->GetProperty("message");
1099     if (popupParam) {
1100         popupParam->SetMessage(messageVal->ToString());
1101     }
1102 
1103     auto messageOptions = popupObj->GetProperty("messageOptions");
1104     JSRef<JSObject> messageOptionsObj;
1105     if (!messageOptions->IsNull() && messageOptions->IsObject()) {
1106         messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
1107         SetPopupMessageOptions(messageOptionsObj, popupParam);
1108     }
1109 
1110     JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
1111     if (primaryButtonVal->IsObject()) {
1112         ButtonProperties properties;
1113         JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
1114         JSRef<JSVal> value = obj->GetProperty("value");
1115         if (value->IsString()) {
1116             properties.value = value->ToString();
1117         }
1118 
1119         JSRef<JSVal> actionValue = obj->GetProperty("action");
1120         if (actionValue->IsFunction()) {
1121             auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1122             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1123             if (popupParam) {
1124                 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1125                                          node = targetNode](GestureEvent& info) {
1126                     JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1127                     ACE_SCORING_EVENT("primaryButton.action");
1128                     PipelineContext::SetCallBackNode(node);
1129                     func->Execute(info);
1130                 };
1131                 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1132             }
1133         }
1134         properties.showButton = true;
1135         if (popupParam) {
1136             popupParam->SetPrimaryButtonProperties(properties);
1137         }
1138     }
1139 
1140     JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
1141     if (secondaryButtonVal->IsObject()) {
1142         ButtonProperties properties;
1143         JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
1144         JSRef<JSVal> value = obj->GetProperty("value");
1145         if (value->IsString()) {
1146             properties.value = value->ToString();
1147         }
1148 
1149         JSRef<JSVal> actionValue = obj->GetProperty("action");
1150         if (actionValue->IsFunction()) {
1151             auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1152             auto targetNode =
1153                 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1154             if (popupParam) {
1155                 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1156                                          node = targetNode](GestureEvent& info) {
1157                     JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1158                     ACE_SCORING_EVENT("secondaryButton.action");
1159                     PipelineContext::SetCallBackNode(node);
1160                     func->Execute(info);
1161                 };
1162                 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1163             }
1164         }
1165         properties.showButton = true;
1166         if (popupParam) {
1167             popupParam->SetSecondaryButtonProperties(properties);
1168         }
1169     }
1170 }
1171 
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1172 void ParseCustomPopupParam(
1173     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1174 {
1175     auto builderValue = popupObj->GetProperty("builder");
1176     if (!builderValue->IsObject()) {
1177         return;
1178     }
1179     if (!builderValue->IsFunction()) {
1180         JSRef<JSObject> builderObj;
1181         builderObj = JSRef<JSObject>::Cast(builderValue);
1182         auto builder = builderObj->GetProperty("builder");
1183         if (!builder->IsFunction()) {
1184             return;
1185         }
1186         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1187         if (!builderFunc) {
1188             return;
1189         }
1190     }
1191     if (popupParam) {
1192         popupParam->SetUseCustomComponent(true);
1193     }
1194 
1195     auto focusableValue = popupObj->GetProperty("focusable");
1196     if (focusableValue->IsBoolean()) {
1197         popupParam->SetFocusable(focusableValue->ToBoolean());
1198     }
1199 
1200     ParsePopupCommonParam(info, popupObj, popupParam);
1201 }
1202 #endif
1203 
GetBundleNameFromContainer()1204 std::string GetBundleNameFromContainer()
1205 {
1206     auto container = Container::Current();
1207     CHECK_NULL_RETURN(container, "");
1208     return container->GetBundleName();
1209 }
1210 
GetModuleNameFromContainer()1211 std::string GetModuleNameFromContainer()
1212 {
1213     auto container = Container::Current();
1214     CHECK_NULL_RETURN(container, "");
1215     return container->GetModuleName();
1216 }
1217 
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)1218 void CompleteResourceObjectFromParams(
1219     int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
1220 {
1221     JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
1222     int32_t typeNum = -1;
1223     if (type->IsNumber()) {
1224         typeNum = type->ToNumber<int32_t>();
1225     }
1226 
1227     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1228     if (!args->IsArray()) {
1229         return;
1230     }
1231     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1232     if (resId != UNKNOWN_RESOURCE_ID) {
1233         return;
1234     }
1235     JSRef<JSVal> identity = params->GetValueAt(0);
1236 
1237     bool isParseDollarResourceSuccess =
1238         JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
1239     if (!isParseDollarResourceSuccess) {
1240         return;
1241     }
1242 
1243     std::regex resNameRegex(RESOURCE_NAME_PATTERN);
1244     std::smatch resNameResults;
1245     if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
1246         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
1247     }
1248 
1249     if (typeNum == UNKNOWN_RESOURCE_TYPE) {
1250         jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1251     }
1252 }
1253 
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)1254 void CompleteResourceObjectFromId(
1255     JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
1256 {
1257     JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1258     if (!args->IsArray()) {
1259         return;
1260     }
1261     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1262     auto paramCount = params->Length();
1263     JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
1264     if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
1265         std::vector<JSRef<JSVal>> tmpParams;
1266         for (uint32_t i = 0; i < paramCount; i++) {
1267             auto param = params->GetValueAt(i);
1268             tmpParams.insert(tmpParams.end(), param);
1269         }
1270         params->SetValueAt(0, name);
1271         uint32_t paramIndex = 1;
1272         if (!type->IsEmpty()) {
1273             params->SetValueAt(paramIndex, type);
1274             paramIndex++;
1275         }
1276         for (auto tmpParam : tmpParams) {
1277             params->SetValueAt(paramIndex, tmpParam);
1278             paramIndex++;
1279         }
1280     } else {
1281         params->SetValueAt(0, name);
1282     }
1283     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
1284     jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1285     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
1286         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1287     }
1288     if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
1289         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1290     }
1291 }
1292 
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)1293 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
1294 {
1295     if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
1296         checkDimension.Reset();
1297         return;
1298     }
1299     if (notNegative && checkDimension.IsNegative()) {
1300         checkDimension.Reset();
1301         return;
1302     }
1303 }
1304 
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1305 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1306 {
1307     Color left;
1308     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1309         commonColor.left = left;
1310     }
1311     Color right;
1312     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1313         commonColor.right = right;
1314     }
1315     Color top;
1316     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1317         commonColor.top = top;
1318     }
1319     Color bottom;
1320     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1321         commonColor.bottom = bottom;
1322     }
1323 }
1324 
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1325 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
1326 {
1327     Color start;
1328     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) {
1329         localizedColor.start = start;
1330     }
1331     Color end;
1332     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) {
1333         localizedColor.end = end;
1334     }
1335     Color top;
1336     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1337         localizedColor.top = top;
1338     }
1339     Color bottom;
1340     if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1341         localizedColor.bottom = bottom;
1342     }
1343 }
1344 
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1345 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1346 {
1347     if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
1348         object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
1349         LocalizedColor localizedColor;
1350         ParseLocalizedEdgeColors(object, localizedColor);
1351         commonColor.top = localizedColor.top;
1352         commonColor.bottom = localizedColor.bottom;
1353         commonColor.left = localizedColor.start;
1354         commonColor.right = localizedColor.end;
1355         return true;
1356     }
1357     ParseEdgeColors(object, commonColor);
1358     return false;
1359 }
1360 
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1361 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1362 {
1363     CalcDimension left;
1364     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1365         CheckDimensionUnit(left, true, notNegative);
1366         commonCalcDimension.left = left;
1367     }
1368     CalcDimension right;
1369     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1370         CheckDimensionUnit(right, true, notNegative);
1371         commonCalcDimension.right = right;
1372     }
1373     CalcDimension top;
1374     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1375         CheckDimensionUnit(top, true, notNegative);
1376         commonCalcDimension.top = top;
1377     }
1378     CalcDimension bottom;
1379     if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1380         CheckDimensionUnit(bottom, true, notNegative);
1381         commonCalcDimension.bottom = bottom;
1382     }
1383 }
1384 
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1385 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
1386     bool notNegative, CalcDimension defaultValue)
1387 {
1388     CalcDimension left;
1389     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) {
1390         CheckDimensionUnit(left, notPercent, notNegative);
1391         commonCalcDimension.left = left;
1392     } else {
1393         commonCalcDimension.left = defaultValue;
1394     }
1395     CalcDimension right;
1396     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) {
1397         CheckDimensionUnit(right, notPercent, notNegative);
1398         commonCalcDimension.right = right;
1399     } else {
1400         commonCalcDimension.right = defaultValue;
1401     }
1402     CalcDimension top;
1403     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) {
1404         CheckDimensionUnit(top, notPercent, notNegative);
1405         commonCalcDimension.top = top;
1406     } else {
1407         commonCalcDimension.top = defaultValue;
1408     }
1409     CalcDimension bottom;
1410     if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) {
1411         CheckDimensionUnit(bottom, false, true);
1412         commonCalcDimension.bottom = bottom;
1413     } else {
1414         commonCalcDimension.bottom = defaultValue;
1415     }
1416 }
1417 
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)1418 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
1419                               bool notNegative)
1420 {
1421     auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
1422     if (jsStart->IsObject()) {
1423         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
1424         CalcDimension calcDimension;
1425         if (ParseJsLengthMetrics(startObj, calcDimension)) {
1426             CheckDimensionUnit(calcDimension, true, notNegative);
1427             localizedCalcDimension.start = calcDimension;
1428         }
1429     }
1430     auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
1431     if (jsEnd->IsObject()) {
1432         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
1433         CalcDimension calcDimension;
1434         if (ParseJsLengthMetrics(endObj, calcDimension)) {
1435             CheckDimensionUnit(calcDimension, true, notNegative);
1436             localizedCalcDimension.end = calcDimension;
1437         }
1438     }
1439     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
1440     if (jsTop->IsObject()) {
1441         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
1442         CalcDimension calcDimension;
1443         if (ParseJsLengthMetrics(topObj, calcDimension)) {
1444             CheckDimensionUnit(calcDimension, true, notNegative);
1445             localizedCalcDimension.top = calcDimension;
1446         }
1447     }
1448     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
1449     if (jsBottom->IsObject()) {
1450         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
1451         CalcDimension calcDimension;
1452         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1453             CheckDimensionUnit(calcDimension, true, notNegative);
1454             localizedCalcDimension.bottom = calcDimension;
1455         }
1456     }
1457 }
1458 
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)1459 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
1460 {
1461     if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
1462         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
1463         CalcDimension calcDimension;
1464         if (ParseJsLengthMetrics(startObj, calcDimension)) {
1465             CheckDimensionUnit(calcDimension, false, true);
1466             localizedCalcDimension.start = calcDimension;
1467         }
1468     }
1469     if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
1470         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
1471         CalcDimension calcDimension;
1472         if (ParseJsLengthMetrics(endObj, calcDimension)) {
1473             CheckDimensionUnit(calcDimension, false, true);
1474             localizedCalcDimension.end = calcDimension;
1475         }
1476     }
1477     if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
1478         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
1479         CalcDimension calcDimension;
1480         if (ParseJsLengthMetrics(topObj, calcDimension)) {
1481             CheckDimensionUnit(calcDimension, false, true);
1482             localizedCalcDimension.top = calcDimension;
1483         }
1484     }
1485     if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
1486         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
1487         CalcDimension calcDimension;
1488         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1489             CheckDimensionUnit(calcDimension, false, true);
1490             localizedCalcDimension.bottom = calcDimension;
1491         }
1492     }
1493 }
1494 
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1495 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1496 {
1497     if (CheckLengthMetrics(object)) {
1498         LocalizedCalcDimension localizedCalcDimension;
1499         ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
1500         commonCalcDimension.top = localizedCalcDimension.top;
1501         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1502         commonCalcDimension.left = localizedCalcDimension.start;
1503         commonCalcDimension.right = localizedCalcDimension.end;
1504         return true;
1505     }
1506     ParseEdgeWidths(object, commonCalcDimension, notNegative);
1507     return false;
1508 }
1509 
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1510 void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1511 {
1512     if (CheckLengthMetrics(object)) {
1513         LocalizedCalcDimension localizedCalcDimension;
1514         ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
1515         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1516         commonCalcDimension.top = localizedCalcDimension.top;
1517         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1518         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1519         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1520         return;
1521     }
1522     ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1523 }
1524 
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1525 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1526 {
1527     if (CheckLengthMetrics(object)) {
1528         LocalizedCalcDimension localizedCalcDimension;
1529         ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1530         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1531         commonCalcDimension.top = localizedCalcDimension.top;
1532         commonCalcDimension.bottom = localizedCalcDimension.bottom;
1533         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1534         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1535         return;
1536     }
1537     ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1538 }
1539 
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1540 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1541 {
1542     auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1543     auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1544     auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1545         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1546         NG::PipelineContext::SetCallBackNode(targetNode);
1547         JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1548         jsFuncFinish->ExecuteJS(1, &newJSVal);
1549     };
1550     return finishCallback;
1551 }
1552 } // namespace
1553 
GetResourceObject(const JSRef<JSObject> & jsObj)1554 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1555 {
1556     auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1557     auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1558     auto args = jsObj->GetProperty("params");
1559 
1560     std::string bundleName;
1561     std::string moduleName;
1562     auto bundle = jsObj->GetProperty("bundleName");
1563     auto module = jsObj->GetProperty("moduleName");
1564     if (bundle->IsString() && module->IsString()) {
1565         bundleName = bundle->ToString();
1566         moduleName = module->ToString();
1567     }
1568     if (!args->IsArray()) {
1569         return nullptr;
1570     }
1571     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1572     std::vector<ResourceObjectParams> resObjParamsList;
1573     auto size = static_cast<int32_t>(params->Length());
1574     for (int32_t i = 0; i < size; i++) {
1575         auto item = params->GetValueAt(i);
1576         ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1577         if (item->IsString()) {
1578             resObjParams.type = ResourceObjectParamType::STRING;
1579         } else if (item->IsNumber()) {
1580             if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1581                 resObjParams.type = ResourceObjectParamType::FLOAT;
1582             } else {
1583                 resObjParams.type = ResourceObjectParamType::INT;
1584             }
1585         }
1586         resObjParamsList.push_back(resObjParams);
1587     }
1588     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName);
1589     return resourceObject;
1590 }
1591 
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1592 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1593 {
1594     auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1595     auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1596     auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName);
1597     return resourceObject;
1598 }
1599 
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1600 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1601 {
1602     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1603     RefPtr<ThemeConstants> themeConstants = nullptr;
1604     if (SystemProperties::GetResourceDecoupling()) {
1605         resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1606         if (!resourceAdapter) {
1607             return nullptr;
1608         }
1609     } else {
1610         themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1611         if (!themeConstants) {
1612             return nullptr;
1613         }
1614     }
1615     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1616     return resourceWrapper;
1617 }
1618 
CreateResourceWrapper()1619 RefPtr<ResourceWrapper> CreateResourceWrapper()
1620 {
1621     RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1622     RefPtr<ThemeConstants> themeConstants = nullptr;
1623     if (SystemProperties::GetResourceDecoupling()) {
1624         resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter();
1625         if (!resourceAdapter) {
1626             return nullptr;
1627         }
1628     } else {
1629         themeConstants = JSViewAbstract::GetThemeConstants();
1630         if (!themeConstants) {
1631             return nullptr;
1632         }
1633     }
1634     auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1635     return resourceWrapper;
1636 }
1637 
ColorAlphaAdapt(uint32_t origin)1638 uint32_t ColorAlphaAdapt(uint32_t origin)
1639 {
1640     uint32_t result = origin;
1641     if (origin >> COLOR_ALPHA_OFFSET == 0) {
1642         result = origin | COLOR_ALPHA_VALUE;
1643     }
1644     return result;
1645 }
1646 
JsScale(const JSCallbackInfo & info)1647 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1648 {
1649     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1650     auto jsVal = info[0];
1651     if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1652         SetDefaultScale();
1653         return;
1654     }
1655 
1656     if (jsVal->IsObject()) {
1657         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1658         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1659             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1660             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1661             // default: x, y, z (1.0, 1.0, 1.0)
1662             auto scaleX = 1.0f;
1663             auto scaleY = 1.0f;
1664             auto scaleZ = 1.0f;
1665             // default centerX, centerY 50% 50%;
1666             CalcDimension centerX = 0.5_pct;
1667             CalcDimension centerY = 0.5_pct;
1668             ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1669             ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1670             ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1671             return;
1672         } else {
1673             SetDefaultScale();
1674         }
1675     }
1676     double scale = 0.0;
1677     if (ParseJsDouble(jsVal, scale)) {
1678         ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1679     }
1680 }
1681 
SetDefaultScale()1682 void JSViewAbstract::SetDefaultScale()
1683 {
1684     ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1685     ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1686 }
1687 
JsScaleX(const JSCallbackInfo & info)1688 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1689 {
1690     double scaleVal = 0.0;
1691     if (!ParseJsDouble(info[0], scaleVal)) {
1692         return;
1693     }
1694     ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1695 }
1696 
JsScaleY(const JSCallbackInfo & info)1697 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1698 {
1699     double scaleVal = 0.0;
1700     if (!ParseJsDouble(info[0], scaleVal)) {
1701         return;
1702     }
1703     ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1704 }
1705 
JsOpacity(const JSCallbackInfo & info)1706 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1707 {
1708     double opacity = 0.0;
1709     if (!ParseJsDouble(info[0], opacity)) {
1710         ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1711         return;
1712     }
1713     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1714         opacity = std::clamp(opacity, 0.0, 1.0);
1715     } else {
1716         if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1717             opacity = 1.0;
1718         }
1719     }
1720     ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1721 }
1722 
JsTranslate(const JSCallbackInfo & info)1723 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1724 {
1725     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1726         JSCallbackInfoType::OBJECT };
1727     auto jsVal = info[0];
1728     if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
1729         SetDefaultTranslate();
1730         return;
1731     }
1732 
1733     if (jsVal->IsObject()) {
1734         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1735         if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1736             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1737             jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1738             // default: x, y, z (0.0, 0.0, 0.0)
1739             auto translateX = CalcDimension(0.0);
1740             auto translateY = CalcDimension(0.0);
1741             auto translateZ = CalcDimension(0.0);
1742             ParseJsTranslate(jsVal, translateX, translateY, translateZ);
1743             ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1744             return;
1745         } else {
1746             SetDefaultTranslate();
1747         }
1748     }
1749     CalcDimension value;
1750     if (ParseJsDimensionVp(jsVal, value)) {
1751         ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1752     }
1753 }
1754 
SetDefaultTranslate()1755 void JSViewAbstract::SetDefaultTranslate()
1756 {
1757     ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1758 }
1759 
JsTranslateX(const JSCallbackInfo & info)1760 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1761 {
1762     CalcDimension value;
1763     if (!ParseJsDimensionVp(info[0], value)) {
1764         return;
1765     }
1766     ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1767 }
1768 
JsTranslateY(const JSCallbackInfo & info)1769 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1770 {
1771     CalcDimension value;
1772     if (!ParseJsDimensionVp(info[0], value)) {
1773         return;
1774     }
1775     ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1776 }
1777 
JsRotate(const JSCallbackInfo & info)1778 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1779 {
1780     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1781     auto jsVal = info[0];
1782     if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
1783         SetDefaultRotate();
1784         return;
1785     }
1786 
1787     if (jsVal->IsObject()) {
1788         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1789         std::optional<float> angle;
1790         ParseJsRotate(jsVal, rotate, angle);
1791         if (angle) {
1792             ViewAbstractModel::GetInstance()->SetRotate(
1793                 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1794             ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1795         } else {
1796             SetDefaultRotate();
1797         }
1798         return;
1799     }
1800     double rotateZ;
1801     if (ParseJsDouble(jsVal, rotateZ)) {
1802         ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1803     }
1804 }
1805 
SetDefaultRotate()1806 void JSViewAbstract::SetDefaultRotate()
1807 {
1808     NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1809     ViewAbstractModel::GetInstance()->SetRotate(
1810         rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1811     ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1812 }
1813 
JsRotateX(const JSCallbackInfo & info)1814 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1815 {
1816     double rotateVal = 0.0;
1817     if (!ParseJsDouble(info[0], rotateVal)) {
1818         return;
1819     }
1820     ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1821 }
1822 
JsRotateY(const JSCallbackInfo & info)1823 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1824 {
1825     double rotateVal = 0.0;
1826     if (!ParseJsDouble(info[0], rotateVal)) {
1827         return;
1828     }
1829     ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1830 }
1831 
JsTransform(const JSCallbackInfo & info)1832 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1833 {
1834     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1835     auto jsVal = info[0];
1836     if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
1837         SetDefaultTransform();
1838         return;
1839     }
1840     JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
1841     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1842     if (!array->IsArray()) {
1843         return;
1844     }
1845     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1846     if (jsArray->Length() != matrix4Len) {
1847         return;
1848     }
1849     std::vector<float> matrix(matrix4Len);
1850     for (int32_t i = 0; i < matrix4Len; i++) {
1851         double value = 0.0;
1852         ParseJsDouble(jsArray->GetValueAt(i), value);
1853         matrix[i] = static_cast<float>(value);
1854     }
1855     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1856 }
1857 
SetDefaultTransform()1858 void JSViewAbstract::SetDefaultTransform()
1859 {
1860     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1861     std::vector<float> matrix(matrix4Len);
1862     const int32_t initPosition = 5;
1863     for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1864         double value = 1.0;
1865         matrix[i] = static_cast<float>(value);
1866     }
1867     ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1868 }
1869 
ParseJsTransition(const JSRef<JSObject> & jsObj)1870 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
1871 {
1872     NG::TransitionOptions transitionOption;
1873     bool hasEffect = false;
1874     transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1875     if (jsObj->HasProperty("opacity")) {
1876         double opacity = 1.0;
1877         ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1878         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1879             if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1880                 opacity = 1.0;
1881             }
1882         } else {
1883             opacity = std::clamp(opacity, 0.0, 1.0);
1884         }
1885         transitionOption.UpdateOpacity(static_cast<float>(opacity));
1886         hasEffect = true;
1887     }
1888     if (jsObj->HasProperty("translate")) {
1889         // default: x, y, z (0.0, 0.0, 0.0)
1890         NG::TranslateOptions translate;
1891         ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1892         transitionOption.UpdateTranslate(translate);
1893         hasEffect = true;
1894     }
1895     if (jsObj->HasProperty("scale")) {
1896         // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1897         NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1898         ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1899             scale.centerX, scale.centerY);
1900         transitionOption.UpdateScale(scale);
1901         hasEffect = true;
1902     }
1903     if (jsObj->HasProperty("rotate")) {
1904         // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1905         NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1906         std::optional<float> angle;
1907         ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1908         if (angle.has_value()) {
1909             rotate.angle = angle.value();
1910             transitionOption.UpdateRotate(rotate);
1911             hasEffect = true;
1912         }
1913     }
1914     if (!hasEffect) {
1915         // default transition
1916         transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1917     }
1918     return transitionOption;
1919 }
1920 
ParseJsTransitionEffect(const JSCallbackInfo & info)1921 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
1922 {
1923     JSRef<JSVal> arg = info[0];
1924     if (!arg->IsObject()) {
1925         return nullptr;
1926     }
1927     auto obj = JSRef<JSObject>::Cast(arg);
1928     auto transitionVal = obj->GetProperty("transition");
1929 
1930     if (!transitionVal->IsObject()) {
1931         return nullptr;
1932     }
1933 
1934     auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
1935     auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
1936     return chainedEffect;
1937 }
1938 
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)1939 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
1940     const JSExecutionContext& context)
1941 {
1942     auto chainedEffect = ParseChainedTransition(object, context);
1943     return chainedEffect;
1944 }
1945 
JsTransition(const JSCallbackInfo & info)1946 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
1947 {
1948     if (info.Length() < 1 || !info[0]->IsObject()) {
1949         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
1950             ViewAbstractModel::GetInstance()->CleanTransition();
1951             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
1952         }
1953         return;
1954     }
1955     auto obj = JSRef<JSObject>::Cast(info[0]);
1956     if (!obj->GetProperty("successor_")->IsUndefined()) {
1957         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
1958         std::function<void(bool)> finishCallback;
1959         if (info.Length() > 1 && info[1]->IsFunction()) {
1960             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
1961         }
1962         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
1963         return;
1964     }
1965     auto options = ParseJsTransition(obj);
1966     ViewAbstractModel::GetInstance()->SetTransition(options);
1967 }
1968 
JsWidth(const JSCallbackInfo & info)1969 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
1970 {
1971     JsWidth(info[0]);
1972 }
1973 
JsWidth(const JSRef<JSVal> & jsValue)1974 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
1975 {
1976     CalcDimension value;
1977     if (jsValue->IsUndefined()) {
1978         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1979         return true;
1980     }
1981     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1982         if (!ParseJsDimensionVpNG(jsValue, value)) {
1983             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1984             return false;
1985         }
1986     } else if (!ParseJsDimensionVp(jsValue, value)) {
1987         return false;
1988     }
1989 
1990     if (LessNotEqual(value.Value(), 0.0)) {
1991         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1992             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1993             return true;
1994         } else {
1995             value.SetValue(0.0);
1996         }
1997     }
1998 
1999     ViewAbstractModel::GetInstance()->SetWidth(value);
2000     return true;
2001 }
2002 
JsHeight(const JSCallbackInfo & info)2003 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
2004 {
2005     JsHeight(info[0]);
2006 }
2007 
JsHeight(const JSRef<JSVal> & jsValue)2008 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
2009 {
2010     CalcDimension value;
2011     if (jsValue->IsUndefined()) {
2012         ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2013         return true;
2014     }
2015     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2016         if (!ParseJsDimensionVpNG(jsValue, value)) {
2017             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2018             return false;
2019         }
2020     } else if (!ParseJsDimensionVp(jsValue, value)) {
2021         return false;
2022     }
2023 
2024     if (LessNotEqual(value.Value(), 0.0)) {
2025         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2026             ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2027             return true;
2028         } else {
2029             value.SetValue(0.0);
2030         }
2031     }
2032 
2033     ViewAbstractModel::GetInstance()->SetHeight(value);
2034     return true;
2035 }
2036 
JsResponseRegion(const JSCallbackInfo & info)2037 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
2038 {
2039     std::vector<DimensionRect> result;
2040     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2041         ViewAbstractModel::GetInstance()->SetResponseRegion({});
2042         return;
2043     }
2044 
2045     ViewAbstractModel::GetInstance()->SetResponseRegion(result);
2046 }
2047 
JsMouseResponseRegion(const JSCallbackInfo & info)2048 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
2049 {
2050     std::vector<DimensionRect> result;
2051     if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2052         ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
2053         return;
2054     }
2055     ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
2056 }
2057 
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2058 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
2059 {
2060     result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
2061     result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
2062     if (!jsValue->IsObject()) {
2063         return true;
2064     }
2065 
2066     JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
2067     JSRef<JSVal> x = obj->GetProperty("x");
2068     JSRef<JSVal> y = obj->GetProperty("y");
2069     JSRef<JSVal> width = obj->GetProperty("width");
2070     JSRef<JSVal> height = obj->GetProperty("height");
2071     CalcDimension xDimen = result.GetOffset().GetX();
2072     CalcDimension yDimen = result.GetOffset().GetY();
2073     CalcDimension widthDimen = result.GetWidth();
2074     CalcDimension heightDimen = result.GetHeight();
2075     auto s1 = width->ToString();
2076     auto s2 = height->ToString();
2077     if (s1.find('-') != std::string::npos) {
2078         width = JSRef<JSVal>::Make(ToJSValue("100%"));
2079     }
2080     if (s2.find('-') != std::string::npos) {
2081         height = JSRef<JSVal>::Make(ToJSValue("100%"));
2082     }
2083     if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
2084         auto offset = result.GetOffset();
2085         offset.SetX(xDimen);
2086         result.SetOffset(offset);
2087     }
2088     if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
2089         auto offset = result.GetOffset();
2090         offset.SetY(yDimen);
2091         result.SetOffset(offset);
2092     }
2093     if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
2094         if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
2095             return true;
2096         }
2097         result.SetWidth(widthDimen);
2098     }
2099     if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
2100         if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
2101             return true;
2102         }
2103         result.SetHeight(heightDimen);
2104     }
2105     return true;
2106 }
2107 
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2108 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
2109 {
2110     if (!jsValue->IsArray() && !jsValue->IsObject()) {
2111         return false;
2112     }
2113 
2114     if (jsValue->IsArray()) {
2115         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2116         for (size_t i = 0; i < array->Length(); i++) {
2117             CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2118             CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2119             CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2120             CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2121             DimensionOffset offsetDimen(xDimen, yDimen);
2122             DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2123             if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
2124                 result.emplace_back(dimenRect);
2125             } else {
2126                 return false;
2127             }
2128         }
2129         return true;
2130     }
2131 
2132     CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2133     CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2134     CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2135     CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2136     DimensionOffset offsetDimen(xDimen, yDimen);
2137     DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2138     if (ParseJsDimensionRect(jsValue, dimenRect)) {
2139         result.emplace_back(dimenRect);
2140         return true;
2141     } else {
2142         return false;
2143     }
2144 }
2145 
JsSize(const JSCallbackInfo & info)2146 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
2147 {
2148     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2149     auto jsVal = info[0];
2150     if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
2151         return;
2152     }
2153 
2154     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2155     JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
2156     JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
2157 }
2158 
JsConstraintSize(const JSCallbackInfo & info)2159 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
2160 {
2161     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2162     auto jsVal = info[0];
2163     if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
2164         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2165         ViewAbstractModel::GetInstance()->ResetMinSize(true);
2166         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2167         ViewAbstractModel::GetInstance()->ResetMinSize(false);
2168         return;
2169     }
2170 
2171     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2172 
2173     JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
2174     CalcDimension minWidth;
2175     JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
2176     CalcDimension maxWidth;
2177     JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
2178     CalcDimension minHeight;
2179     JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
2180     CalcDimension maxHeight;
2181     bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
2182     if (ParseJsDimensionVp(minWidthValue, minWidth)) {
2183         ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
2184     } else if (version10OrLarger) {
2185         ViewAbstractModel::GetInstance()->ResetMinSize(true);
2186     }
2187 
2188     if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
2189         ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
2190     } else if (version10OrLarger) {
2191         ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2192     }
2193 
2194     if (ParseJsDimensionVp(minHeightValue, minHeight)) {
2195         ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
2196     } else if (version10OrLarger) {
2197         ViewAbstractModel::GetInstance()->ResetMinSize(false);
2198     }
2199 
2200     if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
2201         ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
2202     } else if (version10OrLarger) {
2203         ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2204     }
2205 }
2206 
JsLayoutPriority(const JSCallbackInfo & info)2207 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
2208 {
2209     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2210     auto jsVal = info[0];
2211     if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
2212         return;
2213     }
2214 
2215     int32_t priority;
2216     if (jsVal->IsNumber()) {
2217         priority = jsVal->ToNumber<int32_t>();
2218     } else {
2219         priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
2220     }
2221     ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
2222 }
2223 
JsPixelRound(const JSCallbackInfo & info)2224 void JSViewAbstract::JsPixelRound(const JSCallbackInfo& info)
2225 {
2226     uint8_t value = 0;
2227     JSRef<JSVal> arg = info[0];
2228     if (!arg->IsObject()) {
2229         return;
2230     }
2231     JSRef<JSObject> object = JSRef<JSObject>::Cast(arg);
2232     JSRef<JSVal> jsStartValue = object->GetProperty("start");
2233     if (jsStartValue->IsNumber()) {
2234         int32_t startValue = jsStartValue->ToNumber<int32_t>();
2235         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(startValue)) {
2236             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_START);
2237         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(startValue)) {
2238             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_START);
2239         }
2240     }
2241     JSRef<JSVal> jsTopValue = object->GetProperty("top");
2242     if (jsTopValue->IsNumber()) {
2243         int32_t topValue = jsTopValue->ToNumber<int32_t>();
2244         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(topValue)) {
2245             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
2246         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(topValue)) {
2247             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
2248         }
2249     }
2250     JSRef<JSVal> jsEndValue = object->GetProperty("end");
2251     if (jsEndValue->IsNumber()) {
2252         int32_t endValue = jsEndValue->ToNumber<int32_t>();
2253         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(endValue)) {
2254             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_END);
2255         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(endValue)) {
2256             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_END);
2257         }
2258     }
2259     JSRef<JSVal> jsBottomValue = object->GetProperty("bottom");
2260     if (jsBottomValue->IsNumber()) {
2261         int32_t bottomValue = jsBottomValue->ToNumber<int32_t>();
2262         if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2263             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
2264         } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2265             value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
2266         }
2267     }
2268     ViewAbstractModel::GetInstance()->SetPixelRound(value);
2269 }
2270 
JsLayoutWeight(const JSCallbackInfo & info)2271 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
2272 {
2273     float value = 0.0f;
2274     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2275     auto jsVal = info[0];
2276     if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
2277         if (!jsVal->IsUndefined()) {
2278             return;
2279         }
2280     }
2281 
2282     if (jsVal->IsNumber()) {
2283         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2284             value = jsVal->ToNumber<float>();
2285         } else {
2286             value = jsVal->ToNumber<int32_t>();
2287         }
2288     } else {
2289         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2290             value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
2291         } else {
2292             value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
2293         }
2294     }
2295 
2296     ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
2297 }
2298 
JsAlign(const JSCallbackInfo & info)2299 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
2300 {
2301     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2302     auto jsVal = info[0];
2303     if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
2304         Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2305         ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
2306         return;
2307     }
2308     auto value = jsVal->ToNumber<int32_t>();
2309     Alignment alignment = ParseAlignment(value);
2310     ViewAbstractModel::GetInstance()->SetAlign(alignment);
2311 }
2312 
JsPosition(const JSCallbackInfo & info)2313 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
2314 {
2315     CalcDimension x;
2316     CalcDimension y;
2317     OHOS::Ace::EdgesParam edges;
2318 
2319     auto jsArg = info[0];
2320     if (jsArg->IsObject()) {
2321         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2322         if (ParseLocationProps(jsObj, x, y)) {
2323             return ViewAbstractModel::GetInstance()->SetPosition(x, y);
2324         } else if (ParseLocalizedEdges(jsObj, edges)) {
2325             ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
2326             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2327         } else if (ParseLocationPropsEdges(jsObj, edges)) {
2328             return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2329         }
2330     }
2331     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2332         ViewAbstractModel::GetInstance()->ResetPosition();
2333     } else {
2334         ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
2335     }
2336 }
2337 
JsMarkAnchor(const JSCallbackInfo & info)2338 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
2339 {
2340     CalcDimension x;
2341     CalcDimension y;
2342 
2343     auto jsArg = info[0];
2344     if (jsArg->IsObject()) {
2345         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2346         if (ParseMarkAnchorPosition(jsObj, x, y)) {
2347             ViewAbstractModel::GetInstance()->SetLocalizedMarkAnchor(true);
2348             return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2349         } else if (ParseLocationProps(jsObj, x, y)) {
2350             return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2351         }
2352     }
2353     ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
2354 }
2355 
JsOffset(const JSCallbackInfo & info)2356 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
2357 {
2358     CalcDimension x;
2359     CalcDimension y;
2360     OHOS::Ace::EdgesParam edges;
2361     auto jsArg = info[0];
2362     if (jsArg->IsObject()) {
2363         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2364         if (ParseLocalizedEdges(jsObj, edges)) {
2365             ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
2366             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2367         } else if (ParseLocationProps(jsObj, x, y)) {
2368             return ViewAbstractModel::GetInstance()->SetOffset(x, y);
2369         } else if (ParseLocationPropsEdges(jsObj, edges)) {
2370             return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2371         }
2372     }
2373 
2374     ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
2375 }
2376 
JsEnabled(const JSCallbackInfo & info)2377 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
2378 {
2379     auto arg = info[0];
2380     if (!arg->IsBoolean()) {
2381         ViewAbstractModel::GetInstance()->SetEnabled(true);
2382     } else {
2383         ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
2384     }
2385 }
2386 
JsAspectRatio(const JSCallbackInfo & info)2387 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
2388 {
2389     double value = 0.0;
2390     auto jsAspectRatio = info[0];
2391     if (!ParseJsDouble(jsAspectRatio, value)) {
2392         // add version protection, undefined use default value
2393         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
2394             (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
2395             ViewAbstractModel::GetInstance()->ResetAspectRatio();
2396             return;
2397         } else {
2398             return;
2399         }
2400     }
2401 
2402     // negative use default value.
2403     if (LessOrEqual(value, 0.0)) {
2404         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2405             ViewAbstractModel::GetInstance()->ResetAspectRatio();
2406             return;
2407         } else {
2408             value = 1.0;
2409         }
2410     }
2411 
2412     ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
2413 }
2414 
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2415 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
2416     std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
2417 {
2418     if (info[0]->IsString()) {
2419         std::string text = info[0]->ToString();
2420         ViewAbstractModel::GetInstance()->SetOverlay(
2421             text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
2422     } else if (info[0]->IsObject()) {
2423         JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
2424         auto builder = overlayObject->GetProperty("builder");
2425         if (builder->IsFunction()) {
2426             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2427             CHECK_NULL_VOID(builderFunc);
2428             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2429             auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
2430                               node = targetNode]() {
2431                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2432                 ACE_SCORING_EVENT("Overlay");
2433                 PipelineContext::SetCallBackNode(node);
2434                 func->Execute();
2435             };
2436             ViewAbstractModel::GetInstance()->SetOverlay(
2437                 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
2438             return;
2439         }
2440 
2441         JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
2442         if (!builderNode->IsObject()) {
2443             return;
2444         }
2445         auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2446         JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2447         if (nodePtr.IsEmpty()) {
2448             return;
2449         }
2450         const auto* vm = nodePtr->GetEcmaVM();
2451         auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
2452         auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2453         CHECK_NULL_VOID(frameNode);
2454         RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2455         ViewAbstractModel::GetInstance()->SetOverlay(
2456             "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2457     }
2458 }
2459 
JsOverlay(const JSCallbackInfo & info)2460 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2461 {
2462     if (info.Length() > 0 && (info[0]->IsUndefined())) {
2463         ViewAbstractModel::GetInstance()->SetOverlay(
2464             "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2465         return;
2466     }
2467 
2468     if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2469         return;
2470     }
2471     std::optional<Alignment> align;
2472     std::optional<CalcDimension> offsetX;
2473     std::optional<CalcDimension> offsetY;
2474 
2475     if (info[1]->IsObject()) {
2476         JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2477         JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2478         auto value = alignVal->ToNumber<int32_t>();
2479         Alignment alignment = ParseAlignment(value);
2480         align = alignment;
2481 
2482         JSRef<JSVal> val = optionObj->GetProperty("offset");
2483         if (val->IsObject()) {
2484             JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2485             JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2486             CalcDimension x;
2487             if (ParseJsDimensionVp(xVal, x)) {
2488                 offsetX = x;
2489             }
2490             JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2491             CalcDimension y;
2492             if (ParseJsDimensionVp(yVal, y)) {
2493                 offsetY = y;
2494             }
2495         }
2496     }
2497 
2498     ParseOverlayFirstParam(info, align, offsetX, offsetY);
2499 }
2500 
ParseAlignment(int32_t align)2501 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2502 {
2503     Alignment alignment = Alignment::CENTER;
2504     switch (align) {
2505         case 0:
2506             alignment = Alignment::TOP_LEFT;
2507             break;
2508         case 1:
2509             alignment = Alignment::TOP_CENTER;
2510             break;
2511         case 2:
2512             alignment = Alignment::TOP_RIGHT;
2513             break;
2514         case 3:
2515             alignment = Alignment::CENTER_LEFT;
2516             break;
2517         case 4:
2518             alignment = Alignment::CENTER;
2519             break;
2520         case 5:
2521             alignment = Alignment::CENTER_RIGHT;
2522             break;
2523         case 6:
2524             alignment = Alignment::BOTTOM_LEFT;
2525             break;
2526         case 7:
2527             alignment = Alignment::BOTTOM_CENTER;
2528             break;
2529         case 8:
2530             alignment = Alignment::BOTTOM_RIGHT;
2531             break;
2532         default:
2533             break;
2534     }
2535     return alignment;
2536 }
2537 
SetVisibility(const JSCallbackInfo & info)2538 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2539 {
2540     int32_t visible = 0;
2541     JSRef<JSVal> arg = info[0];
2542     if (arg->IsNull() || arg->IsUndefined()) {
2543         // undefined value use default value.
2544         visible = 0;
2545     } else if (!arg->IsNumber()) {
2546         return;
2547     } else {
2548         visible = arg->ToNumber<int32_t>();
2549     }
2550 
2551     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2552         (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
2553         visible = 0;
2554     }
2555 
2556     if (info.Length() > 1 && info[1]->IsFunction()) {
2557         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2558         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2559         auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2560                                       int32_t visible) {
2561             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2562             ACE_SCORING_EVENT("onVisibilityChange");
2563             PipelineContext::SetCallBackNode(node);
2564             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2565             func->ExecuteJS(1, &newJSVal);
2566         };
2567         ViewAbstractModel::GetInstance()->SetVisibility(
2568             static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2569     } else {
2570         ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2571     }
2572 }
2573 
JsSetFreeze(const JSCallbackInfo & info)2574 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2575 {
2576     if (info[0]->IsBoolean()) {
2577         ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2578     }
2579 }
2580 
JsFlexBasis(const JSCallbackInfo & info)2581 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2582 {
2583     CalcDimension value;
2584     if (!ParseJsDimensionVp(info[0], value)) {
2585         value.SetUnit(DimensionUnit::AUTO);
2586     }
2587     // flexbasis don't support percent case.
2588     if (value.Unit() == DimensionUnit::PERCENT) {
2589         value.SetUnit(DimensionUnit::AUTO);
2590     }
2591     ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2592 }
2593 
JsFlexGrow(const JSCallbackInfo & info)2594 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2595 {
2596     double value = 0.0;
2597     if (!ParseJsDouble(info[0], value)) {
2598         if (info[0]->IsNull() || info[0]->IsUndefined()) {
2599             // undefined use default value.
2600             value = 0.0;
2601         } else {
2602             return;
2603         }
2604     }
2605     // negative use default value.
2606     if (value < 0.0) {
2607         value = 0.0;
2608     }
2609     ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2610 }
2611 
JsFlexShrink(const JSCallbackInfo & info)2612 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2613 {
2614     double value = 0.0;
2615     if (!ParseJsDouble(info[0], value)) {
2616         if (info[0]->IsNull() || info[0]->IsUndefined()) {
2617             // undefined use default value.
2618             ViewAbstractModel::GetInstance()->ResetFlexShrink();
2619             return;
2620         } else {
2621             return;
2622         }
2623     }
2624     // negative use default value.
2625     if (value < 0.0) {
2626         ViewAbstractModel::GetInstance()->ResetFlexShrink();
2627         return;
2628     }
2629     ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2630 }
2631 
JsDisplayPriority(const JSCallbackInfo & info)2632 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2633 {
2634     double value = 0.0;
2635     if (!ParseJsDouble(info[0], value)) {
2636         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2637             ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
2638         }
2639         return;
2640     }
2641     ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2642 }
2643 
JsSharedTransition(const JSCallbackInfo & info)2644 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2645 {
2646     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2647     auto jsVal = info[0];
2648     if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
2649         return;
2650     }
2651     // id
2652     auto id = jsVal->ToString();
2653     if (id.empty()) {
2654         return;
2655     }
2656     std::shared_ptr<SharedTransitionOption> sharedOption;
2657 
2658     // options
2659     if (info.Length() > 1 && info[1]->IsObject()) {
2660         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2661         sharedOption = std::make_shared<SharedTransitionOption>();
2662         // default: duration: 1000
2663         sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2664         if (sharedOption->duration < 0) {
2665             sharedOption->duration = DEFAULT_DURATION;
2666         }
2667         // default: delay: 0
2668         sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2669         if (sharedOption->delay < 0) {
2670             sharedOption->delay = 0;
2671         }
2672         // default: LinearCurve
2673         RefPtr<Curve> curve;
2674         JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2675         if (curveArgs->IsString()) {
2676             curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2677         } else if (curveArgs->IsObject()) {
2678             JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2679             if (!curveString->IsString()) {
2680                 return;
2681             }
2682             curve = CreateCurve(curveString->ToString(), false);
2683         }
2684         if (!curve) {
2685             curve = Curves::LINEAR;
2686         }
2687         sharedOption->curve = curve;
2688         // motionPath
2689         if (jsObj->HasProperty("motionPath")) {
2690             MotionPathOption motionPathOption;
2691             if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2692                 sharedOption->motionPathOption = motionPathOption;
2693             }
2694         }
2695         // zIndex
2696         sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2697         // type
2698         int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2699             static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2700         sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2701     }
2702     ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2703 }
2704 
JsGeometryTransition(const JSCallbackInfo & info)2705 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2706 {
2707     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2708     auto jsVal = info[0];
2709     if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
2710         return;
2711     }
2712     // id
2713     auto id = jsVal->ToString();
2714     // follow flag
2715     bool followWithOutTransition = false;
2716     // hierarchy flag
2717     bool doRegisterSharedTransition = true;
2718     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
2719         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2720         ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2721 
2722         auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
2723         ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
2724         switch (transitionHierarchyStrategy) {
2725             case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
2726                 doRegisterSharedTransition = false;
2727                 break;
2728             case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
2729                 doRegisterSharedTransition = true;
2730                 break;
2731             default:
2732                 break;
2733         }
2734     }
2735     ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
2736 }
2737 
JsAlignSelf(const JSCallbackInfo & info)2738 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2739 {
2740     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2741     auto jsVal = info[0];
2742     if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
2743         ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2744         return;
2745     }
2746     auto alignVal = jsVal->ToNumber<int32_t>();
2747 
2748     if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2749         ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2750     }
2751 }
2752 
JsBackgroundColor(const JSCallbackInfo & info)2753 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2754 {
2755     Color backgroundColor;
2756     if (!ParseJsColor(info[0], backgroundColor)) {
2757         backgroundColor = Color::TRANSPARENT;
2758     }
2759 
2760     ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2761 }
2762 
JsBackgroundImage(const JSCallbackInfo & info)2763 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2764 {
2765     int32_t resId = 0;
2766     std::string src;
2767     std::string bundle;
2768     std::string module;
2769     RefPtr<PixelMap> pixmap = nullptr;
2770     auto jsBackgroundImage = info[0];
2771     GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
2772     if (jsBackgroundImage->IsString()) {
2773         src = jsBackgroundImage->ToString();
2774         ViewAbstractModel::GetInstance()->SetBackgroundImage(
2775             ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2776     } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) {
2777         ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2778     } else {
2779 #if defined(PIXEL_MAP_SUPPORTED)
2780         if (IsDrawable(jsBackgroundImage)) {
2781             pixmap = GetDrawablePixmap(jsBackgroundImage);
2782         } else {
2783             pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
2784         }
2785 #endif
2786         ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2787     }
2788 
2789     int32_t repeatIndex = 0;
2790     if (info.Length() == 2) {
2791         auto jsImageRepeat = info[1];
2792         if (jsImageRepeat->IsNumber()) {
2793             repeatIndex = jsImageRepeat->ToNumber<int32_t>();
2794         }
2795     }
2796     auto repeat = static_cast<ImageRepeat>(repeatIndex);
2797     ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2798 }
2799 
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2800 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2801 {
2802     if (jsBlurOption->GetProperty("grayscale")->IsArray()) {
2803         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsBlurOption->GetProperty("grayscale"));
2804         auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2805         auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2806         std::vector<float> greyVec(2); // 2 number
2807         greyVec[0] = grey1;
2808         greyVec[1] = grey2;
2809         blurOption.grayscale = greyVec;
2810     }
2811 }
2812 
JsBackgroundBlurStyle(const JSCallbackInfo & info)2813 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2814 {
2815     if (info.Length() == 0) {
2816         return;
2817     }
2818     BlurStyleOption styleOption;
2819     if (info[0]->IsNumber()) {
2820         auto blurStyle = info[0]->ToNumber<int32_t>();
2821         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2822             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2823             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2824         }
2825     }
2826     if (info.Length() > 1 && info[1]->IsObject()) {
2827         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2828         auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2829         ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2830         if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2831             colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2832             styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2833         }
2834         auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2835         ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2836         if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2837             adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2838             styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2839         }
2840         if (jsOption->GetProperty("scale")->IsNumber()) {
2841             double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2842             styleOption.scale = std::clamp(scale, 0.0, 1.0);
2843         }
2844 
2845         if (jsOption->GetProperty("blurOptions")->IsObject()) {
2846             JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2847             BlurOption blurOption;
2848             ParseBlurOption(jsBlurOption, blurOption);
2849             styleOption.blurOption = blurOption;
2850         }
2851     }
2852     ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption);
2853 }
2854 
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2855 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
2856 {
2857     double rate = 1.0f;
2858     if (jsOption->GetProperty("rate")->IsNumber()) {
2859         rate = jsOption->GetProperty("rate")->ToNumber<double>();
2860     }
2861     double lightUpDegree = 0.0f;
2862     if (jsOption->GetProperty("lightUpDegree")->IsNumber()) {
2863         lightUpDegree = jsOption->GetProperty("lightUpDegree")->ToNumber<double>();
2864     }
2865     double cubicCoeff = 0.0f;
2866     if (jsOption->GetProperty("cubicCoeff")->IsNumber()) {
2867         cubicCoeff = jsOption->GetProperty("cubicCoeff")->ToNumber<double>();
2868     }
2869     double quadCoeff = 0.0f;
2870     if (jsOption->GetProperty("quadCoeff")->IsNumber()) {
2871         quadCoeff = jsOption->GetProperty("quadCoeff")->ToNumber<double>();
2872     }
2873     double saturation = 1.0f;
2874     if (jsOption->GetProperty("saturation")->IsNumber()) {
2875         saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2876     }
2877     std::vector<float> posRGB(3, 0.0);
2878     if (jsOption->GetProperty("posRGB")->IsArray()) {
2879         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("posRGB"));
2880         auto r = params->GetValueAt(0)->ToNumber<double>();
2881         auto g = params->GetValueAt(1)->ToNumber<double>();
2882         auto b = params->GetValueAt(2)->ToNumber<double>();
2883         posRGB[0] = r;
2884         posRGB[1] = g;
2885         posRGB[2] = b;
2886     }
2887     std::vector<float> negRGB(3, 0.0);
2888     if (jsOption->GetProperty("negRGB")->IsArray()) {
2889         JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("negRGB"));
2890         auto r = params->GetValueAt(0)->ToNumber<double>();
2891         auto g = params->GetValueAt(1)->ToNumber<double>();
2892         auto b = params->GetValueAt(2)->ToNumber<double>();
2893         negRGB[0] = r;
2894         negRGB[1] = g;
2895         negRGB[2] = b;
2896     }
2897     double fraction = 1.0f;
2898     if (jsOption->GetProperty("fraction")->IsNumber()) {
2899         fraction = jsOption->GetProperty("fraction")->ToNumber<double>();
2900         fraction = std::clamp(fraction, 0.0, 1.0);
2901     }
2902     brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
2903 }
2904 
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)2905 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
2906 {
2907     CalcDimension radius;
2908     if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
2909         radius.SetValue(0.0f);
2910     }
2911     double saturation = 1.0f;
2912     if (jsOption->GetProperty("saturation")->IsNumber()) {
2913         saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2914         saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
2915     }
2916     double brightness = 1.0f;
2917     if (jsOption->GetProperty("brightness")->IsNumber()) {
2918         brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
2919         brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
2920     }
2921     Color color = Color::TRANSPARENT;
2922     if (!ParseJsColor(jsOption->GetProperty("color"), color)) {
2923         color.SetValue(Color::TRANSPARENT.GetValue());
2924     }
2925     auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2926     auto adaptiveColor = AdaptiveColor::DEFAULT;
2927     ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
2928     if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2929         adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2930         adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
2931     }
2932 
2933     BlurOption blurOption;
2934     if (jsOption->GetProperty("blurOptions")->IsObject()) {
2935         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2936         ParseBlurOption(jsBlurOption, blurOption);
2937     }
2938     effectOption = { radius, saturation, brightness, color, adaptiveColor, blurOption };
2939 }
2940 
JsForegroundEffect(const JSCallbackInfo & info)2941 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
2942 {
2943     if (info.Length() == 0) {
2944         return;
2945     }
2946     float radius = 0.0;
2947     if (info[0]->IsObject()) {
2948         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2949         if (jsOption->GetProperty("radius")->IsNumber()) {
2950             radius = jsOption->GetProperty("radius")->ToNumber<float>();
2951         }
2952     }
2953     radius = std::max(radius, 0.0f);
2954     ViewAbstractModel::GetInstance()->SetForegroundEffect(radius);
2955 }
2956 
JsBackgroundEffect(const JSCallbackInfo & info)2957 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
2958 {
2959     if (info.Length() == 0) {
2960         return;
2961     }
2962     EffectOption option;
2963     if (info[0]->IsObject()) {
2964         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2965         ParseEffectOption(jsOption, option);
2966     }
2967     ViewAbstractModel::GetInstance()->SetBackgroundEffect(option);
2968 }
2969 
JsForegroundBlurStyle(const JSCallbackInfo & info)2970 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
2971 {
2972     if (info.Length() == 0) {
2973         return;
2974     }
2975     BlurStyleOption styleOption;
2976     if (info[0]->IsNumber()) {
2977         auto blurStyle = info[0]->ToNumber<int32_t>();
2978         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2979             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2980             styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2981         }
2982     }
2983     if (info.Length() > 1 && info[1]->IsObject()) {
2984         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2985         auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2986         ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2987         if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2988             colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2989             styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2990         }
2991         auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2992         ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2993         if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2994             adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2995             styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2996         }
2997         if (jsOption->GetProperty("scale")->IsNumber()) {
2998             double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2999             styleOption.scale = std::clamp(scale, 0.0, 1.0);
3000         }
3001 
3002         if (jsOption->GetProperty("blurOptions")->IsObject()) {
3003             JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3004             BlurOption blurOption;
3005             ParseBlurOption(jsBlurOption, blurOption);
3006             styleOption.blurOption = blurOption;
3007         }
3008     }
3009     ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption);
3010 }
3011 
JsSphericalEffect(const JSCallbackInfo & info)3012 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
3013 {
3014     auto radio = 0.0;
3015     if (info[0]->IsNumber()) {
3016         radio = info[0]->ToNumber<double>();
3017     }
3018     ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
3019 }
3020 
JsPixelStretchEffect(const JSCallbackInfo & info)3021 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
3022 {
3023     if (!info[0]->IsObject()) {
3024         PixStretchEffectOption option;
3025         option.ResetValue();
3026         ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3027         return;
3028     }
3029     auto jsObject = JSRef<JSObject>::Cast(info[0]);
3030     CalcDimension left;
3031     ParseJsDimensionVp(jsObject->GetProperty("left"), left);
3032     CalcDimension right;
3033     ParseJsDimensionVp(jsObject->GetProperty("right"), right);
3034     CalcDimension top;
3035     ParseJsDimensionVp(jsObject->GetProperty("top"), top);
3036     CalcDimension bottom;
3037     ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
3038 
3039     PixStretchEffectOption option;
3040     bool illegalInput = false;
3041     if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
3042         top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
3043         if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
3044             (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
3045             (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
3046             (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
3047             left.SetUnit(DimensionUnit::PERCENT);
3048             top.SetUnit(DimensionUnit::PERCENT);
3049             right.SetUnit(DimensionUnit::PERCENT);
3050             bottom.SetUnit(DimensionUnit::PERCENT);
3051         } else {
3052             illegalInput = true;
3053         }
3054     }
3055     if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
3056         (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
3057         option.left = left;
3058         option.top = top;
3059         option.right = right;
3060         option.bottom = bottom;
3061     } else {
3062         illegalInput = true;
3063     }
3064     if (illegalInput) {
3065         option.ResetValue();
3066     }
3067     ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3068 }
3069 
JsLightUpEffect(const JSCallbackInfo & info)3070 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
3071 {
3072     auto radio = 1.0;
3073     if (info[0]->IsNumber()) {
3074         radio = info[0]->ToNumber<double>();
3075     }
3076     ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
3077 }
3078 
JsBackgroundImageSize(const JSCallbackInfo & info)3079 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
3080 {
3081     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3082     BackgroundImageSize bgImgSize;
3083     auto jsVal = info[0];
3084     if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
3085         bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
3086         bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
3087         ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3088         return;
3089     }
3090     if (jsVal->IsNumber()) {
3091         auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
3092         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3093             (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
3094             sizeType = BackgroundImageSizeType::AUTO;
3095         }
3096         bgImgSize.SetSizeTypeX(sizeType);
3097         bgImgSize.SetSizeTypeY(sizeType);
3098     } else {
3099         CalcDimension width;
3100         CalcDimension height;
3101         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3102         ParseJsDimensionVp(object->GetProperty("width"), width);
3103         ParseJsDimensionVp(object->GetProperty("height"), height);
3104         double valueWidth = width.ConvertToPx();
3105         double valueHeight = height.ConvertToPx();
3106         BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
3107         BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
3108         if (width.Unit() == DimensionUnit::PERCENT) {
3109             typeWidth = BackgroundImageSizeType::PERCENT;
3110             valueWidth = width.Value() * FULL_DIMENSION;
3111         }
3112         if (height.Unit() == DimensionUnit::PERCENT) {
3113             typeHeight = BackgroundImageSizeType::PERCENT;
3114             valueHeight = height.Value() * FULL_DIMENSION;
3115         }
3116         bgImgSize.SetSizeTypeX(typeWidth);
3117         bgImgSize.SetSizeValueX(valueWidth);
3118         bgImgSize.SetSizeTypeY(typeHeight);
3119         bgImgSize.SetSizeValueY(valueHeight);
3120     }
3121 
3122     ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3123 }
3124 
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3125 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
3126 {
3127     if (align > 8 || align < 0) {
3128         return;
3129     }
3130     std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
3131         { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
3132         { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
3133     SetBgImgPosition(
3134                 DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
3135 }
3136 
JsBackgroundImagePosition(const JSCallbackInfo & info)3137 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
3138 {
3139     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3140     BackgroundImagePosition bgImgPosition;
3141     auto jsVal = info[0];
3142     if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
3143         SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
3144         ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3145         return;
3146     }
3147     if (jsVal->IsNumber()) {
3148         int32_t align = jsVal->ToNumber<int32_t>();
3149         bgImgPosition.SetIsAlign(true);
3150         SetBgImgPositionWithAlign(bgImgPosition, align);
3151     } else {
3152         CalcDimension x;
3153         CalcDimension y;
3154         JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3155         ParseJsDimensionVp(object->GetProperty("x"), x);
3156         ParseJsDimensionVp(object->GetProperty("y"), y);
3157         double valueX = x.Value();
3158         double valueY = y.Value();
3159         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3160             valueX = x.ConvertToPx();
3161             valueY = y.ConvertToPx();
3162         }
3163         DimensionUnit typeX = DimensionUnit::PX;
3164         DimensionUnit typeY = DimensionUnit::PX;
3165         if (x.Unit() == DimensionUnit::PERCENT) {
3166             valueX = x.Value();
3167             typeX = DimensionUnit::PERCENT;
3168         }
3169         if (y.Unit() == DimensionUnit::PERCENT) {
3170             valueY = y.Value();
3171             typeY = DimensionUnit::PERCENT;
3172         }
3173         SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
3174     }
3175 
3176     ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3177 }
3178 
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)3179 std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
3180 {
3181     JSRef<JSVal> arg = info[optionIndex];
3182     if (!arg->IsArray()) {
3183         return std::vector<NG::OptionParam>();
3184     }
3185     auto paramArray = JSRef<JSArray>::Cast(arg);
3186     auto paramArrayLength = paramArray->Length();
3187     std::vector<NG::OptionParam> params(paramArrayLength);
3188     // parse paramArray
3189     for (size_t i = 0; i < paramArrayLength; ++i) {
3190         if (!paramArray->GetValueAt(i)->IsObject()) {
3191             return std::vector<NG::OptionParam>();
3192         }
3193         auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
3194         JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
3195             params[i].value);
3196         auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
3197         if (!actionFunc->IsFunction()) {
3198             return params;
3199         }
3200         auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
3201         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3202         // set onClick function
3203         params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
3204             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
3205             ACE_SCORING_EVENT("menu.action");
3206             PipelineContext::SetCallBackNode(node);
3207             if (func) {
3208                 func->Execute();
3209             }
3210         };
3211         std::string iconPath;
3212         if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
3213             params[i].icon = iconPath;
3214         }
3215         if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
3216             std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
3217             JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
3218                 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
3219             params[i].symbol = symbolApply;
3220         }
3221         auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
3222         if (enabled->IsBoolean()) {
3223             params[i].enabled = enabled->ToBoolean();
3224         }
3225     }
3226     return params;
3227 }
3228 
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3229 void ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3230 {
3231     auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
3232     NG::BorderRadiusProperty menuBorderRadius;
3233     CalcDimension borderRadius;
3234     if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) {
3235         if (borderRadius.Unit() != DimensionUnit::PERCENT && GreatOrEqual(borderRadius.Value(), 0.0f)) {
3236             menuBorderRadius.SetRadius(borderRadius);
3237             menuBorderRadius.multiValued = false;
3238             menuParam.borderRadius = menuBorderRadius;
3239         };
3240     } else if (borderRadiusValue->IsObject()) {
3241         JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
3242         CalcDimension topLeft;
3243         CalcDimension topRight;
3244         CalcDimension bottomLeft;
3245         CalcDimension bottomRight;
3246         bool hasSetBorderRadius =
3247             JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
3248         if (LessNotEqual(topLeft.Value(), 0.0f)) {
3249             topLeft.Reset();
3250         }
3251         if (LessNotEqual(topRight.Value(), 0.0f)) {
3252             topRight.Reset();
3253         }
3254         if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
3255             bottomLeft.Reset();
3256         }
3257         if (LessNotEqual(bottomRight.Value(), 0.0f)) {
3258             bottomRight.Reset();
3259         }
3260         auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
3261         menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
3262         menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight;
3263         menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
3264         menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
3265         menuBorderRadius.multiValued = true;
3266         menuParam.borderRadius = menuBorderRadius;
3267     }
3268 }
3269 
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3270 void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3271 {
3272     auto enableArrowValue = menuOptions->GetProperty("enableArrow");
3273     if (enableArrowValue->IsBoolean()) {
3274         menuParam.enableArrow = enableArrowValue->ToBoolean();
3275     }
3276 
3277     auto arrowOffset = menuOptions->GetProperty("arrowOffset");
3278     CalcDimension offset;
3279     if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
3280         menuParam.arrowOffset = offset;
3281     }
3282 
3283     // if enableArrow is true and placement not set, set placement default value to top.
3284     if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
3285         menuParam.placement = Placement::TOP;
3286     }
3287 }
3288 
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)3289 void ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
3290 {
3291     CalcDimension dimension;
3292     if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
3293         return;
3294     }
3295 
3296     if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
3297         calcDimension = dimension;
3298     }
3299 }
3300 
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3301 void ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3302 {
3303     auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
3304     if (!marginVal->IsObject()) {
3305         return;
3306     }
3307 
3308     CommonCalcDimension commonCalcDimension;
3309     auto object = JSRef<JSObject>::Cast(marginVal);
3310     ParseLayoutRegionMargin(object->GetProperty(TOP_PROPERTY), commonCalcDimension.top);
3311     ParseLayoutRegionMargin(object->GetProperty(BOTTOM_PROPERTY), commonCalcDimension.bottom);
3312     ParseLayoutRegionMargin(object->GetProperty(LEFT_PROPERTY), commonCalcDimension.left);
3313     ParseLayoutRegionMargin(object->GetProperty(RIGHT_PROPERTY), commonCalcDimension.right);
3314 
3315     if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3316         commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3317         menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
3318             commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3319     }
3320 }
3321 
GetMenuShowInSubwindow(NG::MenuParam & menuParam)3322 void GetMenuShowInSubwindow(NG::MenuParam& menuParam)
3323 {
3324     menuParam.isShowInSubWindow = false;
3325     auto pipeline = PipelineBase::GetCurrentContext();
3326     CHECK_NULL_VOID(pipeline);
3327     auto theme = pipeline->GetTheme<SelectTheme>();
3328     CHECK_NULL_VOID(theme);
3329     menuParam.isShowInSubWindow = theme->GetExpandDisplay();
3330 }
3331 
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3332 void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3333 {
3334     auto offsetVal = menuOptions->GetProperty("offset");
3335     if (offsetVal->IsObject()) {
3336         auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
3337         JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
3338         JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
3339         CalcDimension dx;
3340         CalcDimension dy;
3341         if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
3342             menuParam.positionOffset.SetX(dx.ConvertToPx());
3343         }
3344         if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
3345             menuParam.positionOffset.SetY(dy.ConvertToPx());
3346         }
3347     }
3348 
3349     auto placementValue = menuOptions->GetProperty("placement");
3350     if (placementValue->IsNumber()) {
3351         auto placement = placementValue->ToNumber<int32_t>();
3352         if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
3353             menuParam.placement = PLACEMENT[placement];
3354         }
3355     }
3356 
3357     auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
3358     Color backgroundColor;
3359     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
3360         menuParam.backgroundColor = backgroundColor;
3361     }
3362 
3363     auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
3364     BlurStyleOption styleOption;
3365     if (backgroundBlurStyle->IsNumber()) {
3366         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
3367         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3368             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3369             menuParam.backgroundBlurStyle = blurStyle;
3370         }
3371     }
3372     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3373     auto onAppearValue = menuOptions->GetProperty("onAppear");
3374     if (onAppearValue->IsFunction()) {
3375         RefPtr<JsFunction> jsOnAppearFunc =
3376             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
3377         auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
3378             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3379             ACE_SCORING_EVENT("onAppear");
3380             PipelineContext::SetCallBackNode(node);
3381             func->Execute();
3382         };
3383         menuParam.onAppear = std::move(onAppear);
3384     }
3385 
3386     auto onDisappearValue = menuOptions->GetProperty("onDisappear");
3387     if (onDisappearValue->IsFunction()) {
3388         RefPtr<JsFunction> jsOnDisAppearFunc =
3389             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
3390         auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
3391                                node = frameNode]() {
3392             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3393             ACE_SCORING_EVENT("onDisappear");
3394             PipelineContext::SetCallBackNode(node);
3395             func->Execute();
3396         };
3397         menuParam.onDisappear = std::move(onDisappear);
3398     }
3399     auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
3400     if (aboutToAppearValue->IsFunction()) {
3401         RefPtr<JsFunction> jsAboutToAppearFunc =
3402             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
3403         auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
3404                             node = frameNode]() {
3405             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3406             ACE_SCORING_EVENT("aboutToAppear");
3407             PipelineContext::SetCallBackNode(node);
3408             func->Execute();
3409         };
3410         menuParam.aboutToAppear = std::move(aboutToAppear);
3411     }
3412 
3413     auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
3414     if (aboutToDisAppearValue->IsFunction()) {
3415         RefPtr<JsFunction> jsAboutToDisAppearFunc =
3416             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
3417         auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
3418                                node = frameNode]() {
3419             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3420             ACE_SCORING_EVENT("aboutToDisappear");
3421             PipelineContext::SetCallBackNode(node);
3422             func->Execute();
3423         };
3424         menuParam.aboutToDisappear = std::move(aboutToDisappear);
3425     }
3426 
3427     auto menuTransition = menuOptions->GetProperty("transition");
3428     menuParam.hasTransitionEffect = false;
3429     if (menuTransition->IsObject()) {
3430         auto obj = JSRef<JSObject>::Cast(menuTransition);
3431         menuParam.hasTransitionEffect = true;
3432         menuParam.transition = ParseChainedTransition(obj, info.GetExecutionContext());
3433     }
3434 
3435     JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
3436     GetMenuShowInSubwindow(menuParam);
3437     if (menuParam.isShowInSubWindow) {
3438         if (showInSubWindowValue->IsBoolean()) {
3439             menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
3440         }
3441     }
3442     ParseMenuArrowParam(menuOptions, menuParam);
3443     ParseMenuBorderRadius(menuOptions, menuParam);
3444     ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
3445 }
3446 
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)3447 void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
3448 {
3449     if (!info[optionIndex]->IsObject()) {
3450         return;
3451     }
3452     auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
3453     JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
3454     ParseMenuParam(info, menuOptions, menuParam);
3455 }
3456 
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)3457 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
3458 {
3459     constexpr int scaleArraySize = 2;
3460     if (scaleArray->Length() == scaleArraySize) {
3461         auto scalePropertyFrom = scaleArray->GetValueAt(0);
3462         if (scalePropertyFrom->IsNumber()) {
3463             auto scaleFrom = scalePropertyFrom->ToNumber<float>();
3464             options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
3465         }
3466         auto scalePropertyTo = scaleArray->GetValueAt(1);
3467         if (scalePropertyTo->IsNumber()) {
3468             auto scaleTo = scalePropertyTo->ToNumber<float>();
3469             options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
3470         }
3471     }
3472 }
3473 
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)3474 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
3475     NG::MenuParam& menuParam)
3476 {
3477     menuParam.previewAnimationOptions.scaleFrom = -1.0f;
3478     menuParam.previewAnimationOptions.scaleTo = -1.0f;
3479 
3480     auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
3481     if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
3482         auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
3483         auto scaleProperty = animationOptionsObj->GetProperty("scale");
3484         if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
3485             JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
3486             ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
3487         }
3488         auto previewTransition = animationOptionsObj->GetProperty("transition");
3489         menuParam.hasPreviewTransitionEffect = false;
3490         if (previewTransition->IsObject()) {
3491             auto obj = JSRef<JSObject>::Cast(previewTransition);
3492             menuParam.hasPreviewTransitionEffect = true;
3493             menuParam.previewTransition = ParseChainedTransition(obj, info.GetExecutionContext());
3494         }
3495         if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
3496             menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect ||
3497             menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
3498             return;
3499         }
3500         auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
3501         menuParam.isShowHoverImage = false;
3502         menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
3503         menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
3504         if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
3505             JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
3506             ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
3507             menuParam.isShowHoverImage = true;
3508         }
3509     }
3510 }
3511 
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)3512 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
3513     std::function<void()>& previewBuildFunc)
3514 {
3515     if (!args->IsObject()) {
3516         return;
3517     }
3518     auto menuContentOptions = JSRef<JSObject>::Cast(args);
3519     ParseMenuParam(info, menuContentOptions, menuParam);
3520     RefPtr<JsFunction> previewBuilderFunc;
3521     auto preview = menuContentOptions->GetProperty("preview");
3522     if (!preview->IsFunction() && !preview->IsNumber()) {
3523         return;
3524     }
3525 
3526     if (preview->IsNumber()) {
3527         if (preview->ToNumber<int32_t>() == 1) {
3528             menuParam.previewMode = MenuPreviewMode::IMAGE;
3529             ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3530         }
3531     } else {
3532         previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
3533         CHECK_NULL_VOID(previewBuilderFunc);
3534         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3535         previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
3536                                node = frameNode]() {
3537             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3538             ACE_SCORING_EVENT("BuildContextMenuPreviwer");
3539             PipelineContext::SetCallBackNode(node);
3540             func->Execute();
3541         };
3542         menuParam.previewMode = MenuPreviewMode::CUSTOM;
3543         ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3544     }
3545 }
3546 
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)3547 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
3548 {
3549     size_t builderIndex = 0;
3550     if (info[0]->IsBoolean()) {
3551         menuParam.isShow = info[0]->ToBoolean();
3552         menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3553         menuParam.placement = Placement::BOTTOM_LEFT;
3554         builderIndex = 1;
3555     } else if (info[0]->IsObject()) {
3556         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
3557         menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3558         auto isShowObj = callbackObj->GetProperty("value");
3559         if (isShowObj->IsBoolean()) {
3560             menuParam.isShow = isShowObj->IsBoolean();
3561             menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3562             builderIndex = 1;
3563         }
3564     }
3565     return builderIndex;
3566 }
3567 
JsBindMenu(const JSCallbackInfo & info)3568 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
3569 {
3570     NG::MenuParam menuParam;
3571     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
3572         menuParam.placement = Placement::BOTTOM_LEFT;
3573     }
3574     size_t builderIndex = 0;
3575     GetMenuShowInSubwindow(menuParam);
3576     if (info.Length() > PARAMETER_LENGTH_FIRST) {
3577         auto jsVal = info[0];
3578         if (jsVal->IsBoolean()) {
3579             menuParam.isShow = jsVal->ToBoolean();
3580             menuParam.setShow = true;
3581             builderIndex = 1;
3582             if (info.Length() > PARAMETER_LENGTH_SECOND) {
3583                 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3584             }
3585         } else if (jsVal->IsUndefined()) {
3586             menuParam.setShow = true;
3587             menuParam.isShow = false;
3588             builderIndex = 1;
3589             if (info.Length() > PARAMETER_LENGTH_SECOND) {
3590                 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3591             }
3592         } else if (jsVal->IsObject()) {
3593             JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
3594             menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3595             auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
3596             if (isShowObj->IsBoolean()) {
3597                 menuParam.isShow = isShowObj->ToBoolean();
3598                 menuParam.setShow = true;
3599                 builderIndex = 1;
3600                 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3601                     ParseBindOptionParam(info, menuParam, builderIndex + 1);
3602                 }
3603             } else {
3604                 builderIndex = 0;
3605                 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3606             }
3607         }
3608     }
3609 
3610     if (info[builderIndex]->IsArray()) {
3611         std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info, builderIndex);
3612         ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
3613     } else if (info[builderIndex]->IsObject()) {
3614         // CustomBuilder
3615         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
3616         auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
3617         if (!builder->IsFunction()) {
3618             return;
3619         }
3620         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
3621 
3622         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3623         CHECK_NULL_VOID(builderFunc);
3624         auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
3625             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3626             ACE_SCORING_EVENT("BuildMenu");
3627             auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3628             func->Execute();
3629         };
3630         ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
3631     }
3632 }
3633 
JsPadding(const JSCallbackInfo & info)3634 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
3635 {
3636     ParseMarginOrPadding(info, false);
3637 }
3638 
JsMargin(const JSCallbackInfo & info)3639 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
3640 {
3641     ParseMarginOrPadding(info, true);
3642 }
3643 
ParseMarginOrPadding(const JSCallbackInfo & info,bool isMargin)3644 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, bool isMargin)
3645 {
3646     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3647         JSCallbackInfoType::NUMBER };
3648     auto jsVal = info[0];
3649     if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
3650         auto resetDimension = CalcDimension(0.0);
3651         if (isMargin) {
3652             ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
3653         } else {
3654             ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
3655         }
3656         return;
3657     }
3658     if (jsVal->IsObject()) {
3659         CommonCalcDimension commonCalcDimension;
3660         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
3661         auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
3662         if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3663             commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3664             if (isMargin) {
3665                 if (useLengthMetrics) {
3666                     ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
3667                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3668                 } else {
3669                     ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
3670                         commonCalcDimension.left, commonCalcDimension.right);
3671                 }
3672             } else {
3673                 if (useLengthMetrics) {
3674                     ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
3675                         commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3676                 } else {
3677                     ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
3678                         commonCalcDimension.left, commonCalcDimension.right);
3679                 }
3680             }
3681             return;
3682         }
3683     }
3684 
3685     CalcDimension length;
3686     if (!ParseJsDimensionVp(jsVal, length)) {
3687         // use default value.
3688         length.Reset();
3689     }
3690     if (isMargin) {
3691         ViewAbstractModel::GetInstance()->SetMargin(length);
3692     } else {
3693         ViewAbstractModel::GetInstance()->SetPadding(length);
3694     }
3695 }
3696 
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)3697 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
3698     const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
3699     const std::optional<CalcDimension>& end)
3700 {
3701     NG::PaddingProperty paddings;
3702     if (start.has_value()) {
3703         if (start.value().Unit() == DimensionUnit::CALC) {
3704             paddings.start = NG::CalcLength(start.value().CalcValue());
3705         } else {
3706             paddings.start = NG::CalcLength(start.value());
3707         }
3708     }
3709     if (bottom.has_value()) {
3710         if (bottom.value().Unit() == DimensionUnit::CALC) {
3711             paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
3712         } else {
3713             paddings.bottom = NG::CalcLength(bottom.value());
3714         }
3715     }
3716     if (end.has_value()) {
3717         if (end.value().Unit() == DimensionUnit::CALC) {
3718             paddings.end = NG::CalcLength(end.value().CalcValue());
3719         } else {
3720             paddings.end = NG::CalcLength(end.value());
3721         }
3722     }
3723     if (top.has_value()) {
3724         if (top.value().Unit() == DimensionUnit::CALC) {
3725             paddings.top = NG::CalcLength(top.value().CalcValue());
3726         } else {
3727             paddings.top = NG::CalcLength(top.value());
3728         }
3729     }
3730     return paddings;
3731 }
3732 
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)3733 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
3734     std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
3735 {
3736     CalcDimension leftDimen;
3737     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
3738         left = leftDimen;
3739     }
3740     CalcDimension rightDimen;
3741     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
3742         right = rightDimen;
3743     }
3744     CalcDimension topDimen;
3745     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
3746         top = topDimen;
3747     }
3748     CalcDimension bottomDimen;
3749     if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
3750         bottom = bottomDimen;
3751     }
3752 }
3753 
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3754 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
3755     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3756 {
3757     auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
3758     if (jsStart->IsObject()) {
3759         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
3760         CalcDimension calcDimension;
3761         if (ParseJsLengthMetrics(startObj, calcDimension)) {
3762             localizedCalcDimension.start = calcDimension;
3763         }
3764     }
3765     auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
3766     if (jsEnd->IsObject()) {
3767         JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
3768         CalcDimension calcDimension;
3769         if (ParseJsLengthMetrics(endObj, calcDimension)) {
3770             localizedCalcDimension.end = calcDimension;
3771         }
3772     }
3773     auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3774     if (jsTop->IsObject()) {
3775         JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
3776         CalcDimension calcDimension;
3777         if (ParseJsLengthMetrics(topObj, calcDimension)) {
3778             localizedCalcDimension.top = calcDimension;
3779         }
3780     }
3781     auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3782     if (jsBottom->IsObject()) {
3783         JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
3784         CalcDimension calcDimension;
3785         if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
3786             localizedCalcDimension.bottom = calcDimension;
3787         }
3788     }
3789 }
3790 
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3791 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
3792     const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
3793 {
3794     if (CheckLengthMetrics(object)) {
3795         LocalizedCalcDimension localizedCalcDimension;
3796         ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
3797         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
3798         commonCalcDimension.top = localizedCalcDimension.top;
3799         commonCalcDimension.bottom = localizedCalcDimension.bottom;
3800         commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
3801         commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
3802         return true;
3803     }
3804     ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
3805         commonCalcDimension.right);
3806     return false;
3807 }
3808 
JsOutline(const JSCallbackInfo & info)3809 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
3810 {
3811     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3812     auto jsVal = info[0];
3813     if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
3814         CalcDimension borderWidth;
3815         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3816         ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3817         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
3818         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3819         return;
3820     }
3821     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3822     auto valueOuterWidth = object->GetProperty("width");
3823     if (!valueOuterWidth->IsUndefined()) {
3824         ParseOuterBorderWidth(valueOuterWidth);
3825     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3826         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3827     }
3828 
3829     // use default value when undefined.
3830     ParseOuterBorderColor(object->GetProperty("color"));
3831 
3832     auto valueOuterRadius = object->GetProperty("radius");
3833     if (!valueOuterRadius->IsUndefined()) {
3834         ParseOuterBorderRadius(valueOuterRadius);
3835     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3836         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3837     }
3838     // use default value when undefined.
3839     ParseOuterBorderStyle(object->GetProperty("style"));
3840     info.ReturnSelf();
3841 }
3842 
JsOutlineWidth(const JSCallbackInfo & info)3843 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
3844 {
3845     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3846         JSCallbackInfoType::OBJECT };
3847     auto jsVal = info[0];
3848     if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
3849         ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3850         return;
3851     }
3852     ParseOuterBorderWidth(jsVal);
3853 }
3854 
JsOutlineColor(const JSCallbackInfo & info)3855 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
3856 {
3857     ParseOuterBorderColor(info[0]);
3858 }
3859 
JsOutlineRadius(const JSCallbackInfo & info)3860 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
3861 {
3862     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3863         JSCallbackInfoType::OBJECT };
3864     auto jsVal = info[0];
3865     if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
3866         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3867         return;
3868     }
3869     ParseOuterBorderRadius(jsVal);
3870 }
3871 
JsOutlineStyle(const JSCallbackInfo & info)3872 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
3873 {
3874     ParseOuterBorderStyle(info[0]);
3875 }
3876 
JsBorder(const JSCallbackInfo & info)3877 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
3878 {
3879     if (!info[0]->IsObject()) {
3880         CalcDimension borderWidth;
3881         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3882         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3883         ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
3884         ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3885         ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
3886         ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
3887         return;
3888     }
3889     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
3890 
3891     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
3892     if (!valueWidth->IsUndefined()) {
3893         ParseBorderWidth(valueWidth);
3894     }
3895 
3896     // use default value when undefined.
3897     ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
3898 
3899     auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
3900     if (!valueRadius->IsUndefined()) {
3901         ParseBorderRadius(valueRadius);
3902     }
3903     // use default value when undefined.
3904     ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
3905 
3906     auto dashGap = object->GetProperty("dashGap");
3907     if (!dashGap->IsUndefined()) {
3908         ParseDashGap(dashGap);
3909     }
3910     auto dashWidth = object->GetProperty("dashWidth");
3911     if (!dashWidth->IsUndefined()) {
3912         ParseDashWidth(dashWidth);
3913     }
3914 
3915     info.ReturnSelf();
3916 }
3917 
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)3918 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
3919 {
3920     if (!args->IsObject()) {
3921         return false;
3922     }
3923     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3924     if (obj->IsUndefined()) {
3925         return true;
3926     }
3927     // filter dynamic $r raw input
3928     if (obj->HasProperty("id")) {
3929         return false;
3930     }
3931     if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
3932         (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
3933         (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
3934         (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
3935         (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
3936         (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
3937         return true;
3938     }
3939 
3940     return false;
3941 }
3942 
JsBorderWidth(const JSCallbackInfo & info)3943 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
3944 {
3945     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3946         JSCallbackInfoType::OBJECT };
3947     auto jsVal = info[0];
3948     if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
3949         ViewAbstractModel::GetInstance()->SetBorderWidth({});
3950         return;
3951     }
3952     ParseBorderWidth(jsVal);
3953 }
3954 
ParseBorderWidth(const JSRef<JSVal> & args)3955 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
3956 {
3957     CalcDimension borderWidth;
3958     if (ParseJsDimensionVp(args, borderWidth)) {
3959         if (borderWidth.IsNegative()) {
3960             borderWidth.Reset();
3961         }
3962         if (borderWidth.Unit() == DimensionUnit::PERCENT) {
3963             borderWidth.Reset();
3964         }
3965         ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3966     } else if (args->IsObject()) {
3967         if (IsBorderWidthObjUndefined(args)) {
3968             ViewAbstractModel::GetInstance()->SetBorderWidth({});
3969             return;
3970         }
3971         CommonCalcDimension commonCalcDimension;
3972         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3973         if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
3974             ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
3975                 commonCalcDimension.top, commonCalcDimension.bottom, true);
3976             return;
3977         }
3978         ViewAbstractModel::GetInstance()->SetBorderWidth(
3979             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3980     } else {
3981         return;
3982     }
3983 }
3984 
ParseDashGap(const JSRef<JSVal> & args)3985 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
3986 {
3987     CalcDimension dashGap;
3988     if (ParseLengthMetricsToDimension(args, dashGap)) {
3989         if (dashGap.Unit() == DimensionUnit::PERCENT) {
3990             dashGap.Reset();
3991         }
3992         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
3993     } else if (args->IsObject()) {
3994         CommonCalcDimension commonCalcDimension;
3995         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3996         ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
3997         ViewAbstractModel::GetInstance()->SetDashGap(
3998             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3999     } else {
4000         dashGap.Reset();
4001         ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4002     }
4003 }
4004 
ParseDashWidth(const JSRef<JSVal> & args)4005 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
4006 {
4007     CalcDimension dashWidth;
4008     if (ParseLengthMetricsToDimension(args, dashWidth)) {
4009         if (dashWidth.Unit() == DimensionUnit::PERCENT) {
4010             dashWidth.Reset();
4011         }
4012         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4013     } else if (args->IsObject()) {
4014         CommonCalcDimension commonCalcDimension;
4015         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4016         ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4017         ViewAbstractModel::GetInstance()->SetDashWidth(
4018             commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4019     } else {
4020         dashWidth.Reset();
4021         ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4022     }
4023 }
4024 
ParseOuterBorderWidth(const JSRef<JSVal> & args)4025 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
4026 {
4027     CalcDimension borderWidth;
4028     if (ParseJsDimensionVp(args, borderWidth)) {
4029         if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4030             borderWidth.Reset();
4031         }
4032         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4033     } else if (args->IsObject()) {
4034         std::optional<CalcDimension> leftDimen;
4035         std::optional<CalcDimension> rightDimen;
4036         std::optional<CalcDimension> topDimen;
4037         std::optional<CalcDimension> bottomDimen;
4038         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4039         CalcDimension left;
4040         if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
4041             if (left.Unit() == DimensionUnit::PERCENT) {
4042                 left.Reset();
4043             }
4044             leftDimen = left;
4045         }
4046         CalcDimension right;
4047         if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
4048             if (right.Unit() == DimensionUnit::PERCENT) {
4049                 right.Reset();
4050             }
4051             rightDimen = right;
4052         }
4053         CalcDimension top;
4054         if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
4055             if (top.Unit() == DimensionUnit::PERCENT) {
4056                 top.Reset();
4057             }
4058             topDimen = top;
4059         }
4060         CalcDimension bottom;
4061         if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
4062             if (bottom.Unit() == DimensionUnit::PERCENT) {
4063                 bottom.Reset();
4064             }
4065             bottomDimen = bottom;
4066         }
4067         ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
4068     } else {
4069         return;
4070     }
4071 }
4072 
JsBorderImage(const JSCallbackInfo & info)4073 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
4074 {
4075     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4076     auto jsVal = info[0];
4077     if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
4078         RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4079         uint8_t imageBorderBitsets = 0;
4080         ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4081         return;
4082     }
4083     JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4084     CHECK_NULL_VOID(!object->IsEmpty());
4085 
4086     RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4087     uint8_t imageBorderBitsets = 0;
4088 
4089     auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
4090     CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
4091     std::string srcResult;
4092     std::string bundleName;
4093     std::string moduleName;
4094     GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
4095     borderImage->SetBundleName(bundleName);
4096     borderImage->SetModuleName(moduleName);
4097     if (valueSource->IsString() && !valueSource->ToString().empty()) {
4098         borderImage->SetSrc(valueSource->ToString());
4099         imageBorderBitsets |= BorderImage::SOURCE_BIT;
4100     } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
4101         borderImage->SetSrc(srcResult);
4102         imageBorderBitsets |= BorderImage::SOURCE_BIT;
4103     } else if (valueSource->IsObject()) {
4104         ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
4105     }
4106     auto valueOutset = object->GetProperty("outset");
4107     if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
4108         imageBorderBitsets |= BorderImage::OUTSET_BIT;
4109         ParseBorderImageOutset(valueOutset, borderImage);
4110     }
4111     auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
4112     if (!valueRepeat->IsNull()) {
4113         imageBorderBitsets |= BorderImage::REPEAT_BIT;
4114         ParseBorderImageRepeat(valueRepeat, borderImage);
4115     }
4116     auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
4117     if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
4118         imageBorderBitsets |= BorderImage::SLICE_BIT;
4119         ParseBorderImageSlice(valueSlice, borderImage);
4120     }
4121     auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4122     if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
4123         imageBorderBitsets |= BorderImage::WIDTH_BIT;
4124         ParseBorderImageWidth(valueWidth, borderImage);
4125     }
4126     auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
4127     if (needFill->IsBoolean()) {
4128         borderImage->SetNeedFillCenter(needFill->ToBoolean());
4129     }
4130     ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4131     info.ReturnSelf();
4132 }
4133 
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4134 bool JSViewAbstract::ParseBorderImageDimension(
4135     const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
4136 {
4137     if (!args->IsObject()) {
4138         return false;
4139     }
4140     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4141     if (CheckLengthMetrics(object)) {
4142         LocalizedCalcDimension localizedCalcDimension;
4143         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4144         borderImageDimension.topDimension = localizedCalcDimension.top;
4145         borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
4146         borderImageDimension.startDimension = localizedCalcDimension.start;
4147         borderImageDimension.endDimension = localizedCalcDimension.end;
4148         return true;
4149     }
4150     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4151         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4152         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4153     for (uint32_t i = 0; i < keys.size(); i++) {
4154         CalcDimension currentDimension;
4155         auto dimensionValue = object->GetProperty(keys.at(i));
4156         if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
4157             auto direction = static_cast<BorderImageDirection>(i);
4158             switch (direction) {
4159                 case BorderImageDirection::LEFT:
4160                     borderImageDimension.leftDimension = currentDimension;
4161                     break;
4162                 case BorderImageDirection::RIGHT:
4163                     borderImageDimension.rightDimension = currentDimension;
4164                     break;
4165                 case BorderImageDirection::TOP:
4166                     borderImageDimension.topDimension = currentDimension;
4167                     break;
4168                 case BorderImageDirection::BOTTOM:
4169                     borderImageDimension.bottomDimension = currentDimension;
4170                     break;
4171                 default:
4172                     break;
4173             }
4174         }
4175     }
4176     return false;
4177 }
4178 
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4179 void JSViewAbstract::ParseBorderImageLengthMetrics(
4180     const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4181 {
4182     for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
4183         auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
4184         if (!jsVal->IsObject()) {
4185             continue;
4186         }
4187         JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
4188         CalcDimension calcDimension;
4189         if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
4190             auto direction = static_cast<BorderImageDirection>(i);
4191             switch (direction) {
4192                 case BorderImageDirection::LEFT:
4193                     localizedCalcDimension.start = calcDimension;
4194                     break;
4195                 case BorderImageDirection::RIGHT:
4196                     localizedCalcDimension.end = calcDimension;
4197                     break;
4198                 case BorderImageDirection::TOP:
4199                     localizedCalcDimension.top = calcDimension;
4200                     break;
4201                 case BorderImageDirection::BOTTOM:
4202                     localizedCalcDimension.bottom = calcDimension;
4203                     break;
4204                 default:
4205                     break;
4206             }
4207         }
4208     }
4209 }
4210 
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4211 bool JSViewAbstract::CheckJSCallbackInfo(
4212     const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
4213 {
4214     bool typeVerified = false;
4215     std::string unrecognizedType;
4216     for (const auto& infoType : infoTypes) {
4217         switch (infoType) {
4218             case JSCallbackInfoType::STRING:
4219                 if (tmpInfo->IsString()) {
4220                     typeVerified = true;
4221                 } else {
4222                     unrecognizedType += "string|";
4223                 }
4224                 break;
4225             case JSCallbackInfoType::NUMBER:
4226                 if (tmpInfo->IsNumber()) {
4227                     typeVerified = true;
4228                 } else {
4229                     unrecognizedType += "number|";
4230                 }
4231                 break;
4232             case JSCallbackInfoType::OBJECT:
4233                 if (tmpInfo->IsObject()) {
4234                     typeVerified = true;
4235                 } else {
4236                     unrecognizedType += "object|";
4237                 }
4238                 break;
4239             case JSCallbackInfoType::FUNCTION:
4240                 if (tmpInfo->IsFunction()) {
4241                     typeVerified = true;
4242                 } else {
4243                     unrecognizedType += "Function|";
4244                 }
4245                 break;
4246             default:
4247                 break;
4248         }
4249     }
4250     if (!typeVerified) {
4251         LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
4252             unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
4253     }
4254     return typeVerified || infoTypes.size() == 0;
4255 }
4256 
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4257 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
4258 {
4259     switch (direction) {
4260         case NG::GradientDirection::LEFT:
4261             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4262             break;
4263         case NG::GradientDirection::RIGHT:
4264             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4265             break;
4266         case NG::GradientDirection::TOP:
4267             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4268             break;
4269         case NG::GradientDirection::BOTTOM:
4270             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4271             break;
4272         case NG::GradientDirection::LEFT_TOP:
4273             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4274             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4275             break;
4276         case NG::GradientDirection::LEFT_BOTTOM:
4277             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4278             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4279             break;
4280         case NG::GradientDirection::RIGHT_TOP:
4281             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4282             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4283             break;
4284         case NG::GradientDirection::RIGHT_BOTTOM:
4285             lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4286             lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4287             break;
4288         case NG::GradientDirection::NONE:
4289         case NG::GradientDirection::START_TO_END:
4290         case NG::GradientDirection::END_TO_START:
4291         default:
4292             break;
4293     }
4294 }
4295 
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)4296 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
4297 {
4298     if (!args->IsObject()) {
4299         return;
4300     }
4301     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
4302     NG::Gradient lineGradient;
4303     lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
4304     // angle
4305     std::optional<float> degree;
4306     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4307         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
4308     } else {
4309         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
4310     }
4311     if (degree) {
4312         lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
4313         degree.reset();
4314     }
4315     // direction
4316     auto direction = static_cast<NG::GradientDirection>(
4317         jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
4318         static_cast<int32_t>(NG::GradientDirection::NONE)));
4319     UpdateGradientWithDirection(lineGradient, direction);
4320     auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
4321     lineGradient.SetRepeat(repeating);
4322     NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
4323     ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
4324     bitset |= BorderImage::GRADIENT_BIT;
4325 }
4326 
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4327 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4328 {
4329     auto repeatString = args->ToString();
4330     if (repeatString == "Repeat") {
4331         borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
4332     } else if (repeatString == "Round") {
4333         borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
4334     } else if (repeatString == "Space") {
4335         borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
4336     } else {
4337         borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
4338     }
4339 }
4340 
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4341 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4342 {
4343     CalcDimension outsetDimension;
4344     if (ParseJsDimensionVp(args, outsetDimension)) {
4345         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
4346         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
4347         borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
4348         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
4349         return;
4350     }
4351     BorderImage::BorderImageOption option;
4352     ParseBorderImageDimension(args, option);
4353     if (option.startDimension.has_value()) {
4354         borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
4355     }
4356     if (option.endDimension.has_value()) {
4357         borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
4358     }
4359     if (option.leftDimension.has_value()) {
4360         borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
4361     }
4362     if (option.rightDimension.has_value()) {
4363         borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
4364     }
4365     if (option.topDimension.has_value()) {
4366         borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
4367     }
4368     if (option.bottomDimension.has_value()) {
4369         borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4370     }
4371 }
4372 
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4373 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4374 {
4375     CalcDimension sliceDimension;
4376     if (ParseJsDimensionVp(args, sliceDimension)) {
4377         borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
4378         borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
4379         borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
4380         borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
4381         return;
4382     }
4383     if (!args->IsObject()) {
4384         return;
4385     }
4386     JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4387     if (CheckLengthMetrics(object)) {
4388         LocalizedCalcDimension localizedCalcDimension;
4389         ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4390         if (localizedCalcDimension.top.has_value()) {
4391             borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
4392         }
4393         if (localizedCalcDimension.bottom.has_value()) {
4394             borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
4395         }
4396         if (localizedCalcDimension.start.has_value()) {
4397             borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
4398         }
4399         if (localizedCalcDimension.end.has_value()) {
4400             borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
4401         }
4402         return;
4403     }
4404     static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4405         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4406         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4407     for (uint32_t i = 0; i < keys.size(); i++) {
4408         auto dimensionValue = object->GetProperty(keys.at(i));
4409         if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
4410             borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
4411         }
4412     }
4413 }
4414 
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4415 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4416 {
4417     CalcDimension widthDimension;
4418     if (ParseJsDimensionVp(args, widthDimension)) {
4419         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
4420         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
4421         borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
4422         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
4423         return;
4424     }
4425 
4426     BorderImage::BorderImageOption option;
4427     ParseBorderImageDimension(args, option);
4428     if (option.startDimension.has_value()) {
4429         borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
4430     }
4431     if (option.endDimension.has_value()) {
4432         borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
4433     }
4434     if (option.leftDimension.has_value()) {
4435         borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
4436     }
4437     if (option.rightDimension.has_value()) {
4438         borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
4439     }
4440     if (option.topDimension.has_value()) {
4441         borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
4442     }
4443     if (option.bottomDimension.has_value()) {
4444         borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4445     }
4446 }
4447 
JsBorderColor(const JSCallbackInfo & info)4448 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
4449 {
4450     ParseBorderColor(info[0]);
4451 }
4452 
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)4453 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
4454     const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
4455     const std::optional<Color>& colorBottom)
4456 {
4457     NG::BorderColorProperty borderColors;
4458     borderColors.startColor = colorStart;
4459     borderColors.endColor = colorEnd;
4460     borderColors.topColor = colorTop;
4461     borderColors.bottomColor = colorBottom;
4462     borderColors.multiValued = true;
4463     return borderColors;
4464 }
4465 
ParseBorderColor(const JSRef<JSVal> & args)4466 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
4467 {
4468     Color borderColor;
4469     if (ParseJsColor(args, borderColor)) {
4470         ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
4471     } else if (args->IsObject()) {
4472         CommonColor commonColor;
4473         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4474         if (ParseCommonEdgeColors(object, commonColor)) {
4475             ViewAbstractModel::GetInstance()->SetBorderColor(
4476                 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4477             return;
4478         }
4479         ViewAbstractModel::GetInstance()->SetBorderColor(
4480             commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4481     } else {
4482         ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4483     }
4484 }
4485 
ParseOuterBorderColor(const JSRef<JSVal> & args)4486 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
4487 {
4488     Color borderColor;
4489     if (ParseJsColor(args, borderColor)) {
4490         ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
4491     } else if (args->IsObject()) {
4492         CommonColor commonColor;
4493         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4494         if (ParseCommonEdgeColors(object, commonColor)) {
4495             ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4496                 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4497             return;
4498         }
4499         ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4500             commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4501     } else {
4502         ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
4503     }
4504 }
4505 
JsBorderRadius(const JSCallbackInfo & info)4506 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
4507 {
4508     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4509         JSCallbackInfoType::OBJECT };
4510     auto jsVal = info[0];
4511     if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
4512         ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
4513         return;
4514     }
4515     ParseBorderRadius(jsVal);
4516 }
4517 
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)4518 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
4519     const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
4520     const std::optional<Dimension>& radiusBottomEnd)
4521 {
4522     NG::BorderRadiusProperty borderRadius;
4523     borderRadius.radiusTopStart = radiusTopStart;
4524     borderRadius.radiusTopEnd = radiusTopEnd;
4525     borderRadius.radiusBottomStart = radiusBottomStart;
4526     borderRadius.radiusBottomEnd = radiusBottomEnd;
4527     borderRadius.multiValued = true;
4528     return borderRadius;
4529 }
4530 
ParseBorderRadius(const JSRef<JSVal> & args)4531 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
4532 {
4533     CalcDimension borderRadius;
4534     if (ParseJsDimensionVp(args, borderRadius)) {
4535         ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
4536     } else if (args->IsObject()) {
4537         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4538         CalcDimension topLeft;
4539         CalcDimension topRight;
4540         CalcDimension bottomLeft;
4541         CalcDimension bottomRight;
4542         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4543             ViewAbstractModel::GetInstance()->SetBorderRadius(
4544                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4545                 return;
4546         }
4547         ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4548     }
4549 }
4550 
ParseOuterBorderRadius(const JSRef<JSVal> & args)4551 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
4552 {
4553     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
4554         return;
4555     }
4556     CalcDimension borderRadius;
4557     if (ParseJsDimensionVp(args, borderRadius)) {
4558         if (borderRadius.Unit() == DimensionUnit::PERCENT) {
4559             borderRadius.Reset();
4560         }
4561         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
4562     } else if (args->IsObject()) {
4563         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4564         CalcDimension topLeft;
4565         CalcDimension topRight;
4566         CalcDimension bottomLeft;
4567         CalcDimension bottomRight;
4568         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4569             ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
4570                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4571         }
4572         ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4573     }
4574 }
4575 
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4576 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4577 {
4578     ParseJsDimensionVp(object->GetProperty(key), radius);
4579 }
4580 
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4581 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4582 {
4583     if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
4584         JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
4585         ParseJsLengthMetrics(startObj, radius);
4586     }
4587 }
4588 
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)4589 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
4590     CalcDimension& bottomLeft, CalcDimension& bottomRight)
4591 {
4592     if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
4593         object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
4594         CalcDimension topStart;
4595         CalcDimension topEnd;
4596         CalcDimension bottomStart;
4597         CalcDimension bottomEnd;
4598         GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
4599         GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
4600         GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
4601         GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
4602         topLeft = topStart;
4603         topRight = topEnd;
4604         bottomLeft = bottomStart;
4605         bottomRight = bottomEnd;
4606         return true;
4607     }
4608     GetBorderRadius("topLeft", object, topLeft);
4609     GetBorderRadius("topRight", object, topRight);
4610     GetBorderRadius("bottomLeft", object, bottomLeft);
4611     GetBorderRadius("bottomRight", object, bottomRight);
4612     return false;
4613 }
4614 
JsBorderStyle(const JSCallbackInfo & info)4615 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
4616 {
4617     ParseBorderStyle(info[0]);
4618 }
4619 namespace {
ConvertBorderStyle(int32_t value)4620 BorderStyle ConvertBorderStyle(int32_t value)
4621 {
4622     auto style = static_cast<BorderStyle>(value);
4623     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4624         style = BorderStyle::SOLID;
4625     }
4626     return style;
4627 }
4628 
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)4629 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
4630 {
4631     style = static_cast<BorderStyle>(value);
4632     if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4633         return false;
4634     }
4635     return true;
4636 }
4637 } // namespace
4638 
ParseBorderStyle(const JSRef<JSVal> & args)4639 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
4640 {
4641     if (args->IsObject()) {
4642         std::optional<BorderStyle> styleLeft;
4643         std::optional<BorderStyle> styleRight;
4644         std::optional<BorderStyle> styleTop;
4645         std::optional<BorderStyle> styleBottom;
4646         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4647         auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
4648         if (leftValue->IsNumber()) {
4649             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4650         }
4651         auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
4652         if (rightValue->IsNumber()) {
4653             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4654         }
4655         auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
4656         if (topValue->IsNumber()) {
4657             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4658         }
4659         auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
4660         if (bottomValue->IsNumber()) {
4661             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4662         }
4663         ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4664         return;
4665     }
4666     if (args->IsNumber()) {
4667         auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4668         ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
4669         return;
4670     }
4671     ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4672 }
4673 
ParseOuterBorderStyle(const JSRef<JSVal> & args)4674 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
4675 {
4676     if (!args->IsObject() && !args->IsNumber()) {
4677         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
4678         return;
4679     }
4680     if (args->IsObject()) {
4681         std::optional<BorderStyle> styleLeft;
4682         std::optional<BorderStyle> styleRight;
4683         std::optional<BorderStyle> styleTop;
4684         std::optional<BorderStyle> styleBottom;
4685         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4686         auto leftValue = object->GetProperty("left");
4687         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
4688             styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4689         }
4690         auto rightValue = object->GetProperty("right");
4691         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
4692             styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4693         }
4694         auto topValue = object->GetProperty("top");
4695         if (!topValue->IsUndefined() && topValue->IsNumber()) {
4696             styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4697         }
4698         auto bottomValue = object->GetProperty("bottom");
4699         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
4700             styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4701         }
4702         ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4703         return;
4704     }
4705     auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4706     ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
4707 }
4708 
JsBlur(const JSCallbackInfo & info)4709 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
4710 {
4711     if (info.Length() == 0) {
4712         return;
4713     }
4714     double blur = 0.0;
4715     if (!ParseJsDouble(info[0], blur)) {
4716         return;
4717     }
4718 
4719     BlurOption blurOption;
4720     if (info.Length() > 1 && info[1]->IsObject()) {
4721         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4722         ParseBlurOption(jsBlurOption, blurOption);
4723     }
4724     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4725     ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption);
4726     info.SetReturnValue(info.This());
4727 }
4728 
JsMotionBlur(const JSCallbackInfo & info)4729 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
4730 {
4731     if (!info[0]->IsObject()) {
4732         return;
4733     }
4734     MotionBlurOption option;
4735     double x = 0.0;
4736     double y = 0.0;
4737     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4738     JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
4739     if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
4740         JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
4741         ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
4742         ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
4743     }
4744     double radius = 0.0;
4745     if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
4746         radius = 0.0;
4747     }
4748     if (LessNotEqual(x, 0.0)) {
4749         x = 0.0;
4750     }
4751     if (LessNotEqual(y, 0.0)) {
4752         y = 0.0;
4753     }
4754     option.radius = radius;
4755     option.anchor.x = std::clamp(x, 0.0, 1.0);
4756     option.anchor.y = std::clamp(y, 0.0, 1.0);
4757     ViewAbstractModel::GetInstance()->SetMotionBlur(option);
4758 }
4759 
JsColorBlend(const JSCallbackInfo & info)4760 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
4761 {
4762     Color colorBlend;
4763     if (info[0]->IsUndefined()) {
4764         colorBlend = Color::TRANSPARENT;
4765         SetColorBlend(colorBlend);
4766         return;
4767     }
4768     if (!ParseJsColor(info[0], colorBlend)) {
4769         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4770             colorBlend = Color::TRANSPARENT;
4771             SetColorBlend(colorBlend);
4772         }
4773         return;
4774     }
4775     SetColorBlend(colorBlend);
4776     info.SetReturnValue(info.This());
4777 }
4778 
JsUseEffect(const JSCallbackInfo & info)4779 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
4780 {
4781     if (info[0]->IsBoolean()) {
4782         ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean());
4783     }
4784 }
4785 
JsUseShadowBatching(const JSCallbackInfo & info)4786 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
4787 {
4788     if (info[0]->IsBoolean()) {
4789         ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
4790     } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4791         ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
4792     }
4793 }
4794 
JsBackdropBlur(const JSCallbackInfo & info)4795 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
4796 {
4797     if (info.Length() == 0) {
4798         return;
4799     }
4800     double blur = 0.0;
4801     BlurOption blurOption;
4802     if (!ParseJsDouble(info[0], blur)) {
4803         if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4804             return;
4805         }
4806     }
4807     CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4808     if (info.Length() > 1 && info[1]->IsObject()) {
4809         JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4810         ParseBlurOption(jsBlurOption, blurOption);
4811     }
4812     ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption);
4813     info.SetReturnValue(info.This());
4814 }
4815 
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4816 void JSViewAbstract::GetFractionStops(
4817     std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
4818 {
4819     if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
4820         return;
4821     }
4822     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
4823     float tmpPos = -1.0f;
4824     size_t length = jsArray->Length();
4825     for (size_t i = 0; i < length; i++) {
4826         std::pair<float, float> fractionStop;
4827         JSRef<JSVal> item = jsArray->GetValueAt(i);
4828         if (!item->IsArray()) {
4829             continue;
4830         }
4831         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
4832         if (subArray->Length() < 2) {
4833             continue;
4834         }
4835 
4836         double value = 0.0;
4837         if (ParseJsDouble(subArray->GetValueAt(0), value)) {
4838             value = std::clamp(value, 0.0, 1.0);
4839             fractionStop.first = static_cast<float>(value);
4840         }
4841         value = 0.0;
4842         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
4843             value = std::clamp(value, 0.0, 1.0);
4844             fractionStop.second = static_cast<float>(value);
4845         }
4846 
4847         if (fractionStop.second <= tmpPos) {
4848             fractionStops.clear();
4849             return;
4850         }
4851         tmpPos = fractionStop.second;
4852         fractionStops.push_back(fractionStop);
4853     }
4854 }
JsLinearGradientBlur(const JSCallbackInfo & info)4855 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
4856 {
4857     if (info.Length() < 2) { // 2 represents the least para num;
4858         return;
4859     }
4860     double blurRadius = 0.0;
4861     ParseJsDouble(info[0], blurRadius);
4862 
4863     std::vector<std::pair<float, float>> fractionStops;
4864     auto direction = GradientDirection::BOTTOM;
4865     if (info[1]->IsObject()) {
4866         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
4867         GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
4868         auto directionValue =
4869             jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
4870         if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
4871             directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
4872             directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
4873         }
4874         direction = static_cast<GradientDirection>(directionValue);
4875     }
4876     if (static_cast<int32_t>(fractionStops.size()) <= 1) {
4877         fractionStops.clear();
4878         fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
4879         fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
4880     }
4881     // Parse direction
4882     CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
4883     NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
4884     SetLinearGradientBlur(blurPara);
4885 }
4886 
JsBackgroundBrightness(const JSCallbackInfo & info)4887 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
4888 {
4889     double rate = 0.0;
4890     double lightUpDegree = 0.0;
4891     if (info[0]->IsObject()) {
4892         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4893         ParseJsDouble(jsObj->GetProperty("rate"), rate);
4894         ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
4895     }
4896     SetDynamicLightUp(rate, lightUpDegree);
4897 }
4898 
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)4899 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
4900 {
4901     if (info.Length() == 0) {
4902         return;
4903     }
4904     BrightnessOption option;
4905     if (info[0]->IsObject()) {
4906         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
4907         ParseBrightnessOption(jsOption, option);
4908     }
4909     SetBgDynamicBrightness(option);
4910 }
4911 
JsForegroundBrightness(const JSCallbackInfo & info)4912 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
4913 {
4914     if (info.Length() == 0) {
4915         return;
4916     }
4917     BrightnessOption option;
4918     if (info[0]->IsObject()) {
4919         JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
4920         ParseBrightnessOption(jsOption, option);
4921     }
4922     SetFgDynamicBrightness(option);
4923 }
4924 
JsWindowBlur(const JSCallbackInfo & info)4925 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
4926 {
4927     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4928     auto jsVal = info[0];
4929     if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
4930         return;
4931     }
4932 
4933     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
4934     double progress = 0.0;
4935     ParseJsDouble(jsObj->GetProperty("percent"), progress);
4936     auto style = jsObj->GetPropertyValue<int32_t>("style",
4937         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
4938 
4939     progress = std::clamp(progress, 0.0, 1.0);
4940     style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
4941         static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
4942 
4943     SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
4944     info.SetReturnValue(info.This());
4945 }
4946 
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)4947 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
4948     std::string& resName, bool isParseType)
4949 {
4950     if (!jsValue->IsString()) {
4951         return false;
4952     }
4953     std::string resPath = jsValue->ToString();
4954     std::smatch results;
4955     std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
4956     if (!std::regex_match(resPath, results, tokenRegex)) {
4957         return false;
4958     }
4959     targetModule = results[1];
4960     if (isParseType && !ConvertResourceType(results[2], resType)) {
4961         return false;
4962     }
4963     resName = resPath;
4964     return true;
4965 }
4966 
ConvertResourceType(const std::string & typeName,ResourceType & resType)4967 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
4968 {
4969     static const std::unordered_map<std::string, ResourceType> resTypeMap {
4970         { "color", ResourceType::COLOR },
4971         { "media", ResourceType::MEDIA },
4972         { "float", ResourceType::FLOAT },
4973         { "string", ResourceType::STRING },
4974         { "plural", ResourceType::PLURAL },
4975         { "pattern", ResourceType::PATTERN },
4976         { "boolean", ResourceType::BOOLEAN },
4977         { "integer", ResourceType::INTEGER },
4978         { "strarray", ResourceType::STRARRAY },
4979         { "intarray", ResourceType::INTARRAY },
4980     };
4981     auto it = resTypeMap.find(typeName);
4982     if (it == resTypeMap.end()) {
4983         return false;
4984     }
4985     resType = it->second;
4986     return true;
4987 }
4988 
CompleteResourceObject(JSRef<JSObject> & jsObj)4989 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
4990 {
4991     std::string bundleName;
4992     std::string moduleName;
4993     int32_t resId = -1;
4994     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
4995 }
4996 
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)4997 void JSViewAbstract::CompleteResourceObjectWithBundleName(
4998     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
4999 {
5000     CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5001 }
5002 
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)5003 void JSViewAbstract::CompleteResourceObjectInner(
5004     JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
5005 {
5006     // dynamic $r raw input format is
5007     // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
5008     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5009     ResourceType resType;
5010 
5011     std::string targetModule;
5012     std::string resName;
5013     if (resId->IsString()) {
5014         JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
5015         int32_t typeNum = -1;
5016         if (type->IsNumber()) {
5017             typeNum = type->ToNumber<int32_t>();
5018         }
5019         if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
5020             return;
5021         }
5022         CompleteResourceObjectFromId(type, jsObj, resType, resName);
5023     } else if (resId->IsNumber()) {
5024         resIdValue = resId->ToNumber<int32_t>();
5025         if (resIdValue == -1) {
5026             CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
5027         }
5028     }
5029 
5030     JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
5031     if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
5032         bundleName = GetBundleNameFromContainer();
5033         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
5034     }
5035     if (moduleName == DEFAULT_HAR_MODULE_NAME) {
5036         moduleName = GetModuleNameFromContainer();
5037         jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
5038     }
5039 }
5040 
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)5041 bool JSViewAbstract::ParseJsDimensionNG(
5042     const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
5043 {
5044     if (jsValue->IsNumber()) {
5045         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5046         return true;
5047     }
5048     if (jsValue->IsString()) {
5049         auto value = jsValue->ToString();
5050         if (!isSupportPercent && value.back() == '%') {
5051             return false;
5052         }
5053         return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5054     }
5055     if (jsValue->IsObject()) {
5056         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5057         CompleteResourceObject(jsObj);
5058         JSRef<JSVal> resId = jsObj->GetProperty("id");
5059         if (!resId->IsNumber()) {
5060             return false;
5061         }
5062         auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5063         if (resType == UNKNOWN_RESOURCE_TYPE) {
5064             return false;
5065         }
5066 
5067         auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5068         auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5069         if (!resourceWrapper) {
5070             return false;
5071         }
5072 
5073         auto resIdNum = resId->ToNumber<int32_t>();
5074         if (resIdNum == -1) {
5075             if (!IsGetResourceByName(jsObj)) {
5076                 return false;
5077             }
5078             JSRef<JSVal> args = jsObj->GetProperty("params");
5079             if (!args->IsArray()) {
5080                 return false;
5081             }
5082             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5083             auto param = params->GetValueAt(0);
5084             if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5085                 auto value = resourceWrapper->GetStringByName(param->ToString());
5086                 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5087             }
5088             if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5089                 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5090                 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5091                 return true;
5092             }
5093             result = resourceWrapper->GetDimensionByName(param->ToString());
5094             return true;
5095         }
5096 
5097         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5098             auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5099             return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5100         }
5101         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5102             auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5103             StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5104             return true;
5105         }
5106 
5107         if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5108             result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
5109             return true;
5110         }
5111     }
5112 
5113     return false;
5114 }
5115 
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)5116 bool JSViewAbstract::ParseJsLengthNG(
5117     const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
5118 {
5119     if (jsValue->IsNumber()) {
5120         if (std::isnan(jsValue->ToNumber<double>())) {
5121             return false;
5122         }
5123         result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
5124         return true;
5125     } else if (jsValue->IsObject()) {
5126         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5127         JSRef<JSVal> value = jsObj->GetProperty("value");
5128         if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
5129             return false;
5130         }
5131         DimensionUnit unit = defaultUnit;
5132         JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
5133         if (jsUnit->IsNumber()) {
5134             if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
5135                 return false;
5136             }
5137             unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
5138         }
5139         result = NG::CalcLength(value->ToNumber<double>(), unit);
5140         return true;
5141     }
5142 
5143     return false;
5144 }
5145 
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)5146 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
5147 {
5148     // 'vp' -> the value varies with pixel density of device.
5149     return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5150 }
5151 
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)5152 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
5153 {
5154     if (jsValue->IsNumber()) {
5155         result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5156         return true;
5157     }
5158     if (jsValue->IsString()) {
5159         result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
5160         return true;
5161     }
5162     if (!jsValue->IsObject()) {
5163         return false;
5164     }
5165     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5166     CompleteResourceObject(jsObj);
5167     JSRef<JSVal> resId = jsObj->GetProperty("id");
5168     if (!resId->IsNumber()) {
5169         return false;
5170     }
5171 
5172     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5173     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5174     if (!resourceWrapper) {
5175         return false;
5176     }
5177 
5178     auto resIdNum = resId->ToNumber<int32_t>();
5179     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5180     if (resType == UNKNOWN_RESOURCE_TYPE) {
5181         return false;
5182     }
5183 
5184     if (resIdNum == -1) {
5185         if (!IsGetResourceByName(jsObj)) {
5186             return false;
5187         }
5188         JSRef<JSVal> args = jsObj->GetProperty("params");
5189         if (!args->IsArray()) {
5190             return false;
5191         }
5192         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5193         auto param = params->GetValueAt(0);
5194         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5195             auto value = resourceWrapper->GetStringByName(param->ToString());
5196             result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5197             return true;
5198         }
5199         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5200             auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5201             result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5202             return true;
5203         }
5204         result = resourceWrapper->GetDimensionByName(param->ToString());
5205         return true;
5206     }
5207 
5208     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5209         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5210         result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5211         return true;
5212     }
5213     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5214         auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5215         result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5216         return true;
5217     }
5218     result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
5219     return true;
5220 }
5221 
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5222 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5223 {
5224     // 'vp' -> the value varies with pixel density of device.
5225     return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5226 }
5227 
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)5228 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5229 {
5230     // 'vp' -> the value varies with pixel density of device.
5231     return ParseJsDimension(jsValue, result, DimensionUnit::VP);
5232 }
5233 
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)5234 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5235 {
5236     // the 'fp' unit is used for text scenes.
5237     return ParseJsDimension(jsValue, result, DimensionUnit::FP);
5238 }
5239 
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5240 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5241 {
5242     // the 'fp' unit is used for text scenes.
5243     return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
5244 }
5245 
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)5246 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
5247 {
5248     return ParseJsDimension(jsValue, result, DimensionUnit::PX);
5249 }
5250 
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)5251 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
5252 {
5253     if (!jsValue->IsObject()) {
5254         return false;
5255     }
5256     auto colorObj = JSRef<JSObject>::Cast(jsValue);
5257     auto toNumericProp = colorObj->GetProperty("toNumeric");
5258     if (toNumericProp->IsFunction()) {
5259         auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
5260         result.SetValue(colorVal->ToNumber<uint32_t>());
5261         return true;
5262     }
5263     return false;
5264 }
5265 
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5266 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5267 {
5268     if (jsValue->IsNumber()) {
5269         result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
5270         return true;
5271     }
5272     if (jsValue->IsString()) {
5273         auto value = jsValue->ToString();
5274         return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
5275     }
5276     if (jsValue->IsObject()) {
5277         auto jsObj = JSRef<JSObject>::Cast(jsValue);
5278         auto valObj = jsObj->GetProperty("value");
5279         if (valObj->IsUndefined() || valObj->IsNull()) {
5280             return false;
5281         }
5282         double value = valObj->ToNumber<double>();
5283         auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
5284         result = CalcDimension(value, unit);
5285         return true;
5286     }
5287     return false;
5288 }
5289 
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5290 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5291 {
5292     return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
5293 }
5294 
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)5295 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
5296 {
5297     if (!jsValue->IsObject()) {
5298         return false;
5299     }
5300     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5301     CompleteResourceObject(jsObj);
5302     if (jsObj->IsEmpty()) {
5303         return false;
5304     }
5305     JSRef<JSVal> id = jsObj->GetProperty("id");
5306     if (!id->IsNumber()) {
5307         return false;
5308     }
5309 
5310     auto resId = id->ToNumber<int32_t>();
5311     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5312     if (resType == UNKNOWN_RESOURCE_TYPE) {
5313         return false;
5314     }
5315 
5316     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5317     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5318     if (!resourceWrapper) {
5319         return false;
5320     }
5321 
5322     if (resId == -1) {
5323         if (!IsGetResourceByName(jsObj)) {
5324             return false;
5325         }
5326         JSRef<JSVal> args = jsObj->GetProperty("params");
5327         if (!args->IsArray()) {
5328             return false;
5329         }
5330         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5331         auto param = params->GetValueAt(0);
5332         if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5333             auto numberString = resourceWrapper->GetStringByName(param->ToString());
5334             return StringUtils::StringToDouble(numberString, result);
5335         }
5336         if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5337             result = resourceWrapper->GetIntByName(param->ToString());
5338             return true;
5339         }
5340         if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5341             result = resourceWrapper->GetDoubleByName(param->ToString());
5342             return true;
5343         }
5344         return false;
5345     }
5346     if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5347         auto numberString = resourceWrapper->GetString(resId);
5348         return StringUtils::StringToDouble(numberString, result);
5349     }
5350     if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5351         result = resourceWrapper->GetInt(resId);
5352         return true;
5353     }
5354     if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5355         result = resourceWrapper->GetDouble(resId);
5356         return true;
5357     }
5358     return false;
5359 }
5360 
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)5361 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
5362 {
5363     if (jsValue->IsNumber()) {
5364         result = jsValue->ToNumber<double>();
5365         return true;
5366     }
5367     if (jsValue->IsString()) {
5368         return StringUtils::StringToDouble(jsValue->ToString(), result);
5369     }
5370     if (jsValue->IsObject()) {
5371         return ParseResourceToDouble(jsValue, result);
5372     }
5373     return false;
5374 }
5375 
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)5376 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
5377 {
5378     if (jsValue->IsNumber()) {
5379         result = jsValue->ToNumber<int32_t>();
5380         return true;
5381     }
5382     if (jsValue->IsString()) {
5383         result = StringUtils::StringToInt(jsValue->ToString());
5384         return true;
5385     }
5386     if (!jsValue->IsObject()) {
5387         return false;
5388     }
5389     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5390     CompleteResourceObject(jsObj);
5391     JSRef<JSVal> resId = jsObj->GetProperty("id");
5392     if (!resId->IsNumber()) {
5393         return false;
5394     }
5395 
5396     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5397     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5398     if (!resourceWrapper) {
5399         return false;
5400     }
5401 
5402     auto resIdNum = resId->ToNumber<int32_t>();
5403     if (resIdNum == -1) {
5404         if (!IsGetResourceByName(jsObj)) {
5405             return false;
5406         }
5407         JSRef<JSVal> args = jsObj->GetProperty("params");
5408         if (!args->IsArray()) {
5409             return false;
5410         }
5411         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5412         auto param = params->GetValueAt(0);
5413         result = resourceWrapper->GetIntByName(param->ToString());
5414         return true;
5415     }
5416     result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5417     return true;
5418 }
5419 
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)5420 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
5421 {
5422     if (!jsValue->IsObject()) {
5423         return false;
5424     }
5425     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5426     CompleteResourceObject(jsObj);
5427 
5428     auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result);
5429     if (ok) {
5430         JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
5431         if (jsOpacityRatio->IsNumber()) {
5432             double opacityRatio = jsOpacityRatio->ToNumber<double>();
5433             result = result.BlendOpacity(opacityRatio);
5434         }
5435     }
5436     return ok;
5437 }
5438 
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)5439 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result)
5440 {
5441     JSRef<JSVal> resId = jsObj->GetProperty("id");
5442     if (!resId->IsNumber()) {
5443         return false;
5444     }
5445 
5446     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5447     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5448     if (!resourceWrapper) {
5449         return false;
5450     }
5451 
5452     auto resIdNum = resId->ToNumber<int32_t>();
5453     if (resIdNum == -1) {
5454         if (!IsGetResourceByName(jsObj)) {
5455             return false;
5456         }
5457         JSRef<JSVal> args = jsObj->GetProperty("params");
5458         if (!args->IsArray()) {
5459             return false;
5460         }
5461         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5462         auto param = params->GetValueAt(0);
5463         result = resourceWrapper->GetColorByName(param->ToString());
5464         return true;
5465     }
5466 
5467     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5468     if (type == static_cast<int32_t>(ResourceType::STRING)) {
5469         auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5470         return Color::ParseColorString(value, result);
5471     }
5472     if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5473         auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5474         result = Color(ColorAlphaAdapt(value));
5475         return true;
5476     }
5477     if (type == static_cast<int32_t>(ResourceType::COLOR)) {
5478         result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
5479         result.SetResourceId(resId->ToNumber<uint32_t>());
5480         return true;
5481     }
5482     return false;
5483 }
5484 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)5485 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
5486 {
5487     if (jsValue->IsNumber()) {
5488         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5489         return true;
5490     }
5491     if (jsValue->IsString()) {
5492         return Color::ParseColorString(jsValue->ToString(), result);
5493     }
5494     if (jsValue->IsObject()) {
5495         return ParseJsColorFromResource(jsValue, result);
5496     }
5497     return false;
5498 }
5499 
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)5500 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
5501 {
5502     if (jsValue->IsNumber()) {
5503         result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5504         return true;
5505     }
5506     if (jsValue->IsString()) {
5507         return Color::ParseColorString(jsValue->ToString(), result, defaultColor);
5508     }
5509     if (!jsValue->IsObject()) {
5510         return false;
5511     }
5512     return ParseJsColorFromResource(jsValue, result);
5513 }
5514 
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)5515 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
5516 {
5517     if (jsValue->IsString()) {
5518         std::string colorStr = jsValue->ToString();
5519         if (colorStr.compare("invert") == 0) {
5520             strategy = ForegroundColorStrategy::INVERT;
5521             return true;
5522         }
5523     }
5524     return false;
5525 }
5526 
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)5527 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
5528 {
5529     if (jsValue->IsString()) {
5530         std::string colorStr = jsValue->ToString();
5531         if (colorStr.compare("average") == 0) {
5532             strategy = ShadowColorStrategy::AVERAGE;
5533             return true;
5534         } else if (colorStr.compare("primary") == 0) {
5535             strategy = ShadowColorStrategy::PRIMARY;
5536             return true;
5537         }
5538     }
5539     return false;
5540 }
5541 
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)5542 bool JSViewAbstract::ParseJsSymbolId(
5543     const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
5544 {
5545     if (jsValue->IsNull() || jsValue->IsUndefined()) {
5546         symbolId = 0;
5547         return false;
5548     }
5549     if (!jsValue->IsObject()) {
5550         return false;
5551     }
5552     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5553     CompleteResourceObject(jsObj);
5554     JSRef<JSVal> resId = jsObj->GetProperty("id");
5555     if (resId->IsNull() || !resId->IsNumber()) {
5556         return false;
5557     }
5558     auto resourceObject = GetResourceObject(jsObj);
5559     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5560     symbolResourceObject = resourceObject;
5561     if (!resourceWrapper) {
5562         return false;
5563     }
5564     if (!resourceObject) {
5565         return false;
5566     }
5567 
5568     auto resIdNum = resId->ToNumber<int32_t>();
5569     if (resIdNum == -1) {
5570         if (!IsGetResourceByName(jsObj)) {
5571             return false;
5572         }
5573         JSRef<JSVal> args = jsObj->GetProperty("params");
5574         if (!args->IsArray()) {
5575             return false;
5576         }
5577         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5578         auto param = params->GetValueAt(0);
5579         auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
5580         if (!symbol) {
5581             return false;
5582         }
5583         symbolId = symbol;
5584         return true;
5585     }
5586 
5587     auto symbol = resourceWrapper->GetSymbolById(resIdNum);
5588     if (!symbol) {
5589         return false;
5590     }
5591     symbolId = symbol;
5592     return true;
5593 }
5594 
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)5595 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
5596 {
5597     if (!jsValue->IsArray()) {
5598         return false;
5599     }
5600     if (jsValue->IsArray()) {
5601         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5602         for (size_t i = 0; i < array->Length(); i++) {
5603             JSRef<JSVal> value = array->GetValueAt(i);
5604             if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
5605                 return false;
5606             }
5607             if (value->IsNumber()) {
5608                 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
5609                 continue;
5610             } else if (value->IsString()) {
5611                 Color color;
5612                 Color::ParseColorString(value->ToString(), color);
5613                 result.emplace_back(color);
5614                 continue;
5615             } else {
5616                 Color color;
5617                 ParseJsColorFromResource(value, color);
5618                 result.emplace_back(color);
5619             }
5620         }
5621         return true;
5622     }
5623     return false;
5624 }
5625 
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5626 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
5627 {
5628     result.clear();
5629     if (!jsValue->IsString() && !jsValue->IsObject()) {
5630         return false;
5631     }
5632     if (jsValue->IsString()) {
5633         result = ConvertStrToFontFamilies(jsValue->ToString());
5634         return true;
5635     }
5636     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5637     CompleteResourceObject(jsObj);
5638     JSRef<JSVal> resId = jsObj->GetProperty("id");
5639     if (!resId->IsNumber()) {
5640         return false;
5641     }
5642 
5643     auto resourceObject = GetResourceObject(jsObj);
5644     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5645     if (!resourceWrapper) {
5646         return false;
5647     }
5648 
5649     auto resIdNum = resId->ToNumber<int32_t>();
5650     if (resIdNum == -1) {
5651         if (!IsGetResourceByName(jsObj)) {
5652             return false;
5653         }
5654         JSRef<JSVal> args = jsObj->GetProperty("params");
5655         if (!args->IsArray()) {
5656             return false;
5657         }
5658         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5659         auto param = params->GetValueAt(0);
5660         result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
5661         return true;
5662     }
5663     result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
5664     return true;
5665 }
5666 
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5667 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
5668 {
5669     if (jsValue->IsString()) {
5670         result = jsValue->ToString();
5671         return true;
5672     }
5673 
5674     if (!jsValue->IsObject()) {
5675         return false;
5676     }
5677 
5678     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5679     CompleteResourceObject(jsObj);
5680 
5681     JSRef<JSVal> resId = jsObj->GetProperty("id");
5682     if (!resId->IsNumber()) {
5683         return false;
5684     }
5685     auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5686     if (type == UNKNOWN_RESOURCE_TYPE) {
5687         return false;
5688     }
5689 
5690     JSRef<JSVal> args = jsObj->GetProperty("params");
5691     if (!args->IsArray()) {
5692         return false;
5693     }
5694 
5695     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5696     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5697     if (!resourceWrapper) {
5698         return false;
5699     }
5700 
5701     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5702     auto resIdNum = resId->ToNumber<int32_t>();
5703     if (resIdNum == -1) {
5704         if (!IsGetResourceByName(jsObj)) {
5705             return false;
5706         }
5707         auto param = params->GetValueAt(0);
5708         if (type == static_cast<int32_t>(ResourceType::STRING)) {
5709             auto originStr = resourceWrapper->GetStringByName(param->ToString());
5710             ReplaceHolder(originStr, params, 1);
5711             result = originStr;
5712         } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5713             auto countJsVal = params->GetValueAt(1);
5714             int count = 0;
5715             if (!countJsVal->IsNumber()) {
5716                 return false;
5717             }
5718             count = countJsVal->ToNumber<int>();
5719             auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
5720             ReplaceHolder(pluralStr, params, 2);
5721             result = pluralStr;
5722         } else {
5723             return false;
5724         }
5725         return true;
5726     }
5727     if (type == static_cast<int32_t>(ResourceType::STRING)) {
5728         auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5729         ReplaceHolder(originStr, params, 0);
5730         result = originStr;
5731     } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5732         auto countJsVal = params->GetValueAt(0);
5733         int count = 0;
5734         if (!countJsVal->IsNumber()) {
5735             return false;
5736         }
5737         count = countJsVal->ToNumber<int>();
5738         auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
5739         ReplaceHolder(pluralStr, params, 1);
5740         result = pluralStr;
5741     } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
5742         result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
5743     } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5744         result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5745     } else {
5746         return false;
5747     }
5748     return true;
5749 }
5750 
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5751 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
5752 {
5753     if (!jsValue->IsObject() && !jsValue->IsString()) {
5754         return false;
5755     }
5756     if (jsValue->IsString()) {
5757         result = jsValue->ToString();
5758         return true;
5759     }
5760     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5761     CompleteResourceObject(jsObj);
5762     return ParseJSMediaInternal(jsObj, result);
5763 }
5764 
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5765 bool JSViewAbstract::ParseJsMediaWithBundleName(
5766     const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
5767 {
5768     if (!jsValue->IsObject() && !jsValue->IsString()) {
5769         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5770     }
5771     if (jsValue->IsString()) {
5772         result = jsValue->ToString();
5773         return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5774     }
5775     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5776     CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
5777     return ParseJSMediaInternal(jsObj, result);
5778 }
5779 
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5780 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result)
5781 {
5782     int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5783     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5784     if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
5785         auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5786         auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5787         CHECK_NULL_RETURN(resourceWrapper, false);
5788         if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
5789             JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5790             if (!args->IsArray()) {
5791                 return false;
5792             }
5793             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5794             auto fileName = params->GetValueAt(0);
5795             if (!fileName->IsString()) {
5796                 return false;
5797             }
5798             result = resourceWrapper->GetRawfile(fileName->ToString());
5799             return true;
5800         }
5801         auto resIdNum = resId->ToNumber<int32_t>();
5802         if (resIdNum == -1) {
5803             if (!IsGetResourceByName(jsObj)) {
5804                 return false;
5805             }
5806             JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5807             if (!args->IsArray()) {
5808                 return false;
5809             }
5810             JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5811             auto param = params->GetValueAt(0);
5812             if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5813                 result = resourceWrapper->GetMediaPathByName(param->ToString());
5814                 return true;
5815             }
5816             if (type == static_cast<int32_t>(ResourceType::STRING)) {
5817                 result = resourceWrapper->GetStringByName(param->ToString());
5818                 return true;
5819             }
5820             return false;
5821         } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5822             result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
5823             return true;
5824         } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
5825             result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5826             return true;
5827         }
5828     }
5829     return false;
5830 }
5831 
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5832 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
5833     const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
5834 {
5835     auto vm = info.GetVm();
5836     auto globalObj = JSNApi::GetGlobalObject(vm);
5837     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
5838     JsiValue jsiValue(globalFunc);
5839     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
5840     if (!globalFuncRef->IsFunction()) {
5841         return;
5842     }
5843     if (modifierNormalObj->IsUndefined()) {
5844         symbolApply.onApply = nullptr;
5845     } else {
5846         RefPtr<JsFunction> jsFunc =
5847             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
5848         auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
5849                             modifierNormal = std::move(modifierNormalObj),
5850                             modifierSelected = std::move(modifierSelectedObj)](
5851                             WeakPtr<NG::FrameNode> frameNode, std::string type) {
5852             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5853             auto node = frameNode.Upgrade();
5854             CHECK_NULL_VOID(node);
5855             JSRef<JSVal> params[SECOND_INDEX];
5856             if (type == "normal") {
5857                 params[0] = modifierNormal;
5858             } else if (!modifierSelected->IsUndefined()) {
5859                 params[0] = modifierSelected;
5860             }
5861             params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
5862             PipelineContext::SetCallBackNode(node);
5863             func->ExecuteJS(SECOND_INDEX, params);
5864         };
5865         symbolApply.onApply = onApply;
5866     }
5867 }
5868 
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)5869 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
5870 {
5871     if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
5872         return false;
5873     }
5874 
5875     if (jsValue->IsBoolean()) {
5876         result = jsValue->ToBoolean();
5877         return true;
5878     }
5879 
5880     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5881     CompleteResourceObject(jsObj);
5882     int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5883     if (resType == UNKNOWN_RESOURCE_TYPE) {
5884         return false;
5885     }
5886 
5887     JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5888     if (!resId->IsNumber()) {
5889         return false;
5890     }
5891 
5892     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5893     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5894     if (!resourceWrapper) {
5895         return false;
5896     }
5897 
5898     auto resIdNum = resId->ToNumber<int32_t>();
5899     if (resIdNum == -1) {
5900         if (!IsGetResourceByName(jsObj)) {
5901             return false;
5902         }
5903         JSRef<JSVal> args = jsObj->GetProperty("params");
5904         if (!args->IsArray()) {
5905             return false;
5906         }
5907         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5908         auto param = params->GetValueAt(0);
5909         if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
5910             result = resourceWrapper->GetBooleanByName(param->ToString());
5911             return true;
5912         }
5913         return false;
5914     }
5915 
5916     if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
5917         result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
5918         return true;
5919     }
5920     return false;
5921 }
5922 
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)5923 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
5924 {
5925     return ParseJsInteger<uint32_t>(jsValue, result);
5926 }
5927 
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)5928 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
5929 {
5930     return ParseJsInteger<int32_t>(jsValue, result);
5931 }
5932 
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)5933 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
5934 {
5935     if (!jsValue->IsArray() && !jsValue->IsObject()) {
5936         return false;
5937     }
5938 
5939     if (jsValue->IsArray()) {
5940         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5941         for (size_t i = 0; i < array->Length(); i++) {
5942             JSRef<JSVal> value = array->GetValueAt(i);
5943             if (value->IsNumber()) {
5944                 result.emplace_back(value->ToNumber<uint32_t>());
5945             } else if (value->IsObject()) {
5946                 uint32_t singleResInt;
5947                 if (ParseJsInteger(value, singleResInt)) {
5948                     result.emplace_back(singleResInt);
5949                 } else {
5950                     return false;
5951                 }
5952             } else {
5953                 return false;
5954             }
5955         }
5956         return true;
5957     }
5958 
5959     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5960     CompleteResourceObject(jsObj);
5961     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5962     if (resType == UNKNOWN_RESOURCE_TYPE) {
5963         return false;
5964     }
5965 
5966     JSRef<JSVal> resId = jsObj->GetProperty("id");
5967     if (!resId->IsNumber()) {
5968         return false;
5969     }
5970 
5971     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5972     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5973     if (!resourceWrapper) {
5974         return false;
5975     }
5976 
5977     auto resIdNum = resId->ToNumber<int32_t>();
5978     if (resIdNum == -1) {
5979         if (!IsGetResourceByName(jsObj)) {
5980             return false;
5981         }
5982         JSRef<JSVal> args = jsObj->GetProperty("params");
5983         if (!args->IsArray()) {
5984             return false;
5985         }
5986         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5987         auto param = params->GetValueAt(0);
5988         if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
5989             result = resourceWrapper->GetIntArrayByName(param->ToString());
5990             return true;
5991         }
5992         return false;
5993     }
5994 
5995     if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
5996         result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
5997         return true;
5998     }
5999     return false;
6000 }
6001 
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)6002 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
6003 {
6004     if (!jsValue->IsArray() && !jsValue->IsObject()) {
6005         return false;
6006     }
6007 
6008     if (jsValue->IsArray()) {
6009         JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6010         for (size_t i = 0; i < array->Length(); i++) {
6011             JSRef<JSVal> value = array->GetValueAt(i);
6012             if (value->IsString()) {
6013                 result.emplace_back(value->ToString());
6014             } else if (value->IsObject()) {
6015                 std::string singleResStr;
6016                 if (ParseJsString(value, singleResStr)) {
6017                     result.emplace_back(singleResStr);
6018                 } else {
6019                     return false;
6020                 }
6021             } else {
6022                 return false;
6023             }
6024         }
6025         return true;
6026     }
6027 
6028     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6029     CompleteResourceObject(jsObj);
6030     int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6031     if (resType == UNKNOWN_RESOURCE_TYPE) {
6032         return false;
6033     }
6034 
6035     JSRef<JSVal> resId = jsObj->GetProperty("id");
6036     if (!resId->IsNumber()) {
6037         return false;
6038     }
6039 
6040     auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6041     auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6042     if (!resourceWrapper) {
6043         return false;
6044     }
6045 
6046     auto resIdNum = resId->ToNumber<int32_t>();
6047     if (resIdNum == -1) {
6048         if (!IsGetResourceByName(jsObj)) {
6049             return false;
6050         }
6051         JSRef<JSVal> args = jsObj->GetProperty("params");
6052         if (!args->IsArray()) {
6053             return false;
6054         }
6055         JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6056         auto param = params->GetValueAt(0);
6057         if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6058             result = resourceWrapper->GetStringArrayByName(param->ToString());
6059             return true;
6060         }
6061         return false;
6062     }
6063 
6064     if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6065         result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
6066         return true;
6067     }
6068     return false;
6069 }
6070 
IsGetResourceByName(const JSRef<JSObject> & jsObj)6071 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
6072 {
6073     JSRef<JSVal> resId = jsObj->GetProperty("id");
6074     if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
6075         return false;
6076     }
6077     JSRef<JSVal> args = jsObj->GetProperty("params");
6078     if (!args->IsArray()) {
6079         return false;
6080     }
6081     JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
6082     JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
6083     if (!bundleName->IsString() || !moduleName->IsString()) {
6084         return false;
6085     }
6086     JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6087     if (params->IsEmpty()) {
6088         return false;
6089     }
6090     return true;
6091 }
6092 
ParseSize(const JSCallbackInfo & info)6093 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
6094 {
6095     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6096     auto jsVal = info[0];
6097     if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
6098         return std::pair<CalcDimension, CalcDimension>();
6099     }
6100     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
6101     CalcDimension width;
6102     CalcDimension height;
6103     if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
6104         !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
6105         return std::pair<CalcDimension, CalcDimension>();
6106     }
6107     return std::pair<CalcDimension, CalcDimension>(width, height);
6108 }
6109 
JsUseAlign(const JSCallbackInfo & info)6110 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
6111 {
6112     if (info.Length() < 2) {
6113         return;
6114     }
6115 
6116     if (!info[0]->IsObject() && !info[1]->IsObject()) {
6117         return;
6118     }
6119 
6120     AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
6121     if (declaration == nullptr) {
6122         return;
6123     }
6124 
6125     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6126     JSRef<JSVal> side = obj->GetProperty("side");
6127     JSRef<JSVal> offset = obj->GetProperty("offset");
6128 
6129     if (!side->IsNumber()) {
6130         return;
6131     }
6132 
6133     auto sideValue = side->ToNumber<int32_t>();
6134 
6135     if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
6136         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
6137             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
6138             return;
6139         }
6140     } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
6141         if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
6142             sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
6143             return;
6144         }
6145     }
6146 
6147     std::optional<CalcDimension> optOffset;
6148     CalcDimension offsetDimension;
6149     if (ParseJsDimensionVp(offset, offsetDimension)) {
6150         optOffset = offsetDimension;
6151     }
6152     ViewAbstractModel::GetInstance()->SetUseAlign(
6153         declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
6154 }
6155 
JsGridSpan(const JSCallbackInfo & info)6156 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
6157 {
6158     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6159     auto jsVal = info[0];
6160     if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
6161         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6162             ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
6163         }
6164         return;
6165     }
6166     auto span = jsVal->ToNumber<int32_t>();
6167     ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
6168 }
6169 
JsGridOffset(const JSCallbackInfo & info)6170 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
6171 {
6172     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6173     auto jsVal = info[0];
6174     if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
6175         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6176             ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
6177         }
6178         return;
6179     }
6180     auto offset = jsVal->ToNumber<int32_t>();
6181     ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
6182 }
6183 
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)6184 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
6185 {
6186     // {lg: 4}
6187     if (val->IsNumber()) {
6188         span = val->ToNumber<uint32_t>();
6189         return true;
6190     }
6191 
6192     if (!val->IsObject()) {
6193         return false;
6194     }
6195 
6196     // {lg: {span: 1, offset: 2}}
6197     JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
6198     span = obj->GetProperty("span")->ToNumber<uint32_t>();
6199     offset = obj->GetProperty("offset")->ToNumber<int32_t>();
6200     return true;
6201 }
6202 
JsUseSizeType(const JSCallbackInfo & info)6203 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
6204 {
6205     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6206     auto jsVal = info[0];
6207     if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
6208         return;
6209     }
6210     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
6211     for (auto values : SCREEN_SIZE_VALUES) {
6212         JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
6213         if (val->IsNull() || val->IsEmpty()) {
6214             continue;
6215         }
6216         uint32_t span = 0;
6217         int32_t offset = 0;
6218         if (ParseSpanAndOffset(val, span, offset)) {
6219             ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
6220         }
6221     }
6222 }
6223 
JsZIndex(const JSCallbackInfo & info)6224 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
6225 {
6226     int zIndex = 0;
6227     if (info[0]->IsNumber()) {
6228         zIndex = info[0]->ToNumber<int>();
6229     }
6230 
6231     ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
6232 }
6233 
Pop()6234 void JSViewAbstract::Pop()
6235 {
6236     ViewStackModel::GetInstance()->Pop();
6237 }
6238 
JsSetDraggable(bool draggable)6239 void JSViewAbstract::JsSetDraggable(bool draggable)
6240 {
6241     ViewAbstractModel::GetInstance()->SetDraggable(draggable);
6242 }
6243 
ParseDragPreviewOptions(const JSCallbackInfo & info)6244 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
6245 {
6246     NG::DragPreviewOption previewOption;
6247     if (!info[0]->IsObject()) {
6248         return previewOption;
6249     }
6250     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
6251     auto mode = obj->GetProperty("mode");
6252     bool isAuto = true;
6253     if (mode->IsNumber()) {
6254         ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
6255     } else if (mode->IsArray()) {
6256         JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
6257         for (size_t i = 0; i < array->Length(); i++) {
6258             JSRef<JSVal> value = array->GetValueAt(i);
6259             if (value->IsNumber()) {
6260                 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
6261             }
6262             if (isAuto) {
6263                 break;
6264             }
6265         }
6266     }
6267 
6268     JSViewAbstract::SetDragNumberBadge(info, previewOption);
6269 
6270     if (info.Length() > 1 && info[1]->IsObject()) {
6271         JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
6272         auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
6273         if (multiSelection->IsBoolean()) {
6274             previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
6275         }
6276         auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
6277         if (defaultAnimation->IsBoolean()) {
6278             previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
6279         }
6280         auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
6281         if (dragPreview->IsBoolean()) {
6282             previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
6283         }
6284     }
6285 
6286     JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
6287 
6288     return previewOption;
6289 }
6290 
JsSetDragPreviewOptions(const JSCallbackInfo & info)6291 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
6292 {
6293     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6294     auto jsVal = info[0];
6295     if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
6296         return;
6297     }
6298     NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
6299     ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
6300 }
6301 
JsOnDragStart(const JSCallbackInfo & info)6302 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
6303 {
6304     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6305     auto jsVal = info[0];
6306     if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
6307         return;
6308     }
6309 
6310     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6311 
6312     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6313     auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
6314                            const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
6315         NG::DragDropBaseInfo dragDropInfo;
6316         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
6317         PipelineContext::SetCallBackNode(node);
6318         auto ret = func->Execute(info, extraParams);
6319         if (!ret->IsObject()) {
6320             return dragDropInfo;
6321         }
6322 
6323         dragDropInfo.node = ParseDragNode(ret);
6324         auto builderObj = JSRef<JSObject>::Cast(ret);
6325 #if defined(PIXEL_MAP_SUPPORTED)
6326         auto pixmap = builderObj->GetProperty("pixelMap");
6327         dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
6328 #endif
6329         auto extraInfo = builderObj->GetProperty("extraInfo");
6330         ParseJsString(extraInfo, dragDropInfo.extraInfo);
6331         return dragDropInfo;
6332     };
6333     ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
6334 }
6335 
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)6336 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
6337 {
6338     auto node = ParseDragNode(info);
6339     if (!node) {
6340         return false;
6341     }
6342     dragInfo.node = node;
6343     return true;
6344 }
6345 
ParseDragNode(const JSRef<JSVal> & info)6346 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
6347 {
6348     auto builderFunc = ParseDragStartBuilderFunc(info);
6349     if (!builderFunc) {
6350         return nullptr;
6351     }
6352     // use another VSP instance while executing the builder function
6353     ViewStackModel::GetInstance()->NewScope();
6354     {
6355         ACE_SCORING_EVENT("onDragStart.builder");
6356         builderFunc->Execute();
6357     }
6358 
6359     return ViewStackModel::GetInstance()->Finish();
6360 }
6361 
JsOnDragEnter(const JSCallbackInfo & info)6362 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
6363 {
6364     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6365     auto jsVal = info[0];
6366     if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
6367         return;
6368     }
6369     RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6370     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6371     auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
6372                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6373         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6374         ACE_SCORING_EVENT("onDragEnter");
6375         PipelineContext::SetCallBackNode(node);
6376         func->Execute(info, extraParams);
6377     };
6378 
6379     ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
6380 }
6381 
JsOnDragEnd(const JSCallbackInfo & info)6382 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
6383 {
6384     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6385     auto jsVal = info[0];
6386     if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
6387         return;
6388     }
6389     RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6390     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6391     auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
6392                          const RefPtr<OHOS::Ace::DragEvent>& info) {
6393         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6394         ACE_SCORING_EVENT("onDragEnd");
6395         auto extraParams = JsonUtil::Create(true);
6396         PipelineContext::SetCallBackNode(node);
6397         func->Execute(info, extraParams->ToString());
6398     };
6399 
6400     ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
6401 }
6402 
JsOnDragMove(const JSCallbackInfo & info)6403 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
6404 {
6405     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6406     auto jsVal = info[0];
6407     if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
6408         return;
6409     }
6410     RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6411     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6412     auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
6413                           const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6414         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6415         ACE_SCORING_EVENT("onDragMove");
6416         PipelineContext::SetCallBackNode(node);
6417         func->Execute(info, extraParams);
6418     };
6419 
6420     ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
6421 }
6422 
JsOnDragLeave(const JSCallbackInfo & info)6423 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
6424 {
6425     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6426     auto jsVal = info[0];
6427     if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
6428         return;
6429     }
6430     RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6431     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6432     auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
6433                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6434         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6435         ACE_SCORING_EVENT("onDragLeave");
6436         PipelineContext::SetCallBackNode(node);
6437         func->Execute(info, extraParams);
6438     };
6439 
6440     ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
6441 }
6442 
JsOnDrop(const JSCallbackInfo & info)6443 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
6444 {
6445     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6446     auto jsVal = info[0];
6447     if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
6448         return;
6449     }
6450     RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6451     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6452     auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
6453                       const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6454         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6455         ACE_SCORING_EVENT("onDrop");
6456         PipelineContext::SetCallBackNode(node);
6457         func->Execute(info, extraParams);
6458     };
6459 
6460     ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
6461 }
6462 
JsOnAreaChange(const JSCallbackInfo & info)6463 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
6464 {
6465     auto jsVal = info[0];
6466     if (jsVal->IsUndefined() && IsDisableEventVersion()) {
6467         ViewAbstractModel::GetInstance()->DisableOnAreaChange();
6468         return;
6469     }
6470     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6471     if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
6472         return;
6473     }
6474     auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6475 
6476     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6477     auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
6478                              node = frameNode](
6479                              const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
6480         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6481         ACE_SCORING_EVENT("onAreaChange");
6482         PipelineContext::SetCallBackNode(node);
6483         func->Execute(oldRect, oldOrigin, rect, origin);
6484     };
6485     ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
6486 }
6487 
JsOnSizeChange(const JSCallbackInfo & info)6488 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
6489 {
6490     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6491     auto jsVal = info[0];
6492     if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
6493         return;
6494     }
6495     auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6496 
6497     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6498     auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
6499                             node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
6500         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6501         ACE_SCORING_EVENT("onSizeChange");
6502         PipelineContext::SetCallBackNode(node);
6503         func->Execute(oldRect, rect);
6504     };
6505     ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
6506 }
6507 
6508 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)6509 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
6510 {
6511     if (info.Length() < 2) {
6512         return;
6513     }
6514     if ((!info[0]->IsBoolean() && !info[0]->IsObject()) || !info[1]->IsObject()) {
6515         return;
6516     }
6517     auto popupParam = AceType::MakeRefPtr<PopupParam>();
6518     // Set IsShow to popupParam
6519     if (info[0]->IsBoolean()) {
6520         popupParam->SetIsShow(info[0]->ToBoolean());
6521     } else {
6522         JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
6523         auto callback = ParseDoubleBindCallback(info, showObj);
6524         popupParam->SetOnStateChange(std::move(callback));
6525         popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
6526     }
6527     // Set popup to popupParam
6528     auto popupObj = JSRef<JSObject>::Cast(info[1]);
6529     SetPopupDismiss(info, popupObj, popupParam);
6530     if (popupObj->GetProperty("message")->IsString()) {
6531         ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
6532         ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6533     } else if (!popupObj->GetProperty("builder").IsEmpty()) {
6534         ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
6535         auto builderValue = popupObj->GetProperty("builder");
6536         auto builder = builderValue;
6537         if (!builderValue->IsObject()) {
6538             return;
6539         }
6540         if (!builderValue->IsFunction()) {
6541             JSRef<JSObject> builderObj;
6542             builderObj = JSRef<JSObject>::Cast(builderValue);
6543             builder = builderObj->GetProperty("builder");
6544             if (!builder->IsFunction()) {
6545                 return;
6546             }
6547         }
6548         if (popupParam->IsShow() && !IsPopupCreated()) {
6549             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
6550             CHECK_NULL_VOID(builderFunc);
6551             ViewStackModel::GetInstance()->NewScope();
6552             builderFunc->Execute();
6553             auto customNode = ViewStackModel::GetInstance()->Finish();
6554             ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
6555         } else {
6556             ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6557         }
6558     } else {
6559         return;
6560     }
6561 }
6562 
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)6563 void JSViewAbstract::SetPopupDismiss(
6564     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
6565 {
6566     auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
6567     if (onWillDismissFunc->IsBoolean()) {
6568         bool onWillDismissBool = onWillDismissFunc->ToBoolean();
6569         popupParam->SetInteractiveDismiss(onWillDismissBool);
6570         popupParam->SetOnWillDismiss(nullptr);
6571         if (onWillDismissBool) {
6572             TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6573         }
6574     } else if (onWillDismissFunc->IsFunction()) {
6575         auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
6576         popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
6577         popupParam->SetInteractiveDismiss(true);
6578         if (onWillDismissCallback != nullptr) {
6579             TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6580         }
6581     }
6582 }
6583 
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)6584 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
6585 {
6586     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6587     if (!onWillDismissFunc->IsFunction()) {
6588         return PopupOnWillDismiss();
6589     }
6590     RefPtr<JsFunction> jsFunc =
6591         AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6592     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6593     auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
6594                           node = frameNode](int32_t reason) {
6595         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6596         ACE_SCORING_EVENT("Bindpopup.dismiss");
6597         PipelineContext::SetCallBackNode(node);
6598 
6599         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6600         objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6601         JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6602         dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
6603         dismissObj->SetProperty<int32_t>("reason", reason);
6604         JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6605 
6606         func->ExecuteJS(1, &newJSVal);
6607     };
6608     return onWillDismiss;
6609 }
6610 
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)6611 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6612 {
6613     ViewAbstractModel::GetInstance()->DismissPopup();
6614     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6615 }
6616 #endif
6617 
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info)> & onWillDismiss)6618 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
6619     std::function<void(const int32_t& info)>& onWillDismiss)
6620 {
6621     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6622     if (onWillDismissFunc->IsFunction()) {
6623         RefPtr<JsFunction> jsFunc =
6624             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6625         onWillDismiss = [func = std::move(jsFunc)](const int32_t& info) {
6626             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6627             objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6628             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6629             dismissObj->SetPropertyObject(
6630                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
6631             dismissObj->SetProperty<int32_t>("reason", info);
6632             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6633             func->ExecuteJS(1, &newJSVal);
6634         };
6635     }
6636 }
6637 
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)6638 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6639 {
6640     ViewAbstractModel::GetInstance()->DismissDialog();
6641     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6642 }
6643 
JsLinearGradient(const JSCallbackInfo & info)6644 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
6645 {
6646     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6647     auto jsVal = info[0];
6648     if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
6649         NG::Gradient newGradient;
6650         newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6651         ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6652         return;
6653     }
6654     NG::Gradient newGradient;
6655     NewJsLinearGradient(info, newGradient);
6656     ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6657 }
6658 
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6659 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6660 {
6661     if (!info[0]->IsObject()) {
6662         return;
6663     }
6664     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
6665     newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6666     // angle
6667     std::optional<float> degree;
6668     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6669         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
6670     } else {
6671         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
6672     }
6673     if (degree) {
6674         newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
6675         degree.reset();
6676     }
6677     // direction
6678     auto direction = static_cast<GradientDirection>(
6679         jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
6680     switch (direction) {
6681         case GradientDirection::LEFT:
6682             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6683             break;
6684         case GradientDirection::RIGHT:
6685             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6686             break;
6687         case GradientDirection::TOP:
6688             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6689             break;
6690         case GradientDirection::BOTTOM:
6691             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6692             break;
6693         case GradientDirection::LEFT_TOP:
6694             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6695             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6696             break;
6697         case GradientDirection::LEFT_BOTTOM:
6698             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6699             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6700             break;
6701         case GradientDirection::RIGHT_TOP:
6702             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6703             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6704             break;
6705         case GradientDirection::RIGHT_BOTTOM:
6706             newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6707             newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6708             break;
6709         case GradientDirection::NONE:
6710         case GradientDirection::START_TO_END:
6711         case GradientDirection::END_TO_START:
6712         default:
6713             break;
6714     }
6715     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6716     newGradient.SetRepeat(repeating);
6717     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6718 }
6719 
JsRadialGradient(const JSCallbackInfo & info)6720 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
6721 {
6722     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6723     auto jsVal = info[0];
6724     if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
6725         NG::Gradient newGradient;
6726         newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6727         ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6728         return;
6729     }
6730     NG::Gradient newGradient;
6731     NewJsRadialGradient(info, newGradient);
6732     ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6733 }
6734 
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6735 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6736 {
6737     JSRef<JSVal> arg = info[0];
6738     if (!arg->IsObject()) {
6739         return;
6740     }
6741     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6742     newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6743     // center
6744     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6745     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6746         CalcDimension value;
6747         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6748         if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6749             newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
6750             if (value.Unit() == DimensionUnit::PERCENT) {
6751                 // [0,1] -> [0, 100]
6752                 newGradient.GetRadialGradient()->radialCenterX =
6753                     CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6754             }
6755         }
6756         if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6757             newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
6758             if (value.Unit() == DimensionUnit::PERCENT) {
6759                 // [0,1] -> [0, 100]
6760                 newGradient.GetRadialGradient()->radialCenterY =
6761                     CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6762             }
6763         }
6764     }
6765     // radius
6766     CalcDimension radius;
6767     if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) {
6768         newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
6769         newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
6770     }
6771     // repeating
6772     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6773     newGradient.SetRepeat(repeating);
6774     // color stops
6775     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6776 }
6777 
JsSweepGradient(const JSCallbackInfo & info)6778 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
6779 {
6780     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6781     auto jsVal = info[0];
6782     if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
6783         NG::Gradient newGradient;
6784         newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6785         ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6786         return;
6787     }
6788 
6789     NG::Gradient newGradient;
6790     NewJsSweepGradient(info, newGradient);
6791     ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6792 }
6793 
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6794 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6795 {
6796     JSRef<JSVal> arg = info[0];
6797     if (!arg->IsObject()) {
6798         return;
6799     }
6800     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6801     newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6802     // center
6803     JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6804     if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6805         CalcDimension value;
6806         JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6807         if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6808             newGradient.GetSweepGradient()->centerX = CalcDimension(value);
6809             if (value.Unit() == DimensionUnit::PERCENT) {
6810                 // [0,1] -> [0, 100]
6811                 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6812             }
6813         }
6814         if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6815             newGradient.GetSweepGradient()->centerY = CalcDimension(value);
6816             if (value.Unit() == DimensionUnit::PERCENT) {
6817                 // [0,1] -> [0, 100]
6818                 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6819             }
6820         }
6821     }
6822     // start, end and rotation
6823     ParseSweepGradientPartly(jsObj, newGradient);
6824     // repeating
6825     auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6826     newGradient.SetRepeat(repeating);
6827     // color stops
6828     NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6829 }
6830 
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)6831 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
6832 {
6833     std::optional<float> degreeStart;
6834     std::optional<float> degreeEnd;
6835     std::optional<float> degreeRotation;
6836     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6837         GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
6838         GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
6839         GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
6840     } else {
6841         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
6842         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
6843         GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
6844     }
6845     if (degreeStart) {
6846         CheckAngle(degreeStart);
6847         newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
6848     }
6849     if (degreeEnd) {
6850         CheckAngle(degreeEnd);
6851         newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
6852     }
6853     if (degreeRotation) {
6854         CheckAngle(degreeRotation);
6855         newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
6856     }
6857 }
6858 
JsMotionPath(const JSCallbackInfo & info)6859 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
6860 {
6861     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6862     auto jsVal = info[0];
6863     if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
6864         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6865         return;
6866     }
6867     MotionPathOption motionPathOption;
6868     if (ParseMotionPath(jsVal, motionPathOption)) {
6869         ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
6870     } else {
6871         TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
6872         ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6873     }
6874 }
6875 
JsShadow(const JSCallbackInfo & info)6876 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
6877 {
6878     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
6879     auto jsVal = info[0];
6880     if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
6881         Shadow shadow;
6882         std::vector<Shadow> shadows { shadow };
6883         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6884         return;
6885     }
6886     Shadow shadow;
6887     if (!ParseShadowProps(jsVal, shadow)) {
6888         info.ReturnSelf();
6889         return;
6890     }
6891     std::vector<Shadow> shadows { shadow };
6892     ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6893 }
6894 
JsBlendMode(const JSCallbackInfo & info)6895 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
6896 {
6897     if (info.Length() == 0) {
6898         return;
6899     }
6900     BlendMode blendMode = BlendMode::NONE;
6901     BlendApplyType blendApplyType = BlendApplyType::FAST;
6902     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
6903     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
6904     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
6905     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
6906     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
6907     if (info[0]->IsNumber()) {
6908         auto blendModeNum = info[0]->ToNumber<int32_t>();
6909         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
6910             blendMode = static_cast<BlendMode>(blendModeNum);
6911         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
6912             // backward compatibility code, will remove soon
6913             blendMode = BlendMode::SRC_OVER;
6914             blendApplyType = BlendApplyType::OFFSCREEN;
6915         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
6916             // backward compatibility code, will remove soon
6917             blendMode = BlendMode::SRC_IN;
6918             blendApplyType = BlendApplyType::OFFSCREEN;
6919         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
6920             // backward compatibility code, will remove soon
6921             blendMode = BlendMode::DST_IN;
6922             blendApplyType = BlendApplyType::OFFSCREEN;
6923         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
6924             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
6925         }
6926     }
6927     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
6928         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
6929         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
6930             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
6931         }
6932     }
6933     ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
6934     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
6935 }
6936 
JsAdvancedBlendMode(const JSCallbackInfo & info)6937 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
6938 {
6939     if (info.Length() == 0) {
6940         return;
6941     }
6942     BlendMode blendMode = BlendMode::NONE;
6943     BlendApplyType blendApplyType = BlendApplyType::FAST;
6944     // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
6945     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
6946     constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
6947     constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
6948     constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
6949     if (info[0]->IsNumber()) {
6950         auto blendModeNum = info[0]->ToNumber<int32_t>();
6951         if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
6952             blendMode = static_cast<BlendMode>(blendModeNum);
6953         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
6954             // backward compatibility code, will remove soon
6955             blendMode = BlendMode::SRC_OVER;
6956             blendApplyType = BlendApplyType::OFFSCREEN;
6957         } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
6958             // backward compatibility code, will remove soon
6959             blendMode = BlendMode::SRC_IN;
6960             blendApplyType = BlendApplyType::OFFSCREEN;
6961         } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
6962             // backward compatibility code, will remove soon
6963             blendMode = BlendMode::DST_IN;
6964             blendApplyType = BlendApplyType::OFFSCREEN;
6965         } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
6966             blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
6967         }
6968     } else if (info[0]->IsObject()) {
6969         auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]);
6970         ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender);
6971     }
6972     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
6973         auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
6974         if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
6975             blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
6976         }
6977     }
6978     if (!info[0]->IsObject()) {
6979         ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
6980     }
6981     ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
6982 }
6983 
JsGrayScale(const JSCallbackInfo & info)6984 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
6985 {
6986     CalcDimension value;
6987     if (!ParseJsDimensionVp(info[0], value)) {
6988         value.SetValue(0.0);
6989         ViewAbstractModel::GetInstance()->SetGrayScale(value);
6990         return;
6991     }
6992 
6993     if (LessNotEqual(value.Value(), 0.0)) {
6994         value.SetValue(0.0);
6995     }
6996 
6997     if (GreatNotEqual(value.Value(), 1.0)) {
6998         value.SetValue(1.0);
6999     }
7000 
7001     ViewAbstractModel::GetInstance()->SetGrayScale(value);
7002 }
7003 
JsBrightness(const JSCallbackInfo & info)7004 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
7005 {
7006     CalcDimension value;
7007     if (!ParseJsDimensionVp(info[0], value)) {
7008         value.SetValue(1.0);
7009         ViewAbstractModel::GetInstance()->SetBrightness(value);
7010         return;
7011     }
7012 
7013     ViewAbstractModel::GetInstance()->SetBrightness(value);
7014 }
7015 
JsContrast(const JSCallbackInfo & info)7016 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
7017 {
7018     CalcDimension value;
7019     if (!ParseJsDimensionVp(info[0], value)) {
7020         value.SetValue(1.0);
7021         ViewAbstractModel::GetInstance()->SetContrast(value);
7022         return;
7023     }
7024 
7025     if (LessNotEqual(value.Value(), 0.0)) {
7026         value.SetValue(0.0);
7027     }
7028 
7029     ViewAbstractModel::GetInstance()->SetContrast(value);
7030 }
7031 
JsSaturate(const JSCallbackInfo & info)7032 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
7033 {
7034     CalcDimension value;
7035     if (!ParseJsDimensionVp(info[0], value)) {
7036         value.SetValue(1.0);
7037         ViewAbstractModel::GetInstance()->SetSaturate(value);
7038         return;
7039     }
7040 
7041     if (LessNotEqual(value.Value(), 0.0)) {
7042         value.SetValue(0.0);
7043     }
7044 
7045     ViewAbstractModel::GetInstance()->SetSaturate(value);
7046 }
7047 
JsSepia(const JSCallbackInfo & info)7048 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
7049 {
7050     CalcDimension value;
7051     if (!ParseJsDimensionVp(info[0], value)) {
7052         value.SetValue(0.0);
7053         ViewAbstractModel::GetInstance()->SetSepia(value);
7054         return;
7055     }
7056 
7057     if (LessNotEqual(value.Value(), 0.0)) {
7058         value.SetValue(0.0);
7059     }
7060 
7061     ViewAbstractModel::GetInstance()->SetSepia(value);
7062 }
7063 
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)7064 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
7065 {
7066     double invertValue = 0.0;
7067     if (ParseJsDouble(jsValue, invertValue)) {
7068         invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
7069         return true;
7070     }
7071     auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
7072     if (!argsPtrItem || argsPtrItem->IsNull()) {
7073         return false;
7074     }
7075     InvertOption option;
7076     double low = 0.0;
7077     if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
7078         option.low_ = std::clamp(low, 0.0, 1.0);
7079     }
7080     double high = 0.0;
7081     if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
7082         option.high_ = std::clamp(high, 0.0, 1.0);
7083     }
7084     double threshold = 0.0;
7085     if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
7086         option.threshold_ = std::clamp(threshold, 0.0, 1.0);
7087     }
7088     double thresholdRange = 0.0;
7089     if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
7090         option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
7091     }
7092     invert = option;
7093     return true;
7094 }
7095 
JsInvert(const JSCallbackInfo & info)7096 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
7097 {
7098     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
7099     InvertVariant invert = 0.0f;
7100     auto jsVal = info[0];
7101     if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
7102         ViewAbstractModel::GetInstance()->SetInvert(invert);
7103         return;
7104     }
7105     if (ParseInvertProps(jsVal, invert)) {
7106         ViewAbstractModel::GetInstance()->SetInvert(invert);
7107     }
7108     ViewAbstractModel::GetInstance()->SetInvert(invert);
7109 }
7110 
JsSystemBarEffect(const JSCallbackInfo & info)7111 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
7112 {
7113     ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
7114 }
7115 
JsHueRotate(const JSCallbackInfo & info)7116 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
7117 {
7118     std::optional<float> degree;
7119     JSRef<JSVal> arg = info[0];
7120     if (arg->IsString()) {
7121         degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
7122     } else if (arg->IsNumber()) {
7123         degree = static_cast<float>(arg->ToNumber<int32_t>());
7124     } else {
7125         ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
7126         return;
7127     }
7128     float deg = 0.0f;
7129     if (degree) {
7130         deg = degree.value();
7131         degree.reset();
7132     }
7133     deg = std::fmod(deg, ROUND_UNIT);
7134     if (deg < 0.0f) {
7135         deg += ROUND_UNIT;
7136     }
7137     ViewAbstractModel::GetInstance()->SetHueRotate(deg);
7138 }
7139 
JsClip(const JSCallbackInfo & info)7140 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
7141 {
7142     JSRef<JSVal> arg = info[0];
7143     if (arg->IsUndefined()) {
7144         ViewAbstractModel::GetInstance()->SetClipEdge(false);
7145         return;
7146     }
7147     if (arg->IsObject()) {
7148         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7149         if (clipShape == nullptr) {
7150             return;
7151         }
7152         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7153     } else if (arg->IsBoolean()) {
7154         ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
7155     }
7156 }
7157 
JsClipShape(const JSCallbackInfo & info)7158 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
7159 {
7160     if (info[0]->IsObject()) {
7161         JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7162         if (clipShape == nullptr) {
7163             return;
7164         }
7165         ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7166     }
7167 }
7168 
JsMask(const JSCallbackInfo & info)7169 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
7170 {
7171     JSRef<JSVal> arg = info[0];
7172     if (!arg->IsObject()) {
7173         ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
7174         return;
7175     }
7176     auto paramObject = JSRef<JSObject>::Cast(arg);
7177     JSRef<JSVal> typeParam = paramObject->GetProperty("type");
7178     if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
7179         typeParam->ToString() == "ProgressMask") {
7180         auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
7181         JSRef<JSVal> jValue = paramObject->GetProperty("value");
7182         auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
7183         if (value < 0.0f) {
7184             value = 0.0f;
7185         }
7186         progressMask->SetValue(value);
7187         JSRef<JSVal> jTotal = paramObject->GetProperty("total");
7188         auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
7189         if (total < 0.0f) {
7190             total = DEFAULT_PROGRESS_TOTAL;
7191         }
7192         progressMask->SetMaxValue(total);
7193         JSRef<JSVal> jColor = paramObject->GetProperty("color");
7194         Color colorVal;
7195         if (ParseJsColor(jColor, colorVal)) {
7196             progressMask->SetColor(colorVal);
7197         } else {
7198             RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
7199             progressMask->SetColor(theme->GetMaskColor());
7200         }
7201         JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
7202         if (jEnableBreathe->IsBoolean()) {
7203             progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
7204         }
7205         ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
7206     } else {
7207         JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7208         if (maskShape == nullptr) {
7209             return;
7210         };
7211         ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7212     }
7213 }
7214 
JsMaskShape(const JSCallbackInfo & info)7215 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
7216 {
7217     if (!info[0]->IsObject()) {
7218         return;
7219     }
7220 
7221     JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7222     if (maskShape == nullptr) {
7223         return;
7224     };
7225     ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7226 }
7227 
JsFocusable(const JSCallbackInfo & info)7228 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
7229 {
7230     if (!info[0]->IsBoolean()) {
7231         return;
7232     }
7233     ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
7234 }
7235 
JsFocusBox(const JSCallbackInfo & info)7236 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
7237 {
7238     if (!info[0]->IsObject() || info.Length() != 1) {
7239         return;
7240     }
7241     auto obj = JSRef<JSObject>::Cast(info[0]);
7242     NG::FocusBoxStyle style;
7243 
7244     CalcDimension margin;
7245     if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) {
7246         style.margin = margin;
7247     }
7248     CalcDimension strokeWidth;
7249     if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) {
7250         style.strokeWidth = strokeWidth;
7251     }
7252     Color strokeColor;
7253     if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) {
7254         style.strokeColor = strokeColor;
7255     }
7256 
7257     ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
7258 }
7259 
JsOnFocusMove(const JSCallbackInfo & args)7260 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
7261 {
7262     JSRef<JSVal> arg = args[0];
7263     if (arg->IsFunction()) {
7264         RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7265         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7266         auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
7267                                int info) {
7268             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7269             ACE_SCORING_EVENT("onFocusMove");
7270             PipelineContext::SetCallBackNode(node);
7271             func->Execute(info);
7272         };
7273         ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
7274     }
7275 }
7276 
JsOnKeyEvent(const JSCallbackInfo & args)7277 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
7278 {
7279     JSRef<JSVal> arg = args[0];
7280     if (arg->IsUndefined() && IsDisableEventVersion()) {
7281         ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
7282         return;
7283     }
7284     if (!arg->IsFunction()) {
7285         return;
7286     }
7287     RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
7288     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7289     auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
7290                           KeyEventInfo& info) {
7291         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7292         ACE_SCORING_EVENT("onKey");
7293         PipelineContext::SetCallBackNode(node);
7294         func->Execute(info);
7295     };
7296     ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
7297 }
7298 
JsOnFocus(const JSCallbackInfo & args)7299 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
7300 {
7301     JSRef<JSVal> arg = args[0];
7302     if (arg->IsUndefined() && IsDisableEventVersion()) {
7303         ViewAbstractModel::GetInstance()->DisableOnFocus();
7304         return;
7305     }
7306     if (!arg->IsFunction()) {
7307         return;
7308     }
7309     RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7310     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7311     auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
7312         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7313         ACE_SCORING_EVENT("onFocus");
7314         PipelineContext::SetCallBackNode(node);
7315         func->Execute();
7316     };
7317 
7318     ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
7319 }
7320 
JsOnBlur(const JSCallbackInfo & args)7321 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
7322 {
7323     JSRef<JSVal> arg = args[0];
7324     if (arg->IsUndefined() && IsDisableEventVersion()) {
7325         ViewAbstractModel::GetInstance()->DisableOnBlur();
7326         return;
7327     }
7328     if (!arg->IsFunction()) {
7329         return;
7330     }
7331     RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7332     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7333     auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
7334         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7335         ACE_SCORING_EVENT("onBlur");
7336         PipelineContext::SetCallBackNode(node);
7337         func->Execute();
7338     };
7339 
7340     ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
7341 }
7342 
JsTabIndex(const JSCallbackInfo & info)7343 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
7344 {
7345     JSRef<JSVal> arg = info[0];
7346     if (!arg->IsNumber()) {
7347         return;
7348     }
7349     ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
7350 }
7351 
JsFocusOnTouch(const JSCallbackInfo & info)7352 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
7353 {
7354     JSRef<JSVal> arg = info[0];
7355     if (!arg->IsBoolean()) {
7356         return;
7357     }
7358     auto isFocusOnTouch = arg->ToBoolean();
7359     ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
7360 }
7361 
JsDefaultFocus(const JSCallbackInfo & info)7362 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
7363 {
7364     JSRef<JSVal> arg = info[0];
7365     if (!arg->IsBoolean()) {
7366         return;
7367     }
7368     auto isDefaultFocus = arg->ToBoolean();
7369     ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
7370 }
7371 
JsGroupDefaultFocus(const JSCallbackInfo & info)7372 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
7373 {
7374     JSRef<JSVal> arg = info[0];
7375     if (!arg->IsBoolean()) {
7376         return;
7377     }
7378     auto isGroupDefaultFocus = arg->ToBoolean();
7379     ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
7380 }
7381 
JsKey(const std::string & key)7382 void JSViewAbstract::JsKey(const std::string& key)
7383 {
7384     ViewAbstractModel::GetInstance()->SetInspectorId(key);
7385 }
7386 
JsId(const JSCallbackInfo & info)7387 void JSViewAbstract::JsId(const JSCallbackInfo& info)
7388 {
7389     JSRef<JSVal> arg = info[0];
7390     if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
7391         return;
7392     }
7393     std::string id = arg->ToString();
7394     if (id.empty()) {
7395         return;
7396     }
7397     JsKey(id);
7398 }
7399 
JsRestoreId(int32_t restoreId)7400 void JSViewAbstract::JsRestoreId(int32_t restoreId)
7401 {
7402     ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
7403 }
7404 
JsDebugLine(const JSCallbackInfo & info)7405 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
7406 {
7407     std::string debugLine;
7408     auto length = info.Length();
7409     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
7410 
7411     if (length == 1) { // deprecated version of debug line
7412         auto jsVal = info[0];
7413         if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
7414             return;
7415         }
7416         debugLine = jsVal->ToString();
7417     } else if (length == 2) { // debug line with extra package name
7418         auto line = info[0];
7419         auto packageName = info[1];
7420         if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
7421             !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
7422             return;
7423         }
7424         auto json = JsonUtil::Create(true);
7425         json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
7426         json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
7427         debugLine = json->ToString();
7428     }
7429 
7430     ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
7431 }
7432 
JsOpacityPassThrough(const JSCallbackInfo & info)7433 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
7434 {
7435     double opacity = 1.0;
7436     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7437         if (ParseJsDouble(info[0], opacity)) {
7438             opacity = std::clamp(opacity, 0.0, 1.0);
7439         }
7440     } else {
7441         if (!ParseJsDouble(info[0], opacity)) {
7442             return;
7443         }
7444         if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
7445             opacity = 1.0;
7446         }
7447     }
7448 
7449     ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
7450 }
7451 
JsTransitionPassThrough(const JSCallbackInfo & info)7452 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
7453 {
7454     if (info.Length() == 0) {
7455         ViewAbstractModel::GetInstance()->SetTransition(
7456             NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
7457         return;
7458     }
7459     if (!info[0]->IsObject()) {
7460         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7461             ViewAbstractModel::GetInstance()->CleanTransition();
7462             ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
7463         }
7464         return;
7465     }
7466     auto obj = JSRef<JSObject>::Cast(info[0]);
7467     if (!obj->GetProperty("successor_")->IsUndefined()) {
7468         auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
7469         std::function<void(bool)> finishCallback;
7470         if (info.Length() > 1 && info[1]->IsFunction()) {
7471             finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
7472         }
7473         ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
7474         return;
7475     }
7476     auto options = ParseJsTransition(obj);
7477     ViewAbstractModel::GetInstance()->SetTransition(options, true);
7478 }
7479 
JsAccessibilityGroup(bool accessible)7480 void JSViewAbstract::JsAccessibilityGroup(bool accessible)
7481 {
7482     ViewAbstractModel::GetInstance()->SetAccessibilityGroup(accessible);
7483 }
7484 
JsAccessibilityText(const JSCallbackInfo & info)7485 void JSViewAbstract::JsAccessibilityText(const JSCallbackInfo& info)
7486 {
7487     const JSRef<JSVal>& jsValue = info[0];
7488     std::string text;
7489     if (!ParseJsString(jsValue, text)) {
7490         return;
7491     }
7492     ViewAbstractModel::GetInstance()->SetAccessibilityText(text);
7493 }
7494 
JsAccessibilityTextHint(const std::string & text)7495 void JSViewAbstract::JsAccessibilityTextHint(const std::string& text)
7496 {
7497     ViewAbstractModel::GetInstance()->SetAccessibilityTextHint(text);
7498 }
7499 
JsAccessibilityDescription(const JSCallbackInfo & info)7500 void JSViewAbstract::JsAccessibilityDescription(const JSCallbackInfo& info)
7501 {
7502     const JSRef<JSVal>& jsValue = info[0];
7503     std::string description;
7504     if (!ParseJsString(jsValue, description)) {
7505         return;
7506     }
7507     std::pair<bool, std::string> autoEventPair(false, "");
7508     std::pair<bool, std::string> descriptionPair(false, "");
7509     ParseAccessibilityDescriptionJson(description, autoEventPair, descriptionPair);
7510     if (descriptionPair.first) {
7511         ViewAbstractModel::GetInstance()->SetAccessibilityDescription(descriptionPair.second);
7512     } else {
7513         ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description);
7514     }
7515     if (autoEventPair.first) {
7516         ViewAbstractModel::GetInstance()->SetAutoEventParam(autoEventPair.second);
7517     }
7518 }
7519 
ParseAccessibilityDescriptionJson(const std::string & description,std::pair<bool,std::string> & autoEventPair,std::pair<bool,std::string> & descriptionPair)7520 void JSViewAbstract::ParseAccessibilityDescriptionJson(const std::string& description,
7521     std::pair<bool, std::string>& autoEventPair, std::pair<bool, std::string>& descriptionPair)
7522 {
7523     if (description.empty()) {
7524         return;
7525     }
7526     if (!StartWith(description, "{") || !EndWith(description, "}")) {
7527         return;
7528     }
7529     auto jsonObj = JsonUtil::ParseJsonString(description);
7530     if (!jsonObj || !jsonObj->IsValid() || !jsonObj->IsObject()) {
7531         return;
7532     }
7533     if (jsonObj->Contains("$autoEventParam")) {
7534         auto param = jsonObj->GetValue("$autoEventParam");
7535         if (param) {
7536             autoEventPair = std::make_pair(true, param->ToString());
7537         }
7538     }
7539     if (jsonObj->Contains("$accessibilityDescription")) {
7540         descriptionPair = std::make_pair(true, jsonObj->GetString("$accessibilityDescription"));
7541     } else if (jsonObj->Contains("$autoEventParam")) {
7542         descriptionPair = std::make_pair(true, "");
7543     }
7544 }
7545 
JsAccessibilityImportance(const std::string & importance)7546 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
7547 {
7548     ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance);
7549 }
7550 
JsAccessibilityLevel(const std::string & level)7551 void JSViewAbstract::JsAccessibilityLevel(const std::string& level)
7552 {
7553     ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level);
7554 }
7555 
JsAccessibilityVirtualNode(const JSCallbackInfo & info)7556 void JSViewAbstract::JsAccessibilityVirtualNode(const JSCallbackInfo& info)
7557 {
7558     // parse builder
7559     if (!info[0]->IsObject()) {
7560         return;
7561     }
7562     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7563     auto builder = obj->GetProperty("builder");
7564     if (builder->IsFunction()) {
7565         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7566         CHECK_NULL_VOID(builderFunc);
7567         auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
7568             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7569             ACE_SCORING_EVENT("AccessibilityVirtualNode");
7570             func->Execute();
7571         };
7572         NG::ViewAbstractModelNG::GetInstance()->SetAccessibilityVirtualNode(std::move(buildFunc));
7573     }
7574 }
7575 
JsAccessibilitySelected(const JSCallbackInfo & info)7576 void JSViewAbstract::JsAccessibilitySelected(const JSCallbackInfo& info)
7577 {
7578     bool selected = false;
7579     bool resetValue = false;
7580     JSRef<JSVal> arg = info[0];
7581     if (arg->IsUndefined()) {
7582         resetValue = true;
7583     } else if (arg->IsBoolean()) {
7584         selected = arg->ToBoolean();
7585     } else {
7586         return;
7587     }
7588 
7589     ViewAbstractModel::GetInstance()->SetAccessibilitySelected(selected, resetValue);
7590 }
7591 
JsAccessibilityChecked(const JSCallbackInfo & info)7592 void JSViewAbstract::JsAccessibilityChecked(const JSCallbackInfo& info)
7593 {
7594     bool checked = false;
7595     bool resetValue = false;
7596     JSRef<JSVal> arg = info[0];
7597     if (arg->IsUndefined()) {
7598         resetValue = true;
7599     } else if (arg->IsBoolean()) {
7600         checked = arg->ToBoolean();
7601     } else {
7602         return;
7603     }
7604 
7605     ViewAbstractModel::GetInstance()->SetAccessibilityChecked(checked, resetValue);
7606 }
7607 
JsBackground(const JSCallbackInfo & info)7608 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
7609 {
7610     // Check the parameters
7611     if (info.Length() <= 0 || !info[0]->IsObject()) {
7612         return;
7613     }
7614     JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
7615     auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
7616     if (!builder->IsFunction()) {
7617         return;
7618     }
7619     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7620     CHECK_NULL_VOID(builderFunc);
7621     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7622     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7623         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7624         ACE_SCORING_EVENT("BindBackground");
7625         PipelineContext::SetCallBackNode(node);
7626         func->Execute();
7627     };
7628     Alignment alignment = Alignment::CENTER;
7629     if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
7630         JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
7631         auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
7632         auto value = align->ToNumber<int32_t>();
7633         alignment = ParseAlignment(value);
7634     }
7635     ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
7636 }
7637 
JsBindContextMenu(const JSCallbackInfo & info)7638 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
7639 {
7640     NG::MenuParam menuParam;
7641     // Check the parameters
7642     if (info.Length() <= 0) {
7643         return;
7644     }
7645     size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
7646     if (!info[builderIndex]->IsObject()) {
7647         return;
7648     }
7649 
7650     JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
7651     auto builder = menuObj->GetProperty("builder");
7652     if (!builder->IsFunction()) {
7653         return;
7654     }
7655     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7656     CHECK_NULL_VOID(builderFunc);
7657 
7658     ResponseType responseType = ResponseType::LONG_PRESS;
7659     if (!info[0]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7660         auto response = info[1]->ToNumber<int32_t>();
7661         responseType = static_cast<ResponseType>(response);
7662     }
7663     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7664     std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
7665                                           node = frameNode]() {
7666         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7667         ACE_SCORING_EVENT("BuildContextMenu");
7668         PipelineContext::SetCallBackNode(node);
7669         func->Execute();
7670     };
7671 
7672     menuParam.previewMode = MenuPreviewMode::NONE;
7673     std::function<void()> previewBuildFunc = nullptr;
7674     if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) {
7675         ParseBindContentOptionParam(info, info[2], menuParam, previewBuildFunc);
7676     }
7677 
7678     if (responseType != ResponseType::LONG_PRESS) {
7679         menuParam.previewMode = MenuPreviewMode::NONE;
7680         menuParam.isShowHoverImage = false;
7681         menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
7682     }
7683     menuParam.type = NG::MenuType::CONTEXT_MENU;
7684     ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
7685     ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
7686 }
7687 
ParseBindContentCoverIsShow(const JSCallbackInfo & info)7688 bool ParseBindContentCoverIsShow(const JSCallbackInfo& info)
7689 {
7690     bool isShow = false;
7691     if (info[0]->IsBoolean()) {
7692         isShow = info[0]->ToBoolean();
7693     } else if (info[0]->IsObject()) {
7694         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7695         auto isShowObj = callbackObj->GetProperty("value");
7696         isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7697     }
7698     TAG_LOGD(AceLogTag::ACE_SHEET, "ContentCover get isShow is: %{public}d", isShow);
7699     return isShow;
7700 }
7701 
JsBindContentCover(const JSCallbackInfo & info)7702 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
7703 {
7704     // parse isShow
7705     bool isShow = ParseBindContentCoverIsShow(info);
7706     DoubleBindCallback callback = nullptr;
7707     if (info[0]->IsObject()) {
7708         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7709         callback = ParseDoubleBindCallback(info, callbackObj);
7710     }
7711 
7712     // parse builder
7713     if (!info[1]->IsObject()) {
7714         return;
7715     }
7716     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7717     auto builder = obj->GetProperty("builder");
7718     if (!builder->IsFunction()) {
7719         return;
7720     }
7721     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7722     CHECK_NULL_VOID(builderFunc);
7723     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7724     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7725         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7726         ACE_SCORING_EVENT("BindContentCover");
7727         PipelineContext::SetCallBackNode(node);
7728         func->Execute();
7729     };
7730 
7731     // parse ModalTransition
7732     NG::ModalStyle modalStyle;
7733     modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
7734     std::function<void()> onShowCallback;
7735     std::function<void()> onDismissCallback;
7736     std::function<void()> onWillShowCallback;
7737     std::function<void()> onWillDismissCallback;
7738     NG::ContentCoverParam contentCoverParam;
7739     std::function<void(const int32_t&)> onWillDismissFunc;
7740     if (info.Length() == 3) {
7741         if (info[2]->IsObject()) {
7742             ParseOverlayCallback(info[2], onShowCallback, onDismissCallback, onWillShowCallback, /* 2:args index */
7743                 onWillDismissCallback, onWillDismissFunc);
7744             ParseModalStyle(info[2], modalStyle);
7745             contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
7746             ParseModalTransitonEffect(info[2], contentCoverParam, info.GetExecutionContext()); /* 2:args index */
7747         } else if (info[2]->IsNumber()) {
7748             auto transitionNumber = info[2]->ToNumber<int32_t>();
7749             if (transitionNumber >= 0 && transitionNumber <= 2) {
7750                 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7751             }
7752         }
7753     }
7754     ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
7755         std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
7756         std::move(onWillDismissCallback), contentCoverParam);
7757 }
7758 
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)7759 void JSViewAbstract::ParseModalTransitonEffect(
7760     const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
7761 {
7762     auto transitionEffectValue = paramObj->GetProperty("transition");
7763     if (transitionEffectValue->IsObject()) {
7764         JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
7765         contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
7766     }
7767 }
7768 
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)7769 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
7770 {
7771     auto modalTransition = paramObj->GetProperty("modalTransition");
7772     auto backgroundColor = paramObj->GetProperty("backgroundColor");
7773     if (modalTransition->IsNumber()) {
7774         auto transitionNumber = modalTransition->ToNumber<int32_t>();
7775         if (transitionNumber >= 0 && transitionNumber <= 2) {
7776             modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7777         }
7778     }
7779     Color color;
7780     if (ParseJsColor(backgroundColor, color)) {
7781         modalStyle.backgroundColor = color;
7782     }
7783 }
7784 
ParseSheetIsShow(const JSCallbackInfo & info,bool & isShow,std::function<void (const std::string &)> & callback)7785 void JSViewAbstract::ParseSheetIsShow(
7786     const JSCallbackInfo& info, bool& isShow, std::function<void(const std::string&)>& callback)
7787 {
7788     if (info[0]->IsBoolean()) {
7789         isShow = info[0]->ToBoolean();
7790     } else if (info[0]->IsObject()) {
7791         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7792         callback = ParseDoubleBindCallback(info, callbackObj);
7793         auto isShowObj = callbackObj->GetProperty("value");
7794         isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7795     }
7796     TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet get isShow is: %{public}d", isShow);
7797 }
7798 
JsBindSheet(const JSCallbackInfo & info)7799 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
7800 {
7801     // parse isShow and builder
7802     bool isShow = false;
7803     DoubleBindCallback callback = nullptr;
7804     ParseSheetIsShow(info, isShow, callback);
7805     if (!info[1]->IsObject())
7806         return;
7807     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7808     auto builder = obj->GetProperty("builder");
7809     if (!builder->IsFunction())
7810         return;
7811     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7812     CHECK_NULL_VOID(builderFunc);
7813     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7814     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7815         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7816         ACE_SCORING_EVENT("BindSheet");
7817         PipelineContext::SetCallBackNode(node);
7818         func->Execute();
7819     };
7820     // parse SheetStyle and callbacks
7821     NG::SheetStyle sheetStyle;
7822     sheetStyle.sheetMode = NG::SheetMode::LARGE;
7823     sheetStyle.showDragBar = true;
7824     sheetStyle.showCloseIcon = true;
7825     sheetStyle.showInPage = false;
7826     std::function<void()> onAppearCallback;
7827     std::function<void()> onDisappearCallback;
7828     std::function<void()> onWillAppearCallback;
7829     std::function<void()> onWillDisappearCallback  ;
7830     std::function<void()> shouldDismissFunc;
7831     std::function<void(const int32_t)> onWillDismissCallback;
7832     std::function<void(const float)> onHeightDidChangeCallback;
7833     std::function<void(const float)> onDetentsDidChangeCallback;
7834     std::function<void(const float)> onWidthDidChangeCallback;
7835     std::function<void(const float)> onTypeDidChangeCallback;
7836     std::function<void()> titleBuilderFunction;
7837     std::function<void()> sheetSpringBackFunc;
7838     if (info.Length() == PARAMETER_LENGTH_THIRD && info[SECOND_INDEX]->IsObject()) {
7839         ParseSheetCallback(info[SECOND_INDEX], onAppearCallback, onDisappearCallback, shouldDismissFunc,
7840             onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
7841             onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
7842         ParseSheetStyle(info[2], sheetStyle);
7843         ParseSheetTitle(info[2], sheetStyle, titleBuilderFunction);
7844     }
7845     ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
7846         std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
7847         std::move(shouldDismissFunc), std::move(onWillDismissCallback),  std::move(onWillAppearCallback),
7848         std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
7849         std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
7850 }
7851 
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)7852 void JSViewAbstract::ParseSheetStyle(
7853     const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
7854 {
7855     auto height = paramObj->GetProperty("height");
7856     auto showDragBar = paramObj->GetProperty("dragBar");
7857     auto backgroundColor = paramObj->GetProperty("backgroundColor");
7858     auto maskColor = paramObj->GetProperty("maskColor");
7859     auto sheetDetents = paramObj->GetProperty("detents");
7860     auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
7861     auto showCloseIcon = paramObj->GetProperty("showClose");
7862     auto type = paramObj->GetProperty("preferType");
7863     auto interactive = paramObj->GetProperty("enableOutsideInteractive");
7864     auto showMode = paramObj->GetProperty("mode");
7865     auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
7866     auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
7867     auto uiContextObj = paramObj->GetProperty("uiContext");
7868     if (uiContextObj->IsObject()) {
7869         JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
7870         auto prop = obj->GetProperty("instanceId_");
7871         if (prop->IsNumber()) {
7872             sheetStyle.instanceId = prop->ToNumber<int32_t>();
7873         }
7874     }
7875     NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
7876     if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
7877         sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
7878     }
7879 
7880     std::vector<NG::SheetHeight> detents;
7881     if (ParseSheetDetents(sheetDetents, detents)) {
7882         sheetStyle.detents = detents;
7883     }
7884     BlurStyleOption styleOption;
7885     if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
7886         sheetStyle.backgroundBlurStyle = styleOption;
7887     }
7888     bool showClose = true;
7889     if (ParseJsBool(showCloseIcon, showClose)) {
7890         sheetStyle.showCloseIcon = showClose;
7891     } else if (!isPartialUpdate) {
7892         sheetStyle.showCloseIcon = true;
7893     }
7894 
7895     bool isInteractive = false;
7896     if (ParseJsBool(interactive, isInteractive)) {
7897         sheetStyle.interactive = isInteractive;
7898     }
7899 
7900     if (showDragBar->IsBoolean()) {
7901         sheetStyle.showDragBar = showDragBar->ToBoolean();
7902     } else if (isPartialUpdate) {
7903         sheetStyle.showDragBar.reset();
7904     } else {
7905         sheetStyle.showDragBar = true;
7906     }
7907 
7908     if (type->IsNull() || type->IsUndefined()) {
7909         sheetStyle.sheetType.reset();
7910     } else {
7911         if (type->IsNumber()) {
7912             auto sheetType = type->ToNumber<int32_t>();
7913             if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
7914                 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
7915                 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
7916             }
7917         }
7918     }
7919     if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
7920         sheetStyle.scrollSizeMode.reset();
7921     } else if (scrollSizeMode->IsNumber()) {
7922         auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
7923         if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
7924             sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
7925             sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
7926         }
7927     }
7928 
7929     if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
7930         sheetStyle.sheetKeyboardAvoidMode.reset();
7931     } else if (keyboardAvoidMode->IsNumber()) {
7932         auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
7933         if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
7934             sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) {
7935             sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
7936         }
7937     }
7938 
7939     Color color;
7940     if (ParseJsColor(backgroundColor, color)) {
7941         sheetStyle.backgroundColor = color;
7942     }
7943     // parse maskColor
7944     Color parseMaskColor;
7945     if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
7946         sheetStyle.maskColor = std::move(parseMaskColor);
7947     }
7948 
7949     // Parse border width
7950     auto borderWidthValue = paramObj->GetProperty("borderWidth");
7951     NG::BorderWidthProperty borderWidth;
7952     if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
7953         sheetStyle.borderWidth = borderWidth;
7954         // Parse border color
7955         auto colorValue = paramObj->GetProperty("borderColor");
7956         NG::BorderColorProperty borderColor;
7957         if (ParseBorderColorProps(colorValue, borderColor)) {
7958             sheetStyle.borderColor = borderColor;
7959         } else {
7960             sheetStyle.borderColor =
7961                 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
7962         }
7963         // Parse border style
7964         auto styleValue = paramObj->GetProperty("borderStyle");
7965         NG::BorderStyleProperty borderStyle;
7966         if (ParseBorderStyleProps(styleValue, borderStyle)) {
7967             sheetStyle.borderStyle = borderStyle;
7968         } else {
7969             sheetStyle.borderStyle = NG::BorderStyleProperty(
7970                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
7971         }
7972     }
7973     if (isPartialUpdate) {
7974         auto colorValue = paramObj->GetProperty("borderColor");
7975         NG::BorderColorProperty borderColor;
7976         if (ParseBorderColorProps(colorValue, borderColor)) {
7977             sheetStyle.borderColor = borderColor;
7978         } else {
7979             sheetStyle.borderColor.reset();
7980         }
7981         auto styleValue = paramObj->GetProperty("borderStyle");
7982         NG::BorderStyleProperty borderStyle;
7983         if (ParseBorderStyleProps(styleValue, borderStyle)) {
7984             sheetStyle.borderStyle = borderStyle;
7985         } else {
7986             sheetStyle.borderStyle.reset();
7987         }
7988     }
7989 
7990     // Parse shadow
7991     Shadow shadow;
7992     auto shadowValue = paramObj->GetProperty("shadow");
7993     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
7994         sheetStyle.shadow = shadow;
7995     }
7996 
7997     auto widthValue = paramObj->GetProperty("width");
7998     CalcDimension width;
7999     if (ParseJsDimensionVpNG(widthValue, width, true)) {
8000         sheetStyle.width = width;
8001     }
8002 
8003     CalcDimension sheetHeight;
8004     if (height->IsString()) {
8005         std::string heightStr = height->ToString();
8006         // Remove all " ".
8007         heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8008         std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8009         if (heightStr == SHEET_HEIGHT_MEDIUM) {
8010             sheetStyle.sheetMode = NG::SheetMode::MEDIUM;
8011             sheetStyle.height.reset();
8012             return;
8013         }
8014         if (heightStr == SHEET_HEIGHT_LARGE) {
8015             sheetStyle.sheetMode = NG::SheetMode::LARGE;
8016             sheetStyle.height.reset();
8017             return;
8018         }
8019         if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8020             sheetStyle.sheetMode = NG::SheetMode::AUTO;
8021             sheetStyle.height.reset();
8022             return;
8023         }
8024         if (heightStr.find("calc") != std::string::npos) {
8025             sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8026         } else {
8027             sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8028         }
8029         if (sheetHeight.Value() < 0) {
8030             sheetStyle.sheetMode = NG::SheetMode::LARGE;
8031             sheetStyle.height.reset();
8032             return;
8033         }
8034     }
8035     if (!ParseJsDimensionVpNG(height, sheetHeight)) {
8036         if (isPartialUpdate) {
8037             sheetStyle.sheetMode.reset();
8038         } else {
8039             sheetStyle.sheetMode = NG::SheetMode::LARGE;
8040         }
8041         sheetStyle.height.reset();
8042     } else {
8043         sheetStyle.height = sheetHeight;
8044         sheetStyle.sheetMode.reset();
8045     }
8046 }
8047 
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)8048 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
8049 {
8050     if (!args->IsArray()) {
8051         return false;
8052     }
8053     JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
8054     NG::SheetHeight sheetDetent;
8055     for (size_t i = 0; i < array->Length(); i++) {
8056         ParseSheetDetentHeight(array->GetValueAt(i), sheetDetent);
8057         if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
8058             continue;
8059         }
8060         sheetDetents.emplace_back(sheetDetent);
8061         sheetDetent.height.reset();
8062         sheetDetent.sheetMode.reset();
8063     }
8064     return true;
8065 }
8066 
ParseSheetDetentHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent)8067 void JSViewAbstract::ParseSheetDetentHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent)
8068 {
8069     CalcDimension sheetHeight;
8070     if (args->IsString()) {
8071         std::string heightStr = args->ToString();
8072         // Remove all " ".
8073         heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8074         std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8075         if (heightStr == SHEET_HEIGHT_MEDIUM) {
8076             detent.sheetMode = NG::SheetMode::MEDIUM;
8077             detent.height.reset();
8078             return;
8079         }
8080         if (heightStr == SHEET_HEIGHT_LARGE) {
8081             detent.sheetMode = NG::SheetMode::LARGE;
8082             detent.height.reset();
8083             return;
8084         }
8085         if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8086             detent.sheetMode = NG::SheetMode::AUTO;
8087             detent.height.reset();
8088             return;
8089         }
8090         if (heightStr.find("calc") != std::string::npos) {
8091             sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8092         } else {
8093             sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8094         }
8095         if (sheetHeight.Value() < 0) {
8096             detent.sheetMode = NG::SheetMode::LARGE;
8097             detent.height.reset();
8098             return;
8099         }
8100     }
8101     if (!ParseJsDimensionVpNG(args, sheetHeight)) {
8102         detent.sheetMode = NG::SheetMode::LARGE;
8103         detent.height.reset();
8104     } else {
8105         detent.height = sheetHeight;
8106         detent.sheetMode.reset();
8107     }
8108 }
8109 
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)8110 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
8111 {
8112     if (args->IsNumber()) {
8113         auto sheetBlurStyle = args->ToNumber<int32_t>();
8114         if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
8115             sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
8116             blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
8117         } else {
8118             return false;
8119         }
8120     } else {
8121         return false;
8122     }
8123     return true;
8124 }
8125 
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)8126 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
8127 {
8128     if (!args->IsNumber()) {
8129         return false;
8130     }
8131     auto sheetMode = args->ToNumber<int32_t>();
8132     if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
8133         sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
8134         sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
8135         return true;
8136     }
8137     return false;
8138 }
8139 
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)8140 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
8141     std::function<void(const float)>& callbackDidChange, const char* prop)
8142 {
8143     auto callBack = paramObj->GetProperty(prop);
8144     if (callBack->IsFunction()) {
8145         RefPtr<JsFunction> jsFunc =
8146             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
8147         callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
8148             JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
8149             func->ExecuteJS(1, &param);
8150         };
8151     }
8152 }
8153 
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)8154 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
8155     std::function<void()>& lifeCycleCallBack, const char* prop)
8156 {
8157     auto callback = paramObj->GetProperty(prop);
8158     if (callback->IsFunction()) {
8159         RefPtr<JsFunction> jsFunc =
8160             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8161         lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
8162     }
8163 }
8164 
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)8165 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
8166     std::function<void()>& sheetSpringBack, const char* prop)
8167 {
8168     auto sheetSpringBackCallback = paramObj->GetProperty(prop);
8169     if (sheetSpringBackCallback->IsFunction()) {
8170         RefPtr<JsFunction> jsFunc =
8171             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
8172         sheetSpringBack = [func = std::move(jsFunc)]() {
8173             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8174             objectTemplate->SetInternalFieldCount(1);
8175             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8176             dismissObj->SetPropertyObject(
8177                 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
8178             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8179             func->ExecuteJS(1, &newJSVal);
8180         };
8181     }
8182 }
8183 
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)8184 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8185     std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
8186     std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
8187     std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
8188     std::function<void(const float)>& onDetentsDidChange,
8189     std::function<void(const float)>& onWidthDidChange,
8190     std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
8191 {
8192     auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
8193     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8194     ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
8195     ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
8196     ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
8197     ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
8198     if (shouldDismissFunc->IsFunction()) {
8199         RefPtr<JsFunction> jsFunc =
8200             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
8201         shouldDismiss = [func = std::move(jsFunc)]() {
8202             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8203             objectTemplate->SetInternalFieldCount(1);
8204             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8205             dismissObj->SetPropertyObject(
8206                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8207             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8208             func->ExecuteJS(1, &newJSVal);
8209         };
8210     }
8211     if (onWillDismissFunc->IsFunction()) {
8212         RefPtr<JsFunction> jsFunc =
8213             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8214         onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
8215             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8216             objectTemplate->SetInternalFieldCount(1);
8217             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8218             dismissObj->SetPropertyObject(
8219                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8220             dismissObj->SetProperty<int32_t>("reason", info);
8221             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8222             func->ExecuteJS(1, &newJSVal);
8223         };
8224     }
8225     ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
8226     ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
8227     ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
8228     ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
8229     ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
8230 }
8231 
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)8232 void JSViewAbstract::ParseSheetTitle(
8233     const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
8234 {
8235     auto title = paramObj->GetProperty("title");
8236     std::string mainTitle;
8237     std::string subtitle;
8238     if (title->IsFunction()) {
8239         sheetStyle.isTitleBuilder = true;
8240         auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
8241         CHECK_NULL_VOID(titleBuilderFunc);
8242         titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
8243             ACE_SCORING_EVENT("BindSheet");
8244             func->Execute();
8245         };
8246     } else if (title->IsObject()) {
8247         JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
8248         sheetStyle.isTitleBuilder = false;
8249         auto sheetTitle = obj->GetProperty("title");
8250         auto sheetSubtitle = obj->GetProperty("subtitle");
8251         if (ParseJsString(sheetTitle, mainTitle)) {
8252             sheetStyle.sheetTitle = mainTitle;
8253         }
8254         if (ParseJsString(sheetSubtitle, subtitle)) {
8255             sheetStyle.sheetSubtitle = subtitle;
8256         }
8257     }
8258 }
8259 
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)8260 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8261 {
8262     ViewAbstractModel::GetInstance()->DismissSheet();
8263     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8264 }
8265 
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)8266 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8267 {
8268     ViewAbstractModel::GetInstance()->DismissContentCover();
8269     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8270 }
8271 
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)8272 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8273 {
8274     ViewAbstractModel::GetInstance()->SheetSpringBack();
8275     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8276 }
8277 
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)8278 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8279     std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
8280     std::function<void(const int32_t& info)>& onWillDismiss)
8281 {
8282     auto showCallback = paramObj->GetProperty("onAppear");
8283     auto dismissCallback = paramObj->GetProperty("onDisappear");
8284     auto willShowCallback = paramObj->GetProperty("onWillAppear");
8285     auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
8286     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8287     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8288     if (showCallback->IsFunction()) {
8289         RefPtr<JsFunction> jsFunc =
8290             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
8291         onAppear = [func = std::move(jsFunc), node = frameNode]() {
8292             PipelineContext::SetCallBackNode(node);
8293             func->Execute();
8294         };
8295     }
8296     if (dismissCallback->IsFunction()) {
8297         RefPtr<JsFunction> jsFunc =
8298             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
8299         onDisappear = [func = std::move(jsFunc), node = frameNode]() {
8300             PipelineContext::SetCallBackNode(node);
8301             func->Execute();
8302         };
8303     }
8304     if (willShowCallback->IsFunction()) {
8305         RefPtr<JsFunction> jsFunc =
8306             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
8307         onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
8308     }
8309     if (willDismissCallback->IsFunction()) {
8310         RefPtr<JsFunction> jsFunc =
8311             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
8312         onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
8313     }
8314     if (onWillDismissFunc->IsFunction()) {
8315         RefPtr<JsFunction> jsFunc =
8316             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8317         onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
8318             ACE_SCORING_EVENT("contentCover.dismiss");
8319             PipelineContext::SetCallBackNode(node);
8320             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8321             objectTemplate->SetInternalFieldCount(1);
8322             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8323             dismissObj->SetPropertyObject(
8324                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
8325             dismissObj->SetProperty<int32_t>("reason", info);
8326             JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8327             func->ExecuteJS(1, &newJSVal);
8328         };
8329     }
8330 }
8331 
JSCreateAnimatableProperty(const JSCallbackInfo & info)8332 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
8333 {
8334     if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
8335         return;
8336     }
8337 
8338     JSRef<JSVal> callback = info[2]; /* 2:args index */
8339     if (!callback->IsFunction()) {
8340         return;
8341     }
8342     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8343     std::string propertyName = info[0]->ToString();
8344     if (info[1]->IsNumber()) {
8345         float numValue = info[1]->ToNumber<float>();
8346         std::function<void(float)> onCallbackEvent;
8347         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8348         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8349                               node = frameNode](const float val) {
8350             ContainerScope scope(id);
8351             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8352             auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
8353             PipelineContext::SetCallBackNode(node);
8354             func->ExecuteJS(1, &newJSVal);
8355         };
8356         ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
8357     } else if (info[1]->IsObject()) {
8358         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8359         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8360             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8361         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8362             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8363         std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
8364         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8365         onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8366                               node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
8367             ContainerScope scope(id);
8368             RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
8369             if (!impl) {
8370                 return;
8371             }
8372             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8373             auto newJSVal = JSRef<JSVal>(impl->GetObject());
8374             PipelineContext::SetCallBackNode(node);
8375             func->ExecuteJS(1, &newJSVal);
8376         };
8377         ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
8378             propertyName, animatableArithmetic, onCallbackEvent);
8379     }
8380 }
8381 
JSUpdateAnimatableProperty(const JSCallbackInfo & info)8382 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
8383 {
8384     if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
8385         return;
8386     }
8387 
8388     std::string propertyName = info[0]->ToString();
8389     float numValue = 0.0;
8390     if (info[1]->IsNumber()) {
8391         numValue = info[1]->ToNumber<float>();
8392         ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
8393     } else if (info[1]->IsObject()) {
8394         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8395         RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8396             AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8397         RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8398             AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8399         ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
8400     }
8401 }
8402 
JsExpandSafeArea(const JSCallbackInfo & info)8403 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
8404 {
8405     NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
8406     if (info.Length() >= 1 && info[0]->IsArray()) {
8407         auto paramArray = JSRef<JSArray>::Cast(info[0]);
8408         uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
8409         for (size_t i = 0; i < paramArray->Length(); ++i) {
8410             if (!paramArray->GetValueAt(i)->IsNumber() ||
8411                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
8412                 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
8413                 break;
8414             }
8415             safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8416         }
8417         opts.type = safeAreaType;
8418     }
8419     if (info.Length() >= 2 && info[1]->IsArray()) {
8420         auto paramArray = JSRef<JSArray>::Cast(info[1]);
8421         uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
8422         for (size_t i = 0; i < paramArray->Length(); ++i) {
8423             if (!paramArray->GetValueAt(i)->IsNumber() ||
8424                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
8425                 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
8426                 break;
8427             }
8428             safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8429         }
8430         opts.edges = safeAreaEdge;
8431     }
8432 
8433     ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
8434 }
8435 
ParseJSLightSource(JSRef<JSObject> & lightSource)8436 void ParseJSLightSource(JSRef<JSObject>& lightSource)
8437 {
8438     if (lightSource->IsUndefined()) {
8439         return;
8440     }
8441     JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
8442     JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
8443     JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
8444     JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
8445     JSRef<JSVal> color = lightSource->GetProperty("color");
8446 
8447     CalcDimension dimPositionX;
8448     CalcDimension dimPositionY;
8449     CalcDimension dimPositionZ;
8450     if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
8451         JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
8452         JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
8453         ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
8454     }
8455 
8456     if (intensity->IsNumber()) {
8457         float intensityValue = intensity->ToNumber<float>();
8458         ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
8459     }
8460 
8461     Color lightColor;
8462     if (JSViewAbstract::ParseJsColor(color, lightColor)) {
8463         ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
8464     }
8465 }
8466 
JsPointLight(const JSCallbackInfo & info)8467 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
8468 {
8469 #ifdef POINT_LIGHT_ENABLE
8470     if (!info[0]->IsObject()) {
8471         return;
8472     }
8473 
8474     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
8475     JSRef<JSObject> lightSource = object->GetProperty("lightSource");
8476     ParseJSLightSource(lightSource);
8477 
8478     auto resourceWrapper = CreateResourceWrapper();
8479     if (!resourceWrapper) {
8480         return;
8481     }
8482     double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
8483     Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
8484     Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
8485 
8486     JSRef<JSVal> illuminated = object->GetProperty("illuminated");
8487     if (illuminated->IsNumber()) {
8488         uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
8489         ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
8490         ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
8491     }
8492 
8493     JSRef<JSVal> bloom = object->GetProperty("bloom");
8494     if (bloom->IsNumber()) {
8495         float bloomValue = bloom->ToNumber<float>();
8496         ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
8497 
8498         Shadow shadow;
8499         shadow.SetBlurRadius(bloomValue * bloomRadius);
8500         shadow.SetColor(bloomColor);
8501         std::vector<Shadow> shadows { shadow };
8502         ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8503     }
8504 #endif
8505 }
8506 
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)8507 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
8508 {
8509     if (info[0]->IsBoolean()) {
8510         ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
8511     }
8512 }
8513 
JSBind(BindingTarget globalObj)8514 void JSViewAbstract::JSBind(BindingTarget globalObj)
8515 {
8516     JSClass<JSViewAbstract>::Declare("JSViewAbstract");
8517 
8518     // static methods
8519     MethodOptions opt = MethodOptions::NONE;
8520     JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
8521 
8522     JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
8523     JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
8524     JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
8525     JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
8526     JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
8527     JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
8528     JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
8529     JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSViewAbstract::JsPixelRound);
8530     JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
8531 
8532     JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
8533     JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
8534     JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
8535     JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
8536     JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
8537 
8538     JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
8539     JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
8540     JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
8541     JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
8542     JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
8543 
8544     JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
8545     JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
8546     JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
8547     JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
8548     JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
8549     JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
8550     JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
8551     JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
8552     JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
8553     JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
8554     JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
8555     JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
8556     JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
8557     JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
8558     JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
8559     JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
8560     JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
8561     JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
8562     JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
8563     JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
8564     JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
8565     JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
8566     JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
8567     JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
8568 
8569     JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
8570     JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
8571     JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
8572     JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
8573     JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
8574     JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
8575     JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
8576     JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
8577     JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
8578     JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
8579     JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
8580     JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
8581 
8582     JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
8583     JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
8584     JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
8585     JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
8586     JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
8587     JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
8588     JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
8589 
8590     JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
8591     JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
8592     JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
8593     JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
8594     JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
8595     JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
8596     JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
8597     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
8598     JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal",
8599         &JSViewAbstract::JsBackgroundBrightnessInternal);
8600     JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
8601     JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
8602     JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
8603     JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
8604     JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
8605     JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
8606     JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
8607     JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
8608     JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
8609     JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
8610     JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
8611     JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
8612 #ifndef WEARABLE_PRODUCT
8613     JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
8614 #endif
8615 
8616     JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
8617     JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
8618     JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
8619     JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
8620     JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
8621     JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
8622     JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
8623     JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
8624     JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
8625     JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
8626     JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
8627     JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
8628     JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
8629     JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
8630 
8631     JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
8632     JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
8633     JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
8634     JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
8635     JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
8636     JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
8637     JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
8638     JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
8639     JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
8640     JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
8641     JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
8642     JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
8643     JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
8644     JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
8645     JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
8646     JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
8647     JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
8648     JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
8649     JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
8650     JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
8651     JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
8652     JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
8653     JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
8654     JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
8655     JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
8656     JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
8657     JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
8658     JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
8659     JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
8660     JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
8661     JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
8662     JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
8663     JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
8664     JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
8665     JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
8666     JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
8667     JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
8668     JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
8669     JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
8670     JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
8671     JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
8672     JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
8673     JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
8674     JSClass<JSViewAbstract>::StaticMethod(
8675         "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
8676     JSClass<JSViewAbstract>::StaticMethod(
8677         "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
8678     JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
8679     JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
8680     JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
8681     JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
8682     JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
8683     JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
8684     JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
8685 
8686     JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
8687     JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
8688     JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
8689     JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
8690     JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
8691     JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
8692     JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
8693     JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
8694     JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
8695 
8696     JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
8697     JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
8698     JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
8699     JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
8700     JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
8701     JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
8702     JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
8703     JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
8704     JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
8705     JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
8706     JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
8707 
8708     JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
8709     JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
8710     JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
8711     JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
8712 
8713     JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
8714 
8715     JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
8716 
8717     JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
8718     JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
8719     JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
8720 
8721     JSClass<JSViewAbstract>::StaticMethod(
8722         "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
8723 
8724     JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
8725     JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
8726 
8727     JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
8728     JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
8729     JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
8730     JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
8731 
8732     JSClass<JSViewAbstract>::Bind(globalObj);
8733 }
8734 
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)8735 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
8736 {
8737     auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
8738         auto vm = info->GetVM();
8739         CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
8740         Local<JSValueRef> thisObj = info->GetFunctionRef();
8741         auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
8742         if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
8743             return panda::JSValueRef::Undefined(vm);
8744         }
8745 
8746         auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
8747         if (weak->Invalid()) {
8748             return panda::JSValueRef::Undefined(vm);
8749         }
8750 
8751         auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
8752         if (frameNode) {
8753             const auto& extensionHandler = frameNode->GetExtensionHandler();
8754             if (extensionHandler) {
8755                 extensionHandler->InvalidateRender();
8756             } else {
8757                 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
8758             }
8759         }
8760 
8761         return panda::JSValueRef::Undefined(vm);
8762     };
8763     auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
8764     if (frameNode) {
8765         const auto& extensionHandler = frameNode->GetExtensionHandler();
8766         if (extensionHandler) {
8767             extensionHandler->InvalidateRender();
8768         } else {
8769             frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
8770         }
8771     }
8772     auto vm = jsInvalidate->GetEcmaVM();
8773     auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
8774     jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
8775     jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
8776     jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
8777 }
8778 
JsDrawModifier(const JSCallbackInfo & info)8779 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
8780 {
8781     if (!info[0]->IsObject()) {
8782         return;
8783     }
8784 
8785     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
8786     bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
8787     if (!IsSupportDrawModifier) {
8788         return;
8789     }
8790     auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
8791     RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
8792     auto execCtx = info.GetExecutionContext();
8793     auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
8794         JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
8795         if (!drawMethod->IsFunction()) {
8796             return nullptr;
8797         }
8798 
8799         auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
8800             JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
8801 
8802         return GetDrawCallback(jsDrawFunc, execCtx);
8803     };
8804 
8805     drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
8806     drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
8807     drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
8808 
8809     ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
8810     AddInvalidateFunc(jsDrawModifier, frameNode);
8811 }
8812 
JsAllowDrop(const JSCallbackInfo & info)8813 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
8814 {
8815     std::set<std::string> allowDropSet;
8816     allowDropSet.clear();
8817     if (!info[0]->IsUndefined() && info[0]->IsArray()) {
8818         auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
8819         std::string allowDrop;
8820         for (size_t i = 0; i < allowDropArray->Length(); i++) {
8821             allowDrop = allowDropArray->GetValueAt(i)->ToString();
8822             allowDropSet.insert(allowDrop);
8823         }
8824         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
8825     } else if (info[0]->IsNull()) {
8826         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
8827     } else {
8828         ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
8829     }
8830     ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
8831 }
8832 
JsOnPreDrag(const JSCallbackInfo & info)8833 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
8834 {
8835     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8836     auto jsVal = info[0];
8837     if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
8838         return;
8839     }
8840     RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8841     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8842     auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
8843                          const PreDragStatus preDragStatus) {
8844         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8845         ACE_SCORING_EVENT("onPreDrag");
8846         PipelineContext::SetCallBackNode(node);
8847         func->PreDragExecute(preDragStatus);
8848     };
8849     ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
8850 }
8851 
JsDragPreview(const JSCallbackInfo & info)8852 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
8853 {
8854     auto jsVal = info[0];
8855     if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
8856         return;
8857     }
8858     NG::DragDropInfo dragPreviewInfo;
8859     JSRef<JSVal> builder;
8860     JSRef<JSVal> pixelMap;
8861     JSRef<JSVal> extraInfo;
8862     if (jsVal->IsFunction()) {
8863         builder = jsVal;
8864     } else if (jsVal->IsObject()) {
8865         auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
8866         builder = dragItemInfo->GetProperty("builder");
8867 #if defined(PIXEL_MAP_SUPPORTED)
8868         pixelMap = dragItemInfo->GetProperty("pixelMap");
8869         dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
8870 #endif
8871         extraInfo = dragItemInfo->GetProperty("extraInfo");
8872         ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
8873     } else if (jsVal->IsString()) {
8874         auto inspectorId = jsVal;
8875         ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
8876     } else {
8877         return;
8878     }
8879 
8880     if (builder->IsFunction()) {
8881         RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
8882         if (builderFunc != nullptr) {
8883             ViewStackModel::GetInstance()->NewScope();
8884             {
8885                 ACE_SCORING_EVENT("dragPreview.builder");
8886                 builderFunc->Execute();
8887             }
8888             RefPtr<AceType> node = ViewStackModel::GetInstance()->Finish();
8889             dragPreviewInfo.customNode = AceType::DynamicCast<NG::UINode>(node);
8890         }
8891     }
8892     ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
8893 }
8894 
JsAlignRules(const JSCallbackInfo & info)8895 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
8896 {
8897     if (!info[0]->IsObject()) {
8898         return;
8899     }
8900 
8901     JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
8902     if (valueObj->IsEmpty()) {
8903         return;
8904     }
8905     const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
8906     std::map<AlignDirection, AlignRule> alignRules;
8907     BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
8908     for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
8909         auto rule = valueObj->GetProperty(keys[i]);
8910         if (rule->IsObject()) {
8911             JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
8912             JSRef<JSVal> align = val->GetProperty("align");
8913             AlignRule alignRule;
8914             alignRule.anchor = val->GetProperty("anchor")->ToString();
8915             if (i < HORIZONTAL_DIRECTION_RANGE) {
8916                 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
8917             } else {
8918                 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
8919             }
8920             if (i < VERTICAL_DIRECTION_RANGE) {
8921                 alignRules[static_cast<AlignDirection>(i)] = alignRule;
8922             } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
8923                 alignRules[AlignDirection::LEFT] = alignRule;
8924             } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
8925                 alignRules[AlignDirection::RIGHT] = alignRule;
8926             }
8927             auto biasX = val->GetProperty("horizontal");
8928             if (biasX->IsNumber()) {
8929                 biasPair.first = biasX->ToNumber<float>();
8930             }
8931             auto biasY = val->GetProperty("vertical");
8932             if (biasY->IsNumber()) {
8933                 biasPair.second = biasY->ToNumber<float>();
8934             }
8935         }
8936     }
8937 
8938     ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
8939     ViewAbstractModel::GetInstance()->SetBias(biasPair);
8940 }
8941 
JsChainMode(const JSCallbackInfo & info)8942 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
8943 {
8944     ChainInfo chainInfo;
8945     if (info.Length() >= 1) {
8946         auto tmpDirection = info[0];
8947         if (tmpDirection->IsUndefined()) {
8948             chainInfo.direction = std::nullopt;
8949         } else if (tmpDirection->IsNumber()) {
8950             auto direction = tmpDirection->ToNumber<int32_t>();
8951             chainInfo.direction = static_cast<LineDirection>(direction);
8952         }
8953     }
8954 
8955     if (info.Length() >= 2) { // 2 : two args
8956         auto tmpStyle = info[1];
8957         if (tmpStyle->IsUndefined()) {
8958             chainInfo.style = std::nullopt;
8959         } else if (tmpStyle->IsNumber()) {
8960             auto style = tmpStyle->ToNumber<int32_t>();
8961             chainInfo.style = static_cast<ChainStyle>(style);
8962         }
8963     }
8964     ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
8965 }
8966 
SetMarginTop(const JSCallbackInfo & info)8967 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
8968 {
8969     CalcDimension value;
8970     if (!ParseJsDimensionVp(info[0], value)) {
8971         return;
8972     }
8973     ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
8974 }
8975 
SetMarginBottom(const JSCallbackInfo & info)8976 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
8977 {
8978     CalcDimension value;
8979     if (!ParseJsDimensionVp(info[0], value)) {
8980         return;
8981     }
8982     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
8983 }
8984 
SetMarginLeft(const JSCallbackInfo & info)8985 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
8986 {
8987     CalcDimension value;
8988     if (!ParseJsDimensionVp(info[0], value)) {
8989         return;
8990     }
8991     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
8992 }
8993 
SetMarginRight(const JSCallbackInfo & info)8994 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
8995 {
8996     CalcDimension value;
8997     if (!ParseJsDimensionVp(info[0], value)) {
8998         return;
8999     }
9000     ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
9001 }
9002 
SetPaddingTop(const JSCallbackInfo & info)9003 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
9004 {
9005     CalcDimension value;
9006     if (!ParseJsDimensionVp(info[0], value)) {
9007         return;
9008     }
9009     ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
9010 }
9011 
SetPaddingBottom(const JSCallbackInfo & info)9012 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
9013 {
9014     CalcDimension value;
9015     if (!ParseJsDimensionVp(info[0], value)) {
9016         return;
9017     }
9018     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
9019 }
9020 
SetPaddingLeft(const JSCallbackInfo & info)9021 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
9022 {
9023     CalcDimension value;
9024     if (!ParseJsDimensionVp(info[0], value)) {
9025         return;
9026     }
9027     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
9028 }
9029 
SetPaddingRight(const JSCallbackInfo & info)9030 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
9031 {
9032     CalcDimension value;
9033     if (!ParseJsDimensionVp(info[0], value)) {
9034         return;
9035     }
9036     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
9037 }
9038 
SetColorBlend(Color color)9039 void JSViewAbstract::SetColorBlend(Color color)
9040 {
9041     ViewAbstractModel::GetInstance()->SetColorBlend(color);
9042 }
9043 
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)9044 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
9045 {
9046     ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
9047 }
9048 
SetDynamicLightUp(float rate,float lightUpDegree)9049 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
9050 {
9051     ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
9052 }
9053 
SetBgDynamicBrightness(BrightnessOption brightnessOption)9054 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
9055 {
9056     ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
9057 }
9058 
SetFgDynamicBrightness(BrightnessOption brightnessOption)9059 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
9060 {
9061     ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
9062 }
9063 
SetWindowBlur(float progress,WindowBlurStyle blurStyle)9064 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
9065 {
9066     ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
9067 }
9068 
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)9069 bool JSViewAbstract::ParseJsonDimension(
9070     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
9071 {
9072     if (!jsonValue || jsonValue->IsNull()) {
9073         return false;
9074     }
9075     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9076         return false;
9077     }
9078     if (jsonValue->IsNumber()) {
9079         result = Dimension(jsonValue->GetDouble(), defaultUnit);
9080         return true;
9081     }
9082     if (jsonValue->IsString()) {
9083         if (checkIllegal) {
9084             return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
9085         }
9086         result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
9087         return true;
9088     }
9089     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9090     auto resId = resVal->GetValue("id");
9091     if (!resId || !resId->IsNumber()) {
9092         return false;
9093     }
9094 
9095     auto resourceWrapper = CreateResourceWrapper();
9096     if (!resourceWrapper) {
9097         return false;
9098     }
9099     result = resourceWrapper->GetDimension(resId->GetUInt());
9100     return true;
9101 }
9102 
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)9103 bool JSViewAbstract::ParseJsonDimensionVp(
9104     const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
9105 {
9106     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9107         return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
9108     }
9109     return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
9110 }
9111 
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)9112 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
9113 {
9114     if (!jsonValue || jsonValue->IsNull()) {
9115         return false;
9116     }
9117     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9118         return false;
9119     }
9120     if (jsonValue->IsNumber()) {
9121         result = jsonValue->GetDouble();
9122         return true;
9123     }
9124     if (jsonValue->IsString()) {
9125         result = StringUtils::StringToDouble(jsonValue->GetString());
9126         return true;
9127     }
9128     // parse json Resource
9129     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9130     auto resId = resVal->GetValue("id");
9131     CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
9132     auto id = resId->GetUInt();
9133     auto resType = resVal->GetValue("type");
9134     CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
9135     auto type = resType->GetUInt();
9136 
9137     auto resourceWrapper = CreateResourceWrapper();
9138     if (!resourceWrapper) {
9139         return false;
9140     }
9141     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9142         auto numberString = resourceWrapper->GetString(id);
9143         return StringUtils::StringToDouble(numberString, result);
9144     }
9145     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9146         result = resourceWrapper->GetInt(id);
9147         return true;
9148     }
9149     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9150         result = resourceWrapper->GetDouble(id);
9151         return true;
9152     }
9153     return false;
9154 }
9155 
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)9156 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
9157 {
9158     if (!jsonValue || jsonValue->IsNull()) {
9159         return false;
9160     }
9161     if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9162         return false;
9163     }
9164     if (jsonValue->IsNumber()) {
9165         result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
9166         return true;
9167     }
9168 
9169     bool isSetColor = false;
9170     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
9171         isSetColor = jsonValue->IsString();
9172     } else {
9173         isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
9174     }
9175     if (isSetColor) {
9176         result = Color::FromString(jsonValue->GetString());
9177         return true;
9178     }
9179     auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9180     auto resId = resVal->GetValue("id");
9181     if (!resId || !resId->IsNumber()) {
9182         return false;
9183     }
9184     auto resourceWrapper = CreateResourceWrapper();
9185     if (!resourceWrapper) {
9186         return false;
9187     }
9188     result = resourceWrapper->GetColor(resId->GetUInt());
9189     return true;
9190 }
9191 
ParseShadowOffsetX(const JSRef<JSObject> & jsObj,CalcDimension & offsetX,Shadow & shadow)9192 void JSViewAbstract::ParseShadowOffsetX(const JSRef<JSObject>& jsObj, CalcDimension& offsetX, Shadow& shadow)
9193 {
9194     auto jsOffsetX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_X));
9195     bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
9196     if (ParseJsResource(jsOffsetX, offsetX)) {
9197         double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9198         shadow.SetOffsetX(xValue);
9199     } else {
9200         if (ParseJsDimensionVp(jsOffsetX, offsetX)) {
9201             double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9202             shadow.SetOffsetX(xValue);
9203         }
9204     }
9205 }
9206 
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)9207 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
9208 {
9209     int32_t shadowStyle = 0;
9210     if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
9211         auto style = static_cast<ShadowStyle>(shadowStyle);
9212         return GetShadowFromTheme(style, shadow);
9213     }
9214     if (!jsValue->IsObject()) {
9215         return false;
9216     }
9217     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9218     double radius = 0.0;
9219     ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius);
9220     if (LessNotEqual(radius, 0.0)) {
9221         radius = 0.0;
9222     }
9223     shadow.SetBlurRadius(radius);
9224     CalcDimension offsetX;
9225     ParseShadowOffsetX(jsObj, offsetX, shadow);
9226     CalcDimension offsetY;
9227     auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
9228     if (ParseJsResource(jsOffsetY, offsetY)) {
9229         shadow.SetOffsetY(offsetY.Value());
9230     } else {
9231         if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
9232             shadow.SetOffsetY(offsetY.Value());
9233         }
9234     }
9235     Color color;
9236     ShadowColorStrategy shadowColorStrategy;
9237     auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
9238     if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
9239         shadow.SetShadowColorStrategy(shadowColorStrategy);
9240     } else if (ParseJsColor(jsColor, color)) {
9241         shadow.SetColor(color);
9242     }
9243     int32_t type = static_cast<int32_t>(ShadowType::COLOR);
9244     JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
9245     if (type != static_cast<int32_t>(ShadowType::BLUR)) {
9246         type = static_cast<int32_t>(ShadowType::COLOR);
9247     }
9248     shadow.SetShadowType(static_cast<ShadowType>(type));
9249     bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
9250     shadow.SetIsFilled(isFilled);
9251     return true;
9252 }
9253 
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)9254 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
9255 {
9256     auto colorMode = SystemProperties::GetColorMode();
9257     if (shadowStyle == ShadowStyle::None) {
9258         return true;
9259     }
9260 
9261     auto container = Container::Current();
9262     CHECK_NULL_RETURN(container, false);
9263     auto pipelineContext = container->GetPipelineContext();
9264     CHECK_NULL_RETURN(pipelineContext, false);
9265 
9266     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
9267     if (!shadowTheme) {
9268         return false;
9269     }
9270 
9271     shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
9272     return true;
9273 }
9274 
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)9275 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
9276 {
9277     if (!jsValue->IsObject()) {
9278         return false;
9279     }
9280     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9281     uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
9282     if (type == 0) {
9283         return false;
9284     }
9285     auto resourceWrapper = CreateResourceWrapper();
9286     CHECK_NULL_RETURN(resourceWrapper, false);
9287     if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9288         auto value = resourceWrapper->GetString(
9289             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9290         return StringUtils::StringToCalcDimensionNG(value, result, false);
9291     }
9292     if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9293         auto value = std::to_string(
9294             resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
9295         StringUtils::StringToDimensionWithUnitNG(value, result);
9296         return true;
9297     }
9298 
9299     if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9300         result = resourceWrapper->GetDimension(
9301             jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9302         return true;
9303     }
9304     return false;
9305 }
9306 
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)9307 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
9308 {
9309     JSRef<JSVal> arg = info[0];
9310     if (!arg->IsObject()) {
9311         return false;
9312     }
9313     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
9314     JSRef<JSVal> typeValue = obj->GetProperty("types");
9315     if (!typeValue->IsArray()) {
9316         return false;
9317     }
9318     JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
9319     for (size_t i = 0; i < array->Length(); i++) {
9320         JSRef<JSVal> value = array->GetValueAt(i);
9321         auto index = value->ToNumber<int32_t>();
9322         if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
9323             return false;
9324         }
9325         if (i != 0) {
9326             textDetectConfig.types.append(",");
9327         }
9328         textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
9329     }
9330     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9331     JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
9332     if (resultCallback->IsFunction()) {
9333         auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
9334         textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
9335                        const std::string& result) {
9336             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9337             PipelineContext::SetCallBackNode(node);
9338             func->Execute(result);
9339         };
9340     }
9341 
9342     return ParseAIEntityColor(obj, textDetectConfig);
9343 }
9344 
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)9345 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
9346 {
9347     JSRef<JSVal> entityColorValue = obj->GetProperty("color");
9348     ParseJsColor(entityColorValue, textDetectConfig.entityColor);
9349 
9350     JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
9351     if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
9352         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9353         return true;
9354     }
9355     JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
9356     JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
9357     JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
9358     JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
9359 
9360     if (typeValue->IsNumber()) {
9361         textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
9362     } else {
9363         textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
9364     }
9365     if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) {
9366         textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9367     }
9368     if (styleValue->IsNumber()) {
9369          textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
9370     } else {
9371         textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
9372     }
9373 
9374     return true;
9375 }
9376 
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)9377 void JSViewAbstract::GetAngle(
9378     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
9379 {
9380     auto value = jsonValue->GetValue(key);
9381     if (value && value->IsString()) {
9382         angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
9383     } else if (value && value->IsNumber()) {
9384         angle = static_cast<float>(value->GetDouble());
9385     }
9386 }
9387 
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)9388 void JSViewAbstract::GetJsAngle(
9389     int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
9390 {
9391     if (!jsValue->IsObject()) {
9392         return;
9393     }
9394     JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
9395     if (value->IsString()) {
9396         angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
9397     } else if (value->IsNumber()) {
9398         angle = value->ToNumber<float>();
9399     }
9400 }
9401 
9402 // 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)9403 void JSViewAbstract::GetJsAngleWithDefault(
9404     int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
9405 {
9406     JSRef<JSVal> value = jsObj->GetProperty(key);
9407     if (value->IsString()) {
9408         double temp = 0.0;
9409         if (StringUtils::StringToDegree(value->ToString(), temp)) {
9410             angle = static_cast<float>(temp);
9411         } else {
9412             angle = defaultValue;
9413         }
9414     } else if (value->IsNumber()) {
9415         angle = value->ToNumber<float>();
9416     }
9417 }
9418 
CheckAngle(std::optional<float> & angle)9419 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
9420 {
9421     angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
9422 }
9423 
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)9424 void JSViewAbstract::GetPerspective(
9425     const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
9426 {
9427     auto value = jsonValue->GetValue(key);
9428     if (value && value->IsNumber()) {
9429         perspective = static_cast<float>(value->GetDouble());
9430     }
9431 }
9432 
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)9433 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
9434 {
9435     auto value = jsValue->GetProperty(key);
9436     if (value->IsNumber()) {
9437         perspective = value->ToNumber<float>();
9438     }
9439 }
9440 
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9441 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9442 {
9443     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9444         return;
9445     }
9446 
9447     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9448         GradientColor gradientColor;
9449         auto item = colorStops->GetArrayItem(i);
9450         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9451             auto colorParams = item->GetArrayItem(0);
9452             // color
9453             Color color;
9454             if (!ParseJsonColor(colorParams, color)) {
9455                 continue;
9456             }
9457             gradientColor.SetColor(color);
9458             gradientColor.SetHasValue(false);
9459             // stop value
9460             if (item->GetArraySize() <= 1) {
9461                 continue;
9462             }
9463             auto stopValue = item->GetArrayItem(1);
9464             double value = 0.0;
9465             if (ParseJsonDouble(stopValue, value)) {
9466                 value = std::clamp(value, 0.0, 1.0);
9467                 gradientColor.SetHasValue(true);
9468                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9469             }
9470             gradient.AddColor(gradientColor);
9471         }
9472     }
9473 }
9474 
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9475 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9476 {
9477     if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9478         return;
9479     }
9480 
9481     for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9482         NG::GradientColor gradientColor;
9483         auto item = colorStops->GetArrayItem(i);
9484         if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9485             auto colorParams = item->GetArrayItem(0);
9486             // color
9487             Color color;
9488             if (!ParseJsonColor(colorParams, color)) {
9489                 continue;
9490             }
9491             gradientColor.SetColor(color);
9492             gradientColor.SetHasValue(false);
9493             // stop value
9494             if (item->GetArraySize() <= 1) {
9495                 continue;
9496             }
9497             auto stopValue = item->GetArrayItem(1);
9498             double value = 0.0;
9499             if (ParseJsonDouble(stopValue, value)) {
9500                 value = std::clamp(value, 0.0, 1.0);
9501                 gradientColor.SetHasValue(true);
9502                 //  [0, 1] -> [0, 100.0];
9503                 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9504             }
9505             gradient.AddColor(gradientColor);
9506         }
9507     }
9508 }
9509 
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)9510 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
9511 {
9512     if (!colorStops->IsArray()) {
9513         return;
9514     }
9515 
9516     JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
9517     size_t length = jsArray->Length();
9518     for (size_t i = 0; i < length; i++) {
9519         NG::GradientColor gradientColor;
9520         JSRef<JSVal> item = jsArray->GetValueAt(i);
9521         if (!item->IsArray()) {
9522             continue;
9523         }
9524         JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
9525         if (subArray->Length() < 2) {
9526             continue;
9527         }
9528         // color
9529         Color color;
9530         if (!ParseJsColor(subArray->GetValueAt(0), color)) {
9531             continue;
9532         }
9533         gradientColor.SetColor(color);
9534         gradientColor.SetHasValue(false);
9535         // stop value
9536         double value = 0.0;
9537         if (ParseJsDouble(subArray->GetValueAt(1), value)) {
9538             value = std::clamp(value, 0.0, 1.0);
9539             gradientColor.SetHasValue(true);
9540         }
9541         //  [0, 1] -> [0, 100.0];
9542         gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9543         gradient.AddColor(gradientColor);
9544     }
9545 }
9546 
SetDirection(const std::string & dir)9547 void JSViewAbstract::SetDirection(const std::string& dir)
9548 {
9549     TextDirection direction = TextDirection::AUTO;
9550     if (dir == "Ltr") {
9551         direction = TextDirection::LTR;
9552     } else if (dir == "Rtl") {
9553         direction = TextDirection::RTL;
9554     } else if (dir == "Auto") {
9555         direction = TextDirection::AUTO;
9556     } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9557         direction = TextDirection::AUTO;
9558     }
9559     ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
9560 }
9561 
GetThemeConstants(const JSRef<JSObject> & jsObj)9562 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
9563 {
9564     std::string bundleName;
9565     std::string moduleName;
9566     if (!jsObj->IsUndefined()) {
9567         JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
9568         JSRef<JSVal> module = jsObj->GetProperty("moduleName");
9569         if (bundle->IsString() && module->IsString()) {
9570             bundleName = bundle->ToString();
9571             moduleName = module->ToString();
9572         }
9573     }
9574 
9575     auto cardId = CardScope::CurrentId();
9576     if (cardId != INVALID_CARD_ID) {
9577         auto container = Container::Current();
9578         auto weak = container->GetCardPipeline(cardId);
9579         auto cardPipelineContext = weak.Upgrade();
9580         CHECK_NULL_RETURN(cardPipelineContext, nullptr);
9581         auto cardThemeManager = cardPipelineContext->GetThemeManager();
9582         CHECK_NULL_RETURN(cardThemeManager, nullptr);
9583         return cardThemeManager->GetThemeConstants(bundleName, moduleName);
9584     }
9585 
9586 #ifdef PLUGIN_COMPONENT_SUPPORTED
9587     if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
9588         auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
9589         if (!pluginContainer) {
9590             return nullptr;
9591         }
9592         auto pluginPipelineContext = pluginContainer->GetPipelineContext();
9593         if (!pluginPipelineContext) {
9594             return nullptr;
9595         }
9596         auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
9597         if (!pluginThemeManager) {
9598             return nullptr;
9599         }
9600         return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
9601     }
9602 #endif
9603     auto container = Container::Current();
9604     CHECK_NULL_RETURN(container, nullptr);
9605     auto pipelineContext = container->GetPipelineContext();
9606     CHECK_NULL_RETURN(pipelineContext, nullptr);
9607     auto themeManager = pipelineContext->GetThemeManager();
9608     CHECK_NULL_RETURN(themeManager, nullptr);
9609     return themeManager->GetThemeConstants(bundleName, moduleName);
9610 }
9611 
JsHoverEffect(const JSCallbackInfo & info)9612 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
9613 {
9614     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
9615     auto jsVal = info[0];
9616     if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
9617         ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
9618         return;
9619     }
9620     if (!jsVal->IsNumber()) {
9621         return;
9622     }
9623     ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
9624 }
9625 
JsOnMouse(const JSCallbackInfo & info)9626 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
9627 {
9628     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9629         ViewAbstractModel::GetInstance()->DisableOnMouse();
9630         return;
9631     }
9632     if (!info[0]->IsFunction()) {
9633         return;
9634     }
9635 
9636     RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
9637     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9638     auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
9639                        MouseInfo& mouseInfo) {
9640         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9641         ACE_SCORING_EVENT("onMouse");
9642         PipelineContext::SetCallBackNode(node);
9643         func->Execute(mouseInfo);
9644     };
9645     ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
9646 }
9647 
JsOnHover(const JSCallbackInfo & info)9648 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
9649 {
9650     if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9651         ViewAbstractModel::GetInstance()->DisableOnHover();
9652         return;
9653     }
9654     if (!info[0]->IsFunction()) {
9655         return;
9656     }
9657 
9658     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
9659     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9660     auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
9661                        bool isHover, HoverInfo& hoverInfo) {
9662         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9663         ACE_SCORING_EVENT("onHover");
9664         PipelineContext::SetCallBackNode(node);
9665         func->HoverExecute(isHover, hoverInfo);
9666     };
9667     ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
9668 }
9669 
JsOnAccessibilityHover(const JSCallbackInfo & info)9670 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
9671 {
9672     if (info[0]->IsUndefined()) {
9673         ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
9674         return;
9675     }
9676     if (!info[0]->IsFunction()) {
9677         return;
9678     }
9679 
9680     RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
9681     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9682     auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
9683                                     node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
9684         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9685         ACE_SCORING_EVENT("onAccessibilityHover");
9686         PipelineContext::SetCallBackNode(node);
9687         func->AccessibilityHoverExecute(isHover, hoverInfo);
9688     };
9689     ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
9690 }
9691 
JsOnClick(const JSCallbackInfo & info)9692 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
9693 {
9694     auto arg = info[0];
9695     if (arg->IsUndefined() && IsDisableEventVersion()) {
9696         ViewAbstractModel::GetInstance()->DisableOnClick();
9697         return;
9698     }
9699     if (!arg->IsFunction()) {
9700         return;
9701     }
9702 
9703     auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
9704     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9705     auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
9706                      BaseEventInfo* info) {
9707         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9708         auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
9709         ACE_SCORING_EVENT("onClick");
9710         PipelineContext::SetCallBackNode(node);
9711         func->Execute(*tapInfo);
9712 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
9713         JSInteractableView::ReportClickEvent(node);
9714 #endif
9715     };
9716     auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
9717     auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
9718                        const ClickInfo* info) {
9719         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9720         ACE_SCORING_EVENT("onClick");
9721         PipelineContext::SetCallBackNode(node);
9722         func->Execute(*info);
9723 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
9724         JSInteractableView::ReportClickEvent(node);
9725 #endif
9726     };
9727 
9728     double distanceThreshold = std::numeric_limits<double>::infinity();
9729     if (info.Length() > 1 && info[1]->IsNumber()) {
9730         distanceThreshold = info[1]->ToNumber<double>();
9731         if (distanceThreshold < 0) {
9732             distanceThreshold = std::numeric_limits<double>::infinity();
9733         }
9734     }
9735     distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
9736     ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
9737 }
9738 
JsOnGestureJudgeBegin(const JSCallbackInfo & info)9739 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
9740 {
9741     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9742         ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
9743         return;
9744     }
9745 
9746     auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
9747     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9748     auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
9749                                   const RefPtr<NG::GestureInfo>& gestureInfo,
9750                                   const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
9751         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
9752         ACE_SCORING_EVENT("onGestureJudgeBegin");
9753         return func->Execute(gestureInfo, info);
9754     };
9755     ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
9756 }
9757 
JsOnTouchIntercept(const JSCallbackInfo & info)9758 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
9759 {
9760     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9761         ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
9762         return;
9763     }
9764 
9765     auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
9766     auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9767     auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
9768                                     TouchEventInfo& info) -> NG::HitTestMode {
9769         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
9770         ACE_SCORING_EVENT("onTouchIntercept");
9771         PipelineContext::SetCallBackNode(node);
9772         return func->Execute(info);
9773     };
9774     ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
9775 }
9776 
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)9777 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
9778 {
9779     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9780         ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
9781         return;
9782     }
9783 
9784     auto jsParallelInnerGestureToFunc =
9785         AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
9786     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9787     auto shouldBuiltInRecognizerParallelWithFunc =
9788         [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
9789             const RefPtr<NG::NGGestureRecognizer>& current,
9790             const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
9791         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
9792         ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
9793         PipelineContext::SetCallBackNode(node);
9794         return func->Execute(current, others);
9795     };
9796     ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
9797         std::move(shouldBuiltInRecognizerParallelWithFunc));
9798 }
9799 
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)9800 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
9801 {
9802     if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9803         ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
9804         return;
9805     }
9806 
9807     auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
9808     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9809     auto onGestureRecognizerJudgefunc =
9810         [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
9811             const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
9812             const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
9813         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
9814         ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
9815         PipelineContext::SetCallBackNode(node);
9816         return func->Execute(info, current, others);
9817     };
9818 
9819     bool exposeInnerGestureFlag = false;
9820     if (info.Length() > 1 && info[1]->IsBoolean()) {
9821         exposeInnerGestureFlag = info[1]->ToBoolean();
9822     }
9823     ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
9824         std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
9825 }
9826 
JsClickEffect(const JSCallbackInfo & info)9827 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
9828 {
9829     JSRef<JSVal> arg = info[0];
9830     if (arg->IsUndefined() || arg->IsNull()) {
9831         ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
9832         return;
9833     }
9834     if (!arg->IsObject()) {
9835         return;
9836     }
9837     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
9838     JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
9839     int32_t clickEffectLevelValue = 0;
9840     if (clickEffectLevel->IsNumber()) {
9841         clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
9842         if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
9843             clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
9844             clickEffectLevelValue = 0;
9845         }
9846     }
9847 
9848     JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
9849     float scaleNumberValue = DEFAULT_SCALE_LIGHT;
9850     if (!scaleNumber->IsNumber()) {
9851         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
9852             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
9853             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
9854         }
9855         ViewAbstractModel::GetInstance()->SetClickEffectLevel(
9856             (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
9857         return;
9858     }
9859 
9860     scaleNumberValue = scaleNumber->ToNumber<float>();
9861     if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
9862         if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
9863             (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
9864             scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
9865         } else {
9866             scaleNumberValue = DEFAULT_SCALE_LIGHT;
9867         }
9868     }
9869 
9870     ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
9871 }
9872 
JsOnVisibleAreaChange(const JSCallbackInfo & info)9873 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
9874 {
9875     if (info.Length() != 2) {
9876         return;
9877     }
9878 
9879     if (!info[0]->IsArray() || !info[1]->IsFunction()) {
9880         return;
9881     }
9882 
9883     auto ratioArray = JSRef<JSArray>::Cast(info[0]);
9884     size_t size = ratioArray->Length();
9885     std::vector<double> ratioVec(size);
9886     ratioVec.clear();
9887     for (size_t i = 0; i < size; i++) {
9888         double ratio = 0.0;
9889         ParseJsDouble(ratioArray->GetValueAt(i), ratio);
9890         if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
9891             ratio = VISIBLE_RATIO_MIN;
9892         }
9893 
9894         if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
9895             ratio = VISIBLE_RATIO_MAX;
9896         }
9897         ratioVec.push_back(ratio);
9898     }
9899 
9900     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
9901     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9902     auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
9903                                bool visible, double ratio) {
9904         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9905         ACE_SCORING_EVENT("onVisibleAreaChange");
9906 
9907         JSRef<JSVal> params[2];
9908         params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
9909         params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
9910         PipelineContext::SetCallBackNode(node);
9911         func->ExecuteJS(2, params);
9912     };
9913     ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
9914 }
9915 
JsHitTestBehavior(const JSCallbackInfo & info)9916 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
9917 {
9918     if (info.Length() != 1 || !info[0]->IsNumber()) {
9919         return;
9920     }
9921 
9922     NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
9923     hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
9924     ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
9925 }
9926 
JsOnChildTouchTest(const JSCallbackInfo & info)9927 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
9928 {
9929     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
9930     auto jsVal = info[0];
9931     if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
9932         return;
9933     }
9934 
9935     RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
9936         AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
9937 
9938     auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
9939                                const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
9940         NG::TouchResult touchRes;
9941         NG::TouchResult defaultRes;
9942         defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
9943         defaultRes.id = "";
9944         auto ret = func->Execute(touchInfo);
9945         if (!ret->IsObject()) {
9946             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
9947             return defaultRes;
9948         }
9949 
9950         auto retObj = JSRef<JSObject>::Cast(ret);
9951         auto strategy = retObj->GetProperty("strategy");
9952         if (!strategy->IsNumber()) {
9953             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
9954             return defaultRes;
9955         }
9956         touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
9957         auto id = retObj->GetProperty("id");
9958         if (!id->IsString()) {
9959             TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
9960             return defaultRes;
9961         }
9962         touchRes.id = id->ToString();
9963         return touchRes;
9964     };
9965     ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
9966 }
9967 
JsForegroundColor(const JSCallbackInfo & info)9968 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
9969 {
9970     Color foregroundColor = Color::TRANSPARENT;
9971     ForegroundColorStrategy strategy;
9972     if (ParseJsColorStrategy(info[0], strategy)) {
9973         ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
9974         return;
9975     }
9976     ParseJsColor(info[0], foregroundColor);
9977     ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
9978 }
9979 
JsKeyboardShortcut(const JSCallbackInfo & info)9980 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
9981 {
9982     // KeyboardShortcut only allows 2 or 3 params.
9983     if (info.Length() < 2 || info.Length() > 3) {
9984         return;
9985     }
9986     if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
9987         // clear shortcut key
9988         ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
9989         return;
9990     }
9991 
9992     std::string value;
9993     if (info[0]->IsString()) {
9994         // common letter/number/symbol
9995         value = info[0]->ToString();
9996         if (value.size() != 1) {
9997             // clear shortcut key
9998             ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
9999             return;
10000         }
10001     } else {
10002         // function keys such as F1-F10/ESC
10003         FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
10004         value = GetFunctionKeyName(functionkey);
10005     }
10006 
10007     auto keysArray = JSRef<JSArray>::Cast(info[1]);
10008     size_t size = keysArray->Length();
10009     std::vector<ModifierKey> keys(size);
10010     keys.clear();
10011     for (size_t i = 0; i < size; i++) {
10012         JSRef<JSVal> key = keysArray->GetValueAt(i);
10013         if (key->IsNumber()) {
10014             keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
10015         }
10016     }
10017 
10018     // KeyboardShortcut allows 3 params, the third param is function callback.
10019     if (info.Length() == 3 && info[2]->IsFunction()) {
10020         RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
10021         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10022         auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10023                                             node = frameNode]() {
10024             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10025             ACE_SCORING_EVENT("onKeyboardShortcutAction");
10026             PipelineContext::SetCallBackNode(node);
10027             func->ExecuteJS();
10028         };
10029         ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
10030         return;
10031     }
10032     ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
10033 }
10034 
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)10035 bool JSViewAbstract::CheckColor(
10036     const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
10037 {
10038     // Color is undefined or null
10039     if (jsValue->IsUndefined() || jsValue->IsNull()) {
10040         return false;
10041     }
10042     // input type is not in [number, string, Resource]
10043     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10044         return false;
10045     }
10046     // Correct type, incorrect value parsing
10047     if (!ParseJsColor(jsValue, result)) {
10048         return false;
10049     }
10050     return true;
10051 }
10052 
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)10053 bool JSViewAbstract::CheckLength(
10054     const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
10055 {
10056     // Length is undefined or null
10057     if (jsValue->IsUndefined() || jsValue->IsNull()) {
10058         return false;
10059     }
10060     // input type is not in [number, string, Resource]
10061     if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10062         return false;
10063     }
10064     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10065         return ParseJsDimensionVpNG(jsValue, result);
10066     }
10067     // Correct type, incorrect value parsing
10068     if (!ParseJsDimensionVp(jsValue, result)) {
10069         return false;
10070     }
10071     return true;
10072 }
10073 
10074 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)10075 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
10076 {
10077     JSRef<JSVal> arg = info[0];
10078     if (arg->IsUndefined() || arg->IsNull()) {
10079         std::vector<ObscuredReasons> reasons(0);
10080         ViewAbstractModel::GetInstance()->SetObscured(reasons);
10081         return;
10082     }
10083     if (!arg->IsArray()) {
10084         return;
10085     }
10086 
10087     auto obscuredArray = JSRef<JSArray>::Cast(arg);
10088     size_t size = obscuredArray->Length();
10089     std::vector<ObscuredReasons> reasons(size);
10090     reasons.clear();
10091     for (size_t i = 0; i < size; i++) {
10092         JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
10093         if (reason->IsNumber()) {
10094             reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
10095         }
10096     }
10097 
10098     ViewAbstractModel::GetInstance()->SetObscured(reasons);
10099 }
10100 
10101 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)10102 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
10103 {
10104     auto sensitiveInfo = info[0];
10105     if (sensitiveInfo->IsUndefined()) {
10106         ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
10107         return;
10108     }
10109     bool sensitive = false;
10110     if (sensitiveInfo->IsBoolean()) {
10111         sensitive = sensitiveInfo->ToBoolean();
10112     }
10113     ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
10114 }
10115 
JSRenderGroup(const JSCallbackInfo & info)10116 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
10117 {
10118     if (info.Length() != 1) {
10119         return;
10120     }
10121     bool isRenderGroup = false;
10122     if (info[0]->IsBoolean()) {
10123         isRenderGroup = info[0]->ToBoolean();
10124     }
10125     ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
10126 }
10127 
JSRenderFit(const JSCallbackInfo & info)10128 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
10129 {
10130     if (info.Length() != 1) {
10131         return;
10132     }
10133     RenderFit renderFit = RenderFit::TOP_LEFT;
10134     if (info[0]->IsNumber()) {
10135         int32_t fitNumber = info[0]->ToNumber<int32_t>();
10136         if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
10137             fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
10138             renderFit = static_cast<RenderFit>(fitNumber);
10139         }
10140     }
10141     // how content fills the node duration implicit animation
10142     ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
10143 }
10144 
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)10145 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
10146 {
10147     if (!jsValue->IsObject() || jsValue->IsString()) {
10148         return false;
10149     }
10150     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10151     if (!jsObj->IsUndefined()) {
10152         JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
10153         JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
10154         if (bundle->IsString() && module->IsString()) {
10155             bundleName = bundle->ToString();
10156             moduleName = module->ToString();
10157             return true;
10158         }
10159     }
10160     return false;
10161 }
10162 
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)10163 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
10164     const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
10165 {
10166     std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx](
10167                                                                          NG::DrawingContext& context) -> void {
10168         JAVASCRIPT_EXECUTION_SCOPE(execCtx);
10169 
10170         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
10171         objectTemplate->SetInternalFieldCount(1);
10172         JSRef<JSObject> contextObj = objectTemplate->NewInstance();
10173         JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
10174         sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
10175         sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
10176         contextObj->SetPropertyObject("size", sizeObj);
10177 
10178         JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
10179         sizeInPxObj->SetProperty<float>("height", context.height);
10180         sizeInPxObj->SetProperty<float>("width", context.width);
10181         contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
10182 
10183         auto engine = EngineHelper::GetCurrentEngine();
10184         CHECK_NULL_VOID(engine);
10185         NativeEngine* nativeEngine = engine->GetNativeEngine();
10186         napi_env env = reinterpret_cast<napi_env>(nativeEngine);
10187         ScopeRAII scope(env);
10188 
10189         auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
10190         OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
10191         napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
10192         if (unwrapCanvas) {
10193             unwrapCanvas->SaveCanvas();
10194             unwrapCanvas->ClipCanvas(context.width, context.height);
10195         }
10196         JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
10197         contextObj->SetPropertyObject("canvas", jsCanvasVal);
10198 
10199         auto jsVal = JSRef<JSVal>::Cast(contextObj);
10200         panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
10201         JSValueWrapper valueWrapper = value;
10202         napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
10203 
10204         napi_wrap(
10205             env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
10206 
10207         JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
10208         if (unwrapCanvas) {
10209             unwrapCanvas->RestoreCanvas();
10210             unwrapCanvas->ResetCanvas();
10211         }
10212     };
10213     return drawCallback;
10214 }
10215 
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)10216 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
10217 {
10218     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10219         return false;
10220     }
10221     Color borderColor;
10222     if (ParseJsColor(args, borderColor)) {
10223         colorProperty.SetColor(borderColor);
10224         return true;
10225     } else if (args->IsObject()) {
10226         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10227         CommonColor commonColor;
10228         ParseCommonEdgeColors(obj, commonColor);
10229         colorProperty.topColor = commonColor.top;
10230         colorProperty.bottomColor = commonColor.bottom;
10231         colorProperty.leftColor = commonColor.left;
10232         colorProperty.rightColor = commonColor.right;
10233         colorProperty.multiValued = true;
10234         return true;
10235     }
10236     return false;
10237 }
10238 
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)10239 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
10240 {
10241     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10242         return false;
10243     }
10244     CalcDimension borderWidth;
10245     if (ParseJsDimensionVpNG(args, borderWidth, true)) {
10246         if (borderWidth.IsNegative()) {
10247             borderWidth.Reset();
10248         }
10249         borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth });
10250         return true;
10251     } else if (args->IsObject()) {
10252         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10253         CommonCalcDimension commonCalcDimension;
10254         ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
10255         borderWidthProperty.topDimen = commonCalcDimension.top;
10256         borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
10257         borderWidthProperty.leftDimen = commonCalcDimension.left;
10258         borderWidthProperty.rightDimen = commonCalcDimension.right;
10259         borderWidthProperty.multiValued = true;
10260         return true;
10261     }
10262     return false;
10263 }
10264 
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)10265 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
10266 {
10267     if (!args->IsObject() && !args->IsNumber()) {
10268         return false;
10269     }
10270     if (args->IsObject()) {
10271         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10272         auto leftValue = obj->GetProperty("left");
10273         if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
10274             ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
10275         }
10276         auto rightValue = obj->GetProperty("right");
10277         if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
10278             ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
10279         }
10280         auto topValue = obj->GetProperty("top");
10281         if (!topValue->IsUndefined() && topValue->IsNumber()) {
10282             ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
10283         }
10284         auto bottomValue = obj->GetProperty("bottom");
10285         if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
10286             ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
10287         }
10288         borderStyleProperty.multiValued = true;
10289         return true;
10290     }
10291     std::optional<BorderStyle> borderStyle;
10292     if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
10293         borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
10294         return true;
10295     }
10296     return false;
10297 }
10298 
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10299 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10300 {
10301     std::optional<CalcDimension> radiusTopLeft;
10302     std::optional<CalcDimension> radiusTopRight;
10303     std::optional<CalcDimension> radiusBottomLeft;
10304     std::optional<CalcDimension> radiusBottomRight;
10305     CalcDimension topLeft;
10306     if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) {
10307         radiusTopLeft = topLeft;
10308     }
10309     CalcDimension topRight;
10310     if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) {
10311         radiusTopRight = topRight;
10312     }
10313     CalcDimension bottomLeft;
10314     if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) {
10315         radiusBottomLeft = bottomLeft;
10316     }
10317     CalcDimension bottomRight;
10318     if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) {
10319         radiusBottomRight = bottomRight;
10320     }
10321     CheckLengthMetrics(object);
10322     radius.radiusTopLeft = radiusTopLeft;
10323     radius.radiusTopRight = radiusTopRight;
10324     radius.radiusBottomLeft = radiusBottomLeft;
10325     radius.radiusBottomRight = radiusBottomRight;
10326     radius.multiValued = true;
10327     return;
10328 }
10329 
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10330 void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10331 {
10332     if (CheckLengthMetrics(object)) {
10333         std::optional<CalcDimension> radiusTopStart;
10334         std::optional<CalcDimension> radiusTopEnd;
10335         std::optional<CalcDimension> radiusBottomStart;
10336         std::optional<CalcDimension> radiusBottomEnd;
10337         if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
10338             JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
10339             CalcDimension calcDimension;
10340             if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
10341                 CheckDimensionUnit(calcDimension, false, true);
10342                 radiusTopStart = calcDimension;
10343             }
10344         }
10345         if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
10346             JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
10347             CalcDimension calcDimension;
10348             if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
10349                 CheckDimensionUnit(calcDimension, false, true);
10350                 radiusTopEnd = calcDimension;
10351             }
10352         }
10353         if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
10354             JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
10355             CalcDimension calcDimension;
10356             if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
10357                 CheckDimensionUnit(calcDimension, false, true);
10358                 radiusBottomStart = calcDimension;
10359             }
10360         }
10361         if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
10362             JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
10363             CalcDimension calcDimension;
10364             if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
10365                 CheckDimensionUnit(calcDimension, false, true);
10366                 radiusBottomEnd = calcDimension;
10367             }
10368         }
10369         auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
10370         radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
10371         radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
10372         radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
10373         radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
10374         radius.multiValued = true;
10375         return;
10376     }
10377     ParseBorderRadiusProps(object, radius);
10378 }
10379 
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)10380 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
10381 {
10382     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10383         return false;
10384     }
10385     CalcDimension borderRadius;
10386     if (ParseJsDimensionVpNG(args, borderRadius, true)) {
10387         radius = NG::BorderRadiusProperty(borderRadius);
10388         radius.multiValued = false;
10389     } else if (args->IsObject()) {
10390         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
10391         ParseCommonBorderRadiusProps(object, radius);
10392     } else {
10393         return false;
10394     }
10395     return true;
10396 }
10397 
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)10398 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10399 {
10400     JSRef<JSVal> arg = info[0];
10401     if (!arg->IsObject()) {
10402         return;
10403     }
10404     JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
10405     auto vm = info.GetVm();
10406     auto globalObj = JSNApi::GetGlobalObject(vm);
10407     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
10408     JsiValue jsiValue(globalFunc);
10409     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
10410     if (globalFuncRef->IsFunction()) {
10411         auto modifierObj = obj->GetProperty("modifier");
10412         if (modifierObj->IsUndefined()) {
10413             option.onApply = nullptr;
10414         } else {
10415             RefPtr<JsFunction> jsFunc =
10416                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
10417             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10418                                modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
10419                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10420                 auto node = frameNode.Upgrade();
10421                 JSRef<JSVal> params[PARAMETER_LENGTH_SECOND];
10422                 params[0] = modifier;
10423                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
10424                 PipelineContext::SetCallBackNode(node);
10425                 func->ExecuteJS(PARAMETER_LENGTH_SECOND, params);
10426             };
10427             option.onApply = onApply;
10428         }
10429     }
10430 }
10431 
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)10432 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10433 {
10434     if (!info[0]->IsObject()) {
10435         return;
10436     }
10437     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
10438     auto numberBadge = obj->GetProperty("numberBadge");
10439     if (!numberBadge->IsEmpty()) {
10440         if (numberBadge->IsNumber()) {
10441             int64_t number = numberBadge->ToNumber<int64_t>();
10442             if (number < 0 || number > INT_MAX) {
10443                 option.isNumber = false;
10444                 option.isShowBadge = true;
10445             } else {
10446                 option.isNumber = true;
10447                 option.badgeNumber = numberBadge->ToNumber<int>();
10448             }
10449         } else if (numberBadge->IsBoolean()) {
10450             option.isNumber = false;
10451             option.isShowBadge = numberBadge->ToBoolean();
10452         }
10453     } else {
10454         option.isNumber = false;
10455         option.isShowBadge = true;
10456     }
10457 }
10458 
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10459 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10460 {
10461     // Parse cornerRadius.
10462     auto cornerRadiusValue = obj->GetProperty("cornerRadius");
10463     NG::BorderRadiusProperty radius;
10464     if (ParseBorderRadius(cornerRadiusValue, radius)) {
10465         properties.borderRadius = radius;
10466     }
10467     // Parse border width
10468     auto borderWidthValue = obj->GetProperty("borderWidth");
10469     NG::BorderWidthProperty borderWidth;
10470     if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
10471         properties.borderWidth = borderWidth;
10472         auto colorValue = obj->GetProperty("borderColor");
10473         NG::BorderColorProperty borderColor;
10474         if (ParseBorderColorProps(colorValue, borderColor)) {
10475             properties.borderColor = borderColor;
10476         } else {
10477             borderColor.SetColor(Color::BLACK);
10478             properties.borderColor = borderColor;
10479         }
10480         // Parse border style
10481         auto styleValue = obj->GetProperty("borderStyle");
10482         NG::BorderStyleProperty borderStyle;
10483         if (ParseBorderStyleProps(styleValue, borderStyle)) {
10484             properties.borderStyle = borderStyle;
10485         } else {
10486             properties.borderStyle = NG::BorderStyleProperty(
10487                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
10488         }
10489     }
10490     auto shadowValue = obj->GetProperty("shadow");
10491     Shadow shadow;
10492     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
10493         properties.shadow = shadow;
10494     }
10495     auto widthValue = obj->GetProperty("width");
10496     CalcDimension width;
10497     if (ParseJsDimensionVpNG(widthValue, width, true)) {
10498         properties.width = width;
10499     }
10500     auto heightValue = obj->GetProperty("height");
10501     CalcDimension height;
10502     if (ParseJsDimensionVpNG(heightValue, height, true)) {
10503         properties.height = height;
10504     }
10505 }
10506 
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)10507 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
10508 {
10509     auto* vm = info.GetVm();
10510     return [vm, nodeId](const std::string& key) -> std::string {
10511         std::string resultString = std::string();
10512         CHECK_NULL_RETURN(vm, resultString);
10513         panda::LocalScope scope(vm);
10514         auto global = JSNApi::GetGlobalObject(vm);
10515         auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
10516         if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
10517             return resultString;
10518         }
10519         auto obj = getCustomProperty->ToObject(vm);
10520         panda::Local<panda::FunctionRef> func = obj;
10521         panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
10522             panda::StringRef::NewFromUtf8(vm, key.c_str()) };
10523         auto function = panda::CopyableGlobal(vm, func);
10524         auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
10525         if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
10526             return resultString;
10527         }
10528         auto value = callValue->ToString(vm)->ToString(vm);
10529         return value;
10530     };
10531 }
10532 
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)10533 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
10534 {
10535     auto* vm = info.GetVm();
10536     panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
10537         info[1]->GetLocalHandle() };
10538     return [vm, params3]() -> bool {
10539         CHECK_NULL_RETURN(vm, false);
10540         panda::LocalScope scope(vm);
10541         auto global = JSNApi::GetGlobalObject(vm);
10542         auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
10543         if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
10544             return false;
10545         }
10546         auto obj = setCustomProperty->ToObject(vm);
10547         panda::Local<panda::FunctionRef> func = obj;
10548         auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10549         auto nodeId = frameNode->GetId();
10550         auto function = panda::CopyableGlobal(vm, func);
10551         auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
10552         if (customPropertyExisted) {
10553             frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
10554                 CHECK_NULL_VOID(vm);
10555                 panda::LocalScope scope(vm);
10556                 auto global = JSNApi::GetGlobalObject(vm);
10557                 auto removeCustomProperty =
10558                     global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
10559                 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
10560                     return;
10561                 }
10562                 auto obj = removeCustomProperty->ToObject(vm);
10563                 panda::Local<panda::FunctionRef> func = obj;
10564                 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
10565                 auto function = panda::CopyableGlobal(vm, func);
10566                 function->Call(vm, function.ToLocal(), params, 1);
10567             });
10568         }
10569         return true;
10570     };
10571 }
10572 
JsCustomProperty(const JSCallbackInfo & info)10573 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
10574 {
10575     if (info[0]->GetLocalHandle()->IsUndefined()) {
10576         return;
10577     }
10578     auto* vm = info.GetVm();
10579     CHECK_NULL_VOID(vm);
10580     auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10581     auto nodeId = frameNode->GetId();
10582     auto getFunc = ParseJsGetFunc(info, nodeId);
10583     auto func = ParseJsFunc(info, nodeId);
10584     frameNode->SetJSCustomProperty(func, getFunc);
10585 }
10586 
JsGestureModifier(const JSCallbackInfo & info)10587 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
10588 {
10589     auto* vm = info.GetExecutionContext().vm_;
10590     CHECK_NULL_VOID(vm);
10591     auto global = JSNApi::GetGlobalObject(vm);
10592     auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
10593     if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
10594         return;
10595     }
10596     auto obj = gestureModifier->ToObject(vm);
10597     panda::Local<panda::FunctionRef> func = obj;
10598     auto thisObj = info.This()->GetLocalHandle();
10599     panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
10600     func->Call(vm, thisObj, params, 1);
10601 }
10602 
JsBackgroundImageResizable(const JSCallbackInfo & info)10603 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
10604 {
10605     auto infoObj = info[0];
10606     ImageResizableSlice sliceResult;
10607     if (!infoObj->IsObject()) {
10608         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10609         return;
10610     }
10611     JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
10612     if (resizableObject->IsEmpty()) {
10613         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10614         return;
10615     }
10616     auto sliceValue = resizableObject->GetProperty("slice");
10617     if (!sliceValue->IsObject()) {
10618         return;
10619     }
10620     JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
10621     if (sliceObj->IsEmpty()) {
10622         ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10623         return;
10624     }
10625     for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
10626         auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
10627         CalcDimension sliceDimension;
10628         if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
10629             continue;
10630         }
10631         if (!sliceDimension.IsValid()) {
10632             continue;
10633         }
10634         switch (static_cast<BorderImageDirection>(i)) {
10635             case BorderImageDirection::LEFT:
10636                 sliceResult.left = sliceDimension;
10637                 break;
10638             case BorderImageDirection::RIGHT:
10639                 sliceResult.right = sliceDimension;
10640                 break;
10641             case BorderImageDirection::TOP:
10642                 sliceResult.top = sliceDimension;
10643                 break;
10644             case BorderImageDirection::BOTTOM:
10645                 sliceResult.bottom = sliceDimension;
10646                 break;
10647             default:
10648                 break;
10649         }
10650     }
10651     ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10652 }
10653 
JsFocusScopeId(const JSCallbackInfo & info)10654 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
10655 {
10656     if (info.Length() == 0) {
10657         return;
10658     }
10659 
10660     std::string focusScopeId;
10661     if (info[0]->IsString()) {
10662         focusScopeId = info[0]->ToString();
10663     }
10664 
10665     bool isGroup = false;
10666     if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
10667         info[1]->IsBoolean()) {
10668         isGroup = info[1]->ToBoolean();
10669     }
10670     ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup);
10671 }
10672 
JsFocusScopePriority(const JSCallbackInfo & info)10673 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
10674 {
10675     if (info.Length() == 0) {
10676         return;
10677     }
10678 
10679     if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
10680         return;
10681     }
10682     std::string focusScopeId = info[0]->ToString();
10683 
10684     int32_t focusPriority = 0;
10685     if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
10686         info[1]->IsNumber()) {
10687         focusPriority = info[1]->ToNumber<int32_t>();
10688     }
10689     ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
10690 }
10691 
ParseJsPropertyId(const JSRef<JSVal> & jsValue)10692 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
10693 {
10694     int32_t resId = 0;
10695     if (jsValue->IsObject()) {
10696         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10697         JSRef<JSVal> tmp = jsObj->GetProperty("id");
10698         if (!tmp->IsNull() && tmp->IsNumber()) {
10699             resId = tmp->ToNumber<int32_t>();
10700         }
10701     }
10702     return resId;
10703 }
10704 
JsVisualEffect(const JSCallbackInfo & info)10705 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
10706 {
10707     if (!info[0]->IsObject()) {
10708         return;
10709     }
10710     auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
10711     ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
10712 }
10713 
JsBackgroundFilter(const JSCallbackInfo & info)10714 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
10715 {
10716     if (!info[0]->IsObject()) {
10717         return;
10718     }
10719     auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
10720     ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
10721 }
10722 
JsForegroundFilter(const JSCallbackInfo & info)10723 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
10724 {
10725     if (!info[0]->IsObject()) {
10726         return;
10727     }
10728     auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
10729     ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
10730 }
10731 
JsCompositingFilter(const JSCallbackInfo & info)10732 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
10733 {
10734     if (!info[0]->IsObject()) {
10735         return;
10736     }
10737     auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
10738     ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
10739 }
10740 
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)10741 void JSViewAbstract::ParseOnCreateMenu(
10742     const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
10743 {
10744     if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
10745         return;
10746     }
10747     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10748     auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
10749         JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
10750     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
10751                           instanceId = Container::CurrentId(), node = frameNode](
10752                           const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
10753         ContainerScope scope(instanceId);
10754         std::vector<NG::MenuOptionsParam> menuParams;
10755         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
10756         auto pipelineContext = PipelineContext::GetCurrentContext();
10757         CHECK_NULL_RETURN(pipelineContext, menuParams);
10758 
10759         pipelineContext->UpdateCurrentActiveNode(node);
10760         auto menuItem = func->ExecuteWithValue(systemMenuItems);
10761         if (!menuItem->IsArray()) {
10762             return menuParams;
10763         }
10764         auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
10765         for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
10766             auto menuItem = menuItemsArray->GetValueAt(i);
10767             if (!menuItem->IsObject()) {
10768                 continue;
10769             }
10770             auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
10771             NG::MenuOptionsParam menuOptionsParam;
10772             auto jsContent = menuItemObject->GetProperty("content");
10773             std::string content;
10774             ParseJsString(jsContent, content);
10775             menuOptionsParam.content = content;
10776             auto jsStartIcon = menuItemObject->GetProperty("icon");
10777             std::string icon;
10778             ParseJsMedia(jsStartIcon, icon);
10779             menuOptionsParam.icon = icon;
10780             auto jsTextMenuId = menuItemObject->GetProperty("id");
10781             std::string id;
10782             if (jsTextMenuId->IsObject()) {
10783                 auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
10784                 auto jsId = textMenuIdObject->GetProperty("id_");
10785                 ParseJsString(jsId, id);
10786             }
10787             menuOptionsParam.id = id;
10788             menuParams.emplace_back(menuOptionsParam);
10789         }
10790         return menuParams;
10791     };
10792     onCreateMenuCallback = jsCallback;
10793 }
10794 
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)10795 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
10796 {
10797     JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
10798     uint32_t idx = 0;
10799     for (const auto& item : systemMenuItems) {
10800         systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
10801     }
10802     return systemMenuItemsArray;
10803 }
10804 
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)10805 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
10806     NG::OnMenuItemClickCallback& onMenuItemClick)
10807 {
10808     auto tmpInfo = info[0];
10809     if (info.Length() != 1 || !tmpInfo->IsObject()) {
10810         return false;
10811     }
10812     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10813     auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
10814     auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
10815     ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
10816 
10817     auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
10818     if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
10819         return false;
10820     }
10821     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
10822     auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10823                           onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
10824                           node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
10825         ContainerScope scope(instanceId);
10826         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
10827         auto pipelineContext = PipelineContext::GetCurrentContext();
10828         CHECK_NULL_RETURN(pipelineContext, false);
10829         pipelineContext->UpdateCurrentActiveNode(node);
10830         auto paramArray = onMenuItemCallback(menuOptionsParam);
10831         if (paramArray->Length() != 2) {
10832             return false;
10833         }
10834         JSRef<JSVal> params[2];
10835         params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
10836         params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
10837         auto ret = func->ExecuteJS(2, params);
10838         if (ret->IsBoolean()) {
10839             return ret->ToBoolean();
10840         }
10841         return false;
10842     };
10843     onMenuItemClick = jsCallback;
10844     return true;
10845 }
10846 
CreateJsTextMenuId(const std::string & id)10847 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
10848 {
10849     JSRef<JSObject> empty;
10850     auto engine = EngineHelper::GetCurrentEngine();
10851     CHECK_NULL_RETURN(engine, empty);
10852     NativeEngine* nativeEngine = engine->GetNativeEngine();
10853     CHECK_NULL_RETURN(nativeEngine, empty);
10854     auto env = reinterpret_cast<napi_env>(nativeEngine);
10855 
10856     napi_value global;
10857     napi_status ret = napi_get_global(env, &global);
10858     if (ret != napi_ok) {
10859         return empty;
10860     }
10861     napi_value constructor;
10862     ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
10863     if (ret != napi_ok) {
10864         return empty;
10865     }
10866 
10867     napi_value obj;
10868     napi_value menuId = nullptr;
10869 
10870     ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
10871     if (ret != napi_ok) {
10872         return empty;
10873     }
10874     ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
10875     if (ret != napi_ok) {
10876         return empty;
10877     }
10878 
10879     JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
10880     if (!value->IsObject()) {
10881         return empty;
10882     }
10883 
10884     return JSRef<JSObject>::Cast(value);
10885 }
10886 
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)10887 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
10888 {
10889     JSRef<JSArray> params = JSRef<JSArray>::New();
10890     params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
10891     params->SetValueAt(1, CreateJsTextRange(menuItemParam));
10892     return params;
10893 }
10894 
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)10895 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
10896 {
10897     JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
10898     TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
10899     JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
10900     TextMenuItem->SetPropertyObject("id", obj);
10901     return JSRef<JSVal>::Cast(TextMenuItem);
10902 }
10903 
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)10904 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
10905 {
10906     JSRef<JSObject> textRange = JSRef<JSObject>::New();
10907     textRange->SetProperty<int32_t>("start", menuItemParam.start);
10908     textRange->SetProperty<int32_t>("end", menuItemParam.end);
10909     return JSRef<JSVal>::Cast(textRange);
10910 }
10911 
OHOS_ACE_ParseJsMedia(void * value,void * resource)10912 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
10913 {
10914     napi_value napiValue = reinterpret_cast<napi_value>(value);
10915     ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
10916     if (!napiValue || !res) {
10917         return;
10918     }
10919     JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
10920     std::string src;
10921     std::string bundleName;
10922     std::string moduleName;
10923     JSViewAbstract::ParseJsMedia(jsVal, src);
10924     JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
10925     res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
10926     res->src = src;
10927     res->bundleName = bundleName;
10928     res->moduleName = moduleName;
10929 }
10930 
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)10931 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
10932     std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
10933 {
10934     if (!modifierObj->IsObject()) {
10935         textStyleApply = nullptr;
10936         return;
10937     }
10938     auto vm = info.GetVm();
10939     auto globalObj = JSNApi::GetGlobalObject(vm);
10940     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
10941     JsiValue jsiValue(globalFunc);
10942     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
10943     if (!globalFuncRef->IsFunction()) {
10944         textStyleApply = nullptr;
10945         return;
10946     }
10947     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
10948     auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10949                     modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
10950         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10951         auto node = frameNode.Upgrade();
10952         CHECK_NULL_VOID(node);
10953         JSRef<JSVal> params[2];
10954         params[0] = modifierParam;
10955         params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
10956         PipelineContext::SetCallBackNode(node);
10957         func->ExecuteJS(2, params);
10958     };
10959     textStyleApply = onApply;
10960 }
10961 
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)10962 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
10963     std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
10964 {
10965     auto vm = info.GetVm();
10966     auto globalObj = JSNApi::GetGlobalObject(vm);
10967     auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
10968     JsiValue jsiValue(globalFunc);
10969     JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
10970     if (globalFuncRef->IsFunction()) {
10971         RefPtr<JsFunction> jsFunc =
10972             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
10973         if (!modifierObj->IsObject()) {
10974             symbolApply = nullptr;
10975         } else {
10976             auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10977                                modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
10978                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10979                 auto node = frameNode.Upgrade();
10980                 CHECK_NULL_VOID(node);
10981                 JSRef<JSVal> params[2];
10982                 params[0] = modifierParam;
10983                 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
10984                 PipelineContext::SetCallBackNode(node);
10985                 func->ExecuteJS(2, params);
10986             };
10987             symbolApply = onApply;
10988         }
10989     }
10990 }
10991 } // namespace OHOS::Ace::Framework
10992