1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
17
18 #include <algorithm>
19 #include <cstdint>
20 #include <functional>
21 #include <memory>
22 #include <optional>
23 #include <regex>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 #include <unordered_map>
28
29 #include "base/geometry/calc_dimension.h"
30 #include "base/geometry/dimension.h"
31 #include "base/geometry/matrix4.h"
32 #include "base/geometry/ng/offset_t.h"
33 #include "base/geometry/ng/vector.h"
34 #include "base/geometry/shape.h"
35 #include "base/json/json_util.h"
36 #include "base/log/ace_scoring_log.h"
37 #include "base/log/log.h"
38 #include "base/memory/ace_type.h"
39 #include "base/memory/referenced.h"
40 #include "base/utils/utils.h"
41 #include "base/utils/utf_helper.h"
42 #include "bridge/common/utils/engine_helper.h"
43 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
44 #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h"
45 #include "bridge/declarative_frontend/engine/functions/js_event_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_on_child_touch_test_function.h"
47 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
48 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
49 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
50 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
51 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
52 #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h"
53 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
54 #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h"
55 #include "bridge/declarative_frontend/engine/functions/js_touch_test_done_function.h"
56 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
57 #include "bridge/declarative_frontend/engine/js_types.h"
58 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h"
59 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
60 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
61 #include "bridge/declarative_frontend/engine/js_converter.h"
62 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
63 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
64 #include "bridge/declarative_frontend/jsview/js_utils.h"
65 #include "bridge/declarative_frontend/jsview/js_view_context.h"
66 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
67 #include "bridge/declarative_frontend/jsview/js_layoutable_view.h"
68 #include "core/event/focus_axis_event.h"
69 #include "canvas_napi/js_canvas.h"
70 #ifdef SUPPORT_DIGITAL_CROWN
71 #include "bridge/declarative_frontend/engine/functions/js_crown_function.h"
72 #endif
73 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
74 #include "core/components/text_overlay/text_overlay_theme.h"
75 #include "core/components/theme/shadow_theme.h"
76 #ifdef PLUGIN_COMPONENT_SUPPORTED
77 #include "core/common/plugin_manager.h"
78 #endif
79 #include "interfaces/native/node/resource.h"
80
81 #include "core/common/card_scope.h"
82 #include "core/common/resource/resource_manager.h"
83 #include "core/common/resource/resource_wrapper.h"
84 #include "core/common/resource/resource_parse_utils.h"
85 #include "core/common/resource/resource_configuration.h"
86 #include "core/components_ng/base/view_abstract_model_ng.h"
87 #include "core/components_ng/base/view_stack_model.h"
88 #include "core/components_ng/base/inspector.h"
89 #include "core/components_ng/pattern/toolbaritem/toolbaritem_model.h"
90 #include "core/event/key_event.h"
91
92 #include "interfaces/inner_api/ace_kit/include/ui/properties/safe_area_insets.h"
93
94 namespace OHOS::Ace::NG {
95 constexpr uint32_t DEFAULT_GRID_SPAN = 1;
96 constexpr int32_t DEFAULT_GRID_OFFSET = 0;
97 }
98
99 namespace OHOS::Ace {
100 namespace {
101 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
102 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
103 constexpr int32_t DIRECTION_COUNT = 4;
104 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
105 constexpr int NUM1 = 1;
106 constexpr int NUM2 = 2;
107 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
108 HoverModeAreaType::BOTTOM_SCREEN };
109 const std::string CUSTOM_SYMBOL_SUFFIX = "_CustomSymbol";
110 } // namespace
111
GetInstance()112 ViewAbstractModel* ViewAbstractModel::GetInstance()
113 {
114 #ifdef NG_BUILD
115 static NG::ViewAbstractModelNG instance;
116 return &instance;
117 #else
118 if (Container::IsCurrentUseNewPipeline()) {
119 static NG::ViewAbstractModelNG instance;
120 return &instance;
121 } else {
122 static Framework::ViewAbstractModelImpl instance;
123 return &instance;
124 }
125 #endif
126 }
127 } // namespace OHOS::Ace
128
129 namespace OHOS::Ace::Framework {
130 namespace {
131
132 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
133 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
134 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
135 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
136 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
137 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
138 constexpr uint32_t LAYOUT_SAFE_AREA_TYPE_LIMIT = 2;
139 constexpr uint32_t LAYOUT_SAFE_AREA_EDGE_LIMIT = 6;
140 constexpr int32_t MAX_ALIGN_VALUE = 8;
141 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
142 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
143 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
144 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
145 constexpr double FULL_DIMENSION = 100.0;
146 constexpr double HALF_DIMENSION = 50.0;
147 constexpr double ROUND_UNIT = 360.0;
148 constexpr double VISIBLE_RATIO_MIN = 0.0;
149 constexpr double VISIBLE_RATIO_MAX = 1.0;
150 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
151 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
152 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
153 constexpr int32_t SECOND_INDEX = 2;
154 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
155 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
156 constexpr float MAX_ANGLE = 360.0f;
157 constexpr float DEFAULT_BIAS = 0.5f;
158 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
159 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
160 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
161 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
162 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
163 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
164 const std::vector<int32_t> LENGTH_METRICS_KEYS {
165 static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
166 static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
167 const char* START_PROPERTY = "start";
168 const char* END_PROPERTY = "end";
169 const char* TOP_PROPERTY = "top";
170 const char* BOTTOM_PROPERTY = "bottom";
171 const char* LEFT_PROPERTY = "left";
172 const char* RIGHT_PROPERTY = "right";
173 const char* TOP_START_PROPERTY = "topStart";
174 const char* TOP_END_PROPERTY = "topEnd";
175 const char* BOTTOM_START_PROPERTY = "bottomStart";
176 const char* BOTTOM_END_PROPERTY = "bottomEnd";
177 const char* DEBUG_LINE_INFO_LINE = "$line";
178 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
179
180 enum class MenuItemType { COPY, PASTE, CUT, SELECT_ALL, UNKNOWN, CAMERA_INPUT,
181 AI_WRITER, TRANSLATE, SHARE, SEARCH, ASK_CELIA };
182 enum class BackgroundType { CUSTOM_BUILDER, COLOR };
183
184 const int32_t NUM_0 = 0;
185 const int32_t NUM_1 = 1;
186 const int32_t NUM_2 = 2;
187
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)188 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
189 CalcDimension& centerX, CalcDimension& centerY)
190 {
191 double xVal = 1.0;
192 double yVal = 1.0;
193 double zVal = 1.0;
194 if (!jsValue->IsObject()) {
195 scaleX = static_cast<float>(xVal);
196 scaleY = static_cast<float>(yVal);
197 scaleZ = static_cast<float>(zVal);
198 CalcDimension length;
199 centerX = length;
200 centerY = length;
201 return;
202 }
203 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
204 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
205 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
206 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
207 scaleX = static_cast<float>(xVal);
208 scaleY = static_cast<float>(yVal);
209 scaleZ = static_cast<float>(zVal);
210 // if specify centerX
211 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
212 // if specify centerY
213 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
214 }
215
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)216 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
217 CalcDimension& translateZ)
218 {
219 if (!jsValue->IsObject()) {
220 return;
221 }
222 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
223 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
224 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
225 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
226 }
227
GetDefaultRotateVector(double & dx,double & dy,double & dz)228 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
229 {
230 dx = 0.0;
231 dy = 0.0;
232 dz = 0.0;
233 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
234 dz = 1.0;
235 }
236 }
237
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)238 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
239 {
240 if (!jsValue->IsObject()) {
241 return;
242 }
243 // default: dx, dy, dz (0.0, 0.0, 0.0)
244 double dxVal = 0.0;
245 double dyVal = 0.0;
246 double dzVal = 0.0;
247 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
248 auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
249 auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
250 auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
251 if (jsRotateX->IsUndefined()
252 && jsRotateY->IsUndefined()
253 && jsRotateZ->IsUndefined()) {
254 GetDefaultRotateVector(dxVal, dyVal, dzVal);
255 } else {
256 JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
257 JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
258 JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
259 }
260 rotate.xDirection = static_cast<float>(dxVal);
261 rotate.yDirection = static_cast<float>(dyVal);
262 rotate.zDirection = static_cast<float>(dzVal);
263 // if specify centerX
264 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
265 rotate.centerX)) {
266 rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
267 }
268 // if specify centerY
269 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
270 rotate.centerY)) {
271 rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
272 }
273 // if specify centerZ
274 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
275 rotate.centerZ)) {
276 rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
277 }
278 // if specify angle
279 JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
280 rotate.perspective = 0.0f;
281 JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
282 }
283
ParseJsRotateAngle(const JSRef<JSVal> & jsValue,NG::RotateAngleOptions & rotateAngle)284 void ParseJsRotateAngle(const JSRef<JSVal>& jsValue, NG::RotateAngleOptions& rotateAngle)
285 {
286 if (!jsValue->IsObject()) {
287 return;
288 }
289
290 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
291
292 std::optional<float> angleX = 0.0;
293 std::optional<float> angleY = 0.0;
294 std::optional<float> angleZ = 0.0;
295
296 JSViewAbstract::GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE_X), jsObj, angleX, 0.0f);
297 JSViewAbstract::GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE_Y), jsObj, angleY, 0.0f);
298 JSViewAbstract::GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE_Z), jsObj, angleZ, 0.0f);
299
300 rotateAngle.angleX = angleX.value_or(0.0f);
301 rotateAngle.angleY = angleY.value_or(0.0f);
302 rotateAngle.angleZ = angleZ.value_or(0.0f);
303
304 // if specify centerX
305 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
306 rotateAngle.centerX)) {
307 rotateAngle.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
308 }
309 // if specify centerY
310 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
311 rotateAngle.centerY)) {
312 rotateAngle.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
313 }
314 // if specify centerZ
315 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
316 rotateAngle.centerZ)) {
317 rotateAngle.centerZ = Dimension(0.0f, DimensionUnit::VP);
318 }
319 rotateAngle.perspective = 0.0f;
320 JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotateAngle.perspective);
321 }
322
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)323 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
324 {
325 if (!jsValue->IsObject()) {
326 return false;
327 }
328
329 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
330 auto path = jsObj->GetPropertyValue<std::string>("path", "");
331 if (path.empty()) {
332 return false;
333 }
334 option.SetPath(path);
335 double from = 0.0;
336 double to = 1.0;
337 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
338 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
339 if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
340 from = 0.0;
341 }
342 if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
343 to = 1.0;
344 } else if (to < from) {
345 to = from;
346 }
347 option.SetBegin(static_cast<float>(from));
348 option.SetEnd(static_cast<float>(to));
349 option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
350 return true;
351 }
352
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)353 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
354 {
355 isAuto = false;
356 switch (modeValue) {
357 case static_cast<int32_t>(NG::DragPreviewMode::AUTO):
358 previewOption.ResetDragPreviewMode();
359 isAuto = true;
360 break;
361 case static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE):
362 previewOption.isScaleEnabled = false;
363 break;
364 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW):
365 previewOption.isDefaultShadowEnabled = true;
366 break;
367 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS):
368 previewOption.isDefaultRadiusEnabled = true;
369 break;
370 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DRAG_ITEM_GRAY_EFFECT):
371 previewOption.isDefaultDragItemGrayEffectEnabled = true;
372 break;
373 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_MULTI_TILE_EFFECT):
374 previewOption.isMultiTiled = true;
375 break;
376 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW):
377 previewOption.isTouchPointCalculationBasedOnFinalPreviewEnable = true;
378 break;
379 default:
380 break;
381 }
382 }
383
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)384 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
385 BackgroundImagePosition& bgImgPosition)
386 {
387 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
388 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
389 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
390 }
391
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)392 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
393 {
394 auto index = pos + containCount;
395 if (index < 0) {
396 return std::string();
397 }
398
399 JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
400 if (type == "d") {
401 if (item->IsNumber()) {
402 return std::to_string(item->ToNumber<int32_t>());
403 } else if (item->IsObject()) {
404 int32_t result = 0;
405 JSViewAbstract::ParseJsInteger(item, result);
406 return std::to_string(result);
407 }
408 } else if (type == "s") {
409 if (item->IsString()) {
410 return item->ToString();
411 } else if (item->IsObject()) {
412 std::string result;
413 JSViewAbstract::ParseJsString(item, result);
414 return result;
415 }
416 } else if (type == "f") {
417 if (item->IsNumber()) {
418 return std::to_string(item->ToNumber<float>());
419 } else if (item->IsObject()) {
420 double result = 0.0;
421 JSViewAbstract::ParseJsDouble(item, result);
422 return std::to_string(result);
423 }
424 }
425 return std::string();
426 }
427
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)428 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
429 {
430 auto size = static_cast<int32_t>(params->Length());
431 if (containCount == size) {
432 return;
433 }
434 std::string::const_iterator start = originStr.begin();
435 std::string::const_iterator end = originStr.end();
436 std::smatch matches;
437 bool shortHolderType = false;
438 bool firstMatch = true;
439 int searchTime = 0;
440 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
441 std::string pos = matches[2];
442 std::string type = matches[4];
443 if (firstMatch) {
444 firstMatch = false;
445 shortHolderType = pos.length() == 0;
446 } else {
447 if (shortHolderType ^ (pos.length() == 0)) {
448 return;
449 }
450 }
451
452 std::string replaceContentStr;
453 if (shortHolderType) {
454 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
455 } else {
456 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
457 }
458
459 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
460 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
461 end = originStr.end();
462 searchTime++;
463 }
464 }
465
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y,RefPtr<ResourceObject> & xresObj,RefPtr<ResourceObject> & yresObj)466 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y,
467 RefPtr<ResourceObject>& xresObj, RefPtr<ResourceObject>& yresObj)
468 {
469 JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
470 JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
471 bool hasX = false;
472 bool hasY = false;
473 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
474 hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP, xresObj);
475 hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP, yresObj);
476 } else {
477 hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP, xresObj);
478 hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP, yresObj);
479 }
480 return hasX || hasY;
481 }
482
ParseLocationPropsEdgesResObj(EdgesParam & edges,const RefPtr<ResourceObject> & topResObj,const RefPtr<ResourceObject> & leftResObj,const RefPtr<ResourceObject> & bottomResObj,const RefPtr<ResourceObject> & rightResObj)483 void ParseLocationPropsEdgesResObj(EdgesParam& edges, const RefPtr<ResourceObject>& topResObj,
484 const RefPtr<ResourceObject>& leftResObj, const RefPtr<ResourceObject>& bottomResObj,
485 const RefPtr<ResourceObject>& rightResObj)
486 {
487 if (!SystemProperties::ConfigChangePerform()) {
488 return;
489 }
490 edges.resMap_.clear();
491 if (topResObj) {
492 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
493 CalcDimension result;
494 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
495 edges.SetTop(result);
496 };
497 edges.AddResource("edges.top", topResObj, std::move(updateFunc));
498 }
499 if (leftResObj) {
500 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
501 CalcDimension result;
502 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
503 edges.SetLeft(result);
504 };
505 edges.AddResource("edges.left", leftResObj, std::move(updateFunc));
506 }
507 if (bottomResObj) {
508 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
509 CalcDimension result;
510 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
511 edges.SetBottom(result);
512 };
513 edges.AddResource("edges.bottom", bottomResObj, std::move(updateFunc));
514 }
515 if (rightResObj) {
516 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, EdgesParam& edges) {
517 CalcDimension result;
518 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
519 edges.SetRight(result);
520 };
521 edges.AddResource("edges.right", rightResObj, std::move(updateFunc));
522 }
523 }
524
ParseAllBorderRadiusesResObj(NG::BorderRadiusProperty & borderRadius,const RefPtr<ResourceObject> & topLeftResObj,const RefPtr<ResourceObject> & topRightResObj,const RefPtr<ResourceObject> & bottomLeftResObj,const RefPtr<ResourceObject> & bottomRightResObj)525 void ParseAllBorderRadiusesResObj(NG::BorderRadiusProperty& borderRadius, const RefPtr<ResourceObject>& topLeftResObj,
526 const RefPtr<ResourceObject>& topRightResObj, const RefPtr<ResourceObject>& bottomLeftResObj,
527 const RefPtr<ResourceObject>& bottomRightResObj)
528 {
529 if (!SystemProperties::ConfigChangePerform()) {
530 return;
531 }
532 borderRadius.resMap_.clear();
533 if (topLeftResObj) {
534 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
535 CalcDimension result;
536 ResourceParseUtils::ParseResDimensionVp(resObj, result);
537 borderRadius.radiusTopLeft = result;
538 };
539 borderRadius.AddResource("borderRadius.topLeft", topLeftResObj, std::move(updateFunc));
540 }
541 if (topRightResObj) {
542 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
543 CalcDimension result;
544 ResourceParseUtils::ParseResDimensionVp(resObj, result);
545 borderRadius.radiusTopRight = result;
546 };
547 borderRadius.AddResource("borderRadius.topRight", topRightResObj, std::move(updateFunc));
548 }
549 if (bottomLeftResObj) {
550 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
551 CalcDimension result;
552 ResourceParseUtils::ParseResDimensionVp(resObj, result);
553 borderRadius.radiusBottomLeft = result;
554 };
555 borderRadius.AddResource("borderRadius.bottomLeft", bottomLeftResObj, std::move(updateFunc));
556 }
557 if (bottomRightResObj) {
558 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
559 CalcDimension result;
560 ResourceParseUtils::ParseResDimensionVp(resObj, result);
561 borderRadius.radiusBottomRight = result;
562 };
563 borderRadius.AddResource("borderRadius.bottomRight", bottomRightResObj, std::move(updateFunc));
564 }
565 }
566
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)567 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
568 {
569 bool useEdges = false;
570 CalcDimension top;
571 CalcDimension left;
572 CalcDimension bottom;
573 CalcDimension right;
574 RefPtr<ResourceObject> topResObj;
575 RefPtr<ResourceObject> leftResObj;
576 RefPtr<ResourceObject> bottomResObj;
577 RefPtr<ResourceObject> rightResObj;
578 JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
579 JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
580 JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
581 JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
582 if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP, topResObj)) {
583 edges.SetTop(top);
584 useEdges = true;
585 }
586 if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP, leftResObj)) {
587 edges.SetLeft(left);
588 useEdges = true;
589 }
590 if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP, bottomResObj)) {
591 edges.SetBottom(bottom);
592 useEdges = true;
593 }
594 if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP, rightResObj)) {
595 edges.SetRight(right);
596 useEdges = true;
597 }
598 ParseLocationPropsEdgesResObj(edges, topResObj, leftResObj, bottomResObj, rightResObj);
599 return useEdges;
600 }
601
602 decltype(JSViewAbstract::ParseJsLengthMetricsVp)* ParseJsLengthMetrics = JSViewAbstract::ParseJsLengthMetricsVp;
603
ParseJsLengthMetricsToDimension(const JSRef<JSObject> & obj,Dimension & result,RefPtr<ResourceObject> & resourceObj)604 void ParseJsLengthMetricsToDimension(const JSRef<JSObject>& obj, Dimension& result, RefPtr<ResourceObject>& resourceObj)
605 {
606 auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
607 if (!value->IsNumber()) {
608 return;
609 }
610 auto unit = DimensionUnit::VP;
611 auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
612 if (jsUnit->IsNumber()) {
613 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
614 }
615 CalcDimension dimension(value->ToNumber<double>(), unit);
616 result = dimension;
617 auto jsRes = obj->GetProperty("res");
618 if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
619 !jsRes->IsNull() && jsRes->IsObject()) {
620 JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
621 JSViewAbstract::CompleteResourceObject(resObj);
622 resourceObj = JSViewAbstract::GetResourceObject(resObj);
623 }
624 return;
625 }
626
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)627 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
628 {
629 bool useLocalizedEdges = false;
630 CalcDimension start;
631 CalcDimension end;
632 CalcDimension top;
633 CalcDimension bottom;
634
635 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
636 if (startVal->IsObject()) {
637 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
638 ParseJsLengthMetrics(startObj, start);
639 edges.start = start;
640 useLocalizedEdges = true;
641 }
642 JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
643 if (endVal->IsObject()) {
644 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
645 ParseJsLengthMetrics(endObj, end);
646 edges.end = end;
647 useLocalizedEdges = true;
648 }
649 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
650 if (topVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(topVal), top)) {
651 edges.SetTop(top);
652 useLocalizedEdges = true;
653 }
654 JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
655 if (bottomVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(bottomVal), bottom)) {
656 edges.SetBottom(bottom);
657 useLocalizedEdges = true;
658 }
659 return useLocalizedEdges;
660 }
661
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)662 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
663 {
664 bool useMarkAnchorPosition = false;
665 CalcDimension start;
666 CalcDimension top;
667
668 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
669 if (startVal->IsObject()) {
670 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
671 ParseJsLengthMetrics(startObj, start);
672 x = start;
673 useMarkAnchorPosition = true;
674 }
675 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
676 if (topVal->IsObject()) {
677 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
678 ParseJsLengthMetrics(topObj, top);
679 y = top;
680 useMarkAnchorPosition = true;
681 }
682 return useMarkAnchorPosition;
683 }
684
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)685 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
686 {
687 JSRef<JSVal> builder;
688 if (info->IsObject()) {
689 auto builderObj = JSRef<JSObject>::Cast(info);
690 builder = builderObj->GetProperty("builder");
691 } else if (info->IsFunction()) {
692 builder = info;
693 } else {
694 return nullptr;
695 }
696
697 if (!builder->IsFunction()) {
698 return nullptr;
699 }
700
701 return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
702 }
703
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)704 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
705 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
706 {
707 RefPtr<NG::ChainedTransitionEffect> effect;
708 if (effectOption->IsObject()) {
709 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
710 std::optional<float> angle;
711 ParseJsRotate(effectOption, rotate, angle);
712 if (angle.has_value()) {
713 rotate.angle = angle.value();
714 return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
715 }
716 }
717 return nullptr;
718 }
719
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)720 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
721 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
722 {
723 double opacity = 1.0;
724 if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
725 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
726 if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
727 opacity = 1.0;
728 }
729 } else {
730 opacity = std::clamp(opacity, 0.0, 1.0);
731 }
732 return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
733 }
734 return nullptr;
735 }
736
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)737 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
738 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
739 {
740 if (effectOption->IsObject()) {
741 // default: x, y, z (0.0, 0.0, 0.0)
742 NG::TranslateOptions translate;
743 ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
744 return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
745 }
746 return nullptr;
747 }
748
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)749 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
750 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
751 {
752 if (effectOption->IsObject()) {
753 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
754 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
755 ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
756 return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
757 }
758 return nullptr;
759 }
760
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)761 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
762 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
763 {
764 int32_t edge = 0;
765 if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
766 if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
767 edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
768 edge = static_cast<int32_t>(NG::TransitionEdge::START);
769 }
770 return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
771 }
772 return nullptr;
773 }
774
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)775 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
776 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
777 {
778 if (effectOption->IsObject()) {
779 auto effectObj = JSRef<JSObject>::Cast(effectOption);
780 auto appearJsVal = effectObj->GetProperty("appear");
781 auto disappearJsVal = effectObj->GetProperty("disappear");
782 RefPtr<NG::ChainedTransitionEffect> appearEffect;
783 RefPtr<NG::ChainedTransitionEffect> disappearEffect;
784 if (appearJsVal->IsObject()) {
785 auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
786 appearEffect = JSViewAbstract::ParseChainedTransition(appearObj, context);
787 }
788 if (disappearJsVal->IsObject()) {
789 auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
790 disappearEffect = JSViewAbstract::ParseChainedTransition(disappearObj, context);
791 }
792 return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
793 }
794 return nullptr;
795 }
796
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)797 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
798 {
799 CHECK_NULL_RETURN(pipelineContext, 0);
800 return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
801 }
802
803 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
804 const JSRef<JSVal>&, const JSExecutionContext&);
805
GetBundleNameFromContainer()806 std::string GetBundleNameFromContainer()
807 {
808 auto container = Container::Current();
809 CHECK_NULL_RETURN(container, "");
810 return container->GetBundleName();
811 }
812
GetModuleNameFromContainer()813 std::string GetModuleNameFromContainer()
814 {
815 auto container = Container::Current();
816 CHECK_NULL_RETURN(container, "");
817 return container->GetModuleName();
818 }
819
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)820 void CompleteResourceObjectFromParams(
821 int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
822 {
823 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
824 int32_t typeNum = -1;
825 if (type->IsNumber()) {
826 typeNum = type->ToNumber<int32_t>();
827 }
828
829 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
830 if (!args->IsArray()) {
831 return;
832 }
833 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
834 if (resId != UNKNOWN_RESOURCE_ID) {
835 return;
836 }
837 JSRef<JSVal> identity = params->GetValueAt(0);
838
839 bool isParseDollarResourceSuccess =
840 JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
841 if (!isParseDollarResourceSuccess) {
842 return;
843 }
844
845 std::regex resNameRegex(RESOURCE_NAME_PATTERN);
846 std::smatch resNameResults;
847 if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
848 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
849 }
850
851 if (typeNum == UNKNOWN_RESOURCE_TYPE) {
852 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
853 }
854 }
855
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)856 void CompleteResourceObjectFromId(
857 JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
858 {
859 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
860 if (!args->IsArray()) {
861 return;
862 }
863 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
864 auto paramCount = params->Length();
865 JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
866 if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
867 std::vector<JSRef<JSVal>> tmpParams;
868 for (uint32_t i = 0; i < paramCount; i++) {
869 auto param = params->GetValueAt(i);
870 tmpParams.insert(tmpParams.end(), param);
871 }
872 params->SetValueAt(0, name);
873 uint32_t paramIndex = 1;
874 if (!type->IsEmpty()) {
875 params->SetValueAt(paramIndex, type);
876 paramIndex++;
877 }
878 for (auto tmpParam : tmpParams) {
879 params->SetValueAt(paramIndex, tmpParam);
880 paramIndex++;
881 }
882 } else {
883 params->SetValueAt(0, name);
884 }
885 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
886 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
887 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
888 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
889 }
890 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
891 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
892 }
893 }
894
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)895 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
896 {
897 if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
898 checkDimension.Reset();
899 return;
900 }
901 if (notNegative && checkDimension.IsNegative()) {
902 checkDimension.Reset();
903 return;
904 }
905 }
906
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)907 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
908 {
909 Color left;
910 RefPtr<ResourceObject> leftResObj;
911 if (JSViewAbstract::ParseJsColor(
912 object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left, leftResObj)) {
913 commonColor.left = left;
914 }
915 Color right;
916 RefPtr<ResourceObject> rightResObj;
917 if (JSViewAbstract::ParseJsColor(
918 object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right, rightResObj)) {
919 commonColor.right = right;
920 }
921 Color top;
922 RefPtr<ResourceObject> topResObj;
923 if (JSViewAbstract::ParseJsColor(
924 object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
925 commonColor.top = top;
926 }
927 Color bottom;
928 RefPtr<ResourceObject> bottomResObj;
929 if (JSViewAbstract::ParseJsColor(
930 object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
931 commonColor.bottom = bottom;
932 }
933 if (!SystemProperties::ConfigChangePerform()) {
934 return;
935 }
936 if (leftResObj) {
937 commonColor.leftResObj = leftResObj;
938 }
939 if (rightResObj) {
940 commonColor.rightResObj = rightResObj;
941 }
942 if (topResObj) {
943 commonColor.topResObj = topResObj;
944 }
945 if (bottomResObj) {
946 commonColor.bottomResObj = bottomResObj;
947 }
948 }
949
ParseLocalizedEdgeStartColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)950 void ParseLocalizedEdgeStartColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
951 {
952 if (object->IsUndefined()) {
953 return;
954 }
955 RefPtr<ResourceObject> startResObj;
956 Color start;
957 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start, startResObj)) {
958 borderColors.leftColor = start;
959 }
960 if (startResObj) {
961 auto&& updateFunc = [](const RefPtr<ResourceObject>& startResObj, NG::BorderColorProperty& borderColors) {
962 Color color;
963 ResourceParseUtils::ParseResColor(startResObj, color);
964 borderColors.leftColor = color;
965 };
966 borderColors.AddResource("localizedEdgeColor.start", startResObj, std::move(updateFunc));
967 }
968 }
969
ParseLocalizedEdgeEndColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)970 void ParseLocalizedEdgeEndColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
971 {
972 if (object->IsUndefined()) {
973 return;
974 }
975 RefPtr<ResourceObject> endResObj;
976 Color end;
977 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end, endResObj)) {
978 borderColors.rightColor = end;
979 }
980 if (endResObj) {
981 auto&& updateFunc = [](const RefPtr<ResourceObject>& endResObj, NG::BorderColorProperty& borderColors) {
982 Color color;
983 ResourceParseUtils::ParseResColor(endResObj, color);
984 borderColors.rightColor = color;
985 };
986 borderColors.AddResource("localizedEdgeColor.end", endResObj, std::move(updateFunc));
987 }
988 }
989
ParseLocalizedEdgeTopColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)990 void ParseLocalizedEdgeTopColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
991 {
992 if (object->IsUndefined()) {
993 return;
994 }
995 RefPtr<ResourceObject> topResObj;
996 Color top;
997 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
998 borderColors.topColor = top;
999 }
1000 if (topResObj) {
1001 auto&& updateFunc = [](const RefPtr<ResourceObject>& topResObj, NG::BorderColorProperty& borderColors) {
1002 Color color;
1003 ResourceParseUtils::ParseResColor(topResObj, color);
1004 borderColors.topColor = color;
1005 };
1006 borderColors.AddResource("localizedEdgeColor.top", topResObj, std::move(updateFunc));
1007 }
1008 }
1009
ParseLocalizedEdgeBottomColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1010 void ParseLocalizedEdgeBottomColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1011 {
1012 if (object->IsUndefined()) {
1013 return;
1014 }
1015 RefPtr<ResourceObject> bottomResObj;
1016 Color bottom;
1017 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1018 borderColors.bottomColor = bottom;
1019 }
1020 if (bottomResObj) {
1021 auto&& updateFunc = [](const RefPtr<ResourceObject>& bottomResObj, NG::BorderColorProperty& borderColors) {
1022 Color color;
1023 ResourceParseUtils::ParseResColor(bottomResObj, color);
1024 borderColors.bottomColor = color;
1025 };
1026 borderColors.AddResource("localizedEdgeColor.bottom", bottomResObj, std::move(updateFunc));
1027 }
1028 }
1029
ParseLocalizedEdgeColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1030 void ParseLocalizedEdgeColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1031 {
1032 ParseLocalizedEdgeStartColorsForOutLineColor(object, borderColors);
1033 ParseLocalizedEdgeEndColorsForOutLineColor(object, borderColors);
1034 ParseLocalizedEdgeTopColorsForOutLineColor(object, borderColors);
1035 ParseLocalizedEdgeBottomColorsForOutLineColor(object, borderColors);
1036 }
1037
ParseEdgeLeftColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1038 void ParseEdgeLeftColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1039 {
1040 if (object->IsUndefined()) {
1041 return;
1042 }
1043 RefPtr<ResourceObject> leftResObj;
1044 Color left;
1045 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left, leftResObj)) {
1046 borderColors.leftColor = left;
1047 }
1048 if (leftResObj) {
1049 auto&& updateFunc = [](const RefPtr<ResourceObject>& leftResObj, NG::BorderColorProperty& borderColors) {
1050 Color color;
1051 ResourceParseUtils::ParseResColor(leftResObj, color);
1052 borderColors.leftColor = color;
1053 };
1054 borderColors.AddResource("outLineColor.edgeColor.left", leftResObj, std::move(updateFunc));
1055 }
1056 }
1057
ParseEdgeRightColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1058 void ParseEdgeRightColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1059 {
1060 if (object->IsUndefined()) {
1061 return;
1062 }
1063 RefPtr<ResourceObject> rightResObj;
1064 Color right;
1065 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right, rightResObj)) {
1066 borderColors.rightColor = right;
1067 }
1068 if (rightResObj) {
1069 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1070 Color color;
1071 ResourceParseUtils::ParseResColor(resObj, color);
1072 borderColors.rightColor = color;
1073 };
1074 borderColors.AddResource("outLineColor.edgeColor.right", rightResObj, std::move(updateFunc));
1075 }
1076 }
1077
ParseEdgeTopColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1078 void ParseEdgeTopColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1079 {
1080 if (object->IsUndefined()) {
1081 return;
1082 }
1083 RefPtr<ResourceObject> topResObj;
1084 Color top;
1085 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
1086 borderColors.topColor = top;
1087 }
1088 if (topResObj) {
1089 auto&& updateFunc = [](const RefPtr<ResourceObject>& topResObj, NG::BorderColorProperty& borderColors) {
1090 Color color;
1091 ResourceParseUtils::ParseResColor(topResObj, color);
1092 borderColors.topColor = color;
1093 };
1094 borderColors.AddResource("outLineColor.edgeColor.top", topResObj, std::move(updateFunc));
1095 }
1096 }
1097
ParseEdgeBottomColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1098 void ParseEdgeBottomColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1099 {
1100 if (object->IsUndefined()) {
1101 return;
1102 }
1103 RefPtr<ResourceObject> bottomResObj;
1104 Color bottom;
1105 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1106 borderColors.bottomColor = bottom;
1107 }
1108 if (bottomResObj) {
1109 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1110 Color color;
1111 ResourceParseUtils::ParseResColor(resObj, color);
1112 borderColors.bottomColor = color;
1113 };
1114 borderColors.AddResource("outLineColor.edgeColor.bottom", bottomResObj, std::move(updateFunc));
1115 }
1116 }
1117
ParseEdgeColorsForOutLineColor(const JSRef<JSObject> & object,NG::BorderColorProperty & borderColors)1118 void ParseEdgeColorsForOutLineColor(const JSRef<JSObject>& object, NG::BorderColorProperty& borderColors)
1119 {
1120 ParseEdgeLeftColorsForOutLineColor(object, borderColors);
1121 ParseEdgeRightColorsForOutLineColor(object, borderColors);
1122 ParseEdgeTopColorsForOutLineColor(object, borderColors);
1123 ParseEdgeBottomColorsForOutLineColor(object, borderColors);
1124 }
1125
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1126 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
1127 {
1128 Color start;
1129 RefPtr<ResourceObject> startResObj;
1130 if (JSViewAbstract::ParseJsColor(
1131 object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start, startResObj)) {
1132 localizedColor.start = start;
1133 }
1134 Color end;
1135 RefPtr<ResourceObject> endResObj;
1136 if (JSViewAbstract::ParseJsColor(
1137 object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end, endResObj)) {
1138 localizedColor.end = end;
1139 }
1140 Color top;
1141 RefPtr<ResourceObject> topResObj;
1142 if (JSViewAbstract::ParseJsColor(
1143 object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
1144 localizedColor.top = top;
1145 }
1146 Color bottom;
1147 RefPtr<ResourceObject> bottomResObj;
1148 if (JSViewAbstract::ParseJsColor(
1149 object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1150 localizedColor.bottom = bottom;
1151 }
1152 if (!SystemProperties::ConfigChangePerform()) {
1153 return;
1154 }
1155 if (startResObj) {
1156 localizedColor.startResObj = startResObj;
1157 }
1158 if (endResObj) {
1159 localizedColor.endResObj = endResObj;
1160 }
1161 if (topResObj) {
1162 localizedColor.topResObj = topResObj;
1163 }
1164 if (bottomResObj) {
1165 localizedColor.bottomResObj = bottomResObj;
1166 }
1167 }
1168
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1169 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1170 {
1171 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
1172 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
1173 LocalizedColor localizedColor;
1174 ParseLocalizedEdgeColors(object, localizedColor);
1175 commonColor.top = localizedColor.top;
1176 commonColor.bottom = localizedColor.bottom;
1177 commonColor.left = localizedColor.start;
1178 commonColor.right = localizedColor.end;
1179 commonColor.topResObj = localizedColor.topResObj;
1180 commonColor.bottomResObj = localizedColor.bottomResObj;
1181 commonColor.leftResObj = localizedColor.startResObj;
1182 commonColor.rightResObj = localizedColor.endResObj;
1183 return true;
1184 }
1185 ParseEdgeColors(object, commonColor);
1186 return false;
1187 }
1188
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1189 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1190 {
1191 CalcDimension left;
1192 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1193 CheckDimensionUnit(left, true, notNegative);
1194 commonCalcDimension.left = left;
1195 }
1196 CalcDimension right;
1197 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1198 CheckDimensionUnit(right, true, notNegative);
1199 commonCalcDimension.right = right;
1200 }
1201 CalcDimension top;
1202 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1203 CheckDimensionUnit(top, true, notNegative);
1204 commonCalcDimension.top = top;
1205 }
1206 CalcDimension bottom;
1207 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1208 CheckDimensionUnit(bottom, true, notNegative);
1209 commonCalcDimension.bottom = bottom;
1210 }
1211 }
1212
ParseEdgeWidthsResObjFunc(NG::BorderWidthProperty & borderWidth,RefPtr<ResourceObject> leftResObj,RefPtr<ResourceObject> rightResObj,RefPtr<ResourceObject> topResObj,RefPtr<ResourceObject> bottomResObj)1213 void ParseEdgeWidthsResObjFunc(NG::BorderWidthProperty& borderWidth, RefPtr<ResourceObject> leftResObj,
1214 RefPtr<ResourceObject> rightResObj, RefPtr<ResourceObject> topResObj, RefPtr<ResourceObject> bottomResObj)
1215 {
1216 if (!SystemProperties::ConfigChangePerform()) {
1217 return;
1218 }
1219 borderWidth.resMap_.clear();
1220 if (leftResObj) {
1221 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1222 CalcDimension result;
1223 ResourceParseUtils::ParseResDimensionVp(resObj, result);
1224 borderWidth.leftDimen = result;
1225 borderWidth.multiValued = true;
1226 };
1227 borderWidth.AddResource("borderWidth.left", leftResObj, std::move(updateFunc));
1228 }
1229 if (rightResObj) {
1230 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1231 CalcDimension result;
1232 ResourceParseUtils::ParseResDimensionVp(resObj, result);
1233 borderWidth.rightDimen = result;
1234 borderWidth.multiValued = true;
1235 };
1236 borderWidth.AddResource("borderWidth.right", rightResObj, std::move(updateFunc));
1237 }
1238 if (topResObj) {
1239 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1240 CalcDimension result;
1241 ResourceParseUtils::ParseResDimensionVp(resObj, result);
1242 borderWidth.topDimen = result;
1243 borderWidth.multiValued = true;
1244 };
1245 borderWidth.AddResource("borderWidth.top", topResObj, std::move(updateFunc));
1246 }
1247 if (bottomResObj) {
1248 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1249 CalcDimension result;
1250 ResourceParseUtils::ParseResDimensionVp(resObj, result);
1251 borderWidth.bottomDimen = result;
1252 borderWidth.multiValued = true;
1253 };
1254 borderWidth.AddResource("borderWidth.bottom", bottomResObj, std::move(updateFunc));
1255 }
1256 }
1257
ParseEdgeWidthsForDashParamsResObj(NG::BorderWidthProperty & borderWidth,RefPtr<ResourceObject> topResObj,RefPtr<ResourceObject> rightResObj,RefPtr<ResourceObject> bottomResObj,RefPtr<ResourceObject> leftResObj)1258 void ParseEdgeWidthsForDashParamsResObj(NG::BorderWidthProperty& borderWidth, RefPtr<ResourceObject> topResObj,
1259 RefPtr<ResourceObject> rightResObj, RefPtr<ResourceObject> bottomResObj, RefPtr<ResourceObject> leftResObj)
1260 {
1261 if (!SystemProperties::ConfigChangePerform()) {
1262 return;
1263 }
1264 borderWidth.resMap_.clear();
1265 if (leftResObj) {
1266 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1267 CalcDimension result;
1268 if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1269 CheckDimensionUnit(result, true, false);
1270 borderWidth.leftDimen = result;
1271 } else {
1272 borderWidth.leftDimen = static_cast<CalcDimension>(-1);
1273 }
1274 };
1275 borderWidth.AddResource("borderWidth.left", leftResObj, std::move(updateFunc));
1276 }
1277 if (rightResObj) {
1278 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1279 CalcDimension result;
1280 if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1281 CheckDimensionUnit(result, true, false);
1282 borderWidth.rightDimen = result;
1283 } else {
1284 borderWidth.rightDimen = static_cast<CalcDimension>(-1);
1285 }
1286 };
1287 borderWidth.AddResource("borderWidth.right", rightResObj, std::move(updateFunc));
1288 }
1289 if (topResObj) {
1290 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1291 CalcDimension result;
1292 if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1293 CheckDimensionUnit(result, true, false);
1294 borderWidth.topDimen = result;
1295 } else {
1296 borderWidth.topDimen = static_cast<CalcDimension>(-1);
1297 }
1298 };
1299 borderWidth.AddResource("borderWidth.top", topResObj, std::move(updateFunc));
1300 }
1301 if (bottomResObj) {
1302 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
1303 CalcDimension result;
1304 if (ResourceParseUtils::ParseResDimensionVp(resObj, result)) {
1305 CheckDimensionUnit(result, true, false);
1306 borderWidth.bottomDimen = result;
1307 } else {
1308 borderWidth.bottomDimen = static_cast<CalcDimension>(-1);
1309 }
1310 };
1311 borderWidth.AddResource("borderWidth.bottom", bottomResObj, std::move(updateFunc));
1312 }
1313 }
1314
ParseEdgeWidthsResObj(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth,bool notNegative)1315 void ParseEdgeWidthsResObj(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth, bool notNegative)
1316 {
1317 CalcDimension left;
1318 RefPtr<ResourceObject> leftResObj;
1319 if (JSViewAbstract::ParseJsDimensionVp(
1320 object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left, leftResObj)) {
1321 CheckDimensionUnit(left, true, notNegative);
1322 borderWidth.leftDimen = left;
1323 borderWidth.multiValued = true;
1324 }
1325 CalcDimension right;
1326 RefPtr<ResourceObject> rightResObj;
1327 if (JSViewAbstract::ParseJsDimensionVp(
1328 object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right, rightResObj)) {
1329 CheckDimensionUnit(right, true, notNegative);
1330 borderWidth.rightDimen = right;
1331 borderWidth.multiValued = true;
1332 }
1333 CalcDimension top;
1334 RefPtr<ResourceObject> topResObj;
1335 if (JSViewAbstract::ParseJsDimensionVp(
1336 object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topResObj)) {
1337 CheckDimensionUnit(top, true, notNegative);
1338 borderWidth.topDimen = top;
1339 borderWidth.multiValued = true;
1340 }
1341 CalcDimension bottom;
1342 RefPtr<ResourceObject> bottomResObj;
1343 if (JSViewAbstract::ParseJsDimensionVp(
1344 object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomResObj)) {
1345 CheckDimensionUnit(bottom, true, notNegative);
1346 borderWidth.bottomDimen = bottom;
1347 borderWidth.multiValued = true;
1348 }
1349 ParseEdgeWidthsResObjFunc(borderWidth, leftResObj, rightResObj, topResObj, bottomResObj);
1350 }
1351
ParseEdgeWidthsForDashParamsResObj(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth,CalcDimension defaultValue)1352 void ParseEdgeWidthsForDashParamsResObj(
1353 const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth, CalcDimension defaultValue)
1354 {
1355 CalcDimension left;
1356 RefPtr<ResourceObject> leftResObj;
1357 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, leftResObj, true)) {
1358 CheckDimensionUnit(left, true, false);
1359 borderWidth.leftDimen = left;
1360 } else {
1361 borderWidth.leftDimen = defaultValue;
1362 }
1363 CalcDimension right;
1364 RefPtr<ResourceObject> rightResObj;
1365 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, rightResObj, true)) {
1366 CheckDimensionUnit(right, true, false);
1367 borderWidth.rightDimen = right;
1368 } else {
1369 borderWidth.rightDimen = defaultValue;
1370 }
1371 CalcDimension top;
1372 RefPtr<ResourceObject> topResObj;
1373 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, topResObj, true)) {
1374 CheckDimensionUnit(top, true, false);
1375 borderWidth.topDimen = top;
1376 } else {
1377 borderWidth.topDimen = defaultValue;
1378 }
1379 CalcDimension bottom;
1380 RefPtr<ResourceObject> bottomResObj;
1381 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, bottomResObj, true)) {
1382 CheckDimensionUnit(bottom, false, true);
1383 borderWidth.bottomDimen = bottom;
1384 } else {
1385 borderWidth.bottomDimen = defaultValue;
1386 }
1387 ParseEdgeWidthsForDashParamsResObj(borderWidth, leftResObj, rightResObj, topResObj, bottomResObj);
1388 }
1389
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1390 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
1391 bool notNegative, CalcDimension defaultValue)
1392 {
1393 CalcDimension left;
1394 RefPtr<ResourceObject> leftResObj;
1395 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, leftResObj, true)) {
1396 CheckDimensionUnit(left, notPercent, notNegative);
1397 commonCalcDimension.left = left;
1398 } else {
1399 commonCalcDimension.left = defaultValue;
1400 }
1401 CalcDimension right;
1402 RefPtr<ResourceObject> rightResObj;
1403 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, rightResObj, true)) {
1404 CheckDimensionUnit(right, notPercent, notNegative);
1405 commonCalcDimension.right = right;
1406 } else {
1407 commonCalcDimension.right = defaultValue;
1408 }
1409 CalcDimension top;
1410 RefPtr<ResourceObject> topResObj;
1411 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, topResObj, true)) {
1412 CheckDimensionUnit(top, notPercent, notNegative);
1413 commonCalcDimension.top = top;
1414 } else {
1415 commonCalcDimension.top = defaultValue;
1416 }
1417 CalcDimension bottom;
1418 RefPtr<ResourceObject> bottomResObj;
1419 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, bottomResObj, true)) {
1420 CheckDimensionUnit(bottom, false, true);
1421 commonCalcDimension.bottom = bottom;
1422 } else {
1423 commonCalcDimension.bottom = defaultValue;
1424 }
1425 if (leftResObj) {
1426 commonCalcDimension.leftResObj = leftResObj;
1427 }
1428 if (rightResObj) {
1429 commonCalcDimension.rightResObj = rightResObj;
1430 }
1431 if (topResObj) {
1432 commonCalcDimension.topResObj = topResObj;
1433 }
1434 if (bottomResObj) {
1435 commonCalcDimension.bottomResObj = bottomResObj;
1436 }
1437 }
1438
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)1439 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
1440 bool notNegative)
1441 {
1442 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
1443 if (jsStart->IsObject()) {
1444 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
1445 CalcDimension calcDimension;
1446 if (ParseJsLengthMetrics(startObj, calcDimension)) {
1447 CheckDimensionUnit(calcDimension, true, notNegative);
1448 localizedCalcDimension.start = calcDimension;
1449 }
1450 }
1451 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
1452 if (jsEnd->IsObject()) {
1453 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
1454 CalcDimension calcDimension;
1455 if (ParseJsLengthMetrics(endObj, calcDimension)) {
1456 CheckDimensionUnit(calcDimension, true, notNegative);
1457 localizedCalcDimension.end = calcDimension;
1458 }
1459 }
1460 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
1461 if (jsTop->IsObject()) {
1462 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
1463 CalcDimension calcDimension;
1464 if (ParseJsLengthMetrics(topObj, calcDimension)) {
1465 CheckDimensionUnit(calcDimension, true, notNegative);
1466 localizedCalcDimension.top = calcDimension;
1467 }
1468 }
1469 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
1470 if (jsBottom->IsObject()) {
1471 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
1472 CalcDimension calcDimension;
1473 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1474 CheckDimensionUnit(calcDimension, true, notNegative);
1475 localizedCalcDimension.bottom = calcDimension;
1476 }
1477 }
1478 }
1479
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)1480 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
1481 {
1482 if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
1483 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
1484 CalcDimension calcDimension;
1485 RefPtr<ResourceObject> leftResObj;
1486 if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(startObj, calcDimension, leftResObj)) {
1487 CheckDimensionUnit(calcDimension, false, true);
1488 localizedCalcDimension.start = calcDimension;
1489 localizedCalcDimension.leftResObj = leftResObj;
1490 }
1491 }
1492 if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
1493 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
1494 CalcDimension calcDimension;
1495 RefPtr<ResourceObject> rightResObj;
1496 if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(endObj, calcDimension, rightResObj)) {
1497 CheckDimensionUnit(calcDimension, false, true);
1498 localizedCalcDimension.end = calcDimension;
1499 localizedCalcDimension.rightResObj = rightResObj;
1500 }
1501 }
1502 if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
1503 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
1504 CalcDimension calcDimension;
1505 RefPtr<ResourceObject> topResObj;
1506 if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(topObj, calcDimension, topResObj)) {
1507 CheckDimensionUnit(calcDimension, false, true);
1508 localizedCalcDimension.top = calcDimension;
1509 localizedCalcDimension.topResObj = topResObj;
1510 }
1511 }
1512 if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
1513 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
1514 CalcDimension calcDimension;
1515 RefPtr<ResourceObject> bottomResObj;
1516 if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(bottomObj, calcDimension, bottomResObj)) {
1517 CheckDimensionUnit(calcDimension, false, true);
1518 localizedCalcDimension.bottom = calcDimension;
1519 localizedCalcDimension.bottomResObj = bottomResObj;
1520 }
1521 }
1522 }
1523
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1524 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1525 {
1526 if (JSViewAbstract::CheckLengthMetrics(object)) {
1527 LocalizedCalcDimension localizedCalcDimension;
1528 ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
1529 commonCalcDimension.top = localizedCalcDimension.top;
1530 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1531 commonCalcDimension.left = localizedCalcDimension.start;
1532 commonCalcDimension.right = localizedCalcDimension.end;
1533 return true;
1534 }
1535 if (!SystemProperties::ConfigChangePerform()) {
1536 ParseEdgeWidths(object, commonCalcDimension, notNegative);
1537 }
1538 return false;
1539 }
1540
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1541 bool ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1542 {
1543 if (JSViewAbstract::CheckLengthMetrics(object)) {
1544 LocalizedCalcDimension localizedCalcDimension;
1545 ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
1546 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1547 commonCalcDimension.top = localizedCalcDimension.top;
1548 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1549 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1550 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1551 return true;
1552 }
1553 ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1554 return false;
1555 }
1556
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1557 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1558 {
1559 if (JSViewAbstract::CheckLengthMetrics(object)) {
1560 LocalizedCalcDimension localizedCalcDimension;
1561 ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1562 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1563 commonCalcDimension.top = localizedCalcDimension.top;
1564 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1565 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1566 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1567 commonCalcDimension.leftResObj = isRightToLeft ? localizedCalcDimension.rightResObj : localizedCalcDimension.leftResObj;
1568 commonCalcDimension.rightResObj = isRightToLeft ? localizedCalcDimension.leftResObj : localizedCalcDimension.rightResObj;
1569 commonCalcDimension.topResObj = localizedCalcDimension.topResObj;
1570 commonCalcDimension.bottomResObj = localizedCalcDimension.bottomResObj;
1571 return;
1572 }
1573 ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1574 }
1575
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1576 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1577 {
1578 auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1579 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1580 auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1581 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1582 NG::PipelineContext::SetCallBackNode(targetNode);
1583 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1584 jsFuncFinish->ExecuteJS(1, &newJSVal);
1585 };
1586 return finishCallback;
1587 }
1588
ConvertCalcLength(CalcDimension & target)1589 NG::CalcLength ConvertCalcLength(CalcDimension& target)
1590 {
1591 NG::CalcLength targetLength = (target.Unit() == DimensionUnit::CALC) ?
1592 NG::CalcLength(target.IsNonNegative() ? target.CalcValue() : CalcDimension().CalcValue()) :
1593 NG::CalcLength(target.IsNonNegative() ? target : CalcDimension());
1594 return targetLength;
1595 }
1596
SetConstraintSize(const RefPtr<ResourceObject> & minWidthResObj,const RefPtr<ResourceObject> & maxWidthResObj,const RefPtr<ResourceObject> & minHeightResObj,const RefPtr<ResourceObject> & maxHeightResObj)1597 void SetConstraintSize(const RefPtr<ResourceObject>& minWidthResObj, const RefPtr<ResourceObject>& maxWidthResObj,
1598 const RefPtr<ResourceObject>& minHeightResObj, const RefPtr<ResourceObject>& maxHeightResObj)
1599 {
1600 if (!SystemProperties::ConfigChangePerform()) {
1601 return;
1602 }
1603 if (minWidthResObj) {
1604 ViewAbstractModel::GetInstance()->SetMinWidth(minWidthResObj);
1605 }
1606 if (maxWidthResObj) {
1607 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidthResObj);
1608 }
1609 if (minHeightResObj) {
1610 ViewAbstractModel::GetInstance()->SetMinHeight(minHeightResObj);
1611 }
1612 if (maxHeightResObj) {
1613 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeightResObj);
1614 }
1615 }
1616
RegisterBorderColorRes(NG::BorderColorProperty & colorProperty,const CommonColor & commonColor,bool isLocalizedEdgeColor)1617 void RegisterBorderColorRes(NG::BorderColorProperty& colorProperty,
1618 const CommonColor& commonColor, bool isLocalizedEdgeColor)
1619 {
1620 if (!SystemProperties::ConfigChangePerform()) {
1621 return;
1622 }
1623 if (commonColor.leftResObj) {
1624 auto&& updateFunc = [isLocalizedEdgeColor](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1625 Color result;
1626 ResourceParseUtils::ParseResColor(resObj, result);
1627 isLocalizedEdgeColor ? (borderColors.startColor = result) : (borderColors.leftColor = result);
1628 };
1629 colorProperty.AddResource("borderColor.start", commonColor.leftResObj, std::move(updateFunc));
1630 } else {
1631 colorProperty.RemoveResource("borderColor.start");
1632 }
1633 if (commonColor.rightResObj) {
1634 auto&& updateFunc = [isLocalizedEdgeColor](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1635 Color result;
1636 ResourceParseUtils::ParseResColor(resObj, result);
1637 isLocalizedEdgeColor ? (borderColors.endColor = result) : (borderColors.rightColor = result);
1638 };
1639 colorProperty.AddResource("borderColor.end", commonColor.rightResObj, std::move(updateFunc));
1640 } else {
1641 colorProperty.RemoveResource("borderColor.end");
1642 }
1643 if (commonColor.topResObj) {
1644 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1645 Color result;
1646 ResourceParseUtils::ParseResColor(resObj, result);
1647 borderColors.topColor = result;
1648 };
1649 colorProperty.AddResource("borderColor.top", commonColor.topResObj, std::move(updateFunc));
1650 } else {
1651 colorProperty.RemoveResource("borderColor.top");
1652 }
1653 if (commonColor.bottomResObj) {
1654 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
1655 Color result;
1656 ResourceParseUtils::ParseResColor(resObj, result);
1657 borderColors.bottomColor = result;
1658 };
1659 colorProperty.AddResource("borderColor.bottom", commonColor.bottomResObj, std::move(updateFunc));
1660 } else {
1661 colorProperty.RemoveResource("borderColor.bottom");
1662 }
1663 }
1664
RegisterRadiusRes(NG::BorderRadiusProperty & radius,RefPtr<ResourceObject> topStartResObj,RefPtr<ResourceObject> topEndResObj,RefPtr<ResourceObject> bottomStartResObj,RefPtr<ResourceObject> bottomEndResObj)1665 void RegisterRadiusRes(NG::BorderRadiusProperty& radius,
1666 RefPtr<ResourceObject> topStartResObj, RefPtr<ResourceObject> topEndResObj,
1667 RefPtr<ResourceObject> bottomStartResObj, RefPtr<ResourceObject> bottomEndResObj)
1668 {
1669 if (!SystemProperties::ConfigChangePerform()) {
1670 return;
1671 }
1672 if (topStartResObj) {
1673 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1674 CalcDimension result;
1675 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1676 radius.radiusTopLeft = result;
1677 radius.multiValued = true;
1678 };
1679 radius.AddResource("radius.topStart", topStartResObj, std::move(updateFunc));
1680 } else {
1681 radius.RemoveResource("radius.topStart");
1682 }
1683 if (topEndResObj) {
1684 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1685 CalcDimension result;
1686 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1687 radius.radiusTopRight = result;
1688 radius.multiValued = true;
1689 };
1690 radius.AddResource("radius.topEnd", topEndResObj, std::move(updateFunc));
1691 } else {
1692 radius.RemoveResource("radius.topEnd");
1693 }
1694 if (bottomStartResObj) {
1695 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1696 CalcDimension result;
1697 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1698 radius.radiusBottomRight = result;
1699 radius.multiValued = true;
1700 };
1701 radius.AddResource("radius.bottomStart", bottomStartResObj, std::move(updateFunc));
1702 } else {
1703 radius.RemoveResource("radius.bottomStart");
1704 }
1705 if (bottomEndResObj) {
1706 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& radius) {
1707 CalcDimension result;
1708 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
1709 radius.radiusBottomLeft = result;
1710 radius.multiValued = true;
1711 };
1712 radius.AddResource("radius.bottomEnd", bottomEndResObj, std::move(updateFunc));
1713 } else {
1714 radius.RemoveResource("radius.bottomEnd");
1715 }
1716 }
1717 } // namespace
1718
GetResourceObject(const JSRef<JSObject> & jsObj)1719 RefPtr<ResourceObject> JSViewAbstract::GetResourceObject(const JSRef<JSObject>& jsObj)
1720 {
1721 auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1722 auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1723 auto args = jsObj->GetProperty("params");
1724
1725 std::string bundleName;
1726 std::string moduleName;
1727 auto bundle = jsObj->GetProperty("bundleName");
1728 auto module = jsObj->GetProperty("moduleName");
1729 if (bundle->IsString() && module->IsString()) {
1730 bundleName = bundle->ToString();
1731 moduleName = module->ToString();
1732 }
1733 if (!args->IsArray()) {
1734 return nullptr;
1735 }
1736 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1737 std::vector<ResourceObjectParams> resObjParamsList;
1738 auto size = static_cast<int32_t>(params->Length());
1739 for (int32_t i = 0; i < size; i++) {
1740 auto item = params->GetValueAt(i);
1741 ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1742 if (item->IsString()) {
1743 resObjParams.type = ResourceObjectParamType::STRING;
1744 } else if (item->IsNumber()) {
1745 if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1746 resObjParams.type = ResourceObjectParamType::FLOAT;
1747 } else {
1748 resObjParams.type = ResourceObjectParamType::INT;
1749 }
1750 }
1751 resObjParamsList.push_back(resObjParams);
1752 }
1753 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(
1754 id, type, resObjParamsList, bundleName, moduleName, Container::CurrentIdSafely());
1755 return resourceObject;
1756 }
1757
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1758 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1759 {
1760 auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1761 auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1762 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName, Container::CurrentIdSafely());
1763 return resourceObject;
1764 }
1765
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1766 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1767 {
1768 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1769 RefPtr<ThemeConstants> themeConstants = nullptr;
1770 if (SystemProperties::GetResourceDecoupling()) {
1771 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1772 if (!resourceAdapter) {
1773 return nullptr;
1774 }
1775 } else {
1776 themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1777 if (!themeConstants) {
1778 return nullptr;
1779 }
1780 }
1781 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1782 return resourceWrapper;
1783 }
1784
CreateResourceWrapper()1785 RefPtr<ResourceWrapper> CreateResourceWrapper()
1786 {
1787 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1788 RefPtr<ThemeConstants> themeConstants = nullptr;
1789 if (SystemProperties::GetResourceDecoupling()) {
1790 resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(Container::CurrentIdSafely());
1791 if (!resourceAdapter) {
1792 return nullptr;
1793 }
1794 } else {
1795 themeConstants = JSViewAbstract::GetThemeConstants();
1796 if (!themeConstants) {
1797 return nullptr;
1798 }
1799 }
1800 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1801 return resourceWrapper;
1802 }
1803
ColorAlphaAdapt(uint32_t origin)1804 uint32_t ColorAlphaAdapt(uint32_t origin)
1805 {
1806 uint32_t result = origin;
1807 if (origin >> COLOR_ALPHA_OFFSET == 0) {
1808 result = origin | COLOR_ALPHA_VALUE;
1809 }
1810 return result;
1811 }
1812
StringToMenuItemType(std::string_view id)1813 MenuItemType StringToMenuItemType(std::string_view id)
1814 {
1815 static const std::unordered_map<std::string_view, MenuItemType> keyMenuItemMap = {
1816 { "OH_DEFAULT_COPY", MenuItemType::COPY },
1817 { "OH_DEFAULT_PASTE", MenuItemType::PASTE },
1818 { "OH_DEFAULT_CUT", MenuItemType::CUT },
1819 { "OH_DEFAULT_SELECT_ALL", MenuItemType::SELECT_ALL },
1820 { "OH_DEFAULT_CAMERA_INPUT", MenuItemType::CAMERA_INPUT },
1821 { "OH_DEFAULT_AI_WRITE", MenuItemType::AI_WRITER },
1822 { "OH_DEFAULT_TRANSLATE", MenuItemType::TRANSLATE },
1823 { "OH_DEFAULT_SHARE", MenuItemType::SHARE },
1824 { "OH_DEFAULT_SEARCH", MenuItemType::SEARCH },
1825 { "OH_DEFAULT_ASK_CELIA", MenuItemType::ASK_CELIA },
1826 };
1827
1828 auto item = keyMenuItemMap.find(id);
1829 return item != keyMenuItemMap.end() ? item->second : MenuItemType::UNKNOWN;
1830 }
1831
UpdateInfoById(NG::MenuOptionsParam & menuOptionsParam,std::string_view id)1832 void UpdateInfoById(NG::MenuOptionsParam& menuOptionsParam, std::string_view id)
1833 {
1834 auto opType = StringToMenuItemType(id);
1835 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1836 CHECK_NULL_VOID(pipeline);
1837 auto theme = pipeline->GetTheme<TextOverlayTheme>();
1838 CHECK_NULL_VOID(theme);
1839 switch (opType) {
1840 case MenuItemType::COPY:
1841 menuOptionsParam.labelInfo = theme->GetCopyLabelInfo();
1842 menuOptionsParam.symbolId = theme->GetCopySymbolId();
1843 break;
1844 case MenuItemType::PASTE:
1845 menuOptionsParam.labelInfo = theme->GetPasteLabelInfo();
1846 menuOptionsParam.symbolId = theme->GetPasteSymbolId();
1847 break;
1848 case MenuItemType::CUT:
1849 menuOptionsParam.labelInfo = theme->GetCutLabelInfo();
1850 menuOptionsParam.symbolId = theme->GetCutSymbolId();
1851 break;
1852 case MenuItemType::SELECT_ALL:
1853 menuOptionsParam.labelInfo = theme->GetSelectAllLabelInfo();
1854 menuOptionsParam.symbolId = theme->GetCopyAllSymbolId();
1855 break;
1856 case MenuItemType::CAMERA_INPUT:
1857 menuOptionsParam.symbolId = theme->GetCameraInputSymbolId();
1858 break;
1859 case MenuItemType::AI_WRITER:
1860 menuOptionsParam.symbolId = theme->GetAIWriteSymbolId();
1861 break;
1862 case MenuItemType::TRANSLATE:
1863 menuOptionsParam.symbolId = theme->GetTranslateSymbolId();
1864 break;
1865 case MenuItemType::SHARE:
1866 menuOptionsParam.symbolId = theme->GetShareSymbolId();
1867 break;
1868 case MenuItemType::SEARCH:
1869 menuOptionsParam.symbolId = theme->GetSearchSymbolId();
1870 break;
1871 case MenuItemType::ASK_CELIA:
1872 menuOptionsParam.symbolId = theme->GetAskCeliaSymbolId();
1873 break;
1874 default:
1875 menuOptionsParam.labelInfo = menuOptionsParam.labelInfo.value_or("");
1876 menuOptionsParam.symbolId = menuOptionsParam.symbolId.value_or(0);
1877 break;
1878 }
1879 }
1880
UpdateOptionsInfo(std::vector<NG::MenuItemParam> & params)1881 void UpdateOptionsInfo(std::vector<NG::MenuItemParam>& params)
1882 {
1883 for (auto& param : params) {
1884 UpdateInfoById(param.menuOptionsParam, param.menuOptionsParam.id);
1885 }
1886 }
1887
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context,const RefPtr<NG::FrameNode> node)1888 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseChainedTransition(
1889 const JSRef<JSObject>& object, const JSExecutionContext& context, const RefPtr<NG::FrameNode> node)
1890 {
1891 auto propType = object->GetProperty("type_");
1892 if (!propType->IsString()) {
1893 return nullptr;
1894 }
1895 std::string type = propType->ToString();
1896 auto propEffectOption = object->GetProperty("effect_");
1897 auto propAnimationOption = object->GetProperty("animation_");
1898 auto propSuccessor = object->GetProperty("successor_");
1899 static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
1900 { "asymmetric", ParseChainedAsymmetricTransition },
1901 { "identity",
1902 [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
1903 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
1904 { "move", ParseChainedMoveTransition },
1905 { "opacity", ParseChainedOpacityTransition },
1906 { "rotate", ParseChainedRotateTransition },
1907 { "scale", ParseChainedScaleTransition },
1908 { "slideSwitch",
1909 [](const JSRef<JSVal>& effectOption,
1910 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
1911 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
1912 } },
1913 { "translate", ParseChainedTranslateTransition },
1914 };
1915 int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
1916 if (index < 0) {
1917 return nullptr;
1918 }
1919 RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
1920 if (!result) {
1921 return nullptr;
1922 }
1923 if (propAnimationOption->IsObject()) {
1924 auto container = Container::Current();
1925 CHECK_NULL_RETURN(container, nullptr);
1926 auto pipelineContext = container->GetPipelineContext();
1927 CHECK_NULL_RETURN(pipelineContext, nullptr);
1928 auto animationOptionResult = std::make_shared<AnimationOption>(
1929 JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRenderExceptDynamicComponent()));
1930 // The maximum of the form-animation-playback duration value is 1000 ms.
1931 if (pipelineContext->IsFormRenderExceptDynamicComponent() && pipelineContext->IsFormAnimation()) {
1932 auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
1933 // If the duration exceeds 1000ms, init it to 0 ms.
1934 if (formAnimationTimeInterval > DEFAULT_DURATION) {
1935 animationOptionResult->SetDuration(0);
1936 } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
1937 // If remaining time is less than 1000ms, check for update duration.
1938 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
1939 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form Transition SetDuration: %{public}lld ms",
1940 static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
1941 }
1942 }
1943 auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
1944 JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
1945 WeakPtr<NG::FrameNode> targetNode = nullptr;
1946 if (node) {
1947 targetNode = AceType::WeakClaim(AceType::RawPtr(node));
1948 } else {
1949 targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1950 }
1951 if (onFinish->IsFunction()) {
1952 RefPtr<JsFunction> jsFunc =
1953 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
1954 std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
1955 id = Container::CurrentId(), node = targetNode]() {
1956 ContainerScope scope(id);
1957 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1958 PipelineContext::SetCallBackNode(node);
1959 func->Execute();
1960 };
1961 animationOptionResult->SetOnFinishEvent(onFinishEvent);
1962 }
1963 result->SetAnimationOption(animationOptionResult);
1964 }
1965 if (propSuccessor->IsObject()) {
1966 result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
1967 }
1968 return result;
1969 }
1970
JsScale(const JSCallbackInfo & info)1971 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1972 {
1973 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1974 auto jsVal = info[0];
1975 if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1976 SetDefaultScale();
1977 return;
1978 }
1979
1980 if (jsVal->IsObject()) {
1981 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1982 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1983 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1984 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1985 // default: x, y, z (1.0, 1.0, 1.0)
1986 auto scaleX = 1.0f;
1987 auto scaleY = 1.0f;
1988 auto scaleZ = 1.0f;
1989 // default centerX, centerY 50% 50%;
1990 CalcDimension centerX = 0.5_pct;
1991 CalcDimension centerY = 0.5_pct;
1992 ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1993 ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1994 ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1995 return;
1996 } else {
1997 SetDefaultScale();
1998 }
1999 }
2000 double scale = 0.0;
2001 if (ParseJsDouble(jsVal, scale)) {
2002 ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
2003 }
2004 }
2005
SetDefaultScale()2006 void JSViewAbstract::SetDefaultScale()
2007 {
2008 ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
2009 ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
2010 }
2011
JsScaleX(const JSCallbackInfo & info)2012 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
2013 {
2014 double scaleVal = 0.0;
2015 if (!ParseJsDouble(info[0], scaleVal)) {
2016 return;
2017 }
2018 ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
2019 }
2020
JsScaleY(const JSCallbackInfo & info)2021 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
2022 {
2023 double scaleVal = 0.0;
2024 if (!ParseJsDouble(info[0], scaleVal)) {
2025 return;
2026 }
2027 ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
2028 }
2029
JsOpacity(const JSCallbackInfo & info)2030 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
2031 {
2032 ViewAbstractModel::GetInstance()->RemoveResObj("viewAbstract.opacity");
2033 double opacity = 0.0;
2034 RefPtr<ResourceObject> opacityResObj;
2035 if (!ParseJsDouble(info[0], opacity, opacityResObj)) {
2036 ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
2037 return;
2038 }
2039 if (SystemProperties::ConfigChangePerform() && opacityResObj) {
2040 ViewAbstractModel::GetInstance()->CreateWithOpacityResourceObj(opacityResObj);
2041 return;
2042 }
2043 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2044 opacity = std::clamp(opacity, 0.0, 1.0);
2045 } else {
2046 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
2047 opacity = 1.0;
2048 }
2049 }
2050 ViewAbstractModel::GetInstance()->SetOpacity(opacity);
2051 }
2052
JsTranslate(const JSCallbackInfo & info)2053 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
2054 {
2055 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
2056 JSCallbackInfoType::OBJECT };
2057 auto jsVal = info[0];
2058 if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
2059 SetDefaultTranslate();
2060 return;
2061 }
2062
2063 if (jsVal->IsObject()) {
2064 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
2065 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
2066 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
2067 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
2068 // default: x, y, z (0.0, 0.0, 0.0)
2069 auto translateX = CalcDimension(0.0);
2070 auto translateY = CalcDimension(0.0);
2071 auto translateZ = CalcDimension(0.0);
2072 ParseJsTranslate(jsVal, translateX, translateY, translateZ);
2073 ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
2074 return;
2075 } else {
2076 SetDefaultTranslate();
2077 }
2078 }
2079 CalcDimension value;
2080 if (ParseJsDimensionVp(jsVal, value)) {
2081 ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
2082 }
2083 }
2084
SetDefaultTranslate()2085 void JSViewAbstract::SetDefaultTranslate()
2086 {
2087 ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
2088 }
2089
JsTranslateX(const JSCallbackInfo & info)2090 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
2091 {
2092 CalcDimension value;
2093 if (!ParseJsDimensionVp(info[0], value)) {
2094 return;
2095 }
2096 ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
2097 }
2098
JsTranslateY(const JSCallbackInfo & info)2099 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
2100 {
2101 CalcDimension value;
2102 if (!ParseJsDimensionVp(info[0], value)) {
2103 return;
2104 }
2105 ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
2106 }
2107
JsRotate(const JSCallbackInfo & info)2108 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
2109 {
2110 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2111 auto jsVal = info[0];
2112 if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
2113 SetDefaultRotate();
2114 return;
2115 }
2116
2117 if (jsVal->IsObject()) {
2118 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
2119 NG::RotateAngleOptions rotateAngle(0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
2120 std::optional<float> angle;
2121 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
2122 bool hasAngleProp = jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::ANGLE));
2123 if (hasAngleProp) {
2124 ParseJsRotate(jsVal, rotate, angle);
2125 if (angle) {
2126 ViewAbstractModel::GetInstance()->SetRotate(
2127 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
2128 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
2129 } else {
2130 SetDefaultRotate();
2131 }
2132 } else {
2133 ParseJsRotateAngle(jsVal, rotateAngle);
2134 ViewAbstractModel::GetInstance()->SetRotateAngle(
2135 rotateAngle.angleX, rotateAngle.angleY, rotateAngle.angleZ, rotateAngle.perspective);
2136 ViewAbstractModel::GetInstance()->SetPivot(rotateAngle.centerX, rotateAngle.centerY, rotateAngle.centerZ);
2137 }
2138 return;
2139 }
2140 double rotateZ;
2141 if (ParseJsDouble(jsVal, rotateZ)) {
2142 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
2143 }
2144 }
2145
SetDefaultRotate()2146 void JSViewAbstract::SetDefaultRotate()
2147 {
2148 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
2149 ViewAbstractModel::GetInstance()->SetRotate(
2150 rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
2151 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
2152 }
2153
JsRotateX(const JSCallbackInfo & info)2154 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
2155 {
2156 double rotateVal = 0.0;
2157 if (!ParseJsDouble(info[0], rotateVal)) {
2158 return;
2159 }
2160 ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
2161 }
2162
JsRotateY(const JSCallbackInfo & info)2163 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
2164 {
2165 double rotateVal = 0.0;
2166 if (!ParseJsDouble(info[0], rotateVal)) {
2167 return;
2168 }
2169 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
2170 }
2171
JsTransform(const JSCallbackInfo & info)2172 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
2173 {
2174 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2175 auto jsVal = info[0];
2176 if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
2177 SetDefaultTransform();
2178 return;
2179 }
2180 JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
2181 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2182 if (!array->IsArray()) {
2183 return;
2184 }
2185 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
2186 if (jsArray->Length() != matrix4Len) {
2187 return;
2188 }
2189 std::vector<float> matrix(matrix4Len);
2190 for (int32_t i = 0; i < matrix4Len; i++) {
2191 double value = 0.0;
2192 ParseJsDouble(jsArray->GetValueAt(i), value);
2193 matrix[i] = static_cast<float>(value);
2194 }
2195 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
2196 }
2197
JsTransform3D(const JSCallbackInfo & info)2198 void JSViewAbstract::JsTransform3D(const JSCallbackInfo& info)
2199 {
2200 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2201 auto jsVal = info[0];
2202 if (!CheckJSCallbackInfo("JsTransform3D", jsVal, checkList)) {
2203 SetDefaultTransform3D();
2204 return;
2205 }
2206 JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
2207 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2208 if (!array->IsArray()) {
2209 TAG_LOGW(AceLogTag::ACE_VISUAL_EFFECT, "[JSI] Type check failed in %{public}s: expected array", __FUNCTION__);
2210 SetDefaultTransform3D();
2211 return;
2212 }
2213 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
2214 if (jsArray->Length() != matrix4Len) {
2215 TAG_LOGW(AceLogTag::ACE_VISUAL_EFFECT,
2216 "Invalid matrix parameter: Expected %{public}d elements, but JS array has %{public}zu elements", matrix4Len,
2217 jsArray->Length());
2218 SetDefaultTransform3D();
2219 return;
2220 }
2221 std::vector<float> matrix(matrix4Len);
2222 for (int32_t i = 0; i < matrix4Len; i++) {
2223 double value = 0.0;
2224 if (!ParseJsDouble(jsArray->GetValueAt(i), value)) {
2225 TAG_LOGW(AceLogTag::ACE_VISUAL_EFFECT,"[JSView] Failed to parse double");
2226 value = 0.0;
2227 }
2228 matrix[i] = static_cast<float>(value);
2229 }
2230 ViewAbstractModel::GetInstance()->SetTransform3DMatrix(matrix);
2231 }
2232
SetDefaultTransform()2233 void JSViewAbstract::SetDefaultTransform()
2234 {
2235 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2236 std::vector<float> matrix(matrix4Len);
2237 const int32_t initPosition = 5;
2238 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
2239 double value = 1.0;
2240 matrix[i] = static_cast<float>(value);
2241 }
2242 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
2243 }
2244
SetDefaultTransform3D()2245 void JSViewAbstract::SetDefaultTransform3D()
2246 {
2247 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
2248 std::vector<float> matrix(matrix4Len);
2249 const int32_t initPosition = 5;
2250 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
2251 double value = 1.0;
2252 matrix[i] = static_cast<float>(value);
2253 }
2254 ViewAbstractModel::GetInstance()->SetTransform3DMatrix(matrix);
2255 }
2256
ParseJsTransition(const JSRef<JSObject> & jsObj)2257 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
2258 {
2259 NG::TransitionOptions transitionOption;
2260 bool hasEffect = false;
2261 transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
2262 if (jsObj->HasProperty("opacity")) {
2263 double opacity = 1.0;
2264 ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
2265 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2266 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
2267 opacity = 1.0;
2268 }
2269 } else {
2270 opacity = std::clamp(opacity, 0.0, 1.0);
2271 }
2272 transitionOption.UpdateOpacity(static_cast<float>(opacity));
2273 hasEffect = true;
2274 }
2275 if (jsObj->HasProperty("translate")) {
2276 // default: x, y, z (0.0, 0.0, 0.0)
2277 NG::TranslateOptions translate;
2278 ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
2279 transitionOption.UpdateTranslate(translate);
2280 hasEffect = true;
2281 }
2282 if (jsObj->HasProperty("scale")) {
2283 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
2284 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
2285 ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
2286 scale.centerX, scale.centerY);
2287 transitionOption.UpdateScale(scale);
2288 hasEffect = true;
2289 }
2290 if (jsObj->HasProperty("rotate")) {
2291 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
2292 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
2293 std::optional<float> angle;
2294 ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
2295 if (angle.has_value()) {
2296 rotate.angle = angle.value();
2297 transitionOption.UpdateRotate(rotate);
2298 hasEffect = true;
2299 }
2300 }
2301 if (!hasEffect) {
2302 // default transition
2303 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
2304 }
2305 return transitionOption;
2306 }
2307
ParseJsTransitionEffect(const JSCallbackInfo & info)2308 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
2309 {
2310 JSRef<JSVal> arg = info[0];
2311 if (!arg->IsObject()) {
2312 return nullptr;
2313 }
2314 auto obj = JSRef<JSObject>::Cast(arg);
2315 auto transitionVal = obj->GetProperty("transition");
2316 if (!transitionVal->IsObject()) {
2317 return nullptr;
2318 }
2319 auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
2320 auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
2321 return chainedEffect;
2322 }
2323
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)2324 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
2325 const JSExecutionContext& context)
2326 {
2327 auto chainedEffect = ParseChainedTransition(object, context);
2328 return chainedEffect;
2329 }
2330
JsTransition(const JSCallbackInfo & info)2331 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
2332 {
2333 if (info.Length() < 1 || !info[0]->IsObject()) {
2334 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
2335 ViewAbstractModel::GetInstance()->CleanTransition();
2336 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
2337 }
2338 return;
2339 }
2340 auto obj = JSRef<JSObject>::Cast(info[0]);
2341 if (!obj->GetProperty("successor_")->IsUndefined()) {
2342 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
2343 std::function<void(bool)> finishCallback;
2344 if (info.Length() > 1 && info[1]->IsFunction()) {
2345 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
2346 }
2347 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
2348 return;
2349 }
2350 auto options = ParseJsTransition(obj);
2351 ViewAbstractModel::GetInstance()->SetTransition(options);
2352 }
2353
JsWidth(const JSCallbackInfo & info)2354 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
2355 {
2356 JsWidth(info[0]);
2357 }
2358
JsWidth(const JSRef<JSVal> & jsValue)2359 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
2360 {
2361 ViewAbstractModel::GetInstance()->ResetResObj("width");
2362 CalcDimension value;
2363 RefPtr<ResourceObject> valueResObj;
2364 if (jsValue->IsUndefined()) {
2365 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, true);
2366 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2367 return true;
2368 }
2369 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2370 if (!ParseJsDimensionVpNG(jsValue, value, valueResObj)) {
2371 // JsWidth return false, check if set LayoutPolicy before return.
2372 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2373 if (jsValue->IsObject()) {
2374 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
2375 JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
2376 if (layoutPolicy->IsString()) {
2377 auto policy = ParseLayoutPolicy(layoutPolicy->ToString());
2378 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, true);
2379 return true;
2380 }
2381 }
2382 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, true);
2383 return false;
2384 }
2385 } else if (!ParseJsDimensionVp(jsValue, value, valueResObj)) {
2386 return false;
2387 }
2388
2389 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, true);
2390 if (!SystemProperties::ConfigChangePerform() ? LessNotEqual(value.Value(), 0.0) :
2391 (LessNotEqual(value.Value(), 0.0) && !valueResObj)) {
2392 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2393 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2394 return true;
2395 } else {
2396 value.SetValue(0.0);
2397 }
2398 }
2399
2400 if (SystemProperties::ConfigChangePerform() && valueResObj) {
2401 ViewAbstractModel::GetInstance()->SetWidth(valueResObj);
2402 } else {
2403 ViewAbstractModel::GetInstance()->SetWidth(value);
2404 }
2405 return true;
2406 }
2407
JsHeight(const JSCallbackInfo & info)2408 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
2409 {
2410 JsHeight(info[0]);
2411 }
2412
JsToolbar(const JSCallbackInfo & info)2413 void JSViewAbstract::JsToolbar(const JSCallbackInfo& info)
2414 {
2415 // Check the parameters
2416 if (info.Length() <= 0) {
2417 return;
2418 }
2419 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2420 ViewAbstractModel::GetInstance()->SetToolbarBuilder(nullptr);
2421 } else if (info[0]->IsObject()) {
2422 JSRef<JSObject> toolbarObj = JSRef<JSObject>::Cast(info[0]);
2423 auto builder = toolbarObj->GetProperty("builder");
2424 if (!builder->IsFunction()) {
2425 return;
2426 }
2427 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2428 CHECK_NULL_VOID(builderFunc);
2429 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
2430 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2431 ACE_SCORING_EVENT("CrateToolbarItems");
2432 ToolBarItemModel::GetInstance()->SetIsFirstCreate(true);
2433 func->Execute();
2434 };
2435 ViewAbstractModel::GetInstance()->SetToolbarBuilder(std::move(buildFunc));
2436 }
2437 }
2438
JsHeight(const JSRef<JSVal> & jsValue)2439 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
2440 {
2441 ViewAbstractModel::GetInstance()->ResetResObj("height");
2442 CalcDimension value;
2443 RefPtr<ResourceObject> valueResObj;
2444 if (jsValue->IsUndefined()) {
2445 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, false);
2446 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2447 return true;
2448 }
2449 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2450 if (!ParseJsDimensionVpNG(jsValue, value, valueResObj)) {
2451 // JsHeight return false, check if set LayoutPolicy before return.
2452 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2453 if (jsValue->IsObject()) {
2454 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
2455 JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
2456 if (layoutPolicy->IsString()) {
2457 auto policy = ParseLayoutPolicy(layoutPolicy->ToString());
2458 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, false);
2459 return true;
2460 }
2461 }
2462 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, false);
2463 return false;
2464 }
2465 } else if (!ParseJsDimensionVp(jsValue, value, valueResObj)) {
2466 return false;
2467 }
2468
2469 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(LayoutCalPolicy::NO_MATCH, false);
2470 if (!SystemProperties::ConfigChangePerform() ? LessNotEqual(value.Value(), 0.0) :
2471 (LessNotEqual(value.Value(), 0.0) && !valueResObj)) {
2472 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2473 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2474 return true;
2475 } else {
2476 value.SetValue(0.0);
2477 }
2478 }
2479
2480 if (SystemProperties::ConfigChangePerform() && valueResObj) {
2481 ViewAbstractModel::GetInstance()->SetHeight(valueResObj);
2482 } else {
2483 ViewAbstractModel::GetInstance()->SetHeight(value);
2484 }
2485 return true;
2486 }
2487
JsResponseRegion(const JSCallbackInfo & info)2488 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
2489 {
2490 std::vector<DimensionRect> result;
2491 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2492 ViewAbstractModel::GetInstance()->SetResponseRegion({});
2493 return;
2494 }
2495
2496 ViewAbstractModel::GetInstance()->SetResponseRegion(result);
2497 }
2498
JsMouseResponseRegion(const JSCallbackInfo & info)2499 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
2500 {
2501 std::vector<DimensionRect> result;
2502 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2503 ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
2504 return;
2505 }
2506 ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
2507 }
2508
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2509 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
2510 {
2511 result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
2512 result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
2513 if (!jsValue->IsObject()) {
2514 return true;
2515 }
2516 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
2517 JSRef<JSVal> x = obj->GetProperty("x");
2518 JSRef<JSVal> y = obj->GetProperty("y");
2519 JSRef<JSVal> width = obj->GetProperty("width");
2520 JSRef<JSVal> height = obj->GetProperty("height");
2521 CalcDimension xDimen = result.GetOffset().GetX();
2522 CalcDimension yDimen = result.GetOffset().GetY();
2523 CalcDimension widthDimen = result.GetWidth();
2524 CalcDimension heightDimen = result.GetHeight();
2525 auto s1 = width->ToString();
2526 auto s2 = height->ToString();
2527 if (s1.find('-') != std::string::npos) {
2528 width = JSRef<JSVal>::Make(ToJSValue("100%"));
2529 }
2530 if (s2.find('-') != std::string::npos) {
2531 height = JSRef<JSVal>::Make(ToJSValue("100%"));
2532 }
2533 if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
2534 auto offset = result.GetOffset();
2535 offset.SetX(xDimen);
2536 result.SetOffset(offset);
2537 }
2538 if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
2539 auto offset = result.GetOffset();
2540 offset.SetY(yDimen);
2541 result.SetOffset(offset);
2542 }
2543 if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
2544 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
2545 return true;
2546 }
2547 result.SetWidth(widthDimen);
2548 }
2549 if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
2550 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
2551 return true;
2552 }
2553 result.SetHeight(heightDimen);
2554 }
2555 return true;
2556 }
2557
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2558 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
2559 {
2560 if (!jsValue->IsArray() && !jsValue->IsObject()) {
2561 return false;
2562 }
2563
2564 if (jsValue->IsArray()) {
2565 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2566 for (size_t i = 0; i < array->Length(); i++) {
2567 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2568 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2569 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2570 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2571 DimensionOffset offsetDimen(xDimen, yDimen);
2572 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2573 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
2574 result.emplace_back(dimenRect);
2575 } else {
2576 return false;
2577 }
2578 }
2579 return true;
2580 }
2581
2582 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2583 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2584 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2585 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2586 DimensionOffset offsetDimen(xDimen, yDimen);
2587 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2588 if (ParseJsDimensionRect(jsValue, dimenRect)) {
2589 result.emplace_back(dimenRect);
2590 return true;
2591 } else {
2592 return false;
2593 }
2594 }
2595
JsSize(const JSCallbackInfo & info)2596 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
2597 {
2598 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2599 auto jsVal = info[0];
2600 if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
2601 return;
2602 }
2603
2604 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2605 JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
2606 JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
2607 }
2608
JsConstraintSize(const JSCallbackInfo & info)2609 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
2610 {
2611 ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.minWidth");
2612 ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.maxWidth");
2613 ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.minHeight");
2614 ViewAbstractModel::GetInstance()->ResetResObj("constraintSize.maxHeight");
2615 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2616 auto jsVal = info[0];
2617 if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
2618 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2619 ViewAbstractModel::GetInstance()->ResetMinSize(true);
2620 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2621 ViewAbstractModel::GetInstance()->ResetMinSize(false);
2622 return;
2623 }
2624
2625 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2626
2627 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
2628 CalcDimension minWidth;
2629 RefPtr<ResourceObject> minWidthResObj;
2630 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
2631 CalcDimension maxWidth;
2632 RefPtr<ResourceObject> maxWidthResObj;
2633 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
2634 CalcDimension minHeight;
2635 RefPtr<ResourceObject> minHeightResObj;
2636 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
2637 CalcDimension maxHeight;
2638 RefPtr<ResourceObject> maxHeightResObj;
2639 bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
2640 if (ParseJsDimensionVp(minWidthValue, minWidth, minWidthResObj)) {
2641 ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
2642 } else if (version10OrLarger) {
2643 ViewAbstractModel::GetInstance()->ResetMinSize(true);
2644 }
2645
2646 if (ParseJsDimensionVp(maxWidthValue, maxWidth, maxWidthResObj)) {
2647 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
2648 } else if (version10OrLarger) {
2649 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2650 }
2651
2652 if (ParseJsDimensionVp(minHeightValue, minHeight, minHeightResObj)) {
2653 ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
2654 } else if (version10OrLarger) {
2655 ViewAbstractModel::GetInstance()->ResetMinSize(false);
2656 }
2657
2658 if (ParseJsDimensionVp(maxHeightValue, maxHeight, maxHeightResObj)) {
2659 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
2660 } else if (version10OrLarger) {
2661 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2662 }
2663 SetConstraintSize(minWidthResObj, maxWidthResObj, minHeightResObj, maxHeightResObj);
2664 }
2665
JsLayoutPriority(const JSCallbackInfo & info)2666 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
2667 {
2668 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2669 auto jsVal = info[0];
2670 if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
2671 return;
2672 }
2673
2674 int32_t priority;
2675 if (jsVal->IsNumber()) {
2676 priority = jsVal->ToNumber<int32_t>();
2677 } else {
2678 priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
2679 }
2680 ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
2681 }
2682
JsLayoutWeight(const JSCallbackInfo & info)2683 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
2684 {
2685 float value = 0.0f;
2686 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2687 auto jsVal = info[0];
2688 if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
2689 if (!jsVal->IsUndefined()) {
2690 return;
2691 }
2692 }
2693
2694 if (jsVal->IsNumber()) {
2695 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2696 value = jsVal->ToNumber<float>();
2697 } else {
2698 value = jsVal->ToNumber<int32_t>();
2699 }
2700 } else {
2701 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2702 value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
2703 } else {
2704 value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
2705 }
2706 }
2707
2708 ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
2709 }
2710
JsAlign(const JSCallbackInfo & info)2711 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
2712 {
2713 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::STRING };
2714 auto jsVal = info[0];
2715 if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
2716 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2717 ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
2718 return;
2719 }
2720 if (jsVal->IsNumber()) {
2721 auto value = jsVal->ToNumber<int32_t>();
2722 Alignment alignment = ParseAlignment(value);
2723 ViewAbstractModel::GetInstance()->SetAlign(alignment);
2724 ViewAbstractModel::GetInstance()->SetIsMirrorable(false);
2725 } else {
2726 std::string localizedAlignment = jsVal->ToString();
2727 ViewAbstractModel::GetInstance()->SetAlign(localizedAlignment);
2728 ViewAbstractModel::GetInstance()->SetIsMirrorable(true);
2729 }
2730 }
2731
JsLayoutGravity(const JSCallbackInfo & info)2732 void JSViewAbstract::JsLayoutGravity(const JSCallbackInfo& info)
2733 {
2734 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2735 auto jsVal = info[0];
2736 if (!CheckJSCallbackInfo("JsLayoutGravity", jsVal, checkList)) {
2737 ViewAbstractModel::GetInstance()->SetLayoutGravity(Alignment::CENTER);
2738 return;
2739 }
2740
2741 if (jsVal->IsString()) {
2742 std::string value = jsVal->ToString();
2743 Alignment layoutGravityAlignment = NG::BoxLayoutAlgorithm::MapLocalizedToAlignment(value);
2744 ViewAbstractModel::GetInstance()->SetLayoutGravity(layoutGravityAlignment);
2745 }
2746 }
2747
JsPosition(const JSCallbackInfo & info)2748 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
2749 {
2750 ViewAbstractModel::GetInstance()->ResetResObj("position.x");
2751 ViewAbstractModel::GetInstance()->ResetResObj("position.y");
2752 ViewAbstractModel::GetInstance()->ResetResObj("position.edges");
2753 CalcDimension x;
2754 CalcDimension y;
2755 RefPtr<ResourceObject> xResObj;
2756 RefPtr<ResourceObject> yResObj;
2757 OHOS::Ace::EdgesParam edges;
2758
2759 auto jsArg = info[0];
2760 if (jsArg->IsObject()) {
2761 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2762 if (ParseLocationProps(jsObj, x, y, xResObj, yResObj)) {
2763 if (SystemProperties::ConfigChangePerform()) {
2764 return ViewAbstractModel::GetInstance()->SetPosition(x, y, xResObj, yResObj);
2765 } else {
2766 return ViewAbstractModel::GetInstance()->SetPosition(x, y);
2767 }
2768 } else if (ParseLocalizedEdges(jsObj, edges)) {
2769 ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
2770 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2771 } else if (ParseLocationPropsEdges(jsObj, edges)) {
2772 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2773 }
2774 }
2775 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2776 ViewAbstractModel::GetInstance()->ResetPosition();
2777 } else {
2778 ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
2779 }
2780 }
2781
JsMarkAnchor(const JSCallbackInfo & info)2782 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
2783 {
2784 ViewAbstractModel::GetInstance()->ResetResObj("markAnchor.x");
2785 ViewAbstractModel::GetInstance()->ResetResObj("markAnchor.y");
2786 CalcDimension x;
2787 CalcDimension y;
2788 RefPtr<ResourceObject> xResObj;
2789 RefPtr<ResourceObject> yResObj;
2790
2791 auto jsArg = info[0];
2792 if (jsArg->IsObject()) {
2793 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2794 if (ParseMarkAnchorPosition(jsObj, x, y)) {
2795 ViewAbstractModel::GetInstance()->SetMarkAnchorStart(x);
2796 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2797 }
2798 if (ParseLocationProps(jsObj, x, y, xResObj, yResObj)) {
2799 ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
2800 if (SystemProperties::ConfigChangePerform()) {
2801 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y, xResObj, yResObj);
2802 } else {
2803 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2804 }
2805 }
2806 }
2807 ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
2808 ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
2809 }
2810
JsOffset(const JSCallbackInfo & info)2811 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
2812 {
2813 ViewAbstractModel::GetInstance()->ResetResObj("offset.x");
2814 ViewAbstractModel::GetInstance()->ResetResObj("offset.y");
2815 ViewAbstractModel::GetInstance()->ResetResObj("offset.edges");
2816 CalcDimension x;
2817 CalcDimension y;
2818 RefPtr<ResourceObject> xResObj;
2819 RefPtr<ResourceObject> yResObj;
2820 OHOS::Ace::EdgesParam edges;
2821 auto jsArg = info[0];
2822 if (jsArg->IsObject()) {
2823 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2824 if (ParseLocalizedEdges(jsObj, edges)) {
2825 ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
2826 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2827 } else if (ParseLocationProps(jsObj, x, y, xResObj, yResObj)) {
2828 if (SystemProperties::ConfigChangePerform()) {
2829 return ViewAbstractModel::GetInstance()->SetOffset(x, y, xResObj, yResObj);
2830 } else {
2831 return ViewAbstractModel::GetInstance()->SetOffset(x, y);
2832 }
2833 } else if (ParseLocationPropsEdges(jsObj, edges)) {
2834 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2835 }
2836 }
2837
2838 ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
2839 }
2840
JsEnabled(const JSCallbackInfo & info)2841 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
2842 {
2843 auto arg = info[0];
2844 if (!arg->IsBoolean()) {
2845 ViewAbstractModel::GetInstance()->SetEnabled(true);
2846 } else {
2847 ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
2848 }
2849 }
2850
JsAspectRatio(const JSCallbackInfo & info)2851 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
2852 {
2853 double value = 0.0;
2854 auto jsAspectRatio = info[0];
2855 if (!ParseJsDouble(jsAspectRatio, value)) {
2856 // add version protection, undefined use default value
2857 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
2858 (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
2859 ViewAbstractModel::GetInstance()->ResetAspectRatio();
2860 return;
2861 } else {
2862 return;
2863 }
2864 }
2865
2866 // negative use default value.
2867 if (LessOrEqual(value, 0.0)) {
2868 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2869 ViewAbstractModel::GetInstance()->ResetAspectRatio();
2870 return;
2871 } else {
2872 value = 1.0;
2873 }
2874 }
2875
2876 ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
2877 }
2878
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2879 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
2880 std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
2881 {
2882 if (info[0]->IsString()) {
2883 std::string text = info[0]->ToString();
2884 ViewAbstractModel::GetInstance()->SetOverlay(
2885 text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
2886 } else if (info[0]->IsObject()) {
2887 JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
2888 auto builder = overlayObject->GetProperty("builder");
2889 if (builder->IsFunction()) {
2890 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2891 CHECK_NULL_VOID(builderFunc);
2892 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2893 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
2894 node = targetNode]() {
2895 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2896 ACE_SCORING_EVENT("Overlay");
2897 PipelineContext::SetCallBackNode(node);
2898 func->Execute();
2899 };
2900 ViewAbstractModel::GetInstance()->SetOverlay(
2901 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
2902 return;
2903 }
2904
2905 JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
2906 if (!builderNode->IsObject()) {
2907 return;
2908 }
2909 auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2910 JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2911 if (nodePtr.IsEmpty()) {
2912 return;
2913 }
2914 const auto* vm = nodePtr->GetEcmaVM();
2915 auto localHandle = nodePtr->GetLocalHandle();
2916 if (!localHandle->IsNativePointer(vm)) {
2917 return;
2918 }
2919 auto* node = localHandle->ToNativePointer(vm)->Value();
2920 auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2921 CHECK_NULL_VOID(frameNode);
2922 RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2923 ViewAbstractModel::GetInstance()->SetOverlay(
2924 "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2925 }
2926 }
2927
JsOverlay(const JSCallbackInfo & info)2928 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2929 {
2930 if (info.Length() > 0 && (info[0]->IsUndefined())) {
2931 ViewAbstractModel::GetInstance()->SetOverlay(
2932 "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2933 return;
2934 }
2935
2936 if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2937 return;
2938 }
2939 std::optional<Alignment> align;
2940 std::optional<CalcDimension> offsetX;
2941 std::optional<CalcDimension> offsetY;
2942
2943 if (info[1]->IsObject()) {
2944 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2945 JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2946 auto value = alignVal->ToNumber<int32_t>();
2947 Alignment alignment = ParseAlignment(value);
2948 align = alignment;
2949
2950 JSRef<JSVal> val = optionObj->GetProperty("offset");
2951 if (val->IsObject()) {
2952 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2953 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2954 CalcDimension x;
2955 if (ParseJsDimensionVp(xVal, x)) {
2956 offsetX = x;
2957 }
2958 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2959 CalcDimension y;
2960 if (ParseJsDimensionVp(yVal, y)) {
2961 offsetY = y;
2962 }
2963 }
2964 }
2965
2966 ParseOverlayFirstParam(info, align, offsetX, offsetY);
2967 }
2968
ParseAlignment(int32_t align)2969 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2970 {
2971 Alignment alignment = Alignment::CENTER;
2972 switch (align) {
2973 case 0:
2974 alignment = Alignment::TOP_LEFT;
2975 break;
2976 case 1:
2977 alignment = Alignment::TOP_CENTER;
2978 break;
2979 case 2:
2980 alignment = Alignment::TOP_RIGHT;
2981 break;
2982 case 3:
2983 alignment = Alignment::CENTER_LEFT;
2984 break;
2985 case 4:
2986 alignment = Alignment::CENTER;
2987 break;
2988 case 5:
2989 alignment = Alignment::CENTER_RIGHT;
2990 break;
2991 case 6:
2992 alignment = Alignment::BOTTOM_LEFT;
2993 break;
2994 case 7:
2995 alignment = Alignment::BOTTOM_CENTER;
2996 break;
2997 case 8:
2998 alignment = Alignment::BOTTOM_RIGHT;
2999 break;
3000 default:
3001 break;
3002 }
3003 return alignment;
3004 }
3005
ParseLayoutPolicy(const std::string & layoutPolicy)3006 LayoutCalPolicy JSViewAbstract::ParseLayoutPolicy(const std::string& layoutPolicy)
3007 {
3008 if (layoutPolicy == "matchParent") {
3009 return LayoutCalPolicy::MATCH_PARENT;
3010 }
3011 if (layoutPolicy == "wrapContent") {
3012 return LayoutCalPolicy::WRAP_CONTENT;
3013 }
3014 if (layoutPolicy == "fixAtIdealSize") {
3015 return LayoutCalPolicy::FIX_AT_IDEAL_SIZE;
3016 }
3017 return LayoutCalPolicy::NO_MATCH;
3018 }
3019
SetVisibility(const JSCallbackInfo & info)3020 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
3021 {
3022 int32_t visible = 0;
3023 JSRef<JSVal> arg = info[0];
3024 if (arg->IsNull() || arg->IsUndefined()) {
3025 // undefined value use default value.
3026 visible = 0;
3027 } else if (!arg->IsNumber()) {
3028 return;
3029 } else {
3030 visible = arg->ToNumber<int32_t>();
3031 }
3032
3033 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3034 (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
3035 visible = 0;
3036 }
3037
3038 if (info.Length() > 1 && info[1]->IsFunction()) {
3039 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
3040 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3041 auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
3042 int32_t visible) {
3043 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3044 ACE_SCORING_EVENT("onVisibilityChange");
3045 PipelineContext::SetCallBackNode(node);
3046 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
3047 func->ExecuteJS(1, &newJSVal);
3048 };
3049 ViewAbstractModel::GetInstance()->SetVisibility(
3050 static_cast<VisibleType>(visible), std::move(onVisibilityChange));
3051 } else {
3052 ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
3053 }
3054 }
3055
JsSetFreeze(const JSCallbackInfo & info)3056 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
3057 {
3058 if (info[0]->IsBoolean()) {
3059 ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
3060 }
3061 }
3062
JsFlexBasis(const JSCallbackInfo & info)3063 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
3064 {
3065 CalcDimension value;
3066 if (!ParseJsDimensionVp(info[0], value)) {
3067 value.SetUnit(DimensionUnit::AUTO);
3068 }
3069 // flexbasis don't support percent case.
3070 if (value.Unit() == DimensionUnit::PERCENT) {
3071 value.SetUnit(DimensionUnit::AUTO);
3072 }
3073 ViewAbstractModel::GetInstance()->SetFlexBasis(value);
3074 }
3075
JsFlexGrow(const JSCallbackInfo & info)3076 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
3077 {
3078 double value = 0.0;
3079 if (!ParseJsDouble(info[0], value)) {
3080 if (info[0]->IsNull() || info[0]->IsUndefined()) {
3081 // undefined use default value.
3082 value = 0.0;
3083 } else {
3084 return;
3085 }
3086 }
3087 // negative use default value.
3088 if (value < 0.0) {
3089 value = 0.0;
3090 }
3091 ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
3092 }
3093
JsFlexShrink(const JSCallbackInfo & info)3094 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
3095 {
3096 double value = 0.0;
3097 if (!ParseJsDouble(info[0], value)) {
3098 if (info[0]->IsNull() || info[0]->IsUndefined()) {
3099 // undefined use default value.
3100 ViewAbstractModel::GetInstance()->ResetFlexShrink();
3101 return;
3102 } else {
3103 return;
3104 }
3105 }
3106 // negative use default value.
3107 if (value < 0.0) {
3108 ViewAbstractModel::GetInstance()->ResetFlexShrink();
3109 return;
3110 }
3111 ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
3112 }
3113
JsDisplayPriority(const JSCallbackInfo & info)3114 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
3115 {
3116 double value = 0.0;
3117 if (!ParseJsDouble(info[0], value)) {
3118 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
3119 ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
3120 }
3121 return;
3122 }
3123 ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
3124 }
3125
JsSharedTransition(const JSCallbackInfo & info)3126 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
3127 {
3128 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
3129 auto jsVal = info[0];
3130 if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
3131 return;
3132 }
3133 // id
3134 auto id = jsVal->ToString();
3135 if (id.empty()) {
3136 return;
3137 }
3138 std::shared_ptr<SharedTransitionOption> sharedOption;
3139
3140 // options
3141 if (info.Length() > 1 && info[1]->IsObject()) {
3142 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
3143 sharedOption = std::make_shared<SharedTransitionOption>();
3144 // default: duration: 1000
3145 sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
3146 if (sharedOption->duration < 0) {
3147 sharedOption->duration = DEFAULT_DURATION;
3148 }
3149 // default: delay: 0
3150 sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
3151 if (sharedOption->delay < 0) {
3152 sharedOption->delay = 0;
3153 }
3154 // default: LinearCurve
3155 RefPtr<Curve> curve;
3156 JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
3157 if (curveArgs->IsString()) {
3158 curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
3159 } else if (curveArgs->IsObject()) {
3160 JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
3161 if (!curveString->IsString()) {
3162 return;
3163 }
3164 curve = CreateCurve(curveString->ToString(), false);
3165 }
3166 if (!curve) {
3167 curve = Curves::LINEAR;
3168 }
3169 sharedOption->curve = curve;
3170 // motionPath
3171 if (jsObj->HasProperty("motionPath")) {
3172 MotionPathOption motionPathOption;
3173 if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
3174 sharedOption->motionPathOption = motionPathOption;
3175 }
3176 }
3177 // zIndex
3178 sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
3179 // type
3180 int32_t type = jsObj->GetPropertyValue<int32_t>("type",
3181 static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
3182 sharedOption->type = static_cast<SharedTransitionEffectType>(type);
3183 }
3184 ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
3185 }
3186
JsGeometryTransition(const JSCallbackInfo & info)3187 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
3188 {
3189 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
3190 auto jsVal = info[0];
3191 if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
3192 return;
3193 }
3194 // id
3195 auto id = jsVal->ToString();
3196 // follow flag
3197 bool followWithOutTransition = false;
3198 // hierarchy flag
3199 bool doRegisterSharedTransition = true;
3200 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
3201 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3202 ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
3203
3204 auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
3205 ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
3206 switch (transitionHierarchyStrategy) {
3207 case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
3208 doRegisterSharedTransition = false;
3209 break;
3210 case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
3211 doRegisterSharedTransition = true;
3212 break;
3213 default:
3214 break;
3215 }
3216 }
3217 ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
3218 }
3219
JsAlignSelf(const JSCallbackInfo & info)3220 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
3221 {
3222 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
3223 auto jsVal = info[0];
3224 if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
3225 ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
3226 return;
3227 }
3228 auto alignVal = jsVal->ToNumber<int32_t>();
3229
3230 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
3231 ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
3232 }
3233 }
3234
JsBackgroundColor(const JSCallbackInfo & info)3235 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
3236 {
3237 Color backgroundColor;
3238 if (SystemProperties::ConfigChangePerform()) {
3239 RefPtr<ResourceObject> backgroundColorResObj;
3240 if (!ParseJsColor(info[0], backgroundColor, backgroundColorResObj)) {
3241 backgroundColor = Color::TRANSPARENT;
3242 }
3243 ViewAbstractModel::GetInstance()->SetBackgroundColorWithResourceObj(backgroundColor, backgroundColorResObj);
3244 return;
3245 } else {
3246 if (!ParseJsColor(info[0], backgroundColor)) {
3247 backgroundColor = Color::TRANSPARENT;
3248 }
3249 }
3250
3251 ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
3252 }
3253
JsBackgroundImage(const JSCallbackInfo & info)3254 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
3255 {
3256 int32_t resId = 0;
3257 std::string src;
3258 std::string bundle;
3259 std::string module;
3260 RefPtr<PixelMap> pixmap = nullptr;
3261 auto jsBackgroundImage = info[0];
3262 GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
3263 int32_t repeatIndex = 0;
3264 bool syncMode = false;
3265 ParseBackgroundImageOption(info, repeatIndex, syncMode);
3266 ViewAbstractModel::GetInstance()->SetBackgroundImageSyncMode(syncMode);
3267 RefPtr<ResourceObject> backgroundImageResObj;
3268 if (jsBackgroundImage->IsString()) {
3269 src = jsBackgroundImage->ToString();
3270 ViewAbstractModel::GetInstance()->SetBackgroundImage(
3271 ImageSourceInfo { src, bundle, module }, GetThemeConstants());
3272 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSrc");
3273 } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId, backgroundImageResObj)) {
3274 if (!SystemProperties::ConfigChangePerform()) {
3275 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo{src, bundle, module}, nullptr);
3276 } else {
3277 ViewAbstractModel::GetInstance()->SetBackgroundImageWithResourceObj(
3278 backgroundImageResObj, ImageSourceInfo { src, bundle, module }, nullptr);
3279 }
3280 } else {
3281 #if defined(PIXEL_MAP_SUPPORTED)
3282 if (IsDrawable(jsBackgroundImage)) {
3283 pixmap = GetDrawablePixmap(jsBackgroundImage);
3284 } else {
3285 pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
3286 }
3287 #endif
3288 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
3289 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSrc");
3290 }
3291 if (info.Length() == 2) { // 2 is background image info length
3292 auto jsImageRepeat = info[1];
3293 if (jsImageRepeat->IsNumber()) {
3294 repeatIndex = jsImageRepeat->ToNumber<int32_t>();
3295 }
3296 }
3297 auto repeat = static_cast<ImageRepeat>(repeatIndex);
3298 ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
3299 }
3300
ParseBackgroundImageOption(const JSCallbackInfo & info,int32_t & repeatIndex,bool & syncMode)3301 void JSViewAbstract::ParseBackgroundImageOption(const JSCallbackInfo& info, int32_t& repeatIndex, bool& syncMode)
3302 {
3303 if (info.Length() < 2) { // 2 represents the least para num;
3304 return;
3305 }
3306 if (!info[1]->IsObject()) {
3307 return;
3308 }
3309 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3310 if (jsOption->GetProperty("syncLoad")->IsBoolean()) {
3311 syncMode = jsOption->GetProperty("syncLoad")->ToBoolean();
3312 }
3313 if (jsOption->GetProperty("repeat")->IsNumber()) {
3314 repeatIndex = jsOption->GetProperty("repeat")->ToNumber<int32_t>();
3315 }
3316 }
3317
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)3318 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
3319 {
3320 auto blurOptionProperty = jsBlurOption->GetProperty("grayscale");
3321 if (blurOptionProperty->IsArray()) {
3322 JSRef<JSArray> params = JSRef<JSArray>::Cast(blurOptionProperty);
3323 auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
3324 auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
3325 std::vector<float> greyVec(2); // 2 number
3326 greyVec[0] = grey1;
3327 greyVec[1] = grey2;
3328 blurOption.grayscale = greyVec;
3329 }
3330 }
3331
ParseSysOptions(const JSRef<JSObject> & jsSysOptions,SysOptions & sysOptions)3332 void JSViewAbstract::ParseSysOptions(const JSRef<JSObject>& jsSysOptions, SysOptions& sysOptions)
3333 {
3334 auto disableAdaptation = jsSysOptions->GetProperty("disableSystemAdaptation");
3335 if (disableAdaptation->IsBoolean()) {
3336 sysOptions.disableSystemAdaptation = disableAdaptation->ToBoolean();
3337 }
3338 }
3339
ParseInactiveColor(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)3340 void JSViewAbstract::ParseInactiveColor(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
3341 {
3342 RefPtr<ResourceObject> inactiveColorResObj;
3343 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor, inactiveColorResObj)) {
3344 styleOption.isValidColor = true;
3345 }
3346 if (SystemProperties::ConfigChangePerform() && inactiveColorResObj) {
3347 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, BlurStyleOption& styleOption) {
3348 Color inactiveColorValue;
3349 ResourceParseUtils::ParseResColor(resObj, inactiveColorValue);
3350 styleOption.inactiveColor = inactiveColorValue;
3351 styleOption.isValidColor = true;
3352 };
3353 styleOption.AddResource("backgroundBlurStyle.backgroundBlurStyleOptions.inactiveColor",
3354 inactiveColorResObj, std::move(updateFunc));
3355 }
3356 }
3357
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)3358 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
3359 {
3360 if (jsOption->IsUndefined()) {
3361 return;
3362 }
3363 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3364 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3365 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3366 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3367 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3368 }
3369 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3370 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3371 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3372 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3373 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3374 }
3375
3376 // policy
3377 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
3378 ParseJsInt32(jsOption->GetProperty("policy"), policy);
3379 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
3380 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3381 styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3382 }
3383
3384 // blurType
3385 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3386 ParseJsInt32(jsOption->GetProperty("type"), blurType);
3387 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3388 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3389 styleOption.blurType = static_cast<BlurType>(blurType);
3390 }
3391
3392 // inactiveColor
3393 ParseInactiveColor(jsOption, styleOption);
3394
3395 // scale
3396 if (jsOption->GetProperty("scale")->IsNumber()) {
3397 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3398 styleOption.scale = std::clamp(scale, 0.0, 1.0);
3399 }
3400
3401 if (jsOption->GetProperty("blurOptions")->IsObject()) {
3402 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3403 BlurOption blurOption;
3404 ParseBlurOption(jsBlurOption, blurOption);
3405 styleOption.blurOption = blurOption;
3406 }
3407 }
3408
JsBackgroundBlurStyle(const JSCallbackInfo & info)3409 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
3410 {
3411 if (info.Length() == 0) {
3412 return;
3413 }
3414 ViewAbstractModel::GetInstance()->RemoveResObj("backgroundBlurStyle.backgroundBlurStyleOptions");
3415 BlurStyleOption styleOption;
3416 if (info[0]->IsNumber()) {
3417 auto blurStyle = info[0]->ToNumber<int32_t>();
3418 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3419 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3420 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3421 }
3422 }
3423 if (info.Length() > 1 && info[1]->IsObject()) {
3424 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3425 ParseBlurStyleOption(jsOption, styleOption);
3426 }
3427 SysOptions sysOptions;
3428 sysOptions.disableSystemAdaptation = false;
3429 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
3430 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
3431 ParseSysOptions(jsSysOptions, sysOptions);
3432 }
3433 ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption, sysOptions);
3434 }
3435
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)3436 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
3437 {
3438 double rate = 1.0f;
3439 auto jsRate = jsOption->GetProperty("rate");
3440 if (jsRate->IsNumber()) {
3441 rate = jsRate->ToNumber<double>();
3442 }
3443 double lightUpDegree = 0.0f;
3444 auto jslightUpDegree = jsOption->GetProperty("lightUpDegree");
3445 if (jslightUpDegree->IsNumber()) {
3446 lightUpDegree = jslightUpDegree->ToNumber<double>();
3447 }
3448 double cubicCoeff = 0.0f;
3449 auto jsCubicCoeff = jsOption->GetProperty("cubicCoeff");
3450 if (jsCubicCoeff->IsNumber()) {
3451 cubicCoeff = jsCubicCoeff->ToNumber<double>();
3452 }
3453 double quadCoeff = 0.0f;
3454 auto jsQuadCoeff = jsOption->GetProperty("quadCoeff");
3455 if (jsQuadCoeff->IsNumber()) {
3456 quadCoeff = jsQuadCoeff->ToNumber<double>();
3457 }
3458 double saturation = 1.0f;
3459 auto jsSaturation = jsOption->GetProperty("saturation");
3460 if (jsSaturation->IsNumber()) {
3461 saturation = jsSaturation->ToNumber<double>();
3462 }
3463 std::vector<float> posRGB(3, 0.0);
3464 auto jsPosRGB = jsOption->GetProperty("posRGB");
3465 if (jsPosRGB->IsArray()) {
3466 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsPosRGB);
3467 auto r = params->GetValueAt(0)->ToNumber<double>();
3468 auto g = params->GetValueAt(1)->ToNumber<double>();
3469 auto b = params->GetValueAt(2)->ToNumber<double>();
3470 posRGB[0] = r;
3471 posRGB[1] = g;
3472 posRGB[2] = b;
3473 }
3474 std::vector<float> negRGB(3, 0.0);
3475 auto jsNegRGB = jsOption->GetProperty("negRGB");
3476 if (jsNegRGB->IsArray()) {
3477 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsNegRGB);
3478 auto r = params->GetValueAt(0)->ToNumber<double>();
3479 auto g = params->GetValueAt(1)->ToNumber<double>();
3480 auto b = params->GetValueAt(2)->ToNumber<double>();
3481 negRGB[0] = r;
3482 negRGB[1] = g;
3483 negRGB[2] = b;
3484 }
3485 double fraction = 1.0f;
3486 auto jsFraction = jsOption->GetProperty("fraction");
3487 if (jsFraction->IsNumber()) {
3488 fraction = jsFraction->ToNumber<double>();
3489 fraction = std::clamp(fraction, 0.0, 1.0);
3490 }
3491 brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
3492 }
3493
GetEffectOptionColor(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3494 void JSViewAbstract::GetEffectOptionColor(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3495 {
3496 if (!SystemProperties::ConfigChangePerform()) {
3497 ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
3498 } else {
3499 RefPtr<ResourceObject> colorResObj;
3500 ParseJsColor(jsOption->GetProperty("color"), effectOption.color, colorResObj);
3501 if (colorResObj) {
3502 auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, EffectOption& effectOption) {
3503 Color effectOptionColor;
3504 ResourceParseUtils::ParseResColor(colorResObj, effectOptionColor);
3505 effectOption.color = effectOptionColor;
3506 };
3507 effectOption.AddResource("backgroundEffect.color", colorResObj, std::move(updateFunc));
3508 }
3509 }
3510 }
3511
GetEffectOptionInactiveColorUpdate(const RefPtr<ResourceObject> & inactiveColorObj,EffectOption & effectOption)3512 void JSViewAbstract::GetEffectOptionInactiveColorUpdate(const RefPtr<ResourceObject>& inactiveColorObj,
3513 EffectOption& effectOption)
3514 {
3515 if (inactiveColorObj) {
3516 auto&& updateFunc = [](const RefPtr<ResourceObject>& inactiveColorObj, EffectOption& effectOption) {
3517 Color effectOptionInactiveColor;
3518 ResourceParseUtils::ParseResColor(inactiveColorObj, effectOptionInactiveColor);
3519 effectOption.inactiveColor = effectOptionInactiveColor;
3520 };
3521 effectOption.AddResource("backgroundEffect.inactiveColor", inactiveColorObj, std::move(updateFunc));
3522 }
3523 }
3524
GetEffectOptionInactiveColor(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3525 void JSViewAbstract::GetEffectOptionInactiveColor(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3526 {
3527 if (!SystemProperties::ConfigChangePerform()) {
3528 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
3529 effectOption.isValidColor = true;
3530 }
3531 } else {
3532 RefPtr<ResourceObject> inactiveColorObj;
3533 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor, inactiveColorObj)) {
3534 GetEffectOptionInactiveColorUpdate(inactiveColorObj, effectOption);
3535 effectOption.isValidColor = true;
3536 }
3537 }
3538 }
3539
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3540 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3541 {
3542 CalcDimension radius;
3543 if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
3544 radius.SetValue(0.0f);
3545 }
3546 effectOption.radius = radius;
3547
3548 double saturation = 1.0f;
3549 if (jsOption->GetProperty("saturation")->IsNumber()) {
3550 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
3551 saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
3552 }
3553 effectOption.saturation = saturation;
3554
3555 double brightness = 1.0f;
3556 if (jsOption->GetProperty("brightness")->IsNumber()) {
3557 brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
3558 brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
3559 }
3560 effectOption.brightness = brightness;
3561
3562 GetEffectOptionColor(jsOption, effectOption);
3563
3564 auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3565 auto adaptiveColor = AdaptiveColor::DEFAULT;
3566 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
3567 if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3568 adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3569 adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
3570 }
3571 effectOption.adaptiveColor = adaptiveColor;
3572
3573 // policy
3574 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
3575 ParseJsInt32(jsOption->GetProperty("policy"), policy);
3576 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
3577 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3578 effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3579 }
3580
3581 // blurType
3582 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3583 ParseJsInt32(jsOption->GetProperty("type"), blurType);
3584 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3585 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3586 effectOption.blurType = static_cast<BlurType>(blurType);
3587 }
3588
3589 // inactiveColor
3590 GetEffectOptionInactiveColor(jsOption, effectOption);
3591
3592 BlurOption blurOption;
3593 if (jsOption->GetProperty("blurOptions")->IsObject()) {
3594 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3595 ParseBlurOption(jsBlurOption, blurOption);
3596 effectOption.blurOption = blurOption;
3597 }
3598 }
3599
JsForegroundEffect(const JSCallbackInfo & info)3600 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
3601 {
3602 if (info.Length() == 0) {
3603 return;
3604 }
3605 float radius = 0.0;
3606 if (info[0]->IsObject()) {
3607 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3608 if (jsOption->GetProperty("radius")->IsNumber()) {
3609 radius = jsOption->GetProperty("radius")->ToNumber<float>();
3610 }
3611 }
3612 radius = std::max(radius, 0.0f);
3613 ViewAbstractModel::GetInstance()->SetForegroundEffect(radius);
3614 }
3615
JsBackgroundEffect(const JSCallbackInfo & info)3616 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
3617 {
3618 if (info.Length() == 0) {
3619 return;
3620 }
3621 ViewAbstractModel::GetInstance()->RemoveResObj("backgroundEffect");
3622 EffectOption option;
3623 if (info[0]->IsObject()) {
3624 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3625 ParseEffectOption(jsOption, option);
3626 }
3627 SysOptions sysOptions;
3628 sysOptions.disableSystemAdaptation = false;
3629 if (info.Length() > NUM1 && info[NUM1]->IsObject()) {
3630 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM1]);
3631 ParseSysOptions(jsSysOptions, sysOptions);
3632 }
3633 ViewAbstractModel::GetInstance()->SetBackgroundEffect(option, sysOptions);
3634 }
3635
JsForegroundBlurStyle(const JSCallbackInfo & info)3636 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
3637 {
3638 if (info.Length() == 0) {
3639 return;
3640 }
3641 BlurStyleOption styleOption;
3642 if (info[0]->IsNumber()) {
3643 auto blurStyle = info[0]->ToNumber<int32_t>();
3644 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3645 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3646 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3647 }
3648 }
3649 if (info.Length() > 1 && info[1]->IsObject()) {
3650 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3651 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3652 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3653 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3654 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3655 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3656 }
3657 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3658 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3659 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3660 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3661 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3662 }
3663 if (jsOption->GetProperty("scale")->IsNumber()) {
3664 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3665 styleOption.scale = std::clamp(scale, 0.0, 1.0);
3666 }
3667
3668 if (jsOption->GetProperty("blurOptions")->IsObject()) {
3669 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3670 BlurOption blurOption;
3671 ParseBlurOption(jsBlurOption, blurOption);
3672 styleOption.blurOption = blurOption;
3673 }
3674 }
3675 SysOptions sysOptions;
3676 sysOptions.disableSystemAdaptation = false;
3677 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
3678 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
3679 ParseSysOptions(jsSysOptions, sysOptions);
3680 }
3681 ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption, sysOptions);
3682 }
3683
JsSphericalEffect(const JSCallbackInfo & info)3684 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
3685 {
3686 auto radio = 0.0;
3687 if (info[0]->IsNumber()) {
3688 radio = info[0]->ToNumber<double>();
3689 }
3690 ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
3691 }
3692
GetPixelStretchEffectLeftObj(const JSRef<JSObject> & jsObject,CalcDimension & left,PixStretchEffectOption & option)3693 void JSViewAbstract::GetPixelStretchEffectLeftObj(const JSRef<JSObject>& jsObject, CalcDimension& left, PixStretchEffectOption& option)
3694 {
3695 RefPtr<ResourceObject> leftObj;
3696 ParseJsDimensionVp(jsObject->GetProperty("left"), left, leftObj);
3697 if (leftObj) {
3698 auto&& updateFunc = [](const RefPtr<ResourceObject>& leftObj, PixStretchEffectOption& effectOption) {
3699 CalcDimension left;
3700 ResourceParseUtils::ParseResDimensionVp(leftObj, left);
3701 effectOption.left = left;
3702 };
3703 option.AddResource("pixelStretchEffect.left", leftObj, std::move(updateFunc));
3704 }
3705 }
3706
GetPixelStretchEffectRightObj(const JSRef<JSObject> & jsObject,CalcDimension & right,PixStretchEffectOption & option)3707 void JSViewAbstract::GetPixelStretchEffectRightObj(const JSRef<JSObject>& jsObject, CalcDimension& right, PixStretchEffectOption& option)
3708 {
3709 RefPtr<ResourceObject> rightObj;
3710 ParseJsDimensionVp(jsObject->GetProperty("right"), right, rightObj);
3711 if (rightObj) {
3712 auto&& updateFunc = [](const RefPtr<ResourceObject>& rightObj, PixStretchEffectOption& effectOption) {
3713 CalcDimension right;
3714 ResourceParseUtils::ParseResDimensionVp(rightObj, right);
3715 effectOption.right = right;
3716 };
3717 option.AddResource("pixelStretchEffect.right", rightObj, std::move(updateFunc));
3718 }
3719 }
3720
GetPixelStretchEffectTopObj(const JSRef<JSObject> & jsObject,CalcDimension & top,PixStretchEffectOption & option)3721 void JSViewAbstract::GetPixelStretchEffectTopObj(const JSRef<JSObject>& jsObject, CalcDimension& top, PixStretchEffectOption& option)
3722 {
3723 RefPtr<ResourceObject> topObj;
3724 ParseJsDimensionVp(jsObject->GetProperty("top"), top, topObj);
3725 if (topObj) {
3726 auto&& updateFunc = [](const RefPtr<ResourceObject>& topObj, PixStretchEffectOption& effectOption) {
3727 CalcDimension top;
3728 ResourceParseUtils::ParseResDimensionVp(topObj, top);
3729 effectOption.top = top;
3730 };
3731 option.AddResource("pixelStretchEffect.top", topObj, std::move(updateFunc));
3732 }
3733 }
3734
GetPixelStretchEffectBottomObj(const JSRef<JSObject> & jsObject,CalcDimension & bottom,PixStretchEffectOption & option)3735 void JSViewAbstract::GetPixelStretchEffectBottomObj(const JSRef<JSObject>& jsObject, CalcDimension& bottom, PixStretchEffectOption& option)
3736 {
3737 RefPtr<ResourceObject> bottomObj;
3738 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom, bottomObj);
3739 if (bottomObj) {
3740 auto&& updateFunc = [](const RefPtr<ResourceObject>& bottomObj, PixStretchEffectOption& effectOption) {
3741 CalcDimension bottom;
3742 ResourceParseUtils::ParseResDimensionVp(bottomObj, bottom);
3743 effectOption.bottom = bottom;
3744 };
3745 option.AddResource("pixelStretchEffect.bottom", bottomObj, std::move(updateFunc));
3746 }
3747 }
3748
JsPixelStretchEffect(const JSCallbackInfo & info)3749 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
3750 {
3751 ViewAbstractModel::GetInstance()->RemoveResObj("pixelStretchEffect");
3752 if (!info[0]->IsObject()) {
3753 PixStretchEffectOption option;
3754 option.ResetValue();
3755 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3756 return;
3757 }
3758 auto jsObject = JSRef<JSObject>::Cast(info[0]);
3759 CalcDimension left;
3760 CalcDimension right;
3761 CalcDimension top;
3762 CalcDimension bottom;
3763 PixStretchEffectOption option;
3764 if (!SystemProperties::ConfigChangePerform()) {
3765 ParseJsDimensionVp(jsObject->GetProperty("left"), left);
3766 ParseJsDimensionVp(jsObject->GetProperty("right"), right);
3767 ParseJsDimensionVp(jsObject->GetProperty("top"), top);
3768 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
3769 } else {
3770 GetPixelStretchEffectLeftObj(jsObject, left, option);
3771 GetPixelStretchEffectRightObj(jsObject, right, option);
3772 GetPixelStretchEffectTopObj(jsObject, top, option);
3773 GetPixelStretchEffectBottomObj(jsObject, bottom, option);
3774 }
3775
3776 bool illegalInput = InitPixStretchEffect(left, right, top, bottom);
3777 if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
3778 (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
3779 option.left = left;
3780 option.top = top;
3781 option.right = right;
3782 option.bottom = bottom;
3783 } else {
3784 illegalInput = true;
3785 }
3786 if (illegalInput) {
3787 option.ResetValue();
3788 }
3789 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3790 }
3791
InitPixStretchEffect(CalcDimension & left,CalcDimension & right,CalcDimension & top,CalcDimension bottom)3792 bool JSViewAbstract::InitPixStretchEffect(
3793 CalcDimension& left, CalcDimension& right, CalcDimension& top, CalcDimension bottom)
3794 {
3795 bool illegalInput = false;
3796 if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
3797 top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
3798 if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
3799 (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
3800 (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
3801 (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
3802 left.SetUnit(DimensionUnit::PERCENT);
3803 top.SetUnit(DimensionUnit::PERCENT);
3804 right.SetUnit(DimensionUnit::PERCENT);
3805 bottom.SetUnit(DimensionUnit::PERCENT);
3806 } else {
3807 illegalInput = true;
3808 }
3809 }
3810 return illegalInput;
3811 }
3812
JsLightUpEffect(const JSCallbackInfo & info)3813 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
3814 {
3815 auto radio = 1.0;
3816 if (info[0]->IsNumber()) {
3817 radio = info[0]->ToNumber<double>();
3818 }
3819 ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
3820 }
3821
JsBackgroundImageSize(const JSCallbackInfo & info)3822 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
3823 {
3824 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3825 BackgroundImageSize bgImgSize;
3826 auto jsVal = info[0];
3827 if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
3828 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
3829 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
3830 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3831 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSize");
3832 return;
3833 }
3834 if (jsVal->IsNumber()) {
3835 auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
3836 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3837 (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
3838 sizeType = BackgroundImageSizeType::AUTO;
3839 }
3840 bgImgSize.SetSizeTypeX(sizeType);
3841 bgImgSize.SetSizeTypeY(sizeType);
3842 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageSize");
3843 } else {
3844 CalcDimension width;
3845 CalcDimension height;
3846 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3847 RefPtr<ResourceObject> resObjWidth;
3848 RefPtr<ResourceObject> resObjHeight;
3849 ParseJsDimensionVp(object->GetProperty("width"), width, resObjWidth);
3850 ParseJsDimensionVp(object->GetProperty("height"), height, resObjHeight);
3851 ViewAbstractModel::GetInstance()->SetBackgroundImageSizeUpdateFunc(bgImgSize, resObjWidth, "width");
3852 ViewAbstractModel::GetInstance()->SetBackgroundImageSizeUpdateFunc(bgImgSize, resObjHeight, "height");
3853 double valueWidth = width.ConvertToPx();
3854 double valueHeight = height.ConvertToPx();
3855 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
3856 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
3857 if (width.Unit() == DimensionUnit::PERCENT) {
3858 typeWidth = BackgroundImageSizeType::PERCENT;
3859 valueWidth = width.Value() * FULL_DIMENSION;
3860 }
3861 if (height.Unit() == DimensionUnit::PERCENT) {
3862 typeHeight = BackgroundImageSizeType::PERCENT;
3863 valueHeight = height.Value() * FULL_DIMENSION;
3864 }
3865 bgImgSize.SetSizeTypeX(typeWidth);
3866 bgImgSize.SetSizeValueX(valueWidth);
3867 bgImgSize.SetSizeTypeY(typeHeight);
3868 bgImgSize.SetSizeValueY(valueHeight);
3869 }
3870
3871 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3872 }
3873
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3874 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
3875 {
3876 if (align > 8 || align < 0) { // align ranges from [0, 8].
3877 return;
3878 }
3879 std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
3880 { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
3881 { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
3882 SetBgImgPosition(
3883 DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
3884 }
3885
SetBackgroundImagePositionUpdateFunc(BackgroundImagePosition & bgImgPosition,const RefPtr<ResourceObject> & resObj,const std::string direction)3886 void SetBackgroundImagePositionUpdateFunc(
3887 BackgroundImagePosition& bgImgPosition, const RefPtr<ResourceObject>& resObj, const std::string direction)
3888 {
3889 if (direction.empty()) {
3890 return;
3891 }
3892 if (!resObj) {
3893 (direction == "x") ? bgImgPosition.RemoveResource("backgroundImagePositionX")
3894 : bgImgPosition.RemoveResource("backgroundImagePositionY");
3895 return;
3896 }
3897 auto&& updateFunc = [direction](const RefPtr<ResourceObject>& resObj, BackgroundImagePosition& position) {
3898 CalcDimension dimension;
3899 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
3900 double value = dimension.Value();
3901 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3902 value = dimension.ConvertToPx();
3903 }
3904 DimensionUnit type = DimensionUnit::PX;
3905 if (dimension.Unit() == DimensionUnit::PERCENT) {
3906 value = dimension.Value();
3907 type = DimensionUnit::PERCENT;
3908 }
3909 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
3910 (direction == "x") ? position.SetSizeX(AnimatableDimension(value, type, option))
3911 : position.SetSizeY(AnimatableDimension(value, type, option));
3912 };
3913 (direction == "x") ? bgImgPosition.AddResource("backgroundImagePositionX", resObj, std::move(updateFunc))
3914 : bgImgPosition.AddResource("backgroundImagePositionY", resObj, std::move(updateFunc));
3915 }
3916
JsBackgroundImagePosition(const JSCallbackInfo & info)3917 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
3918 {
3919 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3920 BackgroundImagePosition bgImgPosition;
3921 auto jsVal = info[0];
3922 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
3923 SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
3924 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3925 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImagePosition");
3926 return;
3927 }
3928 if (jsVal->IsNumber()) {
3929 int32_t align = jsVal->ToNumber<int32_t>();
3930 bgImgPosition.SetIsAlign(true);
3931 SetBgImgPositionWithAlign(bgImgPosition, align);
3932 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImagePosition");
3933 } else {
3934 CalcDimension x;
3935 CalcDimension y;
3936 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3937 RefPtr<ResourceObject> resObjX;
3938 RefPtr<ResourceObject> resObjY;
3939 ParseJsDimensionVp(object->GetProperty("x"), x, resObjX);
3940 ParseJsDimensionVp(object->GetProperty("y"), y, resObjY);
3941 SetBackgroundImagePositionUpdateFunc(bgImgPosition, resObjX, "x");
3942 SetBackgroundImagePositionUpdateFunc(bgImgPosition, resObjY, "y");
3943 double valueX = x.Value();
3944 double valueY = y.Value();
3945 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3946 valueX = x.ConvertToPx();
3947 valueY = y.ConvertToPx();
3948 }
3949 DimensionUnit typeX = DimensionUnit::PX;
3950 DimensionUnit typeY = DimensionUnit::PX;
3951 if (x.Unit() == DimensionUnit::PERCENT) {
3952 valueX = x.Value();
3953 typeX = DimensionUnit::PERCENT;
3954 }
3955 if (y.Unit() == DimensionUnit::PERCENT) {
3956 valueY = y.Value();
3957 typeY = DimensionUnit::PERCENT;
3958 }
3959 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
3960 }
3961
3962 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3963 }
3964
JsPadding(const JSCallbackInfo & info)3965 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
3966 {
3967 ParseMarginOrPadding(info, EdgeType::PADDING);
3968 }
3969
JsMargin(const JSCallbackInfo & info)3970 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
3971 {
3972 ParseMarginOrPadding(info, EdgeType::MARGIN);
3973 }
3974
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)3975 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
3976 {
3977 ViewAbstractModel::GetInstance()->ResetResObj("margin");
3978 ViewAbstractModel::GetInstance()->ResetResObj("padding");
3979 ViewAbstractModel::GetInstance()->ResetResObj("safeAreaPadding");
3980 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3981 JSCallbackInfoType::NUMBER };
3982 auto jsVal = info[0];
3983 if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
3984 auto resetDimension = CalcDimension(0.0);
3985 if (type == EdgeType::MARGIN) {
3986 ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
3987 } else if (type == EdgeType::PADDING) {
3988 ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
3989 } else if (type == EdgeType::SAFE_AREA_PADDING) {
3990 ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
3991 }
3992 return;
3993 }
3994
3995 if (jsVal->IsObject()) {
3996 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
3997
3998 CalcDimension length;
3999 if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
4000 ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
4001 return;
4002 }
4003
4004 CommonCalcDimension commonCalcDimension;
4005 auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
4006 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
4007 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
4008 if (type == EdgeType::MARGIN) {
4009 if (useLengthMetrics) {
4010 ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
4011 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
4012 } else {
4013 if (SystemProperties::ConfigChangePerform()) {
4014 ViewAbstractModel::GetInstance()->SetMargins(GetEdgeMargins(commonCalcDimension));
4015 } else {
4016 ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
4017 commonCalcDimension.left, commonCalcDimension.right);
4018 }
4019 }
4020 } else if (type == EdgeType::PADDING) {
4021 if (useLengthMetrics) {
4022 ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
4023 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
4024 } else {
4025 if (SystemProperties::ConfigChangePerform()) {
4026 ViewAbstractModel::GetInstance()->SetPaddings(
4027 GetEdgePaddingsOrSafeAreaPaddings(commonCalcDimension));
4028 } else {
4029 ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top,
4030 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
4031 }
4032 }
4033 } else if (type == EdgeType::SAFE_AREA_PADDING) {
4034 if (useLengthMetrics) {
4035 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
4036 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
4037 } else {
4038 if (SystemProperties::ConfigChangePerform()) {
4039 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(
4040 GetEdgePaddingsOrSafeAreaPaddings(commonCalcDimension));
4041 } else {
4042 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
4043 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
4044 }
4045 }
4046 }
4047 return;
4048 }
4049 }
4050
4051 CalcDimension length;
4052 RefPtr<ResourceObject> lengthResObj;
4053 if (!ParseJsDimensionVp(jsVal, length, lengthResObj)) {
4054 // use default value.
4055 length.Reset();
4056 }
4057 if (type == EdgeType::MARGIN) {
4058 if (SystemProperties::ConfigChangePerform() && lengthResObj) {
4059 ViewAbstractModel::GetInstance()->SetMargin(lengthResObj);
4060 } else {
4061 ViewAbstractModel::GetInstance()->SetMargin(length);
4062 }
4063 } else if (type == EdgeType::PADDING) {
4064 if (SystemProperties::ConfigChangePerform() && lengthResObj) {
4065 ViewAbstractModel::GetInstance()->SetPadding(lengthResObj);
4066 } else {
4067 ViewAbstractModel::GetInstance()->SetPadding(length);
4068 }
4069 }
4070 }
4071
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)4072 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
4073 const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
4074 const std::optional<CalcDimension>& end)
4075 {
4076 NG::PaddingProperty paddings;
4077 if (start.has_value()) {
4078 if (start.value().Unit() == DimensionUnit::CALC) {
4079 paddings.start = NG::CalcLength(start.value().CalcValue());
4080 } else {
4081 paddings.start = NG::CalcLength(start.value());
4082 }
4083 }
4084 if (bottom.has_value()) {
4085 if (bottom.value().Unit() == DimensionUnit::CALC) {
4086 paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
4087 } else {
4088 paddings.bottom = NG::CalcLength(bottom.value());
4089 }
4090 }
4091 if (end.has_value()) {
4092 if (end.value().Unit() == DimensionUnit::CALC) {
4093 paddings.end = NG::CalcLength(end.value().CalcValue());
4094 } else {
4095 paddings.end = NG::CalcLength(end.value());
4096 }
4097 }
4098 if (top.has_value()) {
4099 if (top.value().Unit() == DimensionUnit::CALC) {
4100 paddings.top = NG::CalcLength(top.value().CalcValue());
4101 } else {
4102 paddings.top = NG::CalcLength(top.value());
4103 }
4104 }
4105 return paddings;
4106 }
4107
GetEdgeMargins(const CommonCalcDimension & commonCalcDimension)4108 NG::MarginProperty JSViewAbstract::GetEdgeMargins(const CommonCalcDimension& commonCalcDimension)
4109 {
4110 NG::MarginProperty margins;
4111 if (commonCalcDimension.top.has_value()) {
4112 if (commonCalcDimension.top.value().Unit() == DimensionUnit::CALC) {
4113 margins.top = NG::CalcLength(commonCalcDimension.top.value().CalcValue());
4114 } else {
4115 margins.top = NG::CalcLength(commonCalcDimension.top.value());
4116 }
4117 }
4118 if (commonCalcDimension.bottom.has_value()) {
4119 if (commonCalcDimension.bottom.value().Unit() == DimensionUnit::CALC) {
4120 margins.bottom = NG::CalcLength(commonCalcDimension.bottom.value().CalcValue());
4121 } else {
4122 margins.bottom = NG::CalcLength(commonCalcDimension.bottom.value());
4123 }
4124 }
4125 if (commonCalcDimension.left.has_value()) {
4126 if (commonCalcDimension.left.value().Unit() == DimensionUnit::CALC) {
4127 margins.left = NG::CalcLength(commonCalcDimension.left.value().CalcValue());
4128 } else {
4129 margins.left = NG::CalcLength(commonCalcDimension.left.value());
4130 }
4131 }
4132 if (commonCalcDimension.right.has_value()) {
4133 if (commonCalcDimension.right.value().Unit() == DimensionUnit::CALC) {
4134 margins.right = NG::CalcLength(commonCalcDimension.right.value().CalcValue());
4135 } else {
4136 margins.right = NG::CalcLength(commonCalcDimension.right.value());
4137 }
4138 }
4139 GetEdgeMarginsResObj(margins, commonCalcDimension);
4140 return margins;
4141 }
4142
GetEdgeMarginsResObj(NG::MarginProperty & margins,const CommonCalcDimension & commonCalcDimension)4143 void JSViewAbstract::GetEdgeMarginsResObj(NG::MarginProperty& margins, const CommonCalcDimension& commonCalcDimension)
4144 {
4145 if (!SystemProperties::ConfigChangePerform()) {
4146 return;
4147 }
4148 margins.resMap_.clear();
4149 if (commonCalcDimension.topResObj) {
4150 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4151 CalcDimension result;
4152 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4153 NG::CalcLength resultLength;
4154 resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4155 NG::CalcLength(result);
4156 margins.top = resultLength;
4157 };
4158 margins.AddResource("margin.top", commonCalcDimension.topResObj, std::move(updateFunc));
4159 }
4160 if (commonCalcDimension.bottomResObj) {
4161 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4162 CalcDimension result;
4163 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4164 NG::CalcLength resultLength;
4165 resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4166 NG::CalcLength(result);
4167 margins.bottom = resultLength;
4168 };
4169 margins.AddResource("margin.bottom", commonCalcDimension.bottomResObj, std::move(updateFunc));
4170 }
4171 if (commonCalcDimension.leftResObj) {
4172 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4173 CalcDimension result;
4174 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4175 NG::CalcLength resultLength;
4176 resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4177 NG::CalcLength(result);
4178 margins.left = resultLength;
4179 };
4180 margins.AddResource("margin.left", commonCalcDimension.leftResObj, std::move(updateFunc));
4181 }
4182 if (commonCalcDimension.rightResObj) {
4183 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MarginProperty& margins) {
4184 CalcDimension result;
4185 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4186 NG::CalcLength resultLength;
4187 resultLength = (result.Unit() == DimensionUnit::CALC) ? NG::CalcLength(result.CalcValue()) :
4188 NG::CalcLength(result);
4189 margins.right = resultLength;
4190 };
4191 margins.AddResource("margin.right", commonCalcDimension.rightResObj, std::move(updateFunc));
4192 }
4193 }
4194
GetEdgePaddingsOrSafeAreaPaddings(const CommonCalcDimension & commonCalcDimension)4195 NG::PaddingProperty JSViewAbstract::GetEdgePaddingsOrSafeAreaPaddings(const CommonCalcDimension& commonCalcDimension)
4196 {
4197 NG::PaddingProperty paddings = NG::ConvertToCalcPaddingProperty(
4198 commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
4199 if (!SystemProperties::ConfigChangePerform()) {
4200 return paddings;
4201 }
4202 if (commonCalcDimension.topResObj) {
4203 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4204 CalcDimension result;
4205 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4206 NG::CalcLength resultLength = ConvertCalcLength(result);
4207 paddings.top = resultLength;
4208 };
4209 paddings.AddResource("top", commonCalcDimension.topResObj, std::move(updateFunc));
4210 }
4211 if (commonCalcDimension.bottomResObj) {
4212 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4213 CalcDimension result;
4214 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4215 NG::CalcLength resultLength = ConvertCalcLength(result);
4216 paddings.bottom = resultLength;
4217 };
4218 paddings.AddResource("bottom", commonCalcDimension.bottomResObj, std::move(updateFunc));
4219 }
4220 if (commonCalcDimension.leftResObj) {
4221 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4222 CalcDimension result;
4223 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4224 NG::CalcLength resultLength = ConvertCalcLength(result);
4225 paddings.left = resultLength;
4226 };
4227 paddings.AddResource("left", commonCalcDimension.leftResObj, std::move(updateFunc));
4228 }
4229 if (commonCalcDimension.rightResObj) {
4230 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::PaddingProperty& paddings) {
4231 CalcDimension result;
4232 ResourceParseUtils::ParseResDimensionVpNG(resObj, result);
4233 NG::CalcLength resultLength = ConvertCalcLength(result);
4234 paddings.right = resultLength;
4235 };
4236 paddings.AddResource("right", commonCalcDimension.rightResObj, std::move(updateFunc));
4237 }
4238 return paddings;
4239 }
4240
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)4241 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
4242 std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
4243 {
4244 CalcDimension leftDimen;
4245 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
4246 left = leftDimen;
4247 }
4248 CalcDimension rightDimen;
4249 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
4250 right = rightDimen;
4251 }
4252 CalcDimension topDimen;
4253 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
4254 top = topDimen;
4255 }
4256 CalcDimension bottomDimen;
4257 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
4258 bottom = bottomDimen;
4259 }
4260 }
4261
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,CommonCalcDimension & commonCalcDimension)4262 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, CommonCalcDimension& commonCalcDimension)
4263 {
4264 CalcDimension leftDimen;
4265 RefPtr<ResourceObject> leftResObj;
4266 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen, leftResObj)) {
4267 commonCalcDimension.left = leftDimen;
4268 }
4269 CalcDimension rightDimen;
4270 RefPtr<ResourceObject> rightResObj;
4271 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen, rightResObj)) {
4272 commonCalcDimension.right = rightDimen;
4273 }
4274 CalcDimension topDimen;
4275 RefPtr<ResourceObject> topResObj;
4276 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen, topResObj)) {
4277 commonCalcDimension.top = topDimen;
4278 }
4279 CalcDimension bottomDimen;
4280 RefPtr<ResourceObject> bottomResObj;
4281 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen, bottomResObj)) {
4282 commonCalcDimension.bottom = bottomDimen;
4283 }
4284 if (!SystemProperties::ConfigChangePerform()) {
4285 return;
4286 }
4287 if (leftResObj) {
4288 commonCalcDimension.leftResObj = leftResObj;
4289 }
4290 if (rightResObj) {
4291 commonCalcDimension.rightResObj = rightResObj;
4292 }
4293 if (topResObj) {
4294 commonCalcDimension.topResObj = topResObj;
4295 }
4296 if (bottomResObj) {
4297 commonCalcDimension.bottomResObj = bottomResObj;
4298 }
4299 }
4300
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4301 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
4302 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4303 {
4304 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
4305 if (jsStart->IsObject()) {
4306 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
4307 CalcDimension calcDimension;
4308 if (ParseJsLengthMetrics(startObj, calcDimension)) {
4309 localizedCalcDimension.start = calcDimension;
4310 }
4311 }
4312 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
4313 if (jsEnd->IsObject()) {
4314 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
4315 CalcDimension calcDimension;
4316 if (ParseJsLengthMetrics(endObj, calcDimension)) {
4317 localizedCalcDimension.end = calcDimension;
4318 }
4319 }
4320 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
4321 if (jsTop->IsObject()) {
4322 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
4323 CalcDimension calcDimension;
4324 if (ParseJsLengthMetrics(topObj, calcDimension)) {
4325 localizedCalcDimension.top = calcDimension;
4326 }
4327 }
4328 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
4329 if (jsBottom->IsObject()) {
4330 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
4331 CalcDimension calcDimension;
4332 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
4333 localizedCalcDimension.bottom = calcDimension;
4334 }
4335 }
4336 }
4337
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)4338 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
4339 const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
4340 {
4341 if (CheckLengthMetrics(object)) {
4342 LocalizedCalcDimension localizedCalcDimension;
4343 ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
4344 commonCalcDimension.top = localizedCalcDimension.top;
4345 commonCalcDimension.bottom = localizedCalcDimension.bottom;
4346 commonCalcDimension.left = localizedCalcDimension.start;
4347 commonCalcDimension.right = localizedCalcDimension.end;
4348 return true;
4349 }
4350 if (SystemProperties::ConfigChangePerform()) {
4351 ParseMarginOrPaddingCorner(object, commonCalcDimension);
4352 } else {
4353 ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
4354 commonCalcDimension.right);
4355 }
4356 return false;
4357 }
4358
JsOutline(const JSCallbackInfo & info)4359 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
4360 {
4361 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidthRes");
4362 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColorRes");
4363 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadiusRes");
4364 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidth");
4365 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColor");
4366 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadius");
4367 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4368 auto jsVal = info[0];
4369 if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
4370 CalcDimension borderWidth;
4371 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4372 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
4373 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
4374 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
4375 return;
4376 }
4377 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4378 auto valueOuterWidth = object->GetProperty("width");
4379 if (!valueOuterWidth->IsUndefined()) {
4380 ParseOuterBorderWidth(valueOuterWidth);
4381 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4382 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
4383 }
4384
4385 // use default value when undefined.
4386 ParseOuterBorderColor(object->GetProperty("color"));
4387
4388 auto valueOuterRadius = object->GetProperty("radius");
4389 if (!valueOuterRadius->IsUndefined()) {
4390 ParseOuterBorderRadius(valueOuterRadius);
4391 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4392 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
4393 }
4394 // use default value when undefined.
4395 ParseOuterBorderStyle(object->GetProperty("style"));
4396 info.ReturnSelf();
4397 }
4398
JsOutlineWidth(const JSCallbackInfo & info)4399 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
4400 {
4401 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidth");
4402 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderWidthRes");
4403 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4404 JSCallbackInfoType::OBJECT };
4405 auto jsVal = info[0];
4406 if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
4407 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
4408 return;
4409 }
4410 ParseOuterBorderWidth(jsVal);
4411 }
4412
JsOutlineColor(const JSCallbackInfo & info)4413 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
4414 {
4415 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColorRes");
4416 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderColor");
4417 ParseOuterBorderColor(info[0]);
4418 }
4419
JsOutlineRadius(const JSCallbackInfo & info)4420 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
4421 {
4422 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadius");
4423 ViewAbstractModel::GetInstance()->RemoveResObj("outerBorderRadiusRes");
4424 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4425 JSCallbackInfoType::OBJECT };
4426 auto jsVal = info[0];
4427 if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
4428 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
4429 return;
4430 }
4431 ParseOuterBorderRadius(jsVal);
4432 }
4433
JsOutlineStyle(const JSCallbackInfo & info)4434 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
4435 {
4436 ParseOuterBorderStyle(info[0]);
4437 }
4438
JsBorder(const JSCallbackInfo & info)4439 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
4440 {
4441 ViewAbstractModel::GetInstance()->ResetResObj("borderWidth");
4442 ViewAbstractModel::GetInstance()->ResetResObj("borderColor");
4443 ViewAbstractModel::GetInstance()->ResetResObj("borderRadius");
4444 ViewAbstractModel::GetInstance()->ResetResObj("border.dashGap");
4445 ViewAbstractModel::GetInstance()->ResetResObj("border.dashWidth");
4446 if (!info[0]->IsObject()) {
4447 CalcDimension borderWidth;
4448 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4449 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4450 ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
4451 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4452 ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
4453 ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
4454 return;
4455 }
4456 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
4457
4458 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4459 if (!valueWidth->IsUndefined()) {
4460 ParseBorderWidth(valueWidth);
4461 }
4462
4463 // use default value when undefined.
4464 ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
4465
4466 auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
4467 if (!valueRadius->IsUndefined()) {
4468 ParseBorderRadius(valueRadius);
4469 }
4470 // use default value when undefined.
4471 ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
4472
4473 auto dashGap = object->GetProperty("dashGap");
4474 if (!dashGap->IsUndefined()) {
4475 ParseDashGap(dashGap);
4476 }
4477 auto dashWidth = object->GetProperty("dashWidth");
4478 if (!dashWidth->IsUndefined()) {
4479 ParseDashWidth(dashWidth);
4480 }
4481
4482 info.ReturnSelf();
4483 }
4484
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)4485 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
4486 {
4487 if (!args->IsObject()) {
4488 return false;
4489 }
4490 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4491 if (obj->IsUndefined()) {
4492 return true;
4493 }
4494 // filter dynamic $r raw input
4495 if (obj->HasProperty("id")) {
4496 return false;
4497 }
4498 if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
4499 (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
4500 (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
4501 (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
4502 (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
4503 (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
4504 return true;
4505 }
4506
4507 return false;
4508 }
4509
JsBorderWidth(const JSCallbackInfo & info)4510 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
4511 {
4512 ViewAbstractModel::GetInstance()->ResetResObj("borderWidth");
4513 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4514 JSCallbackInfoType::OBJECT };
4515 auto jsVal = info[0];
4516 if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
4517 CalcDimension value = {};
4518 ViewAbstractModel::GetInstance()->SetBorderWidth(value);
4519 return;
4520 }
4521
4522 ParseBorderWidth(jsVal);
4523 }
4524
ParseBorderWidth(const JSRef<JSVal> & args)4525 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
4526 {
4527 CalcDimension borderWidth;
4528 RefPtr<ResourceObject> borderWidthResObj;
4529 if (ParseJsDimensionVp(args, borderWidth, borderWidthResObj)) {
4530 if (borderWidth.IsNegative()) {
4531 borderWidth.Reset();
4532 }
4533 if (borderWidth.Unit() == DimensionUnit::PERCENT) {
4534 borderWidth.Reset();
4535 }
4536 if (SystemProperties::ConfigChangePerform() && borderWidthResObj) {
4537 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidthResObj);
4538 } else {
4539 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4540 }
4541 } else if (args->IsObject()) {
4542 if (IsBorderWidthObjUndefined(args)) {
4543 CalcDimension value = {};
4544 ViewAbstractModel::GetInstance()->SetBorderWidth(value);
4545 return;
4546 }
4547 CommonCalcDimension commonCalcDimension;
4548 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4549 if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
4550 ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
4551 commonCalcDimension.top, commonCalcDimension.bottom, true);
4552 return;
4553 }
4554 if (SystemProperties::ConfigChangePerform()) {
4555 NG::BorderWidthProperty borderWidth;
4556 ParseEdgeWidthsResObj(obj, borderWidth, true);
4557 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4558 } else {
4559 ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left,
4560 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4561 }
4562 } else {
4563 return;
4564 }
4565 }
4566
ParseDashGap(const JSRef<JSVal> & args)4567 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
4568 {
4569 CalcDimension dashGap;
4570 if (ParseLengthMetricsToDimension(args, dashGap)) {
4571 if (dashGap.Unit() == DimensionUnit::PERCENT) {
4572 dashGap.Reset();
4573 }
4574 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4575 } else if (args->IsObject()) {
4576 CommonCalcDimension commonCalcDimension;
4577 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4578 if (ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension)) {
4579 ViewAbstractModel::GetInstance()->SetDashGap(commonCalcDimension.left,
4580 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4581 return;
4582 }
4583 if (SystemProperties::ConfigChangePerform()) {
4584 NG::BorderWidthProperty dashGap;
4585 ParseEdgeWidthsForDashParamsResObj(obj, dashGap, static_cast<CalcDimension>(-1));
4586 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4587 } else {
4588 ViewAbstractModel::GetInstance()->SetDashGap(commonCalcDimension.left,
4589 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4590 }
4591 } else {
4592 dashGap.Reset();
4593 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4594 }
4595 }
4596
ParseDashWidth(const JSRef<JSVal> & args)4597 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
4598 {
4599 CalcDimension dashWidth;
4600 if (ParseLengthMetricsToDimension(args, dashWidth)) {
4601 if (dashWidth.Unit() == DimensionUnit::PERCENT) {
4602 dashWidth.Reset();
4603 }
4604 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4605 } else if (args->IsObject()) {
4606 CommonCalcDimension commonCalcDimension;
4607 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4608 if (ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension)) {
4609 ViewAbstractModel::GetInstance()->SetDashWidth(commonCalcDimension.left,
4610 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4611 return;
4612 }
4613 if (SystemProperties::ConfigChangePerform()) {
4614 NG::BorderWidthProperty dashWidth;
4615 ParseEdgeWidthsForDashParamsResObj(obj, dashWidth, static_cast<CalcDimension>(-1));
4616 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4617 } else {
4618 ViewAbstractModel::GetInstance()->SetDashWidth(commonCalcDimension.left,
4619 commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4620 }
4621 } else {
4622 dashWidth.Reset();
4623 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4624 }
4625 }
4626
ParseEdgeOutlineWidthLeft(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4627 void JSViewAbstract::ParseEdgeOutlineWidthLeft(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4628 {
4629 if (object->IsUndefined()) {
4630 return;
4631 }
4632 RefPtr<ResourceObject> resObj;
4633 CalcDimension calcDim;
4634 bool ret = ParseJsDimensionVp(object->GetProperty("left"), calcDim, resObj);
4635 if (ret && calcDim.IsNonNegative()) {
4636 if (calcDim.Unit() == DimensionUnit::PERCENT) {
4637 calcDim.Reset();
4638 }
4639 borderWidth.leftDimen = calcDim;
4640 }
4641 if (resObj) {
4642 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4643 CalcDimension dimension;
4644 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4645 borderWidth.leftDimen = dimension;
4646 };
4647 borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.left", resObj, std::move(updateFunc));
4648 }
4649 }
4650
ParseEdgeOutlineWidthRight(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4651 void JSViewAbstract::ParseEdgeOutlineWidthRight(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4652 {
4653 if (object->IsUndefined()) {
4654 return;
4655 }
4656 RefPtr<ResourceObject> resObj;
4657 CalcDimension calcDim;
4658 bool ret = ParseJsDimensionVp(object->GetProperty("right"), calcDim, resObj);
4659 if (ret && calcDim.IsNonNegative()) {
4660 if (calcDim.Unit() == DimensionUnit::PERCENT) {
4661 calcDim.Reset();
4662 }
4663 borderWidth.rightDimen = calcDim;
4664 }
4665 if (resObj) {
4666 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4667 CalcDimension dimension;
4668 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4669 borderWidth.rightDimen = dimension;
4670 };
4671 borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.right", resObj, std::move(updateFunc));
4672 }
4673 }
4674
ParseEdgeOutlineWidthTop(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4675 void JSViewAbstract::ParseEdgeOutlineWidthTop(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4676 {
4677 if (object->IsUndefined()) {
4678 return;
4679 }
4680 RefPtr<ResourceObject> resObj;
4681 CalcDimension calcDim;
4682 bool ret = ParseJsDimensionVp(object->GetProperty("top"), calcDim, resObj);
4683 if (ret && calcDim.IsNonNegative()) {
4684 if (calcDim.Unit() == DimensionUnit::PERCENT) {
4685 calcDim.Reset();
4686 }
4687 borderWidth.topDimen = calcDim;
4688 }
4689 if (resObj) {
4690 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4691 CalcDimension dimension;
4692 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4693 borderWidth.topDimen = dimension;
4694 };
4695 borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.top", resObj, std::move(updateFunc));
4696 }
4697 }
4698
ParseEdgeOutlineWidthBottom(const JSRef<JSObject> & object,NG::BorderWidthProperty & borderWidth)4699 void JSViewAbstract::ParseEdgeOutlineWidthBottom(const JSRef<JSObject>& object, NG::BorderWidthProperty& borderWidth)
4700 {
4701 if (object->IsUndefined()) {
4702 return;
4703 }
4704 RefPtr<ResourceObject> resObj;
4705 CalcDimension calcDim;
4706 bool ret = ParseJsDimensionVp(object->GetProperty("bottom"), calcDim, resObj);
4707 if (ret && calcDim.IsNonNegative()) {
4708 if (calcDim.Unit() == DimensionUnit::PERCENT) {
4709 calcDim.Reset();
4710 }
4711 borderWidth.bottomDimen = calcDim;
4712 }
4713 if (resObj) {
4714 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& borderWidth) {
4715 CalcDimension dimension;
4716 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
4717 borderWidth.bottomDimen = dimension;
4718 };
4719 borderWidth.AddResource("outLineWidth.EdgeOutlineWidths.bottom", resObj, std::move(updateFunc));
4720 }
4721 }
4722
ParseOuterBorderWidthNew(const JSRef<JSVal> & args)4723 void JSViewAbstract::ParseOuterBorderWidthNew(const JSRef<JSVal>& args)
4724 {
4725 CalcDimension borderWidth;
4726 RefPtr<ResourceObject> borderResObj;
4727 bool ret = ParseJsDimensionVp(args, borderWidth, borderResObj);
4728 if (borderResObj) {
4729 // Dimension
4730 ViewAbstractModel::GetInstance()->CreateWithOuterBorderWidthResourceObj(borderResObj);
4731 } else if (ret) {
4732 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4733 borderWidth.Reset();
4734 }
4735 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4736 } else if (args->IsObject()) {
4737 // obj
4738 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4739 NG::BorderWidthProperty borderWidthProperty;
4740 borderWidthProperty.multiValued = true;
4741 borderWidthProperty.resMap_.clear();
4742 ParseEdgeOutlineWidthLeft(object, borderWidthProperty);
4743 ParseEdgeOutlineWidthRight(object, borderWidthProperty);
4744 ParseEdgeOutlineWidthTop(object, borderWidthProperty);
4745 ParseEdgeOutlineWidthBottom(object, borderWidthProperty);
4746 ViewAbstractModel::GetInstance()->SetOuterBorderWidthNew(borderWidthProperty);
4747 } else {
4748 return;
4749 }
4750 }
4751
ParseOuterBorderWidth(const JSRef<JSVal> & args)4752 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
4753 {
4754 if (SystemProperties::ConfigChangePerform()) {
4755 ParseOuterBorderWidthNew(args);
4756 return;
4757 }
4758 CalcDimension borderWidth;
4759 if (ParseJsDimensionVp(args, borderWidth)) {
4760 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4761 borderWidth.Reset();
4762 }
4763 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4764 } else if (args->IsObject()) {
4765 std::optional<CalcDimension> leftDimen;
4766 std::optional<CalcDimension> rightDimen;
4767 std::optional<CalcDimension> topDimen;
4768 std::optional<CalcDimension> bottomDimen;
4769 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4770 CalcDimension left;
4771 if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
4772 if (left.Unit() == DimensionUnit::PERCENT) {
4773 left.Reset();
4774 }
4775 leftDimen = left;
4776 }
4777 CalcDimension right;
4778 if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
4779 if (right.Unit() == DimensionUnit::PERCENT) {
4780 right.Reset();
4781 }
4782 rightDimen = right;
4783 }
4784 CalcDimension top;
4785 if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
4786 if (top.Unit() == DimensionUnit::PERCENT) {
4787 top.Reset();
4788 }
4789 topDimen = top;
4790 }
4791 CalcDimension bottom;
4792 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
4793 if (bottom.Unit() == DimensionUnit::PERCENT) {
4794 bottom.Reset();
4795 }
4796 bottomDimen = bottom;
4797 }
4798 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
4799 } else {
4800 return;
4801 }
4802 }
4803
JsBorderImage(const JSCallbackInfo & info)4804 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
4805 {
4806 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4807 auto jsVal = info[0];
4808 if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
4809 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4810 uint8_t imageBorderBitsets = 0;
4811 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4812 return;
4813 }
4814 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4815 CHECK_NULL_VOID(!object->IsEmpty());
4816
4817 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4818 uint8_t imageBorderBitsets = 0;
4819
4820 auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
4821 CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
4822 std::string srcResult;
4823 std::string bundleName;
4824 std::string moduleName;
4825 GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
4826 borderImage->SetBundleName(bundleName);
4827 borderImage->SetModuleName(moduleName);
4828 if (valueSource->IsString() && !valueSource->ToString().empty()) {
4829 borderImage->SetSrc(valueSource->ToString());
4830 imageBorderBitsets |= BorderImage::SOURCE_BIT;
4831 } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
4832 borderImage->SetSrc(srcResult);
4833 imageBorderBitsets |= BorderImage::SOURCE_BIT;
4834 } else if (valueSource->IsObject()) {
4835 ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
4836 }
4837 auto valueOutset = object->GetProperty("outset");
4838 if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
4839 imageBorderBitsets |= BorderImage::OUTSET_BIT;
4840 ParseBorderImageOutset(valueOutset, borderImage);
4841 }
4842 auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
4843 if (!valueRepeat->IsNull()) {
4844 imageBorderBitsets |= BorderImage::REPEAT_BIT;
4845 ParseBorderImageRepeat(valueRepeat, borderImage);
4846 }
4847 auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
4848 if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
4849 imageBorderBitsets |= BorderImage::SLICE_BIT;
4850 ParseBorderImageSlice(valueSlice, borderImage);
4851 }
4852 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4853 if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
4854 imageBorderBitsets |= BorderImage::WIDTH_BIT;
4855 ParseBorderImageWidth(valueWidth, borderImage);
4856 }
4857 auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
4858 if (needFill->IsBoolean()) {
4859 borderImage->SetNeedFillCenter(needFill->ToBoolean());
4860 }
4861 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4862 info.ReturnSelf();
4863 }
4864
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4865 bool JSViewAbstract::ParseBorderImageDimension(
4866 const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
4867 {
4868 if (!args->IsObject()) {
4869 return false;
4870 }
4871 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4872 if (CheckLengthMetrics(object)) {
4873 LocalizedCalcDimension localizedCalcDimension;
4874 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4875 borderImageDimension.topDimension = localizedCalcDimension.top;
4876 borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
4877 borderImageDimension.startDimension = localizedCalcDimension.start;
4878 borderImageDimension.endDimension = localizedCalcDimension.end;
4879 return true;
4880 }
4881 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4882 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4883 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4884 for (uint32_t i = 0; i < keys.size(); i++) {
4885 CalcDimension currentDimension;
4886 auto dimensionValue = object->GetProperty(keys.at(i));
4887 if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
4888 auto direction = static_cast<BorderImageDirection>(i);
4889 switch (direction) {
4890 case BorderImageDirection::LEFT:
4891 borderImageDimension.leftDimension = currentDimension;
4892 break;
4893 case BorderImageDirection::RIGHT:
4894 borderImageDimension.rightDimension = currentDimension;
4895 break;
4896 case BorderImageDirection::TOP:
4897 borderImageDimension.topDimension = currentDimension;
4898 break;
4899 case BorderImageDirection::BOTTOM:
4900 borderImageDimension.bottomDimension = currentDimension;
4901 break;
4902 default:
4903 break;
4904 }
4905 }
4906 }
4907 return false;
4908 }
4909
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4910 void JSViewAbstract::ParseBorderImageLengthMetrics(
4911 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4912 {
4913 for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
4914 auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
4915 if (!jsVal->IsObject()) {
4916 continue;
4917 }
4918 JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
4919 CalcDimension calcDimension;
4920 if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
4921 auto direction = static_cast<BorderImageDirection>(i);
4922 switch (direction) {
4923 case BorderImageDirection::LEFT:
4924 localizedCalcDimension.start = calcDimension;
4925 break;
4926 case BorderImageDirection::RIGHT:
4927 localizedCalcDimension.end = calcDimension;
4928 break;
4929 case BorderImageDirection::TOP:
4930 localizedCalcDimension.top = calcDimension;
4931 break;
4932 case BorderImageDirection::BOTTOM:
4933 localizedCalcDimension.bottom = calcDimension;
4934 break;
4935 default:
4936 break;
4937 }
4938 }
4939 }
4940 }
4941
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4942 bool JSViewAbstract::CheckJSCallbackInfo(
4943 const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
4944 {
4945 bool typeVerified = false;
4946 std::string unrecognizedType;
4947 for (const auto& infoType : infoTypes) {
4948 switch (infoType) {
4949 case JSCallbackInfoType::STRING:
4950 if (tmpInfo->IsString()) {
4951 typeVerified = true;
4952 } else {
4953 unrecognizedType += "string|";
4954 }
4955 break;
4956 case JSCallbackInfoType::NUMBER:
4957 if (tmpInfo->IsNumber()) {
4958 typeVerified = true;
4959 } else {
4960 unrecognizedType += "number|";
4961 }
4962 break;
4963 case JSCallbackInfoType::OBJECT:
4964 if (tmpInfo->IsObject()) {
4965 typeVerified = true;
4966 } else {
4967 unrecognizedType += "object|";
4968 }
4969 break;
4970 case JSCallbackInfoType::FUNCTION:
4971 if (tmpInfo->IsFunction()) {
4972 typeVerified = true;
4973 } else {
4974 unrecognizedType += "Function|";
4975 }
4976 break;
4977 default:
4978 break;
4979 }
4980 }
4981 if (!typeVerified) {
4982 LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
4983 unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
4984 }
4985 return typeVerified || infoTypes.size() == 0;
4986 }
4987
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4988 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
4989 {
4990 switch (direction) {
4991 case NG::GradientDirection::LEFT:
4992 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4993 break;
4994 case NG::GradientDirection::RIGHT:
4995 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4996 break;
4997 case NG::GradientDirection::TOP:
4998 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4999 break;
5000 case NG::GradientDirection::BOTTOM:
5001 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5002 break;
5003 case NG::GradientDirection::LEFT_TOP:
5004 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5005 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5006 break;
5007 case NG::GradientDirection::LEFT_BOTTOM:
5008 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5009 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5010 break;
5011 case NG::GradientDirection::RIGHT_TOP:
5012 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5013 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5014 break;
5015 case NG::GradientDirection::RIGHT_BOTTOM:
5016 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5017 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5018 break;
5019 case NG::GradientDirection::NONE:
5020 case NG::GradientDirection::START_TO_END:
5021 case NG::GradientDirection::END_TO_START:
5022 default:
5023 break;
5024 }
5025 }
5026
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)5027 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
5028 {
5029 if (!args->IsObject()) {
5030 return;
5031 }
5032 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
5033 NG::Gradient lineGradient;
5034 lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
5035 // angle
5036 std::optional<float> degree;
5037 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5038 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
5039 } else {
5040 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
5041 }
5042 if (degree) {
5043 lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
5044 degree.reset();
5045 }
5046 // direction
5047 auto direction = static_cast<NG::GradientDirection>(
5048 jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
5049 static_cast<int32_t>(NG::GradientDirection::NONE)));
5050 UpdateGradientWithDirection(lineGradient, direction);
5051 auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
5052 lineGradient.SetRepeat(repeating);
5053 NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
5054 ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
5055 bitset |= BorderImage::GRADIENT_BIT;
5056 }
5057
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5058 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5059 {
5060 auto repeatString = args->ToString();
5061 if (repeatString == "Repeat") {
5062 borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
5063 } else if (repeatString == "Round") {
5064 borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
5065 } else if (repeatString == "Space") {
5066 borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
5067 } else {
5068 borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
5069 }
5070 }
5071
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5072 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5073 {
5074 CalcDimension outsetDimension;
5075 if (ParseJsDimensionVp(args, outsetDimension)) {
5076 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
5077 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
5078 borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
5079 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
5080 return;
5081 }
5082 BorderImage::BorderImageOption option;
5083 ParseBorderImageDimension(args, option);
5084 if (option.startDimension.has_value()) {
5085 borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
5086 }
5087 if (option.endDimension.has_value()) {
5088 borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
5089 }
5090 if (option.leftDimension.has_value()) {
5091 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
5092 }
5093 if (option.rightDimension.has_value()) {
5094 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
5095 }
5096 if (option.topDimension.has_value()) {
5097 borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
5098 }
5099 if (option.bottomDimension.has_value()) {
5100 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
5101 }
5102 }
5103
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5104 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5105 {
5106 CalcDimension sliceDimension;
5107 if (ParseJsDimensionVp(args, sliceDimension)) {
5108 borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
5109 borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
5110 borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
5111 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
5112 return;
5113 }
5114 if (!args->IsObject()) {
5115 return;
5116 }
5117 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5118 if (CheckLengthMetrics(object)) {
5119 LocalizedCalcDimension localizedCalcDimension;
5120 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
5121 if (localizedCalcDimension.top.has_value()) {
5122 borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
5123 }
5124 if (localizedCalcDimension.bottom.has_value()) {
5125 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
5126 }
5127 if (localizedCalcDimension.start.has_value()) {
5128 borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
5129 }
5130 if (localizedCalcDimension.end.has_value()) {
5131 borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
5132 }
5133 return;
5134 }
5135 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
5136 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
5137 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
5138 for (uint32_t i = 0; i < keys.size(); i++) {
5139 auto dimensionValue = object->GetProperty(keys.at(i));
5140 if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
5141 borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
5142 }
5143 }
5144 }
5145
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)5146 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
5147 {
5148 CalcDimension widthDimension;
5149 if (ParseJsDimensionVp(args, widthDimension)) {
5150 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
5151 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
5152 borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
5153 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
5154 return;
5155 }
5156
5157 BorderImage::BorderImageOption option;
5158 ParseBorderImageDimension(args, option);
5159 if (option.startDimension.has_value()) {
5160 borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
5161 }
5162 if (option.endDimension.has_value()) {
5163 borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
5164 }
5165 if (option.leftDimension.has_value()) {
5166 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
5167 }
5168 if (option.rightDimension.has_value()) {
5169 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
5170 }
5171 if (option.topDimension.has_value()) {
5172 borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
5173 }
5174 if (option.bottomDimension.has_value()) {
5175 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
5176 }
5177 }
5178
JsBorderColor(const JSCallbackInfo & info)5179 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
5180 {
5181 ViewAbstractModel::GetInstance()->ResetResObj("borderColor");
5182 ParseBorderColor(info[0]);
5183 }
5184
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)5185 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
5186 const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
5187 const std::optional<Color>& colorBottom)
5188 {
5189 NG::BorderColorProperty borderColors;
5190 borderColors.startColor = colorStart;
5191 borderColors.endColor = colorEnd;
5192 borderColors.topColor = colorTop;
5193 borderColors.bottomColor = colorBottom;
5194 borderColors.multiValued = true;
5195 return borderColors;
5196 }
5197
GetLocalizedBorderColor(const CommonColor & commonColor)5198 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const CommonColor& commonColor)
5199 {
5200 NG::BorderColorProperty borderColors;
5201 borderColors.startColor = commonColor.left;
5202 borderColors.endColor = commonColor.right;
5203 borderColors.topColor = commonColor.top;
5204 borderColors.bottomColor = commonColor.bottom;
5205 if (!SystemProperties::ConfigChangePerform()) {
5206 return borderColors;
5207 }
5208 if (commonColor.leftResObj) {
5209 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5210 Color result;
5211 ResourceParseUtils::ParseResColor(resObj, result);
5212 borderColors.startColor = result;
5213 };
5214 borderColors.AddResource("borderColor.start", commonColor.leftResObj, std::move(updateFunc));
5215 }
5216 if (commonColor.rightResObj) {
5217 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5218 Color result;
5219 ResourceParseUtils::ParseResColor(resObj, result);
5220 borderColors.endColor = result;
5221 };
5222 borderColors.AddResource("borderColor.end", commonColor.rightResObj, std::move(updateFunc));
5223 }
5224 if (commonColor.topResObj) {
5225 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5226 Color result;
5227 ResourceParseUtils::ParseResColor(resObj, result);
5228 borderColors.topColor = result;
5229 };
5230 borderColors.AddResource("borderColor.top", commonColor.topResObj, std::move(updateFunc));
5231 }
5232 if (commonColor.bottomResObj) {
5233 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5234 Color result;
5235 ResourceParseUtils::ParseResColor(resObj, result);
5236 borderColors.bottomColor = result;
5237 };
5238 borderColors.AddResource("borderColor.bottom", commonColor.bottomResObj, std::move(updateFunc));
5239 }
5240 borderColors.multiValued = true;
5241 return borderColors;
5242 }
5243
GetBorderColor(const CommonColor & commonColor)5244 NG::BorderColorProperty JSViewAbstract::GetBorderColor(const CommonColor& commonColor)
5245 {
5246 NG::BorderColorProperty borderColors;
5247 borderColors.leftColor = commonColor.left;
5248 borderColors.rightColor = commonColor.right;
5249 borderColors.topColor = commonColor.top;
5250 borderColors.bottomColor = commonColor.bottom;
5251 if (!SystemProperties::ConfigChangePerform()) {
5252 return borderColors;
5253 }
5254 if (commonColor.leftResObj) {
5255 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5256 Color result;
5257 ResourceParseUtils::ParseResColor(resObj, result);
5258 borderColors.leftColor = result;
5259 };
5260 borderColors.AddResource("borderColor.left", commonColor.leftResObj, std::move(updateFunc));
5261 }
5262 if (commonColor.rightResObj) {
5263 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5264 Color result;
5265 ResourceParseUtils::ParseResColor(resObj, result);
5266 borderColors.rightColor = result;
5267 };
5268 borderColors.AddResource("borderColor.right", commonColor.rightResObj, std::move(updateFunc));
5269 }
5270 if (commonColor.topResObj) {
5271 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5272 Color result;
5273 ResourceParseUtils::ParseResColor(resObj, result);
5274 borderColors.topColor = result;
5275 };
5276 borderColors.AddResource("borderColor.top", commonColor.topResObj, std::move(updateFunc));
5277 }
5278 if (commonColor.bottomResObj) {
5279 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderColorProperty& borderColors) {
5280 Color result;
5281 ResourceParseUtils::ParseResColor(resObj, result);
5282 borderColors.bottomColor = result;
5283 };
5284 borderColors.AddResource("borderColor.bottom", commonColor.bottomResObj, std::move(updateFunc));
5285 }
5286 borderColors.multiValued = true;
5287 return borderColors;
5288 }
5289
ParseBorderColor(const JSRef<JSVal> & args)5290 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
5291 {
5292 Color borderColor;
5293 RefPtr<ResourceObject> borderColorResObj;
5294 if (ParseJsColor(args, borderColor, borderColorResObj)) {
5295 if (SystemProperties::ConfigChangePerform() && borderColorResObj) {
5296 ViewAbstractModel::GetInstance()->SetBorderColor(borderColorResObj);
5297 } else {
5298 ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
5299 }
5300 } else if (args->IsObject()) {
5301 CommonColor commonColor;
5302 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5303 if (ParseCommonEdgeColors(object, commonColor)) {
5304 ViewAbstractModel::GetInstance()->SetBorderColor(GetLocalizedBorderColor(commonColor));
5305 return;
5306 }
5307 ViewAbstractModel::GetInstance()->SetBorderColor(GetBorderColor(commonColor));
5308 } else {
5309 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
5310 }
5311 }
5312
ParseOuterBorderColor(const JSRef<JSVal> & args)5313 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
5314 {
5315 Color borderColor;
5316 if (!SystemProperties::ConfigChangePerform()) {
5317 if (ParseJsColor(args, borderColor)) {
5318 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
5319 } else if (args->IsObject()) {
5320 CommonColor commonColor;
5321 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5322 if (ParseCommonEdgeColors(object, commonColor)) {
5323 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
5324 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
5325 return;
5326 }
5327 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
5328 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
5329 } else {
5330 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
5331 }
5332 } else {
5333 RefPtr<ResourceObject> borderResObj;
5334 bool ret = ParseJsColor(args, borderColor, borderResObj);
5335 if (borderResObj) {
5336 ViewAbstractModel::GetInstance()->CreateWithOuterBorderColorResourceObj(borderResObj);
5337 } else if (ret) {
5338 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
5339 } else if (args->IsObject()) {
5340 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5341 NG::BorderColorProperty borderColors;
5342 borderColors.resMap_.clear();
5343 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
5344 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
5345 ParseLocalizedEdgeColorsForOutLineColor(object, borderColors);
5346 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColors);
5347 } else {
5348 ParseEdgeColorsForOutLineColor(object, borderColors);
5349 borderColors.multiValued = true;
5350 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColors);
5351 }
5352 } else {
5353 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
5354 }
5355 }
5356 }
5357
JsBorderRadius(const JSCallbackInfo & info)5358 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
5359 {
5360 ViewAbstractModel::GetInstance()->ResetResObj("borderRadius");
5361 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
5362 JSCallbackInfoType::OBJECT };
5363 auto jsVal = info[0];
5364 if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
5365 ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
5366 return;
5367 }
5368 ParseBorderRadius(jsVal);
5369 }
5370
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)5371 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
5372 const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
5373 const std::optional<Dimension>& radiusBottomEnd)
5374 {
5375 NG::BorderRadiusProperty borderRadius;
5376 borderRadius.radiusTopStart = radiusTopStart;
5377 borderRadius.radiusTopEnd = radiusTopEnd;
5378 borderRadius.radiusBottomStart = radiusBottomStart;
5379 borderRadius.radiusBottomEnd = radiusBottomEnd;
5380 borderRadius.multiValued = true;
5381 return borderRadius;
5382 }
5383
ParseBorderRadius(const JSRef<JSVal> & args)5384 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
5385 {
5386 CalcDimension borderRadius;
5387 RefPtr<ResourceObject> borderRadiusResObj;
5388 if (ParseJsDimensionVp(args, borderRadius, borderRadiusResObj)) {
5389 if (SystemProperties::ConfigChangePerform() && borderRadiusResObj) {
5390 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadiusResObj);
5391 } else {
5392 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
5393 }
5394 } else if (args->IsObject()) {
5395 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5396 CalcDimension topLeft;
5397 CalcDimension topRight;
5398 CalcDimension bottomLeft;
5399 CalcDimension bottomRight;
5400 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
5401 ViewAbstractModel::GetInstance()->SetBorderRadius(
5402 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
5403 return;
5404 }
5405 if (SystemProperties::ConfigChangePerform()) {
5406 NG::BorderRadiusProperty borderRadius;
5407 RefPtr<ResourceObject> topLeftResObj;
5408 RefPtr<ResourceObject> topRightResObj;
5409 RefPtr<ResourceObject> bottomLeftResObj;
5410 RefPtr<ResourceObject> bottomRightResObj;
5411 GetBorderRadiusResObj("topLeft", object, topLeft, topLeftResObj);
5412 GetBorderRadiusResObj("topRight", object, topRight, topRightResObj);
5413 GetBorderRadiusResObj("bottomLeft", object, bottomLeft, bottomLeftResObj);
5414 GetBorderRadiusResObj("bottomRight", object, bottomRight, bottomRightResObj);
5415 borderRadius.radiusTopLeft = topLeft;
5416 borderRadius.radiusTopRight = topRight;
5417 borderRadius.radiusBottomLeft = bottomLeft;
5418 borderRadius.radiusBottomRight = bottomRight;
5419 borderRadius.multiValued = true;
5420 ParseAllBorderRadiusesResObj(
5421 borderRadius, topLeftResObj, topRightResObj, bottomLeftResObj, bottomRightResObj);
5422 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
5423 } else {
5424 ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
5425 }
5426 }
5427 }
5428
ParseOuterBorderRadius(const JSRef<JSVal> & args)5429 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
5430 {
5431 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
5432 return;
5433 }
5434 CalcDimension borderRadius;
5435 if (!SystemProperties::ConfigChangePerform()) {
5436 if (ParseJsDimensionVp(args, borderRadius)) {
5437 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
5438 borderRadius.Reset();
5439 }
5440 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
5441 } else if (args->IsObject()) {
5442 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5443 CalcDimension topLeft;
5444 CalcDimension topRight;
5445 CalcDimension bottomLeft;
5446 CalcDimension bottomRight;
5447 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
5448 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
5449 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
5450 }
5451 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
5452 }
5453 } else {
5454 RefPtr<ResourceObject> resObj;
5455 bool ret = ParseJsDimensionVp(args, borderRadius, resObj);
5456 if (resObj) {
5457 ViewAbstractModel::GetInstance()->CreateWithOuterBorderRadiusResourceObj(resObj);
5458 } else if (ret) {
5459 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
5460 borderRadius.Reset();
5461 }
5462 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
5463 } else if (args->IsObject()) {
5464 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5465 NG::BorderRadiusProperty borderRadius;
5466 if (!ParseAllBorderRadiusesForOutLine(object, borderRadius)) {
5467 borderRadius.multiValued = true;
5468 }
5469 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
5470 }
5471 }
5472 }
5473
GetBorderRadiusTopLeft(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5474 void JSViewAbstract::GetBorderRadiusTopLeft(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5475 {
5476 RefPtr<ResourceObject> topLeftResObj;
5477 CalcDimension dim;
5478 if (ParseJsDimensionVp(jsValue, dim, topLeftResObj)) {
5479 borderRadius.radiusTopLeft = dim;
5480 }
5481 if (topLeftResObj) {
5482 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5483 CalcDimension dimension;
5484 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5485 borderRadius.radiusTopLeft = dimension;
5486 };
5487 borderRadius.AddResource("outLineRadius.radius.radiusTopLft", topLeftResObj, std::move(updateFunc));
5488 }
5489 }
5490
GetBorderRadiusTopRight(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5491 void JSViewAbstract::GetBorderRadiusTopRight(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5492 {
5493 RefPtr<ResourceObject> topRightResObj;
5494 CalcDimension dim;
5495 if (ParseJsDimensionVp(jsValue, dim, topRightResObj)) {
5496 borderRadius.radiusTopRight = dim;
5497 }
5498 if (topRightResObj) {
5499 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5500 CalcDimension dimension;
5501 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5502 borderRadius.radiusTopRight = dimension;
5503 };
5504 borderRadius.AddResource("outLineRadius.radius.radiusTopRight", topRightResObj, std::move(updateFunc));
5505 }
5506 }
5507
GetBorderRadiusBottomLeft(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5508 void JSViewAbstract::GetBorderRadiusBottomLeft(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5509 {
5510 RefPtr<ResourceObject> bottomLeftResObj;
5511 CalcDimension dim;
5512 if (ParseJsDimensionVp(jsValue, dim, bottomLeftResObj)) {
5513 borderRadius.radiusBottomLeft = dim;
5514 }
5515 if (bottomLeftResObj) {
5516 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5517 CalcDimension dimension;
5518 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5519 borderRadius.radiusBottomLeft = dimension;
5520 };
5521 borderRadius.AddResource("outLineRadius.radius.radiusBottomLeft", bottomLeftResObj, std::move(updateFunc));
5522 }
5523 }
5524
GetBorderRadiusBottomRight(const JSRef<JSVal> & jsValue,NG::BorderRadiusProperty & borderRadius)5525 void JSViewAbstract::GetBorderRadiusBottomRight(const JSRef<JSVal>& jsValue, NG::BorderRadiusProperty& borderRadius)
5526 {
5527 RefPtr<ResourceObject> bottomRightResObj;
5528 CalcDimension dim;
5529 if (ParseJsDimensionVp(jsValue, dim, bottomRightResObj)) {
5530 borderRadius.radiusBottomRight = dim;
5531 }
5532 if (bottomRightResObj) {
5533 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadius) {
5534 CalcDimension dimension;
5535 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
5536 borderRadius.radiusBottomRight = dimension;
5537 };
5538 borderRadius.AddResource("outLineRadius.radius.radiusBottomRight", bottomRightResObj, std::move(updateFunc));
5539 }
5540 }
5541
ParseAllBorderRadiusesForOutLine(JSRef<JSObject> & object,NG::BorderRadiusProperty & borderRadius)5542 bool JSViewAbstract::ParseAllBorderRadiusesForOutLine(JSRef<JSObject>& object, NG::BorderRadiusProperty& borderRadius)
5543 {
5544 if (object->IsUndefined()) {
5545 return false;
5546 }
5547 borderRadius.resMap_.clear();
5548 if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
5549 object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
5550 CalcDimension topStart;
5551 CalcDimension topEnd;
5552 CalcDimension bottomStart;
5553 CalcDimension bottomEnd;
5554 GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
5555 GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
5556 GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
5557 GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
5558 borderRadius.radiusTopStart = topStart;
5559 borderRadius.radiusTopEnd = topEnd;
5560 borderRadius.radiusBottomEnd = bottomStart;
5561 borderRadius.radiusBottomStart = bottomEnd;
5562 return true;
5563 }
5564 GetBorderRadiusTopLeft(object->GetProperty("topLeft"), borderRadius);
5565 GetBorderRadiusTopRight(object->GetProperty("topRight"), borderRadius);
5566 GetBorderRadiusBottomLeft(object->GetProperty("bottomLeft"), borderRadius);
5567 GetBorderRadiusBottomRight(object->GetProperty("bottomRight"), borderRadius);
5568 return false;
5569 }
5570
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)5571 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
5572 {
5573 ParseJsDimensionVp(object->GetProperty(key), radius);
5574 }
5575
GetBorderRadiusResObj(const char * key,JSRef<JSObject> & object,CalcDimension & radius,RefPtr<ResourceObject> & resObj)5576 void JSViewAbstract::GetBorderRadiusResObj(
5577 const char* key, JSRef<JSObject>& object, CalcDimension& radius, RefPtr<ResourceObject>& resObj)
5578 {
5579 ParseJsDimensionVp(object->GetProperty(key), radius, resObj);
5580 }
5581
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)5582 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
5583 {
5584 if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
5585 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
5586 ParseJsLengthMetrics(startObj, radius);
5587 }
5588 }
5589
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)5590 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
5591 CalcDimension& bottomLeft, CalcDimension& bottomRight)
5592 {
5593 TextBackgroundStyle textBackgroundStyle;
5594 return ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight, textBackgroundStyle);
5595 }
5596
RegisterTextBackgroundStyleResource(TextBackgroundStyle & textBackgroundStyle,RefPtr<ResourceObject> & resObjTopLeft,RefPtr<ResourceObject> & resObjTopRight,RefPtr<ResourceObject> & resObjBottomLeft,RefPtr<ResourceObject> & resObjBottomRight)5597 void JSViewAbstract::RegisterTextBackgroundStyleResource(TextBackgroundStyle& textBackgroundStyle,
5598 RefPtr<ResourceObject>& resObjTopLeft, RefPtr<ResourceObject>& resObjTopRight,
5599 RefPtr<ResourceObject>& resObjBottomLeft, RefPtr<ResourceObject>& resObjBottomRight)
5600 {
5601 if (!SystemProperties::ConfigChangePerform()) {
5602 return;
5603 }
5604 if (resObjTopLeft) {
5605 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjTopLeft,
5606 TextBackgroundStyle& textBackgroundStyle) {
5607 CalcDimension radius;
5608 ResourceParseUtils::ParseResDimensionVp(resObjTopLeft, radius);
5609 textBackgroundStyle.backgroundRadius->radiusTopLeft = radius;
5610 textBackgroundStyle.backgroundRadius->multiValued = true;
5611 };
5612 textBackgroundStyle.AddResource("textBackgroundStyle.radiusTopLeft", resObjTopLeft,
5613 std::move(updateFunc));
5614 }
5615 if (resObjTopRight) {
5616 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjTopRight,
5617 TextBackgroundStyle& textBackgroundStyle) {
5618 CalcDimension radius;
5619 ResourceParseUtils::ParseResDimensionVp(resObjTopRight, radius);
5620 textBackgroundStyle.backgroundRadius->radiusTopRight = radius;
5621 textBackgroundStyle.backgroundRadius->multiValued = true;
5622 };
5623 textBackgroundStyle.AddResource("textBackgroundStyle.radiusTopRight", resObjTopRight,
5624 std::move(updateFunc));
5625 }
5626 if (resObjBottomLeft) {
5627 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjBottomLeft,
5628 TextBackgroundStyle& textBackgroundStyle) {
5629 CalcDimension radius;
5630 ResourceParseUtils::ParseResDimensionVp(resObjBottomLeft, radius);
5631 textBackgroundStyle.backgroundRadius->radiusBottomLeft = radius;
5632 textBackgroundStyle.backgroundRadius->multiValued = true;
5633 };
5634 textBackgroundStyle.AddResource("textBackgroundStyle.radiusBottomLeft", resObjBottomLeft,
5635 std::move(updateFunc));
5636 }
5637 if (resObjBottomRight) {
5638 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObjBottomRight,
5639 TextBackgroundStyle& textBackgroundStyle) {
5640 CalcDimension radius;
5641 ResourceParseUtils::ParseResDimensionVp(resObjBottomRight, radius);
5642 textBackgroundStyle.backgroundRadius->radiusBottomRight = radius;
5643 textBackgroundStyle.backgroundRadius->multiValued = true;
5644 };
5645 textBackgroundStyle.AddResource("textBackgroundStyle.radiusBottomRight", resObjBottomRight,
5646 std::move(updateFunc));
5647 }
5648 }
5649
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight,TextBackgroundStyle & textBackgroundStyle)5650 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
5651 CalcDimension& bottomLeft, CalcDimension& bottomRight, TextBackgroundStyle& textBackgroundStyle)
5652 {
5653 if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
5654 object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
5655 CalcDimension topStart;
5656 CalcDimension topEnd;
5657 CalcDimension bottomStart;
5658 CalcDimension bottomEnd;
5659 GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
5660 GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
5661 GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
5662 GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
5663 topLeft = topStart;
5664 topRight = topEnd;
5665 bottomLeft = bottomStart;
5666 bottomRight = bottomEnd;
5667 return true;
5668 }
5669 RefPtr<ResourceObject> resObjTopLeft;
5670 RefPtr<ResourceObject> resObjTopRight;
5671 RefPtr<ResourceObject> resObjBottomLeft;
5672 RefPtr<ResourceObject> resObjBottomRight;
5673 GetBorderRadiusResObj("topLeft", object, topLeft, resObjTopLeft);
5674 GetBorderRadiusResObj("topRight", object, topRight, resObjTopRight);
5675 GetBorderRadiusResObj("bottomLeft", object, bottomLeft, resObjBottomLeft);
5676 GetBorderRadiusResObj("bottomRight", object, bottomRight, resObjBottomRight);
5677
5678 RegisterTextBackgroundStyleResource(textBackgroundStyle, resObjTopLeft, resObjTopRight, resObjBottomLeft,
5679 resObjBottomRight);
5680 return false;
5681 }
5682
5683 #define ADDRESOURCE_UPDATE_FUNC(property, resObj, radiusMember, resourceName) \
5684 RefPtr<ResourceObject> resObj; \
5685 ParseJsDimensionVp(object->GetProperty(#property), property, resObj); \
5686 if (resObj) { \
5687 auto&& updateFunc = [](const RefPtr<ResourceObject>& (resObj), NG::BorderRadiusProperty& borderRadiusProperty) { \
5688 CalcDimension property; \
5689 ResourceParseUtils::ParseResDimensionVp(resObj, property); \
5690 if (LessNotEqual((property).Value(), 0.0f)) { \
5691 (property).Reset(); \
5692 } \
5693 borderRadiusProperty.radiusMember = property; \
5694 }; \
5695 borderRadius.AddResource(resourceName, resObj, std::move(updateFunc)); \
5696 }
5697
ParseAllBorderRadiuses(JSRef<JSObject> & object,NG::BorderRadiusProperty & borderRadius)5698 void JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, NG::BorderRadiusProperty& borderRadius)
5699 {
5700 CalcDimension topLeft;
5701 CalcDimension topRight;
5702 CalcDimension bottomLeft;
5703 CalcDimension bottomRight;
5704 bool hasSetBorderRadius = false;
5705 if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
5706 object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
5707 CalcDimension topStart;
5708 CalcDimension topEnd;
5709 CalcDimension bottomStart;
5710 CalcDimension bottomEnd;
5711 GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
5712 GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
5713 GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
5714 GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
5715 topLeft = topStart;
5716 topRight = topEnd;
5717 bottomLeft = bottomStart;
5718 bottomRight = bottomEnd;
5719 hasSetBorderRadius = true;
5720 }
5721 else {
5722 ADDRESOURCE_UPDATE_FUNC(topLeft, topLeftResObj, radiusTopLeft, "borderRadius.topLeft")
5723 ADDRESOURCE_UPDATE_FUNC(topRight, topRightResObj, radiusTopRight, "borderRadius.topRight")
5724 ADDRESOURCE_UPDATE_FUNC(bottomLeft, bottomLeftResObj, radiusBottomLeft, "borderRadius.bottomLeft")
5725 ADDRESOURCE_UPDATE_FUNC(bottomRight, bottomRightResObj, radiusBottomRight, "borderRadius.bottomRight")
5726 }
5727 if (LessNotEqual(topLeft.Value(), 0.0f)) {
5728 topLeft.Reset();
5729 }
5730 if (LessNotEqual(topRight.Value(), 0.0f)) {
5731 topRight.Reset();
5732 }
5733 if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
5734 bottomLeft.Reset();
5735 }
5736 if (LessNotEqual(bottomRight.Value(), 0.0f)) {
5737 bottomRight.Reset();
5738 }
5739 auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
5740 borderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
5741 borderRadius.radiusTopRight = isRtl ? topLeft : topRight;
5742 borderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
5743 borderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
5744 borderRadius.multiValued = true;
5745 }
5746
JsBorderStyle(const JSCallbackInfo & info)5747 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
5748 {
5749 ParseBorderStyle(info[0]);
5750 }
5751 namespace {
ConvertBorderStyle(int32_t value)5752 BorderStyle ConvertBorderStyle(int32_t value)
5753 {
5754 auto style = static_cast<BorderStyle>(value);
5755 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
5756 style = BorderStyle::SOLID;
5757 }
5758 return style;
5759 }
5760
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)5761 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
5762 {
5763 style = static_cast<BorderStyle>(value);
5764 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
5765 return false;
5766 }
5767 return true;
5768 }
5769 } // namespace
5770
ParseBorderStyle(const JSRef<JSVal> & args)5771 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
5772 {
5773 if (args->IsObject()) {
5774 std::optional<BorderStyle> styleLeft;
5775 std::optional<BorderStyle> styleRight;
5776 std::optional<BorderStyle> styleTop;
5777 std::optional<BorderStyle> styleBottom;
5778 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5779 auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
5780 if (leftValue->IsNumber()) {
5781 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
5782 }
5783 auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
5784 if (rightValue->IsNumber()) {
5785 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
5786 }
5787 auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
5788 if (topValue->IsNumber()) {
5789 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
5790 }
5791 auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
5792 if (bottomValue->IsNumber()) {
5793 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
5794 }
5795 ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
5796 return;
5797 }
5798 if (args->IsNumber()) {
5799 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
5800 ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
5801 return;
5802 }
5803 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
5804 }
5805
ParseOuterBorderStyle(const JSRef<JSVal> & args)5806 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
5807 {
5808 if (!args->IsObject() && !args->IsNumber()) {
5809 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
5810 return;
5811 }
5812 if (args->IsObject()) {
5813 std::optional<BorderStyle> styleLeft;
5814 std::optional<BorderStyle> styleRight;
5815 std::optional<BorderStyle> styleTop;
5816 std::optional<BorderStyle> styleBottom;
5817 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
5818 auto leftValue = object->GetProperty("left");
5819 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
5820 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
5821 }
5822 auto rightValue = object->GetProperty("right");
5823 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
5824 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
5825 }
5826 auto topValue = object->GetProperty("top");
5827 if (!topValue->IsUndefined() && topValue->IsNumber()) {
5828 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
5829 }
5830 auto bottomValue = object->GetProperty("bottom");
5831 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
5832 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
5833 }
5834 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
5835 return;
5836 }
5837 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
5838 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
5839 }
5840
JsBlur(const JSCallbackInfo & info)5841 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
5842 {
5843 if (info.Length() == 0) {
5844 return;
5845 }
5846 double blur = 0.0;
5847 if (!ParseJsDouble(info[0], blur)) {
5848 return;
5849 }
5850
5851 BlurOption blurOption;
5852 if (info.Length() > 1 && info[1]->IsObject()) {
5853 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
5854 ParseBlurOption(jsBlurOption, blurOption);
5855 }
5856 SysOptions sysOptions;
5857 sysOptions.disableSystemAdaptation = false;
5858 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
5859 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
5860 ParseSysOptions(jsSysOptions, sysOptions);
5861 }
5862 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
5863 ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption, sysOptions);
5864 info.SetReturnValue(info.This());
5865 }
5866
JsMotionBlur(const JSCallbackInfo & info)5867 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
5868 {
5869 if (!info[0]->IsObject()) {
5870 return;
5871 }
5872 MotionBlurOption option;
5873 double x = 0.0;
5874 double y = 0.0;
5875 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5876 JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
5877 if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
5878 JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
5879 ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
5880 ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
5881 }
5882 double radius = 0.0;
5883 if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
5884 radius = 0.0;
5885 }
5886 if (LessNotEqual(x, 0.0)) {
5887 x = 0.0;
5888 }
5889 if (LessNotEqual(y, 0.0)) {
5890 y = 0.0;
5891 }
5892 option.radius = radius;
5893 option.anchor.x = std::clamp(x, 0.0, 1.0);
5894 option.anchor.y = std::clamp(y, 0.0, 1.0);
5895 ViewAbstractModel::GetInstance()->SetMotionBlur(option);
5896 }
5897
JsColorBlend(const JSCallbackInfo & info)5898 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
5899 {
5900 ViewAbstractModel::GetInstance()->RemoveResObj("viewAbstract.colorBlend");
5901 Color colorBlend;
5902 if (info[0]->IsUndefined()) {
5903 colorBlend = Color::TRANSPARENT;
5904 SetColorBlend(colorBlend);
5905 return;
5906 }
5907 if (!SystemProperties::ConfigChangePerform()) {
5908 if (!ParseJsColor(info[0], colorBlend)) {
5909 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5910 colorBlend = Color::TRANSPARENT;
5911 SetColorBlend(colorBlend);
5912 }
5913 return;
5914 }
5915 SetColorBlend(colorBlend);
5916 info.SetReturnValue(info.This());
5917 } else {
5918 RefPtr<ResourceObject> colorBlendResObj;
5919 if (ParseJsColor(info[0], colorBlend, colorBlendResObj) && !colorBlendResObj) {
5920 SetColorBlend(colorBlend);
5921 info.SetReturnValue(info.This());
5922 return;
5923 }
5924 if (colorBlendResObj) {
5925 ViewAbstractModel::GetInstance()->CreateWithColorBlendResourceObj(colorBlendResObj);
5926 info.SetReturnValue(info.This());
5927 } else {
5928 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5929 colorBlend = Color::TRANSPARENT;
5930 SetColorBlend(colorBlend);
5931 }
5932 }
5933 }
5934 }
5935
JsUseEffect(const JSCallbackInfo & info)5936 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
5937 {
5938 if (info[0]->IsBoolean()) {
5939 auto effectType = EffectType::DEFAULT;
5940 if (info.Length() == 2 && info[1]->IsNumber()) {
5941 effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
5942 if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
5943 effectType = EffectType::DEFAULT;
5944 }
5945 }
5946 ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
5947 }
5948 }
5949
JsUseShadowBatching(const JSCallbackInfo & info)5950 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
5951 {
5952 if (info[0]->IsBoolean()) {
5953 ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
5954 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5955 ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
5956 }
5957 }
5958
JsBackdropBlur(const JSCallbackInfo & info)5959 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
5960 {
5961 if (info.Length() == 0) {
5962 return;
5963 }
5964 double blur = 0.0;
5965 BlurOption blurOption;
5966 if (!ParseJsDouble(info[0], blur)) {
5967 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5968 return;
5969 }
5970 }
5971 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
5972 if (info.Length() > 1 && info[1]->IsObject()) {
5973 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
5974 ParseBlurOption(jsBlurOption, blurOption);
5975 }
5976 SysOptions sysOptions;
5977 sysOptions.disableSystemAdaptation = false;
5978 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
5979 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
5980 ParseSysOptions(jsSysOptions, sysOptions);
5981 }
5982 ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption, sysOptions);
5983 info.SetReturnValue(info.This());
5984 }
5985
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)5986 void JSViewAbstract::GetFractionStops(
5987 std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
5988 {
5989 if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
5990 return;
5991 }
5992 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
5993 float tmpPos = -1.0f;
5994 size_t length = jsArray->Length();
5995 for (size_t i = 0; i < length; i++) {
5996 std::pair<float, float> fractionStop;
5997 JSRef<JSVal> item = jsArray->GetValueAt(i);
5998 if (!item->IsArray()) {
5999 continue;
6000 }
6001 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
6002 if (subArray->Length() < 2) {
6003 continue;
6004 }
6005
6006 double value = 0.0;
6007 if (ParseJsDouble(subArray->GetValueAt(0), value)) {
6008 value = std::clamp(value, 0.0, 1.0);
6009 fractionStop.first = static_cast<float>(value);
6010 }
6011 value = 0.0;
6012 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
6013 value = std::clamp(value, 0.0, 1.0);
6014 fractionStop.second = static_cast<float>(value);
6015 }
6016
6017 if (fractionStop.second <= tmpPos) {
6018 fractionStops.clear();
6019 return;
6020 }
6021 tmpPos = fractionStop.second;
6022 fractionStops.push_back(fractionStop);
6023 }
6024 }
JsLinearGradientBlur(const JSCallbackInfo & info)6025 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
6026 {
6027 if (info.Length() < 2) { // 2 represents the least para num;
6028 return;
6029 }
6030 double blurRadius = 0.0;
6031 ParseJsDouble(info[0], blurRadius);
6032
6033 std::vector<std::pair<float, float>> fractionStops;
6034 auto direction = GradientDirection::BOTTOM;
6035 if (info[1]->IsObject()) {
6036 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
6037 GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
6038 auto directionValue =
6039 jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
6040 if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
6041 directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
6042 directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
6043 }
6044 direction = static_cast<GradientDirection>(directionValue);
6045 }
6046 if (static_cast<int32_t>(fractionStops.size()) <= 1) {
6047 fractionStops.clear();
6048 fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
6049 fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
6050 }
6051 // Parse direction
6052 CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
6053 NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
6054 SetLinearGradientBlur(blurPara);
6055 }
6056
JsBackgroundBrightness(const JSCallbackInfo & info)6057 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
6058 {
6059 double rate = 0.0;
6060 double lightUpDegree = 0.0;
6061 if (info[0]->IsObject()) {
6062 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
6063 ParseJsDouble(jsObj->GetProperty("rate"), rate);
6064 ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
6065 }
6066 SetDynamicLightUp(rate, lightUpDegree);
6067 }
6068
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)6069 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
6070 {
6071 if (info.Length() == 0) {
6072 return;
6073 }
6074 BrightnessOption option;
6075 if (info[0]->IsObject()) {
6076 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
6077 ParseBrightnessOption(jsOption, option);
6078 }
6079 SetBgDynamicBrightness(option);
6080 }
6081
JsForegroundBrightness(const JSCallbackInfo & info)6082 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
6083 {
6084 if (info.Length() == 0) {
6085 return;
6086 }
6087 BrightnessOption option;
6088 if (info[0]->IsObject()) {
6089 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
6090 ParseBrightnessOption(jsOption, option);
6091 }
6092 SetFgDynamicBrightness(option);
6093 }
6094
JsWindowBlur(const JSCallbackInfo & info)6095 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
6096 {
6097 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6098 auto jsVal = info[0];
6099 if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
6100 return;
6101 }
6102
6103 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
6104 double progress = 0.0;
6105 ParseJsDouble(jsObj->GetProperty("percent"), progress);
6106 auto style = jsObj->GetPropertyValue<int32_t>("style",
6107 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
6108
6109 progress = std::clamp(progress, 0.0, 1.0);
6110 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
6111 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
6112
6113 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
6114 info.SetReturnValue(info.This());
6115 }
6116
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)6117 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
6118 std::string& resName, bool isParseType)
6119 {
6120 if (!jsValue->IsString()) {
6121 return false;
6122 }
6123 std::string resPath = jsValue->ToString();
6124 std::smatch results;
6125 std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
6126 if (!std::regex_match(resPath, results, tokenRegex)) {
6127 return false;
6128 }
6129 targetModule = results[1];
6130 if (isParseType && !ConvertResourceType(results[2], resType)) {
6131 return false;
6132 }
6133 resName = resPath;
6134 return true;
6135 }
6136
ConvertResourceType(const std::string & typeName,ResourceType & resType)6137 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
6138 {
6139 static const std::unordered_map<std::string, ResourceType> resTypeMap {
6140 { "color", ResourceType::COLOR },
6141 { "media", ResourceType::MEDIA },
6142 { "float", ResourceType::FLOAT },
6143 { "string", ResourceType::STRING },
6144 { "plural", ResourceType::PLURAL },
6145 { "pattern", ResourceType::PATTERN },
6146 { "boolean", ResourceType::BOOLEAN },
6147 { "integer", ResourceType::INTEGER },
6148 { "strarray", ResourceType::STRARRAY },
6149 { "intarray", ResourceType::INTARRAY },
6150 };
6151 auto it = resTypeMap.find(typeName);
6152 if (it == resTypeMap.end()) {
6153 return false;
6154 }
6155 resType = it->second;
6156 return true;
6157 }
6158
CompleteResourceObject(JSRef<JSObject> & jsObj)6159 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
6160 {
6161 std::string bundleName;
6162 std::string moduleName;
6163 int32_t resId = -1;
6164 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
6165 }
6166
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)6167 void JSViewAbstract::CompleteResourceObjectWithBundleName(
6168 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
6169 {
6170 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
6171 }
6172
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)6173 void JSViewAbstract::CompleteResourceObjectInner(
6174 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
6175 {
6176 // dynamic $r raw input format is
6177 // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
6178 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
6179 ResourceType resType;
6180
6181 std::string targetModule;
6182 std::string resName;
6183 if (resId->IsString()) {
6184 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
6185 int32_t typeNum = -1;
6186 if (type->IsNumber()) {
6187 typeNum = type->ToNumber<int32_t>();
6188 }
6189 if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
6190 return;
6191 }
6192 CompleteResourceObjectFromId(type, jsObj, resType, resName);
6193 } else if (resId->IsNumber()) {
6194 resIdValue = resId->ToNumber<int32_t>();
6195 if (resIdValue == -1) {
6196 CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
6197 }
6198 }
6199
6200 JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
6201 if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
6202 bundleName = GetBundleNameFromContainer();
6203 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
6204 }
6205 if (moduleName == DEFAULT_HAR_MODULE_NAME) {
6206 moduleName = GetModuleNameFromContainer();
6207 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
6208 }
6209 }
6210
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)6211 bool JSViewAbstract::ParseJsDimensionNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6212 DimensionUnit defaultUnit, bool isSupportPercent)
6213 {
6214 RefPtr<ResourceObject> resObj;
6215 return ParseJsDimensionNG(jsValue, result, defaultUnit, resObj, isSupportPercent);
6216 }
6217
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6218 bool JSViewAbstract::ParseJsDimensionNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6219 DimensionUnit defaultUnit, RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6220 {
6221 if (jsValue->IsNumber()) {
6222 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
6223 return true;
6224 }
6225 if (jsValue->IsString()) {
6226 auto value = jsValue->ToString();
6227 if (!isSupportPercent && value.back() == '%') {
6228 return false;
6229 }
6230 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
6231 }
6232 if (jsValue->IsObject()) {
6233 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6234 CompleteResourceObject(jsObj);
6235 JSRef<JSVal> resId = jsObj->GetProperty("id");
6236 if (!resId->IsNumber()) {
6237 return false;
6238 }
6239 auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6240 if (resType == UNKNOWN_RESOURCE_TYPE) {
6241 return false;
6242 }
6243 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6244 GetResourceObjectByBundleAndModule(jsObj);
6245 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6246 if (!resourceWrapper) {
6247 return false;
6248 }
6249 auto resIdNum = resId->ToNumber<int32_t>();
6250 if (resIdNum == -1) {
6251 if (!IsGetResourceByName(jsObj)) {
6252 return false;
6253 }
6254 JSRef<JSVal> args = jsObj->GetProperty("params");
6255 if (!args->IsArray()) {
6256 return false;
6257 }
6258 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6259 auto param = params->GetValueAt(0);
6260 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6261 auto value = resourceWrapper->GetStringByName(param->ToString());
6262 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
6263 }
6264 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6265 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
6266 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
6267 return true;
6268 }
6269 result = resourceWrapper->GetDimensionByName(param->ToString());
6270 return true;
6271 }
6272 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6273 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
6274 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
6275 }
6276 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6277 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
6278 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
6279 return true;
6280 }
6281 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
6282 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
6283 return true;
6284 }
6285 }
6286 return false;
6287 }
6288
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)6289 bool JSViewAbstract::ParseJsLengthNG(
6290 const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
6291 {
6292 RefPtr<ResourceObject> resourceObj;
6293 return ParseJsLengthNG(jsValue, result, defaultUnit, resourceObj, isSupportPercent);
6294 }
6295
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resourceObj,bool isSupportPercent)6296 bool JSViewAbstract::ParseJsLengthNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit,
6297 RefPtr<ResourceObject>& resourceObj, bool isSupportPercent)
6298 {
6299 if (jsValue->IsNumber()) {
6300 if (std::isnan(jsValue->ToNumber<double>())) {
6301 return false;
6302 }
6303 result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
6304 return true;
6305 } else if (jsValue->IsObject()) {
6306 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6307 JSRef<JSVal> value = jsObj->GetProperty("value");
6308 if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
6309 return false;
6310 }
6311 DimensionUnit unit = defaultUnit;
6312 JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
6313 if (jsUnit->IsNumber()) {
6314 if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
6315 return false;
6316 }
6317 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
6318 }
6319 result = NG::CalcLength(value->ToNumber<double>(), unit);
6320 auto jsRes = jsObj->GetProperty("res");
6321 if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
6322 !jsRes->IsNull() && jsRes->IsObject()) {
6323 JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
6324 JSViewAbstract::CompleteResourceObject(resObj);
6325 resourceObj = JSViewAbstract::GetResourceObject(resObj);
6326 }
6327 return true;
6328 }
6329
6330 return false;
6331 }
6332
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)6333 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
6334 {
6335 RefPtr<ResourceObject> resObj;
6336 return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, resObj, isSupportPercent);
6337 }
6338
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6339 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result,
6340 RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6341 {
6342 // 'vp' -> the value varies with pixel density of device.
6343 return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, resObj, isSupportPercent);
6344 }
6345
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)6346 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
6347 {
6348 RefPtr<ResourceObject> resObj;
6349 return ParseJsDimension(jsValue, result, defaultUnit, resObj);
6350 }
6351
ParseJsDimensionByNameInternal(const JSRef<JSObject> & jsObj,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceWrapper> & resourceWrapper,int32_t resType)6352 bool JSViewAbstract::ParseJsDimensionByNameInternal(const JSRef<JSObject>& jsObj, CalcDimension& result,
6353 DimensionUnit defaultUnit, RefPtr<ResourceWrapper>& resourceWrapper, int32_t resType)
6354 {
6355 if (!IsGetResourceByName(jsObj)) {
6356 return false;
6357 }
6358 JSRef<JSVal> args = jsObj->GetProperty("params");
6359 if (!args->IsArray()) {
6360 return false;
6361 }
6362 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6363 auto param = params->GetValueAt(0);
6364 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6365 auto value = resourceWrapper->GetStringByName(param->ToString());
6366 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
6367 return true;
6368 }
6369 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6370 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
6371 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
6372 return true;
6373 }
6374 result = resourceWrapper->GetDimensionByName(param->ToString());
6375 return true;
6376 }
6377
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,RefPtr<ResourceObject> & resObj)6378 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit,
6379 RefPtr<ResourceObject>& resObj)
6380 {
6381 if (jsValue->IsNumber()) {
6382 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
6383 return true;
6384 }
6385 if (jsValue->IsString()) {
6386 result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
6387 return true;
6388 }
6389 if (!jsValue->IsObject()) {
6390 return false;
6391 }
6392 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6393 CompleteResourceObject(jsObj);
6394 JSRef<JSVal> resId = jsObj->GetProperty("id");
6395 if (!resId->IsNumber()) {
6396 return false;
6397 }
6398 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6399 GetResourceObjectByBundleAndModule(jsObj);
6400 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6401 if (!resourceWrapper) {
6402 return false;
6403 }
6404 auto resIdNum = resId->ToNumber<int32_t>();
6405 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6406 if (resType == UNKNOWN_RESOURCE_TYPE) {
6407 return false;
6408 }
6409 if (resIdNum == -1) {
6410 return ParseJsDimensionByNameInternal(jsObj, result, defaultUnit, resourceWrapper, resType);
6411 }
6412 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6413 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
6414 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
6415 return true;
6416 }
6417 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6418 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
6419 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
6420 return true;
6421 }
6422 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
6423 return true;
6424 }
6425
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)6426 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
6427 {
6428 // 'vp' -> the value varies with pixel density of device.
6429 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
6430 }
6431
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6432 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6433 RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6434 {
6435 // 'vp' -> the value varies with pixel density of device.
6436 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, resObj, isSupportPercent);
6437 }
6438
ParseJsLengthMetricsVp(const JSRef<JSObject> & jsObj,CalcDimension & result)6439 bool JSViewAbstract::ParseJsLengthMetricsVp(const JSRef<JSObject>& jsObj, CalcDimension& result)
6440 {
6441 RefPtr<ResourceObject> resourceObj;
6442 return ParseJsLengthMetricsVpWithResObj(jsObj, result, resourceObj);
6443 }
6444
ParseJsLengthMetricsVpWithResObj(const JSRef<JSObject> & jsObj,CalcDimension & result,RefPtr<ResourceObject> & resourceObj)6445 bool JSViewAbstract::ParseJsLengthMetricsVpWithResObj(const JSRef<JSObject>& jsObj, CalcDimension& result,
6446 RefPtr<ResourceObject>& resourceObj)
6447 {
6448 auto value = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
6449 if (!value->IsNumber()) {
6450 return false;
6451 }
6452 auto unit = DimensionUnit::VP;
6453 auto jsUnit = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
6454 if (jsUnit->IsNumber()) {
6455 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
6456 }
6457 CalcDimension dimension(value->ToNumber<double>(), unit);
6458 result = dimension;
6459 auto jsRes = jsObj->GetProperty("res");
6460 if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
6461 !jsRes->IsNull() && jsRes->IsObject()) {
6462 JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
6463 JSViewAbstract::CompleteResourceObject(resObj);
6464 resourceObj = JSViewAbstract::GetResourceObject(resObj);
6465 }
6466 return true;
6467 }
6468
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)6469 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
6470 {
6471 RefPtr<ResourceObject> resObj;
6472 // 'vp' -> the value varies with pixel density of device.
6473 return ParseJsDimension(jsValue, result, DimensionUnit::VP, resObj);
6474 }
6475
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6476 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result,
6477 RefPtr<ResourceObject>& resObj)
6478 {
6479 // 'vp' -> the value varies with pixel density of device.
6480 return ParseJsDimension(jsValue, result, DimensionUnit::VP, resObj);
6481 }
6482
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)6483 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
6484 {
6485 RefPtr<ResourceObject> resObj;
6486 // the 'fp' unit is used for text scenes.
6487 return ParseJsDimension(jsValue, result, DimensionUnit::FP, resObj);
6488 }
6489
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6490 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result,
6491 RefPtr<ResourceObject>& resObj)
6492 {
6493 // the 'fp' unit is used for text scenes.
6494 return ParseJsDimension(jsValue, result, DimensionUnit::FP, resObj);
6495 }
6496
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)6497 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
6498 {
6499 // the 'fp' unit is used for text scenes.
6500 return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
6501 }
6502
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj,bool isSupportPercent)6503 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result,
6504 RefPtr<ResourceObject>& resObj, bool isSupportPercent)
6505 {
6506 // the 'fp' unit is used for text scenes.
6507 return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, resObj, isSupportPercent);
6508 }
6509
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)6510 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
6511 {
6512 RefPtr<ResourceObject> resObj;
6513 return ParseJsDimension(jsValue, result, DimensionUnit::PX, resObj);
6514 }
6515
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6516 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result,
6517 RefPtr<ResourceObject>& resObj)
6518 {
6519 return ParseJsDimension(jsValue, result, DimensionUnit::PX, resObj);
6520 }
6521
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)6522 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
6523 {
6524 RefPtr<ResourceObject> resObj;
6525 return ParseColorMetricsToColor(jsValue, result, resObj);
6526 }
6527
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result,RefPtr<ResourceObject> & resObj)6528 bool JSViewAbstract::ParseColorMetricsToColor(
6529 const JSRef<JSVal>& jsValue, Color& result, RefPtr<ResourceObject>& resObj)
6530 {
6531 if (!jsValue->IsObject()) {
6532 return false;
6533 }
6534 auto colorObj = JSRef<JSObject>::Cast(jsValue);
6535 auto toNumericProp = colorObj->GetProperty("toNumeric");
6536 auto colorSpaceProp = colorObj->GetProperty("getColorSpace");
6537 auto jsRes = colorObj->GetProperty("res_");
6538 if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() && !jsRes->IsNull() && jsRes->IsObject()) {
6539 JSRef<JSObject> jsResObj = JSRef<JSObject>::Cast(jsRes);
6540 JSViewAbstract::CompleteResourceObject(jsResObj);
6541 resObj = JSViewAbstract::GetResourceObject(jsResObj);
6542 }
6543 if (toNumericProp->IsFunction() && colorSpaceProp->IsFunction()) {
6544 auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
6545 result.SetValue(colorVal->ToNumber<uint32_t>());
6546
6547 auto resourceIdProp = colorObj->GetProperty("getResourceId");
6548 if (resourceIdProp->IsFunction()) {
6549 auto resourceIdVal = JSRef<JSFunc>::Cast(resourceIdProp)->Call(colorObj, 0, nullptr);
6550 result.SetResourceId(resourceIdVal->ToNumber<uint32_t>());
6551 }
6552
6553 auto colorSpaceVal = JSRef<JSFunc>::Cast(colorSpaceProp)->Call(colorObj, 0, nullptr);
6554 if (colorSpaceVal->IsNumber() &&
6555 colorSpaceVal->ToNumber<uint32_t>() == static_cast<uint32_t>(ColorSpace::DISPLAY_P3)) {
6556 result.SetColorSpace(ColorSpace::DISPLAY_P3);
6557 } else {
6558 result.SetColorSpace(ColorSpace::SRGB);
6559 }
6560
6561 return true;
6562 }
6563 return false;
6564 }
6565
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)6566 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
6567 {
6568 RefPtr<ResourceObject> resObj;
6569 return ParseLengthMetricsToDimension(jsValue, result, resObj);
6570 }
6571
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resourceObj)6572 bool JSViewAbstract::ParseLengthMetricsToDimension(
6573 const JSRef<JSVal>& jsValue, CalcDimension& result, RefPtr<ResourceObject>& resourceObj)
6574 {
6575 if (jsValue->IsNumber()) {
6576 result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
6577 return true;
6578 }
6579 if (jsValue->IsString()) {
6580 auto value = jsValue->ToString();
6581 return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
6582 }
6583 if (jsValue->IsObject()) {
6584 auto jsObj = JSRef<JSObject>::Cast(jsValue);
6585 auto valObj = jsObj->GetProperty("value");
6586 if (valObj->IsUndefined() || valObj->IsNull()) {
6587 return false;
6588 }
6589 double value = valObj->ToNumber<double>();
6590 auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
6591 result = CalcDimension(value, unit);
6592 auto jsRes = jsObj->GetProperty("res");
6593 if (SystemProperties::ConfigChangePerform() && !jsRes->IsUndefined() &&
6594 !jsRes->IsNull() && jsRes->IsObject()) {
6595 JSRef<JSObject> resObj = JSRef<JSObject>::Cast(jsRes);
6596 JSViewAbstract::CompleteResourceObject(resObj);
6597 resourceObj = JSViewAbstract::GetResourceObject(resObj);
6598 }
6599 return true;
6600 }
6601 return false;
6602 }
6603
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)6604 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
6605 {
6606 return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
6607 }
6608
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)6609 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(
6610 const JSRef<JSVal>& jsValue, CalcDimension& result, RefPtr<ResourceObject>& resObj)
6611 {
6612 return ParseLengthMetricsToDimension(jsValue, result, resObj) ? GreatOrEqual(result.Value(), 0.0f) : false;
6613 }
6614
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result,RefPtr<ResourceObject> & resObj)6615 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result,
6616 RefPtr<ResourceObject>& resObj)
6617 {
6618 if (!jsValue->IsObject()) {
6619 return false;
6620 }
6621 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6622 CompleteResourceObject(jsObj);
6623 if (jsObj->IsEmpty()) {
6624 return false;
6625 }
6626 JSRef<JSVal> id = jsObj->GetProperty("id");
6627 if (!id->IsNumber()) {
6628 return false;
6629 }
6630
6631 auto resId = id->ToNumber<int32_t>();
6632 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6633 if (resType == UNKNOWN_RESOURCE_TYPE) {
6634 return false;
6635 }
6636
6637 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6638 GetResourceObjectByBundleAndModule(jsObj);
6639 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6640 if (!resourceWrapper) {
6641 return false;
6642 }
6643
6644 if (resId == -1) {
6645 return ParseResourceToDoubleByName(jsObj, resType, resourceWrapper, result);
6646 }
6647 return ParseResourceToDoubleById(resId, resType, resourceWrapper, result);
6648 }
6649
ParseResourceToDoubleByName(const JSRef<JSObject> & jsObj,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)6650 bool JSViewAbstract::ParseResourceToDoubleByName(
6651 const JSRef<JSObject>& jsObj, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
6652 {
6653 if (!IsGetResourceByName(jsObj)) {
6654 return false;
6655 }
6656 JSRef<JSVal> args = jsObj->GetProperty("params");
6657 if (!args->IsArray()) {
6658 return false;
6659 }
6660 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6661 auto param = params->GetValueAt(0);
6662 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6663 auto numberString = resourceWrapper->GetStringByName(param->ToString());
6664 return StringUtils::StringToDouble(numberString, result);
6665 }
6666 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6667 result = resourceWrapper->GetIntByName(param->ToString());
6668 return true;
6669 }
6670 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
6671 result = resourceWrapper->GetDoubleByName(param->ToString());
6672 return true;
6673 }
6674 return false;
6675 }
6676
ParseResourceToDoubleById(int32_t resId,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)6677 bool JSViewAbstract::ParseResourceToDoubleById(
6678 int32_t resId, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
6679 {
6680 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
6681 auto numberString = resourceWrapper->GetString(resId);
6682 return StringUtils::StringToDouble(numberString, result);
6683 }
6684 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
6685 result = resourceWrapper->GetInt(resId);
6686 return true;
6687 }
6688 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
6689 result = resourceWrapper->GetDouble(resId);
6690 return true;
6691 }
6692 return false;
6693 }
6694
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)6695 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
6696 {
6697 RefPtr<ResourceObject> resObj;
6698 return ParseJsDouble(jsValue, result, resObj);
6699 }
6700
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result,RefPtr<ResourceObject> & resObj)6701 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result,
6702 RefPtr<ResourceObject>& resObj)
6703 {
6704 if (jsValue->IsNumber()) {
6705 result = jsValue->ToNumber<double>();
6706 return true;
6707 }
6708 if (jsValue->IsString()) {
6709 return StringUtils::StringToDouble(jsValue->ToString(), result);
6710 }
6711 if (jsValue->IsObject()) {
6712 return ParseResourceToDouble(jsValue, result, resObj);
6713 }
6714 return false;
6715 }
6716
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)6717 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
6718 {
6719 if (jsValue->IsNumber()) {
6720 result = jsValue->ToNumber<int32_t>();
6721 return true;
6722 }
6723 if (jsValue->IsString()) {
6724 result = StringUtils::StringToInt(jsValue->ToString());
6725 return true;
6726 }
6727 if (!jsValue->IsObject()) {
6728 return false;
6729 }
6730 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6731 CompleteResourceObject(jsObj);
6732 JSRef<JSVal> resId = jsObj->GetProperty("id");
6733 if (!resId->IsNumber()) {
6734 return false;
6735 }
6736
6737 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6738 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6739 if (!resourceWrapper) {
6740 return false;
6741 }
6742
6743 auto resIdNum = resId->ToNumber<int32_t>();
6744 if (resIdNum == -1) {
6745 if (!IsGetResourceByName(jsObj)) {
6746 return false;
6747 }
6748 JSRef<JSVal> args = jsObj->GetProperty("params");
6749 if (!args->IsArray()) {
6750 return false;
6751 }
6752 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6753 auto param = params->GetValueAt(0);
6754 result = resourceWrapper->GetIntByName(param->ToString());
6755 return true;
6756 }
6757 result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
6758 return true;
6759 }
6760
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result,RefPtr<ResourceObject> & resObj)6761 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result,
6762 RefPtr<ResourceObject>& resObj)
6763 {
6764 if (!jsValue->IsObject()) {
6765 return false;
6766 }
6767 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6768 CompleteResourceObject(jsObj);
6769
6770 auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result, resObj);
6771 if (ok) {
6772 JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
6773 if (jsOpacityRatio->IsNumber()) {
6774 double opacityRatio = jsOpacityRatio->ToNumber<double>();
6775 result = result.BlendOpacity(opacityRatio);
6776 }
6777 }
6778 return ok;
6779 }
6780
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result,RefPtr<ResourceObject> & resObj)6781 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result,
6782 RefPtr<ResourceObject>& resObj)
6783 {
6784 JSRef<JSVal> resId = jsObj->GetProperty("id");
6785 if (!resId->IsNumber()) {
6786 return false;
6787 }
6788
6789 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
6790 GetResourceObjectByBundleAndModule(jsObj);
6791 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
6792 if (!resourceWrapper) {
6793 return false;
6794 }
6795
6796 auto resIdNum = resId->ToNumber<int32_t>();
6797 if (resIdNum == -1) {
6798 if (!IsGetResourceByName(jsObj)) {
6799 return false;
6800 }
6801 JSRef<JSVal> args = jsObj->GetProperty("params");
6802 if (!args->IsArray()) {
6803 return false;
6804 }
6805 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6806 auto param = params->GetValueAt(0);
6807 result = resourceWrapper->GetColorByName(param->ToString());
6808 return true;
6809 }
6810
6811 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6812 if (type == static_cast<int32_t>(ResourceType::STRING)) {
6813 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
6814 return Color::ParseColorString(value, result);
6815 }
6816 if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
6817 auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
6818 result = Color(ColorAlphaAdapt(value));
6819 return true;
6820 }
6821 if (type == static_cast<int32_t>(ResourceType::COLOR)) {
6822 result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
6823 result.SetResourceId(resId->ToNumber<uint32_t>());
6824 return true;
6825 }
6826 return false;
6827 }
6828
CheckDarkResource(const RefPtr<ResourceObject> & resObj)6829 bool JSViewAbstract::CheckDarkResource(const RefPtr<ResourceObject>& resObj)
6830 {
6831 if (!SystemProperties::GetResourceDecoupling() || !resObj) {
6832 return false;
6833 }
6834 auto resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resObj);
6835 CHECK_NULL_RETURN(resourceAdapter, false);
6836
6837 int32_t resId = resObj->GetId();
6838 bool hasDarkRes = false;
6839 auto params = resObj->GetParams();
6840 if (resId == -1 && !params.empty() && params.back().value.has_value()) {
6841 hasDarkRes = resourceAdapter->ExistDarkResByName(params.back().value.value(),
6842 std::to_string(resObj->GetType()));
6843 } else {
6844 hasDarkRes = resourceAdapter->ExistDarkResById(std::to_string(resId));
6845 }
6846 return hasDarkRes;
6847 }
6848
CompleteResourceObjectFromColor(RefPtr<ResourceObject> & resObj,Color & color,bool state)6849 void JSViewAbstract::CompleteResourceObjectFromColor(RefPtr<ResourceObject>& resObj,
6850 Color& color, bool state)
6851 {
6852 if (!state || !SystemProperties::ConfigChangePerform()) {
6853 return;
6854 }
6855
6856 auto node = NG::ViewStackProcessor::GetInstance()->GetMainElementNode();
6857 CHECK_NULL_VOID(node);
6858
6859 auto instanceId = Container::CurrentIdSafely();
6860 auto nodeTag = node->GetTag();
6861 auto invertFunc = ColorInverter::GetInstance().GetInvertFunc(instanceId, nodeTag);
6862 CHECK_NULL_VOID(invertFunc);
6863
6864 auto localColorMode = node->GetLocalColorMode();
6865 if (localColorMode == ColorMode::LIGHT) {
6866 resObj = nullptr;
6867 return;
6868 }
6869 bool hasDarkRes = CheckDarkResource(resObj);
6870 if (localColorMode == ColorMode::DARK) {
6871 if (!hasDarkRes) {
6872 color = Color(invertFunc(color.GetValue()));
6873 }
6874 resObj = nullptr;
6875 return;
6876 }
6877 auto colorMode = Container::CurrentColorMode();
6878 Color curColor = color;
6879 if ((colorMode == ColorMode::DARK) && !hasDarkRes) {
6880 color = Color(invertFunc(color.GetValue()));
6881 }
6882 if (!resObj) {
6883 resObj = AceType::MakeRefPtr<ResourceObject>();
6884 resObj->SetIsResource(false);
6885 resObj->SetInstanceId(instanceId);
6886 }
6887 resObj->SetNodeTag(nodeTag);
6888 resObj->SetColorMode(colorMode);
6889 resObj->SetHasDarkRes(hasDarkRes);
6890 resObj->SetColor(((colorMode == ColorMode::DARK) ? curColor : color));
6891 }
6892
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)6893 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
6894 {
6895 RefPtr<ResourceObject> resObj;
6896 return ParseJsColor(jsValue, result, resObj);
6897 }
6898
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,RefPtr<ResourceObject> & resObj)6899 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result,
6900 RefPtr<ResourceObject>& resObj)
6901 {
6902 bool state = false;
6903 if (jsValue->IsNumber()) {
6904 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
6905 CompleteResourceObjectFromColor(resObj, result, true);
6906 return true;
6907 }
6908 if (jsValue->IsString()) {
6909 state = Color::ParseColorString(jsValue->ToString(), result);
6910 CompleteResourceObjectFromColor(resObj, result, state);
6911 return state;
6912 }
6913 if (jsValue->IsObject()) {
6914 if (ParseColorMetricsToColor(jsValue, result, resObj)) {
6915 CompleteResourceObjectFromColor(resObj, result, true);
6916 return true;
6917 }
6918 state = ParseJsColorFromResource(jsValue, result, resObj);
6919 CompleteResourceObjectFromColor(resObj, result, state);
6920 return state;
6921 }
6922 return state;
6923 }
6924
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)6925 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
6926 {
6927 RefPtr<ResourceObject> resObj;
6928 return ParseJsColor(jsValue, result, defaultColor, resObj);
6929 }
6930
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor,RefPtr<ResourceObject> & resObj)6931 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result,
6932 const Color& defaultColor, RefPtr<ResourceObject>& resObj)
6933 {
6934 bool state = false;
6935 if (jsValue->IsNumber()) {
6936 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
6937 CompleteResourceObjectFromColor(resObj, result, true);
6938 return true;
6939 }
6940 if (jsValue->IsString()) {
6941 state = Color::ParseColorString(jsValue->ToString(), result, defaultColor);
6942 CompleteResourceObjectFromColor(resObj, result, state);
6943 return state;
6944 }
6945 if (!jsValue->IsObject()) {
6946 return state;
6947 }
6948 state = ParseJsColorFromResource(jsValue, result, resObj);
6949 CompleteResourceObjectFromColor(resObj, result, state);
6950 return state;
6951 }
6952
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)6953 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
6954 {
6955 if (jsValue->IsString()) {
6956 std::string colorStr = jsValue->ToString();
6957 if (colorStr.compare("invert") == 0) {
6958 strategy = ForegroundColorStrategy::INVERT;
6959 return true;
6960 }
6961 }
6962 return false;
6963 }
6964
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)6965 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
6966 {
6967 if (jsValue->IsString()) {
6968 std::string colorStr = jsValue->ToString();
6969 if (colorStr.compare("average") == 0) {
6970 strategy = ShadowColorStrategy::AVERAGE;
6971 return true;
6972 } else if (colorStr.compare("primary") == 0) {
6973 strategy = ShadowColorStrategy::PRIMARY;
6974 return true;
6975 }
6976 }
6977 return false;
6978 }
6979
ParseJsSymbolCustomFamilyNames(std::vector<std::string> & customFamilyNames,const JSRef<JSVal> & jsValue)6980 void JSViewAbstract::ParseJsSymbolCustomFamilyNames(std::vector<std::string>& customFamilyNames,
6981 const JSRef<JSVal>& jsValue)
6982 {
6983 if (jsValue->IsNull() || jsValue->IsUndefined()) {
6984 return;
6985 }
6986 if (!jsValue->IsObject()) {
6987 return;
6988 }
6989 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6990 CompleteResourceObject(jsObj);
6991 JSRef<JSVal> resId = jsObj->GetProperty("id");
6992 if (resId->IsNull() || !resId->IsNumber()) {
6993 return;
6994 }
6995 auto resourceObject = GetResourceObject(jsObj);
6996 std::string bundleName = resourceObject->GetBundleName();
6997 std::string moduleName = resourceObject->GetModuleName();
6998 auto customSymbolFamilyName = bundleName + "_" + moduleName + CUSTOM_SYMBOL_SUFFIX;
6999 std::replace(customSymbolFamilyName.begin(), customSymbolFamilyName.end(), '.', '_');
7000 customFamilyNames.push_back(customSymbolFamilyName);
7001 }
7002
CheckResource(RefPtr<ResourceObject> resourceObject,RefPtr<ResourceWrapper> resourceWrapper)7003 bool JSViewAbstract::CheckResource(RefPtr<ResourceObject> resourceObject, RefPtr<ResourceWrapper> resourceWrapper)
7004 {
7005 if (!resourceWrapper) {
7006 return false;
7007 }
7008 if (!resourceObject) {
7009 return false;
7010 }
7011 return true;
7012 }
7013
CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper,JSRef<JSVal> & resId,std::uint32_t & symbolId)7014 bool JSViewAbstract::CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper, JSRef<JSVal>& resId,
7015 std::uint32_t& symbolId)
7016 {
7017 auto strValue = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
7018 if (!strValue.empty()) {
7019 auto customSymbolId = static_cast<uint32_t>(strtol(strValue.c_str(), nullptr, 16));
7020 symbolId = customSymbolId;
7021 return true;
7022 }
7023 return false;
7024 }
7025
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)7026 bool JSViewAbstract::ParseJsSymbolId(
7027 const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
7028 {
7029 if (jsValue->IsNull() || jsValue->IsUndefined()) {
7030 symbolId = 0;
7031 return false;
7032 }
7033 if (jsValue->IsNumber()) {
7034 symbolId = jsValue->ToNumber<uint32_t>();
7035 return true;
7036 }
7037 if (!jsValue->IsObject()) {
7038 return false;
7039 }
7040 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7041 CompleteResourceObject(jsObj);
7042 JSRef<JSVal> resId = jsObj->GetProperty("id");
7043 if (resId->IsNull() || !resId->IsNumber()) {
7044 return false;
7045 }
7046 auto resourceObject = GetResourceObject(jsObj);
7047 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
7048 symbolResourceObject = resourceObject;
7049 int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
7050 if (type == static_cast<int32_t>(ResourceType::STRING) && CheckCustomSymbolId(resourceWrapper, resId, symbolId)) {
7051 return true;
7052 }
7053 if (!CheckResource(resourceObject, resourceWrapper)) {
7054 return false;
7055 }
7056 auto resIdNum = resId->ToNumber<int32_t>();
7057 if (resIdNum == -1) {
7058 if (!IsGetResourceByName(jsObj)) {
7059 return false;
7060 }
7061 JSRef<JSVal> args = jsObj->GetProperty("params");
7062 if (!args->IsArray()) {
7063 return false;
7064 }
7065 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7066 auto param = params->GetValueAt(0);
7067 auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
7068 if (!symbol) {
7069 return false;
7070 }
7071 symbolId = symbol;
7072 return true;
7073 }
7074
7075 auto symbol = resourceWrapper->GetSymbolById(resIdNum);
7076 if (!symbol) {
7077 return false;
7078 }
7079 symbolId = symbol;
7080 return true;
7081 }
7082
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result,bool enableResourceUpdate,std::vector<std::pair<int32_t,RefPtr<ResourceObject>>> & resObjArr)7083 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result,
7084 bool enableResourceUpdate, std::vector<std::pair<int32_t, RefPtr<ResourceObject>>>& resObjArr)
7085 {
7086 if (!jsValue->IsArray()) {
7087 return false;
7088 }
7089 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
7090 for (size_t i = 0; i < array->Length(); i++) {
7091 JSRef<JSVal> value = array->GetValueAt(i);
7092 if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
7093 return false;
7094 }
7095 RefPtr<ResourceObject> resObj;
7096 Color color;
7097 if (value->IsNumber()) {
7098 color = Color(ColorAlphaAdapt(value->ToNumber<uint32_t>()));
7099 } else if (value->IsString()) {
7100 Color::ParseColorString(value->ToString(), color);
7101 } else {
7102 ParseJsColorFromResource(value, color, resObj);
7103 }
7104
7105 result.emplace_back(color);
7106 CompleteResourceObjectFromColor(resObj, color, true);
7107 if (enableResourceUpdate && resObj) {
7108 std::pair<int32_t, RefPtr<ResourceObject>> pair(i, resObj);
7109 resObjArr.push_back(pair);
7110 }
7111 }
7112 return true;
7113 }
7114
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)7115 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
7116 {
7117 RefPtr<ResourceObject> resObj;
7118 return ParseJsFontFamilies(jsValue, result, resObj);
7119 }
7120
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result,RefPtr<ResourceObject> & resObj)7121 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result,
7122 RefPtr<ResourceObject>& resObj)
7123 {
7124 result.clear();
7125 if (!jsValue->IsString() && !jsValue->IsObject()) {
7126 return false;
7127 }
7128 if (jsValue->IsString()) {
7129 result = ConvertStrToFontFamilies(jsValue->ToString());
7130 return true;
7131 }
7132 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7133 CompleteResourceObject(jsObj);
7134 JSRef<JSVal> resId = jsObj->GetProperty("id");
7135 if (!resId->IsNumber()) {
7136 return false;
7137 }
7138
7139 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7140 GetResourceObjectByBundleAndModule(jsObj);
7141 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7142 if (!resourceWrapper) {
7143 return false;
7144 }
7145
7146 auto resIdNum = resId->ToNumber<int32_t>();
7147 if (resIdNum == -1) {
7148 if (!IsGetResourceByName(jsObj)) {
7149 return false;
7150 }
7151 JSRef<JSVal> args = jsObj->GetProperty("params");
7152 if (!args->IsArray()) {
7153 return false;
7154 }
7155 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7156 auto param = params->GetValueAt(0);
7157 result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
7158 return true;
7159 }
7160 result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
7161 return true;
7162 }
7163
ParseJsStringObj(const JSRef<JSVal> & jsValue,std::string & result,RefPtr<ResourceObject> & resObj)7164 bool JSViewAbstract::ParseJsStringObj(const JSRef<JSVal>& jsValue, std::string& result,
7165 RefPtr<ResourceObject>& resObj)
7166 {
7167 if (!jsValue->IsObject()) {
7168 return false;
7169 }
7170 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7171 CompleteResourceObject(jsObj);
7172 JSRef<JSVal> resId = jsObj->GetProperty("id");
7173 if (!resId->IsNumber()) {
7174 return false;
7175 }
7176 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
7177 if (type == UNKNOWN_RESOURCE_TYPE) {
7178 return false;
7179 }
7180 JSRef<JSVal> args = jsObj->GetProperty("params");
7181 if (!args->IsArray()) {
7182 return false;
7183 }
7184 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7185 GetResourceObjectByBundleAndModule(jsObj);
7186 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7187 if (!resourceWrapper) {
7188 return false;
7189 }
7190 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7191 auto resIdNum = resId->ToNumber<int32_t>();
7192 if (resIdNum == -1) {
7193 if (!IsGetResourceByName(jsObj)) {
7194 return false;
7195 }
7196 auto param = params->GetValueAt(0);
7197 if (type == static_cast<int32_t>(ResourceType::STRING)) {
7198 auto originStr = resourceWrapper->GetStringByName(param->ToString());
7199 ReplaceHolder(originStr, params, 1);
7200 result = originStr;
7201 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
7202 auto countJsVal = params->GetValueAt(1);
7203 int count = 0;
7204 if (!countJsVal->IsNumber()) {
7205 return false;
7206 }
7207 count = countJsVal->ToNumber<int>();
7208 auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
7209 ReplaceHolder(pluralStr, params, 2); // params[2] applys pluralStr.
7210 result = pluralStr;
7211 } else {
7212 return false;
7213 }
7214 return true;
7215 }
7216 if (type == static_cast<int32_t>(ResourceType::STRING)) {
7217 auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
7218 ReplaceHolder(originStr, params, 0);
7219 result = originStr;
7220 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
7221 auto countJsVal = params->GetValueAt(0);
7222 int count = 0;
7223 if (!countJsVal->IsNumber()) {
7224 return false;
7225 }
7226 count = countJsVal->ToNumber<int>();
7227 auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
7228 ReplaceHolder(pluralStr, params, 1);
7229 result = pluralStr;
7230 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
7231 result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
7232 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
7233 result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
7234 } else {
7235 return false;
7236 }
7237 return true;
7238 }
7239
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)7240 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
7241 {
7242 RefPtr<ResourceObject> resObj;
7243 return ParseJsString(jsValue, result, resObj);
7244 }
7245
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result,RefPtr<ResourceObject> & resObj)7246 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result,
7247 RefPtr<ResourceObject>& resObj)
7248 {
7249 if (jsValue->IsString()) {
7250 result = jsValue->ToString();
7251 return true;
7252 }
7253 return ParseJsStringObj(jsValue, result, resObj);
7254 }
7255
ParseJsString(const JSRef<JSVal> & jsValue,std::u16string & result)7256 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::u16string& result)
7257 {
7258 RefPtr<ResourceObject> resObj;
7259 return ParseJsString(jsValue, result, resObj);
7260 }
7261
ParseJsString(const JSRef<JSVal> & jsValue,std::u16string & result,RefPtr<ResourceObject> & resObj)7262 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::u16string& result,
7263 RefPtr<ResourceObject>& resObj)
7264 {
7265 std::string u8Result;
7266 if (jsValue->IsString()) {
7267 result = jsValue->ToU16String();
7268 return true;
7269 }
7270 bool ret = ParseJsStringObj(jsValue, u8Result, resObj);
7271 if (ret) {
7272 result = UtfUtils::Str8DebugToStr16(u8Result);
7273 return true;
7274 }
7275 return false;
7276 }
7277
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result,RefPtr<ResourceObject> & resObj)7278 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result,
7279 RefPtr<ResourceObject>& resObj)
7280 {
7281 if (!jsValue->IsObject() && !jsValue->IsString()) {
7282 return false;
7283 }
7284 if (jsValue->IsString()) {
7285 result = jsValue->ToString();
7286 return true;
7287 }
7288 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7289 CompleteResourceObject(jsObj);
7290 return ParseJSMediaInternal(jsObj, result, resObj);
7291 }
7292
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)7293 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
7294 {
7295 RefPtr<ResourceObject> resObj;
7296 return ParseJsMedia(jsValue, result, resObj);
7297 }
7298
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)7299 bool JSViewAbstract::ParseJsMediaWithBundleName(
7300 const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
7301 {
7302 RefPtr<ResourceObject> resObj;
7303 return ParseJsMediaWithBundleName(jsValue, result, bundleName, moduleName, resId, resObj);
7304 }
7305
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId,RefPtr<ResourceObject> & resObj)7306 bool JSViewAbstract::ParseJsMediaWithBundleName(
7307 const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName,
7308 int32_t& resId, RefPtr<ResourceObject>& resObj)
7309 {
7310 if (!jsValue->IsObject() && !jsValue->IsString()) {
7311 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
7312 }
7313 if (jsValue->IsString()) {
7314 result = jsValue->ToString();
7315 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
7316 }
7317 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7318 CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
7319 return ParseJSMediaInternal(jsObj, result, resObj);
7320 }
7321
ParseJSMediaWithRawFile(const JSRef<JSObject> & jsObj,std::string & result,RefPtr<ResourceWrapper> & resourceWrapper)7322 bool JSViewAbstract::ParseJSMediaWithRawFile(const JSRef<JSObject>& jsObj, std::string& result,
7323 RefPtr<ResourceWrapper>& resourceWrapper)
7324 {
7325 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
7326 if (!args->IsArray()) {
7327 return false;
7328 }
7329 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7330 auto fileName = params->GetValueAt(0);
7331 if (!fileName->IsString()) {
7332 return false;
7333 }
7334 result = resourceWrapper->GetRawfile(fileName->ToString());
7335 return true;
7336 }
7337
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result,RefPtr<ResourceObject> & resObj)7338 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result,
7339 RefPtr<ResourceObject>& resObj)
7340 {
7341 int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
7342 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
7343 if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
7344 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7345 GetResourceObjectByBundleAndModule(jsObj);
7346 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7347 CHECK_NULL_RETURN(resourceWrapper, false);
7348 if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
7349 return JSViewAbstract::ParseJSMediaWithRawFile(jsObj, result, resourceWrapper);
7350 }
7351 auto resIdNum = resId->ToNumber<int32_t>();
7352 if (resIdNum == -1) {
7353 if (!IsGetResourceByName(jsObj)) {
7354 return false;
7355 }
7356 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
7357 if (!args->IsArray()) {
7358 return false;
7359 }
7360 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7361 auto param = params->GetValueAt(0);
7362 if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
7363 result = resourceWrapper->GetMediaPathByName(param->ToString());
7364 return true;
7365 }
7366 if (type == static_cast<int32_t>(ResourceType::STRING)) {
7367 result = resourceWrapper->GetStringByName(param->ToString());
7368 return true;
7369 }
7370 return false;
7371 } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
7372 result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
7373 return true;
7374 } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
7375 result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
7376 return true;
7377 }
7378 }
7379 return false;
7380 }
7381
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)7382 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
7383 const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
7384 {
7385 auto vm = info.GetVm();
7386 auto globalObj = JSNApi::GetGlobalObject(vm);
7387 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
7388 JsiValue jsiValue(globalFunc);
7389 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
7390 if (!globalFuncRef->IsFunction()) {
7391 return;
7392 }
7393 if (modifierNormalObj->IsUndefined()) {
7394 symbolApply.onApply = nullptr;
7395 } else {
7396 RefPtr<JsFunction> jsFunc =
7397 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
7398 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
7399 modifierNormal = std::move(modifierNormalObj),
7400 modifierSelected = std::move(modifierSelectedObj)](
7401 WeakPtr<NG::FrameNode> frameNode, std::string type) {
7402 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7403 auto node = frameNode.Upgrade();
7404 CHECK_NULL_VOID(node);
7405 JSRef<JSVal> params[SECOND_INDEX];
7406 if (type == "normal") {
7407 params[0] = modifierNormal;
7408 } else if (!modifierSelected->IsUndefined()) {
7409 params[0] = modifierSelected;
7410 }
7411 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
7412 PipelineContext::SetCallBackNode(node);
7413 func->ExecuteJS(SECOND_INDEX, params);
7414 };
7415 symbolApply.onApply = onApply;
7416 }
7417 }
7418
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)7419 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
7420 {
7421 RefPtr<ResourceObject> resObj;
7422 return ParseJsBool(jsValue, result, resObj);
7423 }
7424
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result,RefPtr<ResourceObject> & resObj)7425 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result,
7426 RefPtr<ResourceObject>& resObj)
7427 {
7428 if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
7429 return false;
7430 }
7431
7432 if (jsValue->IsBoolean()) {
7433 result = jsValue->ToBoolean();
7434 return true;
7435 }
7436
7437 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7438 CompleteResourceObject(jsObj);
7439 int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
7440 if (resType == UNKNOWN_RESOURCE_TYPE) {
7441 return false;
7442 }
7443
7444 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
7445 if (!resId->IsNumber()) {
7446 return false;
7447 }
7448
7449 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7450 GetResourceObjectByBundleAndModule(jsObj);
7451 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7452 if (!resourceWrapper) {
7453 return false;
7454 }
7455
7456 auto resIdNum = resId->ToNumber<int32_t>();
7457 if (resIdNum == -1) {
7458 if (!IsGetResourceByName(jsObj)) {
7459 return false;
7460 }
7461 JSRef<JSVal> args = jsObj->GetProperty("params");
7462 if (!args->IsArray()) {
7463 return false;
7464 }
7465 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7466 auto param = params->GetValueAt(0);
7467 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
7468 result = resourceWrapper->GetBooleanByName(param->ToString());
7469 return true;
7470 }
7471 return false;
7472 }
7473
7474 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
7475 result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
7476 return true;
7477 }
7478 return false;
7479 }
7480
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)7481 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
7482 {
7483 return ParseJsInteger<uint32_t>(jsValue, result);
7484 }
7485
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)7486 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
7487 {
7488 return ParseJsInteger<int32_t>(jsValue, result);
7489 }
7490
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)7491 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
7492 {
7493 RefPtr<ResourceObject> resObj;
7494 std::vector<RefPtr<ResourceObject>> resObjArray;
7495 return ParseJsIntegerArray(jsValue, result, resObj, resObjArray);
7496 }
7497
ParseJsIntegerArrayInternal(const JSRef<JSArray> & jsArray,std::vector<uint32_t> & result,std::vector<RefPtr<ResourceObject>> & resObjArray)7498 bool JSViewAbstract::ParseJsIntegerArrayInternal(const JSRef<JSArray>& jsArray, std::vector<uint32_t>& result,
7499 std::vector<RefPtr<ResourceObject>>& resObjArray)
7500 {
7501 for (size_t i = 0; i < jsArray->Length(); i++) {
7502 RefPtr<ResourceObject> resObj;
7503 JSRef<JSVal> value = jsArray->GetValueAt(i);
7504 if (value->IsNumber()) {
7505 result.emplace_back(value->ToNumber<uint32_t>());
7506 } else if (value->IsObject()) {
7507 uint32_t singleResInt;
7508 if (ParseJsInteger(value, singleResInt, resObj)) {
7509 result.emplace_back(singleResInt);
7510 } else {
7511 resObjArray.clear();
7512 return false;
7513 }
7514 } else {
7515 resObjArray.clear();
7516 return false;
7517 }
7518 resObjArray.emplace_back(resObj);
7519 }
7520 return true;
7521 }
7522
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result,RefPtr<ResourceObject> & resObj,std::vector<RefPtr<ResourceObject>> & resObjArray)7523 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result,
7524 RefPtr<ResourceObject>& resObj, std::vector<RefPtr<ResourceObject>>& resObjArray)
7525 {
7526 if (!jsValue->IsArray() && !jsValue->IsObject()) {
7527 return false;
7528 }
7529 if (jsValue->IsArray()) {
7530 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(jsValue);
7531 return ParseJsIntegerArrayInternal(jsArray, result, resObjArray);
7532 }
7533 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7534 CompleteResourceObject(jsObj);
7535 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
7536 if (resType == UNKNOWN_RESOURCE_TYPE) {
7537 return false;
7538 }
7539 JSRef<JSVal> resId = jsObj->GetProperty("id");
7540 if (!resId->IsNumber()) {
7541 return false;
7542 }
7543 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7544 GetResourceObjectByBundleAndModule(jsObj);
7545 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7546 if (!resourceWrapper) {
7547 return false;
7548 }
7549 auto resIdNum = resId->ToNumber<int32_t>();
7550 if (resIdNum == -1) {
7551 if (!IsGetResourceByName(jsObj)) {
7552 return false;
7553 }
7554 JSRef<JSVal> args = jsObj->GetProperty("params");
7555 if (!args->IsArray()) {
7556 return false;
7557 }
7558 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7559 auto param = params->GetValueAt(0);
7560 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
7561 result = resourceWrapper->GetIntArrayByName(param->ToString());
7562 return true;
7563 }
7564 return false;
7565 }
7566 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
7567 result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
7568 return true;
7569 }
7570 return false;
7571 }
7572
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)7573 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
7574 {
7575 RefPtr<ResourceObject> resObj;
7576 std::vector<RefPtr<ResourceObject>> resObjArray;
7577 return ParseJsStrArray(jsValue, result, resObj, resObjArray);
7578 }
7579
ParseJsStrArrayInternal(const JSRef<JSArray> & jsArray,std::vector<std::string> & result,std::vector<RefPtr<ResourceObject>> & resObjArray)7580 bool JSViewAbstract::ParseJsStrArrayInternal(const JSRef<JSArray>& jsArray, std::vector<std::string>& result,
7581 std::vector<RefPtr<ResourceObject>>& resObjArray)
7582 {
7583 for (size_t i = 0; i < jsArray->Length(); i++) {
7584 RefPtr<ResourceObject> resObj;
7585 JSRef<JSVal> value = jsArray->GetValueAt(i);
7586 if (value->IsString()) {
7587 result.emplace_back(value->ToString());
7588 } else if (value->IsObject()) {
7589 std::string singleResStr;
7590 if (ParseJsString(value, singleResStr, resObj)) {
7591 result.emplace_back(singleResStr);
7592 } else {
7593 resObjArray.clear();
7594 return false;
7595 }
7596 } else {
7597 resObjArray.clear();
7598 return false;
7599 }
7600 resObjArray.emplace_back(resObj);
7601 }
7602 return true;
7603 }
7604
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result,RefPtr<ResourceObject> & resObj,std::vector<RefPtr<ResourceObject>> & resObjArray)7605 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result,
7606 RefPtr<ResourceObject>& resObj, std::vector<RefPtr<ResourceObject>>& resObjArray)
7607 {
7608 if (!jsValue->IsArray() && !jsValue->IsObject()) {
7609 return false;
7610 }
7611 if (jsValue->IsArray()) {
7612 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(jsValue);
7613 return ParseJsStrArrayInternal(jsArray, result, resObjArray);
7614 }
7615 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7616 CompleteResourceObject(jsObj);
7617 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
7618 if (resType == UNKNOWN_RESOURCE_TYPE) {
7619 return false;
7620 }
7621 JSRef<JSVal> resId = jsObj->GetProperty("id");
7622 if (!resId->IsNumber()) {
7623 return false;
7624 }
7625 resObj = SystemProperties::ConfigChangePerform() ? GetResourceObject(jsObj) :
7626 GetResourceObjectByBundleAndModule(jsObj);
7627 auto resourceWrapper = CreateResourceWrapper(jsObj, resObj);
7628 if (!resourceWrapper) {
7629 return false;
7630 }
7631 auto resIdNum = resId->ToNumber<int32_t>();
7632 if (resIdNum == -1) {
7633 if (!IsGetResourceByName(jsObj)) {
7634 return false;
7635 }
7636 JSRef<JSVal> args = jsObj->GetProperty("params");
7637 if (!args->IsArray()) {
7638 return false;
7639 }
7640 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7641 auto param = params->GetValueAt(0);
7642 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
7643 result = resourceWrapper->GetStringArrayByName(param->ToString());
7644 return true;
7645 }
7646 return false;
7647 }
7648 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
7649 result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
7650 return true;
7651 }
7652 return false;
7653 }
7654
ParseJsLengthMetricsArray(const JSRef<JSVal> & jsValue,std::vector<Dimension> & result)7655 bool JSViewAbstract::ParseJsLengthMetricsArray(const JSRef<JSVal>& jsValue, std::vector<Dimension>& result)
7656 {
7657 std::vector<RefPtr<ResourceObject>> resObjArray;
7658 return ParseJsLengthMetricsArray(jsValue, result, resObjArray);
7659 }
7660
ParseJsLengthMetricsArray(const JSRef<JSVal> & jsValue,std::vector<Dimension> & result,std::vector<RefPtr<ResourceObject>> & resObjArray)7661 bool JSViewAbstract::ParseJsLengthMetricsArray(const JSRef<JSVal>& jsValue, std::vector<Dimension>& result,
7662 std::vector<RefPtr<ResourceObject>>& resObjArray)
7663 {
7664 if (jsValue->IsArray()) {
7665 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
7666 for (size_t i = 0; i < array->Length(); i++) {
7667 RefPtr<ResourceObject> resObj;
7668 JSRef<JSVal> value = array->GetValueAt(i);
7669 Dimension calc;
7670 ParseJsLengthMetricsToDimension(value, calc, resObj);
7671 result.emplace_back(calc);
7672 resObjArray.emplace_back(resObj);
7673 }
7674 return true;
7675 }
7676
7677 return false;
7678 }
7679
IsGetResourceByName(const JSRef<JSObject> & jsObj)7680 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
7681 {
7682 JSRef<JSVal> resId = jsObj->GetProperty("id");
7683 if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
7684 return false;
7685 }
7686 JSRef<JSVal> args = jsObj->GetProperty("params");
7687 if (!args->IsArray()) {
7688 return false;
7689 }
7690 JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
7691 JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
7692 if (!bundleName->IsString() || !moduleName->IsString()) {
7693 return false;
7694 }
7695 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
7696 if (params->IsEmpty()) {
7697 return false;
7698 }
7699 return true;
7700 }
7701
ParseSize(const JSCallbackInfo & info)7702 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
7703 {
7704 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7705 auto jsVal = info[0];
7706 if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
7707 return std::pair<CalcDimension, CalcDimension>();
7708 }
7709 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
7710 CalcDimension width;
7711 CalcDimension height;
7712 if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
7713 !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
7714 return std::pair<CalcDimension, CalcDimension>();
7715 }
7716 return std::pair<CalcDimension, CalcDimension>(width, height);
7717 }
7718
JsUseAlign(const JSCallbackInfo & info)7719 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
7720 {
7721 if (info.Length() < 2) {
7722 return;
7723 }
7724
7725 if (!info[0]->IsObject() && !info[1]->IsObject()) {
7726 return;
7727 }
7728
7729 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
7730 if (declaration == nullptr) {
7731 return;
7732 }
7733
7734 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7735 JSRef<JSVal> side = obj->GetProperty("side");
7736 JSRef<JSVal> offset = obj->GetProperty("offset");
7737
7738 if (!side->IsNumber()) {
7739 return;
7740 }
7741
7742 auto sideValue = side->ToNumber<int32_t>();
7743
7744 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
7745 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
7746 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
7747 return;
7748 }
7749 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
7750 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
7751 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
7752 return;
7753 }
7754 }
7755
7756 std::optional<CalcDimension> optOffset;
7757 CalcDimension offsetDimension;
7758 if (ParseJsDimensionVp(offset, offsetDimension)) {
7759 optOffset = offsetDimension;
7760 }
7761 ViewAbstractModel::GetInstance()->SetUseAlign(
7762 declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
7763 }
7764
JsGridSpan(const JSCallbackInfo & info)7765 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
7766 {
7767 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
7768 auto jsVal = info[0];
7769 if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
7770 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
7771 ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
7772 }
7773 return;
7774 }
7775 auto span = jsVal->ToNumber<int32_t>();
7776 ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
7777 }
7778
JsGridOffset(const JSCallbackInfo & info)7779 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
7780 {
7781 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
7782 auto jsVal = info[0];
7783 if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
7784 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
7785 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
7786 }
7787 return;
7788 }
7789 auto offset = jsVal->ToNumber<int32_t>();
7790 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
7791 }
7792
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)7793 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
7794 {
7795 // {lg: 4}
7796 if (val->IsNumber()) {
7797 span = val->ToNumber<uint32_t>();
7798 return true;
7799 }
7800
7801 if (!val->IsObject()) {
7802 return false;
7803 }
7804
7805 // {lg: {span: 1, offset: 2}}
7806 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
7807 span = obj->GetProperty("span")->ToNumber<uint32_t>();
7808 offset = obj->GetProperty("offset")->ToNumber<int32_t>();
7809 return true;
7810 }
7811
JsUseSizeType(const JSCallbackInfo & info)7812 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
7813 {
7814 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7815 auto jsVal = info[0];
7816 if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
7817 return;
7818 }
7819 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
7820 for (auto values : SCREEN_SIZE_VALUES) {
7821 JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
7822 if (val->IsNull() || val->IsEmpty()) {
7823 continue;
7824 }
7825 uint32_t span = 0;
7826 int32_t offset = 0;
7827 if (ParseSpanAndOffset(val, span, offset)) {
7828 ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
7829 }
7830 }
7831 }
7832
JsZIndex(const JSCallbackInfo & info)7833 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
7834 {
7835 int zIndex = 0;
7836 if (info[0]->IsNumber()) {
7837 zIndex = info[0]->ToNumber<int>();
7838 }
7839
7840 ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
7841 }
7842
Pop()7843 void JSViewAbstract::Pop()
7844 {
7845 if (ViewStackModel::GetInstance()->IsPrebuilding()) {
7846 return ViewStackModel::GetInstance()->PushPrebuildCompCmd("[JSViewAbstract][pop]", &JSViewAbstract::Pop);
7847 }
7848 ViewStackModel::GetInstance()->Pop();
7849 }
7850
JsSetDraggable(bool draggable)7851 void JSViewAbstract::JsSetDraggable(bool draggable)
7852 {
7853 ViewAbstractModel::GetInstance()->SetDraggable(draggable);
7854 }
7855
ParseDragInteractionOptions(const JSCallbackInfo & info,NG::DragPreviewOption & previewOption)7856 void JSViewAbstract::ParseDragInteractionOptions(const JSCallbackInfo& info,
7857 NG::DragPreviewOption& previewOption)
7858 {
7859 if (info.Length() > 1 && info[1]->IsObject()) {
7860 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
7861 auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
7862 if (multiSelection->IsBoolean()) {
7863 previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
7864 }
7865 auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
7866 if (defaultAnimation->IsBoolean()) {
7867 previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
7868 }
7869 auto hapicFeedback = interObj->GetProperty("enableHapticFeedback");
7870 if (hapicFeedback->IsBoolean()) {
7871 previewOption.enableHapticFeedback = hapicFeedback->ToBoolean();
7872 }
7873 auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
7874 if (dragPreview->IsBoolean()) {
7875 previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
7876 }
7877 auto enableEdgeAutoScroll = interObj->GetProperty("enableEdgeAutoScroll");
7878 if (enableEdgeAutoScroll->IsBoolean()) {
7879 previewOption.enableEdgeAutoScroll = enableEdgeAutoScroll->ToBoolean();
7880 }
7881 auto isLiftingDisabled = interObj->GetProperty("isLiftingDisabled");
7882 if (isLiftingDisabled->IsBoolean()) {
7883 previewOption.isLiftingDisabled = isLiftingDisabled->ToBoolean();
7884 }
7885 }
7886 }
7887
ParseDragPreviewOptions(const JSCallbackInfo & info)7888 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
7889 {
7890 NG::DragPreviewOption previewOption;
7891 if (!info[0]->IsObject()) {
7892 return previewOption;
7893 }
7894 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7895 auto mode = obj->GetProperty("mode");
7896 bool isAuto = true;
7897 if (mode->IsNumber()) {
7898 ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
7899 } else if (mode->IsArray()) {
7900 JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
7901 for (size_t i = 0; i < array->Length(); i++) {
7902 JSRef<JSVal> value = array->GetValueAt(i);
7903 if (value->IsNumber()) {
7904 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
7905 }
7906 if (isAuto) {
7907 break;
7908 }
7909 }
7910 }
7911
7912 auto sizeChangeEffect = obj->GetProperty("sizeChangeEffect");
7913 if (sizeChangeEffect->IsNumber()) {
7914 previewOption.sizeChangeEffect = static_cast<NG::DraggingSizeChangeEffect>(sizeChangeEffect->ToNumber<int>());
7915 }
7916
7917 JSViewAbstract::SetDragNumberBadge(info, previewOption);
7918
7919 ParseDragInteractionOptions(info, previewOption);
7920
7921 JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
7922
7923 return previewOption;
7924 }
7925
JsSetDragPreviewOptions(const JSCallbackInfo & info)7926 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
7927 {
7928 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7929 auto jsVal = info[0];
7930 if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
7931 return;
7932 }
7933 NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
7934 ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
7935 }
7936
JsOnDragStart(const JSCallbackInfo & info)7937 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
7938 {
7939 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
7940 auto jsVal = info[0];
7941 if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
7942 return;
7943 }
7944
7945 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
7946
7947 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7948 auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
7949 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
7950 NG::DragDropBaseInfo dragDropInfo;
7951 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
7952 PipelineContext::SetCallBackNode(node);
7953 auto ret = func->Execute(info, extraParams);
7954 if (!ret->IsObject()) {
7955 return dragDropInfo;
7956 }
7957
7958 dragDropInfo.node = ParseDragNode(ret);
7959 auto builderObj = JSRef<JSObject>::Cast(ret);
7960 #if defined(PIXEL_MAP_SUPPORTED)
7961 auto pixmap = builderObj->GetProperty("pixelMap");
7962 dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
7963 #endif
7964 auto extraInfo = builderObj->GetProperty("extraInfo");
7965 ParseJsString(extraInfo, dragDropInfo.extraInfo);
7966 return dragDropInfo;
7967 };
7968 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
7969 }
7970
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)7971 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
7972 {
7973 auto node = ParseDragNode(info);
7974 if (!node) {
7975 return false;
7976 }
7977 dragInfo.node = node;
7978 return true;
7979 }
7980
ParseDragNode(const JSRef<JSVal> & info)7981 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
7982 {
7983 auto builderFunc = ParseDragStartBuilderFunc(info);
7984 if (!builderFunc) {
7985 return nullptr;
7986 }
7987 // use another VSP instance while executing the builder function
7988 ViewStackModel::GetInstance()->NewScope();
7989 {
7990 ACE_SCORING_EVENT("onDragStart.builder");
7991 builderFunc->Execute();
7992 }
7993
7994 return ViewStackModel::GetInstance()->Finish();
7995 }
7996
JsOnDragEnter(const JSCallbackInfo & info)7997 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
7998 {
7999 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8000 auto jsVal = info[0];
8001 if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
8002 return;
8003 }
8004 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8005 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8006 auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
8007 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8008 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8009 ACE_SCORING_EVENT("onDragEnter");
8010 PipelineContext::SetCallBackNode(node);
8011 func->Execute(info, extraParams);
8012 };
8013
8014 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
8015 }
8016
JsOnDragSpringLoading(const JSCallbackInfo & info)8017 void JSViewAbstract::JsOnDragSpringLoading(const JSCallbackInfo& info)
8018 {
8019 if (info.Length() > 0) {
8020 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION, JSCallbackInfoType::OBJECT };
8021 auto jsVal = info[0];
8022 if (!CheckJSCallbackInfo("JsOnDragSpringLoading", jsVal, checkList)) {
8023 return;
8024 }
8025 NG::OnDragDropSpringLoadingFunc onDragSpringLoading = nullptr;
8026 WeakPtr<NG::FrameNode> frameNode =
8027 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8028 if (jsVal->IsFunction()) {
8029 RefPtr<JsDragFunction> jsOnDragSpringLoadingFunc =
8030 AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8031 onDragSpringLoading = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragSpringLoadingFunc),
8032 node = frameNode](const RefPtr<DragSpringLoadingContext>& info) {
8033 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8034 ACE_SCORING_EVENT("JsOnDragSpringLoading");
8035 PipelineContext::SetCallBackNode(node);
8036 func->DragSpringLoadingExecute(info);
8037 };
8038 }
8039 ViewAbstractModel::GetInstance()->SetOnDragSpringLoading(std::move(onDragSpringLoading));
8040 }
8041 if (info.Length() == NUM2 && info[NUM1]->IsObject()) {
8042 auto dragSpringLoadingConfiguration = AceType::MakeRefPtr<NG::DragSpringLoadingConfiguration>();
8043 ParseDragSpringLoadingConfiguration(info[NUM1], dragSpringLoadingConfiguration);
8044 ViewAbstractModel::GetInstance()->SetOnDragSpringLoadingConfiguration(
8045 std::move(dragSpringLoadingConfiguration));
8046 }
8047 }
8048
JsOnDragEnd(const JSCallbackInfo & info)8049 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
8050 {
8051 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8052 auto jsVal = info[0];
8053 if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
8054 return;
8055 }
8056 RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8057 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8058 auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
8059 const RefPtr<OHOS::Ace::DragEvent>& info) {
8060 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8061 ACE_SCORING_EVENT("onDragEnd");
8062 auto extraParams = JsonUtil::Create(true);
8063 PipelineContext::SetCallBackNode(node);
8064 func->Execute(info, extraParams->ToString());
8065 };
8066
8067 ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
8068 }
8069
JsOnDragMove(const JSCallbackInfo & info)8070 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
8071 {
8072 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8073 auto jsVal = info[0];
8074 if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
8075 return;
8076 }
8077 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8078 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8079 auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
8080 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8081 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8082 ACE_SCORING_EVENT("onDragMove");
8083 PipelineContext::SetCallBackNode(node);
8084 func->Execute(info, extraParams);
8085 };
8086
8087 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
8088 }
8089
JsOnDragLeave(const JSCallbackInfo & info)8090 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
8091 {
8092 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8093 auto jsVal = info[0];
8094 if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
8095 return;
8096 }
8097 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8098 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8099 auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
8100 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8101 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8102 ACE_SCORING_EVENT("onDragLeave");
8103 PipelineContext::SetCallBackNode(node);
8104 func->Execute(info, extraParams);
8105 };
8106
8107 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
8108 }
8109
JsOnDrop(const JSCallbackInfo & info)8110 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
8111 {
8112 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8113 auto jsVal = info[0];
8114 if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
8115 return;
8116 }
8117 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8118 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8119 auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
8120 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
8121 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8122 ACE_SCORING_EVENT("onDrop");
8123 PipelineContext::SetCallBackNode(node);
8124 func->Execute(info, extraParams);
8125 };
8126
8127 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
8128
8129 bool disableDataPrefetch = false;
8130 if (info.Length() > 1 && info[1]->IsObject()) {
8131 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
8132 auto jsDisableDataPrefetch = interObj->GetProperty("disableDataPrefetch");
8133 if (jsDisableDataPrefetch->IsBoolean()) {
8134 disableDataPrefetch = jsDisableDataPrefetch->ToBoolean();
8135 }
8136 }
8137 ViewAbstractModel::GetInstance()->SetDisableDataPrefetch(disableDataPrefetch);
8138 }
8139
JsOnAreaChange(const JSCallbackInfo & info)8140 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
8141 {
8142 auto jsVal = info[0];
8143 if (jsVal->IsUndefined() && IsDisableEventVersion()) {
8144 ViewAbstractModel::GetInstance()->DisableOnAreaChange();
8145 return;
8146 }
8147 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8148 if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
8149 return;
8150 }
8151 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
8152
8153 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8154 auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
8155 node = frameNode](
8156 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
8157 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8158 ACE_SCORING_EVENT("onAreaChange");
8159 PipelineContext::SetCallBackNode(node);
8160 func->Execute(oldRect, oldOrigin, rect, origin);
8161 };
8162 ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
8163 }
8164
JsOnSizeChange(const JSCallbackInfo & info)8165 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
8166 {
8167 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8168 auto jsVal = info[0];
8169 if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
8170 return;
8171 }
8172 auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
8173
8174 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8175 auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
8176 node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
8177 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8178 ACE_SCORING_EVENT("onSizeChange");
8179 PipelineContext::SetCallBackNode(node);
8180 func->Execute(oldRect, rect);
8181 };
8182 ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
8183 }
8184
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)8185 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
8186 {
8187 if (!info[0]->IsObject()) {
8188 return;
8189 }
8190 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
8191 NewLinearGradient(jsObj, newGradient);
8192 }
8193
NewLinearGradient(const JSRef<JSObject> & jsObj,NG::Gradient & newGradient)8194 void JSViewAbstract::NewLinearGradient(const JSRef<JSObject>& jsObj, NG::Gradient& newGradient)
8195 {
8196 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
8197 // angle
8198 std::optional<float> degree;
8199 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
8200 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
8201 } else {
8202 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
8203 }
8204 if (degree) {
8205 newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
8206 degree.reset();
8207 }
8208 // direction
8209 auto direction = static_cast<GradientDirection>(
8210 jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
8211 SetGradientDirection(newGradient, direction);
8212 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
8213 newGradient.SetRepeat(repeating);
8214 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)), NUM_0);
8215 }
8216
SetGradientDirection(NG::Gradient & newGradient,const GradientDirection & direction)8217 void JSViewAbstract::SetGradientDirection(NG::Gradient& newGradient, const GradientDirection& direction)
8218 {
8219 switch (direction) {
8220 case GradientDirection::LEFT:
8221 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
8222 break;
8223 case GradientDirection::RIGHT:
8224 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
8225 break;
8226 case GradientDirection::TOP:
8227 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
8228 break;
8229 case GradientDirection::BOTTOM:
8230 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
8231 break;
8232 case GradientDirection::LEFT_TOP:
8233 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
8234 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
8235 break;
8236 case GradientDirection::LEFT_BOTTOM:
8237 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
8238 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
8239 break;
8240 case GradientDirection::RIGHT_TOP:
8241 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
8242 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
8243 break;
8244 case GradientDirection::RIGHT_BOTTOM:
8245 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
8246 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
8247 break;
8248 default:
8249 break;
8250 }
8251 }
8252
JsRadialGradient(const JSCallbackInfo & info)8253 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
8254 {
8255 ViewAbstractModel::GetInstance()->RemoveResObj("RadialGradient.gradient");
8256 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
8257 auto jsVal = info[0];
8258 if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
8259 NG::Gradient newGradient;
8260 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
8261 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
8262 return;
8263 }
8264 NG::Gradient newGradient;
8265 NewJsRadialGradient(info, newGradient);
8266 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
8267 }
8268
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)8269 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
8270 {
8271 JSRef<JSVal> arg = info[0];
8272 if (!arg->IsObject()) {
8273 return;
8274 }
8275 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
8276 NewRadialGradient(jsObj, newGradient);
8277 }
8278
NewRadialGradient(const JSRef<JSObject> & jsObj,NG::Gradient & newGradient)8279 void JSViewAbstract::NewRadialGradient(const JSRef<JSObject>& jsObj, NG::Gradient& newGradient)
8280 {
8281 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
8282 // center
8283 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
8284 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
8285 CalcDimension value;
8286 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
8287 ParseRadialGradientCenter(newGradient, center);
8288 }
8289 // radius
8290 CalcDimension radius;
8291 RefPtr<ResourceObject> resObj;
8292 if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius, resObj)) {
8293 newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
8294 newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
8295 }
8296 if (SystemProperties::ConfigChangePerform() && resObj) {
8297 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8298 CalcDimension dimension;
8299 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8300 gradient.GetRadialGradient()->radialVerticalSize = CalcDimension(dimension);
8301 gradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(dimension);
8302 };
8303 newGradient.AddResource("RadialGradient.radius", resObj, std::move(updateFunc));
8304 }
8305
8306 // repeating
8307 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
8308 newGradient.SetRepeat(repeating);
8309 // color stops
8310 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)), NUM_2);
8311 }
8312
ParseRadialGradientCenter(NG::Gradient & newGradient,JSRef<JSArray> centerArray)8313 void JSViewAbstract::ParseRadialGradientCenter(NG::Gradient& newGradient, JSRef<JSArray> centerArray)
8314 {
8315 RefPtr<ResourceObject> resObjX;
8316 RefPtr<ResourceObject> resObjY;
8317 CalcDimension value;
8318
8319 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value, resObjX)) {
8320 newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
8321 if (value.Unit() == DimensionUnit::PERCENT) {
8322 // [0,1] -> [0, 100]
8323 newGradient.GetRadialGradient()->radialCenterX =
8324 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8325 }
8326 }
8327 if (SystemProperties::ConfigChangePerform() && resObjX) {
8328 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8329 CalcDimension dimension;
8330 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8331 gradient.GetRadialGradient()->radialCenterX = CalcDimension(dimension);
8332 if (dimension.Unit() == DimensionUnit::PERCENT) {
8333 // [0,1] -> [0, 100]
8334 gradient.GetRadialGradient()->radialCenterX =
8335 CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8336 }
8337 };
8338 newGradient.AddResource("RadialGradient.center.centerX", resObjX, std::move(updateFunc));
8339 }
8340 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value, resObjY)) {
8341 newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
8342 if (value.Unit() == DimensionUnit::PERCENT) {
8343 // [0,1] -> [0, 100]
8344 newGradient.GetRadialGradient()->radialCenterY =
8345 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8346 }
8347 }
8348 if (SystemProperties::ConfigChangePerform() && resObjY) {
8349 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8350 CalcDimension dimension;
8351 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8352 gradient.GetRadialGradient()->radialCenterY = CalcDimension(dimension);
8353 if (dimension.Unit() == DimensionUnit::PERCENT) {
8354 // [0,1] -> [0, 100]
8355 gradient.GetRadialGradient()->radialCenterY =
8356 CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8357 }
8358 };
8359 newGradient.AddResource("RadialGradient.center.centerY", resObjY, std::move(updateFunc));
8360 }
8361 }
8362
JsSweepGradient(const JSCallbackInfo & info)8363 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
8364 {
8365 ViewAbstractModel::GetInstance()->RemoveResObj("SweepGradient.gradient");
8366 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
8367 auto jsVal = info[0];
8368 if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
8369 NG::Gradient newGradient;
8370 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
8371 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
8372 return;
8373 }
8374
8375 NG::Gradient newGradient;
8376 NewJsSweepGradient(info, newGradient);
8377 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
8378 }
8379
ParseSweepGradientCenter(NG::Gradient & newGradient,JSRef<JSArray> centerArray)8380 void JSViewAbstract::ParseSweepGradientCenter(NG::Gradient& newGradient, JSRef<JSArray> centerArray)
8381 {
8382 RefPtr<ResourceObject> resObjX;
8383 RefPtr<ResourceObject> resObjY;
8384 CalcDimension value;
8385 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value, resObjX)) {
8386 newGradient.GetSweepGradient()->centerX = CalcDimension(value);
8387 if (value.Unit() == DimensionUnit::PERCENT) {
8388 // [0,1] -> [0, 100]
8389 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8390 }
8391 }
8392 if (SystemProperties::ConfigChangePerform() && resObjX) {
8393 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8394 CalcDimension dimension;
8395 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8396 gradient.GetSweepGradient()->centerX = CalcDimension(dimension);
8397 if (dimension.Unit() == DimensionUnit::PERCENT) {
8398 // [0,1] -> [0, 100]
8399 gradient.GetSweepGradient()->centerX = CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8400 }
8401 };
8402 newGradient.AddResource("SweepGradient.center.centerX", resObjX, std::move(updateFunc));
8403 }
8404 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value, resObjY)) {
8405 newGradient.GetSweepGradient()->centerY = CalcDimension(value);
8406 if (value.Unit() == DimensionUnit::PERCENT) {
8407 // [0,1] -> [0, 100]
8408 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
8409 }
8410 }
8411 if (SystemProperties::ConfigChangePerform() && resObjY) {
8412 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::Gradient& gradient) {
8413 CalcDimension dimension;
8414 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
8415 gradient.GetSweepGradient()->centerY = CalcDimension(dimension);
8416 if (dimension.Unit() == DimensionUnit::PERCENT) {
8417 // [0,1] -> [0, 100]
8418 gradient.GetSweepGradient()->centerY = CalcDimension(dimension.Value() * 100.0, DimensionUnit::PERCENT);
8419 }
8420 };
8421 newGradient.AddResource("SweepGradient.center.centerY", resObjY, std::move(updateFunc));
8422 }
8423 }
8424
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)8425 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
8426 {
8427 JSRef<JSVal> arg = info[0];
8428 if (!arg->IsObject()) {
8429 return;
8430 }
8431 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
8432 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
8433 // center
8434 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
8435 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
8436 CalcDimension value;
8437 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
8438 ParseSweepGradientCenter(newGradient, centerArray);
8439 }
8440 // start, end and rotation
8441 ParseSweepGradientPartly(jsObj, newGradient);
8442 // repeating
8443 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
8444 newGradient.SetRepeat(repeating);
8445 // color stops
8446 JSRef<JSVal> metricColors = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::METRICS_COLORS));
8447 if (metricColors->IsArray()) {
8448 NewGetJsGradientColorStopsCheck(newGradient, metricColors);
8449 } else {
8450 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)), NUM_1);
8451 }
8452 }
8453
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)8454 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
8455 {
8456 std::optional<float> degreeStart;
8457 std::optional<float> degreeEnd;
8458 std::optional<float> degreeRotation;
8459 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
8460 GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
8461 GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
8462 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
8463 } else {
8464 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
8465 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
8466 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
8467 }
8468 if (degreeStart) {
8469 CheckAngle(degreeStart);
8470 newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
8471 }
8472 if (degreeEnd) {
8473 CheckAngle(degreeEnd);
8474 newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
8475 }
8476 if (degreeRotation) {
8477 CheckAngle(degreeRotation);
8478 newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
8479 }
8480 }
8481
JsMotionPath(const JSCallbackInfo & info)8482 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
8483 {
8484 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
8485 auto jsVal = info[0];
8486 if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
8487 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
8488 return;
8489 }
8490 MotionPathOption motionPathOption;
8491 if (ParseMotionPath(jsVal, motionPathOption)) {
8492 ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
8493 } else {
8494 TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
8495 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
8496 }
8497 }
8498
JsShadow(const JSCallbackInfo & info)8499 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
8500 {
8501 ViewAbstractModel::GetInstance()->RemoveResObj("shadow");
8502 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
8503 auto jsVal = info[0];
8504 if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
8505 Shadow shadow;
8506 std::vector<Shadow> shadows { shadow };
8507 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8508 return;
8509 }
8510 Shadow shadow;
8511 if (!ParseShadowProps(jsVal, shadow, SystemProperties::ConfigChangePerform())) {
8512 info.ReturnSelf();
8513 return;
8514 }
8515 std::vector<Shadow> shadows { shadow };
8516 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8517 }
8518
JsBlendMode(const JSCallbackInfo & info)8519 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
8520 {
8521 if (info.Length() == 0) {
8522 return;
8523 }
8524 BlendMode blendMode = BlendMode::NONE;
8525 BlendApplyType blendApplyType = BlendApplyType::FAST;
8526 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
8527 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
8528 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
8529 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
8530 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
8531 if (info[0]->IsNumber()) {
8532 auto blendModeNum = info[0]->ToNumber<int32_t>();
8533 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
8534 blendMode = static_cast<BlendMode>(blendModeNum);
8535 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
8536 // backward compatibility code, will remove soon
8537 blendMode = BlendMode::SRC_OVER;
8538 blendApplyType = BlendApplyType::OFFSCREEN;
8539 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
8540 // backward compatibility code, will remove soon
8541 blendMode = BlendMode::SRC_IN;
8542 blendApplyType = BlendApplyType::OFFSCREEN;
8543 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
8544 // backward compatibility code, will remove soon
8545 blendMode = BlendMode::DST_IN;
8546 blendApplyType = BlendApplyType::OFFSCREEN;
8547 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
8548 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
8549 }
8550 }
8551 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
8552 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
8553 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
8554 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
8555 }
8556 }
8557 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
8558 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
8559 }
8560
JsAdvancedBlendMode(const JSCallbackInfo & info)8561 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
8562 {
8563 if (info.Length() == 0) {
8564 return;
8565 }
8566 BlendMode blendMode = BlendMode::NONE;
8567 BlendApplyType blendApplyType = BlendApplyType::FAST;
8568 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
8569 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
8570 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
8571 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
8572 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
8573 if (info[0]->IsNumber()) {
8574 auto blendModeNum = info[0]->ToNumber<int32_t>();
8575 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
8576 blendMode = static_cast<BlendMode>(blendModeNum);
8577 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
8578 // backward compatibility code, will remove soon
8579 blendMode = BlendMode::SRC_OVER;
8580 blendApplyType = BlendApplyType::OFFSCREEN;
8581 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
8582 // backward compatibility code, will remove soon
8583 blendMode = BlendMode::SRC_IN;
8584 blendApplyType = BlendApplyType::OFFSCREEN;
8585 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
8586 // backward compatibility code, will remove soon
8587 blendMode = BlendMode::DST_IN;
8588 blendApplyType = BlendApplyType::OFFSCREEN;
8589 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
8590 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
8591 }
8592 } else if (info[0]->IsObject()) {
8593 auto blender = CreateRSBlenderFromNapiValue(info[0]);
8594 ViewAbstractModel::GetInstance()->SetBlender(blender);
8595 }
8596 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
8597 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
8598 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
8599 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
8600 }
8601 }
8602 if (!info[0]->IsObject()) {
8603 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
8604 }
8605 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
8606 }
8607
JsGrayScale(const JSCallbackInfo & info)8608 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
8609 {
8610 CalcDimension value;
8611 if (!ParseJsDimensionVp(info[0], value)) {
8612 value.SetValue(0.0);
8613 ViewAbstractModel::GetInstance()->SetGrayScale(value);
8614 return;
8615 }
8616
8617 if (LessNotEqual(value.Value(), 0.0)) {
8618 value.SetValue(0.0);
8619 }
8620
8621 if (GreatNotEqual(value.Value(), 1.0)) {
8622 value.SetValue(1.0);
8623 }
8624
8625 ViewAbstractModel::GetInstance()->SetGrayScale(value);
8626 }
8627
JsBrightness(const JSCallbackInfo & info)8628 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
8629 {
8630 CalcDimension value;
8631 if (!ParseJsDimensionVp(info[0], value)) {
8632 value.SetValue(1.0);
8633 ViewAbstractModel::GetInstance()->SetBrightness(value);
8634 return;
8635 }
8636
8637 ViewAbstractModel::GetInstance()->SetBrightness(value);
8638 }
8639
JsContrast(const JSCallbackInfo & info)8640 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
8641 {
8642 CalcDimension value;
8643 if (!ParseJsDimensionVp(info[0], value)) {
8644 value.SetValue(1.0);
8645 ViewAbstractModel::GetInstance()->SetContrast(value);
8646 return;
8647 }
8648
8649 if (LessNotEqual(value.Value(), 0.0)) {
8650 value.SetValue(0.0);
8651 }
8652
8653 ViewAbstractModel::GetInstance()->SetContrast(value);
8654 }
8655
JsSaturate(const JSCallbackInfo & info)8656 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
8657 {
8658 CalcDimension value;
8659 if (!ParseJsDimensionVp(info[0], value)) {
8660 value.SetValue(1.0);
8661 ViewAbstractModel::GetInstance()->SetSaturate(value);
8662 return;
8663 }
8664
8665 if (LessNotEqual(value.Value(), 0.0)) {
8666 value.SetValue(0.0);
8667 }
8668
8669 ViewAbstractModel::GetInstance()->SetSaturate(value);
8670 }
8671
JsSepia(const JSCallbackInfo & info)8672 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
8673 {
8674 CalcDimension value;
8675 if (!ParseJsDimensionVp(info[0], value)) {
8676 value.SetValue(0.0);
8677 ViewAbstractModel::GetInstance()->SetSepia(value);
8678 return;
8679 }
8680
8681 if (LessNotEqual(value.Value(), 0.0)) {
8682 value.SetValue(0.0);
8683 }
8684
8685 ViewAbstractModel::GetInstance()->SetSepia(value);
8686 }
8687
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)8688 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
8689 {
8690 double invertValue = 0.0;
8691 if (ParseJsDouble(jsValue, invertValue)) {
8692 invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
8693 return true;
8694 }
8695 auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
8696 if (!argsPtrItem || argsPtrItem->IsNull()) {
8697 return false;
8698 }
8699 InvertOption option;
8700 double low = 0.0;
8701 if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
8702 option.low_ = std::clamp(low, 0.0, 1.0);
8703 }
8704 double high = 0.0;
8705 if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
8706 option.high_ = std::clamp(high, 0.0, 1.0);
8707 }
8708 double threshold = 0.0;
8709 if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
8710 option.threshold_ = std::clamp(threshold, 0.0, 1.0);
8711 }
8712 double thresholdRange = 0.0;
8713 if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
8714 option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
8715 }
8716 invert = option;
8717 return true;
8718 }
8719
JsInvert(const JSCallbackInfo & info)8720 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
8721 {
8722 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
8723 InvertVariant invert = 0.0f;
8724 auto jsVal = info[0];
8725 if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
8726 ViewAbstractModel::GetInstance()->SetInvert(invert);
8727 return;
8728 }
8729 if (ParseInvertProps(jsVal, invert)) {
8730 ViewAbstractModel::GetInstance()->SetInvert(invert);
8731 }
8732 ViewAbstractModel::GetInstance()->SetInvert(invert);
8733 }
8734
JsSystemBarEffect(const JSCallbackInfo & info)8735 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
8736 {
8737 ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
8738 }
8739
JsHueRotate(const JSCallbackInfo & info)8740 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
8741 {
8742 std::optional<float> degree;
8743 JSRef<JSVal> arg = info[0];
8744 if (arg->IsString()) {
8745 degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
8746 } else if (arg->IsNumber()) {
8747 degree = static_cast<float>(arg->ToNumber<int32_t>());
8748 } else {
8749 ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
8750 return;
8751 }
8752 float deg = 0.0f;
8753 if (degree) {
8754 deg = degree.value();
8755 degree.reset();
8756 }
8757 deg = std::fmod(deg, ROUND_UNIT);
8758 if (deg < 0.0f) {
8759 deg += ROUND_UNIT;
8760 }
8761 ViewAbstractModel::GetInstance()->SetHueRotate(deg);
8762 }
8763
JsClip(const JSCallbackInfo & info)8764 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
8765 {
8766 JSRef<JSVal> arg = info[0];
8767 if (arg->IsUndefined()) {
8768 ViewAbstractModel::GetInstance()->SetClipEdge(false);
8769 return;
8770 }
8771 if (arg->IsObject()) {
8772 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
8773 if (clipShape == nullptr) {
8774 return;
8775 }
8776 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
8777 } else if (arg->IsBoolean()) {
8778 ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
8779 }
8780 }
8781
JsClipShape(const JSCallbackInfo & info)8782 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
8783 {
8784 ViewAbstractModel::GetInstance()->RemoveResObj("clipShape");
8785 if (info[0]->IsObject()) {
8786 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
8787 if (clipShape == nullptr) {
8788 return;
8789 }
8790 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
8791 }
8792 }
8793
ParseProgressMaskResObj(const JSRef<JSVal> & jColor,Color & colorVal,RefPtr<NG::ProgressMaskProperty> & progressMask)8794 void JSViewAbstract::ParseProgressMaskResObj(const JSRef<JSVal>& jColor, Color& colorVal,
8795 RefPtr<NG::ProgressMaskProperty>& progressMask)
8796 {
8797 RefPtr<ResourceObject> colorResObj;
8798 auto ret = ParseJsColor(jColor, colorVal, colorResObj);
8799 if (colorResObj) {
8800 progressMask->SetColor(colorVal);
8801 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::ProgressMaskProperty& progressMask) {
8802 Color color;
8803 ResourceParseUtils::ParseResColor(resObj, color);
8804 progressMask.SetColor(color);
8805 };
8806 progressMask->AddResource("progressMask.color", colorResObj, std::move(updateFunc));
8807 } else if (ret) {
8808 progressMask->SetColor(colorVal);
8809 } else {
8810 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
8811 progressMask->SetColor(theme->GetMaskColor());
8812 RefPtr<ResourceObject> resObj = AceType::MakeRefPtr<ResourceObject>("", "", -1);
8813 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::ProgressMaskProperty& progressMask) {
8814 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
8815 progressMask.SetColor(theme->GetMaskColor());
8816 };
8817 progressMask->AddResource("progressMask.color", resObj, std::move(updateFunc));
8818 }
8819 }
8820
ParseJsMaskProperty(const JSRef<JSObject> & paramObject)8821 void JSViewAbstract::ParseJsMaskProperty(const JSRef<JSObject>& paramObject)
8822 {
8823 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
8824 JSRef<JSVal> jValue = paramObject->GetProperty("value");
8825 auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
8826 if (value < 0.0f) {
8827 value = 0.0f;
8828 }
8829 progressMask->SetValue(value);
8830 JSRef<JSVal> jTotal = paramObject->GetProperty("total");
8831 auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
8832 if (total < 0.0f) {
8833 total = DEFAULT_PROGRESS_TOTAL;
8834 }
8835 progressMask->SetMaxValue(total);
8836 JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
8837 if (jEnableBreathe->IsBoolean()) {
8838 progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
8839 }
8840 JSRef<JSVal> jColor = paramObject->GetProperty("color");
8841 Color colorVal;
8842 if (!SystemProperties::ConfigChangePerform()) {
8843 if (ParseJsColor(jColor, colorVal)) {
8844 progressMask->SetColor(colorVal);
8845 } else {
8846 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
8847 progressMask->SetColor(theme->GetMaskColor());
8848 }
8849 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
8850 } else {
8851 ParseProgressMaskResObj(jColor, colorVal, progressMask);
8852 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
8853 }
8854 }
8855
JsMask(const JSCallbackInfo & info)8856 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
8857 {
8858 JSRef<JSVal> arg = info[0];
8859 if (!arg->IsObject()) {
8860 ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
8861 return;
8862 }
8863 auto paramObject = JSRef<JSObject>::Cast(arg);
8864 JSRef<JSVal> typeParam = paramObject->GetProperty("type");
8865 if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
8866 typeParam->ToString() == "ProgressMask") {
8867 ViewAbstractModel::GetInstance()->RemoveResObj("ProgressMask");
8868 ParseJsMaskProperty(paramObject);
8869 } else {
8870 ViewAbstractModel::GetInstance()->RemoveResObj("maskShape");
8871 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
8872 if (maskShape == nullptr) {
8873 return;
8874 };
8875 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
8876 }
8877 }
8878
JsMaskShape(const JSCallbackInfo & info)8879 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
8880 {
8881 if (!info[0]->IsObject()) {
8882 return;
8883 }
8884
8885 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
8886 if (maskShape == nullptr) {
8887 return;
8888 };
8889 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
8890 }
8891
JsFocusable(const JSCallbackInfo & info)8892 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
8893 {
8894 if (!info[0]->IsBoolean()) {
8895 return;
8896 }
8897 ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
8898 }
8899
JsTabStop(const JSCallbackInfo & info)8900 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
8901 {
8902 if (!info[0]->IsBoolean()) {
8903 ViewAbstractModel::GetInstance()->SetTabStop(false);
8904 return;
8905 }
8906 ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
8907 }
8908
JsNextFocus(const JSCallbackInfo & info)8909 void JSViewAbstract::JsNextFocus(const JSCallbackInfo& info)
8910 {
8911 ViewAbstractModel::GetInstance()->ResetNextFocus();
8912 if (info.Length() == 1 && info[0]->IsObject()) {
8913 auto obj = JSRef<JSObject>::Cast(info[0]);
8914 auto forward = obj->GetPropertyValue<std::string>("forward", "");
8915 if (!forward.empty()) {
8916 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::TAB, forward);
8917 }
8918 auto backward = obj->GetPropertyValue<std::string>("backward", "");
8919 if (!backward.empty()) {
8920 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::SHIFT_TAB, backward);
8921 }
8922 auto up = obj->GetPropertyValue<std::string>("up", "");
8923 if (!up.empty()) {
8924 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::UP, up);
8925 }
8926 auto down = obj->GetPropertyValue<std::string>("down", "");
8927 if (!down.empty()) {
8928 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::DOWN, down);
8929 }
8930 auto left = obj->GetPropertyValue<std::string>("left", "");
8931 if (!left.empty()) {
8932 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::LEFT, left);
8933 }
8934 auto right = obj->GetPropertyValue<std::string>("right", "");
8935 if (!right.empty()) {
8936 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::RIGHT, right);
8937 }
8938 }
8939 }
8940
JsFocusBox(const JSCallbackInfo & info)8941 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
8942 {
8943 if (!info[0]->IsObject() || info.Length() != 1) {
8944 return;
8945 }
8946 auto obj = JSRef<JSObject>::Cast(info[0]);
8947 NG::FocusBoxStyle style;
8948
8949 CalcDimension margin;
8950 RefPtr<ResourceObject> resObjMargin;
8951 if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin, resObjMargin)) {
8952 ViewAbstractModel::GetInstance()->SetFocusBoxStyleUpdateFunc(style, resObjMargin, "focusBoxStyleMargin");
8953 style.margin = margin;
8954 }
8955 CalcDimension strokeWidth;
8956 RefPtr<ResourceObject> resObjWidth;
8957 if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth, resObjWidth)) {
8958 ViewAbstractModel::GetInstance()->SetFocusBoxStyleUpdateFunc(style, resObjWidth, "focusBoxStyleWidth");
8959 style.strokeWidth = strokeWidth;
8960 }
8961 Color strokeColor;
8962 RefPtr<ResourceObject> resObjColor;
8963 if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor, resObjColor)) {
8964 CompleteResourceObjectFromColor(resObjColor, strokeColor, true);
8965 ViewAbstractModel::GetInstance()->SetFocusBoxStyleUpdateFunc(style, resObjColor, "focusBoxStyleColor");
8966 style.strokeColor = strokeColor;
8967 }
8968
8969 ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
8970 }
8971
JsOnFocusMove(const JSCallbackInfo & args)8972 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
8973 {
8974 JSRef<JSVal> arg = args[0];
8975 if (arg->IsFunction()) {
8976 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
8977 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8978 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
8979 int info) {
8980 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8981 ACE_SCORING_EVENT("onFocusMove");
8982 PipelineContext::SetCallBackNode(node);
8983 func->Execute(info);
8984 };
8985 ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
8986 }
8987 }
8988
JsOnKeyEvent(const JSCallbackInfo & args)8989 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
8990 {
8991 JSRef<JSVal> arg = args[0];
8992 if (arg->IsUndefined() && IsDisableEventVersion()) {
8993 ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
8994 return;
8995 }
8996 if (!arg->IsFunction()) {
8997 return;
8998 }
8999 RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
9000 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9001 auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
9002 KeyEventInfo& info) -> bool {
9003 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
9004 ACE_SCORING_EVENT("onKey");
9005 PipelineContext::SetCallBackNode(node);
9006 auto ret = func->ExecuteWithValue(info);
9007 return ret->IsBoolean() ? ret->ToBoolean() : false;
9008 };
9009 ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
9010 }
9011
JsDispatchKeyEvent(const JSCallbackInfo & args)9012 void JSViewAbstract::JsDispatchKeyEvent(const JSCallbackInfo& args)
9013 {
9014 JSRef<JSVal> arg = args[0];
9015 if (!(arg->IsNumber() || arg->IsString())) {
9016 return;
9017 }
9018 RefPtr<NG::FrameNode> frameNode = nullptr;
9019 if (arg->IsString()) {
9020 std::string id = arg->ToString();
9021 frameNode = NG::Inspector::GetFrameNodeByKey(id);
9022 }
9023
9024 if (arg->IsNumber()) {
9025 auto id = arg->ToNumber<int32_t>();
9026 auto node = ElementRegister::GetInstance()->GetNodeById(id);
9027 frameNode = AceType::DynamicCast<NG::FrameNode>(node);
9028 }
9029 CHECK_NULL_VOID(frameNode);
9030 auto focusHub = frameNode->GetOrCreateFocusHub();
9031 CHECK_NULL_VOID(focusHub);
9032
9033 if (!(args[1]->IsObject())) {
9034 return;
9035 }
9036 JSRef<JSObject> jsObject = JSRef<JSObject>::Cast(args[1]);
9037 auto eventInfoPtr = jsObject->Unwrap<KeyEventInfo>();
9038 CHECK_NULL_VOID(eventInfoPtr);
9039 KeyEvent keyEvent;
9040 eventInfoPtr->ParseKeyEvent(keyEvent);
9041 auto result = focusHub->HandleEvent(keyEvent);
9042 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
9043 }
9044
JsOnCrownEvent(const JSCallbackInfo & args)9045 void JSViewAbstract::JsOnCrownEvent(const JSCallbackInfo& args)
9046 {
9047 #ifdef SUPPORT_DIGITAL_CROWN
9048 if (args.Length() <= 0) {
9049 return;
9050 }
9051 if (args[0]->IsFunction()) {
9052 RefPtr<JsCrownFunction> JsOnCrownEventfunc = AceType::MakeRefPtr<JsCrownFunction>(JSRef<JSFunc>::Cast(args[0]));
9053 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->
9054 GetMainFrameNode());
9055 auto onCrownEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnCrownEventfunc),
9056 node = frameNode](CrownEventInfo& info) {
9057 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9058 ACE_SCORING_EVENT("onCrown");
9059 PipelineContext::SetCallBackNode(node);
9060 func->Execute(info);
9061 };
9062 ViewAbstractModel::GetInstance()->SetOnCrownEvent(std::move(onCrownEvent));
9063 } else {
9064 ViewAbstractModel::GetInstance()->DisableOnCrownEvent();
9065 }
9066 #endif
9067 }
9068
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle)9069 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args, NG::SheetStyle& sheetStyle)
9070 {
9071 RefPtr<ResourceObject> resObj;
9072 ParseBindSheetBorderRadius(args, sheetStyle, resObj);
9073 }
9074
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle,RefPtr<ResourceObject> & resourceObj)9075 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args,
9076 NG::SheetStyle& sheetStyle, RefPtr<ResourceObject>& resourceObj)
9077 {
9078 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
9079 TAG_LOGE(AceLogTag::ACE_SHEET, "radius is not correct type");
9080 return;
9081 }
9082 CalcDimension radius;
9083 NG::BorderRadiusProperty borderRadius;
9084 if (ParseJsLengthMetricsVpWithResObj(args, radius, resourceObj)) {
9085 borderRadius.SetRadius(radius);
9086
9087 // multiValued: indicates whether to set multiple directions. The default value is false.
9088 borderRadius.multiValued = false;
9089 sheetStyle.radius = borderRadius;
9090 } else if (ParseBindSheetBorderRadiusProps(args, borderRadius)) {
9091 sheetStyle.radius = borderRadius;
9092 } else {
9093 TAG_LOGW(AceLogTag::ACE_SHEET, "radius is not correct.");
9094 return;
9095 }
9096 }
9097
ParseBindSheetBorderRadiusProps(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)9098 bool JSViewAbstract::ParseBindSheetBorderRadiusProps(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
9099 {
9100 if (args->IsObject()) {
9101 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
9102 if (CheckLengthMetrics(object)) {
9103 RefPtr<ResourceObject> topStartResObj;
9104 std::optional<CalcDimension> radiusTopStart =
9105 ParseBindSheetBorderRadiusProp(object, TOP_START_PROPERTY, topStartResObj);
9106 RefPtr<ResourceObject> topEndResObj;
9107 std::optional<CalcDimension> radiusTopEnd =
9108 ParseBindSheetBorderRadiusProp(object, TOP_END_PROPERTY, topEndResObj);
9109 RefPtr<ResourceObject> bottomStartResObj;
9110 std::optional<CalcDimension> radiusBottomStart =
9111 ParseBindSheetBorderRadiusProp(object, BOTTOM_START_PROPERTY, bottomStartResObj);
9112 RefPtr<ResourceObject> bottomEndResObj;
9113 std::optional<CalcDimension> radiusBottomEnd =
9114 ParseBindSheetBorderRadiusProp(object, BOTTOM_END_PROPERTY, bottomEndResObj);
9115 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
9116 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
9117 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
9118 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
9119 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
9120 radius.multiValued = true;
9121 if (isRightToLeft) {
9122 RegisterRadiusRes(radius, topEndResObj, topStartResObj, bottomEndResObj, bottomStartResObj);
9123 } else {
9124 RegisterRadiusRes(radius, topStartResObj, topEndResObj, bottomStartResObj, bottomEndResObj);
9125 }
9126 } else {
9127 ParseBorderRadiusProps(object, radius);
9128 }
9129 return true;
9130 }
9131 return false;
9132 }
9133
ParseBindSheetBorderRadiusProp(const JSRef<JSObject> & object,const char * prop,RefPtr<ResourceObject> & resourceObj)9134 std::optional<CalcDimension> JSViewAbstract::ParseBindSheetBorderRadiusProp(
9135 const JSRef<JSObject>& object, const char* prop, RefPtr<ResourceObject>& resourceObj)
9136 {
9137 if (object->IsEmpty()) {
9138 return std::nullopt;
9139 }
9140 if (object->HasProperty(prop) && object->GetProperty(prop)->IsObject()) {
9141 JSRef<JSObject> propObj = JSRef<JSObject>::Cast(object->GetProperty(prop));
9142 CalcDimension calcDimension;
9143 if (ParseJsLengthMetricsVpWithResObj(propObj, calcDimension, resourceObj)) {
9144 return calcDimension;
9145 }
9146 }
9147 return std::nullopt;
9148 }
9149
JSCreateAnimatableProperty(const JSCallbackInfo & info)9150 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
9151 {
9152 if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
9153 return;
9154 }
9155
9156 JSRef<JSVal> callback = info[2]; /* 2:args index */
9157 if (!callback->IsFunction()) {
9158 return;
9159 }
9160 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9161 std::string propertyName = info[0]->ToString();
9162 if (info[1]->IsNumber()) {
9163 float numValue = info[1]->ToNumber<float>();
9164 std::function<void(float)> onCallbackEvent;
9165 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
9166 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
9167 node = frameNode](const float val) {
9168 ContainerScope scope(id);
9169 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9170 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
9171 PipelineContext::SetCallBackNode(node);
9172 func->ExecuteJS(1, &newJSVal);
9173 };
9174 ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
9175 } else if (info[1]->IsObject()) {
9176 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
9177 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
9178 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
9179 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
9180 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
9181 std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
9182 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
9183 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
9184 node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
9185 ContainerScope scope(id);
9186 RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
9187 if (!impl) {
9188 return;
9189 }
9190 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9191 auto newJSVal = JSRef<JSVal>(impl->GetObject());
9192 PipelineContext::SetCallBackNode(node);
9193 func->ExecuteJS(1, &newJSVal);
9194 };
9195 ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
9196 propertyName, animatableArithmetic, onCallbackEvent);
9197 }
9198 }
9199
JSUpdateAnimatableProperty(const JSCallbackInfo & info)9200 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
9201 {
9202 if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
9203 return;
9204 }
9205
9206 std::string propertyName = info[0]->ToString();
9207 float numValue = 0.0;
9208 if (info[1]->IsNumber()) {
9209 numValue = info[1]->ToNumber<float>();
9210 ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
9211 } else if (info[1]->IsObject()) {
9212 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
9213 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
9214 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
9215 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
9216 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
9217 ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
9218 }
9219 }
9220
JsExpandSafeArea(const JSCallbackInfo & info)9221 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
9222 {
9223 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
9224 if (info.Length() >= PARAMETER_LENGTH_FIRST && info[0]->IsArray()) {
9225 auto paramArray = JSRef<JSArray>::Cast(info[0]);
9226 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
9227 for (size_t i = 0; i < paramArray->Length(); ++i) {
9228 if (!paramArray->GetValueAt(i)->IsNumber() ||
9229 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
9230 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
9231 break;
9232 }
9233 safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9234 }
9235 opts.type = safeAreaType;
9236 }
9237 if (info.Length() >= 2 && info[1]->IsArray()) {
9238 auto paramArray = JSRef<JSArray>::Cast(info[1]);
9239 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
9240 for (size_t i = 0; i < paramArray->Length(); ++i) {
9241 if (!paramArray->GetValueAt(i)->IsNumber() ||
9242 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
9243 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
9244 break;
9245 }
9246 safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9247 }
9248 opts.edges = safeAreaEdge;
9249 }
9250
9251 ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
9252 }
9253
JsIgnoreLayoutSafeArea(const JSCallbackInfo & info)9254 void JSViewAbstract::JsIgnoreLayoutSafeArea(const JSCallbackInfo& info)
9255 {
9256 NG::IgnoreLayoutSafeAreaOpts opts { .type = NG::LAYOUT_SAFE_AREA_TYPE_SYSTEM, .rawEdges = NG::LAYOUT_SAFE_AREA_EDGE_ALL };
9257 if (info.Length() >= PARAMETER_LENGTH_FIRST && info[0]->IsArray()) {
9258 auto paramArray = JSRef<JSArray>::Cast(info[0]);
9259 uint32_t layoutSafeAreaType = NG::LAYOUT_SAFE_AREA_TYPE_NONE;
9260 for (size_t i = 0; i < paramArray->Length(); ++i) {
9261 if (!paramArray->GetValueAt(i)->IsNumber() ||
9262 paramArray->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_TYPE_LIMIT) {
9263 layoutSafeAreaType = NG::SAFE_AREA_TYPE_SYSTEM;
9264 break;
9265 }
9266 layoutSafeAreaType |= NG::IgnoreLayoutSafeAreaOpts::TypeToMask(paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9267 }
9268 opts.type = layoutSafeAreaType;
9269 }
9270 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsArray()) {
9271 auto paramArray = JSRef<JSArray>::Cast(info[1]);
9272 uint32_t layoutSafeAreaEdge = NG::LAYOUT_SAFE_AREA_EDGE_NONE;
9273 for (size_t i = 0; i < paramArray->Length(); ++i) {
9274 if (!paramArray->GetValueAt(i)->IsNumber() ||
9275 paramArray->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_EDGE_LIMIT) {
9276 layoutSafeAreaEdge = NG::LAYOUT_SAFE_AREA_EDGE_ALL;
9277 break;
9278 }
9279 layoutSafeAreaEdge |=
9280 NG::IgnoreLayoutSafeAreaOpts::EdgeToMask(paramArray->GetValueAt(i)->ToNumber<uint32_t>());
9281 }
9282 opts.rawEdges = layoutSafeAreaEdge;
9283 }
9284
9285 ViewAbstractModel::GetInstance()->UpdateIgnoreLayoutSafeAreaOpts(opts);
9286 }
9287
ParseJSLightSource(JSRef<JSObject> & lightSource)9288 void ParseJSLightSource(JSRef<JSObject>& lightSource)
9289 {
9290 if (lightSource->IsUndefined()) {
9291 return;
9292 }
9293 JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
9294 JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
9295 JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
9296 JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
9297 JSRef<JSVal> color = lightSource->GetProperty("color");
9298
9299 CalcDimension dimPositionX;
9300 CalcDimension dimPositionY;
9301 CalcDimension dimPositionZ;
9302 if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
9303 JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
9304 JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
9305 ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
9306 }
9307
9308 if (intensity->IsNumber()) {
9309 float intensityValue = intensity->ToNumber<float>();
9310 ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
9311 }
9312
9313 Color lightColor;
9314 if (JSViewAbstract::ParseJsColor(color, lightColor)) {
9315 ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
9316 }
9317 }
9318
ParseJSLightSourcePositionX(const JSRef<JSObject> & lightSource,NG::TranslateOptions & option)9319 void ParseJSLightSourcePositionX(const JSRef<JSObject>& lightSource, NG::TranslateOptions& option)
9320 {
9321 JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
9322 CalcDimension dimPositionX;
9323 RefPtr<ResourceObject> dimPositionXResObj;
9324 if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX, dimPositionXResObj)) {
9325 option.x = dimPositionX;
9326 }
9327 if (dimPositionXResObj) {
9328 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::TranslateOptions& option) {
9329 CalcDimension dimension;
9330 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
9331 option.x = dimension;
9332 };
9333 option.AddResource("pointLight.LightSource.PositionX", dimPositionXResObj, std::move(updateFunc));
9334 }
9335 }
9336
ParseJSLightSourcePositionY(const JSRef<JSObject> & lightSource,NG::TranslateOptions & option)9337 void ParseJSLightSourcePositionY(const JSRef<JSObject>& lightSource, NG::TranslateOptions& option)
9338 {
9339 JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
9340 CalcDimension dimPositionY;
9341 RefPtr<ResourceObject> dimPositionYResObj;
9342 if (JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY, dimPositionYResObj)) {
9343 option.y = dimPositionY;
9344 }
9345 if (dimPositionYResObj) {
9346 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::TranslateOptions& option) {
9347 CalcDimension dimension;
9348 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
9349 option.y = dimension;
9350 };
9351 option.AddResource("pointLight.LightSource.PositionY", dimPositionYResObj, std::move(updateFunc));
9352 }
9353 }
9354
ParseJSLightSourcePositionZ(const JSRef<JSObject> & lightSource,NG::TranslateOptions & option)9355 void ParseJSLightSourcePositionZ(const JSRef<JSObject>& lightSource, NG::TranslateOptions& option)
9356 {
9357 JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
9358 CalcDimension dimPositionZ;
9359 RefPtr<ResourceObject> dimPositionZResObj;
9360 if (JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ, dimPositionZResObj)) {
9361 option.z = dimPositionZ;
9362 }
9363 if (dimPositionZResObj) {
9364 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::TranslateOptions& option) {
9365 CalcDimension dimension;
9366 ResourceParseUtils::ParseResDimensionVp(resObj, dimension);
9367 option.z = dimension;
9368 };
9369 option.AddResource("pointLight.LightSource.PositionZ", dimPositionZResObj, std::move(updateFunc));
9370 }
9371
9372 }
9373
ParseJSLightSourceNew(JSRef<JSObject> & lightSource)9374 void ParseJSLightSourceNew(JSRef<JSObject>& lightSource)
9375 {
9376 if (lightSource->IsUndefined()) {
9377 return;
9378 }
9379 JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
9380 JSRef<JSVal> color = lightSource->GetProperty("color");
9381
9382 NG::TranslateOptions option;
9383 ParseJSLightSourcePositionX(lightSource, option);
9384 ParseJSLightSourcePositionY(lightSource, option);
9385 ParseJSLightSourcePositionZ(lightSource, option);
9386 ViewAbstractModel::GetInstance()->SetLightPosition(option);
9387
9388 if (intensity->IsNumber()) {
9389 float intensityValue = intensity->ToNumber<float>();
9390 ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
9391 }
9392
9393 Color lightColor;
9394 RefPtr<ResourceObject> lightColorResObj;
9395 bool ret = JSViewAbstract::ParseJsColor(color, lightColor, lightColorResObj);
9396 if (lightColorResObj) {
9397 ViewAbstractModel::GetInstance()->CreateWithLightColorResourceObj(lightColorResObj);
9398 } else if (ret) {
9399 ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
9400 }
9401 }
9402
JsPointLight(const JSCallbackInfo & info)9403 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
9404 {
9405 #ifdef POINT_LIGHT_ENABLE
9406 if (!info[0]->IsObject()) {
9407 return;
9408 }
9409
9410 ViewAbstractModel::GetInstance()->RemoveResObj("LightColorRes");
9411 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
9412 JSRef<JSObject> lightSource = object->GetProperty("lightSource");
9413 if (!SystemProperties::ConfigChangePerform()) {
9414 ParseJSLightSource(lightSource);
9415 } else {
9416 ParseJSLightSourceNew(lightSource);
9417 }
9418
9419 auto resourceWrapper = CreateResourceWrapper();
9420 if (!resourceWrapper) {
9421 return;
9422 }
9423 double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
9424 Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
9425 Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
9426
9427 JSRef<JSVal> illuminated = object->GetProperty("illuminated");
9428 if (illuminated->IsNumber()) {
9429 uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
9430 ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
9431 ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
9432 }
9433
9434 JSRef<JSVal> bloom = object->GetProperty("bloom");
9435 if (bloom->IsNumber()) {
9436 float bloomValue = bloom->ToNumber<float>();
9437 ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
9438
9439 Shadow shadow;
9440 shadow.SetBlurRadius(bloomValue * bloomRadius);
9441 shadow.SetColor(bloomColor);
9442 std::vector<Shadow> shadows { shadow };
9443 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
9444 }
9445 #endif
9446 }
9447
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)9448 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
9449 {
9450 if (info[0]->IsBoolean()) {
9451 ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
9452 }
9453 }
9454
JsEnableDropDisallowedBadge(const JSCallbackInfo & info)9455 void JSViewAbstract::JsEnableDropDisallowedBadge(const JSCallbackInfo& info)
9456 {
9457 if (info[0]->IsBoolean()) {
9458 ViewAbstractModel::GetInstance()->EnableDropDisallowedBadge(info[0]->ToBoolean());
9459 }
9460 }
9461
JsNotifyDragStartRequest(const JSCallbackInfo & info)9462 void JSViewAbstract::JsNotifyDragStartRequest(const JSCallbackInfo& info)
9463 {
9464 if (info[0]->IsNumber()) {
9465 int32_t dragStatus = info[0]->ToNumber<int32_t>();
9466 ViewAbstractModel::GetInstance()->NotifyDragStartRequest(
9467 static_cast<DragStartRequestStatus>(dragStatus));
9468 }
9469 }
9470
JsCancelDataLoading(const std::string & key)9471 void JSViewAbstract::JsCancelDataLoading(const std::string& key)
9472 {
9473 if (key.empty()) {
9474 JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Invalid input parameter.");
9475 return;
9476 }
9477 auto ret = ViewAbstractModel::GetInstance()->CancelDataLoading(key);
9478 if (ret != 0) {
9479 JSException::Throw(ERROR_CODE_DRAG_OPERATION_FAILED, "%s", "Operation failed.");
9480 }
9481 }
9482
JSBind(BindingTarget globalObj)9483 void JSViewAbstract::JSBind(BindingTarget globalObj)
9484 {
9485 JSClass<JSViewAbstract>::Declare("JSViewAbstract");
9486
9487 // static methods
9488 MethodOptions opt = MethodOptions::NONE;
9489 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
9490
9491 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
9492 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
9493 JSClass<JSViewAbstract>::StaticMethod("toolbar", &JSViewAbstract::JsToolbar);
9494 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
9495 JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
9496 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
9497 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
9498 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
9499 JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSLayoutableView::JsPixelRound);
9500 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
9501 JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSLayoutableView::JsChainWeight);
9502
9503 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
9504 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
9505 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
9506 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
9507 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
9508
9509 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
9510 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
9511 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
9512 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
9513 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
9514 JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
9515
9516 JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
9517 JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
9518 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
9519 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
9520 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
9521 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
9522 JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
9523 JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
9524 JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
9525 JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
9526 JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
9527 JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
9528 JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
9529 JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
9530 JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
9531 JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
9532 JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
9533 JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
9534 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
9535 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
9536 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
9537 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
9538 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
9539 JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
9540
9541 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
9542 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
9543 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
9544 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
9545 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
9546 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
9547 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
9548 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
9549 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
9550 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
9551 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
9552 JSClass<JSViewAbstract>::StaticMethod("transform3D", &JSViewAbstract::JsTransform3D);
9553 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
9554
9555 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
9556 JSClass<JSViewAbstract>::StaticMethod("layoutGravity", &JSViewAbstract::JsLayoutGravity);
9557 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
9558 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
9559 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
9560 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
9561 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
9562 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
9563
9564 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
9565 JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
9566 JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
9567 JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
9568 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
9569 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
9570 JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
9571 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
9572 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal", &JSViewAbstract::JsBackgroundBrightnessInternal);
9573 JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
9574 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
9575 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
9576 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
9577 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
9578 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
9579 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
9580 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
9581 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
9582 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
9583 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
9584 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
9585 #ifndef WEARABLE_PRODUCT
9586 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
9587 JSClass<JSViewAbstract>::StaticMethod("bindTips", &JSViewAbstract::JsBindTips);
9588 #endif
9589
9590 JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
9591 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
9592 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
9593 JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
9594 JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
9595 JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
9596 JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
9597 JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
9598 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
9599 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
9600 JSClass<JSViewAbstract>::StaticMethod("onDragSpringLoading", &JSViewAbstract::JsOnDragSpringLoading);
9601 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
9602 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
9603 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
9604 JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
9605
9606 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
9607 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
9608 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
9609 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
9610 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
9611 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
9612 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
9613 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
9614 JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
9615 JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
9616 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
9617 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
9618 JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
9619 JSClass<JSViewAbstract>::StaticMethod("nextFocus", &JSViewAbstract::JsNextFocus);
9620 JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
9621 JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
9622 JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
9623 JSClass<JSViewAbstract>::StaticMethod("onKeyEventDispatch", &JSInteractableView::JsOnKeyEventDispatch);
9624 JSClass<JSViewAbstract>::StaticMethod("dispatchKeyEvent", &JSViewAbstract::JsDispatchKeyEvent);
9625 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
9626 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
9627 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
9628 JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
9629 JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
9630 JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
9631 JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
9632 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
9633 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
9634 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
9635 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
9636 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
9637 JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
9638 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
9639 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
9640 JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
9641 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
9642 JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
9643 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
9644 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
9645 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
9646 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
9647 JSClass<JSViewAbstract>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
9648 JSClass<JSViewAbstract>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
9649 JSClass<JSViewAbstract>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
9650 JSClass<JSViewAbstract>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
9651 JSClass<JSViewAbstract>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
9652 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
9653 JSClass<JSViewAbstract>::StaticMethod("onAxisEvent", &JSViewAbstract::JsOnAxisEvent);
9654 JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
9655 JSClass<JSViewAbstract>::StaticMethod("onHoverMove", &JSViewAbstract::JsOnHoverMove);
9656 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
9657 JSClass<JSViewAbstract>::StaticMethod("onDigitalCrown", &JSViewAbstract::JsOnCrownEvent);
9658 JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
9659 JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
9660 JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
9661 JSClass<JSViewAbstract>::StaticMethod(
9662 "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
9663 JSClass<JSViewAbstract>::StaticMethod(
9664 "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
9665 JSClass<JSViewAbstract>::StaticMethod("onTouchTestDone", &JSViewAbstract::JsOnTouchTestDone);
9666 JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
9667 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
9668 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
9669 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
9670 JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
9671 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
9672 JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
9673 JSClass<JSViewAbstract>::StaticMethod("onFocusAxisEvent", &JSViewAbstract::JsOnFocusAxisEvent);
9674
9675 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
9676 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
9677 JSClass<JSViewAbstract>::StaticMethod("accessibilityNextFocusId", &JSViewAbstract::JsAccessibilityNextFocusId);
9678 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
9679 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
9680 JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
9681 JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
9682 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
9683 JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
9684 JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
9685 JSClass<JSViewAbstract>::StaticMethod("accessibilityRole", &JSViewAbstract::JsAccessibilityRole);
9686 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityFocus", &JSViewAbstract::JsOnAccessibilityFocus);
9687 JSClass<JSViewAbstract>::StaticMethod("accessibilityDefaultFocus", &JSViewAbstract::JsAccessibilityDefaultFocus);
9688 JSClass<JSViewAbstract>::StaticMethod("accessibilityUseSamePage", &JSViewAbstract::JsAccessibilityUseSamePage);
9689 JSClass<JSViewAbstract>::StaticMethod("accessibilityScrollTriggerable",
9690 &JSViewAbstract::JsAccessibilityScrollTriggerable);
9691 JSClass<JSViewAbstract>::StaticMethod("accessibilityFocusDrawLevel",
9692 &JSViewAbstract::JsAccessibilityFocusDrawLevel);
9693 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityActionIntercept",
9694 &JSViewAbstract::JsOnAccessibilityActionIntercept);
9695 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHoverTransparent",
9696 &JSViewAbstract::JsOnAccessibilityHoverTransparent);
9697
9698 JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
9699 JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
9700 JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
9701 JSClass<JSViewAbstract>::StaticMethod(
9702 "onVisibleAreaApproximateChange", &JSViewAbstract::JsOnVisibleAreaApproximateChange);
9703 JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
9704 JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
9705 JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
9706 JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
9707 JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
9708 JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
9709 JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
9710 JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
9711
9712 JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
9713 JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
9714 JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
9715 JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
9716
9717 JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
9718
9719 JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
9720 JSClass<JSViewAbstract>::StaticMethod("ignoreLayoutSafeArea", &JSViewAbstract::JsIgnoreLayoutSafeArea);
9721
9722 JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
9723 JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
9724 JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
9725 JSClass<JSViewAbstract>::StaticMethod("notifyDragStartRequest", &JSViewAbstract::JsNotifyDragStartRequest);
9726 JSClass<JSViewAbstract>::StaticMethod(
9727 "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
9728 JSClass<JSViewAbstract>::StaticMethod(
9729 "enableDropDisallowedBadge", &JSViewAbstract::JsEnableDropDisallowedBadge);
9730 JSClass<JSViewAbstract>::StaticMethod("cancelDataLoading", &JSViewAbstract::JsCancelDataLoading);
9731
9732 JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
9733 JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
9734
9735 JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
9736 JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
9737 JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
9738 JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
9739
9740 JSClass<JSViewAbstract>::StaticMethod("setPixelRoundMode", &JSViewAbstract::SetPixelRoundMode);
9741 JSClass<JSViewAbstract>::StaticMethod("getPixelRoundMode", &JSViewAbstract::GetPixelRoundMode);
9742
9743 JSClass<JSViewAbstract>::Bind(globalObj);
9744 }
9745
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)9746 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
9747 {
9748 auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
9749 auto vm = info->GetVM();
9750 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
9751 Local<JSValueRef> thisObj = info->GetFunctionRef();
9752 auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
9753 if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
9754 return panda::JSValueRef::Undefined(vm);
9755 }
9756
9757 auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
9758 if (weak->Invalid()) {
9759 return panda::JSValueRef::Undefined(vm);
9760 }
9761
9762 auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
9763 if (frameNode) {
9764 const auto& extensionHandler = frameNode->GetExtensionHandler();
9765 if (extensionHandler) {
9766 extensionHandler->InvalidateRender();
9767 extensionHandler->ForegroundRender();
9768 } else {
9769 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9770 }
9771 }
9772
9773 return panda::JSValueRef::Undefined(vm);
9774 };
9775 auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
9776 if (frameNode) {
9777 const auto& extensionHandler = frameNode->GetExtensionHandler();
9778 if (extensionHandler) {
9779 extensionHandler->InvalidateRender();
9780 extensionHandler->ForegroundRender();
9781 } else {
9782 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9783 }
9784 }
9785 auto vm = jsInvalidate->GetEcmaVM();
9786 auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
9787 jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
9788 jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
9789 jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
9790 }
9791
JsDrawModifier(const JSCallbackInfo & info)9792 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
9793 {
9794 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWENTY) && !info[0]->IsObject()) {
9795 return;
9796 }
9797
9798 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9799 bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
9800 if (!IsSupportDrawModifier) {
9801 return;
9802 }
9803 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWENTY) && !info[0]->IsObject()) {
9804 ViewAbstractModel::GetInstance()->SetDrawModifier(nullptr);
9805 if (frameNode) {
9806 const auto& extensionHandler = frameNode->GetExtensionHandler();
9807 if (extensionHandler) {
9808 extensionHandler->InvalidateRender();
9809 extensionHandler->ForegroundRender();
9810 } else {
9811 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9812 }
9813 }
9814 return;
9815 }
9816 auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
9817 RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
9818 auto execCtx = info.GetExecutionContext();
9819 auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
9820 JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
9821 if (!drawMethod->IsFunction()) {
9822 return nullptr;
9823 }
9824
9825 auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
9826 JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
9827
9828 return GetDrawCallback(jsDrawFunc, execCtx, jsDrawModifier);
9829 };
9830
9831 drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
9832 drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
9833 drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
9834 drawModifier->drawForegroundFunc = getDrawModifierFunc("drawForeground");
9835
9836 ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
9837 AddInvalidateFunc(jsDrawModifier, frameNode);
9838 }
9839
JsAllowDrop(const JSCallbackInfo & info)9840 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
9841 {
9842 std::set<std::string> allowDropSet;
9843 allowDropSet.clear();
9844 if (!info[0]->IsUndefined() && info[0]->IsArray()) {
9845 auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
9846 std::string allowDrop;
9847 for (size_t i = 0; i < allowDropArray->Length(); i++) {
9848 allowDrop = allowDropArray->GetValueAt(i)->ToString();
9849 allowDropSet.insert(allowDrop);
9850 }
9851 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9852 } else if (info[0]->IsNull()) {
9853 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
9854 } else {
9855 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9856 }
9857 ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
9858 }
9859
JsOnPreDrag(const JSCallbackInfo & info)9860 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
9861 {
9862 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
9863 auto jsVal = info[0];
9864 if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
9865 return;
9866 }
9867
9868 RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
9869 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9870 auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
9871 const PreDragStatus preDragStatus) {
9872 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9873 ACE_SCORING_EVENT("onPreDrag");
9874 PipelineContext::SetCallBackNode(node);
9875 func->PreDragExecute(preDragStatus);
9876 };
9877 ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
9878 }
9879
ParseDragPreviewConfig(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9880 void JSViewAbstract::ParseDragPreviewConfig(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9881 {
9882 if (info.Length() <= 1) {
9883 return;
9884 }
9885 auto jsVal = info[1];
9886 if (!jsVal->IsObject()) {
9887 return;
9888 }
9889 auto config = JSRef<JSObject>::Cast(jsVal);
9890 ParseJsBool(config->GetProperty("onlyForLifting"), dragPreviewInfo.onlyForLifting);
9891 ParseJsBool(config->GetProperty("delayCreating"), dragPreviewInfo.delayCreating);
9892 }
9893
ParseDragPreviewValue(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9894 void JSViewAbstract::ParseDragPreviewValue(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9895 {
9896 auto jsVal = info[0];
9897 JSRef<JSVal> builder;
9898 JSRef<JSVal> pixelMap;
9899 JSRef<JSVal> extraInfo;
9900 if (jsVal->IsFunction()) {
9901 builder = jsVal;
9902 } else if (jsVal->IsObject()) {
9903 auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
9904 builder = dragItemInfo->GetProperty("builder");
9905 #if defined(PIXEL_MAP_SUPPORTED)
9906 pixelMap = dragItemInfo->GetProperty("pixelMap");
9907 dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
9908 #endif
9909 extraInfo = dragItemInfo->GetProperty("extraInfo");
9910 ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
9911 } else if (jsVal->IsString()) {
9912 auto inspectorId = jsVal;
9913 ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
9914 } else {
9915 return;
9916 }
9917 ParseDragPreviewBuilderNode(info, dragPreviewInfo, builder);
9918 }
9919
ParseDragPreviewBuilderNode(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo,const JSRef<JSVal> & builder)9920 void JSViewAbstract::ParseDragPreviewBuilderNode(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo,
9921 const JSRef<JSVal>& builder)
9922 {
9923 if (!builder->IsFunction()) {
9924 return;
9925 }
9926 RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9927 CHECK_NULL_VOID(builderFunc);
9928 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9929 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
9930 node = frameNode]() -> RefPtr<NG::UINode> {
9931 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
9932 ACE_SCORING_EVENT("dragPreview.builder");
9933 PipelineContext::SetCallBackNode(node);
9934 func->Execute();
9935 auto customNode = ViewStackModel::GetInstance()->Finish();
9936 return AceType::DynamicCast<NG::UINode>(customNode);
9937 };
9938 if (!dragPreviewInfo.delayCreating) {
9939 ViewStackModel::GetInstance()->NewScope();
9940 {
9941 dragPreviewInfo.customNode = buildFunc();
9942 }
9943 } else {
9944 dragPreviewInfo.buildFunc = buildFunc;
9945 }
9946 }
9947
JsDragPreview(const JSCallbackInfo & info)9948 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
9949 {
9950 auto jsVal = info[0];
9951 if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
9952 return;
9953 }
9954 NG::DragDropInfo dragPreviewInfo;
9955 ParseDragPreviewConfig(info, dragPreviewInfo);
9956 ParseDragPreviewValue(info, dragPreviewInfo);
9957 ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
9958 }
9959
JsAlignRules(const JSCallbackInfo & info)9960 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
9961 {
9962 if (!info[0]->IsObject()) {
9963 return;
9964 }
9965
9966 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
9967 if (valueObj->IsEmpty()) {
9968 return;
9969 }
9970 const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
9971 std::map<AlignDirection, AlignRule> alignRules;
9972 BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
9973 for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
9974 auto rule = valueObj->GetProperty(keys[i]);
9975 if (rule->IsObject()) {
9976 JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
9977 JSRef<JSVal> align = val->GetProperty("align");
9978 AlignRule alignRule;
9979 alignRule.anchor = val->GetProperty("anchor")->ToString();
9980 if (i < HORIZONTAL_DIRECTION_RANGE) {
9981 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9982 } else {
9983 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9984 }
9985 if (i < VERTICAL_DIRECTION_RANGE) {
9986 alignRules[static_cast<AlignDirection>(i)] = alignRule;
9987 } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
9988 alignRules[AlignDirection::LEFT] = alignRule;
9989 } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
9990 alignRules[AlignDirection::RIGHT] = alignRule;
9991 }
9992 auto biasX = val->GetProperty("horizontal");
9993 if (biasX->IsNumber()) {
9994 biasPair.first = biasX->ToNumber<float>();
9995 }
9996 auto biasY = val->GetProperty("vertical");
9997 if (biasY->IsNumber()) {
9998 biasPair.second = biasY->ToNumber<float>();
9999 }
10000 }
10001 }
10002
10003 ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
10004 ViewAbstractModel::GetInstance()->SetBias(biasPair);
10005 }
10006
JsChainMode(const JSCallbackInfo & info)10007 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
10008 {
10009 ChainInfo chainInfo;
10010 if (info.Length() >= 1) {
10011 auto tmpDirection = info[0];
10012 if (tmpDirection->IsUndefined()) {
10013 chainInfo.direction = std::nullopt;
10014 } else if (tmpDirection->IsNumber()) {
10015 auto direction = tmpDirection->ToNumber<int32_t>();
10016 chainInfo.direction = static_cast<LineDirection>(direction);
10017 }
10018 }
10019
10020 if (info.Length() >= 2) { // 2 : two args
10021 auto tmpStyle = info[1];
10022 if (tmpStyle->IsUndefined()) {
10023 chainInfo.style = std::nullopt;
10024 } else if (tmpStyle->IsNumber()) {
10025 auto style = tmpStyle->ToNumber<int32_t>();
10026 chainInfo.style = static_cast<ChainStyle>(style);
10027 }
10028 }
10029 ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
10030 }
10031
SetMarginTop(const JSCallbackInfo & info)10032 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
10033 {
10034 CalcDimension value;
10035 if (!ParseJsDimensionVp(info[0], value)) {
10036 return;
10037 }
10038 ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
10039 }
10040
SetMarginBottom(const JSCallbackInfo & info)10041 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
10042 {
10043 CalcDimension value;
10044 if (!ParseJsDimensionVp(info[0], value)) {
10045 return;
10046 }
10047 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
10048 }
10049
SetMarginLeft(const JSCallbackInfo & info)10050 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
10051 {
10052 CalcDimension value;
10053 if (!ParseJsDimensionVp(info[0], value)) {
10054 return;
10055 }
10056 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
10057 }
10058
SetMarginRight(const JSCallbackInfo & info)10059 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
10060 {
10061 CalcDimension value;
10062 if (!ParseJsDimensionVp(info[0], value)) {
10063 return;
10064 }
10065 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
10066 }
10067
SetPaddingTop(const JSCallbackInfo & info)10068 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
10069 {
10070 CalcDimension value;
10071 if (!ParseJsDimensionVp(info[0], value)) {
10072 return;
10073 }
10074 ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
10075 }
10076
SetPaddingBottom(const JSCallbackInfo & info)10077 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
10078 {
10079 CalcDimension value;
10080 if (!ParseJsDimensionVp(info[0], value)) {
10081 return;
10082 }
10083 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
10084 }
10085
SetPaddingLeft(const JSCallbackInfo & info)10086 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
10087 {
10088 CalcDimension value;
10089 if (!ParseJsDimensionVp(info[0], value)) {
10090 return;
10091 }
10092 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
10093 }
10094
SetPaddingRight(const JSCallbackInfo & info)10095 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
10096 {
10097 CalcDimension value;
10098 if (!ParseJsDimensionVp(info[0], value)) {
10099 return;
10100 }
10101 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
10102 }
10103
SetSafeAreaPadding(const JSCallbackInfo & info)10104 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
10105 {
10106 ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
10107 }
10108
SetColorBlend(Color color)10109 void JSViewAbstract::SetColorBlend(Color color)
10110 {
10111 ViewAbstractModel::GetInstance()->SetColorBlend(color);
10112 }
10113
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)10114 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
10115 {
10116 ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
10117 }
10118
SetDynamicLightUp(float rate,float lightUpDegree)10119 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
10120 {
10121 ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
10122 }
10123
SetBgDynamicBrightness(BrightnessOption brightnessOption)10124 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
10125 {
10126 ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
10127 }
10128
SetFgDynamicBrightness(BrightnessOption brightnessOption)10129 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
10130 {
10131 ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
10132 }
10133
SetWindowBlur(float progress,WindowBlurStyle blurStyle)10134 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
10135 {
10136 ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
10137 }
10138
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)10139 bool JSViewAbstract::ParseJsonDimension(
10140 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
10141 {
10142 if (!jsonValue || jsonValue->IsNull()) {
10143 return false;
10144 }
10145 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
10146 return false;
10147 }
10148 if (jsonValue->IsNumber()) {
10149 result = Dimension(jsonValue->GetDouble(), defaultUnit);
10150 return true;
10151 }
10152 if (jsonValue->IsString()) {
10153 if (checkIllegal) {
10154 return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
10155 }
10156 result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
10157 return true;
10158 }
10159 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
10160 auto resId = resVal->GetValue("id");
10161 if (!resId || !resId->IsNumber()) {
10162 return false;
10163 }
10164
10165 auto resourceWrapper = CreateResourceWrapper();
10166 if (!resourceWrapper) {
10167 return false;
10168 }
10169 result = resourceWrapper->GetDimension(resId->GetUInt());
10170 return true;
10171 }
10172
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)10173 bool JSViewAbstract::ParseJsonDimensionVp(
10174 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
10175 {
10176 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10177 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
10178 }
10179 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
10180 }
10181
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)10182 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
10183 {
10184 if (!jsonValue || jsonValue->IsNull()) {
10185 return false;
10186 }
10187 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
10188 return false;
10189 }
10190 if (jsonValue->IsNumber()) {
10191 result = jsonValue->GetDouble();
10192 return true;
10193 }
10194 if (jsonValue->IsString()) {
10195 result = StringUtils::StringToDouble(jsonValue->GetString());
10196 return true;
10197 }
10198 // parse json Resource
10199 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
10200 auto resId = resVal->GetValue("id");
10201 CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
10202 auto id = resId->GetUInt();
10203 auto resType = resVal->GetValue("type");
10204 CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
10205 auto type = resType->GetUInt();
10206
10207 auto resourceWrapper = CreateResourceWrapper();
10208 if (!resourceWrapper) {
10209 return false;
10210 }
10211 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
10212 auto numberString = resourceWrapper->GetString(id);
10213 return StringUtils::StringToDouble(numberString, result);
10214 }
10215 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
10216 result = resourceWrapper->GetInt(id);
10217 return true;
10218 }
10219 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
10220 result = resourceWrapper->GetDouble(id);
10221 return true;
10222 }
10223 return false;
10224 }
10225
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)10226 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
10227 {
10228 if (!jsonValue || jsonValue->IsNull()) {
10229 return false;
10230 }
10231 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
10232 return false;
10233 }
10234 if (jsonValue->IsNumber()) {
10235 result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
10236 return true;
10237 }
10238
10239 bool isSetColor = false;
10240 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
10241 isSetColor = jsonValue->IsString();
10242 } else {
10243 isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
10244 }
10245 if (isSetColor) {
10246 result = Color::FromString(jsonValue->GetString());
10247 return true;
10248 }
10249 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
10250 auto resId = resVal->GetValue("id");
10251 if (!resId || !resId->IsNumber()) {
10252 return false;
10253 }
10254 auto resourceWrapper = CreateResourceWrapper();
10255 if (!resourceWrapper) {
10256 return false;
10257 }
10258 result = resourceWrapper->GetColor(resId->GetUInt());
10259 return true;
10260 }
10261
ParseShadowOffsetXY(const JSRef<JSObject> & jsObj,Shadow & shadow)10262 void JSViewAbstract::ParseShadowOffsetXY(const JSRef<JSObject>& jsObj, Shadow& shadow)
10263 {
10264 CalcDimension offsetX;
10265 RefPtr<ResourceObject> xResObj;
10266 if (ParseJsResource(jsObj->GetProperty("offsetX"), offsetX, xResObj)) {
10267 if (SystemProperties::ConfigChangePerform() && xResObj) {
10268 auto&& updateFunc = [](const RefPtr<ResourceObject>& xResObj, Shadow& shadow) {
10269 CalcDimension xValue;
10270 ResourceParseUtils::ParseResResource(xResObj, xValue);
10271 shadow.SetOffsetX(xValue.Value());
10272 };
10273 shadow.AddResource("shadow.offsetX", xResObj, std::move(updateFunc));
10274 }
10275 shadow.SetOffsetX(offsetX.Value());
10276 } else {
10277 if (ParseJsDimensionVp(jsObj->GetProperty("offsetX"), offsetX)) {
10278 shadow.SetOffsetX(offsetX.Value());
10279 }
10280 }
10281 CalcDimension offsetY;
10282 RefPtr<ResourceObject> yResObj;
10283 auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
10284 if (ParseJsResource(jsOffsetY, offsetY, yResObj)) {
10285 if (yResObj) {
10286 auto&& updateFunc = [](const RefPtr<ResourceObject>& yResObj, Shadow& shadow) {
10287 CalcDimension yValue;
10288 ResourceParseUtils::ParseResResource(yResObj, yValue);
10289 shadow.SetOffsetY(yValue.Value());
10290 };
10291 shadow.AddResource("shadow.offsetY", yResObj, std::move(updateFunc));
10292 }
10293 shadow.SetOffsetY(offsetY.Value());
10294 } else {
10295 if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
10296 shadow.SetOffsetY(offsetY.Value());
10297 }
10298 }
10299 }
10300
ParseShadowPropsUpdate(const JSRef<JSObject> & jsObj,double & radius,Shadow & shadow)10301 void JSViewAbstract::ParseShadowPropsUpdate(const JSRef<JSObject>& jsObj, double& radius, Shadow& shadow)
10302 {
10303 if (jsObj->IsUndefined()) {
10304 return;
10305 }
10306 RefPtr<ResourceObject> radiusResObj;
10307 ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius, radiusResObj);
10308 if (SystemProperties::ConfigChangePerform() && radiusResObj) {
10309 auto&& updateFunc = [](const RefPtr<ResourceObject>& radiusResObj, Shadow& shadow) {
10310 double radius = 0.0;
10311 ResourceParseUtils::ParseResDouble(radiusResObj, radius);
10312 if (LessNotEqual(radius, 0.0)) {
10313 radius = 0.0;
10314 }
10315 shadow.SetBlurRadius(radius);
10316 };
10317 shadow.AddResource("shadow.radius", radiusResObj, std::move(updateFunc));
10318 }
10319 }
10320
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow,const bool configChangePerform)10321 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow, const bool configChangePerform)
10322 {
10323 int32_t shadowStyle = 0;
10324 if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
10325 auto style = static_cast<ShadowStyle>(shadowStyle);
10326 return GetShadowFromTheme(style, shadow, configChangePerform);
10327 }
10328 if (!jsValue->IsObject()) {
10329 return false;
10330 }
10331 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10332 double radius = 0.0;
10333 ParseShadowPropsUpdate(jsObj, radius, shadow);
10334 if (LessNotEqual(radius, 0.0)) {
10335 radius = 0.0;
10336 }
10337 shadow.SetBlurRadius(radius);
10338 ParseShadowOffsetXY(jsObj, shadow);
10339
10340 Color color;
10341 ShadowColorStrategy shadowColorStrategy;
10342 auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
10343 RefPtr<ResourceObject> colorResObj;
10344 if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
10345 shadow.SetShadowColorStrategy(shadowColorStrategy);
10346 } else if (ParseJsColor(jsColor, color, colorResObj)) {
10347 if (SystemProperties::ConfigChangePerform() && colorResObj) {
10348 auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, Shadow& shadow) {
10349 Color colorValue;
10350 ResourceParseUtils::ParseResColor(colorResObj, colorValue);
10351 shadow.SetColor(colorValue);
10352 };
10353 shadow.AddResource("shadow.colorValue", colorResObj, std::move(updateFunc));
10354 }
10355 shadow.SetColor(color);
10356 }
10357
10358 int32_t type = static_cast<int32_t>(ShadowType::COLOR);
10359 JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
10360 if (type != static_cast<int32_t>(ShadowType::BLUR)) {
10361 type = static_cast<int32_t>(ShadowType::COLOR);
10362 }
10363 shadow.SetShadowType(static_cast<ShadowType>(type));
10364 bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
10365 shadow.SetIsFilled(isFilled);
10366 return true;
10367 }
10368
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow,const bool configChangePerform)10369 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow, const bool configChangePerform)
10370 {
10371 ViewAbstractModel::GetInstance()->RemoveResObj("shadowStyle");
10372 auto colorMode = Container::CurrentColorMode();
10373 if (shadowStyle == ShadowStyle::None) {
10374 return true;
10375 }
10376
10377 auto container = Container::Current();
10378 CHECK_NULL_RETURN(container, false);
10379 auto pipelineContext = container->GetPipelineContext();
10380 CHECK_NULL_RETURN(pipelineContext, false);
10381
10382 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
10383 if (!shadowTheme) {
10384 return false;
10385 }
10386 shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
10387 if (configChangePerform) {
10388 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
10389 CHECK_NULL_RETURN(frameNode, false);
10390 auto pattern = frameNode->GetPattern();
10391 CHECK_NULL_RETURN(pattern, false);
10392 RefPtr<ResourceObject> resObj = AceType::MakeRefPtr<ResourceObject>("", "", -1);
10393 auto&& updateFunc = [shadowStyle, weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
10394 auto frameNode = weak.Upgrade();
10395 CHECK_NULL_VOID(frameNode);
10396 auto colorMode = Container::CurrentColorMode();
10397 auto container = Container::Current();
10398 CHECK_NULL_VOID(container);
10399 auto pipelineContext = container->GetPipelineContext();
10400 CHECK_NULL_VOID(pipelineContext);
10401 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
10402 if (!shadowTheme) {
10403 return;
10404 }
10405 Shadow shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
10406 ACE_UPDATE_NODE_RENDER_CONTEXT(BackShadow, shadow, frameNode);
10407 };
10408 updateFunc(resObj);
10409 pattern->AddResObj("shadowStyle", resObj, std::move(updateFunc));
10410 return false;
10411 }
10412 return true;
10413 }
10414
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)10415 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
10416 {
10417 RefPtr<ResourceObject> resObj;
10418 return ParseJsResource(jsValue, result, resObj);
10419 }
10420
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result,RefPtr<ResourceObject> & resObj)10421 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result,
10422 RefPtr<ResourceObject>& resObj)
10423 {
10424 if (!jsValue->IsObject()) {
10425 return false;
10426 }
10427 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10428 uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
10429 if (type == 0) {
10430 return false;
10431 }
10432 if (SystemProperties::ConfigChangePerform()) {
10433 resObj = GetResourceObject(jsObj);
10434 }
10435 auto resourceWrapper = CreateResourceWrapper();
10436 CHECK_NULL_RETURN(resourceWrapper, false);
10437 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
10438 auto value = resourceWrapper->GetString(
10439 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
10440 return StringUtils::StringToCalcDimensionNG(value, result, false);
10441 }
10442 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
10443 auto value = std::to_string(
10444 resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
10445 StringUtils::StringToDimensionWithUnitNG(value, result);
10446 return true;
10447 }
10448
10449 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
10450 result = resourceWrapper->GetDimension(
10451 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
10452 return true;
10453 }
10454 return false;
10455 }
10456
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)10457 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
10458 {
10459 JSRef<JSVal> arg = info[0];
10460 if (!arg->IsObject()) {
10461 return false;
10462 }
10463 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
10464 JSRef<JSVal> typeValue = obj->GetProperty("types");
10465 if (!typeValue->IsArray()) {
10466 return false;
10467 }
10468 JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
10469 for (size_t i = 0; i < array->Length(); i++) {
10470 JSRef<JSVal> value = array->GetValueAt(i);
10471 auto index = value->ToNumber<int32_t>();
10472 if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
10473 return false;
10474 }
10475 if (i != 0) {
10476 textDetectConfig.types.append(",");
10477 }
10478 textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
10479 }
10480 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10481 JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
10482 if (resultCallback->IsFunction()) {
10483 auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
10484 textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
10485 const std::string& result) {
10486 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10487 PipelineContext::SetCallBackNode(node);
10488 func->Execute(result);
10489 };
10490 }
10491 auto enablePreviewMenuValue = obj->GetProperty("enablePreviewMenu");
10492 if (enablePreviewMenuValue->IsBoolean()) {
10493 textDetectConfig.enablePreviewMenu = enablePreviewMenuValue->ToBoolean();
10494 }
10495 return ParseAIEntityColor(obj, textDetectConfig);
10496 }
10497
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)10498 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
10499 {
10500 RefPtr<ResourceObject> resObj;
10501 JSRef<JSVal> entityColorValue = obj->GetProperty("color");
10502 ParseJsColor(entityColorValue, textDetectConfig.entityColor, resObj);
10503 TextDetectConfig::RegisterColorResource(textDetectConfig, resObj);
10504
10505 JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
10506 if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
10507 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
10508 return true;
10509 }
10510 JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
10511 JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
10512 JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
10513 JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
10514
10515 if (typeValue->IsNumber()) {
10516 textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
10517 } else {
10518 textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
10519 }
10520 RefPtr<ResourceObject> decoColorResObj;
10521 if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor, decoColorResObj)) {
10522 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
10523 }
10524 TextDetectConfig::RegisterDecoColorResource(textDetectConfig, decoColorResObj);
10525 if (styleValue->IsNumber()) {
10526 textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
10527 } else {
10528 textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
10529 }
10530 return true;
10531 }
10532
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)10533 void JSViewAbstract::GetAngle(
10534 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
10535 {
10536 auto value = jsonValue->GetValue(key);
10537 if (value && value->IsString()) {
10538 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
10539 } else if (value && value->IsNumber()) {
10540 angle = static_cast<float>(value->GetDouble());
10541 }
10542 }
10543
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)10544 void JSViewAbstract::GetJsAngle(
10545 int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
10546 {
10547 if (!jsValue->IsObject()) {
10548 return;
10549 }
10550 JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
10551 if (value->IsString()) {
10552 angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
10553 } else if (value->IsNumber()) {
10554 angle = value->ToNumber<float>();
10555 }
10556 }
10557
10558 // if angle is not string or number, return directly. If angle is invalid string, use defaultValue.
GetJsAngleWithDefault(int32_t key,const JSRef<JSObject> & jsObj,std::optional<float> & angle,float defaultValue)10559 void JSViewAbstract::GetJsAngleWithDefault(
10560 int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
10561 {
10562 JSRef<JSVal> value = jsObj->GetProperty(key);
10563 if (value->IsString()) {
10564 double temp = 0.0;
10565 if (StringUtils::StringToDegree(value->ToString(), temp)) {
10566 angle = static_cast<float>(temp);
10567 } else {
10568 angle = defaultValue;
10569 }
10570 } else if (value->IsNumber()) {
10571 angle = value->ToNumber<float>();
10572 }
10573 }
10574
CheckAngle(std::optional<float> & angle)10575 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
10576 {
10577 if (angle.has_value()) {
10578 angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
10579 }
10580 }
10581
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)10582 void JSViewAbstract::GetPerspective(
10583 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
10584 {
10585 auto value = jsonValue->GetValue(key);
10586 if (value && value->IsNumber()) {
10587 perspective = static_cast<float>(value->GetDouble());
10588 }
10589 }
10590
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)10591 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
10592 {
10593 auto value = jsValue->GetProperty(key);
10594 if (value->IsNumber()) {
10595 perspective = value->ToNumber<float>();
10596 }
10597 }
10598
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)10599 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
10600 {
10601 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
10602 return;
10603 }
10604
10605 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
10606 GradientColor gradientColor;
10607 auto item = colorStops->GetArrayItem(i);
10608 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
10609 auto colorParams = item->GetArrayItem(0);
10610 // color
10611 Color color;
10612 if (!ParseJsonColor(colorParams, color)) {
10613 continue;
10614 }
10615 gradientColor.SetColor(color);
10616 gradientColor.SetHasValue(false);
10617 // stop value
10618 if (item->GetArraySize() <= 1) {
10619 continue;
10620 }
10621 auto stopValue = item->GetArrayItem(1);
10622 double value = 0.0;
10623 if (ParseJsonDouble(stopValue, value)) {
10624 value = std::clamp(value, 0.0, 1.0);
10625 gradientColor.SetHasValue(true);
10626 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10627 }
10628 gradient.AddColor(gradientColor);
10629 }
10630 }
10631 }
10632
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)10633 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
10634 {
10635 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
10636 return;
10637 }
10638
10639 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
10640 NG::GradientColor gradientColor;
10641 auto item = colorStops->GetArrayItem(i);
10642 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
10643 auto colorParams = item->GetArrayItem(0);
10644 // color
10645 Color color;
10646 if (!ParseJsonColor(colorParams, color)) {
10647 continue;
10648 }
10649 gradientColor.SetColor(color);
10650 gradientColor.SetHasValue(false);
10651 // stop value
10652 if (item->GetArraySize() <= 1) {
10653 continue;
10654 }
10655 auto stopValue = item->GetArrayItem(1);
10656 double value = 0.0;
10657 if (ParseJsonDouble(stopValue, value)) {
10658 value = std::clamp(value, 0.0, 1.0);
10659 gradientColor.SetHasValue(true);
10660 // [0, 1] -> [0, 100.0];
10661 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10662 }
10663 gradient.AddColor(gradientColor);
10664 }
10665 }
10666 }
10667
NewParseSweepGradientColor(NG::Gradient & gradient,RefPtr<ResourceObject> & resObj,NG::GradientColor & gradientColor,int32_t & indx)10668 void JSViewAbstract::NewParseSweepGradientColor(NG::Gradient& gradient, RefPtr<ResourceObject>& resObj,
10669 NG::GradientColor& gradientColor, int32_t& indx)
10670 {
10671 auto&& updateFunc = [gradientColor, indx](const RefPtr<ResourceObject>& resObj,
10672 NG::Gradient& gradient) {
10673 std::vector<NG::GradientColor> colorVector = gradient.GetColors();
10674 int32_t colorLength = static_cast<int32_t>(colorVector.size());
10675 gradient.ClearColors();
10676 for (int32_t index = 0; index < colorLength; index++) {
10677 NG::GradientColor gradColor = colorVector[index];
10678 if (index == indx) {
10679 Color color;
10680 ResourceParseUtils::ParseResColor(resObj, color);
10681 gradColor.SetColor(color);
10682 }
10683 gradient.AddColor(gradColor);
10684 }
10685 };
10686 std::string key = "SweepGradient.gradient.color" + std::to_string(indx);
10687 gradient.AddResource(key, resObj, std::move(updateFunc));
10688 }
10689
NewParseRadialGradientColor(NG::Gradient & gradient,RefPtr<ResourceObject> & resObj,NG::GradientColor & gradientColor,int32_t & indx)10690 void JSViewAbstract::NewParseRadialGradientColor(NG::Gradient& gradient, RefPtr<ResourceObject>& resObj,
10691 NG::GradientColor& gradientColor, int32_t& indx)
10692 {
10693 auto&& updateFunc = [gradientColor, indx](const RefPtr<ResourceObject>& resObj,
10694 NG::Gradient& gradient) {
10695 std::vector<NG::GradientColor> colorVector = gradient.GetColors();
10696 int32_t colorLength = static_cast<int32_t>(colorVector.size());
10697 gradient.ClearColors();
10698 for (int32_t index = 0; index < colorLength; index++) {
10699 NG::GradientColor gradColor = colorVector[index];
10700 if (index == indx) {
10701 Color color;
10702 ResourceParseUtils::ParseResColor(resObj, color);
10703 gradColor.SetColor(color);
10704 }
10705 gradient.AddColor(gradColor);
10706 }
10707 };
10708 std::string key = "RadialGradient.gradient.color" + std::to_string(indx);
10709 gradient.AddResource(key, resObj, std::move(updateFunc));
10710 }
10711
NewParseGradientColor(NG::Gradient & gradient,RefPtr<ResourceObject> & resObj,NG::GradientColor & gradientColor,int32_t & indx)10712 void JSViewAbstract::NewParseGradientColor(NG::Gradient& gradient, RefPtr<ResourceObject>& resObj,
10713 NG::GradientColor& gradientColor, int32_t& indx)
10714 {
10715 auto&& updateFunc = [gradientColor, indx](const RefPtr<ResourceObject>& resObj,
10716 NG::Gradient& gradient) {
10717 std::vector<NG::GradientColor> colorVector = gradient.GetColors();
10718 int32_t colorLength = static_cast<int32_t>(colorVector.size());
10719 gradient.ClearColors();
10720 for (int32_t index = 0; index < colorLength; index++) {
10721 NG::GradientColor gradColor = colorVector[index];
10722 if (index == indx) {
10723 Color color;
10724 ResourceParseUtils::ParseResColor(resObj, color);
10725 gradColor.SetColor(color);
10726 }
10727 gradient.AddColor(gradColor);
10728 }
10729 };
10730 std::string key = "LinearGradient.gradient.color" + std::to_string(indx);
10731 gradient.AddResource(key, resObj, std::move(updateFunc));
10732 }
10733
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops,const int32_t mapIdx)10734 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops,
10735 const int32_t mapIdx)
10736 {
10737 if (!colorStops->IsArray()) {
10738 return;
10739 }
10740 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
10741 size_t length = jsArray->Length();
10742 int32_t nullNum = 0;
10743 for (size_t i = 0; i < length; i++) {
10744 NG::GradientColor gradientColor;
10745 JSRef<JSVal> item = jsArray->GetValueAt(i);
10746 if (!item->IsArray()) {
10747 continue;
10748 }
10749 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
10750 if (subArray->Length() < 2) {
10751 continue;
10752 }
10753 // color
10754 Color color;
10755 RefPtr<ResourceObject> resObj;
10756 if (!ParseJsColor(subArray->GetValueAt(0), color, resObj)) {
10757 nullNum++;
10758 continue;
10759 }
10760 gradientColor.SetColor(color);
10761 gradientColor.SetHasValue(false);
10762 // stop value
10763 double value = 0.0;
10764 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
10765 value = std::clamp(value, 0.0, 1.0);
10766 gradientColor.SetHasValue(true);
10767 }
10768 // [0, 1] -> [0, 100.0];
10769 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10770 gradient.AddColor(gradientColor);
10771 if (SystemProperties::ConfigChangePerform() && resObj) {
10772 int32_t indx = static_cast<int32_t>(i) - nullNum;
10773 if (mapIdx == NUM_1) {
10774 NewParseSweepGradientColor(gradient, resObj, gradientColor, indx);
10775 } else if (mapIdx == NUM_2) {
10776 NewParseRadialGradientColor(gradient, resObj, gradientColor, indx);
10777 } else {
10778 NewParseGradientColor(gradient, resObj, gradientColor, indx);
10779 }
10780 }
10781 }
10782 }
10783
NewGetJsGradientColorStopsCheck(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)10784 void JSViewAbstract::NewGetJsGradientColorStopsCheck(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
10785 {
10786 if (!colorStops->IsArray()) {
10787 return;
10788 }
10789
10790 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
10791 size_t length = jsArray->Length();
10792 bool isValid = true;
10793 for (size_t i = 0; i < length; i++) {
10794 NG::GradientColor gradientColor;
10795 JSRef<JSVal> item = jsArray->GetValueAt(i);
10796 if (!item->IsArray()) {
10797 continue;
10798 }
10799 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
10800 if (subArray->Length() < 2) {
10801 continue;
10802 }
10803 // color
10804 Color color;
10805 if (!ParseJsColor(subArray->GetValueAt(0), color)) {
10806 continue;
10807 }
10808 // is valid
10809 if (gradient.GetColors().size()) {
10810 if (color.GetColorSpace() != gradient.GetColors().back().GetColor().GetColorSpace()) {
10811 isValid = false;
10812 gradient.ClearColors();
10813 break;
10814 }
10815 }
10816 gradientColor.SetColor(color);
10817 gradientColor.SetHasValue(false);
10818 // stop value
10819 double value = 0.0;
10820 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
10821 value = std::clamp(value, 0.0, 1.0);
10822 gradientColor.SetHasValue(true);
10823 }
10824 // [0, 1] -> [0, 100.0];
10825 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
10826 gradient.AddColor(gradientColor);
10827 }
10828 }
10829
SetDirection(const std::string & dir)10830 void JSViewAbstract::SetDirection(const std::string& dir)
10831 {
10832 TextDirection direction = TextDirection::AUTO;
10833 if (dir == "Ltr") {
10834 direction = TextDirection::LTR;
10835 } else if (dir == "Rtl") {
10836 direction = TextDirection::RTL;
10837 } else if (dir == "Auto") {
10838 direction = TextDirection::AUTO;
10839 } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10840 direction = TextDirection::AUTO;
10841 }
10842 ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
10843 }
10844
GetThemeConstants(const JSRef<JSObject> & jsObj)10845 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
10846 {
10847 std::string bundleName;
10848 std::string moduleName;
10849 if (!jsObj->IsUndefined()) {
10850 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
10851 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
10852 if (bundle->IsString() && module->IsString()) {
10853 bundleName = bundle->ToString();
10854 moduleName = module->ToString();
10855 }
10856 }
10857
10858 auto cardId = CardScope::CurrentId();
10859 if (cardId != INVALID_CARD_ID) {
10860 auto container = Container::Current();
10861 CHECK_NULL_RETURN(container, nullptr);
10862 auto weak = container->GetCardPipeline(cardId);
10863 auto cardPipelineContext = weak.Upgrade();
10864 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
10865 auto cardThemeManager = cardPipelineContext->GetThemeManager();
10866 CHECK_NULL_RETURN(cardThemeManager, nullptr);
10867 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
10868 }
10869
10870 #ifdef PLUGIN_COMPONENT_SUPPORTED
10871 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
10872 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
10873 if (!pluginContainer) {
10874 return nullptr;
10875 }
10876 auto pluginPipelineContext = pluginContainer->GetPipelineContext();
10877 if (!pluginPipelineContext) {
10878 return nullptr;
10879 }
10880 auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
10881 if (!pluginThemeManager) {
10882 return nullptr;
10883 }
10884 return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
10885 }
10886 #endif
10887 auto container = Container::Current();
10888 CHECK_NULL_RETURN(container, nullptr);
10889 auto pipelineContext = container->GetPipelineContext();
10890 CHECK_NULL_RETURN(pipelineContext, nullptr);
10891 auto themeManager = pipelineContext->GetThemeManager();
10892 CHECK_NULL_RETURN(themeManager, nullptr);
10893 return themeManager->GetThemeConstants(bundleName, moduleName);
10894 }
10895
JsHoverEffect(const JSCallbackInfo & info)10896 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
10897 {
10898 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
10899 auto jsVal = info[0];
10900 if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
10901 ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
10902 return;
10903 }
10904 if (!jsVal->IsNumber()) {
10905 return;
10906 }
10907 ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
10908 }
10909
JsOnMouse(const JSCallbackInfo & info)10910 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
10911 {
10912 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10913 ViewAbstractModel::GetInstance()->DisableOnMouse();
10914 return;
10915 }
10916 if (!info[0]->IsFunction()) {
10917 return;
10918 }
10919
10920 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
10921 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10922 auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
10923 MouseInfo& mouseInfo) {
10924 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10925 ACE_SCORING_EVENT("onMouse");
10926 PipelineContext::SetCallBackNode(node);
10927 func->Execute(mouseInfo);
10928 };
10929 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
10930 }
10931
JsOnAxisEvent(const JSCallbackInfo & args)10932 void JSViewAbstract::JsOnAxisEvent(const JSCallbackInfo& args)
10933 {
10934 JSRef<JSVal> arg = args[0];
10935 if (arg->IsUndefined() && IsDisableEventVersion()) {
10936 ViewAbstractModel::GetInstance()->DisableOnAxisEvent();
10937 return;
10938 }
10939 if (!arg->IsFunction()) {
10940 return;
10941 }
10942 EcmaVM* vm = args.GetVm();
10943 CHECK_NULL_VOID(vm);
10944 auto jsOnAxisEventFunc = JSRef<JSFunc>::Cast(args[0]);
10945 if (jsOnAxisEventFunc->IsEmpty()) {
10946 return;
10947 }
10948 auto jsOnAxisFuncLocalHandle = jsOnAxisEventFunc->GetLocalHandle();
10949 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10950 auto onAxisEvent = [vm, execCtx = args.GetExecutionContext(),
10951 func = panda::CopyableGlobal(vm, jsOnAxisFuncLocalHandle),
10952 node = frameNode](Ace::AxisInfo& info) {
10953 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10954 ACE_SCORING_EVENT("onAxis");
10955 PipelineContext::SetCallBackNode(node);
10956 auto eventObj = NG::CommonBridge::CreateAxisEventInfo(vm, info);
10957 panda::Local<panda::JSValueRef> params[1] = { eventObj };
10958 func->Call(vm, func.ToLocal(), params, 1);
10959 };
10960 ViewAbstractModel::GetInstance()->SetOnAxisEvent(std::move(onAxisEvent));
10961 }
10962
JsOnHover(const JSCallbackInfo & info)10963 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
10964 {
10965 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10966 ViewAbstractModel::GetInstance()->DisableOnHover();
10967 return;
10968 }
10969 if (!info[0]->IsFunction()) {
10970 return;
10971 }
10972
10973 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10974 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10975 auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
10976 bool isHover, HoverInfo& hoverInfo) {
10977 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10978 ACE_SCORING_EVENT("onHover");
10979 PipelineContext::SetCallBackNode(node);
10980 func->HoverExecute(isHover, hoverInfo);
10981 };
10982 ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
10983 }
10984
JsOnHoverMove(const JSCallbackInfo & info)10985 void JSViewAbstract::JsOnHoverMove(const JSCallbackInfo& info)
10986 {
10987 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10988 ViewAbstractModel::GetInstance()->DisableOnHoverMove();
10989 return;
10990 }
10991 if (!info[0]->IsFunction()) {
10992 return;
10993 }
10994
10995 RefPtr<JsHoverFunction> jsOnHoverMoveFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10996 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10997 auto onHoverMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverMoveFunc), node = frameNode](
10998 HoverInfo& hoverInfo) {
10999 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11000 ACE_SCORING_EVENT("onHoverMove");
11001 PipelineContext::SetCallBackNode(node);
11002 func->HoverMoveExecute(hoverInfo);
11003 };
11004 ViewAbstractModel::GetInstance()->SetOnHoverMove(std::move(onHoverMove));
11005 }
11006
JsOnAccessibilityHover(const JSCallbackInfo & info)11007 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
11008 {
11009 if (info[0]->IsUndefined()) {
11010 ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
11011 return;
11012 }
11013 if (!info[0]->IsFunction()) {
11014 return;
11015 }
11016
11017 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
11018 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11019 auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
11020 node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
11021 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11022 ACE_SCORING_EVENT("onAccessibilityHover");
11023 PipelineContext::SetCallBackNode(node);
11024 func->AccessibilityHoverExecute(isHover, hoverInfo);
11025 };
11026 ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
11027 }
11028
JsOnClick(const JSCallbackInfo & info)11029 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
11030 {
11031 auto arg = info[0];
11032 if (arg->IsUndefined() && IsDisableEventVersion()) {
11033 ViewAbstractModel::GetInstance()->DisableOnClick();
11034 return;
11035 }
11036 if (!arg->IsFunction()) {
11037 return;
11038 }
11039
11040 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
11041 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11042 auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
11043 BaseEventInfo* info) {
11044 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11045 auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
11046 ACE_SCORING_EVENT("onClick");
11047 PipelineContext::SetCallBackNode(node);
11048 func->Execute(*tapInfo);
11049 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
11050 JSInteractableView::ReportClickEvent(node);
11051 #endif
11052 };
11053 auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
11054 auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
11055 const ClickInfo* info) {
11056 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11057 ACE_SCORING_EVENT("onClick");
11058 PipelineContext::SetCallBackNode(node);
11059 func->Execute(*info);
11060 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
11061 JSInteractableView::ReportClickEvent(node);
11062 #endif
11063 };
11064
11065 Dimension distanceThreshold = Dimension(std::numeric_limits<double>::infinity(), DimensionUnit::PX);
11066 if (info.Length() > 1 && info[1]->IsNumber()) {
11067 double jsDistanceThreshold = info[1]->ToNumber<double>();
11068 if (jsDistanceThreshold < 0) {
11069 distanceThreshold = Dimension(std::numeric_limits<double>::infinity(), DimensionUnit::PX);
11070 }
11071 distanceThreshold = Dimension(jsDistanceThreshold, DimensionUnit::VP);
11072 }
11073 ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
11074 }
11075
JsOnGestureJudgeBegin(const JSCallbackInfo & info)11076 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
11077 {
11078 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11079 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
11080 return;
11081 }
11082
11083 auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
11084 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11085 auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
11086 const RefPtr<NG::GestureInfo>& gestureInfo,
11087 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
11088 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
11089 ACE_SCORING_EVENT("onGestureJudgeBegin");
11090 PipelineContext::SetCallBackNode(node);
11091 return func->Execute(gestureInfo, info);
11092 };
11093 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
11094 }
11095
JsOnTouchIntercept(const JSCallbackInfo & info)11096 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
11097 {
11098 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11099 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
11100 return;
11101 }
11102
11103 auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
11104 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11105 auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
11106 TouchEventInfo& info) -> NG::HitTestMode {
11107 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
11108 ACE_SCORING_EVENT("onTouchIntercept");
11109 PipelineContext::SetCallBackNode(node);
11110 return func->Execute(info);
11111 };
11112 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
11113 }
11114
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)11115 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
11116 {
11117 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11118 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
11119 return;
11120 }
11121
11122 auto jsParallelInnerGestureToFunc =
11123 AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
11124 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11125 auto shouldBuiltInRecognizerParallelWithFunc =
11126 [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
11127 const RefPtr<NG::NGGestureRecognizer>& current,
11128 const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
11129 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
11130 ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
11131 PipelineContext::SetCallBackNode(node);
11132 return func->Execute(current, others);
11133 };
11134 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
11135 std::move(shouldBuiltInRecognizerParallelWithFunc));
11136 }
11137
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)11138 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
11139 {
11140 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
11141 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
11142 return;
11143 }
11144
11145 auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
11146 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11147 auto onGestureRecognizerJudgefunc =
11148 [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
11149 const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
11150 const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
11151 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
11152 ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
11153 PipelineContext::SetCallBackNode(node);
11154 return func->Execute(info, current, others);
11155 };
11156
11157 bool exposeInnerGestureFlag = false;
11158 if (info.Length() > 1 && info[1]->IsBoolean()) {
11159 exposeInnerGestureFlag = info[1]->ToBoolean();
11160 }
11161 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
11162 std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
11163 }
11164
JsOnTouchTestDone(const JSCallbackInfo & info)11165 void JSViewAbstract::JsOnTouchTestDone(const JSCallbackInfo& info)
11166 {
11167 if (info.Length() < 1 || info[0]->IsUndefined() || !info[0]->IsFunction()) {
11168 ViewAbstractModel::GetInstance()->SetOnTouchTestDone(nullptr);
11169 return;
11170 }
11171 auto JsOnTouchTestDoneFunc = AceType::MakeRefPtr<JsTouchTestDoneFunction>(JSRef<JSFunc>::Cast(info[0]));
11172 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11173 auto onTouchTestDoneFunc = [execCtx = info.GetExecutionContext(), func = JsOnTouchTestDoneFunc, node = frameNode](
11174 const std::shared_ptr<BaseGestureEvent>& info,
11175 const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> bool {
11176 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
11177 ACE_SCORING_EVENT("onTouchTestDone");
11178 PipelineContext::SetCallBackNode(node);
11179 return func->Execute(info, others);
11180 };
11181 ViewAbstractModel::GetInstance()->SetOnTouchTestDone(std::move(onTouchTestDoneFunc));
11182 }
11183
JsClickEffect(const JSCallbackInfo & info)11184 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
11185 {
11186 JSRef<JSVal> arg = info[0];
11187 if (arg->IsUndefined() || arg->IsNull()) {
11188 ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
11189 return;
11190 }
11191 if (!arg->IsObject()) {
11192 return;
11193 }
11194 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
11195 JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
11196 int32_t clickEffectLevelValue = 0;
11197 if (clickEffectLevel->IsNumber()) {
11198 clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
11199 if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
11200 clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
11201 clickEffectLevelValue = 0;
11202 }
11203 }
11204
11205 JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
11206 float scaleNumberValue = DEFAULT_SCALE_LIGHT;
11207 if (!scaleNumber->IsNumber()) {
11208 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
11209 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
11210 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
11211 }
11212 ViewAbstractModel::GetInstance()->SetClickEffectLevel(
11213 (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
11214 return;
11215 }
11216
11217 scaleNumberValue = scaleNumber->ToNumber<float>();
11218 if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
11219 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
11220 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
11221 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
11222 } else {
11223 scaleNumberValue = DEFAULT_SCALE_LIGHT;
11224 }
11225 }
11226
11227 ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
11228 }
11229
JsOnVisibleAreaChange(const JSCallbackInfo & info)11230 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
11231 {
11232 if (info.Length() < 2 || info.Length() > 3) {
11233 return;
11234 }
11235
11236 if (!info[0]->IsArray() || !info[1]->IsFunction()) {
11237 return;
11238 }
11239
11240 auto ratioArray = JSRef<JSArray>::Cast(info[0]);
11241 size_t size = ratioArray->Length();
11242 std::vector<double> ratioVec(size);
11243 ratioVec.clear();
11244 for (size_t i = 0; i < size; i++) {
11245 double ratio = 0.0;
11246 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
11247 if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
11248 ratio = VISIBLE_RATIO_MIN;
11249 }
11250
11251 if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
11252 ratio = VISIBLE_RATIO_MAX;
11253 }
11254 ratioVec.push_back(ratio);
11255 }
11256
11257 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
11258 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11259 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
11260 bool visible, double ratio) {
11261 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11262 ACE_SCORING_EVENT("onVisibleAreaChange");
11263
11264 JSRef<JSVal> params[2];
11265 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
11266 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
11267 PipelineContext::SetCallBackNode(node);
11268 func->ExecuteJS(2, params);
11269 };
11270
11271 bool isOutOfBoundsAllowed = false;
11272 if (info.Length() == 3 && info[2]->IsBoolean()) {
11273 isOutOfBoundsAllowed = info[2]->ToBoolean();
11274 }
11275 ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec, isOutOfBoundsAllowed);
11276 }
11277
JsOnVisibleAreaApproximateChange(const JSCallbackInfo & info)11278 void JSViewAbstract::JsOnVisibleAreaApproximateChange(const JSCallbackInfo& info)
11279 {
11280 if (info.Length() != PARAMETER_LENGTH_SECOND) {
11281 return;
11282 }
11283
11284 if (!info[0]->IsObject() || !info[1]->IsFunction()) {
11285 return;
11286 }
11287
11288 const auto& options = info[0];
11289 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(options);
11290 JSRef<JSVal> ratios = optionObj->GetProperty("ratios");
11291 if (!ratios->IsArray()) {
11292 return;
11293 }
11294 auto ratioArray = JSRef<JSArray>::Cast(ratios);
11295 size_t size = ratioArray->Length();
11296 std::vector<double> ratioVec(size);
11297 for (size_t i = 0; i < size; i++) {
11298 double ratio = 0.0;
11299 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
11300 ratio = std::clamp(ratio, VISIBLE_RATIO_MIN, VISIBLE_RATIO_MAX);
11301 ratioVec.push_back(ratio);
11302 }
11303 int32_t expectedUpdateInterval = DEFAULT_DURATION;
11304 JSRef<JSVal> expectedUpdateIntervalVal = optionObj->GetProperty("expectedUpdateInterval");
11305 if (expectedUpdateIntervalVal->IsNumber()) {
11306 JSViewAbstract::ParseJsInteger(expectedUpdateIntervalVal, expectedUpdateInterval);
11307 }
11308 if (expectedUpdateInterval < 0) {
11309 expectedUpdateInterval = DEFAULT_DURATION;
11310 }
11311
11312 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
11313 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11314 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
11315 bool visible, double ratio) {
11316 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11317 ACE_SCORING_EVENT("onVisibleAreaApproximateChange");
11318
11319 JSRef<JSVal> params[2];
11320 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
11321 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
11322 PipelineContext::SetCallBackNode(node);
11323 func->ExecuteJS(2, params);
11324 };
11325 ViewAbstractModel::GetInstance()->SetOnVisibleAreaApproximateChange(
11326 std::move(onVisibleChange), ratioVec, expectedUpdateInterval);
11327 }
11328
JsHitTestBehavior(const JSCallbackInfo & info)11329 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
11330 {
11331 if (info.Length() != 1 || !info[0]->IsNumber()) {
11332 return;
11333 }
11334
11335 NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
11336 hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
11337 ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
11338 }
11339
JsOnChildTouchTest(const JSCallbackInfo & info)11340 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
11341 {
11342 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
11343 auto jsVal = info[0];
11344 if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
11345 return;
11346 }
11347
11348 RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
11349 AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
11350
11351 auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
11352 const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
11353 NG::TouchResult touchRes;
11354 NG::TouchResult defaultRes;
11355 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, defaultRes);
11356 defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
11357 defaultRes.id = "";
11358 auto ret = func->Execute(touchInfo);
11359 if (!ret->IsObject()) {
11360 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
11361 return defaultRes;
11362 }
11363
11364 auto retObj = JSRef<JSObject>::Cast(ret);
11365 auto strategy = retObj->GetProperty("strategy");
11366 if (!strategy->IsNumber()) {
11367 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
11368 return defaultRes;
11369 }
11370 touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
11371 auto id = retObj->GetProperty("id");
11372 if (!id->IsString()) {
11373 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
11374 return defaultRes;
11375 }
11376 touchRes.id = id->ToString();
11377 return touchRes;
11378 };
11379 ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
11380 }
11381
JsForegroundColor(const JSCallbackInfo & info)11382 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
11383 {
11384 ViewAbstractModel::GetInstance()->RemoveResObj("foregroundColor");
11385 ViewAbstractModel::GetInstance()->RemoveResObj("foregroundColorStrategy");
11386 Color foregroundColor = Color::TRANSPARENT;
11387 ForegroundColorStrategy strategy;
11388 if (ParseJsColorStrategy(info[0], strategy)) {
11389 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
11390 return;
11391 }
11392 if (!SystemProperties::ConfigChangePerform()) {
11393 ParseJsColor(info[0], foregroundColor);
11394 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
11395 } else {
11396 RefPtr<ResourceObject> foregroundResObj;
11397 ParseJsColor(info[0], foregroundColor, foregroundResObj);
11398 if (foregroundResObj) {
11399 ViewAbstractModel::GetInstance()->CreateWithForegroundColorResourceObj(foregroundResObj);
11400 } else {
11401 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
11402 }
11403 }
11404 }
11405
JsKeyboardShortcut(const JSCallbackInfo & info)11406 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
11407 {
11408 // KeyboardShortcut only allows 2 or 3 params.
11409 if (info.Length() < 2 || info.Length() > 3) {
11410 return;
11411 }
11412 if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
11413 // clear shortcut key
11414 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
11415 return;
11416 }
11417
11418 std::string value;
11419 if (info[0]->IsString()) {
11420 // common letter/number/symbol
11421 value = info[0]->ToString();
11422 if (value.size() != 1) {
11423 // clear shortcut key
11424 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
11425 return;
11426 }
11427 } else {
11428 // function keys such as F1-F10/ESC
11429 FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
11430 value = GetFunctionKeyName(functionkey);
11431 }
11432
11433 auto keysArray = JSRef<JSArray>::Cast(info[1]);
11434 size_t size = keysArray->Length();
11435 std::vector<ModifierKey> keys(size);
11436 keys.clear();
11437 for (size_t i = 0; i < size; i++) {
11438 JSRef<JSVal> key = keysArray->GetValueAt(i);
11439 if (key->IsNumber()) {
11440 keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
11441 }
11442 }
11443
11444 // KeyboardShortcut allows 3 params, the third param is function callback.
11445 if (info.Length() == 3 && info[2]->IsFunction()) {
11446 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
11447 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11448 auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11449 node = frameNode]() {
11450 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11451 ACE_SCORING_EVENT("onKeyboardShortcutAction");
11452 PipelineContext::SetCallBackNode(node);
11453 func->ExecuteJS();
11454 };
11455 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
11456 return;
11457 }
11458 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
11459 }
11460
JsOnFocusAxisEvent(const JSCallbackInfo & args)11461 void JSViewAbstract::JsOnFocusAxisEvent(const JSCallbackInfo& args)
11462 {
11463 JSRef<JSVal> arg = args[0];
11464 if (arg->IsUndefined() && IsDisableEventVersion()) {
11465 ViewAbstractModel::GetInstance()->DisableOnFocusAxisEvent();
11466 return;
11467 }
11468 if (!arg->IsFunction()) {
11469 return;
11470 }
11471 EcmaVM* vm = args.GetVm();
11472 CHECK_NULL_VOID(vm);
11473 auto jsOnFocusAxisEventFunc = JSRef<JSFunc>::Cast(arg);
11474 if (jsOnFocusAxisEventFunc->IsEmpty()) {
11475 return;
11476 }
11477 auto jsOnFocusAxisFuncLocalHandle = jsOnFocusAxisEventFunc->GetLocalHandle();
11478 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11479 auto onFocusAxisEvent = [vm, execCtx = args.GetExecutionContext(),
11480 func = panda::CopyableGlobal(vm, jsOnFocusAxisFuncLocalHandle),
11481 node = frameNode](NG::FocusAxisEventInfo& info) {
11482 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11483 ACE_SCORING_EVENT("onFocusAxis");
11484 PipelineContext::SetCallBackNode(node);
11485 auto eventObj = NG::CommonBridge::CreateFocusAxisEventInfo(vm, info);
11486 panda::Local<panda::JSValueRef> params[1] = { eventObj };
11487 func->Call(vm, func.ToLocal(), params, 1);
11488 };
11489 ViewAbstractModel::GetInstance()->SetOnFocusAxisEvent(std::move(onFocusAxisEvent));
11490 }
11491
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)11492 bool JSViewAbstract::CheckColor(
11493 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
11494 {
11495 RefPtr<ResourceObject> resourceObject;
11496 return CheckColor(jsValue, result, componentName, propName, resourceObject);
11497 }
11498
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName,RefPtr<ResourceObject> & resourceObject)11499 bool JSViewAbstract::CheckColor(
11500 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName,
11501 RefPtr<ResourceObject>& resourceObject)
11502 {
11503 // Color is undefined or null
11504 if (jsValue->IsUndefined() || jsValue->IsNull()) {
11505 return false;
11506 }
11507 // input type is not in [number, string, Resource]
11508 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
11509 return false;
11510 }
11511 // Correct type, incorrect value parsing
11512 if (!ParseJsColor(jsValue, result, resourceObject)) {
11513 return false;
11514 }
11515 return true;
11516 }
11517
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)11518 bool JSViewAbstract::CheckLength(
11519 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
11520 {
11521 RefPtr<ResourceObject> resourceObject;
11522 return CheckLength(jsValue, result, componentName, propName, resourceObject);
11523 }
11524
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName,RefPtr<ResourceObject> & resourceObject)11525 bool JSViewAbstract::CheckLength(
11526 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName,
11527 RefPtr<ResourceObject>& resourceObject)
11528 {
11529 // Length is undefined or null
11530 if (jsValue->IsUndefined() || jsValue->IsNull()) {
11531 return false;
11532 }
11533 // input type is not in [number, string, Resource]
11534 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
11535 return false;
11536 }
11537 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
11538 return ParseJsDimensionVpNG(jsValue, result, resourceObject);
11539 }
11540 // Correct type, incorrect value parsing
11541 if (!ParseJsDimensionVp(jsValue, result, resourceObject)) {
11542 return false;
11543 }
11544 return true;
11545 }
11546
11547 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)11548 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
11549 {
11550 JSRef<JSVal> arg = info[0];
11551 if (arg->IsUndefined() || arg->IsNull()) {
11552 std::vector<ObscuredReasons> reasons(0);
11553 ViewAbstractModel::GetInstance()->SetObscured(reasons);
11554 return;
11555 }
11556 if (!arg->IsArray()) {
11557 return;
11558 }
11559
11560 auto obscuredArray = JSRef<JSArray>::Cast(arg);
11561 size_t size = obscuredArray->Length();
11562 std::vector<ObscuredReasons> reasons(size);
11563 reasons.clear();
11564 for (size_t i = 0; i < size; i++) {
11565 JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
11566 if (reason->IsNumber()) {
11567 reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
11568 }
11569 }
11570
11571 ViewAbstractModel::GetInstance()->SetObscured(reasons);
11572 }
11573
11574 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)11575 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
11576 {
11577 auto sensitiveInfo = info[0];
11578 if (sensitiveInfo->IsUndefined()) {
11579 ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
11580 return;
11581 }
11582 bool sensitive = false;
11583 if (sensitiveInfo->IsBoolean()) {
11584 sensitive = sensitiveInfo->ToBoolean();
11585 }
11586 ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
11587 }
11588
JSRenderGroup(const JSCallbackInfo & info)11589 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
11590 {
11591 if (info.Length() != 1) {
11592 return;
11593 }
11594 bool isRenderGroup = false;
11595 if (info[0]->IsBoolean()) {
11596 isRenderGroup = info[0]->ToBoolean();
11597 }
11598 ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
11599 }
11600
JSRenderFit(const JSCallbackInfo & info)11601 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
11602 {
11603 if (info.Length() != 1) {
11604 return;
11605 }
11606 RenderFit renderFit = RenderFit::TOP_LEFT;
11607 if (info[0]->IsNumber()) {
11608 int32_t fitNumber = info[0]->ToNumber<int32_t>();
11609 if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
11610 fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
11611 renderFit = static_cast<RenderFit>(fitNumber);
11612 }
11613 }
11614 // how content fills the node duration implicit animation
11615 ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
11616 }
11617
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)11618 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
11619 {
11620 if (!jsValue->IsObject() || jsValue->IsString()) {
11621 return false;
11622 }
11623 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
11624 if (!jsObj->IsUndefined()) {
11625 JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
11626 JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
11627 if (bundle->IsString() && module->IsString()) {
11628 bundleName = bundle->ToString();
11629 moduleName = module->ToString();
11630 return true;
11631 }
11632 }
11633 return false;
11634 }
11635
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)11636 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
11637 {
11638 RefPtr<ResourceObject> resourceObj;
11639 return ParseBorderColorProps(args, colorProperty, resourceObj);
11640 }
11641
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty,RefPtr<ResourceObject> & resourceObj)11642 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args,
11643 NG::BorderColorProperty& colorProperty, RefPtr<ResourceObject>& resourceObj)
11644 {
11645 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
11646 return false;
11647 }
11648 Color borderColor;
11649 if (ParseJsColor(args, borderColor, resourceObj)) {
11650 colorProperty.SetColor(borderColor);
11651 return true;
11652 } else if (args->IsObject()) {
11653 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
11654 CommonColor commonColor;
11655 auto isLocalizedEdgeColor = ParseCommonEdgeColors(obj, commonColor);
11656 colorProperty.topColor = commonColor.top;
11657 colorProperty.bottomColor = commonColor.bottom;
11658 if (isLocalizedEdgeColor) {
11659 colorProperty.startColor = commonColor.left;
11660 colorProperty.endColor = commonColor.right;
11661 } else {
11662 colorProperty.leftColor = commonColor.left;
11663 colorProperty.rightColor = commonColor.right;
11664 }
11665 colorProperty.multiValued = true;
11666 RegisterBorderColorRes(colorProperty, commonColor, isLocalizedEdgeColor);
11667 return true;
11668 }
11669 return false;
11670 }
11671
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)11672 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
11673 {
11674 RefPtr<ResourceObject> resourceObj;
11675 return ParseBorderWidthProps(args, borderWidthProperty, resourceObj);
11676 }
11677
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty,RefPtr<ResourceObject> & resourceObj)11678 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args,
11679 NG::BorderWidthProperty& borderWidthProperty, RefPtr<ResourceObject>& resourceObj)
11680 {
11681 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
11682 return false;
11683 }
11684 CalcDimension borderWidth;
11685 if (ParseJsDimensionVpNG(args, borderWidth, resourceObj, true)) {
11686 if (borderWidth.IsNegative()) {
11687 borderWidth.Reset();
11688 }
11689 borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth,
11690 std::nullopt, std::nullopt});
11691 return true;
11692 } else if (args->IsObject()) {
11693 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
11694 CommonCalcDimension commonCalcDimension;
11695 ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
11696 borderWidthProperty.topDimen = commonCalcDimension.top;
11697 borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
11698 borderWidthProperty.leftDimen = commonCalcDimension.left;
11699 borderWidthProperty.rightDimen = commonCalcDimension.right;
11700 borderWidthProperty.multiValued = true;
11701 if (SystemProperties::ConfigChangePerform()) {
11702 ParseEdgeWidthsResObjFunc(borderWidthProperty,
11703 commonCalcDimension.leftResObj, commonCalcDimension.rightResObj,
11704 commonCalcDimension.topResObj, commonCalcDimension.bottomResObj);
11705 }
11706 return true;
11707 }
11708 return false;
11709 }
11710
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)11711 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
11712 {
11713 if (!args->IsObject() && !args->IsNumber()) {
11714 return false;
11715 }
11716 if (args->IsObject()) {
11717 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
11718 auto leftValue = obj->GetProperty("left");
11719 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
11720 ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
11721 }
11722 auto rightValue = obj->GetProperty("right");
11723 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
11724 ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
11725 }
11726 auto topValue = obj->GetProperty("top");
11727 if (!topValue->IsUndefined() && topValue->IsNumber()) {
11728 ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
11729 }
11730 auto bottomValue = obj->GetProperty("bottom");
11731 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
11732 ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
11733 }
11734 borderStyleProperty.multiValued = true;
11735 return true;
11736 }
11737 std::optional<BorderStyle> borderStyle;
11738 if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
11739 borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
11740 return true;
11741 }
11742 return false;
11743 }
11744
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)11745 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
11746 {
11747 std::optional<CalcDimension> radiusTopLeft;
11748 std::optional<CalcDimension> radiusTopRight;
11749 std::optional<CalcDimension> radiusBottomLeft;
11750 std::optional<CalcDimension> radiusBottomRight;
11751 CalcDimension topLeft;
11752 RefPtr<ResourceObject> topStartResObj;
11753 if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, topStartResObj, true)) {
11754 radiusTopLeft = topLeft;
11755 }
11756 CalcDimension topRight;
11757 RefPtr<ResourceObject> topEndResObj;
11758 if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, topEndResObj, true)) {
11759 radiusTopRight = topRight;
11760 }
11761 CalcDimension bottomLeft;
11762 RefPtr<ResourceObject> bottomStartResObj;
11763 if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, bottomStartResObj, true)) {
11764 radiusBottomLeft = bottomLeft;
11765 }
11766 CalcDimension bottomRight;
11767 RefPtr<ResourceObject> bottomEndResObj;
11768 if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, bottomEndResObj, true)) {
11769 radiusBottomRight = bottomRight;
11770 }
11771 CheckLengthMetrics(object);
11772 radius.radiusTopLeft = radiusTopLeft;
11773 radius.radiusTopRight = radiusTopRight;
11774 radius.radiusBottomLeft = radiusBottomLeft;
11775 radius.radiusBottomRight = radiusBottomRight;
11776 radius.multiValued = true;
11777 RegisterRadiusRes(radius, topStartResObj, topEndResObj, bottomStartResObj, bottomEndResObj);
11778 return;
11779 }
11780
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius,bool notNegative)11781 void JSViewAbstract::ParseCommonBorderRadiusProps(
11782 const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius, bool notNegative)
11783 {
11784 if (CheckLengthMetrics(object)) {
11785 std::optional<CalcDimension> radiusTopStart;
11786 std::optional<CalcDimension> radiusTopEnd;
11787 std::optional<CalcDimension> radiusBottomStart;
11788 std::optional<CalcDimension> radiusBottomEnd;
11789 if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
11790 JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
11791 CalcDimension calcDimension;
11792 if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
11793 CheckDimensionUnit(calcDimension, false, notNegative);
11794 radiusTopStart = calcDimension;
11795 }
11796 }
11797 if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
11798 JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
11799 CalcDimension calcDimension;
11800 if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
11801 CheckDimensionUnit(calcDimension, false, notNegative);
11802 radiusTopEnd = calcDimension;
11803 }
11804 }
11805 if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
11806 JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
11807 CalcDimension calcDimension;
11808 if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
11809 CheckDimensionUnit(calcDimension, false, notNegative);
11810 radiusBottomStart = calcDimension;
11811 }
11812 }
11813 if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
11814 JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
11815 CalcDimension calcDimension;
11816 if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
11817 CheckDimensionUnit(calcDimension, false, notNegative);
11818 radiusBottomEnd = calcDimension;
11819 }
11820 }
11821 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
11822 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
11823 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
11824 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
11825 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
11826 radius.multiValued = true;
11827 return;
11828 }
11829 ParseBorderRadiusProps(object, radius);
11830 }
11831
11832
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius,bool notNegative)11833 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius, bool notNegative)
11834 {
11835 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
11836 return false;
11837 }
11838 CalcDimension borderRadius;
11839 if (ParseJsDimensionVpNG(args, borderRadius, true)) {
11840 radius = NG::BorderRadiusProperty(borderRadius);
11841 radius.multiValued = false;
11842 } else if (args->IsObject()) {
11843 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
11844 ParseCommonBorderRadiusProps(object, radius, notNegative);
11845 } else {
11846 return false;
11847 }
11848 return true;
11849 }
11850
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)11851 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
11852 {
11853 JSRef<JSVal> arg = info[0];
11854 if (!arg->IsObject()) {
11855 return;
11856 }
11857 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
11858 auto vm = info.GetVm();
11859 auto globalObj = JSNApi::GetGlobalObject(vm);
11860 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
11861 JsiValue jsiValue(globalFunc);
11862 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11863 if (globalFuncRef->IsFunction()) {
11864 auto modifierObj = obj->GetProperty("modifier");
11865 if (modifierObj->IsUndefined()) {
11866 option.onApply = nullptr;
11867 } else {
11868 RefPtr<JsFunction> jsFunc =
11869 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11870 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11871 modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11872 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11873 auto node = frameNode.Upgrade();
11874 JSRef<JSVal> params[SECOND_INDEX];
11875 params[0] = modifier;
11876 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11877 PipelineContext::SetCallBackNode(node);
11878 func->ExecuteJS(SECOND_INDEX, params);
11879 };
11880 option.onApply = onApply;
11881 }
11882 }
11883 }
11884
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)11885 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
11886 {
11887 if (!info[0]->IsObject()) {
11888 return;
11889 }
11890 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
11891 auto numberBadge = obj->GetProperty("numberBadge");
11892 if (!numberBadge->IsEmpty()) {
11893 if (numberBadge->IsNumber()) {
11894 int64_t number = numberBadge->ToNumber<int64_t>();
11895 if (number < 0 || number > INT_MAX) {
11896 option.isNumber = false;
11897 option.isShowBadge = true;
11898 } else {
11899 option.isNumber = true;
11900 option.badgeNumber = numberBadge->ToNumber<int>();
11901 }
11902 } else if (numberBadge->IsBoolean()) {
11903 option.isNumber = false;
11904 option.isShowBadge = numberBadge->ToBoolean();
11905 }
11906 } else {
11907 option.isNumber = false;
11908 option.isShowBadge = true;
11909 }
11910 }
11911
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)11912 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
11913 {
11914 // Parse cornerRadius.
11915 auto cornerRadiusValue = obj->GetProperty("cornerRadius");
11916 NG::BorderRadiusProperty radius;
11917 if (ParseBorderRadius(cornerRadiusValue, radius)) {
11918 properties.borderRadius = radius;
11919 }
11920 // Parse border width
11921 auto borderWidthValue = obj->GetProperty("borderWidth");
11922 NG::BorderWidthProperty borderWidth;
11923 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
11924 properties.borderWidth = borderWidth;
11925 auto colorValue = obj->GetProperty("borderColor");
11926 NG::BorderColorProperty borderColor;
11927 if (ParseBorderColorProps(colorValue, borderColor)) {
11928 properties.borderColor = borderColor;
11929 } else {
11930 borderColor.SetColor(Color::BLACK);
11931 properties.borderColor = borderColor;
11932 }
11933 // Parse border style
11934 auto styleValue = obj->GetProperty("borderStyle");
11935 NG::BorderStyleProperty borderStyle;
11936 if (ParseBorderStyleProps(styleValue, borderStyle)) {
11937 properties.borderStyle = borderStyle;
11938 } else {
11939 properties.borderStyle = NG::BorderStyleProperty(
11940 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
11941 }
11942 }
11943 auto shadowValue = obj->GetProperty("shadow");
11944 Shadow shadow;
11945 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
11946 properties.shadow = shadow;
11947 }
11948 auto widthValue = obj->GetProperty("width");
11949 CalcDimension width;
11950 if (ParseJsDimensionVpNG(widthValue, width, true)) {
11951 properties.width = width;
11952 }
11953 auto heightValue = obj->GetProperty("height");
11954 CalcDimension height;
11955 if (ParseJsDimensionVpNG(heightValue, height, true)) {
11956 properties.height = height;
11957 }
11958 }
11959
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx,JSRef<JSObject> modifier)11960 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
11961 const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx, JSRef<JSObject> modifier)
11962 {
11963 std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx, modifier](
11964 NG::DrawingContext& context) -> void {
11965 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
11966 if (modifier->IsEmpty()) {
11967 return;
11968 }
11969 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
11970 objectTemplate->SetInternalFieldCount(1);
11971 JSRef<JSObject> contextObj = objectTemplate->NewInstance();
11972 JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
11973 sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
11974 sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
11975 contextObj->SetPropertyObject("size", sizeObj);
11976
11977 JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
11978 sizeInPxObj->SetProperty<float>("height", context.height);
11979 sizeInPxObj->SetProperty<float>("width", context.width);
11980 contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
11981
11982 auto engine = EngineHelper::GetCurrentEngine();
11983 CHECK_NULL_VOID(engine);
11984 NativeEngine* nativeEngine = engine->GetNativeEngine();
11985 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
11986 ScopeRAII scope(env);
11987
11988 auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
11989 OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
11990 napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
11991 if (unwrapCanvas) {
11992 unwrapCanvas->SaveCanvas();
11993 unwrapCanvas->ClipCanvas(context.width, context.height);
11994 }
11995 JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
11996 contextObj->SetPropertyObject("canvas", jsCanvasVal);
11997
11998 auto jsVal = JSRef<JSVal>::Cast(contextObj);
11999 panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
12000 JSValueWrapper valueWrapper = value;
12001 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
12002
12003 napi_wrap(
12004 env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
12005
12006 JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
12007 if (unwrapCanvas) {
12008 unwrapCanvas->RestoreCanvas();
12009 unwrapCanvas->ResetCanvas();
12010 }
12011 };
12012 return drawCallback;
12013 }
12014
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)12015 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
12016 {
12017 auto* vm = info.GetVm();
12018 return [vm, nodeId](const std::string& key) -> std::string {
12019 std::string resultString = std::string();
12020 CHECK_NULL_RETURN(vm, resultString);
12021 panda::LocalScope scope(vm);
12022 auto global = JSNApi::GetGlobalObject(vm);
12023 auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
12024 if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
12025 return resultString;
12026 }
12027 auto obj = getCustomProperty->ToObject(vm);
12028 panda::Local<panda::FunctionRef> func = obj;
12029 panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
12030 panda::StringRef::NewFromUtf8(vm, key.c_str()) };
12031 auto function = panda::CopyableGlobal(vm, func);
12032 auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
12033 if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
12034 return resultString;
12035 }
12036 auto value = callValue->ToString(vm)->ToString(vm);
12037 return value;
12038 };
12039 }
12040
JsGetCustomMapFunc(const JSCallbackInfo & info,int32_t nodeId)12041 std::function<std::string()> JsGetCustomMapFunc(const JSCallbackInfo& info, int32_t nodeId)
12042 {
12043 auto* vm = info.GetVm();
12044 return [vm, nodeId]() -> std::string {
12045 std::string resultString = std::string();
12046 CHECK_NULL_RETURN(vm, resultString);
12047 panda::LocalScope scope(vm);
12048 auto global = JSNApi::GetGlobalObject(vm);
12049 auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyMapString__"));
12050 if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
12051 return resultString;
12052 }
12053 auto obj = getCustomProperty->ToObject(vm);
12054 panda::Local<panda::FunctionRef> func = obj;
12055 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
12056 auto function = panda::CopyableGlobal(vm, func);
12057 auto callValue = function->Call(vm, function.ToLocal(), params, 1);
12058 if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
12059 return resultString;
12060 }
12061 auto value = callValue->ToString(vm)->ToString(vm);
12062 return value;
12063 };
12064 }
12065
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)12066 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
12067 {
12068 auto* vm = info.GetVm();
12069 panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
12070 info[1]->GetLocalHandle() };
12071 return [vm, params3]() -> bool {
12072 CHECK_NULL_RETURN(vm, false);
12073 panda::LocalScope scope(vm);
12074 auto global = JSNApi::GetGlobalObject(vm);
12075 auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
12076 if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
12077 return false;
12078 }
12079 auto obj = setCustomProperty->ToObject(vm);
12080 panda::Local<panda::FunctionRef> func = obj;
12081 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
12082 auto nodeId = frameNode->GetId();
12083 auto function = panda::CopyableGlobal(vm, func);
12084 auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
12085 if (customPropertyExisted) {
12086 frameNode->SetCustomPropertyMapFlagByKey(params3[1]->ToString(vm)->ToString(vm));
12087 frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
12088 CHECK_NULL_VOID(vm);
12089 panda::LocalScope scope(vm);
12090 auto global = JSNApi::GetGlobalObject(vm);
12091 auto removeCustomProperty =
12092 global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
12093 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
12094 return;
12095 }
12096 auto obj = removeCustomProperty->ToObject(vm);
12097 panda::Local<panda::FunctionRef> func = obj;
12098 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
12099 auto function = panda::CopyableGlobal(vm, func);
12100 function->Call(vm, function.ToLocal(), params, 1);
12101 });
12102 }
12103 return true;
12104 };
12105 }
12106
JsCustomProperty(const JSCallbackInfo & info)12107 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
12108 {
12109 if (info[0]->GetLocalHandle()->IsUndefined()) {
12110 return;
12111 }
12112 auto* vm = info.GetVm();
12113 CHECK_NULL_VOID(vm);
12114 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
12115 auto nodeId = frameNode->GetId();
12116 auto getFunc = ParseJsGetFunc(info, nodeId);
12117 auto func = ParseJsFunc(info, nodeId);
12118 auto getMapFunc = JsGetCustomMapFunc(info, nodeId);
12119 frameNode->SetJSCustomProperty(func, getFunc, std::move(getMapFunc));
12120 }
12121
JsLinearGradient(const JSCallbackInfo & info)12122 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
12123 {
12124 ViewAbstractModel::GetInstance()->RemoveResObj("LinearGradient.gradient");
12125 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
12126 auto jsVal = info[0];
12127 if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
12128 NG::Gradient newGradient;
12129 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
12130 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
12131 return;
12132 }
12133 NG::Gradient newGradient;
12134 NewJsLinearGradient(info, newGradient);
12135 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
12136 }
12137
JsGestureModifier(const JSCallbackInfo & info)12138 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
12139 {
12140 auto* vm = info.GetExecutionContext().vm_;
12141 CHECK_NULL_VOID(vm);
12142 auto global = JSNApi::GetGlobalObject(vm);
12143 auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
12144 if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
12145 return;
12146 }
12147 auto obj = gestureModifier->ToObject(vm);
12148 panda::Local<panda::FunctionRef> func = obj;
12149 auto thisObj = info.This()->GetLocalHandle();
12150 panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
12151 func->Call(vm, thisObj, params, 1);
12152 }
12153
SetBackgroundImageResizableUpdateFunc(ImageResizableSlice & sliceResult,const RefPtr<ResourceObject> & resObj,std::string direction)12154 void SetBackgroundImageResizableUpdateFunc(
12155 ImageResizableSlice& sliceResult, const RefPtr<ResourceObject>& resObj, std::string direction)
12156 {
12157 if (direction.empty()) {
12158 return;
12159 }
12160 if (!resObj) {
12161 sliceResult.RemoveResource("backgroundImageResizable");
12162 return;
12163 }
12164 auto&& updateFunc = [direction](const RefPtr<ResourceObject>& resObj, ImageResizableSlice& sliceResult) {
12165 CHECK_NULL_VOID(resObj);
12166 CalcDimension sliceDimension;
12167 ResourceParseUtils::ParseResDimensionVp(resObj, sliceDimension);
12168 if (direction == "Left") {
12169 sliceResult.left = sliceDimension;
12170 } else if (direction == "Right") {
12171 sliceResult.right = sliceDimension;
12172 } else if (direction == "Top") {
12173 sliceResult.top = sliceDimension;
12174 } else if (direction == "Bottom") {
12175 sliceResult.bottom = sliceDimension;
12176 }
12177 };
12178 sliceResult.AddResource("backgroundImageResizable" + direction, resObj, std::move(updateFunc));
12179 }
12180
JsBackgroundImageResizable(const JSCallbackInfo & info)12181 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
12182 {
12183 auto infoObj = info[0];
12184 ImageResizableSlice sliceResult;
12185 if (!infoObj->IsObject()) {
12186 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12187 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageResizableSlice");
12188 return;
12189 }
12190 JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
12191 if (resizableObject->IsEmpty()) {
12192 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12193 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageResizableSlice");
12194 return;
12195 }
12196 auto sliceValue = resizableObject->GetProperty("slice");
12197 if (!sliceValue->IsObject()) {
12198 return;
12199 }
12200 JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
12201 if (sliceObj->IsEmpty()) {
12202 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12203 ViewAbstractModel::GetInstance()->ClearResObj("backgroundImageResizableSlice");
12204 return;
12205 }
12206 for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
12207 auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
12208 CalcDimension sliceDimension;
12209 RefPtr<ResourceObject> resObj;
12210 if (!ParseJsDimensionVp(sliceSize, sliceDimension, resObj)) {
12211 continue;
12212 }
12213 if (!sliceDimension.IsValid()) {
12214 continue;
12215 }
12216 switch (static_cast<BorderImageDirection>(i)) {
12217 case BorderImageDirection::LEFT:
12218 sliceResult.left = sliceDimension;
12219 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Left");
12220 break;
12221 case BorderImageDirection::RIGHT:
12222 sliceResult.right = sliceDimension;
12223 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Right");
12224 break;
12225 case BorderImageDirection::TOP:
12226 sliceResult.top = sliceDimension;
12227 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Top");
12228 break;
12229 case BorderImageDirection::BOTTOM:
12230 sliceResult.bottom = sliceDimension;
12231 SetBackgroundImageResizableUpdateFunc(sliceResult, resObj, "Bottom");
12232 break;
12233 default:
12234 break;
12235 }
12236 }
12237 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
12238 }
12239
JsOnFocus(const JSCallbackInfo & args)12240 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
12241 {
12242 JSRef<JSVal> arg = args[0];
12243 if (arg->IsUndefined() && IsDisableEventVersion()) {
12244 ViewAbstractModel::GetInstance()->DisableOnFocus();
12245 return;
12246 }
12247 if (!arg->IsFunction()) {
12248 return;
12249 }
12250 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
12251 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12252 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
12253 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12254 ACE_SCORING_EVENT("onFocus");
12255 PipelineContext::SetCallBackNode(node);
12256 func->Execute();
12257 };
12258
12259 ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
12260 }
12261
JsOnBlur(const JSCallbackInfo & args)12262 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
12263 {
12264 JSRef<JSVal> arg = args[0];
12265 if (arg->IsUndefined() && IsDisableEventVersion()) {
12266 ViewAbstractModel::GetInstance()->DisableOnBlur();
12267 return;
12268 }
12269 if (!arg->IsFunction()) {
12270 return;
12271 }
12272 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
12273 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12274 auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
12275 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12276 ACE_SCORING_EVENT("onBlur");
12277 PipelineContext::SetCallBackNode(node);
12278 func->Execute();
12279 };
12280
12281 ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
12282 }
12283
JsTabIndex(const JSCallbackInfo & info)12284 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
12285 {
12286 JSRef<JSVal> arg = info[0];
12287 if (!arg->IsNumber()) {
12288 return;
12289 }
12290 ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
12291 }
12292
JsFocusOnTouch(const JSCallbackInfo & info)12293 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
12294 {
12295 JSRef<JSVal> arg = info[0];
12296 if (!arg->IsBoolean()) {
12297 return;
12298 }
12299 auto isFocusOnTouch = arg->ToBoolean();
12300 ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
12301 }
12302
JsDefaultFocus(const JSCallbackInfo & info)12303 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
12304 {
12305 JSRef<JSVal> arg = info[0];
12306 if (!arg->IsBoolean()) {
12307 return;
12308 }
12309 auto isDefaultFocus = arg->ToBoolean();
12310 ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
12311 }
12312
JsGroupDefaultFocus(const JSCallbackInfo & info)12313 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
12314 {
12315 JSRef<JSVal> arg = info[0];
12316 if (!arg->IsBoolean()) {
12317 return;
12318 }
12319 auto isGroupDefaultFocus = arg->ToBoolean();
12320 ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
12321 }
12322
JsKey(const std::string & key)12323 void JSViewAbstract::JsKey(const std::string& key)
12324 {
12325 ViewAbstractModel::GetInstance()->SetInspectorId(key);
12326 }
12327
JsId(const JSCallbackInfo & info)12328 void JSViewAbstract::JsId(const JSCallbackInfo& info)
12329 {
12330 JSRef<JSVal> arg = info[0];
12331 if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
12332 return;
12333 }
12334 std::string id = arg->ToString();
12335 if (id.empty()) {
12336 return;
12337 }
12338 JsKey(id);
12339 }
12340
JsRestoreId(int32_t restoreId)12341 void JSViewAbstract::JsRestoreId(int32_t restoreId)
12342 {
12343 ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
12344 }
12345
JsDebugLine(const JSCallbackInfo & info)12346 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
12347 {
12348 std::string debugLine;
12349 auto length = info.Length();
12350 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
12351
12352 if (length == 1) { // deprecated version of debug line
12353 auto jsVal = info[0];
12354 if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
12355 return;
12356 }
12357 debugLine = jsVal->ToString();
12358 } else if (length == 2) { // debug line with extra package name
12359 auto line = info[0];
12360 auto packageName = info[1];
12361 if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
12362 !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
12363 return;
12364 }
12365 auto json = JsonUtil::Create(true);
12366 json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
12367 json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
12368 debugLine = json->ToString();
12369 }
12370
12371 ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
12372 }
12373
JsOpacityPassThrough(const JSCallbackInfo & info)12374 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
12375 {
12376 double opacity = 1.0;
12377 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
12378 if (ParseJsDouble(info[0], opacity)) {
12379 opacity = std::clamp(opacity, 0.0, 1.0);
12380 }
12381 } else {
12382 if (!ParseJsDouble(info[0], opacity)) {
12383 return;
12384 }
12385 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
12386 opacity = 1.0;
12387 }
12388 }
12389
12390 ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
12391 }
12392
JsTransitionPassThrough(const JSCallbackInfo & info)12393 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
12394 {
12395 if (info.Length() == 0) {
12396 ViewAbstractModel::GetInstance()->SetTransition(
12397 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
12398 return;
12399 }
12400 if (!info[0]->IsObject()) {
12401 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
12402 ViewAbstractModel::GetInstance()->CleanTransition();
12403 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
12404 }
12405 return;
12406 }
12407 auto obj = JSRef<JSObject>::Cast(info[0]);
12408 if (!obj->GetProperty("successor_")->IsUndefined()) {
12409 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
12410 std::function<void(bool)> finishCallback;
12411 if (info.Length() > 1 && info[1]->IsFunction()) {
12412 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
12413 }
12414 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
12415 return;
12416 }
12417 auto options = ParseJsTransition(obj);
12418 ViewAbstractModel::GetInstance()->SetTransition(options, true);
12419 }
12420
JsFocusScopeId(const JSCallbackInfo & info)12421 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
12422 {
12423 if (info.Length() == 0) {
12424 return;
12425 }
12426
12427 std::string focusScopeId;
12428 if (info[0]->IsString()) {
12429 focusScopeId = info[0]->ToString();
12430 }
12431
12432 bool isGroup = false;
12433 if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
12434 info[1]->IsBoolean()) {
12435 isGroup = info[1]->ToBoolean();
12436 }
12437 bool arrowKeyStepOut = true;
12438 if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() && // 2:args index.
12439 info[2]->IsBoolean()) { // 2:args index.
12440 arrowKeyStepOut = info[2]->ToBoolean(); // 2:args index.
12441 }
12442 ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
12443 }
12444
JsFocusScopePriority(const JSCallbackInfo & info)12445 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
12446 {
12447 if (info.Length() == 0) {
12448 return;
12449 }
12450
12451 if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
12452 return;
12453 }
12454 std::string focusScopeId = info[0]->ToString();
12455
12456 int32_t focusPriority = 0;
12457 if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
12458 info[1]->IsNumber()) {
12459 focusPriority = info[1]->ToNumber<int32_t>();
12460 }
12461 ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
12462 }
12463
JsBackground(const JSCallbackInfo & info)12464 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
12465 {
12466 if (info.Length() <= 0) {
12467 return;
12468 }
12469
12470 // parse custom background
12471 Color color = Color::TRANSPARENT;
12472 RefPtr<ResourceObject> backgroundColorResObj;
12473 std::function<void()> builderFunc;
12474 BackgroundType backgroundType = BackgroundType::COLOR;
12475 if (!ParseJsColor(info[0], color, backgroundColorResObj)) {
12476 ViewAbstractModel::GetInstance()->ClearResObj("customBackgroundColor");
12477 if (ParseBackgroundBuilder(info, info[0], builderFunc)) {
12478 backgroundType = BackgroundType::CUSTOM_BUILDER;
12479 } else {
12480 return;
12481 }
12482 }
12483
12484 // parse background options
12485 Alignment alignment = Alignment::CENTER;
12486 NG::LayoutSafeAreaEdge ignoreLayoutSafeAreaEdges =
12487 (BackgroundType::COLOR == backgroundType) ? NG::LAYOUT_SAFE_AREA_EDGE_ALL : NG::LAYOUT_SAFE_AREA_EDGE_NONE;
12488 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
12489 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
12490 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::ALIGN))) {
12491 auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
12492 auto value = align->ToNumber<int32_t>();
12493 alignment = ParseAlignment(value);
12494 }
12495 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::IGNORES_LAYOUT_SAFE_AREA_EDGES))) {
12496 auto safeAreaEdgesArray =
12497 object->GetProperty(static_cast<int32_t>(ArkUIIndex::IGNORES_LAYOUT_SAFE_AREA_EDGES));
12498 ignoreLayoutSafeAreaEdges = ParseJsLayoutSafeAreaEdgeArray(safeAreaEdgesArray, ignoreLayoutSafeAreaEdges);
12499 }
12500 }
12501
12502 // parameters parsed, set the properties parsed above
12503 if (BackgroundType::CUSTOM_BUILDER == backgroundType &&
12504 NG::LAYOUT_SAFE_AREA_EDGE_NONE == ignoreLayoutSafeAreaEdges) {
12505 ViewAbstractModel::GetInstance()->SetIsTransitionBackground(false);
12506 } else {
12507 ViewAbstractModel::GetInstance()->SetIsTransitionBackground(true);
12508 }
12509
12510 ViewAbstractModel::GetInstance()->SetIsBuilderBackground(BackgroundType::CUSTOM_BUILDER == backgroundType);
12511 ViewAbstractModel::GetInstance()->SetBackground(std::move(builderFunc));
12512 ViewAbstractModel::GetInstance()->SetBackgroundIgnoresLayoutSafeAreaEdges(ignoreLayoutSafeAreaEdges);
12513 ViewAbstractModel::GetInstance()->SetBackgroundAlign(alignment);
12514 if (SystemProperties::ConfigChangePerform()) {
12515 ViewAbstractModel::GetInstance()->SetCustomBackgroundColorWithResourceObj(color, backgroundColorResObj);
12516 } else {
12517 ViewAbstractModel::GetInstance()->SetCustomBackgroundColor(color);
12518 }
12519 }
12520
ParseBackgroundBuilder(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,std::function<void ()> & builderFunc)12521 bool JSViewAbstract::ParseBackgroundBuilder(
12522 const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, std::function<void()>& builderFunc)
12523 {
12524 if (!jsFunc->IsObject()) {
12525 return false;
12526 }
12527
12528 JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(jsFunc);
12529 auto contentObj = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
12530 if (!contentObj->IsFunction()) {
12531 return false;
12532 }
12533 auto jsBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(contentObj));
12534 CHECK_NULL_RETURN(jsBuilderFunc, false);
12535 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12536 builderFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsBuilderFunc), node = frameNode]() {
12537 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12538 ACE_SCORING_EVENT("BindBackground");
12539 PipelineContext::SetCallBackNode(node);
12540 func->Execute();
12541 };
12542
12543 return true;
12544 }
12545
ParseJsLayoutSafeAreaEdgeArray(const JSRef<JSArray> & jsSafeAreaEdges,NG::LayoutSafeAreaEdge defaultVal)12546 NG::LayoutSafeAreaEdge JSViewAbstract::ParseJsLayoutSafeAreaEdgeArray(
12547 const JSRef<JSArray>& jsSafeAreaEdges, NG::LayoutSafeAreaEdge defaultVal)
12548 {
12549 if (!jsSafeAreaEdges->IsArray()) {
12550 return defaultVal;
12551 }
12552
12553 static std::vector<uint32_t> layoutEdgeEnum {
12554 NG::LAYOUT_SAFE_AREA_EDGE_TOP,
12555 NG::LAYOUT_SAFE_AREA_EDGE_BOTTOM,
12556 NG::LAYOUT_SAFE_AREA_EDGE_START,
12557 NG::LAYOUT_SAFE_AREA_EDGE_END,
12558 NG::LAYOUT_SAFE_AREA_EDGE_VERTICAL,
12559 NG::LAYOUT_SAFE_AREA_EDGE_HORIZONTAL,
12560 NG::LAYOUT_SAFE_AREA_EDGE_ALL
12561 };
12562
12563 NG::LayoutSafeAreaEdge edges = NG::LAYOUT_SAFE_AREA_EDGE_NONE;
12564 for (size_t i = 0; i < jsSafeAreaEdges->Length(); ++i) {
12565 if (!jsSafeAreaEdges->GetValueAt(i)->IsNumber() ||
12566 jsSafeAreaEdges->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_EDGE_LIMIT) {
12567 return defaultVal;
12568 }
12569 edges |= layoutEdgeEnum[jsSafeAreaEdges->GetValueAt(i)->ToNumber<uint32_t>()];
12570 }
12571
12572 return edges;
12573 }
12574
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)12575 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
12576 std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
12577 {
12578 auto vm = info.GetVm();
12579 auto globalObj = JSNApi::GetGlobalObject(vm);
12580 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
12581 JsiValue jsiValue(globalFunc);
12582 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
12583 if (globalFuncRef->IsFunction()) {
12584 RefPtr<JsFunction> jsFunc =
12585 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
12586 if (!modifierObj->IsObject()) {
12587 symbolApply = nullptr;
12588 } else {
12589 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
12590 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
12591 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12592 auto node = frameNode.Upgrade();
12593 CHECK_NULL_VOID(node);
12594 JSRef<JSVal> params[2];
12595 params[0] = modifierParam;
12596 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
12597 PipelineContext::SetCallBackNode(node);
12598 func->ExecuteJS(2, params);
12599 };
12600 symbolApply = onApply;
12601 }
12602 }
12603 }
12604
ParseJsPropertyId(const JSRef<JSVal> & jsValue)12605 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
12606 {
12607 int32_t resId = 0;
12608 if (jsValue->IsObject()) {
12609 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
12610 JSRef<JSVal> tmp = jsObj->GetProperty("id");
12611 if (!tmp->IsNull() && tmp->IsNumber()) {
12612 resId = tmp->ToNumber<int32_t>();
12613 }
12614 }
12615 return resId;
12616 }
12617
JsVisualEffect(const JSCallbackInfo & info)12618 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
12619 {
12620 if (!info[0]->IsObject()) {
12621 return;
12622 }
12623 auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
12624 ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
12625 }
12626
JsBackgroundFilter(const JSCallbackInfo & info)12627 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
12628 {
12629 if (!info[0]->IsObject()) {
12630 return;
12631 }
12632 auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
12633 ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
12634 }
12635
JsForegroundFilter(const JSCallbackInfo & info)12636 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
12637 {
12638 if (!info[0]->IsObject()) {
12639 return;
12640 }
12641 auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
12642 ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
12643 }
12644
JsCompositingFilter(const JSCallbackInfo & info)12645 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
12646 {
12647 if (!info[0]->IsObject()) {
12648 return;
12649 }
12650 auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
12651 ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
12652 }
12653
ParseMenuItemsSymbolId(const JSRef<JSVal> & jsStartIcon,NG::MenuOptionsParam menuOptionsParam)12654 void JSViewAbstract::ParseMenuItemsSymbolId(const JSRef<JSVal>& jsStartIcon, NG::MenuOptionsParam menuOptionsParam)
12655 {
12656 if (StringToMenuItemType(menuOptionsParam.id) == MenuItemType::UNKNOWN) {
12657 uint32_t symbolId = 0;
12658 RefPtr<ResourceObject> resourceObject;
12659 if (ParseJsSymbolId(jsStartIcon, symbolId, resourceObject)) {
12660 menuOptionsParam.symbolId = symbolId;
12661 }
12662 } else {
12663 UpdateInfoById(menuOptionsParam, menuOptionsParam.id);
12664 }
12665 }
12666
ParseMenuItems(const JSRef<JSArray> & menuItemsArray,bool showShortcut)12667 std::vector<NG::MenuOptionsParam> JSViewAbstract::ParseMenuItems(const JSRef<JSArray>& menuItemsArray, bool showShortcut)
12668 {
12669 std::vector<NG::MenuOptionsParam> menuParams;
12670 for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
12671 auto menuItem = menuItemsArray->GetValueAt(i);
12672 if (!menuItem->IsObject()) {
12673 continue;
12674 }
12675 auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
12676 NG::MenuOptionsParam menuOptionsParam;
12677 auto jsContent = menuItemObject->GetProperty("content");
12678 std::string content;
12679 ParseJsString(jsContent, content);
12680 menuOptionsParam.content = content;
12681 auto jsTextMenuId = menuItemObject->GetProperty("id");
12682 std::string id;
12683 if (jsTextMenuId->IsObject()) {
12684 auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
12685 auto jsId = textMenuIdObject->GetProperty("id_");
12686 ParseJsString(jsId, id);
12687 }
12688 menuOptionsParam.id = id;
12689 auto jsLabelInfo = menuItemObject->GetProperty("labelInfo");
12690 std::string labelInfo;
12691 ParseJsString(jsLabelInfo, labelInfo);
12692 if (jsLabelInfo->IsString() || jsLabelInfo->IsObject()) {
12693 menuOptionsParam.labelInfo = labelInfo;
12694 }
12695 auto jsStartIcon = menuItemObject->GetProperty("icon");
12696 std::string icon;
12697 ParseJsMedia(jsStartIcon, icon);
12698 menuOptionsParam.icon = icon;
12699 ParseMenuItemsSymbolId(jsStartIcon, menuOptionsParam);
12700 menuParams.emplace_back(menuOptionsParam);
12701 }
12702 return menuParams;
12703 }
12704
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)12705 void JSViewAbstract::ParseOnCreateMenu(
12706 const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
12707 {
12708 if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
12709 return;
12710 }
12711 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12712 auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
12713 JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
12714 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
12715 instanceId = Container::CurrentId(), node = frameNode](
12716 const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
12717 ContainerScope scope(instanceId);
12718 std::vector<NG::MenuOptionsParam> menuParams;
12719 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
12720 auto pipelineContext = PipelineContext::GetCurrentContext();
12721 CHECK_NULL_RETURN(pipelineContext, menuParams);
12722 pipelineContext->UpdateCurrentActiveNode(node);
12723 auto textOverlayTheme = pipelineContext->GetTheme<TextOverlayTheme>();
12724 CHECK_NULL_RETURN(textOverlayTheme, menuParams);
12725 bool showShortcut = textOverlayTheme->GetShowShortcut();
12726 auto modifiedSystemMenuItems = systemMenuItems;
12727 UpdateOptionsInfo(modifiedSystemMenuItems);
12728 auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
12729 if (!menuItem->IsArray()) {
12730 return menuParams;
12731 }
12732 auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
12733 menuParams = ParseMenuItems(menuItemsArray, showShortcut);
12734 return menuParams;
12735 };
12736 onCreateMenuCallback = jsCallback;
12737 }
12738
ParseOnPrepareMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnPrepareMenuCallback & onPrepareMenuCallback)12739 void JSViewAbstract::ParseOnPrepareMenu(
12740 const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnPrepareMenuCallback& onPrepareMenuCallback)
12741 {
12742 if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
12743 return;
12744 }
12745 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12746 auto jsOnPrepareMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
12747 JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
12748 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnPrepareMenu),
12749 instanceId = Container::CurrentId(), node = frameNode](
12750 const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
12751 ContainerScope scope(instanceId);
12752 std::vector<NG::MenuOptionsParam> menuParams;
12753 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
12754 auto pipelineContext = PipelineContext::GetCurrentContext();
12755 CHECK_NULL_RETURN(pipelineContext, menuParams);
12756 auto textOverlayTheme = pipelineContext->GetTheme<TextOverlayTheme>();
12757 CHECK_NULL_RETURN(textOverlayTheme, menuParams);
12758 bool showShortcut = textOverlayTheme->GetShowShortcut();
12759
12760 pipelineContext->UpdateCurrentActiveNode(node);
12761 auto modifiedSystemMenuItems = systemMenuItems;
12762 UpdateOptionsInfo(modifiedSystemMenuItems);
12763 auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
12764 if (!menuItem->IsArray()) {
12765 return menuParams;
12766 }
12767 auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
12768 menuParams = ParseMenuItems(menuItemsArray, showShortcut);
12769 return menuParams;
12770 };
12771 onPrepareMenuCallback = jsCallback;
12772 }
12773
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)12774 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
12775 {
12776 JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
12777 uint32_t idx = 0;
12778 for (const auto& item : systemMenuItems) {
12779 systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
12780 }
12781 return systemMenuItemsArray;
12782 }
12783
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick,NG::OnPrepareMenuCallback & onPrepareMenuCallback)12784 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
12785 NG::OnMenuItemClickCallback& onMenuItemClick, NG::OnPrepareMenuCallback& onPrepareMenuCallback)
12786 {
12787 auto tmpInfo = info[0];
12788 if (info.Length() != 1 || !tmpInfo->IsObject()) {
12789 return false;
12790 }
12791 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
12792 auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
12793 auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
12794 ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
12795 auto jsValueOnPrepareMenu = menuOptionsObject->GetProperty("onPrepareMenu");
12796 ParseOnPrepareMenu(info, jsValueOnPrepareMenu, onPrepareMenuCallback);
12797
12798 auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
12799 if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
12800 return false;
12801 }
12802 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
12803 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
12804 onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
12805 node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
12806 ContainerScope scope(instanceId);
12807 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
12808 auto pipelineContext = PipelineContext::GetCurrentContext();
12809 CHECK_NULL_RETURN(pipelineContext, false);
12810 pipelineContext->UpdateCurrentActiveNode(node);
12811 auto paramArray = onMenuItemCallback(menuOptionsParam);
12812 if (paramArray->Length() != 2) {
12813 return false;
12814 }
12815 JSRef<JSVal> params[2];
12816 params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
12817 params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
12818 auto ret = func->ExecuteJS(2, params);
12819 if (ret->IsBoolean()) {
12820 return ret->ToBoolean();
12821 }
12822 return false;
12823 };
12824 onMenuItemClick = jsCallback;
12825 return true;
12826 }
12827
CreateJsTextMenuId(const std::string & id)12828 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
12829 {
12830 JSRef<JSObject> empty;
12831 auto engine = EngineHelper::GetCurrentEngine();
12832 CHECK_NULL_RETURN(engine, empty);
12833 NativeEngine* nativeEngine = engine->GetNativeEngine();
12834 CHECK_NULL_RETURN(nativeEngine, empty);
12835 auto env = reinterpret_cast<napi_env>(nativeEngine);
12836
12837 napi_value global;
12838 napi_status ret = napi_get_global(env, &global);
12839 if (ret != napi_ok) {
12840 return empty;
12841 }
12842 napi_value constructor;
12843 ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
12844 if (ret != napi_ok) {
12845 return empty;
12846 }
12847
12848 napi_value obj;
12849 napi_value menuId = nullptr;
12850
12851 ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
12852 if (ret != napi_ok) {
12853 return empty;
12854 }
12855 ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
12856 if (ret != napi_ok) {
12857 return empty;
12858 }
12859
12860 JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
12861 if (!value->IsObject()) {
12862 return empty;
12863 }
12864
12865 return JSRef<JSObject>::Cast(value);
12866 }
12867
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)12868 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
12869 {
12870 JSRef<JSArray> params = JSRef<JSArray>::New();
12871 params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
12872 params->SetValueAt(1, CreateJsTextRange(menuItemParam));
12873 return params;
12874 }
12875
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)12876 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
12877 {
12878 JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
12879 TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
12880 JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
12881 TextMenuItem->SetPropertyObject("id", obj);
12882 TextMenuItem->SetProperty<std::string>("labelInfo", menuItemParam.menuOptionsParam.labelInfo.value_or(""));
12883 if (menuItemParam.menuOptionsParam.symbolId.has_value() && menuItemParam.menuOptionsParam.symbolId.value() != 0) {
12884 TextMenuItem->SetProperty<uint32_t>("icon", menuItemParam.menuOptionsParam.symbolId.value());
12885 } else {
12886 TextMenuItem->SetProperty<std::string>("icon", menuItemParam.menuOptionsParam.icon.value_or(""));
12887 }
12888 return JSRef<JSVal>::Cast(TextMenuItem);
12889 }
12890
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)12891 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
12892 {
12893 JSRef<JSObject> textRange = JSRef<JSObject>::New();
12894 textRange->SetProperty<int32_t>("start", menuItemParam.start);
12895 textRange->SetProperty<int32_t>("end", menuItemParam.end);
12896 return JSRef<JSVal>::Cast(textRange);
12897 }
12898
OHOS_ACE_ParseJsMedia(void * value,void * resource)12899 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
12900 {
12901 napi_value napiValue = reinterpret_cast<napi_value>(value);
12902 ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
12903 if (!napiValue || !res) {
12904 return;
12905 }
12906 JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
12907 std::string src;
12908 std::string bundleName;
12909 std::string moduleName;
12910 JSViewAbstract::ParseJsMedia(jsVal, src);
12911 JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
12912 res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
12913 res->src = src;
12914 res->bundleName = bundleName;
12915 res->moduleName = moduleName;
12916 }
12917
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)12918 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
12919 std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
12920 {
12921 if (!modifierObj->IsObject()) {
12922 textStyleApply = nullptr;
12923 return;
12924 }
12925 auto vm = info.GetVm();
12926 auto globalObj = JSNApi::GetGlobalObject(vm);
12927 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
12928 JsiValue jsiValue(globalFunc);
12929 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
12930 if (!globalFuncRef->IsFunction()) {
12931 textStyleApply = nullptr;
12932 return;
12933 }
12934 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
12935 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
12936 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
12937 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
12938 auto node = frameNode.Upgrade();
12939 CHECK_NULL_VOID(node);
12940 JSRef<JSVal> params[2];
12941 params[0] = modifierParam;
12942 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
12943 PipelineContext::SetCallBackNode(node);
12944 func->ExecuteJS(2, params);
12945 };
12946 textStyleApply = onApply;
12947 }
12948
SetPixelRoundMode(const JSCallbackInfo & info)12949 void JSViewAbstract::SetPixelRoundMode(const JSCallbackInfo& info)
12950 {
12951 if (info.Length() < 1) {
12952 return;
12953 }
12954 if (!info[0]->IsNumber()) {
12955 return;
12956 }
12957 auto index = info[0]->ToNumber<uint8_t>();
12958 auto size = sizeof(PixelRoundMode) / sizeof(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
12959 if (index < 0 || index > size) {
12960 return;
12961 }
12962 PixelRoundMode pixelRoundMode = static_cast<PixelRoundMode>(index);
12963 auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
12964 CHECK_NULL_VOID(pipeline);
12965 pipeline->SetPixelRoundMode(pixelRoundMode);
12966 }
12967
GetPixelRoundMode()12968 uint8_t JSViewAbstract::GetPixelRoundMode()
12969 {
12970 auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
12971 return pipeline ? static_cast<uint8_t>(pipeline->GetPixelRoundMode())
12972 : static_cast<uint8_t>(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
12973 }
12974
UnRegisterResource(const std::string & key)12975 void JSViewAbstract::UnRegisterResource(const std::string& key)
12976 {
12977 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
12978 CHECK_NULL_VOID(frameNode);
12979 auto pattern = frameNode->GetPattern();
12980 CHECK_NULL_VOID(pattern);
12981 pattern->UnRegisterResource(key);
12982 }
12983
ParseDragSpringLoadingConfiguration(const JSRef<JSObject> & paramObj,const RefPtr<NG::DragSpringLoadingConfiguration> & config)12984 void JSViewAbstract::ParseDragSpringLoadingConfiguration(
12985 const JSRef<JSObject>& paramObj, const RefPtr<NG::DragSpringLoadingConfiguration>& config)
12986 {
12987 JSRef<JSObject> configuration = paramObj;
12988 auto setConfigurationPropertyIfValid =
12989 [&configuration, &config](const char* propName,
12990 std::function<void(const RefPtr<NG::DragSpringLoadingConfiguration>&, int32_t)> setter) {
12991 CHECK_NULL_VOID(propName);
12992 CHECK_NULL_VOID(config);
12993 CHECK_NULL_VOID(setter);
12994 auto propObj = configuration->GetProperty(propName);
12995 if (propObj->IsNumber()) {
12996 auto value = propObj->ToNumber<double>();
12997 if (!std::isnan(value) && value <= INT32_MAX && value >= 0) {
12998 setter(config, static_cast<int32_t>(value));
12999 }
13000 }
13001 };
13002 setConfigurationPropertyIfValid("stillTimeLimit", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config,
13003 int32_t value) { config->stillTimeLimit = value; });
13004 setConfigurationPropertyIfValid("updateInterval", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config,
13005 int32_t value) { config->updateInterval = value; });
13006 setConfigurationPropertyIfValid("updateNotifyCount", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config,
13007 int32_t value) { config->updateNotifyCount = value; });
13008 setConfigurationPropertyIfValid(
13009 "updateToFinishInterval", [](const RefPtr<NG::DragSpringLoadingConfiguration>& config, int32_t value) {
13010 config->updateToFinishInterval = value;
13011 });
13012 }
13013
SetBorderRadiusWithCheck(std::optional<NG::BorderRadiusProperty> & result,NG::BorderRadiusProperty & borderRadius)13014 void JSViewAbstract::SetBorderRadiusWithCheck(std::optional<NG::BorderRadiusProperty>& result,
13015 NG::BorderRadiusProperty& borderRadius)
13016 {
13017 if (borderRadius.radiusTopLeft.has_value() && !borderRadius.radiusTopLeft->IsNegative() &&
13018 borderRadius.radiusTopRight.has_value() && !borderRadius.radiusTopRight->IsNegative() &&
13019 borderRadius.radiusBottomLeft.has_value() && !borderRadius.radiusBottomLeft->IsNegative() &&
13020 borderRadius.radiusBottomRight.has_value() && !borderRadius.radiusBottomRight->IsNegative()) {
13021 result = borderRadius;
13022 }
13023 }
13024
CheckLengthMetrics(const JSRef<JSObject> & object)13025 bool JSViewAbstract::CheckLengthMetrics(const JSRef<JSObject>& object)
13026 {
13027 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
13028 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
13029 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
13030 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
13031 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
13032 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
13033 return true;
13034 }
13035 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
13036 if (jsTop->IsObject()) {
13037 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
13038 if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
13039 return true;
13040 }
13041 }
13042 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
13043 if (jsBottom->IsObject()) {
13044 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
13045 if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
13046 return true;
13047 }
13048 }
13049 return false;
13050 }
13051
13052 } // namespace OHOS::Ace::Framework
13053