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, ¶m);
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