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_on_child_touch_test_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
47 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
48 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
49 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
50 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
51 #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h"
52 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
53 #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h"
54 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
55 #include "bridge/declarative_frontend/engine/js_types.h"
56 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h"
57 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
58 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
59 #include "bridge/declarative_frontend/engine/js_converter.h"
60 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
61 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
62 #include "bridge/declarative_frontend/jsview/js_utils.h"
63 #include "bridge/declarative_frontend/jsview/js_view_context.h"
64 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
65 #include "bridge/declarative_frontend/jsview/js_layoutable_view.h"
66 #include "core/event/focus_axis_event.h"
67 #include "canvas_napi/js_canvas.h"
68 #ifdef SUPPORT_DIGITAL_CROWN
69 #include "bridge/declarative_frontend/engine/functions/js_crown_function.h"
70 #endif
71 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
72 #include "core/components/text_overlay/text_overlay_theme.h"
73 #include "core/components/theme/shadow_theme.h"
74 #ifdef PLUGIN_COMPONENT_SUPPORTED
75 #include "core/common/plugin_manager.h"
76 #endif
77 #include "interfaces/native/node/resource.h"
78
79 #include "core/common/card_scope.h"
80 #include "core/common/resource/resource_configuration.h"
81 #include "core/components_ng/base/view_abstract_model_ng.h"
82 #include "core/components_ng/base/view_stack_model.h"
83 #include "core/components_ng/base/inspector.h"
84 #include "core/event/key_event.h"
85
86 namespace OHOS::Ace::NG {
87 constexpr uint32_t DEFAULT_GRID_SPAN = 1;
88 constexpr int32_t DEFAULT_GRID_OFFSET = 0;
89 }
90
91 namespace OHOS::Ace {
92 namespace {
93 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
94 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
95 constexpr int32_t DIRECTION_COUNT = 4;
96 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
97 constexpr int NUM1 = 1;
98 constexpr int NUM2 = 2;
99 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
100 HoverModeAreaType::BOTTOM_SCREEN };
101 const std::string CUSTOM_SYMBOL_SUFFIX = "_CustomSymbol";
102 } // namespace
103
GetInstance()104 ViewAbstractModel* ViewAbstractModel::GetInstance()
105 {
106 #ifdef NG_BUILD
107 static NG::ViewAbstractModelNG instance;
108 return &instance;
109 #else
110 if (Container::IsCurrentUseNewPipeline()) {
111 static NG::ViewAbstractModelNG instance;
112 return &instance;
113 } else {
114 static Framework::ViewAbstractModelImpl instance;
115 return &instance;
116 }
117 #endif
118 }
119 } // namespace OHOS::Ace
120
121 namespace OHOS::Ace::Framework {
122 namespace {
123
124 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
125 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
126 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
127 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
128 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
129 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
130 constexpr int32_t MAX_ALIGN_VALUE = 8;
131 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
132 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
133 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
134 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
135 constexpr double FULL_DIMENSION = 100.0;
136 constexpr double HALF_DIMENSION = 50.0;
137 constexpr double ROUND_UNIT = 360.0;
138 constexpr double VISIBLE_RATIO_MIN = 0.0;
139 constexpr double VISIBLE_RATIO_MAX = 1.0;
140 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
141 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
142 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
143 constexpr int32_t SECOND_INDEX = 2;
144 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
145 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
146 constexpr float MAX_ANGLE = 360.0f;
147 constexpr float DEFAULT_BIAS = 0.5f;
148 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
149 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
150 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
151 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
152 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
153 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
154 const std::vector<int32_t> LENGTH_METRICS_KEYS {
155 static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
156 static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
157 const char* START_PROPERTY = "start";
158 const char* END_PROPERTY = "end";
159 const char* TOP_PROPERTY = "top";
160 const char* BOTTOM_PROPERTY = "bottom";
161 const char* LEFT_PROPERTY = "left";
162 const char* RIGHT_PROPERTY = "right";
163 const char* TOP_START_PROPERTY = "topStart";
164 const char* TOP_END_PROPERTY = "topEnd";
165 const char* BOTTOM_START_PROPERTY = "bottomStart";
166 const char* BOTTOM_END_PROPERTY = "bottomEnd";
167 const char* DEBUG_LINE_INFO_LINE = "$line";
168 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
169
170 enum class OperationType { COPY, PASTE, CUT, SELECT_ALL, UNKNOWN };
171
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)172 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
173 CalcDimension& centerX, CalcDimension& centerY)
174 {
175 double xVal = 1.0;
176 double yVal = 1.0;
177 double zVal = 1.0;
178 if (!jsValue->IsObject()) {
179 scaleX = static_cast<float>(xVal);
180 scaleY = static_cast<float>(yVal);
181 scaleZ = static_cast<float>(zVal);
182 CalcDimension length;
183 centerX = length;
184 centerY = length;
185 return;
186 }
187 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
188 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
189 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
190 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
191 scaleX = static_cast<float>(xVal);
192 scaleY = static_cast<float>(yVal);
193 scaleZ = static_cast<float>(zVal);
194 // if specify centerX
195 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
196 // if specify centerY
197 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
198 }
199
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)200 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
201 CalcDimension& translateZ)
202 {
203 if (!jsValue->IsObject()) {
204 return;
205 }
206 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
207 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
208 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
209 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
210 }
211
GetDefaultRotateVector(double & dx,double & dy,double & dz)212 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
213 {
214 dx = 0.0;
215 dy = 0.0;
216 dz = 0.0;
217 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
218 dz = 1.0;
219 }
220 }
221
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)222 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
223 {
224 if (!jsValue->IsObject()) {
225 return;
226 }
227 // default: dx, dy, dz (0.0, 0.0, 0.0)
228 double dxVal = 0.0;
229 double dyVal = 0.0;
230 double dzVal = 0.0;
231 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
232 auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
233 auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
234 auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
235 if (jsRotateX->IsUndefined()
236 && jsRotateY->IsUndefined()
237 && jsRotateZ->IsUndefined()) {
238 GetDefaultRotateVector(dxVal, dyVal, dzVal);
239 } else {
240 JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
241 JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
242 JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
243 }
244 rotate.xDirection = static_cast<float>(dxVal);
245 rotate.yDirection = static_cast<float>(dyVal);
246 rotate.zDirection = static_cast<float>(dzVal);
247 // if specify centerX
248 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
249 rotate.centerX)) {
250 rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
251 }
252 // if specify centerY
253 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
254 rotate.centerY)) {
255 rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
256 }
257 // if specify centerZ
258 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
259 rotate.centerZ)) {
260 rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
261 }
262 // if specify angle
263 JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
264 rotate.perspective = 0.0f;
265 JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
266 }
267
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)268 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
269 {
270 if (!jsValue->IsObject()) {
271 return false;
272 }
273
274 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
275 auto path = jsObj->GetPropertyValue<std::string>("path", "");
276 if (path.empty()) {
277 return false;
278 }
279 option.SetPath(path);
280 double from = 0.0;
281 double to = 1.0;
282 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
283 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
284 if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
285 from = 0.0;
286 }
287 if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
288 to = 1.0;
289 } else if (to < from) {
290 to = from;
291 }
292 option.SetBegin(static_cast<float>(from));
293 option.SetEnd(static_cast<float>(to));
294 option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
295 return true;
296 }
297
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)298 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
299 {
300 isAuto = false;
301 switch (modeValue) {
302 case static_cast<int32_t>(NG::DragPreviewMode::AUTO):
303 previewOption.ResetDragPreviewMode();
304 isAuto = true;
305 break;
306 case static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE):
307 previewOption.isScaleEnabled = false;
308 break;
309 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW):
310 previewOption.isDefaultShadowEnabled = true;
311 break;
312 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS):
313 previewOption.isDefaultRadiusEnabled = true;
314 break;
315 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DRAG_ITEM_GRAY_EFFECT):
316 previewOption.isDefaultDragItemGrayEffectEnabled = true;
317 break;
318 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_MULTI_TILE_EFFECT):
319 previewOption.isMultiTiled = true;
320 break;
321 case static_cast<int32_t>(NG::DragPreviewMode::ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW):
322 previewOption.isTouchPointCalculationBasedOnFinalPreviewEnable = true;
323 break;
324 default:
325 break;
326 }
327 }
328
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)329 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
330 BackgroundImagePosition& bgImgPosition)
331 {
332 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
333 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
334 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
335 }
336
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)337 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
338 {
339 auto index = pos + containCount;
340 if (index < 0) {
341 return std::string();
342 }
343
344 JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
345 if (type == "d") {
346 if (item->IsNumber()) {
347 return std::to_string(item->ToNumber<int32_t>());
348 } else if (item->IsObject()) {
349 int32_t result = 0;
350 JSViewAbstract::ParseJsInteger(item, result);
351 return std::to_string(result);
352 }
353 } else if (type == "s") {
354 if (item->IsString()) {
355 return item->ToString();
356 } else if (item->IsObject()) {
357 std::string result;
358 JSViewAbstract::ParseJsString(item, result);
359 return result;
360 }
361 } else if (type == "f") {
362 if (item->IsNumber()) {
363 return std::to_string(item->ToNumber<float>());
364 } else if (item->IsObject()) {
365 double result = 0.0;
366 JSViewAbstract::ParseJsDouble(item, result);
367 return std::to_string(result);
368 }
369 }
370 return std::string();
371 }
372
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)373 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
374 {
375 auto size = static_cast<int32_t>(params->Length());
376 if (containCount == size) {
377 return;
378 }
379 std::string::const_iterator start = originStr.begin();
380 std::string::const_iterator end = originStr.end();
381 std::smatch matches;
382 bool shortHolderType = false;
383 bool firstMatch = true;
384 int searchTime = 0;
385 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
386 std::string pos = matches[2];
387 std::string type = matches[4];
388 if (firstMatch) {
389 firstMatch = false;
390 shortHolderType = pos.length() == 0;
391 } else {
392 if (shortHolderType ^ (pos.length() == 0)) {
393 return;
394 }
395 }
396
397 std::string replaceContentStr;
398 if (shortHolderType) {
399 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
400 } else {
401 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
402 }
403
404 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
405 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
406 end = originStr.end();
407 searchTime++;
408 }
409 }
410
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)411 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y)
412 {
413 JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
414 JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
415 bool hasX = false;
416 bool hasY = false;
417 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
418 hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP);
419 hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP);
420 } else {
421 hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
422 hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
423 }
424 return hasX || hasY;
425 }
426
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)427 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
428 {
429 bool useEdges = false;
430 CalcDimension top;
431 CalcDimension left;
432 CalcDimension bottom;
433 CalcDimension right;
434 JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
435 JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
436 JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
437 JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
438 if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) {
439 edges.SetTop(top);
440 useEdges = true;
441 }
442 if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) {
443 edges.SetLeft(left);
444 useEdges = true;
445 }
446 if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) {
447 edges.SetBottom(bottom);
448 useEdges = true;
449 }
450 if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) {
451 edges.SetRight(right);
452 useEdges = true;
453 }
454 return useEdges;
455 }
456
457 decltype(JSViewAbstract::ParseJsLengthMetricsVp)* ParseJsLengthMetrics = JSViewAbstract::ParseJsLengthMetricsVp;
458
ParseJsLengthMetricsToDimension(const JSRef<JSObject> & obj,Dimension & result)459 void ParseJsLengthMetricsToDimension(const JSRef<JSObject>& obj, Dimension& result)
460 {
461 auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
462 if (!value->IsNumber()) {
463 return;
464 }
465 auto unit = DimensionUnit::VP;
466 auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
467 if (jsUnit->IsNumber()) {
468 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
469 }
470 CalcDimension dimension(value->ToNumber<double>(), unit);
471 result = dimension;
472 return;
473 }
474
CheckLengthMetrics(const JSRef<JSObject> & object)475 bool CheckLengthMetrics(const JSRef<JSObject>& object)
476 {
477 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
478 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
479 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
480 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
481 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
482 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
483 return true;
484 }
485 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
486 if (jsTop->IsObject()) {
487 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
488 if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
489 return true;
490 }
491 }
492 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
493 if (jsBottom->IsObject()) {
494 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
495 if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
496 return true;
497 }
498 }
499 return false;
500 }
501
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)502 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
503 {
504 bool useLocalizedEdges = false;
505 CalcDimension start;
506 CalcDimension end;
507 CalcDimension top;
508 CalcDimension bottom;
509
510 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
511 if (startVal->IsObject()) {
512 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
513 ParseJsLengthMetrics(startObj, start);
514 edges.start = start;
515 useLocalizedEdges = true;
516 }
517 JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
518 if (endVal->IsObject()) {
519 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
520 ParseJsLengthMetrics(endObj, end);
521 edges.end = end;
522 useLocalizedEdges = true;
523 }
524 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
525 if (topVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(topVal), top)) {
526 edges.SetTop(top);
527 useLocalizedEdges = true;
528 }
529 JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
530 if (bottomVal->IsObject() && ParseJsLengthMetrics(JSRef<JSObject>::Cast(bottomVal), bottom)) {
531 edges.SetBottom(bottom);
532 useLocalizedEdges = true;
533 }
534 return useLocalizedEdges;
535 }
536
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)537 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
538 {
539 bool useMarkAnchorPosition = false;
540 CalcDimension start;
541 CalcDimension top;
542
543 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
544 if (startVal->IsObject()) {
545 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
546 ParseJsLengthMetrics(startObj, start);
547 x = start;
548 useMarkAnchorPosition = true;
549 }
550 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
551 if (topVal->IsObject()) {
552 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
553 ParseJsLengthMetrics(topObj, top);
554 y = top;
555 useMarkAnchorPosition = true;
556 }
557 return useMarkAnchorPosition;
558 }
559
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)560 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
561 {
562 JSRef<JSVal> builder;
563 if (info->IsObject()) {
564 auto builderObj = JSRef<JSObject>::Cast(info);
565 builder = builderObj->GetProperty("builder");
566 } else if (info->IsFunction()) {
567 builder = info;
568 } else {
569 return nullptr;
570 }
571
572 if (!builder->IsFunction()) {
573 return nullptr;
574 }
575
576 return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
577 }
578
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)579 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
580 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
581 {
582 RefPtr<NG::ChainedTransitionEffect> effect;
583 if (effectOption->IsObject()) {
584 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
585 std::optional<float> angle;
586 ParseJsRotate(effectOption, rotate, angle);
587 if (angle.has_value()) {
588 rotate.angle = angle.value();
589 return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
590 }
591 }
592 return nullptr;
593 }
594
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)595 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
596 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
597 {
598 double opacity = 1.0;
599 if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
600 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
601 if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
602 opacity = 1.0;
603 }
604 } else {
605 opacity = std::clamp(opacity, 0.0, 1.0);
606 }
607 return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
608 }
609 return nullptr;
610 }
611
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)612 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
613 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
614 {
615 if (effectOption->IsObject()) {
616 // default: x, y, z (0.0, 0.0, 0.0)
617 NG::TranslateOptions translate;
618 ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
619 return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
620 }
621 return nullptr;
622 }
623
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)624 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
625 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
626 {
627 if (effectOption->IsObject()) {
628 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
629 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
630 ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
631 return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
632 }
633 return nullptr;
634 }
635
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)636 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
637 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
638 {
639 int32_t edge = 0;
640 if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
641 if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
642 edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
643 edge = static_cast<int32_t>(NG::TransitionEdge::START);
644 }
645 return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
646 }
647 return nullptr;
648 }
649
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)650 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
651 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
652 {
653 if (effectOption->IsObject()) {
654 auto effectObj = JSRef<JSObject>::Cast(effectOption);
655 auto appearJsVal = effectObj->GetProperty("appear");
656 auto disappearJsVal = effectObj->GetProperty("disappear");
657 RefPtr<NG::ChainedTransitionEffect> appearEffect;
658 RefPtr<NG::ChainedTransitionEffect> disappearEffect;
659 if (appearJsVal->IsObject()) {
660 auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
661 appearEffect = JSViewAbstract::ParseChainedTransition(appearObj, context);
662 }
663 if (disappearJsVal->IsObject()) {
664 auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
665 disappearEffect = JSViewAbstract::ParseChainedTransition(disappearObj, context);
666 }
667 return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
668 }
669 return nullptr;
670 }
671
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)672 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
673 {
674 CHECK_NULL_RETURN(pipelineContext, 0);
675 return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
676 }
677
678 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
679 const JSRef<JSVal>&, const JSExecutionContext&);
680
GetBundleNameFromContainer()681 std::string GetBundleNameFromContainer()
682 {
683 auto container = Container::Current();
684 CHECK_NULL_RETURN(container, "");
685 return container->GetBundleName();
686 }
687
GetModuleNameFromContainer()688 std::string GetModuleNameFromContainer()
689 {
690 auto container = Container::Current();
691 CHECK_NULL_RETURN(container, "");
692 return container->GetModuleName();
693 }
694
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)695 void CompleteResourceObjectFromParams(
696 int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
697 {
698 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
699 int32_t typeNum = -1;
700 if (type->IsNumber()) {
701 typeNum = type->ToNumber<int32_t>();
702 }
703
704 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
705 if (!args->IsArray()) {
706 return;
707 }
708 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
709 if (resId != UNKNOWN_RESOURCE_ID) {
710 return;
711 }
712 JSRef<JSVal> identity = params->GetValueAt(0);
713
714 bool isParseDollarResourceSuccess =
715 JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
716 if (!isParseDollarResourceSuccess) {
717 return;
718 }
719
720 std::regex resNameRegex(RESOURCE_NAME_PATTERN);
721 std::smatch resNameResults;
722 if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
723 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
724 }
725
726 if (typeNum == UNKNOWN_RESOURCE_TYPE) {
727 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
728 }
729 }
730
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)731 void CompleteResourceObjectFromId(
732 JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
733 {
734 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
735 if (!args->IsArray()) {
736 return;
737 }
738 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
739 auto paramCount = params->Length();
740 JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
741 if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
742 std::vector<JSRef<JSVal>> tmpParams;
743 for (uint32_t i = 0; i < paramCount; i++) {
744 auto param = params->GetValueAt(i);
745 tmpParams.insert(tmpParams.end(), param);
746 }
747 params->SetValueAt(0, name);
748 uint32_t paramIndex = 1;
749 if (!type->IsEmpty()) {
750 params->SetValueAt(paramIndex, type);
751 paramIndex++;
752 }
753 for (auto tmpParam : tmpParams) {
754 params->SetValueAt(paramIndex, tmpParam);
755 paramIndex++;
756 }
757 } else {
758 params->SetValueAt(0, name);
759 }
760 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
761 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
762 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
763 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
764 }
765 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
766 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
767 }
768 }
769
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)770 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
771 {
772 if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
773 checkDimension.Reset();
774 return;
775 }
776 if (notNegative && checkDimension.IsNegative()) {
777 checkDimension.Reset();
778 return;
779 }
780 }
781
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)782 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
783 {
784 Color left;
785 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
786 commonColor.left = left;
787 }
788 Color right;
789 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
790 commonColor.right = right;
791 }
792 Color top;
793 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
794 commonColor.top = top;
795 }
796 Color bottom;
797 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
798 commonColor.bottom = bottom;
799 }
800 }
801
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)802 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
803 {
804 Color start;
805 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) {
806 localizedColor.start = start;
807 }
808 Color end;
809 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) {
810 localizedColor.end = end;
811 }
812 Color top;
813 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
814 localizedColor.top = top;
815 }
816 Color bottom;
817 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
818 localizedColor.bottom = bottom;
819 }
820 }
821
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)822 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
823 {
824 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
825 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
826 LocalizedColor localizedColor;
827 ParseLocalizedEdgeColors(object, localizedColor);
828 commonColor.top = localizedColor.top;
829 commonColor.bottom = localizedColor.bottom;
830 commonColor.left = localizedColor.start;
831 commonColor.right = localizedColor.end;
832 return true;
833 }
834 ParseEdgeColors(object, commonColor);
835 return false;
836 }
837
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)838 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
839 {
840 CalcDimension left;
841 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
842 CheckDimensionUnit(left, true, notNegative);
843 commonCalcDimension.left = left;
844 }
845 CalcDimension right;
846 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
847 CheckDimensionUnit(right, true, notNegative);
848 commonCalcDimension.right = right;
849 }
850 CalcDimension top;
851 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
852 CheckDimensionUnit(top, true, notNegative);
853 commonCalcDimension.top = top;
854 }
855 CalcDimension bottom;
856 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
857 CheckDimensionUnit(bottom, true, notNegative);
858 commonCalcDimension.bottom = bottom;
859 }
860 }
861
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)862 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
863 bool notNegative, CalcDimension defaultValue)
864 {
865 CalcDimension left;
866 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) {
867 CheckDimensionUnit(left, notPercent, notNegative);
868 commonCalcDimension.left = left;
869 } else {
870 commonCalcDimension.left = defaultValue;
871 }
872 CalcDimension right;
873 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) {
874 CheckDimensionUnit(right, notPercent, notNegative);
875 commonCalcDimension.right = right;
876 } else {
877 commonCalcDimension.right = defaultValue;
878 }
879 CalcDimension top;
880 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) {
881 CheckDimensionUnit(top, notPercent, notNegative);
882 commonCalcDimension.top = top;
883 } else {
884 commonCalcDimension.top = defaultValue;
885 }
886 CalcDimension bottom;
887 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) {
888 CheckDimensionUnit(bottom, false, true);
889 commonCalcDimension.bottom = bottom;
890 } else {
891 commonCalcDimension.bottom = defaultValue;
892 }
893 }
894
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)895 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
896 bool notNegative)
897 {
898 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
899 if (jsStart->IsObject()) {
900 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
901 CalcDimension calcDimension;
902 if (ParseJsLengthMetrics(startObj, calcDimension)) {
903 CheckDimensionUnit(calcDimension, true, notNegative);
904 localizedCalcDimension.start = calcDimension;
905 }
906 }
907 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
908 if (jsEnd->IsObject()) {
909 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
910 CalcDimension calcDimension;
911 if (ParseJsLengthMetrics(endObj, calcDimension)) {
912 CheckDimensionUnit(calcDimension, true, notNegative);
913 localizedCalcDimension.end = calcDimension;
914 }
915 }
916 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
917 if (jsTop->IsObject()) {
918 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
919 CalcDimension calcDimension;
920 if (ParseJsLengthMetrics(topObj, calcDimension)) {
921 CheckDimensionUnit(calcDimension, true, notNegative);
922 localizedCalcDimension.top = calcDimension;
923 }
924 }
925 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
926 if (jsBottom->IsObject()) {
927 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
928 CalcDimension calcDimension;
929 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
930 CheckDimensionUnit(calcDimension, true, notNegative);
931 localizedCalcDimension.bottom = calcDimension;
932 }
933 }
934 }
935
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)936 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
937 {
938 if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
939 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
940 CalcDimension calcDimension;
941 if (ParseJsLengthMetrics(startObj, calcDimension)) {
942 CheckDimensionUnit(calcDimension, false, true);
943 localizedCalcDimension.start = calcDimension;
944 }
945 }
946 if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
947 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
948 CalcDimension calcDimension;
949 if (ParseJsLengthMetrics(endObj, calcDimension)) {
950 CheckDimensionUnit(calcDimension, false, true);
951 localizedCalcDimension.end = calcDimension;
952 }
953 }
954 if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
955 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
956 CalcDimension calcDimension;
957 if (ParseJsLengthMetrics(topObj, calcDimension)) {
958 CheckDimensionUnit(calcDimension, false, true);
959 localizedCalcDimension.top = calcDimension;
960 }
961 }
962 if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
963 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
964 CalcDimension calcDimension;
965 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
966 CheckDimensionUnit(calcDimension, false, true);
967 localizedCalcDimension.bottom = calcDimension;
968 }
969 }
970 }
971
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)972 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
973 {
974 if (CheckLengthMetrics(object)) {
975 LocalizedCalcDimension localizedCalcDimension;
976 ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
977 commonCalcDimension.top = localizedCalcDimension.top;
978 commonCalcDimension.bottom = localizedCalcDimension.bottom;
979 commonCalcDimension.left = localizedCalcDimension.start;
980 commonCalcDimension.right = localizedCalcDimension.end;
981 return true;
982 }
983 ParseEdgeWidths(object, commonCalcDimension, notNegative);
984 return false;
985 }
986
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)987 void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
988 {
989 if (CheckLengthMetrics(object)) {
990 LocalizedCalcDimension localizedCalcDimension;
991 ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
992 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
993 commonCalcDimension.top = localizedCalcDimension.top;
994 commonCalcDimension.bottom = localizedCalcDimension.bottom;
995 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
996 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
997 return;
998 }
999 ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1000 }
1001
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1002 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1003 {
1004 if (CheckLengthMetrics(object)) {
1005 LocalizedCalcDimension localizedCalcDimension;
1006 ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1007 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1008 commonCalcDimension.top = localizedCalcDimension.top;
1009 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1010 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1011 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1012 return;
1013 }
1014 ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1015 }
1016
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1017 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1018 {
1019 auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1020 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1021 auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1022 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1023 NG::PipelineContext::SetCallBackNode(targetNode);
1024 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1025 jsFuncFinish->ExecuteJS(1, &newJSVal);
1026 };
1027 return finishCallback;
1028 }
1029 } // namespace
1030
GetResourceObject(const JSRef<JSObject> & jsObj)1031 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1032 {
1033 auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1034 auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1035 auto args = jsObj->GetProperty("params");
1036
1037 std::string bundleName;
1038 std::string moduleName;
1039 auto bundle = jsObj->GetProperty("bundleName");
1040 auto module = jsObj->GetProperty("moduleName");
1041 if (bundle->IsString() && module->IsString()) {
1042 bundleName = bundle->ToString();
1043 moduleName = module->ToString();
1044 }
1045 if (!args->IsArray()) {
1046 return nullptr;
1047 }
1048 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1049 std::vector<ResourceObjectParams> resObjParamsList;
1050 auto size = static_cast<int32_t>(params->Length());
1051 for (int32_t i = 0; i < size; i++) {
1052 auto item = params->GetValueAt(i);
1053 ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1054 if (item->IsString()) {
1055 resObjParams.type = ResourceObjectParamType::STRING;
1056 } else if (item->IsNumber()) {
1057 if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1058 resObjParams.type = ResourceObjectParamType::FLOAT;
1059 } else {
1060 resObjParams.type = ResourceObjectParamType::INT;
1061 }
1062 }
1063 resObjParamsList.push_back(resObjParams);
1064 }
1065 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(
1066 id, type, resObjParamsList, bundleName, moduleName, Container::CurrentIdSafely());
1067 return resourceObject;
1068 }
1069
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1070 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1071 {
1072 auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1073 auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1074 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName, Container::CurrentIdSafely());
1075 return resourceObject;
1076 }
1077
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1078 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1079 {
1080 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1081 RefPtr<ThemeConstants> themeConstants = nullptr;
1082 if (SystemProperties::GetResourceDecoupling()) {
1083 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1084 if (!resourceAdapter) {
1085 return nullptr;
1086 }
1087 } else {
1088 themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1089 if (!themeConstants) {
1090 return nullptr;
1091 }
1092 }
1093 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1094 return resourceWrapper;
1095 }
1096
CreateResourceWrapper()1097 RefPtr<ResourceWrapper> CreateResourceWrapper()
1098 {
1099 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1100 RefPtr<ThemeConstants> themeConstants = nullptr;
1101 if (SystemProperties::GetResourceDecoupling()) {
1102 resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(Container::CurrentIdSafely());
1103 if (!resourceAdapter) {
1104 return nullptr;
1105 }
1106 } else {
1107 themeConstants = JSViewAbstract::GetThemeConstants();
1108 if (!themeConstants) {
1109 return nullptr;
1110 }
1111 }
1112 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1113 return resourceWrapper;
1114 }
1115
ColorAlphaAdapt(uint32_t origin)1116 uint32_t ColorAlphaAdapt(uint32_t origin)
1117 {
1118 uint32_t result = origin;
1119 if (origin >> COLOR_ALPHA_OFFSET == 0) {
1120 result = origin | COLOR_ALPHA_VALUE;
1121 }
1122 return result;
1123 }
1124
StringToOperationType(const std::string & id)1125 OperationType StringToOperationType(const std::string& id)
1126 {
1127 if (id == "OH_DEFAULT_COPY") {
1128 return OperationType::COPY;
1129 } else if (id == "OH_DEFAULT_PASTE") {
1130 return OperationType::PASTE;
1131 } else if (id == "OH_DEFAULT_CUT") {
1132 return OperationType::CUT;
1133 } else if (id == "OH_DEFAULT_SELECT_ALL") {
1134 return OperationType::SELECT_ALL;
1135 } else {
1136 return OperationType::UNKNOWN;
1137 }
1138 }
1139
UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam> & params)1140 void UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam>& params)
1141 {
1142 for (auto& param : params) {
1143 auto opType = StringToOperationType(param.menuOptionsParam.id);
1144 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1145 CHECK_NULL_VOID(pipeline);
1146 auto theme = pipeline->GetTheme<TextOverlayTheme>();
1147 CHECK_NULL_VOID(theme);
1148 switch (opType) {
1149 case OperationType::COPY:
1150 param.menuOptionsParam.labelInfo = theme->GetCopyLabelInfo();
1151 break;
1152 case OperationType::PASTE:
1153 param.menuOptionsParam.labelInfo = theme->GetPasteLabelInfo();
1154 break;
1155 case OperationType::CUT:
1156 param.menuOptionsParam.labelInfo = theme->GetCutLabelInfo();
1157 break;
1158 case OperationType::SELECT_ALL:
1159 param.menuOptionsParam.labelInfo = theme->GetSelectAllLabelInfo();
1160 break;
1161 default:
1162 param.menuOptionsParam.labelInfo = "";
1163 break;
1164 }
1165 }
1166 }
1167
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context,const RefPtr<NG::FrameNode> node)1168 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseChainedTransition(
1169 const JSRef<JSObject>& object, const JSExecutionContext& context, const RefPtr<NG::FrameNode> node)
1170 {
1171 auto propType = object->GetProperty("type_");
1172 if (!propType->IsString()) {
1173 return nullptr;
1174 }
1175 std::string type = propType->ToString();
1176 auto propEffectOption = object->GetProperty("effect_");
1177 auto propAnimationOption = object->GetProperty("animation_");
1178 auto propSuccessor = object->GetProperty("successor_");
1179 static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
1180 { "asymmetric", ParseChainedAsymmetricTransition },
1181 { "identity",
1182 [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
1183 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
1184 { "move", ParseChainedMoveTransition },
1185 { "opacity", ParseChainedOpacityTransition },
1186 { "rotate", ParseChainedRotateTransition },
1187 { "scale", ParseChainedScaleTransition },
1188 { "slideSwitch",
1189 [](const JSRef<JSVal>& effectOption,
1190 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
1191 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
1192 } },
1193 { "translate", ParseChainedTranslateTransition },
1194 };
1195 int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
1196 if (index < 0) {
1197 return nullptr;
1198 }
1199 RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
1200 if (!result) {
1201 return nullptr;
1202 }
1203 if (propAnimationOption->IsObject()) {
1204 auto container = Container::Current();
1205 CHECK_NULL_RETURN(container, nullptr);
1206 auto pipelineContext = container->GetPipelineContext();
1207 CHECK_NULL_RETURN(pipelineContext, nullptr);
1208 auto animationOptionResult = std::make_shared<AnimationOption>(
1209 JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRenderExceptDynamicComponent()));
1210 // The maximum of the form-animation-playback duration value is 1000 ms.
1211 if (pipelineContext->IsFormRenderExceptDynamicComponent() && pipelineContext->IsFormAnimation()) {
1212 auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
1213 // If the duration exceeds 1000ms, init it to 0 ms.
1214 if (formAnimationTimeInterval > DEFAULT_DURATION) {
1215 animationOptionResult->SetDuration(0);
1216 } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
1217 // If remaining time is less than 1000ms, check for update duration.
1218 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
1219 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form Transition SetDuration: %{public}lld ms",
1220 static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
1221 }
1222 }
1223 auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
1224 JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
1225 WeakPtr<NG::FrameNode> targetNode = nullptr;
1226 if (node) {
1227 targetNode = AceType::WeakClaim(AceType::RawPtr(node));
1228 } else {
1229 targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1230 }
1231 if (onFinish->IsFunction()) {
1232 RefPtr<JsFunction> jsFunc =
1233 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
1234 std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
1235 id = Container::CurrentId(), node = targetNode]() {
1236 ContainerScope scope(id);
1237 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1238 PipelineContext::SetCallBackNode(node);
1239 func->Execute();
1240 };
1241 animationOptionResult->SetOnFinishEvent(onFinishEvent);
1242 }
1243 result->SetAnimationOption(animationOptionResult);
1244 }
1245 if (propSuccessor->IsObject()) {
1246 result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
1247 }
1248 return result;
1249 }
1250
JsScale(const JSCallbackInfo & info)1251 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1252 {
1253 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1254 auto jsVal = info[0];
1255 if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1256 SetDefaultScale();
1257 return;
1258 }
1259
1260 if (jsVal->IsObject()) {
1261 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1262 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1263 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1264 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1265 // default: x, y, z (1.0, 1.0, 1.0)
1266 auto scaleX = 1.0f;
1267 auto scaleY = 1.0f;
1268 auto scaleZ = 1.0f;
1269 // default centerX, centerY 50% 50%;
1270 CalcDimension centerX = 0.5_pct;
1271 CalcDimension centerY = 0.5_pct;
1272 ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1273 ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1274 ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1275 return;
1276 } else {
1277 SetDefaultScale();
1278 }
1279 }
1280 double scale = 0.0;
1281 if (ParseJsDouble(jsVal, scale)) {
1282 ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1283 }
1284 }
1285
SetDefaultScale()1286 void JSViewAbstract::SetDefaultScale()
1287 {
1288 ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1289 ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1290 }
1291
JsScaleX(const JSCallbackInfo & info)1292 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1293 {
1294 double scaleVal = 0.0;
1295 if (!ParseJsDouble(info[0], scaleVal)) {
1296 return;
1297 }
1298 ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1299 }
1300
JsScaleY(const JSCallbackInfo & info)1301 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1302 {
1303 double scaleVal = 0.0;
1304 if (!ParseJsDouble(info[0], scaleVal)) {
1305 return;
1306 }
1307 ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1308 }
1309
JsOpacity(const JSCallbackInfo & info)1310 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1311 {
1312 double opacity = 0.0;
1313 if (!ParseJsDouble(info[0], opacity)) {
1314 ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1315 return;
1316 }
1317 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1318 opacity = std::clamp(opacity, 0.0, 1.0);
1319 } else {
1320 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1321 opacity = 1.0;
1322 }
1323 }
1324 ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1325 }
1326
JsTranslate(const JSCallbackInfo & info)1327 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1328 {
1329 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1330 JSCallbackInfoType::OBJECT };
1331 auto jsVal = info[0];
1332 if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
1333 SetDefaultTranslate();
1334 return;
1335 }
1336
1337 if (jsVal->IsObject()) {
1338 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1339 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1340 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1341 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1342 // default: x, y, z (0.0, 0.0, 0.0)
1343 auto translateX = CalcDimension(0.0);
1344 auto translateY = CalcDimension(0.0);
1345 auto translateZ = CalcDimension(0.0);
1346 ParseJsTranslate(jsVal, translateX, translateY, translateZ);
1347 ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1348 return;
1349 } else {
1350 SetDefaultTranslate();
1351 }
1352 }
1353 CalcDimension value;
1354 if (ParseJsDimensionVp(jsVal, value)) {
1355 ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1356 }
1357 }
1358
SetDefaultTranslate()1359 void JSViewAbstract::SetDefaultTranslate()
1360 {
1361 ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1362 }
1363
JsTranslateX(const JSCallbackInfo & info)1364 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1365 {
1366 CalcDimension value;
1367 if (!ParseJsDimensionVp(info[0], value)) {
1368 return;
1369 }
1370 ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1371 }
1372
JsTranslateY(const JSCallbackInfo & info)1373 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1374 {
1375 CalcDimension value;
1376 if (!ParseJsDimensionVp(info[0], value)) {
1377 return;
1378 }
1379 ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1380 }
1381
JsRotate(const JSCallbackInfo & info)1382 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1383 {
1384 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1385 auto jsVal = info[0];
1386 if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
1387 SetDefaultRotate();
1388 return;
1389 }
1390
1391 if (jsVal->IsObject()) {
1392 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1393 std::optional<float> angle;
1394 ParseJsRotate(jsVal, rotate, angle);
1395 if (angle) {
1396 ViewAbstractModel::GetInstance()->SetRotate(
1397 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1398 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1399 } else {
1400 SetDefaultRotate();
1401 }
1402 return;
1403 }
1404 double rotateZ;
1405 if (ParseJsDouble(jsVal, rotateZ)) {
1406 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1407 }
1408 }
1409
SetDefaultRotate()1410 void JSViewAbstract::SetDefaultRotate()
1411 {
1412 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1413 ViewAbstractModel::GetInstance()->SetRotate(
1414 rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1415 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1416 }
1417
JsRotateX(const JSCallbackInfo & info)1418 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1419 {
1420 double rotateVal = 0.0;
1421 if (!ParseJsDouble(info[0], rotateVal)) {
1422 return;
1423 }
1424 ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1425 }
1426
JsRotateY(const JSCallbackInfo & info)1427 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1428 {
1429 double rotateVal = 0.0;
1430 if (!ParseJsDouble(info[0], rotateVal)) {
1431 return;
1432 }
1433 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1434 }
1435
JsTransform(const JSCallbackInfo & info)1436 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1437 {
1438 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1439 auto jsVal = info[0];
1440 if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
1441 SetDefaultTransform();
1442 return;
1443 }
1444 JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
1445 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1446 if (!array->IsArray()) {
1447 return;
1448 }
1449 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1450 if (jsArray->Length() != matrix4Len) {
1451 return;
1452 }
1453 std::vector<float> matrix(matrix4Len);
1454 for (int32_t i = 0; i < matrix4Len; i++) {
1455 double value = 0.0;
1456 ParseJsDouble(jsArray->GetValueAt(i), value);
1457 matrix[i] = static_cast<float>(value);
1458 }
1459 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1460 }
1461
SetDefaultTransform()1462 void JSViewAbstract::SetDefaultTransform()
1463 {
1464 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1465 std::vector<float> matrix(matrix4Len);
1466 const int32_t initPosition = 5;
1467 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1468 double value = 1.0;
1469 matrix[i] = static_cast<float>(value);
1470 }
1471 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1472 }
1473
ParseJsTransition(const JSRef<JSObject> & jsObj)1474 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
1475 {
1476 NG::TransitionOptions transitionOption;
1477 bool hasEffect = false;
1478 transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1479 if (jsObj->HasProperty("opacity")) {
1480 double opacity = 1.0;
1481 ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1482 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1483 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1484 opacity = 1.0;
1485 }
1486 } else {
1487 opacity = std::clamp(opacity, 0.0, 1.0);
1488 }
1489 transitionOption.UpdateOpacity(static_cast<float>(opacity));
1490 hasEffect = true;
1491 }
1492 if (jsObj->HasProperty("translate")) {
1493 // default: x, y, z (0.0, 0.0, 0.0)
1494 NG::TranslateOptions translate;
1495 ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1496 transitionOption.UpdateTranslate(translate);
1497 hasEffect = true;
1498 }
1499 if (jsObj->HasProperty("scale")) {
1500 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1501 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1502 ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1503 scale.centerX, scale.centerY);
1504 transitionOption.UpdateScale(scale);
1505 hasEffect = true;
1506 }
1507 if (jsObj->HasProperty("rotate")) {
1508 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1509 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1510 std::optional<float> angle;
1511 ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1512 if (angle.has_value()) {
1513 rotate.angle = angle.value();
1514 transitionOption.UpdateRotate(rotate);
1515 hasEffect = true;
1516 }
1517 }
1518 if (!hasEffect) {
1519 // default transition
1520 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1521 }
1522 return transitionOption;
1523 }
1524
ParseJsTransitionEffect(const JSCallbackInfo & info)1525 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
1526 {
1527 JSRef<JSVal> arg = info[0];
1528 if (!arg->IsObject()) {
1529 return nullptr;
1530 }
1531 auto obj = JSRef<JSObject>::Cast(arg);
1532 auto transitionVal = obj->GetProperty("transition");
1533 if (!transitionVal->IsObject()) {
1534 return nullptr;
1535 }
1536 auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
1537 auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
1538 return chainedEffect;
1539 }
1540
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)1541 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
1542 const JSExecutionContext& context)
1543 {
1544 auto chainedEffect = ParseChainedTransition(object, context);
1545 return chainedEffect;
1546 }
1547
JsTransition(const JSCallbackInfo & info)1548 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
1549 {
1550 if (info.Length() < 1 || !info[0]->IsObject()) {
1551 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
1552 ViewAbstractModel::GetInstance()->CleanTransition();
1553 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
1554 }
1555 return;
1556 }
1557 auto obj = JSRef<JSObject>::Cast(info[0]);
1558 if (!obj->GetProperty("successor_")->IsUndefined()) {
1559 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
1560 std::function<void(bool)> finishCallback;
1561 if (info.Length() > 1 && info[1]->IsFunction()) {
1562 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
1563 }
1564 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
1565 return;
1566 }
1567 auto options = ParseJsTransition(obj);
1568 ViewAbstractModel::GetInstance()->SetTransition(options);
1569 }
1570
JsWidth(const JSCallbackInfo & info)1571 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
1572 {
1573 JsWidth(info[0]);
1574 }
1575
JsWidth(const JSRef<JSVal> & jsValue)1576 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
1577 {
1578 CalcDimension value;
1579 if (jsValue->IsUndefined()) {
1580 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1581 return true;
1582 }
1583 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1584 if (!ParseJsDimensionVpNG(jsValue, value)) {
1585 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1586 return false;
1587 }
1588 } else if (!ParseJsDimensionVp(jsValue, value)) {
1589 return false;
1590 }
1591
1592 if (LessNotEqual(value.Value(), 0.0)) {
1593 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1594 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1595 return true;
1596 } else {
1597 value.SetValue(0.0);
1598 }
1599 }
1600
1601 ViewAbstractModel::GetInstance()->SetWidth(value);
1602 return true;
1603 }
1604
JsHeight(const JSCallbackInfo & info)1605 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
1606 {
1607 JsHeight(info[0]);
1608 }
1609
JsHeight(const JSRef<JSVal> & jsValue)1610 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
1611 {
1612 CalcDimension value;
1613 if (jsValue->IsUndefined()) {
1614 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1615 return true;
1616 }
1617 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1618 if (!ParseJsDimensionVpNG(jsValue, value)) {
1619 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1620 return false;
1621 }
1622 } else if (!ParseJsDimensionVp(jsValue, value)) {
1623 return false;
1624 }
1625
1626 if (LessNotEqual(value.Value(), 0.0)) {
1627 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1628 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1629 return true;
1630 } else {
1631 value.SetValue(0.0);
1632 }
1633 }
1634
1635 ViewAbstractModel::GetInstance()->SetHeight(value);
1636 return true;
1637 }
1638
JsResponseRegion(const JSCallbackInfo & info)1639 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
1640 {
1641 std::vector<DimensionRect> result;
1642 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1643 ViewAbstractModel::GetInstance()->SetResponseRegion({});
1644 return;
1645 }
1646
1647 ViewAbstractModel::GetInstance()->SetResponseRegion(result);
1648 }
1649
JsMouseResponseRegion(const JSCallbackInfo & info)1650 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
1651 {
1652 std::vector<DimensionRect> result;
1653 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1654 ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
1655 return;
1656 }
1657 ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
1658 }
1659
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)1660 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
1661 {
1662 result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
1663 result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
1664 if (!jsValue->IsObject()) {
1665 return true;
1666 }
1667
1668 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
1669 JSRef<JSVal> x = obj->GetProperty("x");
1670 JSRef<JSVal> y = obj->GetProperty("y");
1671 JSRef<JSVal> width = obj->GetProperty("width");
1672 JSRef<JSVal> height = obj->GetProperty("height");
1673 CalcDimension xDimen = result.GetOffset().GetX();
1674 CalcDimension yDimen = result.GetOffset().GetY();
1675 CalcDimension widthDimen = result.GetWidth();
1676 CalcDimension heightDimen = result.GetHeight();
1677 auto s1 = width->ToString();
1678 auto s2 = height->ToString();
1679 if (s1.find('-') != std::string::npos) {
1680 width = JSRef<JSVal>::Make(ToJSValue("100%"));
1681 }
1682 if (s2.find('-') != std::string::npos) {
1683 height = JSRef<JSVal>::Make(ToJSValue("100%"));
1684 }
1685 if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
1686 auto offset = result.GetOffset();
1687 offset.SetX(xDimen);
1688 result.SetOffset(offset);
1689 }
1690 if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
1691 auto offset = result.GetOffset();
1692 offset.SetY(yDimen);
1693 result.SetOffset(offset);
1694 }
1695 if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
1696 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
1697 return true;
1698 }
1699 result.SetWidth(widthDimen);
1700 }
1701 if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
1702 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
1703 return true;
1704 }
1705 result.SetHeight(heightDimen);
1706 }
1707 return true;
1708 }
1709
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)1710 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
1711 {
1712 if (!jsValue->IsArray() && !jsValue->IsObject()) {
1713 return false;
1714 }
1715
1716 if (jsValue->IsArray()) {
1717 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
1718 for (size_t i = 0; i < array->Length(); i++) {
1719 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1720 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1721 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1722 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1723 DimensionOffset offsetDimen(xDimen, yDimen);
1724 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1725 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
1726 result.emplace_back(dimenRect);
1727 } else {
1728 return false;
1729 }
1730 }
1731 return true;
1732 }
1733
1734 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1735 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1736 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1737 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1738 DimensionOffset offsetDimen(xDimen, yDimen);
1739 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1740 if (ParseJsDimensionRect(jsValue, dimenRect)) {
1741 result.emplace_back(dimenRect);
1742 return true;
1743 } else {
1744 return false;
1745 }
1746 }
1747
JsSize(const JSCallbackInfo & info)1748 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
1749 {
1750 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1751 auto jsVal = info[0];
1752 if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
1753 return;
1754 }
1755
1756 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
1757 JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
1758 JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
1759 }
1760
JsConstraintSize(const JSCallbackInfo & info)1761 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
1762 {
1763 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1764 auto jsVal = info[0];
1765 if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
1766 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1767 ViewAbstractModel::GetInstance()->ResetMinSize(true);
1768 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1769 ViewAbstractModel::GetInstance()->ResetMinSize(false);
1770 return;
1771 }
1772
1773 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
1774
1775 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
1776 CalcDimension minWidth;
1777 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
1778 CalcDimension maxWidth;
1779 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
1780 CalcDimension minHeight;
1781 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
1782 CalcDimension maxHeight;
1783 bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
1784 if (ParseJsDimensionVp(minWidthValue, minWidth)) {
1785 ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
1786 } else if (version10OrLarger) {
1787 ViewAbstractModel::GetInstance()->ResetMinSize(true);
1788 }
1789
1790 if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
1791 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
1792 } else if (version10OrLarger) {
1793 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1794 }
1795
1796 if (ParseJsDimensionVp(minHeightValue, minHeight)) {
1797 ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
1798 } else if (version10OrLarger) {
1799 ViewAbstractModel::GetInstance()->ResetMinSize(false);
1800 }
1801
1802 if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
1803 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
1804 } else if (version10OrLarger) {
1805 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1806 }
1807 }
1808
JsLayoutPriority(const JSCallbackInfo & info)1809 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
1810 {
1811 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1812 auto jsVal = info[0];
1813 if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
1814 return;
1815 }
1816
1817 int32_t priority;
1818 if (jsVal->IsNumber()) {
1819 priority = jsVal->ToNumber<int32_t>();
1820 } else {
1821 priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
1822 }
1823 ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
1824 }
1825
JsLayoutWeight(const JSCallbackInfo & info)1826 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
1827 {
1828 float value = 0.0f;
1829 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1830 auto jsVal = info[0];
1831 if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
1832 if (!jsVal->IsUndefined()) {
1833 return;
1834 }
1835 }
1836
1837 if (jsVal->IsNumber()) {
1838 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1839 value = jsVal->ToNumber<float>();
1840 } else {
1841 value = jsVal->ToNumber<int32_t>();
1842 }
1843 } else {
1844 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1845 value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
1846 } else {
1847 value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
1848 }
1849 }
1850
1851 ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
1852 }
1853
JsAlign(const JSCallbackInfo & info)1854 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
1855 {
1856 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
1857 auto jsVal = info[0];
1858 if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
1859 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1860 ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
1861 return;
1862 }
1863 auto value = jsVal->ToNumber<int32_t>();
1864 Alignment alignment = ParseAlignment(value);
1865 ViewAbstractModel::GetInstance()->SetAlign(alignment);
1866 }
1867
JsPosition(const JSCallbackInfo & info)1868 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
1869 {
1870 CalcDimension x;
1871 CalcDimension y;
1872 OHOS::Ace::EdgesParam edges;
1873
1874 auto jsArg = info[0];
1875 if (jsArg->IsObject()) {
1876 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
1877 if (ParseLocationProps(jsObj, x, y)) {
1878 return ViewAbstractModel::GetInstance()->SetPosition(x, y);
1879 } else if (ParseLocalizedEdges(jsObj, edges)) {
1880 ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
1881 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
1882 } else if (ParseLocationPropsEdges(jsObj, edges)) {
1883 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
1884 }
1885 }
1886 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1887 ViewAbstractModel::GetInstance()->ResetPosition();
1888 } else {
1889 ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
1890 }
1891 }
1892
JsMarkAnchor(const JSCallbackInfo & info)1893 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
1894 {
1895 CalcDimension x;
1896 CalcDimension y;
1897
1898 auto jsArg = info[0];
1899 if (jsArg->IsObject()) {
1900 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
1901 if (ParseMarkAnchorPosition(jsObj, x, y)) {
1902 ViewAbstractModel::GetInstance()->SetMarkAnchorStart(x);
1903 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
1904 } else if (ParseLocationProps(jsObj, x, y)) {
1905 ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
1906 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
1907 }
1908 }
1909 ViewAbstractModel::GetInstance()->ResetMarkAnchorStart();
1910 ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
1911 }
1912
JsOffset(const JSCallbackInfo & info)1913 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
1914 {
1915 CalcDimension x;
1916 CalcDimension y;
1917 OHOS::Ace::EdgesParam edges;
1918 auto jsArg = info[0];
1919 if (jsArg->IsObject()) {
1920 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
1921 if (ParseLocalizedEdges(jsObj, edges)) {
1922 ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
1923 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
1924 } else if (ParseLocationProps(jsObj, x, y)) {
1925 return ViewAbstractModel::GetInstance()->SetOffset(x, y);
1926 } else if (ParseLocationPropsEdges(jsObj, edges)) {
1927 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
1928 }
1929 }
1930
1931 ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
1932 }
1933
JsEnabled(const JSCallbackInfo & info)1934 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
1935 {
1936 auto arg = info[0];
1937 if (!arg->IsBoolean()) {
1938 ViewAbstractModel::GetInstance()->SetEnabled(true);
1939 } else {
1940 ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
1941 }
1942 }
1943
JsAspectRatio(const JSCallbackInfo & info)1944 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
1945 {
1946 double value = 0.0;
1947 auto jsAspectRatio = info[0];
1948 if (!ParseJsDouble(jsAspectRatio, value)) {
1949 // add version protection, undefined use default value
1950 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
1951 (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
1952 ViewAbstractModel::GetInstance()->ResetAspectRatio();
1953 return;
1954 } else {
1955 return;
1956 }
1957 }
1958
1959 // negative use default value.
1960 if (LessOrEqual(value, 0.0)) {
1961 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1962 ViewAbstractModel::GetInstance()->ResetAspectRatio();
1963 return;
1964 } else {
1965 value = 1.0;
1966 }
1967 }
1968
1969 ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
1970 }
1971
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)1972 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
1973 std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
1974 {
1975 if (info[0]->IsString()) {
1976 std::string text = info[0]->ToString();
1977 ViewAbstractModel::GetInstance()->SetOverlay(
1978 text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
1979 } else if (info[0]->IsObject()) {
1980 JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
1981 auto builder = overlayObject->GetProperty("builder");
1982 if (builder->IsFunction()) {
1983 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1984 CHECK_NULL_VOID(builderFunc);
1985 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1986 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
1987 node = targetNode]() {
1988 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1989 ACE_SCORING_EVENT("Overlay");
1990 PipelineContext::SetCallBackNode(node);
1991 func->Execute();
1992 };
1993 ViewAbstractModel::GetInstance()->SetOverlay(
1994 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
1995 return;
1996 }
1997
1998 JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
1999 if (!builderNode->IsObject()) {
2000 return;
2001 }
2002 auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2003 JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2004 if (nodePtr.IsEmpty()) {
2005 return;
2006 }
2007 const auto* vm = nodePtr->GetEcmaVM();
2008 auto localHandle = nodePtr->GetLocalHandle();
2009 if (!localHandle->IsNativePointer(vm)) {
2010 return;
2011 }
2012 auto* node = localHandle->ToNativePointer(vm)->Value();
2013 auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2014 CHECK_NULL_VOID(frameNode);
2015 RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2016 ViewAbstractModel::GetInstance()->SetOverlay(
2017 "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2018 }
2019 }
2020
JsOverlay(const JSCallbackInfo & info)2021 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2022 {
2023 if (info.Length() > 0 && (info[0]->IsUndefined())) {
2024 ViewAbstractModel::GetInstance()->SetOverlay(
2025 "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2026 return;
2027 }
2028
2029 if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2030 return;
2031 }
2032 std::optional<Alignment> align;
2033 std::optional<CalcDimension> offsetX;
2034 std::optional<CalcDimension> offsetY;
2035
2036 if (info[1]->IsObject()) {
2037 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2038 JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2039 auto value = alignVal->ToNumber<int32_t>();
2040 Alignment alignment = ParseAlignment(value);
2041 align = alignment;
2042
2043 JSRef<JSVal> val = optionObj->GetProperty("offset");
2044 if (val->IsObject()) {
2045 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2046 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2047 CalcDimension x;
2048 if (ParseJsDimensionVp(xVal, x)) {
2049 offsetX = x;
2050 }
2051 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2052 CalcDimension y;
2053 if (ParseJsDimensionVp(yVal, y)) {
2054 offsetY = y;
2055 }
2056 }
2057 }
2058
2059 ParseOverlayFirstParam(info, align, offsetX, offsetY);
2060 }
2061
ParseAlignment(int32_t align)2062 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2063 {
2064 Alignment alignment = Alignment::CENTER;
2065 switch (align) {
2066 case 0:
2067 alignment = Alignment::TOP_LEFT;
2068 break;
2069 case 1:
2070 alignment = Alignment::TOP_CENTER;
2071 break;
2072 case 2:
2073 alignment = Alignment::TOP_RIGHT;
2074 break;
2075 case 3:
2076 alignment = Alignment::CENTER_LEFT;
2077 break;
2078 case 4:
2079 alignment = Alignment::CENTER;
2080 break;
2081 case 5:
2082 alignment = Alignment::CENTER_RIGHT;
2083 break;
2084 case 6:
2085 alignment = Alignment::BOTTOM_LEFT;
2086 break;
2087 case 7:
2088 alignment = Alignment::BOTTOM_CENTER;
2089 break;
2090 case 8:
2091 alignment = Alignment::BOTTOM_RIGHT;
2092 break;
2093 default:
2094 break;
2095 }
2096 return alignment;
2097 }
2098
SetVisibility(const JSCallbackInfo & info)2099 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2100 {
2101 int32_t visible = 0;
2102 JSRef<JSVal> arg = info[0];
2103 if (arg->IsNull() || arg->IsUndefined()) {
2104 // undefined value use default value.
2105 visible = 0;
2106 } else if (!arg->IsNumber()) {
2107 return;
2108 } else {
2109 visible = arg->ToNumber<int32_t>();
2110 }
2111
2112 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2113 (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
2114 visible = 0;
2115 }
2116
2117 if (info.Length() > 1 && info[1]->IsFunction()) {
2118 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2119 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2120 auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2121 int32_t visible) {
2122 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2123 ACE_SCORING_EVENT("onVisibilityChange");
2124 PipelineContext::SetCallBackNode(node);
2125 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2126 func->ExecuteJS(1, &newJSVal);
2127 };
2128 ViewAbstractModel::GetInstance()->SetVisibility(
2129 static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2130 } else {
2131 ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2132 }
2133 }
2134
JsSetFreeze(const JSCallbackInfo & info)2135 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2136 {
2137 if (info[0]->IsBoolean()) {
2138 ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2139 }
2140 }
2141
JsFlexBasis(const JSCallbackInfo & info)2142 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2143 {
2144 CalcDimension value;
2145 if (!ParseJsDimensionVp(info[0], value)) {
2146 value.SetUnit(DimensionUnit::AUTO);
2147 }
2148 // flexbasis don't support percent case.
2149 if (value.Unit() == DimensionUnit::PERCENT) {
2150 value.SetUnit(DimensionUnit::AUTO);
2151 }
2152 ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2153 }
2154
JsFlexGrow(const JSCallbackInfo & info)2155 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2156 {
2157 double value = 0.0;
2158 if (!ParseJsDouble(info[0], value)) {
2159 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2160 // undefined use default value.
2161 value = 0.0;
2162 } else {
2163 return;
2164 }
2165 }
2166 // negative use default value.
2167 if (value < 0.0) {
2168 value = 0.0;
2169 }
2170 ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2171 }
2172
JsFlexShrink(const JSCallbackInfo & info)2173 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2174 {
2175 double value = 0.0;
2176 if (!ParseJsDouble(info[0], value)) {
2177 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2178 // undefined use default value.
2179 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2180 return;
2181 } else {
2182 return;
2183 }
2184 }
2185 // negative use default value.
2186 if (value < 0.0) {
2187 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2188 return;
2189 }
2190 ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2191 }
2192
JsDisplayPriority(const JSCallbackInfo & info)2193 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2194 {
2195 double value = 0.0;
2196 if (!ParseJsDouble(info[0], value)) {
2197 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2198 ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
2199 }
2200 return;
2201 }
2202 ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2203 }
2204
JsSharedTransition(const JSCallbackInfo & info)2205 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2206 {
2207 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2208 auto jsVal = info[0];
2209 if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
2210 return;
2211 }
2212 // id
2213 auto id = jsVal->ToString();
2214 if (id.empty()) {
2215 return;
2216 }
2217 std::shared_ptr<SharedTransitionOption> sharedOption;
2218
2219 // options
2220 if (info.Length() > 1 && info[1]->IsObject()) {
2221 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2222 sharedOption = std::make_shared<SharedTransitionOption>();
2223 // default: duration: 1000
2224 sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2225 if (sharedOption->duration < 0) {
2226 sharedOption->duration = DEFAULT_DURATION;
2227 }
2228 // default: delay: 0
2229 sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2230 if (sharedOption->delay < 0) {
2231 sharedOption->delay = 0;
2232 }
2233 // default: LinearCurve
2234 RefPtr<Curve> curve;
2235 JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2236 if (curveArgs->IsString()) {
2237 curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2238 } else if (curveArgs->IsObject()) {
2239 JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2240 if (!curveString->IsString()) {
2241 return;
2242 }
2243 curve = CreateCurve(curveString->ToString(), false);
2244 }
2245 if (!curve) {
2246 curve = Curves::LINEAR;
2247 }
2248 sharedOption->curve = curve;
2249 // motionPath
2250 if (jsObj->HasProperty("motionPath")) {
2251 MotionPathOption motionPathOption;
2252 if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2253 sharedOption->motionPathOption = motionPathOption;
2254 }
2255 }
2256 // zIndex
2257 sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2258 // type
2259 int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2260 static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2261 sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2262 }
2263 ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2264 }
2265
JsGeometryTransition(const JSCallbackInfo & info)2266 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2267 {
2268 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2269 auto jsVal = info[0];
2270 if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
2271 return;
2272 }
2273 // id
2274 auto id = jsVal->ToString();
2275 // follow flag
2276 bool followWithOutTransition = false;
2277 // hierarchy flag
2278 bool doRegisterSharedTransition = true;
2279 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
2280 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2281 ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2282
2283 auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
2284 ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
2285 switch (transitionHierarchyStrategy) {
2286 case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
2287 doRegisterSharedTransition = false;
2288 break;
2289 case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
2290 doRegisterSharedTransition = true;
2291 break;
2292 default:
2293 break;
2294 }
2295 }
2296 ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
2297 }
2298
JsAlignSelf(const JSCallbackInfo & info)2299 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2300 {
2301 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2302 auto jsVal = info[0];
2303 if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
2304 ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2305 return;
2306 }
2307 auto alignVal = jsVal->ToNumber<int32_t>();
2308
2309 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2310 ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2311 }
2312 }
2313
JsBackgroundColor(const JSCallbackInfo & info)2314 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2315 {
2316 Color backgroundColor;
2317 if (!ParseJsColor(info[0], backgroundColor)) {
2318 backgroundColor = Color::TRANSPARENT;
2319 }
2320
2321 ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2322 }
2323
JsBackgroundImage(const JSCallbackInfo & info)2324 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2325 {
2326 int32_t resId = 0;
2327 std::string src;
2328 std::string bundle;
2329 std::string module;
2330 RefPtr<PixelMap> pixmap = nullptr;
2331 auto jsBackgroundImage = info[0];
2332 GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
2333 int32_t repeatIndex = 0;
2334 bool syncMode = false;
2335 ParseBackgroundImageOption(info, repeatIndex, syncMode);
2336 ViewAbstractModel::GetInstance()->SetBackgroundImageSyncMode(syncMode);
2337 if (jsBackgroundImage->IsString()) {
2338 src = jsBackgroundImage->ToString();
2339 ViewAbstractModel::GetInstance()->SetBackgroundImage(
2340 ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2341 } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) {
2342 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2343 } else {
2344 #if defined(PIXEL_MAP_SUPPORTED)
2345 if (IsDrawable(jsBackgroundImage)) {
2346 pixmap = GetDrawablePixmap(jsBackgroundImage);
2347 } else {
2348 pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
2349 }
2350 #endif
2351 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2352 }
2353 if (info.Length() == 2) { // 2 is background image info length
2354 auto jsImageRepeat = info[1];
2355 if (jsImageRepeat->IsNumber()) {
2356 repeatIndex = jsImageRepeat->ToNumber<int32_t>();
2357 }
2358 }
2359 auto repeat = static_cast<ImageRepeat>(repeatIndex);
2360 ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2361 }
2362
ParseBackgroundImageOption(const JSCallbackInfo & info,int32_t & repeatIndex,bool & syncMode)2363 void JSViewAbstract::ParseBackgroundImageOption(const JSCallbackInfo& info, int32_t& repeatIndex, bool& syncMode)
2364 {
2365 if (info.Length() < 2) { // 2 represents the least para num;
2366 return;
2367 }
2368 if (!info[1]->IsObject()) {
2369 return;
2370 }
2371 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2372 if (jsOption->GetProperty("syncLoad")->IsBoolean()) {
2373 syncMode = jsOption->GetProperty("syncLoad")->ToBoolean();
2374 }
2375 if (jsOption->GetProperty("repeat")->IsNumber()) {
2376 repeatIndex = jsOption->GetProperty("repeat")->ToNumber<int32_t>();
2377 }
2378 }
2379
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2380 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2381 {
2382 auto blurOptionProperty = jsBlurOption->GetProperty("grayscale");
2383 if (blurOptionProperty->IsArray()) {
2384 JSRef<JSArray> params = JSRef<JSArray>::Cast(blurOptionProperty);
2385 auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2386 auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2387 std::vector<float> greyVec(2); // 2 number
2388 greyVec[0] = grey1;
2389 greyVec[1] = grey2;
2390 blurOption.grayscale = greyVec;
2391 }
2392 }
2393
ParseSysOptions(const JSRef<JSObject> & jsSysOptions,SysOptions & sysOptions)2394 void JSViewAbstract::ParseSysOptions(const JSRef<JSObject>& jsSysOptions, SysOptions& sysOptions)
2395 {
2396 auto disableAdaptation = jsSysOptions->GetProperty("disableSystemAdaptation");
2397 if (disableAdaptation->IsBoolean()) {
2398 sysOptions.disableSystemAdaptation = disableAdaptation->ToBoolean();
2399 }
2400 }
2401
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)2402 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
2403 {
2404 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2405 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2406 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2407 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2408 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2409 }
2410 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2411 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2412 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2413 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2414 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2415 }
2416
2417 // policy
2418 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2419 ParseJsInt32(jsOption->GetProperty("policy"), policy);
2420 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2421 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2422 styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2423 }
2424
2425 // blurType
2426 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2427 ParseJsInt32(jsOption->GetProperty("type"), blurType);
2428 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2429 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2430 styleOption.blurType = static_cast<BlurType>(blurType);
2431 }
2432
2433 // inactiveColor
2434 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor)) {
2435 styleOption.isValidColor = true;
2436 }
2437
2438 // scale
2439 if (jsOption->GetProperty("scale")->IsNumber()) {
2440 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2441 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2442 }
2443
2444 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2445 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2446 BlurOption blurOption;
2447 ParseBlurOption(jsBlurOption, blurOption);
2448 styleOption.blurOption = blurOption;
2449 }
2450 }
2451
JsBackgroundBlurStyle(const JSCallbackInfo & info)2452 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2453 {
2454 if (info.Length() == 0) {
2455 return;
2456 }
2457 BlurStyleOption styleOption;
2458 if (info[0]->IsNumber()) {
2459 auto blurStyle = info[0]->ToNumber<int32_t>();
2460 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2461 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2462 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2463 }
2464 }
2465 if (info.Length() > 1 && info[1]->IsObject()) {
2466 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2467 ParseBlurStyleOption(jsOption, styleOption);
2468 }
2469 SysOptions sysOptions;
2470 sysOptions.disableSystemAdaptation = false;
2471 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
2472 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
2473 ParseSysOptions(jsSysOptions, sysOptions);
2474 }
2475 ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption, sysOptions);
2476 }
2477
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2478 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
2479 {
2480 double rate = 1.0f;
2481 auto jsRate = jsOption->GetProperty("rate");
2482 if (jsRate->IsNumber()) {
2483 rate = jsRate->ToNumber<double>();
2484 }
2485 double lightUpDegree = 0.0f;
2486 auto jslightUpDegree = jsOption->GetProperty("lightUpDegree");
2487 if (jslightUpDegree->IsNumber()) {
2488 lightUpDegree = jslightUpDegree->ToNumber<double>();
2489 }
2490 double cubicCoeff = 0.0f;
2491 auto jsCubicCoeff = jsOption->GetProperty("cubicCoeff");
2492 if (jsCubicCoeff->IsNumber()) {
2493 cubicCoeff = jsCubicCoeff->ToNumber<double>();
2494 }
2495 double quadCoeff = 0.0f;
2496 auto jsQuadCoeff = jsOption->GetProperty("quadCoeff");
2497 if (jsQuadCoeff->IsNumber()) {
2498 quadCoeff = jsQuadCoeff->ToNumber<double>();
2499 }
2500 double saturation = 1.0f;
2501 auto jsSaturation = jsOption->GetProperty("saturation");
2502 if (jsSaturation->IsNumber()) {
2503 saturation = jsSaturation->ToNumber<double>();
2504 }
2505 std::vector<float> posRGB(3, 0.0);
2506 auto jsPosRGB = jsOption->GetProperty("posRGB");
2507 if (jsPosRGB->IsArray()) {
2508 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsPosRGB);
2509 auto r = params->GetValueAt(0)->ToNumber<double>();
2510 auto g = params->GetValueAt(1)->ToNumber<double>();
2511 auto b = params->GetValueAt(2)->ToNumber<double>();
2512 posRGB[0] = r;
2513 posRGB[1] = g;
2514 posRGB[2] = b;
2515 }
2516 std::vector<float> negRGB(3, 0.0);
2517 auto jsNegRGB = jsOption->GetProperty("negRGB");
2518 if (jsNegRGB->IsArray()) {
2519 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsNegRGB);
2520 auto r = params->GetValueAt(0)->ToNumber<double>();
2521 auto g = params->GetValueAt(1)->ToNumber<double>();
2522 auto b = params->GetValueAt(2)->ToNumber<double>();
2523 negRGB[0] = r;
2524 negRGB[1] = g;
2525 negRGB[2] = b;
2526 }
2527 double fraction = 1.0f;
2528 auto jsFraction = jsOption->GetProperty("fraction");
2529 if (jsFraction->IsNumber()) {
2530 fraction = jsFraction->ToNumber<double>();
2531 fraction = std::clamp(fraction, 0.0, 1.0);
2532 }
2533 brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
2534 }
2535
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)2536 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
2537 {
2538 CalcDimension radius;
2539 if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
2540 radius.SetValue(0.0f);
2541 }
2542 effectOption.radius = radius;
2543
2544 double saturation = 1.0f;
2545 if (jsOption->GetProperty("saturation")->IsNumber()) {
2546 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2547 saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
2548 }
2549 effectOption.saturation = saturation;
2550
2551 double brightness = 1.0f;
2552 if (jsOption->GetProperty("brightness")->IsNumber()) {
2553 brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
2554 brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
2555 }
2556 effectOption.brightness = brightness;
2557
2558 ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
2559
2560 auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2561 auto adaptiveColor = AdaptiveColor::DEFAULT;
2562 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
2563 if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2564 adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2565 adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
2566 }
2567 effectOption.adaptiveColor = adaptiveColor;
2568
2569 // policy
2570 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2571 ParseJsInt32(jsOption->GetProperty("policy"), policy);
2572 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2573 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2574 effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2575 }
2576
2577 // blurType
2578 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2579 ParseJsInt32(jsOption->GetProperty("type"), blurType);
2580 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2581 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2582 effectOption.blurType = static_cast<BlurType>(blurType);
2583 }
2584
2585 // inactiveColor
2586 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
2587 effectOption.isValidColor = true;
2588 }
2589
2590 BlurOption blurOption;
2591 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2592 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2593 ParseBlurOption(jsBlurOption, blurOption);
2594 effectOption.blurOption = blurOption;
2595 }
2596 }
2597
JsForegroundEffect(const JSCallbackInfo & info)2598 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
2599 {
2600 if (info.Length() == 0) {
2601 return;
2602 }
2603 float radius = 0.0;
2604 if (info[0]->IsObject()) {
2605 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2606 if (jsOption->GetProperty("radius")->IsNumber()) {
2607 radius = jsOption->GetProperty("radius")->ToNumber<float>();
2608 }
2609 }
2610 radius = std::max(radius, 0.0f);
2611 SysOptions sysOptions;
2612 sysOptions.disableSystemAdaptation = false;
2613 if (info.Length() > NUM1 && info[NUM1]->IsObject()) {
2614 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM1]);
2615 ParseSysOptions(jsSysOptions, sysOptions);
2616 }
2617 ViewAbstractModel::GetInstance()->SetForegroundEffect(radius, sysOptions);
2618 }
2619
JsBackgroundEffect(const JSCallbackInfo & info)2620 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
2621 {
2622 if (info.Length() == 0) {
2623 return;
2624 }
2625 EffectOption option;
2626 if (info[0]->IsObject()) {
2627 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2628 ParseEffectOption(jsOption, option);
2629 }
2630 SysOptions sysOptions;
2631 sysOptions.disableSystemAdaptation = false;
2632 if (info.Length() > NUM1 && info[NUM1]->IsObject()) {
2633 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM1]);
2634 ParseSysOptions(jsSysOptions, sysOptions);
2635 }
2636 ViewAbstractModel::GetInstance()->SetBackgroundEffect(option, sysOptions);
2637 }
2638
JsForegroundBlurStyle(const JSCallbackInfo & info)2639 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
2640 {
2641 if (info.Length() == 0) {
2642 return;
2643 }
2644 BlurStyleOption styleOption;
2645 if (info[0]->IsNumber()) {
2646 auto blurStyle = info[0]->ToNumber<int32_t>();
2647 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2648 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2649 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2650 }
2651 }
2652 if (info.Length() > 1 && info[1]->IsObject()) {
2653 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2654 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2655 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2656 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2657 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2658 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2659 }
2660 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2661 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2662 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2663 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2664 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2665 }
2666 if (jsOption->GetProperty("scale")->IsNumber()) {
2667 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2668 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2669 }
2670
2671 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2672 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2673 BlurOption blurOption;
2674 ParseBlurOption(jsBlurOption, blurOption);
2675 styleOption.blurOption = blurOption;
2676 }
2677 }
2678 SysOptions sysOptions;
2679 sysOptions.disableSystemAdaptation = false;
2680 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
2681 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
2682 ParseSysOptions(jsSysOptions, sysOptions);
2683 }
2684 ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption, sysOptions);
2685 }
2686
JsSphericalEffect(const JSCallbackInfo & info)2687 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
2688 {
2689 auto radio = 0.0;
2690 if (info[0]->IsNumber()) {
2691 radio = info[0]->ToNumber<double>();
2692 }
2693 ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
2694 }
2695
JsPixelStretchEffect(const JSCallbackInfo & info)2696 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
2697 {
2698 if (!info[0]->IsObject()) {
2699 PixStretchEffectOption option;
2700 option.ResetValue();
2701 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2702 return;
2703 }
2704 auto jsObject = JSRef<JSObject>::Cast(info[0]);
2705 CalcDimension left;
2706 ParseJsDimensionVp(jsObject->GetProperty("left"), left);
2707 CalcDimension right;
2708 ParseJsDimensionVp(jsObject->GetProperty("right"), right);
2709 CalcDimension top;
2710 ParseJsDimensionVp(jsObject->GetProperty("top"), top);
2711 CalcDimension bottom;
2712 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
2713
2714 PixStretchEffectOption option;
2715 bool illegalInput = InitPixStretchEffect(left, right, top, bottom);
2716 if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
2717 (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
2718 option.left = left;
2719 option.top = top;
2720 option.right = right;
2721 option.bottom = bottom;
2722 } else {
2723 illegalInput = true;
2724 }
2725 if (illegalInput) {
2726 option.ResetValue();
2727 }
2728 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2729 }
2730
InitPixStretchEffect(CalcDimension & left,CalcDimension & right,CalcDimension & top,CalcDimension bottom)2731 bool JSViewAbstract::InitPixStretchEffect(
2732 CalcDimension& left, CalcDimension& right, CalcDimension& top, CalcDimension bottom)
2733 {
2734 bool illegalInput = false;
2735 if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
2736 top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
2737 if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
2738 (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
2739 (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
2740 (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
2741 left.SetUnit(DimensionUnit::PERCENT);
2742 top.SetUnit(DimensionUnit::PERCENT);
2743 right.SetUnit(DimensionUnit::PERCENT);
2744 bottom.SetUnit(DimensionUnit::PERCENT);
2745 } else {
2746 illegalInput = true;
2747 }
2748 }
2749 return illegalInput;
2750 }
2751
JsLightUpEffect(const JSCallbackInfo & info)2752 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
2753 {
2754 auto radio = 1.0;
2755 if (info[0]->IsNumber()) {
2756 radio = info[0]->ToNumber<double>();
2757 }
2758 ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
2759 }
2760
JsBackgroundImageSize(const JSCallbackInfo & info)2761 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
2762 {
2763 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2764 BackgroundImageSize bgImgSize;
2765 auto jsVal = info[0];
2766 if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
2767 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2768 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2769 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2770 return;
2771 }
2772 if (jsVal->IsNumber()) {
2773 auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
2774 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2775 (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
2776 sizeType = BackgroundImageSizeType::AUTO;
2777 }
2778 bgImgSize.SetSizeTypeX(sizeType);
2779 bgImgSize.SetSizeTypeY(sizeType);
2780 } else {
2781 CalcDimension width;
2782 CalcDimension height;
2783 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
2784 ParseJsDimensionVp(object->GetProperty("width"), width);
2785 ParseJsDimensionVp(object->GetProperty("height"), height);
2786 double valueWidth = width.ConvertToPx();
2787 double valueHeight = height.ConvertToPx();
2788 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
2789 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
2790 if (width.Unit() == DimensionUnit::PERCENT) {
2791 typeWidth = BackgroundImageSizeType::PERCENT;
2792 valueWidth = width.Value() * FULL_DIMENSION;
2793 }
2794 if (height.Unit() == DimensionUnit::PERCENT) {
2795 typeHeight = BackgroundImageSizeType::PERCENT;
2796 valueHeight = height.Value() * FULL_DIMENSION;
2797 }
2798 bgImgSize.SetSizeTypeX(typeWidth);
2799 bgImgSize.SetSizeValueX(valueWidth);
2800 bgImgSize.SetSizeTypeY(typeHeight);
2801 bgImgSize.SetSizeValueY(valueHeight);
2802 }
2803
2804 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2805 }
2806
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)2807 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
2808 {
2809 if (align > 8 || align < 0) { // align ranges from [0, 8].
2810 return;
2811 }
2812 std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
2813 { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
2814 { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
2815 SetBgImgPosition(
2816 DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
2817 }
2818
JsBackgroundImagePosition(const JSCallbackInfo & info)2819 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
2820 {
2821 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2822 BackgroundImagePosition bgImgPosition;
2823 auto jsVal = info[0];
2824 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
2825 SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
2826 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2827 return;
2828 }
2829 if (jsVal->IsNumber()) {
2830 int32_t align = jsVal->ToNumber<int32_t>();
2831 bgImgPosition.SetIsAlign(true);
2832 SetBgImgPositionWithAlign(bgImgPosition, align);
2833 } else {
2834 CalcDimension x;
2835 CalcDimension y;
2836 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
2837 ParseJsDimensionVp(object->GetProperty("x"), x);
2838 ParseJsDimensionVp(object->GetProperty("y"), y);
2839 double valueX = x.Value();
2840 double valueY = y.Value();
2841 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
2842 valueX = x.ConvertToPx();
2843 valueY = y.ConvertToPx();
2844 }
2845 DimensionUnit typeX = DimensionUnit::PX;
2846 DimensionUnit typeY = DimensionUnit::PX;
2847 if (x.Unit() == DimensionUnit::PERCENT) {
2848 valueX = x.Value();
2849 typeX = DimensionUnit::PERCENT;
2850 }
2851 if (y.Unit() == DimensionUnit::PERCENT) {
2852 valueY = y.Value();
2853 typeY = DimensionUnit::PERCENT;
2854 }
2855 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
2856 }
2857
2858 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2859 }
2860
JsPadding(const JSCallbackInfo & info)2861 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
2862 {
2863 ParseMarginOrPadding(info, EdgeType::PADDING);
2864 }
2865
JsMargin(const JSCallbackInfo & info)2866 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
2867 {
2868 ParseMarginOrPadding(info, EdgeType::MARGIN);
2869 }
2870
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)2871 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
2872 {
2873 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
2874 JSCallbackInfoType::NUMBER };
2875 auto jsVal = info[0];
2876 if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
2877 auto resetDimension = CalcDimension(0.0);
2878 if (type == EdgeType::MARGIN) {
2879 ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
2880 } else if (type == EdgeType::PADDING) {
2881 ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
2882 } else if (type == EdgeType::SAFE_AREA_PADDING) {
2883 ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
2884 }
2885 return;
2886 }
2887
2888 if (jsVal->IsObject()) {
2889 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
2890
2891 CalcDimension length;
2892 if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
2893 ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
2894 return;
2895 }
2896
2897 CommonCalcDimension commonCalcDimension;
2898 auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
2899 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
2900 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
2901 if (type == EdgeType::MARGIN) {
2902 if (useLengthMetrics) {
2903 ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
2904 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
2905 } else {
2906 ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
2907 commonCalcDimension.left, commonCalcDimension.right);
2908 }
2909 } else if (type == EdgeType::PADDING) {
2910 if (useLengthMetrics) {
2911 ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
2912 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
2913 } else {
2914 ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
2915 commonCalcDimension.left, commonCalcDimension.right);
2916 }
2917 } else if (type == EdgeType::SAFE_AREA_PADDING) {
2918 if (useLengthMetrics) {
2919 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
2920 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
2921 } else {
2922 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
2923 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
2924 }
2925 }
2926 return;
2927 }
2928 }
2929
2930 CalcDimension length;
2931 if (!ParseJsDimensionVp(jsVal, length)) {
2932 // use default value.
2933 length.Reset();
2934 }
2935 if (type == EdgeType::MARGIN) {
2936 ViewAbstractModel::GetInstance()->SetMargin(length);
2937 } else if (type == EdgeType::PADDING) {
2938 ViewAbstractModel::GetInstance()->SetPadding(length);
2939 }
2940 }
2941
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)2942 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
2943 const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
2944 const std::optional<CalcDimension>& end)
2945 {
2946 NG::PaddingProperty paddings;
2947 if (start.has_value()) {
2948 if (start.value().Unit() == DimensionUnit::CALC) {
2949 paddings.start = NG::CalcLength(start.value().CalcValue());
2950 } else {
2951 paddings.start = NG::CalcLength(start.value());
2952 }
2953 }
2954 if (bottom.has_value()) {
2955 if (bottom.value().Unit() == DimensionUnit::CALC) {
2956 paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
2957 } else {
2958 paddings.bottom = NG::CalcLength(bottom.value());
2959 }
2960 }
2961 if (end.has_value()) {
2962 if (end.value().Unit() == DimensionUnit::CALC) {
2963 paddings.end = NG::CalcLength(end.value().CalcValue());
2964 } else {
2965 paddings.end = NG::CalcLength(end.value());
2966 }
2967 }
2968 if (top.has_value()) {
2969 if (top.value().Unit() == DimensionUnit::CALC) {
2970 paddings.top = NG::CalcLength(top.value().CalcValue());
2971 } else {
2972 paddings.top = NG::CalcLength(top.value());
2973 }
2974 }
2975 return paddings;
2976 }
2977
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)2978 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
2979 std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
2980 {
2981 CalcDimension leftDimen;
2982 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
2983 left = leftDimen;
2984 }
2985 CalcDimension rightDimen;
2986 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
2987 right = rightDimen;
2988 }
2989 CalcDimension topDimen;
2990 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
2991 top = topDimen;
2992 }
2993 CalcDimension bottomDimen;
2994 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
2995 bottom = bottomDimen;
2996 }
2997 }
2998
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)2999 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
3000 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3001 {
3002 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
3003 if (jsStart->IsObject()) {
3004 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
3005 CalcDimension calcDimension;
3006 if (ParseJsLengthMetrics(startObj, calcDimension)) {
3007 localizedCalcDimension.start = calcDimension;
3008 }
3009 }
3010 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
3011 if (jsEnd->IsObject()) {
3012 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
3013 CalcDimension calcDimension;
3014 if (ParseJsLengthMetrics(endObj, calcDimension)) {
3015 localizedCalcDimension.end = calcDimension;
3016 }
3017 }
3018 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3019 if (jsTop->IsObject()) {
3020 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
3021 CalcDimension calcDimension;
3022 if (ParseJsLengthMetrics(topObj, calcDimension)) {
3023 localizedCalcDimension.top = calcDimension;
3024 }
3025 }
3026 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3027 if (jsBottom->IsObject()) {
3028 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
3029 CalcDimension calcDimension;
3030 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
3031 localizedCalcDimension.bottom = calcDimension;
3032 }
3033 }
3034 }
3035
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3036 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
3037 const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
3038 {
3039 if (CheckLengthMetrics(object)) {
3040 LocalizedCalcDimension localizedCalcDimension;
3041 ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
3042 commonCalcDimension.top = localizedCalcDimension.top;
3043 commonCalcDimension.bottom = localizedCalcDimension.bottom;
3044 commonCalcDimension.left = localizedCalcDimension.start;
3045 commonCalcDimension.right = localizedCalcDimension.end;
3046 return true;
3047 }
3048 ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
3049 commonCalcDimension.right);
3050 return false;
3051 }
3052
JsOutline(const JSCallbackInfo & info)3053 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
3054 {
3055 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3056 auto jsVal = info[0];
3057 if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
3058 CalcDimension borderWidth;
3059 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3060 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3061 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
3062 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3063 return;
3064 }
3065 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3066 auto valueOuterWidth = object->GetProperty("width");
3067 if (!valueOuterWidth->IsUndefined()) {
3068 ParseOuterBorderWidth(valueOuterWidth);
3069 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3070 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3071 }
3072
3073 // use default value when undefined.
3074 ParseOuterBorderColor(object->GetProperty("color"));
3075
3076 auto valueOuterRadius = object->GetProperty("radius");
3077 if (!valueOuterRadius->IsUndefined()) {
3078 ParseOuterBorderRadius(valueOuterRadius);
3079 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3080 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3081 }
3082 // use default value when undefined.
3083 ParseOuterBorderStyle(object->GetProperty("style"));
3084 info.ReturnSelf();
3085 }
3086
JsOutlineWidth(const JSCallbackInfo & info)3087 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
3088 {
3089 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3090 JSCallbackInfoType::OBJECT };
3091 auto jsVal = info[0];
3092 if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
3093 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3094 return;
3095 }
3096 ParseOuterBorderWidth(jsVal);
3097 }
3098
JsOutlineColor(const JSCallbackInfo & info)3099 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
3100 {
3101 ParseOuterBorderColor(info[0]);
3102 }
3103
JsOutlineRadius(const JSCallbackInfo & info)3104 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
3105 {
3106 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3107 JSCallbackInfoType::OBJECT };
3108 auto jsVal = info[0];
3109 if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
3110 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3111 return;
3112 }
3113 ParseOuterBorderRadius(jsVal);
3114 }
3115
JsOutlineStyle(const JSCallbackInfo & info)3116 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
3117 {
3118 ParseOuterBorderStyle(info[0]);
3119 }
3120
JsBorder(const JSCallbackInfo & info)3121 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
3122 {
3123 if (!info[0]->IsObject()) {
3124 CalcDimension borderWidth;
3125 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3126 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3127 ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
3128 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3129 ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
3130 ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
3131 return;
3132 }
3133 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
3134
3135 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
3136 if (!valueWidth->IsUndefined()) {
3137 ParseBorderWidth(valueWidth);
3138 }
3139
3140 // use default value when undefined.
3141 ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
3142
3143 auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
3144 if (!valueRadius->IsUndefined()) {
3145 ParseBorderRadius(valueRadius);
3146 }
3147 // use default value when undefined.
3148 ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
3149
3150 auto dashGap = object->GetProperty("dashGap");
3151 if (!dashGap->IsUndefined()) {
3152 ParseDashGap(dashGap);
3153 }
3154 auto dashWidth = object->GetProperty("dashWidth");
3155 if (!dashWidth->IsUndefined()) {
3156 ParseDashWidth(dashWidth);
3157 }
3158
3159 info.ReturnSelf();
3160 }
3161
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)3162 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
3163 {
3164 if (!args->IsObject()) {
3165 return false;
3166 }
3167 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3168 if (obj->IsUndefined()) {
3169 return true;
3170 }
3171 // filter dynamic $r raw input
3172 if (obj->HasProperty("id")) {
3173 return false;
3174 }
3175 if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
3176 (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
3177 (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
3178 (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
3179 (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
3180 (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
3181 return true;
3182 }
3183
3184 return false;
3185 }
3186
JsBorderWidth(const JSCallbackInfo & info)3187 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
3188 {
3189 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3190 JSCallbackInfoType::OBJECT };
3191 auto jsVal = info[0];
3192 if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
3193 ViewAbstractModel::GetInstance()->SetBorderWidth({});
3194 return;
3195 }
3196
3197 ParseBorderWidth(jsVal);
3198 }
3199
ParseBorderWidth(const JSRef<JSVal> & args)3200 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
3201 {
3202 CalcDimension borderWidth;
3203 if (ParseJsDimensionVp(args, borderWidth)) {
3204 if (borderWidth.IsNegative()) {
3205 borderWidth.Reset();
3206 }
3207 if (borderWidth.Unit() == DimensionUnit::PERCENT) {
3208 borderWidth.Reset();
3209 }
3210 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3211 } else if (args->IsObject()) {
3212 if (IsBorderWidthObjUndefined(args)) {
3213 ViewAbstractModel::GetInstance()->SetBorderWidth({});
3214 return;
3215 }
3216 CommonCalcDimension commonCalcDimension;
3217 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3218 if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
3219 ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
3220 commonCalcDimension.top, commonCalcDimension.bottom, true);
3221 return;
3222 }
3223 ViewAbstractModel::GetInstance()->SetBorderWidth(
3224 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3225 } else {
3226 return;
3227 }
3228 }
3229
ParseDashGap(const JSRef<JSVal> & args)3230 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
3231 {
3232 CalcDimension dashGap;
3233 if (ParseLengthMetricsToDimension(args, dashGap)) {
3234 if (dashGap.Unit() == DimensionUnit::PERCENT) {
3235 dashGap.Reset();
3236 }
3237 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
3238 } else if (args->IsObject()) {
3239 CommonCalcDimension commonCalcDimension;
3240 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3241 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
3242 ViewAbstractModel::GetInstance()->SetDashGap(
3243 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3244 } else {
3245 dashGap.Reset();
3246 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
3247 }
3248 }
3249
ParseDashWidth(const JSRef<JSVal> & args)3250 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
3251 {
3252 CalcDimension dashWidth;
3253 if (ParseLengthMetricsToDimension(args, dashWidth)) {
3254 if (dashWidth.Unit() == DimensionUnit::PERCENT) {
3255 dashWidth.Reset();
3256 }
3257 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
3258 } else if (args->IsObject()) {
3259 CommonCalcDimension commonCalcDimension;
3260 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
3261 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
3262 ViewAbstractModel::GetInstance()->SetDashWidth(
3263 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
3264 } else {
3265 dashWidth.Reset();
3266 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
3267 }
3268 }
3269
ParseOuterBorderWidth(const JSRef<JSVal> & args)3270 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
3271 {
3272 CalcDimension borderWidth;
3273 if (ParseJsDimensionVp(args, borderWidth)) {
3274 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
3275 borderWidth.Reset();
3276 }
3277 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3278 } else if (args->IsObject()) {
3279 std::optional<CalcDimension> leftDimen;
3280 std::optional<CalcDimension> rightDimen;
3281 std::optional<CalcDimension> topDimen;
3282 std::optional<CalcDimension> bottomDimen;
3283 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3284 CalcDimension left;
3285 if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
3286 if (left.Unit() == DimensionUnit::PERCENT) {
3287 left.Reset();
3288 }
3289 leftDimen = left;
3290 }
3291 CalcDimension right;
3292 if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
3293 if (right.Unit() == DimensionUnit::PERCENT) {
3294 right.Reset();
3295 }
3296 rightDimen = right;
3297 }
3298 CalcDimension top;
3299 if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
3300 if (top.Unit() == DimensionUnit::PERCENT) {
3301 top.Reset();
3302 }
3303 topDimen = top;
3304 }
3305 CalcDimension bottom;
3306 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
3307 if (bottom.Unit() == DimensionUnit::PERCENT) {
3308 bottom.Reset();
3309 }
3310 bottomDimen = bottom;
3311 }
3312 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
3313 } else {
3314 return;
3315 }
3316 }
3317
JsBorderImage(const JSCallbackInfo & info)3318 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
3319 {
3320 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3321 auto jsVal = info[0];
3322 if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
3323 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
3324 uint8_t imageBorderBitsets = 0;
3325 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
3326 return;
3327 }
3328 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3329 CHECK_NULL_VOID(!object->IsEmpty());
3330
3331 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
3332 uint8_t imageBorderBitsets = 0;
3333
3334 auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
3335 CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
3336 std::string srcResult;
3337 std::string bundleName;
3338 std::string moduleName;
3339 GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
3340 borderImage->SetBundleName(bundleName);
3341 borderImage->SetModuleName(moduleName);
3342 if (valueSource->IsString() && !valueSource->ToString().empty()) {
3343 borderImage->SetSrc(valueSource->ToString());
3344 imageBorderBitsets |= BorderImage::SOURCE_BIT;
3345 } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
3346 borderImage->SetSrc(srcResult);
3347 imageBorderBitsets |= BorderImage::SOURCE_BIT;
3348 } else if (valueSource->IsObject()) {
3349 ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
3350 }
3351 auto valueOutset = object->GetProperty("outset");
3352 if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
3353 imageBorderBitsets |= BorderImage::OUTSET_BIT;
3354 ParseBorderImageOutset(valueOutset, borderImage);
3355 }
3356 auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
3357 if (!valueRepeat->IsNull()) {
3358 imageBorderBitsets |= BorderImage::REPEAT_BIT;
3359 ParseBorderImageRepeat(valueRepeat, borderImage);
3360 }
3361 auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
3362 if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
3363 imageBorderBitsets |= BorderImage::SLICE_BIT;
3364 ParseBorderImageSlice(valueSlice, borderImage);
3365 }
3366 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
3367 if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
3368 imageBorderBitsets |= BorderImage::WIDTH_BIT;
3369 ParseBorderImageWidth(valueWidth, borderImage);
3370 }
3371 auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
3372 if (needFill->IsBoolean()) {
3373 borderImage->SetNeedFillCenter(needFill->ToBoolean());
3374 }
3375 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
3376 info.ReturnSelf();
3377 }
3378
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)3379 bool JSViewAbstract::ParseBorderImageDimension(
3380 const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
3381 {
3382 if (!args->IsObject()) {
3383 return false;
3384 }
3385 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3386 if (CheckLengthMetrics(object)) {
3387 LocalizedCalcDimension localizedCalcDimension;
3388 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
3389 borderImageDimension.topDimension = localizedCalcDimension.top;
3390 borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
3391 borderImageDimension.startDimension = localizedCalcDimension.start;
3392 borderImageDimension.endDimension = localizedCalcDimension.end;
3393 return true;
3394 }
3395 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
3396 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
3397 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
3398 for (uint32_t i = 0; i < keys.size(); i++) {
3399 CalcDimension currentDimension;
3400 auto dimensionValue = object->GetProperty(keys.at(i));
3401 if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
3402 auto direction = static_cast<BorderImageDirection>(i);
3403 switch (direction) {
3404 case BorderImageDirection::LEFT:
3405 borderImageDimension.leftDimension = currentDimension;
3406 break;
3407 case BorderImageDirection::RIGHT:
3408 borderImageDimension.rightDimension = currentDimension;
3409 break;
3410 case BorderImageDirection::TOP:
3411 borderImageDimension.topDimension = currentDimension;
3412 break;
3413 case BorderImageDirection::BOTTOM:
3414 borderImageDimension.bottomDimension = currentDimension;
3415 break;
3416 default:
3417 break;
3418 }
3419 }
3420 }
3421 return false;
3422 }
3423
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3424 void JSViewAbstract::ParseBorderImageLengthMetrics(
3425 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3426 {
3427 for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
3428 auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
3429 if (!jsVal->IsObject()) {
3430 continue;
3431 }
3432 JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
3433 CalcDimension calcDimension;
3434 if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
3435 auto direction = static_cast<BorderImageDirection>(i);
3436 switch (direction) {
3437 case BorderImageDirection::LEFT:
3438 localizedCalcDimension.start = calcDimension;
3439 break;
3440 case BorderImageDirection::RIGHT:
3441 localizedCalcDimension.end = calcDimension;
3442 break;
3443 case BorderImageDirection::TOP:
3444 localizedCalcDimension.top = calcDimension;
3445 break;
3446 case BorderImageDirection::BOTTOM:
3447 localizedCalcDimension.bottom = calcDimension;
3448 break;
3449 default:
3450 break;
3451 }
3452 }
3453 }
3454 }
3455
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)3456 bool JSViewAbstract::CheckJSCallbackInfo(
3457 const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
3458 {
3459 bool typeVerified = false;
3460 std::string unrecognizedType;
3461 for (const auto& infoType : infoTypes) {
3462 switch (infoType) {
3463 case JSCallbackInfoType::STRING:
3464 if (tmpInfo->IsString()) {
3465 typeVerified = true;
3466 } else {
3467 unrecognizedType += "string|";
3468 }
3469 break;
3470 case JSCallbackInfoType::NUMBER:
3471 if (tmpInfo->IsNumber()) {
3472 typeVerified = true;
3473 } else {
3474 unrecognizedType += "number|";
3475 }
3476 break;
3477 case JSCallbackInfoType::OBJECT:
3478 if (tmpInfo->IsObject()) {
3479 typeVerified = true;
3480 } else {
3481 unrecognizedType += "object|";
3482 }
3483 break;
3484 case JSCallbackInfoType::FUNCTION:
3485 if (tmpInfo->IsFunction()) {
3486 typeVerified = true;
3487 } else {
3488 unrecognizedType += "Function|";
3489 }
3490 break;
3491 default:
3492 break;
3493 }
3494 }
3495 if (!typeVerified) {
3496 LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
3497 unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
3498 }
3499 return typeVerified || infoTypes.size() == 0;
3500 }
3501
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)3502 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
3503 {
3504 switch (direction) {
3505 case NG::GradientDirection::LEFT:
3506 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3507 break;
3508 case NG::GradientDirection::RIGHT:
3509 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3510 break;
3511 case NG::GradientDirection::TOP:
3512 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3513 break;
3514 case NG::GradientDirection::BOTTOM:
3515 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3516 break;
3517 case NG::GradientDirection::LEFT_TOP:
3518 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3519 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3520 break;
3521 case NG::GradientDirection::LEFT_BOTTOM:
3522 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3523 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3524 break;
3525 case NG::GradientDirection::RIGHT_TOP:
3526 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3527 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3528 break;
3529 case NG::GradientDirection::RIGHT_BOTTOM:
3530 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3531 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3532 break;
3533 case NG::GradientDirection::NONE:
3534 case NG::GradientDirection::START_TO_END:
3535 case NG::GradientDirection::END_TO_START:
3536 default:
3537 break;
3538 }
3539 }
3540
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)3541 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
3542 {
3543 if (!args->IsObject()) {
3544 return;
3545 }
3546 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
3547 NG::Gradient lineGradient;
3548 lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
3549 // angle
3550 std::optional<float> degree;
3551 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3552 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
3553 } else {
3554 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
3555 }
3556 if (degree) {
3557 lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
3558 degree.reset();
3559 }
3560 // direction
3561 auto direction = static_cast<NG::GradientDirection>(
3562 jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
3563 static_cast<int32_t>(NG::GradientDirection::NONE)));
3564 UpdateGradientWithDirection(lineGradient, direction);
3565 auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
3566 lineGradient.SetRepeat(repeating);
3567 NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
3568 ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
3569 bitset |= BorderImage::GRADIENT_BIT;
3570 }
3571
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3572 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3573 {
3574 auto repeatString = args->ToString();
3575 if (repeatString == "Repeat") {
3576 borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
3577 } else if (repeatString == "Round") {
3578 borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
3579 } else if (repeatString == "Space") {
3580 borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
3581 } else {
3582 borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
3583 }
3584 }
3585
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3586 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3587 {
3588 CalcDimension outsetDimension;
3589 if (ParseJsDimensionVp(args, outsetDimension)) {
3590 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
3591 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
3592 borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
3593 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
3594 return;
3595 }
3596 BorderImage::BorderImageOption option;
3597 ParseBorderImageDimension(args, option);
3598 if (option.startDimension.has_value()) {
3599 borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
3600 }
3601 if (option.endDimension.has_value()) {
3602 borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
3603 }
3604 if (option.leftDimension.has_value()) {
3605 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
3606 }
3607 if (option.rightDimension.has_value()) {
3608 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
3609 }
3610 if (option.topDimension.has_value()) {
3611 borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
3612 }
3613 if (option.bottomDimension.has_value()) {
3614 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
3615 }
3616 }
3617
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3618 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3619 {
3620 CalcDimension sliceDimension;
3621 if (ParseJsDimensionVp(args, sliceDimension)) {
3622 borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
3623 borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
3624 borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
3625 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
3626 return;
3627 }
3628 if (!args->IsObject()) {
3629 return;
3630 }
3631 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3632 if (CheckLengthMetrics(object)) {
3633 LocalizedCalcDimension localizedCalcDimension;
3634 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
3635 if (localizedCalcDimension.top.has_value()) {
3636 borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
3637 }
3638 if (localizedCalcDimension.bottom.has_value()) {
3639 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
3640 }
3641 if (localizedCalcDimension.start.has_value()) {
3642 borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
3643 }
3644 if (localizedCalcDimension.end.has_value()) {
3645 borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
3646 }
3647 return;
3648 }
3649 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
3650 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
3651 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
3652 for (uint32_t i = 0; i < keys.size(); i++) {
3653 auto dimensionValue = object->GetProperty(keys.at(i));
3654 if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
3655 borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
3656 }
3657 }
3658 }
3659
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3660 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3661 {
3662 CalcDimension widthDimension;
3663 if (ParseJsDimensionVp(args, widthDimension)) {
3664 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
3665 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
3666 borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
3667 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
3668 return;
3669 }
3670
3671 BorderImage::BorderImageOption option;
3672 ParseBorderImageDimension(args, option);
3673 if (option.startDimension.has_value()) {
3674 borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
3675 }
3676 if (option.endDimension.has_value()) {
3677 borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
3678 }
3679 if (option.leftDimension.has_value()) {
3680 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
3681 }
3682 if (option.rightDimension.has_value()) {
3683 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
3684 }
3685 if (option.topDimension.has_value()) {
3686 borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
3687 }
3688 if (option.bottomDimension.has_value()) {
3689 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
3690 }
3691 }
3692
JsBorderColor(const JSCallbackInfo & info)3693 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
3694 {
3695 ParseBorderColor(info[0]);
3696 }
3697
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)3698 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
3699 const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
3700 const std::optional<Color>& colorBottom)
3701 {
3702 NG::BorderColorProperty borderColors;
3703 borderColors.startColor = colorStart;
3704 borderColors.endColor = colorEnd;
3705 borderColors.topColor = colorTop;
3706 borderColors.bottomColor = colorBottom;
3707 borderColors.multiValued = true;
3708 return borderColors;
3709 }
3710
ParseBorderColor(const JSRef<JSVal> & args)3711 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
3712 {
3713 Color borderColor;
3714 if (ParseJsColor(args, borderColor)) {
3715 ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
3716 } else if (args->IsObject()) {
3717 CommonColor commonColor;
3718 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3719 if (ParseCommonEdgeColors(object, commonColor)) {
3720 ViewAbstractModel::GetInstance()->SetBorderColor(
3721 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
3722 return;
3723 }
3724 ViewAbstractModel::GetInstance()->SetBorderColor(
3725 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
3726 } else {
3727 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3728 }
3729 }
3730
ParseOuterBorderColor(const JSRef<JSVal> & args)3731 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
3732 {
3733 Color borderColor;
3734 if (ParseJsColor(args, borderColor)) {
3735 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
3736 } else if (args->IsObject()) {
3737 CommonColor commonColor;
3738 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3739 if (ParseCommonEdgeColors(object, commonColor)) {
3740 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
3741 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
3742 return;
3743 }
3744 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
3745 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
3746 } else {
3747 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3748 }
3749 }
3750
JsBorderRadius(const JSCallbackInfo & info)3751 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
3752 {
3753 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3754 JSCallbackInfoType::OBJECT };
3755 auto jsVal = info[0];
3756 if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
3757 ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
3758 return;
3759 }
3760 ParseBorderRadius(jsVal);
3761 }
3762
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)3763 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
3764 const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
3765 const std::optional<Dimension>& radiusBottomEnd)
3766 {
3767 NG::BorderRadiusProperty borderRadius;
3768 borderRadius.radiusTopStart = radiusTopStart;
3769 borderRadius.radiusTopEnd = radiusTopEnd;
3770 borderRadius.radiusBottomStart = radiusBottomStart;
3771 borderRadius.radiusBottomEnd = radiusBottomEnd;
3772 borderRadius.multiValued = true;
3773 return borderRadius;
3774 }
3775
ParseBorderRadius(const JSRef<JSVal> & args)3776 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
3777 {
3778 CalcDimension borderRadius;
3779 if (ParseJsDimensionVp(args, borderRadius)) {
3780 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
3781 } else if (args->IsObject()) {
3782 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3783 CalcDimension topLeft;
3784 CalcDimension topRight;
3785 CalcDimension bottomLeft;
3786 CalcDimension bottomRight;
3787 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
3788 ViewAbstractModel::GetInstance()->SetBorderRadius(
3789 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
3790 return;
3791 }
3792 ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
3793 }
3794 }
3795
ParseOuterBorderRadius(const JSRef<JSVal> & args)3796 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
3797 {
3798 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
3799 return;
3800 }
3801 CalcDimension borderRadius;
3802 if (ParseJsDimensionVp(args, borderRadius)) {
3803 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
3804 borderRadius.Reset();
3805 }
3806 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
3807 } else if (args->IsObject()) {
3808 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3809 CalcDimension topLeft;
3810 CalcDimension topRight;
3811 CalcDimension bottomLeft;
3812 CalcDimension bottomRight;
3813 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
3814 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
3815 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
3816 }
3817 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
3818 }
3819 }
3820
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)3821 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
3822 {
3823 ParseJsDimensionVp(object->GetProperty(key), radius);
3824 }
3825
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)3826 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
3827 {
3828 if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
3829 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
3830 ParseJsLengthMetrics(startObj, radius);
3831 }
3832 }
3833
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)3834 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
3835 CalcDimension& bottomLeft, CalcDimension& bottomRight)
3836 {
3837 if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
3838 object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
3839 CalcDimension topStart;
3840 CalcDimension topEnd;
3841 CalcDimension bottomStart;
3842 CalcDimension bottomEnd;
3843 GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
3844 GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
3845 GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
3846 GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
3847 topLeft = topStart;
3848 topRight = topEnd;
3849 bottomLeft = bottomStart;
3850 bottomRight = bottomEnd;
3851 return true;
3852 }
3853 GetBorderRadius("topLeft", object, topLeft);
3854 GetBorderRadius("topRight", object, topRight);
3855 GetBorderRadius("bottomLeft", object, bottomLeft);
3856 GetBorderRadius("bottomRight", object, bottomRight);
3857 return false;
3858 }
3859
JsBorderStyle(const JSCallbackInfo & info)3860 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
3861 {
3862 ParseBorderStyle(info[0]);
3863 }
3864 namespace {
ConvertBorderStyle(int32_t value)3865 BorderStyle ConvertBorderStyle(int32_t value)
3866 {
3867 auto style = static_cast<BorderStyle>(value);
3868 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
3869 style = BorderStyle::SOLID;
3870 }
3871 return style;
3872 }
3873
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)3874 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
3875 {
3876 style = static_cast<BorderStyle>(value);
3877 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
3878 return false;
3879 }
3880 return true;
3881 }
3882 } // namespace
3883
ParseBorderStyle(const JSRef<JSVal> & args)3884 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
3885 {
3886 if (args->IsObject()) {
3887 std::optional<BorderStyle> styleLeft;
3888 std::optional<BorderStyle> styleRight;
3889 std::optional<BorderStyle> styleTop;
3890 std::optional<BorderStyle> styleBottom;
3891 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3892 auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
3893 if (leftValue->IsNumber()) {
3894 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
3895 }
3896 auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
3897 if (rightValue->IsNumber()) {
3898 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
3899 }
3900 auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3901 if (topValue->IsNumber()) {
3902 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
3903 }
3904 auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3905 if (bottomValue->IsNumber()) {
3906 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
3907 }
3908 ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
3909 return;
3910 }
3911 if (args->IsNumber()) {
3912 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
3913 ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
3914 return;
3915 }
3916 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3917 }
3918
ParseOuterBorderStyle(const JSRef<JSVal> & args)3919 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
3920 {
3921 if (!args->IsObject() && !args->IsNumber()) {
3922 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3923 return;
3924 }
3925 if (args->IsObject()) {
3926 std::optional<BorderStyle> styleLeft;
3927 std::optional<BorderStyle> styleRight;
3928 std::optional<BorderStyle> styleTop;
3929 std::optional<BorderStyle> styleBottom;
3930 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3931 auto leftValue = object->GetProperty("left");
3932 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
3933 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
3934 }
3935 auto rightValue = object->GetProperty("right");
3936 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
3937 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
3938 }
3939 auto topValue = object->GetProperty("top");
3940 if (!topValue->IsUndefined() && topValue->IsNumber()) {
3941 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
3942 }
3943 auto bottomValue = object->GetProperty("bottom");
3944 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
3945 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
3946 }
3947 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
3948 return;
3949 }
3950 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
3951 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
3952 }
3953
JsBlur(const JSCallbackInfo & info)3954 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
3955 {
3956 if (info.Length() == 0) {
3957 return;
3958 }
3959 double blur = 0.0;
3960 if (!ParseJsDouble(info[0], blur)) {
3961 return;
3962 }
3963
3964 BlurOption blurOption;
3965 if (info.Length() > 1 && info[1]->IsObject()) {
3966 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
3967 ParseBlurOption(jsBlurOption, blurOption);
3968 }
3969 SysOptions sysOptions;
3970 sysOptions.disableSystemAdaptation = false;
3971 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
3972 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
3973 ParseSysOptions(jsSysOptions, sysOptions);
3974 }
3975 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
3976 ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption, sysOptions);
3977 info.SetReturnValue(info.This());
3978 }
3979
JsMotionBlur(const JSCallbackInfo & info)3980 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
3981 {
3982 if (!info[0]->IsObject()) {
3983 return;
3984 }
3985 MotionBlurOption option;
3986 double x = 0.0;
3987 double y = 0.0;
3988 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
3989 JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
3990 if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
3991 JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
3992 ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
3993 ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
3994 }
3995 double radius = 0.0;
3996 if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
3997 radius = 0.0;
3998 }
3999 if (LessNotEqual(x, 0.0)) {
4000 x = 0.0;
4001 }
4002 if (LessNotEqual(y, 0.0)) {
4003 y = 0.0;
4004 }
4005 option.radius = radius;
4006 option.anchor.x = std::clamp(x, 0.0, 1.0);
4007 option.anchor.y = std::clamp(y, 0.0, 1.0);
4008 ViewAbstractModel::GetInstance()->SetMotionBlur(option);
4009 }
4010
JsColorBlend(const JSCallbackInfo & info)4011 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
4012 {
4013 Color colorBlend;
4014 if (info[0]->IsUndefined()) {
4015 colorBlend = Color::TRANSPARENT;
4016 SetColorBlend(colorBlend);
4017 return;
4018 }
4019 if (!ParseJsColor(info[0], colorBlend)) {
4020 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4021 colorBlend = Color::TRANSPARENT;
4022 SetColorBlend(colorBlend);
4023 }
4024 return;
4025 }
4026 SetColorBlend(colorBlend);
4027 info.SetReturnValue(info.This());
4028 }
4029
JsUseEffect(const JSCallbackInfo & info)4030 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
4031 {
4032 if (info[0]->IsBoolean()) {
4033 auto effectType = EffectType::DEFAULT;
4034 if (info.Length() == 2 && info[1]->IsNumber()) {
4035 effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
4036 if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
4037 effectType = EffectType::DEFAULT;
4038 }
4039 }
4040 ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
4041 }
4042 }
4043
JsUseShadowBatching(const JSCallbackInfo & info)4044 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
4045 {
4046 if (info[0]->IsBoolean()) {
4047 ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
4048 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4049 ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
4050 }
4051 }
4052
JsBackdropBlur(const JSCallbackInfo & info)4053 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
4054 {
4055 if (info.Length() == 0) {
4056 return;
4057 }
4058 double blur = 0.0;
4059 BlurOption blurOption;
4060 if (!ParseJsDouble(info[0], blur)) {
4061 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4062 return;
4063 }
4064 }
4065 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4066 if (info.Length() > 1 && info[1]->IsObject()) {
4067 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4068 ParseBlurOption(jsBlurOption, blurOption);
4069 }
4070 SysOptions sysOptions;
4071 sysOptions.disableSystemAdaptation = false;
4072 if (info.Length() > NUM2 && info[NUM2]->IsObject()) {
4073 JSRef<JSObject> jsSysOptions = JSRef<JSObject>::Cast(info[NUM2]);
4074 ParseSysOptions(jsSysOptions, sysOptions);
4075 }
4076 ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption, sysOptions);
4077 info.SetReturnValue(info.This());
4078 }
4079
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4080 void JSViewAbstract::GetFractionStops(
4081 std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
4082 {
4083 if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
4084 return;
4085 }
4086 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
4087 float tmpPos = -1.0f;
4088 size_t length = jsArray->Length();
4089 for (size_t i = 0; i < length; i++) {
4090 std::pair<float, float> fractionStop;
4091 JSRef<JSVal> item = jsArray->GetValueAt(i);
4092 if (!item->IsArray()) {
4093 continue;
4094 }
4095 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
4096 if (subArray->Length() < 2) {
4097 continue;
4098 }
4099
4100 double value = 0.0;
4101 if (ParseJsDouble(subArray->GetValueAt(0), value)) {
4102 value = std::clamp(value, 0.0, 1.0);
4103 fractionStop.first = static_cast<float>(value);
4104 }
4105 value = 0.0;
4106 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
4107 value = std::clamp(value, 0.0, 1.0);
4108 fractionStop.second = static_cast<float>(value);
4109 }
4110
4111 if (fractionStop.second <= tmpPos) {
4112 fractionStops.clear();
4113 return;
4114 }
4115 tmpPos = fractionStop.second;
4116 fractionStops.push_back(fractionStop);
4117 }
4118 }
JsLinearGradientBlur(const JSCallbackInfo & info)4119 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
4120 {
4121 if (info.Length() < 2) { // 2 represents the least para num;
4122 return;
4123 }
4124 double blurRadius = 0.0;
4125 ParseJsDouble(info[0], blurRadius);
4126
4127 std::vector<std::pair<float, float>> fractionStops;
4128 auto direction = GradientDirection::BOTTOM;
4129 if (info[1]->IsObject()) {
4130 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
4131 GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
4132 auto directionValue =
4133 jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
4134 if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
4135 directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
4136 directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
4137 }
4138 direction = static_cast<GradientDirection>(directionValue);
4139 }
4140 if (static_cast<int32_t>(fractionStops.size()) <= 1) {
4141 fractionStops.clear();
4142 fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
4143 fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
4144 }
4145 // Parse direction
4146 CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
4147 NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
4148 SetLinearGradientBlur(blurPara);
4149 }
4150
JsBackgroundBrightness(const JSCallbackInfo & info)4151 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
4152 {
4153 double rate = 0.0;
4154 double lightUpDegree = 0.0;
4155 if (info[0]->IsObject()) {
4156 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4157 ParseJsDouble(jsObj->GetProperty("rate"), rate);
4158 ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
4159 }
4160 SetDynamicLightUp(rate, lightUpDegree);
4161 }
4162
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)4163 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
4164 {
4165 if (info.Length() == 0) {
4166 return;
4167 }
4168 BrightnessOption option;
4169 if (info[0]->IsObject()) {
4170 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
4171 ParseBrightnessOption(jsOption, option);
4172 }
4173 SetBgDynamicBrightness(option);
4174 }
4175
JsForegroundBrightness(const JSCallbackInfo & info)4176 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
4177 {
4178 if (info.Length() == 0) {
4179 return;
4180 }
4181 BrightnessOption option;
4182 if (info[0]->IsObject()) {
4183 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
4184 ParseBrightnessOption(jsOption, option);
4185 }
4186 SetFgDynamicBrightness(option);
4187 }
4188
JsWindowBlur(const JSCallbackInfo & info)4189 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
4190 {
4191 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4192 auto jsVal = info[0];
4193 if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
4194 return;
4195 }
4196
4197 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
4198 double progress = 0.0;
4199 ParseJsDouble(jsObj->GetProperty("percent"), progress);
4200 auto style = jsObj->GetPropertyValue<int32_t>("style",
4201 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
4202
4203 progress = std::clamp(progress, 0.0, 1.0);
4204 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
4205 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
4206
4207 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
4208 info.SetReturnValue(info.This());
4209 }
4210
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)4211 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
4212 std::string& resName, bool isParseType)
4213 {
4214 if (!jsValue->IsString()) {
4215 return false;
4216 }
4217 std::string resPath = jsValue->ToString();
4218 std::smatch results;
4219 std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
4220 if (!std::regex_match(resPath, results, tokenRegex)) {
4221 return false;
4222 }
4223 targetModule = results[1];
4224 if (isParseType && !ConvertResourceType(results[2], resType)) {
4225 return false;
4226 }
4227 resName = resPath;
4228 return true;
4229 }
4230
ConvertResourceType(const std::string & typeName,ResourceType & resType)4231 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
4232 {
4233 static const std::unordered_map<std::string, ResourceType> resTypeMap {
4234 { "color", ResourceType::COLOR },
4235 { "media", ResourceType::MEDIA },
4236 { "float", ResourceType::FLOAT },
4237 { "string", ResourceType::STRING },
4238 { "plural", ResourceType::PLURAL },
4239 { "pattern", ResourceType::PATTERN },
4240 { "boolean", ResourceType::BOOLEAN },
4241 { "integer", ResourceType::INTEGER },
4242 { "strarray", ResourceType::STRARRAY },
4243 { "intarray", ResourceType::INTARRAY },
4244 };
4245 auto it = resTypeMap.find(typeName);
4246 if (it == resTypeMap.end()) {
4247 return false;
4248 }
4249 resType = it->second;
4250 return true;
4251 }
4252
CompleteResourceObject(JSRef<JSObject> & jsObj)4253 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
4254 {
4255 std::string bundleName;
4256 std::string moduleName;
4257 int32_t resId = -1;
4258 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
4259 }
4260
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)4261 void JSViewAbstract::CompleteResourceObjectWithBundleName(
4262 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
4263 {
4264 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
4265 }
4266
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)4267 void JSViewAbstract::CompleteResourceObjectInner(
4268 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
4269 {
4270 // dynamic $r raw input format is
4271 // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
4272 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
4273 ResourceType resType;
4274
4275 std::string targetModule;
4276 std::string resName;
4277 if (resId->IsString()) {
4278 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
4279 int32_t typeNum = -1;
4280 if (type->IsNumber()) {
4281 typeNum = type->ToNumber<int32_t>();
4282 }
4283 if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
4284 return;
4285 }
4286 CompleteResourceObjectFromId(type, jsObj, resType, resName);
4287 } else if (resId->IsNumber()) {
4288 resIdValue = resId->ToNumber<int32_t>();
4289 if (resIdValue == -1) {
4290 CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
4291 }
4292 }
4293
4294 JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
4295 if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
4296 bundleName = GetBundleNameFromContainer();
4297 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
4298 }
4299 if (moduleName == DEFAULT_HAR_MODULE_NAME) {
4300 moduleName = GetModuleNameFromContainer();
4301 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
4302 }
4303 }
4304
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)4305 bool JSViewAbstract::ParseJsDimensionNG(
4306 const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
4307 {
4308 if (jsValue->IsNumber()) {
4309 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
4310 return true;
4311 }
4312 if (jsValue->IsString()) {
4313 auto value = jsValue->ToString();
4314 if (!isSupportPercent && value.back() == '%') {
4315 return false;
4316 }
4317 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
4318 }
4319 if (jsValue->IsObject()) {
4320 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4321 CompleteResourceObject(jsObj);
4322 JSRef<JSVal> resId = jsObj->GetProperty("id");
4323 if (!resId->IsNumber()) {
4324 return false;
4325 }
4326 auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4327 if (resType == UNKNOWN_RESOURCE_TYPE) {
4328 return false;
4329 }
4330 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4331 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4332 if (!resourceWrapper) {
4333 return false;
4334 }
4335 auto resIdNum = resId->ToNumber<int32_t>();
4336 if (resIdNum == -1) {
4337 if (!IsGetResourceByName(jsObj)) {
4338 return false;
4339 }
4340 JSRef<JSVal> args = jsObj->GetProperty("params");
4341 if (!args->IsArray()) {
4342 return false;
4343 }
4344 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4345 auto param = params->GetValueAt(0);
4346 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4347 auto value = resourceWrapper->GetStringByName(param->ToString());
4348 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
4349 }
4350 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4351 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
4352 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
4353 return true;
4354 }
4355 result = resourceWrapper->GetDimensionByName(param->ToString());
4356 return true;
4357 }
4358 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4359 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4360 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
4361 }
4362 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4363 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
4364 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
4365 return true;
4366 }
4367 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4368 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
4369 return true;
4370 }
4371 }
4372 return false;
4373 }
4374
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)4375 bool JSViewAbstract::ParseJsLengthNG(
4376 const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
4377 {
4378 if (jsValue->IsNumber()) {
4379 if (std::isnan(jsValue->ToNumber<double>())) {
4380 return false;
4381 }
4382 result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
4383 return true;
4384 } else if (jsValue->IsObject()) {
4385 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4386 JSRef<JSVal> value = jsObj->GetProperty("value");
4387 if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
4388 return false;
4389 }
4390 DimensionUnit unit = defaultUnit;
4391 JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
4392 if (jsUnit->IsNumber()) {
4393 if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
4394 return false;
4395 }
4396 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
4397 }
4398 result = NG::CalcLength(value->ToNumber<double>(), unit);
4399 return true;
4400 }
4401
4402 return false;
4403 }
4404
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)4405 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
4406 {
4407 // 'vp' -> the value varies with pixel density of device.
4408 return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
4409 }
4410
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)4411 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
4412 {
4413 if (jsValue->IsNumber()) {
4414 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
4415 return true;
4416 }
4417 if (jsValue->IsString()) {
4418 result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
4419 return true;
4420 }
4421 if (!jsValue->IsObject()) {
4422 return false;
4423 }
4424 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4425 CompleteResourceObject(jsObj);
4426 JSRef<JSVal> resId = jsObj->GetProperty("id");
4427 if (!resId->IsNumber()) {
4428 return false;
4429 }
4430 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4431 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4432 if (!resourceWrapper) {
4433 return false;
4434 }
4435 auto resIdNum = resId->ToNumber<int32_t>();
4436 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4437 if (resType == UNKNOWN_RESOURCE_TYPE) {
4438 return false;
4439 }
4440 if (resIdNum == -1) {
4441 if (!IsGetResourceByName(jsObj)) {
4442 return false;
4443 }
4444 JSRef<JSVal> args = jsObj->GetProperty("params");
4445 if (!args->IsArray()) {
4446 return false;
4447 }
4448 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4449 auto param = params->GetValueAt(0);
4450 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4451 auto value = resourceWrapper->GetStringByName(param->ToString());
4452 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
4453 return true;
4454 }
4455 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4456 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
4457 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
4458 return true;
4459 }
4460 result = resourceWrapper->GetDimensionByName(param->ToString());
4461 return true;
4462 }
4463 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4464 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4465 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
4466 return true;
4467 }
4468 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4469 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
4470 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
4471 return true;
4472 }
4473 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
4474 return true;
4475 }
4476
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)4477 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
4478 {
4479 // 'vp' -> the value varies with pixel density of device.
4480 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
4481 }
4482
ParseJsLengthMetricsVp(const JSRef<JSObject> & jsObj,CalcDimension & result)4483 bool JSViewAbstract::ParseJsLengthMetricsVp(const JSRef<JSObject>& jsObj, CalcDimension& result)
4484 {
4485 auto value = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
4486 if (!value->IsNumber()) {
4487 return false;
4488 }
4489 auto unit = DimensionUnit::VP;
4490 auto jsUnit = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
4491 if (jsUnit->IsNumber()) {
4492 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
4493 }
4494 CalcDimension dimension(value->ToNumber<double>(), unit);
4495 result = dimension;
4496 return true;
4497 }
4498
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)4499 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
4500 {
4501 // 'vp' -> the value varies with pixel density of device.
4502 return ParseJsDimension(jsValue, result, DimensionUnit::VP);
4503 }
4504
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)4505 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
4506 {
4507 // the 'fp' unit is used for text scenes.
4508 return ParseJsDimension(jsValue, result, DimensionUnit::FP);
4509 }
4510
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)4511 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
4512 {
4513 // the 'fp' unit is used for text scenes.
4514 return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
4515 }
4516
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)4517 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
4518 {
4519 return ParseJsDimension(jsValue, result, DimensionUnit::PX);
4520 }
4521
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)4522 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
4523 {
4524 if (!jsValue->IsObject()) {
4525 return false;
4526 }
4527 auto colorObj = JSRef<JSObject>::Cast(jsValue);
4528 auto toNumericProp = colorObj->GetProperty("toNumeric");
4529 if (toNumericProp->IsFunction()) {
4530 auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
4531 result.SetValue(colorVal->ToNumber<uint32_t>());
4532
4533 auto resourceIdProp = colorObj->GetProperty("getResourceId");
4534 if (resourceIdProp->IsFunction()) {
4535 auto resourceIdVal = JSRef<JSFunc>::Cast(resourceIdProp)->Call(colorObj, 0, nullptr);
4536 result.SetResourceId(resourceIdVal->ToNumber<uint32_t>());
4537 }
4538
4539 return true;
4540 }
4541 return false;
4542 }
4543
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)4544 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
4545 {
4546 if (jsValue->IsNumber()) {
4547 result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
4548 return true;
4549 }
4550 if (jsValue->IsString()) {
4551 auto value = jsValue->ToString();
4552 return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
4553 }
4554 if (jsValue->IsObject()) {
4555 auto jsObj = JSRef<JSObject>::Cast(jsValue);
4556 auto valObj = jsObj->GetProperty("value");
4557 if (valObj->IsUndefined() || valObj->IsNull()) {
4558 return false;
4559 }
4560 double value = valObj->ToNumber<double>();
4561 auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
4562 result = CalcDimension(value, unit);
4563 return true;
4564 }
4565 return false;
4566 }
4567
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)4568 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
4569 {
4570 return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
4571 }
4572
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)4573 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
4574 {
4575 if (!jsValue->IsObject()) {
4576 return false;
4577 }
4578 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4579 CompleteResourceObject(jsObj);
4580 if (jsObj->IsEmpty()) {
4581 return false;
4582 }
4583 JSRef<JSVal> id = jsObj->GetProperty("id");
4584 if (!id->IsNumber()) {
4585 return false;
4586 }
4587
4588 auto resId = id->ToNumber<int32_t>();
4589 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4590 if (resType == UNKNOWN_RESOURCE_TYPE) {
4591 return false;
4592 }
4593
4594 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4595 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4596 if (!resourceWrapper) {
4597 return false;
4598 }
4599
4600 if (resId == -1) {
4601 return ParseResourceToDoubleByName(jsObj, resType, resourceWrapper, result);
4602 }
4603 return ParseResourceToDoubleById(resId, resType, resourceWrapper, result);
4604 }
4605
ParseResourceToDoubleByName(const JSRef<JSObject> & jsObj,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)4606 bool JSViewAbstract::ParseResourceToDoubleByName(
4607 const JSRef<JSObject>& jsObj, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
4608 {
4609 if (!IsGetResourceByName(jsObj)) {
4610 return false;
4611 }
4612 JSRef<JSVal> args = jsObj->GetProperty("params");
4613 if (!args->IsArray()) {
4614 return false;
4615 }
4616 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4617 auto param = params->GetValueAt(0);
4618 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4619 auto numberString = resourceWrapper->GetStringByName(param->ToString());
4620 return StringUtils::StringToDouble(numberString, result);
4621 }
4622 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4623 result = resourceWrapper->GetIntByName(param->ToString());
4624 return true;
4625 }
4626 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4627 result = resourceWrapper->GetDoubleByName(param->ToString());
4628 return true;
4629 }
4630 return false;
4631 }
4632
ParseResourceToDoubleById(int32_t resId,int32_t resType,const RefPtr<ResourceWrapper> & resourceWrapper,double & result)4633 bool JSViewAbstract::ParseResourceToDoubleById(
4634 int32_t resId, int32_t resType, const RefPtr<ResourceWrapper>& resourceWrapper, double& result)
4635 {
4636 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4637 auto numberString = resourceWrapper->GetString(resId);
4638 return StringUtils::StringToDouble(numberString, result);
4639 }
4640 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4641 result = resourceWrapper->GetInt(resId);
4642 return true;
4643 }
4644 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4645 result = resourceWrapper->GetDouble(resId);
4646 return true;
4647 }
4648 return false;
4649 }
4650
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)4651 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
4652 {
4653 if (jsValue->IsNumber()) {
4654 result = jsValue->ToNumber<double>();
4655 return true;
4656 }
4657 if (jsValue->IsString()) {
4658 return StringUtils::StringToDouble(jsValue->ToString(), result);
4659 }
4660 if (jsValue->IsObject()) {
4661 return ParseResourceToDouble(jsValue, result);
4662 }
4663 return false;
4664 }
4665
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)4666 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
4667 {
4668 if (jsValue->IsNumber()) {
4669 result = jsValue->ToNumber<int32_t>();
4670 return true;
4671 }
4672 if (jsValue->IsString()) {
4673 result = StringUtils::StringToInt(jsValue->ToString());
4674 return true;
4675 }
4676 if (!jsValue->IsObject()) {
4677 return false;
4678 }
4679 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4680 CompleteResourceObject(jsObj);
4681 JSRef<JSVal> resId = jsObj->GetProperty("id");
4682 if (!resId->IsNumber()) {
4683 return false;
4684 }
4685
4686 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4687 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4688 if (!resourceWrapper) {
4689 return false;
4690 }
4691
4692 auto resIdNum = resId->ToNumber<int32_t>();
4693 if (resIdNum == -1) {
4694 if (!IsGetResourceByName(jsObj)) {
4695 return false;
4696 }
4697 JSRef<JSVal> args = jsObj->GetProperty("params");
4698 if (!args->IsArray()) {
4699 return false;
4700 }
4701 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4702 auto param = params->GetValueAt(0);
4703 result = resourceWrapper->GetIntByName(param->ToString());
4704 return true;
4705 }
4706 result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
4707 return true;
4708 }
4709
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)4710 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
4711 {
4712 if (!jsValue->IsObject()) {
4713 return false;
4714 }
4715 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4716 CompleteResourceObject(jsObj);
4717
4718 auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result);
4719 if (ok) {
4720 JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
4721 if (jsOpacityRatio->IsNumber()) {
4722 double opacityRatio = jsOpacityRatio->ToNumber<double>();
4723 result = result.BlendOpacity(opacityRatio);
4724 }
4725 }
4726 return ok;
4727 }
4728
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)4729 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result)
4730 {
4731 JSRef<JSVal> resId = jsObj->GetProperty("id");
4732 if (!resId->IsNumber()) {
4733 return false;
4734 }
4735
4736 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4737 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4738 if (!resourceWrapper) {
4739 return false;
4740 }
4741
4742 auto resIdNum = resId->ToNumber<int32_t>();
4743 if (resIdNum == -1) {
4744 if (!IsGetResourceByName(jsObj)) {
4745 return false;
4746 }
4747 JSRef<JSVal> args = jsObj->GetProperty("params");
4748 if (!args->IsArray()) {
4749 return false;
4750 }
4751 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4752 auto param = params->GetValueAt(0);
4753 result = resourceWrapper->GetColorByName(param->ToString());
4754 return true;
4755 }
4756
4757 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4758 if (type == static_cast<int32_t>(ResourceType::STRING)) {
4759 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4760 return Color::ParseColorString(value, result);
4761 }
4762 if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
4763 auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
4764 result = Color(ColorAlphaAdapt(value));
4765 return true;
4766 }
4767 if (type == static_cast<int32_t>(ResourceType::COLOR)) {
4768 result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
4769 result.SetResourceId(resId->ToNumber<uint32_t>());
4770 return true;
4771 }
4772 return false;
4773 }
4774
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)4775 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
4776 {
4777 if (jsValue->IsNumber()) {
4778 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
4779 return true;
4780 }
4781 if (jsValue->IsString()) {
4782 return Color::ParseColorString(jsValue->ToString(), result);
4783 }
4784 if (jsValue->IsObject()) {
4785 return ParseJsColorFromResource(jsValue, result);
4786 }
4787 return false;
4788 }
4789
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)4790 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
4791 {
4792 if (jsValue->IsNumber()) {
4793 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
4794 return true;
4795 }
4796 if (jsValue->IsString()) {
4797 return Color::ParseColorString(jsValue->ToString(), result, defaultColor);
4798 }
4799 if (!jsValue->IsObject()) {
4800 return false;
4801 }
4802 return ParseJsColorFromResource(jsValue, result);
4803 }
4804
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)4805 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
4806 {
4807 if (jsValue->IsString()) {
4808 std::string colorStr = jsValue->ToString();
4809 if (colorStr.compare("invert") == 0) {
4810 strategy = ForegroundColorStrategy::INVERT;
4811 return true;
4812 }
4813 }
4814 return false;
4815 }
4816
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)4817 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
4818 {
4819 if (jsValue->IsString()) {
4820 std::string colorStr = jsValue->ToString();
4821 if (colorStr.compare("average") == 0) {
4822 strategy = ShadowColorStrategy::AVERAGE;
4823 return true;
4824 } else if (colorStr.compare("primary") == 0) {
4825 strategy = ShadowColorStrategy::PRIMARY;
4826 return true;
4827 }
4828 }
4829 return false;
4830 }
4831
ParseJsSymbolCustomFamilyNames(std::vector<std::string> & customFamilyNames,const JSRef<JSVal> & jsValue)4832 void JSViewAbstract::ParseJsSymbolCustomFamilyNames(std::vector<std::string>& customFamilyNames,
4833 const JSRef<JSVal>& jsValue)
4834 {
4835 if (jsValue->IsNull() || jsValue->IsUndefined()) {
4836 return;
4837 }
4838 if (!jsValue->IsObject()) {
4839 return;
4840 }
4841 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4842 CompleteResourceObject(jsObj);
4843 JSRef<JSVal> resId = jsObj->GetProperty("id");
4844 if (resId->IsNull() || !resId->IsNumber()) {
4845 return;
4846 }
4847 auto resourceObject = GetResourceObject(jsObj);
4848 std::string bundleName = resourceObject->GetBundleName();
4849 std::string moduleName = resourceObject->GetModuleName();
4850 auto customSymbolFamilyName = bundleName + "_" + moduleName + CUSTOM_SYMBOL_SUFFIX;
4851 std::replace(customSymbolFamilyName.begin(), customSymbolFamilyName.end(), '.', '_');
4852 customFamilyNames.push_back(customSymbolFamilyName);
4853 }
4854
CheckResource(RefPtr<ResourceObject> resourceObject,RefPtr<ResourceWrapper> resourceWrapper)4855 bool JSViewAbstract::CheckResource(RefPtr<ResourceObject> resourceObject, RefPtr<ResourceWrapper> resourceWrapper)
4856 {
4857 if (!resourceWrapper) {
4858 return false;
4859 }
4860 if (!resourceObject) {
4861 return false;
4862 }
4863 return true;
4864 }
4865
CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper,JSRef<JSVal> & resId,std::uint32_t & symbolId)4866 bool JSViewAbstract::CheckCustomSymbolId(RefPtr<ResourceWrapper> resourceWrapper, JSRef<JSVal>& resId,
4867 std::uint32_t& symbolId)
4868 {
4869 auto strValue = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4870 if (!strValue.empty()) {
4871 auto customSymbolId = static_cast<uint32_t>(strtol(strValue.c_str(), nullptr, 16));
4872 symbolId = customSymbolId;
4873 return true;
4874 }
4875 return false;
4876 }
4877
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)4878 bool JSViewAbstract::ParseJsSymbolId(
4879 const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
4880 {
4881 if (jsValue->IsNull() || jsValue->IsUndefined()) {
4882 symbolId = 0;
4883 return false;
4884 }
4885 if (!jsValue->IsObject()) {
4886 return false;
4887 }
4888 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4889 CompleteResourceObject(jsObj);
4890 JSRef<JSVal> resId = jsObj->GetProperty("id");
4891 if (resId->IsNull() || !resId->IsNumber()) {
4892 return false;
4893 }
4894 auto resourceObject = GetResourceObject(jsObj);
4895 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4896 symbolResourceObject = resourceObject;
4897 if (CheckCustomSymbolId(resourceWrapper, resId, symbolId)) {
4898 return true;
4899 }
4900 if (!CheckResource(resourceObject, resourceWrapper)) {
4901 return false;
4902 }
4903 auto resIdNum = resId->ToNumber<int32_t>();
4904 if (resIdNum == -1) {
4905 if (!IsGetResourceByName(jsObj)) {
4906 return false;
4907 }
4908 JSRef<JSVal> args = jsObj->GetProperty("params");
4909 if (!args->IsArray()) {
4910 return false;
4911 }
4912 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4913 auto param = params->GetValueAt(0);
4914 auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
4915 if (!symbol) {
4916 return false;
4917 }
4918 symbolId = symbol;
4919 return true;
4920 }
4921
4922 auto symbol = resourceWrapper->GetSymbolById(resIdNum);
4923 if (!symbol) {
4924 return false;
4925 }
4926 symbolId = symbol;
4927 return true;
4928 }
4929
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)4930 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
4931 {
4932 if (!jsValue->IsArray()) {
4933 return false;
4934 }
4935 if (jsValue->IsArray()) {
4936 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
4937 for (size_t i = 0; i < array->Length(); i++) {
4938 JSRef<JSVal> value = array->GetValueAt(i);
4939 if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
4940 return false;
4941 }
4942 if (value->IsNumber()) {
4943 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
4944 continue;
4945 } else if (value->IsString()) {
4946 Color color;
4947 Color::ParseColorString(value->ToString(), color);
4948 result.emplace_back(color);
4949 continue;
4950 } else {
4951 Color color;
4952 ParseJsColorFromResource(value, color);
4953 result.emplace_back(color);
4954 }
4955 }
4956 return true;
4957 }
4958 return false;
4959 }
4960
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)4961 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
4962 {
4963 result.clear();
4964 if (!jsValue->IsString() && !jsValue->IsObject()) {
4965 return false;
4966 }
4967 if (jsValue->IsString()) {
4968 result = ConvertStrToFontFamilies(jsValue->ToString());
4969 return true;
4970 }
4971 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4972 CompleteResourceObject(jsObj);
4973 JSRef<JSVal> resId = jsObj->GetProperty("id");
4974 if (!resId->IsNumber()) {
4975 return false;
4976 }
4977
4978 auto resourceObject = GetResourceObject(jsObj);
4979 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4980 if (!resourceWrapper) {
4981 return false;
4982 }
4983
4984 auto resIdNum = resId->ToNumber<int32_t>();
4985 if (resIdNum == -1) {
4986 if (!IsGetResourceByName(jsObj)) {
4987 return false;
4988 }
4989 JSRef<JSVal> args = jsObj->GetProperty("params");
4990 if (!args->IsArray()) {
4991 return false;
4992 }
4993 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4994 auto param = params->GetValueAt(0);
4995 result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
4996 return true;
4997 }
4998 result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
4999 return true;
5000 }
5001
ParseJsStringObj(const JSRef<JSVal> & jsValue,std::string & result)5002 bool JSViewAbstract::ParseJsStringObj(const JSRef<JSVal>& jsValue, std::string& result)
5003 {
5004 if (!jsValue->IsObject()) {
5005 return false;
5006 }
5007 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5008 CompleteResourceObject(jsObj);
5009 JSRef<JSVal> resId = jsObj->GetProperty("id");
5010 if (!resId->IsNumber()) {
5011 return false;
5012 }
5013 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5014 if (type == UNKNOWN_RESOURCE_TYPE) {
5015 return false;
5016 }
5017 JSRef<JSVal> args = jsObj->GetProperty("params");
5018 if (!args->IsArray()) {
5019 return false;
5020 }
5021 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5022 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5023 if (!resourceWrapper) {
5024 return false;
5025 }
5026 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5027 auto resIdNum = resId->ToNumber<int32_t>();
5028 if (resIdNum == -1) {
5029 if (!IsGetResourceByName(jsObj)) {
5030 return false;
5031 }
5032 auto param = params->GetValueAt(0);
5033 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5034 auto originStr = resourceWrapper->GetStringByName(param->ToString());
5035 ReplaceHolder(originStr, params, 1);
5036 result = originStr;
5037 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5038 auto countJsVal = params->GetValueAt(1);
5039 int count = 0;
5040 if (!countJsVal->IsNumber()) {
5041 return false;
5042 }
5043 count = countJsVal->ToNumber<int>();
5044 auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
5045 ReplaceHolder(pluralStr, params, 2); // params[2] applys pluralStr.
5046 result = pluralStr;
5047 } else {
5048 return false;
5049 }
5050 return true;
5051 }
5052 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5053 auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5054 ReplaceHolder(originStr, params, 0);
5055 result = originStr;
5056 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5057 auto countJsVal = params->GetValueAt(0);
5058 int count = 0;
5059 if (!countJsVal->IsNumber()) {
5060 return false;
5061 }
5062 count = countJsVal->ToNumber<int>();
5063 auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
5064 ReplaceHolder(pluralStr, params, 1);
5065 result = pluralStr;
5066 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
5067 result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
5068 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5069 result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5070 } else {
5071 return false;
5072 }
5073 return true;
5074 }
5075
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5076 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
5077 {
5078 if (jsValue->IsString()) {
5079 result = jsValue->ToString();
5080 return true;
5081 }
5082 return ParseJsStringObj(jsValue, result);
5083 }
5084
ParseJsString(const JSRef<JSVal> & jsValue,std::u16string & result)5085 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::u16string& result)
5086 {
5087 std::string u8Result;
5088 if (jsValue->IsString()) {
5089 result = jsValue->ToU16String();
5090 return true;
5091 }
5092 bool ret = ParseJsStringObj(jsValue, u8Result);
5093 if (ret) {
5094 result = UtfUtils::Str8DebugToStr16(u8Result);
5095 return true;
5096 }
5097 return false;
5098 }
5099
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5100 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
5101 {
5102 if (!jsValue->IsObject() && !jsValue->IsString()) {
5103 return false;
5104 }
5105 if (jsValue->IsString()) {
5106 result = jsValue->ToString();
5107 return true;
5108 }
5109 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5110 CompleteResourceObject(jsObj);
5111 return ParseJSMediaInternal(jsObj, result);
5112 }
5113
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5114 bool JSViewAbstract::ParseJsMediaWithBundleName(
5115 const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
5116 {
5117 if (!jsValue->IsObject() && !jsValue->IsString()) {
5118 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5119 }
5120 if (jsValue->IsString()) {
5121 result = jsValue->ToString();
5122 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5123 }
5124 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5125 CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
5126 return ParseJSMediaInternal(jsObj, result);
5127 }
5128
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5129 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result)
5130 {
5131 int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5132 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5133 if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
5134 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5135 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5136 CHECK_NULL_RETURN(resourceWrapper, false);
5137 if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
5138 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5139 if (!args->IsArray()) {
5140 return false;
5141 }
5142 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5143 auto fileName = params->GetValueAt(0);
5144 if (!fileName->IsString()) {
5145 return false;
5146 }
5147 result = resourceWrapper->GetRawfile(fileName->ToString());
5148 return true;
5149 }
5150 auto resIdNum = resId->ToNumber<int32_t>();
5151 if (resIdNum == -1) {
5152 if (!IsGetResourceByName(jsObj)) {
5153 return false;
5154 }
5155 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5156 if (!args->IsArray()) {
5157 return false;
5158 }
5159 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5160 auto param = params->GetValueAt(0);
5161 if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5162 result = resourceWrapper->GetMediaPathByName(param->ToString());
5163 return true;
5164 }
5165 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5166 result = resourceWrapper->GetStringByName(param->ToString());
5167 return true;
5168 }
5169 return false;
5170 } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5171 result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
5172 return true;
5173 } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
5174 result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5175 return true;
5176 }
5177 }
5178 return false;
5179 }
5180
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5181 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
5182 const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
5183 {
5184 auto vm = info.GetVm();
5185 auto globalObj = JSNApi::GetGlobalObject(vm);
5186 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
5187 JsiValue jsiValue(globalFunc);
5188 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
5189 if (!globalFuncRef->IsFunction()) {
5190 return;
5191 }
5192 if (modifierNormalObj->IsUndefined()) {
5193 symbolApply.onApply = nullptr;
5194 } else {
5195 RefPtr<JsFunction> jsFunc =
5196 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
5197 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
5198 modifierNormal = std::move(modifierNormalObj),
5199 modifierSelected = std::move(modifierSelectedObj)](
5200 WeakPtr<NG::FrameNode> frameNode, std::string type) {
5201 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5202 auto node = frameNode.Upgrade();
5203 CHECK_NULL_VOID(node);
5204 JSRef<JSVal> params[SECOND_INDEX];
5205 if (type == "normal") {
5206 params[0] = modifierNormal;
5207 } else if (!modifierSelected->IsUndefined()) {
5208 params[0] = modifierSelected;
5209 }
5210 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
5211 PipelineContext::SetCallBackNode(node);
5212 func->ExecuteJS(SECOND_INDEX, params);
5213 };
5214 symbolApply.onApply = onApply;
5215 }
5216 }
5217
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)5218 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
5219 {
5220 if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
5221 return false;
5222 }
5223
5224 if (jsValue->IsBoolean()) {
5225 result = jsValue->ToBoolean();
5226 return true;
5227 }
5228
5229 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5230 CompleteResourceObject(jsObj);
5231 int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5232 if (resType == UNKNOWN_RESOURCE_TYPE) {
5233 return false;
5234 }
5235
5236 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5237 if (!resId->IsNumber()) {
5238 return false;
5239 }
5240
5241 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5242 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5243 if (!resourceWrapper) {
5244 return false;
5245 }
5246
5247 auto resIdNum = resId->ToNumber<int32_t>();
5248 if (resIdNum == -1) {
5249 if (!IsGetResourceByName(jsObj)) {
5250 return false;
5251 }
5252 JSRef<JSVal> args = jsObj->GetProperty("params");
5253 if (!args->IsArray()) {
5254 return false;
5255 }
5256 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5257 auto param = params->GetValueAt(0);
5258 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
5259 result = resourceWrapper->GetBooleanByName(param->ToString());
5260 return true;
5261 }
5262 return false;
5263 }
5264
5265 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
5266 result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
5267 return true;
5268 }
5269 return false;
5270 }
5271
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)5272 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
5273 {
5274 return ParseJsInteger<uint32_t>(jsValue, result);
5275 }
5276
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)5277 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
5278 {
5279 return ParseJsInteger<int32_t>(jsValue, result);
5280 }
5281
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)5282 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
5283 {
5284 if (!jsValue->IsArray() && !jsValue->IsObject()) {
5285 return false;
5286 }
5287 if (jsValue->IsArray()) {
5288 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5289 for (size_t i = 0; i < array->Length(); i++) {
5290 JSRef<JSVal> value = array->GetValueAt(i);
5291 if (value->IsNumber()) {
5292 result.emplace_back(value->ToNumber<uint32_t>());
5293 } else if (value->IsObject()) {
5294 uint32_t singleResInt;
5295 if (ParseJsInteger(value, singleResInt)) {
5296 result.emplace_back(singleResInt);
5297 } else {
5298 return false;
5299 }
5300 } else {
5301 return false;
5302 }
5303 }
5304 return true;
5305 }
5306 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5307 CompleteResourceObject(jsObj);
5308 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5309 if (resType == UNKNOWN_RESOURCE_TYPE) {
5310 return false;
5311 }
5312 JSRef<JSVal> resId = jsObj->GetProperty("id");
5313 if (!resId->IsNumber()) {
5314 return false;
5315 }
5316 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5317 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5318 if (!resourceWrapper) {
5319 return false;
5320 }
5321 auto resIdNum = resId->ToNumber<int32_t>();
5322 if (resIdNum == -1) {
5323 if (!IsGetResourceByName(jsObj)) {
5324 return false;
5325 }
5326 JSRef<JSVal> args = jsObj->GetProperty("params");
5327 if (!args->IsArray()) {
5328 return false;
5329 }
5330 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5331 auto param = params->GetValueAt(0);
5332 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
5333 result = resourceWrapper->GetIntArrayByName(param->ToString());
5334 return true;
5335 }
5336 return false;
5337 }
5338 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
5339 result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
5340 return true;
5341 }
5342 return false;
5343 }
5344
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5345 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
5346 {
5347 if (!jsValue->IsArray() && !jsValue->IsObject()) {
5348 return false;
5349 }
5350 if (jsValue->IsArray()) {
5351 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5352 for (size_t i = 0; i < array->Length(); i++) {
5353 JSRef<JSVal> value = array->GetValueAt(i);
5354 if (value->IsString()) {
5355 result.emplace_back(value->ToString());
5356 } else if (value->IsObject()) {
5357 std::string singleResStr;
5358 if (ParseJsString(value, singleResStr)) {
5359 result.emplace_back(singleResStr);
5360 } else {
5361 return false;
5362 }
5363 } else {
5364 return false;
5365 }
5366 }
5367 return true;
5368 }
5369 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5370 CompleteResourceObject(jsObj);
5371 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5372 if (resType == UNKNOWN_RESOURCE_TYPE) {
5373 return false;
5374 }
5375 JSRef<JSVal> resId = jsObj->GetProperty("id");
5376 if (!resId->IsNumber()) {
5377 return false;
5378 }
5379 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5380 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5381 if (!resourceWrapper) {
5382 return false;
5383 }
5384 auto resIdNum = resId->ToNumber<int32_t>();
5385 if (resIdNum == -1) {
5386 if (!IsGetResourceByName(jsObj)) {
5387 return false;
5388 }
5389 JSRef<JSVal> args = jsObj->GetProperty("params");
5390 if (!args->IsArray()) {
5391 return false;
5392 }
5393 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5394 auto param = params->GetValueAt(0);
5395 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
5396 result = resourceWrapper->GetStringArrayByName(param->ToString());
5397 return true;
5398 }
5399 return false;
5400 }
5401 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
5402 result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
5403 return true;
5404 }
5405 return false;
5406 }
5407
ParseJsLengthMetricsArray(const JSRef<JSVal> & jsValue,std::vector<Dimension> & result)5408 bool JSViewAbstract::ParseJsLengthMetricsArray(const JSRef<JSVal>& jsValue, std::vector<Dimension>& result)
5409 {
5410 if (jsValue->IsArray()) {
5411 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5412 for (size_t i = 0; i < array->Length(); i++) {
5413 JSRef<JSVal> value = array->GetValueAt(i);
5414 Dimension calc;
5415 ParseJsLengthMetricsToDimension(value, calc);
5416 result.emplace_back(calc);
5417 }
5418 return true;
5419 }
5420
5421 return false;
5422 }
5423
IsGetResourceByName(const JSRef<JSObject> & jsObj)5424 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
5425 {
5426 JSRef<JSVal> resId = jsObj->GetProperty("id");
5427 if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
5428 return false;
5429 }
5430 JSRef<JSVal> args = jsObj->GetProperty("params");
5431 if (!args->IsArray()) {
5432 return false;
5433 }
5434 JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
5435 JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
5436 if (!bundleName->IsString() || !moduleName->IsString()) {
5437 return false;
5438 }
5439 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5440 if (params->IsEmpty()) {
5441 return false;
5442 }
5443 return true;
5444 }
5445
ParseSize(const JSCallbackInfo & info)5446 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
5447 {
5448 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5449 auto jsVal = info[0];
5450 if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
5451 return std::pair<CalcDimension, CalcDimension>();
5452 }
5453 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
5454 CalcDimension width;
5455 CalcDimension height;
5456 if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
5457 !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
5458 return std::pair<CalcDimension, CalcDimension>();
5459 }
5460 return std::pair<CalcDimension, CalcDimension>(width, height);
5461 }
5462
JsUseAlign(const JSCallbackInfo & info)5463 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
5464 {
5465 if (info.Length() < 2) {
5466 return;
5467 }
5468
5469 if (!info[0]->IsObject() && !info[1]->IsObject()) {
5470 return;
5471 }
5472
5473 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
5474 if (declaration == nullptr) {
5475 return;
5476 }
5477
5478 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
5479 JSRef<JSVal> side = obj->GetProperty("side");
5480 JSRef<JSVal> offset = obj->GetProperty("offset");
5481
5482 if (!side->IsNumber()) {
5483 return;
5484 }
5485
5486 auto sideValue = side->ToNumber<int32_t>();
5487
5488 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
5489 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
5490 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
5491 return;
5492 }
5493 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
5494 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
5495 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
5496 return;
5497 }
5498 }
5499
5500 std::optional<CalcDimension> optOffset;
5501 CalcDimension offsetDimension;
5502 if (ParseJsDimensionVp(offset, offsetDimension)) {
5503 optOffset = offsetDimension;
5504 }
5505 ViewAbstractModel::GetInstance()->SetUseAlign(
5506 declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
5507 }
5508
JsGridSpan(const JSCallbackInfo & info)5509 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
5510 {
5511 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
5512 auto jsVal = info[0];
5513 if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
5514 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5515 ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
5516 }
5517 return;
5518 }
5519 auto span = jsVal->ToNumber<int32_t>();
5520 ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
5521 }
5522
JsGridOffset(const JSCallbackInfo & info)5523 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
5524 {
5525 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
5526 auto jsVal = info[0];
5527 if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
5528 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
5529 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
5530 }
5531 return;
5532 }
5533 auto offset = jsVal->ToNumber<int32_t>();
5534 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
5535 }
5536
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)5537 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
5538 {
5539 // {lg: 4}
5540 if (val->IsNumber()) {
5541 span = val->ToNumber<uint32_t>();
5542 return true;
5543 }
5544
5545 if (!val->IsObject()) {
5546 return false;
5547 }
5548
5549 // {lg: {span: 1, offset: 2}}
5550 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
5551 span = obj->GetProperty("span")->ToNumber<uint32_t>();
5552 offset = obj->GetProperty("offset")->ToNumber<int32_t>();
5553 return true;
5554 }
5555
JsUseSizeType(const JSCallbackInfo & info)5556 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
5557 {
5558 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5559 auto jsVal = info[0];
5560 if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
5561 return;
5562 }
5563 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
5564 for (auto values : SCREEN_SIZE_VALUES) {
5565 JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
5566 if (val->IsNull() || val->IsEmpty()) {
5567 continue;
5568 }
5569 uint32_t span = 0;
5570 int32_t offset = 0;
5571 if (ParseSpanAndOffset(val, span, offset)) {
5572 ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
5573 }
5574 }
5575 }
5576
JsZIndex(const JSCallbackInfo & info)5577 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
5578 {
5579 int zIndex = 0;
5580 if (info[0]->IsNumber()) {
5581 zIndex = info[0]->ToNumber<int>();
5582 }
5583
5584 ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
5585 }
5586
Pop()5587 void JSViewAbstract::Pop()
5588 {
5589 if (ViewStackModel::GetInstance()->IsPrebuilding()) {
5590 return ViewStackModel::GetInstance()->PushPrebuildCompCmd("[JSViewAbstract][pop]", &JSViewAbstract::Pop);
5591 }
5592 ViewStackModel::GetInstance()->Pop();
5593 }
5594
JsSetDraggable(bool draggable)5595 void JSViewAbstract::JsSetDraggable(bool draggable)
5596 {
5597 ViewAbstractModel::GetInstance()->SetDraggable(draggable);
5598 }
5599
ParseDragInteractionOptions(const JSCallbackInfo & info,NG::DragPreviewOption & previewOption)5600 void JSViewAbstract::ParseDragInteractionOptions(const JSCallbackInfo& info,
5601 NG::DragPreviewOption& previewOption)
5602 {
5603 if (info.Length() > 1 && info[1]->IsObject()) {
5604 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
5605 auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
5606 if (multiSelection->IsBoolean()) {
5607 previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
5608 }
5609 auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
5610 if (defaultAnimation->IsBoolean()) {
5611 previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
5612 }
5613 auto hapicFeedback = interObj->GetProperty("enableHapticFeedback");
5614 if (hapicFeedback->IsBoolean()) {
5615 previewOption.enableHapticFeedback = hapicFeedback->ToBoolean();
5616 }
5617 auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
5618 if (dragPreview->IsBoolean()) {
5619 previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
5620 }
5621 auto enableEdgeAutoScroll = interObj->GetProperty("enableEdgeAutoScroll");
5622 if (enableEdgeAutoScroll->IsBoolean()) {
5623 previewOption.enableEdgeAutoScroll = enableEdgeAutoScroll->ToBoolean();
5624 }
5625 auto isLiftingDisabled = interObj->GetProperty("isLiftingDisabled");
5626 if (isLiftingDisabled->IsBoolean()) {
5627 previewOption.isLiftingDisabled = isLiftingDisabled->ToBoolean();
5628 }
5629 }
5630 }
5631
ParseDragPreviewOptions(const JSCallbackInfo & info)5632 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
5633 {
5634 NG::DragPreviewOption previewOption;
5635 if (!info[0]->IsObject()) {
5636 return previewOption;
5637 }
5638 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
5639 auto mode = obj->GetProperty("mode");
5640 bool isAuto = true;
5641 if (mode->IsNumber()) {
5642 ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
5643 } else if (mode->IsArray()) {
5644 JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
5645 for (size_t i = 0; i < array->Length(); i++) {
5646 JSRef<JSVal> value = array->GetValueAt(i);
5647 if (value->IsNumber()) {
5648 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
5649 }
5650 if (isAuto) {
5651 break;
5652 }
5653 }
5654 }
5655
5656 auto sizeChangeEffect = obj->GetProperty("sizeChangeEffect");
5657 if (sizeChangeEffect->IsNumber()) {
5658 previewOption.sizeChangeEffect = static_cast<NG::DraggingSizeChangeEffect>(sizeChangeEffect->ToNumber<int>());
5659 }
5660
5661 JSViewAbstract::SetDragNumberBadge(info, previewOption);
5662
5663 ParseDragInteractionOptions(info, previewOption);
5664
5665 JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
5666
5667 return previewOption;
5668 }
5669
JsSetDragPreviewOptions(const JSCallbackInfo & info)5670 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
5671 {
5672 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5673 auto jsVal = info[0];
5674 if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
5675 return;
5676 }
5677 NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
5678 ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
5679 }
5680
JsOnDragStart(const JSCallbackInfo & info)5681 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
5682 {
5683 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5684 auto jsVal = info[0];
5685 if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
5686 return;
5687 }
5688
5689 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5690
5691 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5692 auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
5693 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
5694 NG::DragDropBaseInfo dragDropInfo;
5695 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
5696 PipelineContext::SetCallBackNode(node);
5697 auto ret = func->Execute(info, extraParams);
5698 if (!ret->IsObject()) {
5699 return dragDropInfo;
5700 }
5701
5702 dragDropInfo.node = ParseDragNode(ret);
5703 auto builderObj = JSRef<JSObject>::Cast(ret);
5704 #if defined(PIXEL_MAP_SUPPORTED)
5705 auto pixmap = builderObj->GetProperty("pixelMap");
5706 dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
5707 #endif
5708 auto extraInfo = builderObj->GetProperty("extraInfo");
5709 ParseJsString(extraInfo, dragDropInfo.extraInfo);
5710 return dragDropInfo;
5711 };
5712 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
5713 }
5714
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)5715 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
5716 {
5717 auto node = ParseDragNode(info);
5718 if (!node) {
5719 return false;
5720 }
5721 dragInfo.node = node;
5722 return true;
5723 }
5724
ParseDragNode(const JSRef<JSVal> & info)5725 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
5726 {
5727 auto builderFunc = ParseDragStartBuilderFunc(info);
5728 if (!builderFunc) {
5729 return nullptr;
5730 }
5731 // use another VSP instance while executing the builder function
5732 ViewStackModel::GetInstance()->NewScope();
5733 {
5734 ACE_SCORING_EVENT("onDragStart.builder");
5735 builderFunc->Execute();
5736 }
5737
5738 return ViewStackModel::GetInstance()->Finish();
5739 }
5740
JsOnDragEnter(const JSCallbackInfo & info)5741 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
5742 {
5743 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5744 auto jsVal = info[0];
5745 if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
5746 return;
5747 }
5748 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5749 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5750 auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
5751 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5752 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5753 ACE_SCORING_EVENT("onDragEnter");
5754 PipelineContext::SetCallBackNode(node);
5755 func->Execute(info, extraParams);
5756 };
5757
5758 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
5759 }
5760
JsOnDragEnd(const JSCallbackInfo & info)5761 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
5762 {
5763 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5764 auto jsVal = info[0];
5765 if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
5766 return;
5767 }
5768 RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5769 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5770 auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
5771 const RefPtr<OHOS::Ace::DragEvent>& info) {
5772 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5773 ACE_SCORING_EVENT("onDragEnd");
5774 auto extraParams = JsonUtil::Create(true);
5775 PipelineContext::SetCallBackNode(node);
5776 func->Execute(info, extraParams->ToString());
5777 };
5778
5779 ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
5780 }
5781
JsOnDragMove(const JSCallbackInfo & info)5782 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
5783 {
5784 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5785 auto jsVal = info[0];
5786 if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
5787 return;
5788 }
5789 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5790 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5791 auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
5792 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5793 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5794 ACE_SCORING_EVENT("onDragMove");
5795 PipelineContext::SetCallBackNode(node);
5796 func->Execute(info, extraParams);
5797 };
5798
5799 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
5800 }
5801
JsOnDragLeave(const JSCallbackInfo & info)5802 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
5803 {
5804 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5805 auto jsVal = info[0];
5806 if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
5807 return;
5808 }
5809 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5810 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5811 auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
5812 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5813 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5814 ACE_SCORING_EVENT("onDragLeave");
5815 PipelineContext::SetCallBackNode(node);
5816 func->Execute(info, extraParams);
5817 };
5818
5819 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
5820 }
5821
JsOnDrop(const JSCallbackInfo & info)5822 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
5823 {
5824 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5825 auto jsVal = info[0];
5826 if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
5827 return;
5828 }
5829 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
5830 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5831 auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
5832 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5833 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5834 ACE_SCORING_EVENT("onDrop");
5835 PipelineContext::SetCallBackNode(node);
5836 func->Execute(info, extraParams);
5837 };
5838
5839 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
5840
5841 bool disableDataPrefetch = false;
5842 if (info.Length() > 1 && info[1]->IsObject()) {
5843 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
5844 auto jsDisableDataPrefetch = interObj->GetProperty("disableDataPrefetch");
5845 if (jsDisableDataPrefetch->IsBoolean()) {
5846 disableDataPrefetch = jsDisableDataPrefetch->ToBoolean();
5847 }
5848 }
5849 ViewAbstractModel::GetInstance()->SetDisableDataPrefetch(disableDataPrefetch);
5850 }
5851
JsOnAreaChange(const JSCallbackInfo & info)5852 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
5853 {
5854 auto jsVal = info[0];
5855 if (jsVal->IsUndefined() && IsDisableEventVersion()) {
5856 ViewAbstractModel::GetInstance()->DisableOnAreaChange();
5857 return;
5858 }
5859 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5860 if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
5861 return;
5862 }
5863 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
5864
5865 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5866 auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
5867 node = frameNode](
5868 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
5869 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5870 ACE_SCORING_EVENT("onAreaChange");
5871 PipelineContext::SetCallBackNode(node);
5872 func->Execute(oldRect, oldOrigin, rect, origin);
5873 };
5874 ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
5875 }
5876
JsOnSizeChange(const JSCallbackInfo & info)5877 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
5878 {
5879 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5880 auto jsVal = info[0];
5881 if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
5882 return;
5883 }
5884 auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
5885
5886 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
5887 auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
5888 node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
5889 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5890 ACE_SCORING_EVENT("onSizeChange");
5891 PipelineContext::SetCallBackNode(node);
5892 func->Execute(oldRect, rect);
5893 };
5894 ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
5895 }
5896
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)5897 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
5898 {
5899 if (!info[0]->IsObject()) {
5900 return;
5901 }
5902 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5903 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
5904 // angle
5905 std::optional<float> degree;
5906 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
5907 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
5908 } else {
5909 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
5910 }
5911 if (degree) {
5912 newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
5913 degree.reset();
5914 }
5915 // direction
5916 auto direction = static_cast<GradientDirection>(
5917 jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
5918 SetGradientDirection(newGradient, direction);
5919 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
5920 newGradient.SetRepeat(repeating);
5921 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
5922 }
5923
SetGradientDirection(NG::Gradient & newGradient,const GradientDirection & direction)5924 void JSViewAbstract::SetGradientDirection(NG::Gradient& newGradient, const GradientDirection& direction)
5925 {
5926 switch (direction) {
5927 case GradientDirection::LEFT:
5928 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5929 break;
5930 case GradientDirection::RIGHT:
5931 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5932 break;
5933 case GradientDirection::TOP:
5934 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5935 break;
5936 case GradientDirection::BOTTOM:
5937 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5938 break;
5939 case GradientDirection::LEFT_TOP:
5940 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5941 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5942 break;
5943 case GradientDirection::LEFT_BOTTOM:
5944 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5945 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5946 break;
5947 case GradientDirection::RIGHT_TOP:
5948 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5949 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5950 break;
5951 case GradientDirection::RIGHT_BOTTOM:
5952 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5953 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5954 break;
5955 default:
5956 break;
5957 }
5958 }
5959
JsRadialGradient(const JSCallbackInfo & info)5960 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
5961 {
5962 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5963 auto jsVal = info[0];
5964 if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
5965 NG::Gradient newGradient;
5966 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
5967 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
5968 return;
5969 }
5970 NG::Gradient newGradient;
5971 NewJsRadialGradient(info, newGradient);
5972 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
5973 }
5974
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)5975 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
5976 {
5977 JSRef<JSVal> arg = info[0];
5978 if (!arg->IsObject()) {
5979 return;
5980 }
5981 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
5982 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
5983 // center
5984 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
5985 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
5986 CalcDimension value;
5987 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
5988 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
5989 newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
5990 if (value.Unit() == DimensionUnit::PERCENT) {
5991 // [0,1] -> [0, 100]
5992 newGradient.GetRadialGradient()->radialCenterX =
5993 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
5994 }
5995 }
5996 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
5997 newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
5998 if (value.Unit() == DimensionUnit::PERCENT) {
5999 // [0,1] -> [0, 100]
6000 newGradient.GetRadialGradient()->radialCenterY =
6001 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6002 }
6003 }
6004 }
6005 // radius
6006 CalcDimension radius;
6007 if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) {
6008 newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
6009 newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
6010 }
6011 // repeating
6012 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6013 newGradient.SetRepeat(repeating);
6014 // color stops
6015 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6016 }
6017
JsSweepGradient(const JSCallbackInfo & info)6018 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
6019 {
6020 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6021 auto jsVal = info[0];
6022 if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
6023 NG::Gradient newGradient;
6024 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6025 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6026 return;
6027 }
6028
6029 NG::Gradient newGradient;
6030 NewJsSweepGradient(info, newGradient);
6031 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6032 }
6033
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6034 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6035 {
6036 JSRef<JSVal> arg = info[0];
6037 if (!arg->IsObject()) {
6038 return;
6039 }
6040 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6041 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6042 // center
6043 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6044 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6045 CalcDimension value;
6046 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6047 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6048 newGradient.GetSweepGradient()->centerX = CalcDimension(value);
6049 if (value.Unit() == DimensionUnit::PERCENT) {
6050 // [0,1] -> [0, 100]
6051 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6052 }
6053 }
6054 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6055 newGradient.GetSweepGradient()->centerY = CalcDimension(value);
6056 if (value.Unit() == DimensionUnit::PERCENT) {
6057 // [0,1] -> [0, 100]
6058 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6059 }
6060 }
6061 }
6062 // start, end and rotation
6063 ParseSweepGradientPartly(jsObj, newGradient);
6064 // repeating
6065 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6066 newGradient.SetRepeat(repeating);
6067 // color stops
6068 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6069 }
6070
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)6071 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
6072 {
6073 std::optional<float> degreeStart;
6074 std::optional<float> degreeEnd;
6075 std::optional<float> degreeRotation;
6076 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6077 GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
6078 GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
6079 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
6080 } else {
6081 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
6082 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
6083 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
6084 }
6085 if (degreeStart) {
6086 CheckAngle(degreeStart);
6087 newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
6088 }
6089 if (degreeEnd) {
6090 CheckAngle(degreeEnd);
6091 newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
6092 }
6093 if (degreeRotation) {
6094 CheckAngle(degreeRotation);
6095 newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
6096 }
6097 }
6098
JsMotionPath(const JSCallbackInfo & info)6099 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
6100 {
6101 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6102 auto jsVal = info[0];
6103 if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
6104 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6105 return;
6106 }
6107 MotionPathOption motionPathOption;
6108 if (ParseMotionPath(jsVal, motionPathOption)) {
6109 ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
6110 } else {
6111 TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
6112 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6113 }
6114 }
6115
JsShadow(const JSCallbackInfo & info)6116 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
6117 {
6118 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
6119 auto jsVal = info[0];
6120 if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
6121 Shadow shadow;
6122 std::vector<Shadow> shadows { shadow };
6123 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6124 return;
6125 }
6126 Shadow shadow;
6127 if (!ParseShadowProps(jsVal, shadow)) {
6128 info.ReturnSelf();
6129 return;
6130 }
6131 std::vector<Shadow> shadows { shadow };
6132 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6133 }
6134
JsBlendMode(const JSCallbackInfo & info)6135 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
6136 {
6137 if (info.Length() == 0) {
6138 return;
6139 }
6140 BlendMode blendMode = BlendMode::NONE;
6141 BlendApplyType blendApplyType = BlendApplyType::FAST;
6142 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
6143 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
6144 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
6145 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
6146 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
6147 if (info[0]->IsNumber()) {
6148 auto blendModeNum = info[0]->ToNumber<int32_t>();
6149 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
6150 blendMode = static_cast<BlendMode>(blendModeNum);
6151 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
6152 // backward compatibility code, will remove soon
6153 blendMode = BlendMode::SRC_OVER;
6154 blendApplyType = BlendApplyType::OFFSCREEN;
6155 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
6156 // backward compatibility code, will remove soon
6157 blendMode = BlendMode::SRC_IN;
6158 blendApplyType = BlendApplyType::OFFSCREEN;
6159 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
6160 // backward compatibility code, will remove soon
6161 blendMode = BlendMode::DST_IN;
6162 blendApplyType = BlendApplyType::OFFSCREEN;
6163 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
6164 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
6165 }
6166 }
6167 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
6168 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
6169 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
6170 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
6171 }
6172 }
6173 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
6174 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
6175 }
6176
JsAdvancedBlendMode(const JSCallbackInfo & info)6177 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
6178 {
6179 if (info.Length() == 0) {
6180 return;
6181 }
6182 BlendMode blendMode = BlendMode::NONE;
6183 BlendApplyType blendApplyType = BlendApplyType::FAST;
6184 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
6185 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
6186 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
6187 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
6188 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
6189 if (info[0]->IsNumber()) {
6190 auto blendModeNum = info[0]->ToNumber<int32_t>();
6191 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
6192 blendMode = static_cast<BlendMode>(blendModeNum);
6193 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
6194 // backward compatibility code, will remove soon
6195 blendMode = BlendMode::SRC_OVER;
6196 blendApplyType = BlendApplyType::OFFSCREEN;
6197 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
6198 // backward compatibility code, will remove soon
6199 blendMode = BlendMode::SRC_IN;
6200 blendApplyType = BlendApplyType::OFFSCREEN;
6201 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
6202 // backward compatibility code, will remove soon
6203 blendMode = BlendMode::DST_IN;
6204 blendApplyType = BlendApplyType::OFFSCREEN;
6205 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
6206 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
6207 }
6208 } else if (info[0]->IsObject()) {
6209 auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]);
6210 ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender);
6211 }
6212 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
6213 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
6214 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
6215 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
6216 }
6217 }
6218 if (!info[0]->IsObject()) {
6219 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
6220 }
6221 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
6222 }
6223
JsGrayScale(const JSCallbackInfo & info)6224 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
6225 {
6226 CalcDimension value;
6227 if (!ParseJsDimensionVp(info[0], value)) {
6228 value.SetValue(0.0);
6229 ViewAbstractModel::GetInstance()->SetGrayScale(value);
6230 return;
6231 }
6232
6233 if (LessNotEqual(value.Value(), 0.0)) {
6234 value.SetValue(0.0);
6235 }
6236
6237 if (GreatNotEqual(value.Value(), 1.0)) {
6238 value.SetValue(1.0);
6239 }
6240
6241 ViewAbstractModel::GetInstance()->SetGrayScale(value);
6242 }
6243
JsBrightness(const JSCallbackInfo & info)6244 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
6245 {
6246 CalcDimension value;
6247 if (!ParseJsDimensionVp(info[0], value)) {
6248 value.SetValue(1.0);
6249 ViewAbstractModel::GetInstance()->SetBrightness(value);
6250 return;
6251 }
6252
6253 ViewAbstractModel::GetInstance()->SetBrightness(value);
6254 }
6255
JsContrast(const JSCallbackInfo & info)6256 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
6257 {
6258 CalcDimension value;
6259 if (!ParseJsDimensionVp(info[0], value)) {
6260 value.SetValue(1.0);
6261 ViewAbstractModel::GetInstance()->SetContrast(value);
6262 return;
6263 }
6264
6265 if (LessNotEqual(value.Value(), 0.0)) {
6266 value.SetValue(0.0);
6267 }
6268
6269 ViewAbstractModel::GetInstance()->SetContrast(value);
6270 }
6271
JsSaturate(const JSCallbackInfo & info)6272 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
6273 {
6274 CalcDimension value;
6275 if (!ParseJsDimensionVp(info[0], value)) {
6276 value.SetValue(1.0);
6277 ViewAbstractModel::GetInstance()->SetSaturate(value);
6278 return;
6279 }
6280
6281 if (LessNotEqual(value.Value(), 0.0)) {
6282 value.SetValue(0.0);
6283 }
6284
6285 ViewAbstractModel::GetInstance()->SetSaturate(value);
6286 }
6287
JsSepia(const JSCallbackInfo & info)6288 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
6289 {
6290 CalcDimension value;
6291 if (!ParseJsDimensionVp(info[0], value)) {
6292 value.SetValue(0.0);
6293 ViewAbstractModel::GetInstance()->SetSepia(value);
6294 return;
6295 }
6296
6297 if (LessNotEqual(value.Value(), 0.0)) {
6298 value.SetValue(0.0);
6299 }
6300
6301 ViewAbstractModel::GetInstance()->SetSepia(value);
6302 }
6303
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)6304 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
6305 {
6306 double invertValue = 0.0;
6307 if (ParseJsDouble(jsValue, invertValue)) {
6308 invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
6309 return true;
6310 }
6311 auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
6312 if (!argsPtrItem || argsPtrItem->IsNull()) {
6313 return false;
6314 }
6315 InvertOption option;
6316 double low = 0.0;
6317 if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
6318 option.low_ = std::clamp(low, 0.0, 1.0);
6319 }
6320 double high = 0.0;
6321 if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
6322 option.high_ = std::clamp(high, 0.0, 1.0);
6323 }
6324 double threshold = 0.0;
6325 if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
6326 option.threshold_ = std::clamp(threshold, 0.0, 1.0);
6327 }
6328 double thresholdRange = 0.0;
6329 if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
6330 option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
6331 }
6332 invert = option;
6333 return true;
6334 }
6335
JsInvert(const JSCallbackInfo & info)6336 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
6337 {
6338 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
6339 InvertVariant invert = 0.0f;
6340 auto jsVal = info[0];
6341 if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
6342 ViewAbstractModel::GetInstance()->SetInvert(invert);
6343 return;
6344 }
6345 if (ParseInvertProps(jsVal, invert)) {
6346 ViewAbstractModel::GetInstance()->SetInvert(invert);
6347 }
6348 ViewAbstractModel::GetInstance()->SetInvert(invert);
6349 }
6350
JsSystemBarEffect(const JSCallbackInfo & info)6351 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
6352 {
6353 ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
6354 }
6355
JsHueRotate(const JSCallbackInfo & info)6356 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
6357 {
6358 std::optional<float> degree;
6359 JSRef<JSVal> arg = info[0];
6360 if (arg->IsString()) {
6361 degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
6362 } else if (arg->IsNumber()) {
6363 degree = static_cast<float>(arg->ToNumber<int32_t>());
6364 } else {
6365 ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
6366 return;
6367 }
6368 float deg = 0.0f;
6369 if (degree) {
6370 deg = degree.value();
6371 degree.reset();
6372 }
6373 deg = std::fmod(deg, ROUND_UNIT);
6374 if (deg < 0.0f) {
6375 deg += ROUND_UNIT;
6376 }
6377 ViewAbstractModel::GetInstance()->SetHueRotate(deg);
6378 }
6379
JsClip(const JSCallbackInfo & info)6380 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
6381 {
6382 JSRef<JSVal> arg = info[0];
6383 if (arg->IsUndefined()) {
6384 ViewAbstractModel::GetInstance()->SetClipEdge(false);
6385 return;
6386 }
6387 if (arg->IsObject()) {
6388 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
6389 if (clipShape == nullptr) {
6390 return;
6391 }
6392 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
6393 } else if (arg->IsBoolean()) {
6394 ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
6395 }
6396 }
6397
JsClipShape(const JSCallbackInfo & info)6398 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
6399 {
6400 if (info[0]->IsObject()) {
6401 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
6402 if (clipShape == nullptr) {
6403 return;
6404 }
6405 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
6406 }
6407 }
6408
JsMask(const JSCallbackInfo & info)6409 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
6410 {
6411 JSRef<JSVal> arg = info[0];
6412 if (!arg->IsObject()) {
6413 ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
6414 return;
6415 }
6416 auto paramObject = JSRef<JSObject>::Cast(arg);
6417 JSRef<JSVal> typeParam = paramObject->GetProperty("type");
6418 if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
6419 typeParam->ToString() == "ProgressMask") {
6420 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
6421 JSRef<JSVal> jValue = paramObject->GetProperty("value");
6422 auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
6423 if (value < 0.0f) {
6424 value = 0.0f;
6425 }
6426 progressMask->SetValue(value);
6427 JSRef<JSVal> jTotal = paramObject->GetProperty("total");
6428 auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
6429 if (total < 0.0f) {
6430 total = DEFAULT_PROGRESS_TOTAL;
6431 }
6432 progressMask->SetMaxValue(total);
6433 JSRef<JSVal> jColor = paramObject->GetProperty("color");
6434 Color colorVal;
6435 if (ParseJsColor(jColor, colorVal)) {
6436 progressMask->SetColor(colorVal);
6437 } else {
6438 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
6439 progressMask->SetColor(theme->GetMaskColor());
6440 }
6441 JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
6442 if (jEnableBreathe->IsBoolean()) {
6443 progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
6444 }
6445 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
6446 } else {
6447 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
6448 if (maskShape == nullptr) {
6449 return;
6450 };
6451 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
6452 }
6453 }
6454
JsMaskShape(const JSCallbackInfo & info)6455 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
6456 {
6457 if (!info[0]->IsObject()) {
6458 return;
6459 }
6460
6461 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
6462 if (maskShape == nullptr) {
6463 return;
6464 };
6465 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
6466 }
6467
JsFocusable(const JSCallbackInfo & info)6468 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
6469 {
6470 if (!info[0]->IsBoolean()) {
6471 return;
6472 }
6473 ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
6474 }
6475
JsTabStop(const JSCallbackInfo & info)6476 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
6477 {
6478 if (!info[0]->IsBoolean()) {
6479 ViewAbstractModel::GetInstance()->SetTabStop(false);
6480 return;
6481 }
6482 ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
6483 }
6484
JsNextFocus(const JSCallbackInfo & info)6485 void JSViewAbstract::JsNextFocus(const JSCallbackInfo& info)
6486 {
6487 ViewAbstractModel::GetInstance()->ResetNextFocus();
6488 if (info.Length() == 1 && info[0]->IsObject()) {
6489 auto obj = JSRef<JSObject>::Cast(info[0]);
6490 auto forward = obj->GetPropertyValue<std::string>("forward", "");
6491 if (!forward.empty()) {
6492 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::TAB, forward);
6493 }
6494 auto backward = obj->GetPropertyValue<std::string>("backward", "");
6495 if (!backward.empty()) {
6496 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::SHIFT_TAB, backward);
6497 }
6498 auto up = obj->GetPropertyValue<std::string>("up", "");
6499 if (!up.empty()) {
6500 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::UP, up);
6501 }
6502 auto down = obj->GetPropertyValue<std::string>("down", "");
6503 if (!down.empty()) {
6504 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::DOWN, down);
6505 }
6506 auto left = obj->GetPropertyValue<std::string>("left", "");
6507 if (!left.empty()) {
6508 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::LEFT, left);
6509 }
6510 auto right = obj->GetPropertyValue<std::string>("right", "");
6511 if (!right.empty()) {
6512 ViewAbstractModel::GetInstance()->SetNextFocus(NG::FocusIntension::RIGHT, right);
6513 }
6514 }
6515 }
6516
JsFocusBox(const JSCallbackInfo & info)6517 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
6518 {
6519 if (!info[0]->IsObject() || info.Length() != 1) {
6520 return;
6521 }
6522 auto obj = JSRef<JSObject>::Cast(info[0]);
6523 NG::FocusBoxStyle style;
6524
6525 CalcDimension margin;
6526 if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) {
6527 style.margin = margin;
6528 }
6529 CalcDimension strokeWidth;
6530 if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) {
6531 style.strokeWidth = strokeWidth;
6532 }
6533 Color strokeColor;
6534 if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) {
6535 style.strokeColor = strokeColor;
6536 }
6537
6538 ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
6539 }
6540
JsOnFocusMove(const JSCallbackInfo & args)6541 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
6542 {
6543 JSRef<JSVal> arg = args[0];
6544 if (arg->IsFunction()) {
6545 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
6546 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6547 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
6548 int info) {
6549 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6550 ACE_SCORING_EVENT("onFocusMove");
6551 PipelineContext::SetCallBackNode(node);
6552 func->Execute(info);
6553 };
6554 ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
6555 }
6556 }
6557
JsOnKeyEvent(const JSCallbackInfo & args)6558 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
6559 {
6560 JSRef<JSVal> arg = args[0];
6561 if (arg->IsUndefined() && IsDisableEventVersion()) {
6562 ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
6563 return;
6564 }
6565 if (!arg->IsFunction()) {
6566 return;
6567 }
6568 RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
6569 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6570 auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
6571 KeyEventInfo& info) -> bool {
6572 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
6573 ACE_SCORING_EVENT("onKey");
6574 PipelineContext::SetCallBackNode(node);
6575 auto ret = func->ExecuteWithValue(info);
6576 return ret->IsBoolean() ? ret->ToBoolean() : false;
6577 };
6578 ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
6579 }
6580
JsDispatchKeyEvent(const JSCallbackInfo & args)6581 void JSViewAbstract::JsDispatchKeyEvent(const JSCallbackInfo& args)
6582 {
6583 JSRef<JSVal> arg = args[0];
6584 if (!(arg->IsNumber() || arg->IsString())) {
6585 return;
6586 }
6587 RefPtr<NG::FrameNode> frameNode = nullptr;
6588 if (arg->IsString()) {
6589 std::string id = arg->ToString();
6590 frameNode = NG::Inspector::GetFrameNodeByKey(id);
6591 }
6592
6593 if (arg->IsNumber()) {
6594 auto id = arg->ToNumber<int32_t>();
6595 auto node = ElementRegister::GetInstance()->GetNodeById(id);
6596 frameNode = AceType::DynamicCast<NG::FrameNode>(node);
6597 }
6598 CHECK_NULL_VOID(frameNode);
6599 auto focusHub = frameNode->GetOrCreateFocusHub();
6600 CHECK_NULL_VOID(focusHub);
6601
6602 if (!(args[1]->IsObject())) {
6603 return;
6604 }
6605 JSRef<JSObject> jsObject = JSRef<JSObject>::Cast(args[1]);
6606 auto eventInfoPtr = jsObject->Unwrap<KeyEventInfo>();
6607 CHECK_NULL_VOID(eventInfoPtr);
6608 KeyEvent keyEvent;
6609 eventInfoPtr->ParseKeyEvent(keyEvent);
6610 auto result = focusHub->HandleEvent(keyEvent);
6611 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
6612 }
6613
JsOnCrownEvent(const JSCallbackInfo & args)6614 void JSViewAbstract::JsOnCrownEvent(const JSCallbackInfo& args)
6615 {
6616 #ifdef SUPPORT_DIGITAL_CROWN
6617 if (args.Length() <= 0) {
6618 return;
6619 }
6620 if (args[0]->IsFunction()) {
6621 RefPtr<JsCrownFunction> JsOnCrownEventfunc = AceType::MakeRefPtr<JsCrownFunction>(JSRef<JSFunc>::Cast(args[0]));
6622 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->
6623 GetMainFrameNode());
6624 auto onCrownEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnCrownEventfunc),
6625 node = frameNode](CrownEventInfo& info) {
6626 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6627 ACE_SCORING_EVENT("onCrown");
6628 PipelineContext::SetCallBackNode(node);
6629 func->Execute(info);
6630 };
6631 ViewAbstractModel::GetInstance()->SetOnCrownEvent(std::move(onCrownEvent));
6632 } else {
6633 ViewAbstractModel::GetInstance()->DisableOnCrownEvent();
6634 }
6635 #endif
6636 }
6637
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle)6638 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args, NG::SheetStyle& sheetStyle)
6639 {
6640 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
6641 TAG_LOGE(AceLogTag::ACE_SHEET, "radius is not correct type");
6642 return;
6643 }
6644 CalcDimension radius;
6645 NG::BorderRadiusProperty borderRadius;
6646 if (ParseJsLengthMetrics(args, radius)) {
6647 borderRadius.SetRadius(radius);
6648 sheetStyle.radius = borderRadius;
6649 } else if (ParseBindSheetBorderRadiusProps(args, borderRadius)) {
6650 sheetStyle.radius = borderRadius;
6651 } else {
6652 TAG_LOGW(AceLogTag::ACE_SHEET, "radius is not correct.");
6653 return;
6654 }
6655 }
6656
ParseBindSheetBorderRadiusProps(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)6657 bool JSViewAbstract::ParseBindSheetBorderRadiusProps(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
6658 {
6659 if (args->IsObject()) {
6660 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
6661 if (CheckLengthMetrics(object)) {
6662 std::optional<CalcDimension> radiusTopStart = ParseBindSheetBorderRadiusProp(object, TOP_START_PROPERTY);
6663 std::optional<CalcDimension> radiusTopEnd = ParseBindSheetBorderRadiusProp(object, TOP_END_PROPERTY);
6664 std::optional<CalcDimension> radiusBottomStart =
6665 ParseBindSheetBorderRadiusProp(object, BOTTOM_START_PROPERTY);
6666 std::optional<CalcDimension> radiusBottomEnd = ParseBindSheetBorderRadiusProp(object, BOTTOM_END_PROPERTY);
6667 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
6668 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
6669 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
6670 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
6671 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
6672 radius.multiValued = true;
6673 } else {
6674 ParseBorderRadiusProps(object, radius);
6675 }
6676 return true;
6677 }
6678 return false;
6679 }
6680
ParseBindSheetBorderRadiusProp(const JSRef<JSObject> & object,const char * prop)6681 std::optional<CalcDimension> JSViewAbstract::ParseBindSheetBorderRadiusProp(
6682 const JSRef<JSObject>& object, const char* prop)
6683 {
6684 if (object->IsEmpty()) {
6685 return std::nullopt;
6686 }
6687 if (object->HasProperty(prop) && object->GetProperty(prop)->IsObject()) {
6688 JSRef<JSObject> propObj = JSRef<JSObject>::Cast(object->GetProperty(prop));
6689 CalcDimension calcDimension;
6690 if (ParseJsLengthMetrics(propObj, calcDimension)) {
6691 return calcDimension;
6692 }
6693 }
6694 return std::nullopt;
6695 }
6696
JSCreateAnimatableProperty(const JSCallbackInfo & info)6697 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
6698 {
6699 if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
6700 return;
6701 }
6702
6703 JSRef<JSVal> callback = info[2]; /* 2:args index */
6704 if (!callback->IsFunction()) {
6705 return;
6706 }
6707 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6708 std::string propertyName = info[0]->ToString();
6709 if (info[1]->IsNumber()) {
6710 float numValue = info[1]->ToNumber<float>();
6711 std::function<void(float)> onCallbackEvent;
6712 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
6713 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
6714 node = frameNode](const float val) {
6715 ContainerScope scope(id);
6716 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6717 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
6718 PipelineContext::SetCallBackNode(node);
6719 func->ExecuteJS(1, &newJSVal);
6720 };
6721 ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
6722 } else if (info[1]->IsObject()) {
6723 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6724 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
6725 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
6726 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
6727 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
6728 std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
6729 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
6730 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
6731 node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
6732 ContainerScope scope(id);
6733 RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
6734 if (!impl) {
6735 return;
6736 }
6737 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6738 auto newJSVal = JSRef<JSVal>(impl->GetObject());
6739 PipelineContext::SetCallBackNode(node);
6740 func->ExecuteJS(1, &newJSVal);
6741 };
6742 ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
6743 propertyName, animatableArithmetic, onCallbackEvent);
6744 }
6745 }
6746
JSUpdateAnimatableProperty(const JSCallbackInfo & info)6747 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
6748 {
6749 if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
6750 return;
6751 }
6752
6753 std::string propertyName = info[0]->ToString();
6754 float numValue = 0.0;
6755 if (info[1]->IsNumber()) {
6756 numValue = info[1]->ToNumber<float>();
6757 ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
6758 } else if (info[1]->IsObject()) {
6759 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6760 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
6761 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
6762 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
6763 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
6764 ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
6765 }
6766 }
6767
JsExpandSafeArea(const JSCallbackInfo & info)6768 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
6769 {
6770 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
6771 if (info.Length() >= PARAMETER_LENGTH_FIRST && info[0]->IsArray()) {
6772 auto paramArray = JSRef<JSArray>::Cast(info[0]);
6773 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
6774 for (size_t i = 0; i < paramArray->Length(); ++i) {
6775 if (!paramArray->GetValueAt(i)->IsNumber() ||
6776 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
6777 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
6778 break;
6779 }
6780 safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
6781 }
6782 opts.type = safeAreaType;
6783 }
6784 if (info.Length() >= 2 && info[1]->IsArray()) {
6785 auto paramArray = JSRef<JSArray>::Cast(info[1]);
6786 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
6787 for (size_t i = 0; i < paramArray->Length(); ++i) {
6788 if (!paramArray->GetValueAt(i)->IsNumber() ||
6789 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
6790 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
6791 break;
6792 }
6793 safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
6794 }
6795 opts.edges = safeAreaEdge;
6796 }
6797
6798 ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
6799 }
6800
ParseJSLightSource(JSRef<JSObject> & lightSource)6801 void ParseJSLightSource(JSRef<JSObject>& lightSource)
6802 {
6803 if (lightSource->IsUndefined()) {
6804 return;
6805 }
6806 JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
6807 JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
6808 JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
6809 JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
6810 JSRef<JSVal> color = lightSource->GetProperty("color");
6811
6812 CalcDimension dimPositionX;
6813 CalcDimension dimPositionY;
6814 CalcDimension dimPositionZ;
6815 if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
6816 JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
6817 JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
6818 ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
6819 }
6820
6821 if (intensity->IsNumber()) {
6822 float intensityValue = intensity->ToNumber<float>();
6823 ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
6824 }
6825
6826 Color lightColor;
6827 if (JSViewAbstract::ParseJsColor(color, lightColor)) {
6828 ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
6829 }
6830 }
6831
JsPointLight(const JSCallbackInfo & info)6832 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
6833 {
6834 #ifdef POINT_LIGHT_ENABLE
6835 if (!info[0]->IsObject()) {
6836 return;
6837 }
6838
6839 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
6840 JSRef<JSObject> lightSource = object->GetProperty("lightSource");
6841 ParseJSLightSource(lightSource);
6842
6843 auto resourceWrapper = CreateResourceWrapper();
6844 if (!resourceWrapper) {
6845 return;
6846 }
6847 double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
6848 Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
6849 Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
6850
6851 JSRef<JSVal> illuminated = object->GetProperty("illuminated");
6852 if (illuminated->IsNumber()) {
6853 uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
6854 ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
6855 ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
6856 }
6857
6858 JSRef<JSVal> bloom = object->GetProperty("bloom");
6859 if (bloom->IsNumber()) {
6860 float bloomValue = bloom->ToNumber<float>();
6861 ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
6862
6863 Shadow shadow;
6864 shadow.SetBlurRadius(bloomValue * bloomRadius);
6865 shadow.SetColor(bloomColor);
6866 std::vector<Shadow> shadows { shadow };
6867 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6868 }
6869 #endif
6870 }
6871
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)6872 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
6873 {
6874 if (info[0]->IsBoolean()) {
6875 ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
6876 }
6877 }
6878
JsNotifyDragStartRequest(const JSCallbackInfo & info)6879 void JSViewAbstract::JsNotifyDragStartRequest(const JSCallbackInfo& info)
6880 {
6881 if (info[0]->IsNumber()) {
6882 int32_t dragStatus = info[0]->ToNumber<int32_t>();
6883 ViewAbstractModel::GetInstance()->NotifyDragStartRequest(
6884 static_cast<DragStartRequestStatus>(dragStatus));
6885 }
6886 }
6887
JsCancelDataLoading(const std::string & key)6888 void JSViewAbstract::JsCancelDataLoading(const std::string& key)
6889 {
6890 auto ret = ViewAbstractModel::GetInstance()->CancelDataLoading(key);
6891 if (ret != 0) {
6892 JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Invalid input parameter.");
6893 }
6894 }
6895
JSBind(BindingTarget globalObj)6896 void JSViewAbstract::JSBind(BindingTarget globalObj)
6897 {
6898 JSClass<JSViewAbstract>::Declare("JSViewAbstract");
6899
6900 // static methods
6901 MethodOptions opt = MethodOptions::NONE;
6902 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
6903
6904 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
6905 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
6906 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
6907 JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
6908 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
6909 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
6910 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
6911 JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSLayoutableView::JsPixelRound);
6912 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
6913 JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSLayoutableView::JsChainWeight);
6914
6915 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
6916 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
6917 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
6918 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
6919 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
6920
6921 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
6922 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
6923 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
6924 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
6925 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
6926 JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
6927
6928 JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
6929 JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
6930 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
6931 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
6932 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
6933 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
6934 JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
6935 JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
6936 JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
6937 JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
6938 JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
6939 JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
6940 JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
6941 JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
6942 JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
6943 JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
6944 JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
6945 JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
6946 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
6947 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
6948 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
6949 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
6950 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
6951 JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
6952
6953 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
6954 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
6955 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
6956 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
6957 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
6958 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
6959 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
6960 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
6961 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
6962 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
6963 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
6964 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
6965
6966 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
6967 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
6968 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
6969 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
6970 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
6971 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
6972 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
6973
6974 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
6975 JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
6976 JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
6977 JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
6978 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
6979 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
6980 JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
6981 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
6982 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal", &JSViewAbstract::JsBackgroundBrightnessInternal);
6983 JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
6984 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
6985 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
6986 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
6987 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
6988 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
6989 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
6990 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
6991 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
6992 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
6993 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
6994 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
6995 #ifndef WEARABLE_PRODUCT
6996 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
6997 JSClass<JSViewAbstract>::StaticMethod("bindTips", &JSViewAbstract::JsBindTips);
6998 #endif
6999
7000 JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
7001 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
7002 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
7003 JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
7004 JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
7005 JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
7006 JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
7007 JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
7008 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
7009 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
7010 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
7011 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
7012 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
7013 JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
7014
7015 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
7016 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
7017 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
7018 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
7019 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
7020 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
7021 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
7022 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
7023 JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
7024 JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
7025 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
7026 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
7027 JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
7028 JSClass<JSViewAbstract>::StaticMethod("nextFocus", &JSViewAbstract::JsNextFocus);
7029 JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
7030 JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
7031 JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
7032 JSClass<JSViewAbstract>::StaticMethod("onKeyEventDispatch", &JSInteractableView::JsOnKeyEventDispatch);
7033 JSClass<JSViewAbstract>::StaticMethod("dispatchKeyEvent", &JSViewAbstract::JsDispatchKeyEvent);
7034 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
7035 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
7036 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
7037 JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
7038 JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
7039 JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
7040 JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
7041 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
7042 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
7043 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
7044 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
7045 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
7046 JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
7047 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
7048 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
7049 JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
7050 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
7051 JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
7052 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
7053 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
7054 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
7055 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
7056 JSClass<JSViewAbstract>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
7057 JSClass<JSViewAbstract>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
7058 JSClass<JSViewAbstract>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
7059 JSClass<JSViewAbstract>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
7060 JSClass<JSViewAbstract>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
7061 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
7062 JSClass<JSViewAbstract>::StaticMethod("onAxisEvent", &JSViewAbstract::JsOnAxisEvent);
7063 JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
7064 JSClass<JSViewAbstract>::StaticMethod("onHoverMove", &JSViewAbstract::JsOnHoverMove);
7065 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
7066 JSClass<JSViewAbstract>::StaticMethod("onDigitalCrown", &JSViewAbstract::JsOnCrownEvent);
7067 JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
7068 JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
7069 JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
7070 JSClass<JSViewAbstract>::StaticMethod(
7071 "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
7072 JSClass<JSViewAbstract>::StaticMethod(
7073 "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
7074 JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
7075 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
7076 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
7077 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
7078 JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
7079 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
7080 JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
7081 JSClass<JSViewAbstract>::StaticMethod("onFocusAxisEvent", &JSViewAbstract::JsOnFocusAxisEvent);
7082
7083 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
7084 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
7085 JSClass<JSViewAbstract>::StaticMethod("accessibilityNextFocusId", &JSViewAbstract::JsAccessibilityNextFocusId);
7086 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
7087 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
7088 JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
7089 JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
7090 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
7091 JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
7092 JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
7093 JSClass<JSViewAbstract>::StaticMethod("accessibilityRole", &JSViewAbstract::JsAccessibilityRole);
7094 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityFocus", &JSViewAbstract::JsOnAccessibilityFocus);
7095 JSClass<JSViewAbstract>::StaticMethod("accessibilityDefaultFocus", &JSViewAbstract::JsAccessibilityDefaultFocus);
7096 JSClass<JSViewAbstract>::StaticMethod("accessibilityUseSamePage", &JSViewAbstract::JsAccessibilityUseSamePage);
7097 JSClass<JSViewAbstract>::StaticMethod("accessibilityScrollTriggerable",
7098 &JSViewAbstract::JsAccessibilityScrollTriggerable);
7099 JSClass<JSViewAbstract>::StaticMethod("accessibilityFocusDrawLevel",
7100 &JSViewAbstract::JsAccessibilityFocusDrawLevel);
7101
7102 JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
7103 JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
7104 JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
7105 JSClass<JSViewAbstract>::StaticMethod(
7106 "onVisibleAreaApproximateChange", &JSViewAbstract::JsOnVisibleAreaApproximateChange);
7107 JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
7108 JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
7109 JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
7110 JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
7111 JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
7112 JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
7113 JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
7114 JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
7115
7116 JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
7117 JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
7118 JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
7119 JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
7120
7121 JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
7122
7123 JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
7124
7125 JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
7126 JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
7127 JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
7128 JSClass<JSViewAbstract>::StaticMethod("notifyDragStartRequest", &JSViewAbstract::JsNotifyDragStartRequest);
7129 JSClass<JSViewAbstract>::StaticMethod(
7130 "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
7131 JSClass<JSViewAbstract>::StaticMethod("cancelDataLoading", &JSViewAbstract::JsCancelDataLoading);
7132
7133 JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
7134 JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
7135
7136 JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
7137 JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
7138 JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
7139 JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
7140
7141 JSClass<JSViewAbstract>::StaticMethod("setPixelRoundMode", &JSViewAbstract::SetPixelRoundMode);
7142 JSClass<JSViewAbstract>::StaticMethod("getPixelRoundMode", &JSViewAbstract::GetPixelRoundMode);
7143
7144 JSClass<JSViewAbstract>::Bind(globalObj);
7145 }
7146
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)7147 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
7148 {
7149 auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
7150 auto vm = info->GetVM();
7151 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
7152 Local<JSValueRef> thisObj = info->GetFunctionRef();
7153 auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
7154 if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
7155 return panda::JSValueRef::Undefined(vm);
7156 }
7157
7158 auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
7159 if (weak->Invalid()) {
7160 return panda::JSValueRef::Undefined(vm);
7161 }
7162
7163 auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
7164 if (frameNode) {
7165 const auto& extensionHandler = frameNode->GetExtensionHandler();
7166 if (extensionHandler) {
7167 extensionHandler->InvalidateRender();
7168 } else {
7169 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
7170 }
7171 }
7172
7173 return panda::JSValueRef::Undefined(vm);
7174 };
7175 auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
7176 if (frameNode) {
7177 const auto& extensionHandler = frameNode->GetExtensionHandler();
7178 if (extensionHandler) {
7179 extensionHandler->InvalidateRender();
7180 } else {
7181 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
7182 }
7183 }
7184 auto vm = jsInvalidate->GetEcmaVM();
7185 auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
7186 jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
7187 jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
7188 jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
7189 }
7190
JsDrawModifier(const JSCallbackInfo & info)7191 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
7192 {
7193 if (!info[0]->IsObject()) {
7194 return;
7195 }
7196
7197 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
7198 bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
7199 if (!IsSupportDrawModifier) {
7200 return;
7201 }
7202 auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
7203 RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
7204 auto execCtx = info.GetExecutionContext();
7205 auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
7206 JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
7207 if (!drawMethod->IsFunction()) {
7208 return nullptr;
7209 }
7210
7211 auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
7212 JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
7213
7214 return GetDrawCallback(jsDrawFunc, execCtx, jsDrawModifier);
7215 };
7216
7217 drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
7218 drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
7219 drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
7220
7221 ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
7222 AddInvalidateFunc(jsDrawModifier, frameNode);
7223 }
7224
JsAllowDrop(const JSCallbackInfo & info)7225 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
7226 {
7227 std::set<std::string> allowDropSet;
7228 allowDropSet.clear();
7229 if (!info[0]->IsUndefined() && info[0]->IsArray()) {
7230 auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
7231 std::string allowDrop;
7232 for (size_t i = 0; i < allowDropArray->Length(); i++) {
7233 allowDrop = allowDropArray->GetValueAt(i)->ToString();
7234 allowDropSet.insert(allowDrop);
7235 }
7236 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
7237 } else if (info[0]->IsNull()) {
7238 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
7239 } else {
7240 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
7241 }
7242 ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
7243 }
7244
JsOnPreDrag(const JSCallbackInfo & info)7245 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
7246 {
7247 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
7248 auto jsVal = info[0];
7249 if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
7250 return;
7251 }
7252
7253 RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
7254 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7255 auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
7256 const PreDragStatus preDragStatus) {
7257 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7258 ACE_SCORING_EVENT("onPreDrag");
7259 PipelineContext::SetCallBackNode(node);
7260 func->PreDragExecute(preDragStatus);
7261 };
7262 ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
7263 }
7264
ParseDragPreviewConfig(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)7265 void JSViewAbstract::ParseDragPreviewConfig(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
7266 {
7267 if (info.Length() <= 1) {
7268 return;
7269 }
7270 auto jsVal = info[1];
7271 if (!jsVal->IsObject()) {
7272 return;
7273 }
7274 auto config = JSRef<JSObject>::Cast(jsVal);
7275 ParseJsBool(config->GetProperty("onlyForLifting"), dragPreviewInfo.onlyForLifting);
7276 ParseJsBool(config->GetProperty("delayCreating"), dragPreviewInfo.delayCreating);
7277 }
7278
ParseDragPreviewValue(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)7279 void JSViewAbstract::ParseDragPreviewValue(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
7280 {
7281 auto jsVal = info[0];
7282 JSRef<JSVal> builder;
7283 JSRef<JSVal> pixelMap;
7284 JSRef<JSVal> extraInfo;
7285 if (jsVal->IsFunction()) {
7286 builder = jsVal;
7287 } else if (jsVal->IsObject()) {
7288 auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
7289 builder = dragItemInfo->GetProperty("builder");
7290 #if defined(PIXEL_MAP_SUPPORTED)
7291 pixelMap = dragItemInfo->GetProperty("pixelMap");
7292 dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
7293 #endif
7294 extraInfo = dragItemInfo->GetProperty("extraInfo");
7295 ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
7296 } else if (jsVal->IsString()) {
7297 auto inspectorId = jsVal;
7298 ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
7299 } else {
7300 return;
7301 }
7302 ParseDragPreviewBuilderNode(info, dragPreviewInfo, builder);
7303 }
7304
ParseDragPreviewBuilderNode(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo,const JSRef<JSVal> & builder)7305 void JSViewAbstract::ParseDragPreviewBuilderNode(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo,
7306 const JSRef<JSVal>& builder)
7307 {
7308 if (!builder->IsFunction()) {
7309 return;
7310 }
7311 RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7312 CHECK_NULL_VOID(builderFunc);
7313 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7314 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
7315 node = frameNode]() -> RefPtr<NG::UINode> {
7316 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
7317 ACE_SCORING_EVENT("dragPreview.builder");
7318 PipelineContext::SetCallBackNode(node);
7319 func->Execute();
7320 auto customNode = ViewStackModel::GetInstance()->Finish();
7321 return AceType::DynamicCast<NG::UINode>(customNode);
7322 };
7323 if (!dragPreviewInfo.delayCreating) {
7324 ViewStackModel::GetInstance()->NewScope();
7325 {
7326 dragPreviewInfo.customNode = buildFunc();
7327 }
7328 } else {
7329 dragPreviewInfo.buildFunc = buildFunc;
7330 }
7331 }
7332
JsDragPreview(const JSCallbackInfo & info)7333 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
7334 {
7335 auto jsVal = info[0];
7336 if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
7337 return;
7338 }
7339 NG::DragDropInfo dragPreviewInfo;
7340 ParseDragPreviewConfig(info, dragPreviewInfo);
7341 ParseDragPreviewValue(info, dragPreviewInfo);
7342 ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
7343 }
7344
JsAlignRules(const JSCallbackInfo & info)7345 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
7346 {
7347 if (!info[0]->IsObject()) {
7348 return;
7349 }
7350
7351 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
7352 if (valueObj->IsEmpty()) {
7353 return;
7354 }
7355 const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
7356 std::map<AlignDirection, AlignRule> alignRules;
7357 BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
7358 for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
7359 auto rule = valueObj->GetProperty(keys[i]);
7360 if (rule->IsObject()) {
7361 JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
7362 JSRef<JSVal> align = val->GetProperty("align");
7363 AlignRule alignRule;
7364 alignRule.anchor = val->GetProperty("anchor")->ToString();
7365 if (i < HORIZONTAL_DIRECTION_RANGE) {
7366 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
7367 } else {
7368 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
7369 }
7370 if (i < VERTICAL_DIRECTION_RANGE) {
7371 alignRules[static_cast<AlignDirection>(i)] = alignRule;
7372 } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
7373 alignRules[AlignDirection::LEFT] = alignRule;
7374 } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
7375 alignRules[AlignDirection::RIGHT] = alignRule;
7376 }
7377 auto biasX = val->GetProperty("horizontal");
7378 if (biasX->IsNumber()) {
7379 biasPair.first = biasX->ToNumber<float>();
7380 }
7381 auto biasY = val->GetProperty("vertical");
7382 if (biasY->IsNumber()) {
7383 biasPair.second = biasY->ToNumber<float>();
7384 }
7385 }
7386 }
7387
7388 ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
7389 ViewAbstractModel::GetInstance()->SetBias(biasPair);
7390 }
7391
JsChainMode(const JSCallbackInfo & info)7392 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
7393 {
7394 ChainInfo chainInfo;
7395 if (info.Length() >= 1) {
7396 auto tmpDirection = info[0];
7397 if (tmpDirection->IsUndefined()) {
7398 chainInfo.direction = std::nullopt;
7399 } else if (tmpDirection->IsNumber()) {
7400 auto direction = tmpDirection->ToNumber<int32_t>();
7401 chainInfo.direction = static_cast<LineDirection>(direction);
7402 }
7403 }
7404
7405 if (info.Length() >= 2) { // 2 : two args
7406 auto tmpStyle = info[1];
7407 if (tmpStyle->IsUndefined()) {
7408 chainInfo.style = std::nullopt;
7409 } else if (tmpStyle->IsNumber()) {
7410 auto style = tmpStyle->ToNumber<int32_t>();
7411 chainInfo.style = static_cast<ChainStyle>(style);
7412 }
7413 }
7414 ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
7415 }
7416
SetMarginTop(const JSCallbackInfo & info)7417 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
7418 {
7419 CalcDimension value;
7420 if (!ParseJsDimensionVp(info[0], value)) {
7421 return;
7422 }
7423 ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
7424 }
7425
SetMarginBottom(const JSCallbackInfo & info)7426 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
7427 {
7428 CalcDimension value;
7429 if (!ParseJsDimensionVp(info[0], value)) {
7430 return;
7431 }
7432 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
7433 }
7434
SetMarginLeft(const JSCallbackInfo & info)7435 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
7436 {
7437 CalcDimension value;
7438 if (!ParseJsDimensionVp(info[0], value)) {
7439 return;
7440 }
7441 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
7442 }
7443
SetMarginRight(const JSCallbackInfo & info)7444 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
7445 {
7446 CalcDimension value;
7447 if (!ParseJsDimensionVp(info[0], value)) {
7448 return;
7449 }
7450 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
7451 }
7452
SetPaddingTop(const JSCallbackInfo & info)7453 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
7454 {
7455 CalcDimension value;
7456 if (!ParseJsDimensionVp(info[0], value)) {
7457 return;
7458 }
7459 ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
7460 }
7461
SetPaddingBottom(const JSCallbackInfo & info)7462 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
7463 {
7464 CalcDimension value;
7465 if (!ParseJsDimensionVp(info[0], value)) {
7466 return;
7467 }
7468 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
7469 }
7470
SetPaddingLeft(const JSCallbackInfo & info)7471 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
7472 {
7473 CalcDimension value;
7474 if (!ParseJsDimensionVp(info[0], value)) {
7475 return;
7476 }
7477 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
7478 }
7479
SetPaddingRight(const JSCallbackInfo & info)7480 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
7481 {
7482 CalcDimension value;
7483 if (!ParseJsDimensionVp(info[0], value)) {
7484 return;
7485 }
7486 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
7487 }
7488
SetSafeAreaPadding(const JSCallbackInfo & info)7489 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
7490 {
7491 ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
7492 }
7493
SetColorBlend(Color color)7494 void JSViewAbstract::SetColorBlend(Color color)
7495 {
7496 ViewAbstractModel::GetInstance()->SetColorBlend(color);
7497 }
7498
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)7499 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
7500 {
7501 ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
7502 }
7503
SetDynamicLightUp(float rate,float lightUpDegree)7504 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
7505 {
7506 ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
7507 }
7508
SetBgDynamicBrightness(BrightnessOption brightnessOption)7509 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
7510 {
7511 ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
7512 }
7513
SetFgDynamicBrightness(BrightnessOption brightnessOption)7514 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
7515 {
7516 ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
7517 }
7518
SetWindowBlur(float progress,WindowBlurStyle blurStyle)7519 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
7520 {
7521 ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
7522 }
7523
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)7524 bool JSViewAbstract::ParseJsonDimension(
7525 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
7526 {
7527 if (!jsonValue || jsonValue->IsNull()) {
7528 return false;
7529 }
7530 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
7531 return false;
7532 }
7533 if (jsonValue->IsNumber()) {
7534 result = Dimension(jsonValue->GetDouble(), defaultUnit);
7535 return true;
7536 }
7537 if (jsonValue->IsString()) {
7538 if (checkIllegal) {
7539 return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
7540 }
7541 result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
7542 return true;
7543 }
7544 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
7545 auto resId = resVal->GetValue("id");
7546 if (!resId || !resId->IsNumber()) {
7547 return false;
7548 }
7549
7550 auto resourceWrapper = CreateResourceWrapper();
7551 if (!resourceWrapper) {
7552 return false;
7553 }
7554 result = resourceWrapper->GetDimension(resId->GetUInt());
7555 return true;
7556 }
7557
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)7558 bool JSViewAbstract::ParseJsonDimensionVp(
7559 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
7560 {
7561 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
7562 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
7563 }
7564 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
7565 }
7566
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)7567 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
7568 {
7569 if (!jsonValue || jsonValue->IsNull()) {
7570 return false;
7571 }
7572 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
7573 return false;
7574 }
7575 if (jsonValue->IsNumber()) {
7576 result = jsonValue->GetDouble();
7577 return true;
7578 }
7579 if (jsonValue->IsString()) {
7580 result = StringUtils::StringToDouble(jsonValue->GetString());
7581 return true;
7582 }
7583 // parse json Resource
7584 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
7585 auto resId = resVal->GetValue("id");
7586 CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
7587 auto id = resId->GetUInt();
7588 auto resType = resVal->GetValue("type");
7589 CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
7590 auto type = resType->GetUInt();
7591
7592 auto resourceWrapper = CreateResourceWrapper();
7593 if (!resourceWrapper) {
7594 return false;
7595 }
7596 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
7597 auto numberString = resourceWrapper->GetString(id);
7598 return StringUtils::StringToDouble(numberString, result);
7599 }
7600 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
7601 result = resourceWrapper->GetInt(id);
7602 return true;
7603 }
7604 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
7605 result = resourceWrapper->GetDouble(id);
7606 return true;
7607 }
7608 return false;
7609 }
7610
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)7611 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
7612 {
7613 if (!jsonValue || jsonValue->IsNull()) {
7614 return false;
7615 }
7616 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
7617 return false;
7618 }
7619 if (jsonValue->IsNumber()) {
7620 result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
7621 return true;
7622 }
7623
7624 bool isSetColor = false;
7625 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
7626 isSetColor = jsonValue->IsString();
7627 } else {
7628 isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
7629 }
7630 if (isSetColor) {
7631 result = Color::FromString(jsonValue->GetString());
7632 return true;
7633 }
7634 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
7635 auto resId = resVal->GetValue("id");
7636 if (!resId || !resId->IsNumber()) {
7637 return false;
7638 }
7639 auto resourceWrapper = CreateResourceWrapper();
7640 if (!resourceWrapper) {
7641 return false;
7642 }
7643 result = resourceWrapper->GetColor(resId->GetUInt());
7644 return true;
7645 }
7646
ParseShadowOffsetXY(const JSRef<JSObject> & jsObj,Shadow & shadow)7647 void JSViewAbstract::ParseShadowOffsetXY(const JSRef<JSObject>& jsObj, Shadow& shadow)
7648 {
7649 CalcDimension offsetX;
7650 if (ParseJsResource(jsObj->GetProperty("offsetX"), offsetX)) {
7651 shadow.SetOffsetX(offsetX.Value());
7652 } else {
7653 if (ParseJsDimensionVp(jsObj->GetProperty("offsetX"), offsetX)) {
7654 shadow.SetOffsetX(offsetX.Value());
7655 }
7656 }
7657 CalcDimension offsetY;
7658 auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
7659 if (ParseJsResource(jsOffsetY, offsetY)) {
7660 shadow.SetOffsetY(offsetY.Value());
7661 } else {
7662 if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
7663 shadow.SetOffsetY(offsetY.Value());
7664 }
7665 }
7666 }
7667
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)7668 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
7669 {
7670 int32_t shadowStyle = 0;
7671 if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
7672 auto style = static_cast<ShadowStyle>(shadowStyle);
7673 return GetShadowFromTheme(style, shadow);
7674 }
7675 if (!jsValue->IsObject()) {
7676 return false;
7677 }
7678 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7679 double radius = 0.0;
7680 ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius);
7681 if (LessNotEqual(radius, 0.0)) {
7682 radius = 0.0;
7683 }
7684 shadow.SetBlurRadius(radius);
7685 ParseShadowOffsetXY(jsObj, shadow);
7686
7687 Color color;
7688 ShadowColorStrategy shadowColorStrategy;
7689 auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
7690 if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
7691 shadow.SetShadowColorStrategy(shadowColorStrategy);
7692 } else if (ParseJsColor(jsColor, color)) {
7693 shadow.SetColor(color);
7694 }
7695 int32_t type = static_cast<int32_t>(ShadowType::COLOR);
7696 JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
7697 if (type != static_cast<int32_t>(ShadowType::BLUR)) {
7698 type = static_cast<int32_t>(ShadowType::COLOR);
7699 }
7700 shadow.SetShadowType(static_cast<ShadowType>(type));
7701 bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
7702 shadow.SetIsFilled(isFilled);
7703 return true;
7704 }
7705
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)7706 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
7707 {
7708 auto colorMode = Container::CurrentColorMode();
7709 if (shadowStyle == ShadowStyle::None) {
7710 return true;
7711 }
7712
7713 auto container = Container::Current();
7714 CHECK_NULL_RETURN(container, false);
7715 auto pipelineContext = container->GetPipelineContext();
7716 CHECK_NULL_RETURN(pipelineContext, false);
7717
7718 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
7719 if (!shadowTheme) {
7720 return false;
7721 }
7722
7723 shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
7724 return true;
7725 }
7726
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)7727 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
7728 {
7729 if (!jsValue->IsObject()) {
7730 return false;
7731 }
7732 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7733 uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
7734 if (type == 0) {
7735 return false;
7736 }
7737 auto resourceWrapper = CreateResourceWrapper();
7738 CHECK_NULL_RETURN(resourceWrapper, false);
7739 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
7740 auto value = resourceWrapper->GetString(
7741 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
7742 return StringUtils::StringToCalcDimensionNG(value, result, false);
7743 }
7744 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
7745 auto value = std::to_string(
7746 resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
7747 StringUtils::StringToDimensionWithUnitNG(value, result);
7748 return true;
7749 }
7750
7751 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
7752 result = resourceWrapper->GetDimension(
7753 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
7754 return true;
7755 }
7756 return false;
7757 }
7758
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)7759 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
7760 {
7761 JSRef<JSVal> arg = info[0];
7762 if (!arg->IsObject()) {
7763 return false;
7764 }
7765 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
7766 JSRef<JSVal> typeValue = obj->GetProperty("types");
7767 if (!typeValue->IsArray()) {
7768 return false;
7769 }
7770 JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
7771 for (size_t i = 0; i < array->Length(); i++) {
7772 JSRef<JSVal> value = array->GetValueAt(i);
7773 auto index = value->ToNumber<int32_t>();
7774 if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
7775 return false;
7776 }
7777 if (i != 0) {
7778 textDetectConfig.types.append(",");
7779 }
7780 textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
7781 }
7782 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7783 JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
7784 if (resultCallback->IsFunction()) {
7785 auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
7786 textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
7787 const std::string& result) {
7788 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7789 PipelineContext::SetCallBackNode(node);
7790 func->Execute(result);
7791 };
7792 }
7793
7794 return ParseAIEntityColor(obj, textDetectConfig);
7795 }
7796
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)7797 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
7798 {
7799 JSRef<JSVal> entityColorValue = obj->GetProperty("color");
7800 ParseJsColor(entityColorValue, textDetectConfig.entityColor);
7801
7802 JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
7803 if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
7804 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
7805 return true;
7806 }
7807 JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
7808 JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
7809 JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
7810 JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
7811
7812 if (typeValue->IsNumber()) {
7813 textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
7814 } else {
7815 textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
7816 }
7817 if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) {
7818 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
7819 }
7820 if (styleValue->IsNumber()) {
7821 textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
7822 } else {
7823 textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
7824 }
7825
7826 return true;
7827 }
7828
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)7829 void JSViewAbstract::GetAngle(
7830 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
7831 {
7832 auto value = jsonValue->GetValue(key);
7833 if (value && value->IsString()) {
7834 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
7835 } else if (value && value->IsNumber()) {
7836 angle = static_cast<float>(value->GetDouble());
7837 }
7838 }
7839
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)7840 void JSViewAbstract::GetJsAngle(
7841 int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
7842 {
7843 if (!jsValue->IsObject()) {
7844 return;
7845 }
7846 JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
7847 if (value->IsString()) {
7848 angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
7849 } else if (value->IsNumber()) {
7850 angle = value->ToNumber<float>();
7851 }
7852 }
7853
7854 // 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)7855 void JSViewAbstract::GetJsAngleWithDefault(
7856 int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
7857 {
7858 JSRef<JSVal> value = jsObj->GetProperty(key);
7859 if (value->IsString()) {
7860 double temp = 0.0;
7861 if (StringUtils::StringToDegree(value->ToString(), temp)) {
7862 angle = static_cast<float>(temp);
7863 } else {
7864 angle = defaultValue;
7865 }
7866 } else if (value->IsNumber()) {
7867 angle = value->ToNumber<float>();
7868 }
7869 }
7870
CheckAngle(std::optional<float> & angle)7871 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
7872 {
7873 angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
7874 }
7875
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)7876 void JSViewAbstract::GetPerspective(
7877 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
7878 {
7879 auto value = jsonValue->GetValue(key);
7880 if (value && value->IsNumber()) {
7881 perspective = static_cast<float>(value->GetDouble());
7882 }
7883 }
7884
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)7885 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
7886 {
7887 auto value = jsValue->GetProperty(key);
7888 if (value->IsNumber()) {
7889 perspective = value->ToNumber<float>();
7890 }
7891 }
7892
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)7893 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
7894 {
7895 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
7896 return;
7897 }
7898
7899 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
7900 GradientColor gradientColor;
7901 auto item = colorStops->GetArrayItem(i);
7902 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
7903 auto colorParams = item->GetArrayItem(0);
7904 // color
7905 Color color;
7906 if (!ParseJsonColor(colorParams, color)) {
7907 continue;
7908 }
7909 gradientColor.SetColor(color);
7910 gradientColor.SetHasValue(false);
7911 // stop value
7912 if (item->GetArraySize() <= 1) {
7913 continue;
7914 }
7915 auto stopValue = item->GetArrayItem(1);
7916 double value = 0.0;
7917 if (ParseJsonDouble(stopValue, value)) {
7918 value = std::clamp(value, 0.0, 1.0);
7919 gradientColor.SetHasValue(true);
7920 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7921 }
7922 gradient.AddColor(gradientColor);
7923 }
7924 }
7925 }
7926
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)7927 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
7928 {
7929 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
7930 return;
7931 }
7932
7933 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
7934 NG::GradientColor gradientColor;
7935 auto item = colorStops->GetArrayItem(i);
7936 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
7937 auto colorParams = item->GetArrayItem(0);
7938 // color
7939 Color color;
7940 if (!ParseJsonColor(colorParams, color)) {
7941 continue;
7942 }
7943 gradientColor.SetColor(color);
7944 gradientColor.SetHasValue(false);
7945 // stop value
7946 if (item->GetArraySize() <= 1) {
7947 continue;
7948 }
7949 auto stopValue = item->GetArrayItem(1);
7950 double value = 0.0;
7951 if (ParseJsonDouble(stopValue, value)) {
7952 value = std::clamp(value, 0.0, 1.0);
7953 gradientColor.SetHasValue(true);
7954 // [0, 1] -> [0, 100.0];
7955 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7956 }
7957 gradient.AddColor(gradientColor);
7958 }
7959 }
7960 }
7961
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)7962 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
7963 {
7964 if (!colorStops->IsArray()) {
7965 return;
7966 }
7967
7968 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
7969 size_t length = jsArray->Length();
7970 for (size_t i = 0; i < length; i++) {
7971 NG::GradientColor gradientColor;
7972 JSRef<JSVal> item = jsArray->GetValueAt(i);
7973 if (!item->IsArray()) {
7974 continue;
7975 }
7976 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
7977 if (subArray->Length() < 2) {
7978 continue;
7979 }
7980 // color
7981 Color color;
7982 if (!ParseJsColor(subArray->GetValueAt(0), color)) {
7983 continue;
7984 }
7985 gradientColor.SetColor(color);
7986 gradientColor.SetHasValue(false);
7987 // stop value
7988 double value = 0.0;
7989 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
7990 value = std::clamp(value, 0.0, 1.0);
7991 gradientColor.SetHasValue(true);
7992 }
7993 // [0, 1] -> [0, 100.0];
7994 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7995 gradient.AddColor(gradientColor);
7996 }
7997 }
7998
SetDirection(const std::string & dir)7999 void JSViewAbstract::SetDirection(const std::string& dir)
8000 {
8001 TextDirection direction = TextDirection::AUTO;
8002 if (dir == "Ltr") {
8003 direction = TextDirection::LTR;
8004 } else if (dir == "Rtl") {
8005 direction = TextDirection::RTL;
8006 } else if (dir == "Auto") {
8007 direction = TextDirection::AUTO;
8008 } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
8009 direction = TextDirection::AUTO;
8010 }
8011 ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
8012 }
8013
GetThemeConstants(const JSRef<JSObject> & jsObj)8014 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
8015 {
8016 std::string bundleName;
8017 std::string moduleName;
8018 if (!jsObj->IsUndefined()) {
8019 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
8020 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
8021 if (bundle->IsString() && module->IsString()) {
8022 bundleName = bundle->ToString();
8023 moduleName = module->ToString();
8024 }
8025 }
8026
8027 auto cardId = CardScope::CurrentId();
8028 if (cardId != INVALID_CARD_ID) {
8029 auto container = Container::Current();
8030 auto weak = container->GetCardPipeline(cardId);
8031 auto cardPipelineContext = weak.Upgrade();
8032 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
8033 auto cardThemeManager = cardPipelineContext->GetThemeManager();
8034 CHECK_NULL_RETURN(cardThemeManager, nullptr);
8035 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
8036 }
8037
8038 #ifdef PLUGIN_COMPONENT_SUPPORTED
8039 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
8040 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
8041 if (!pluginContainer) {
8042 return nullptr;
8043 }
8044 auto pluginPipelineContext = pluginContainer->GetPipelineContext();
8045 if (!pluginPipelineContext) {
8046 return nullptr;
8047 }
8048 auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
8049 if (!pluginThemeManager) {
8050 return nullptr;
8051 }
8052 return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
8053 }
8054 #endif
8055 auto container = Container::Current();
8056 CHECK_NULL_RETURN(container, nullptr);
8057 auto pipelineContext = container->GetPipelineContext();
8058 CHECK_NULL_RETURN(pipelineContext, nullptr);
8059 auto themeManager = pipelineContext->GetThemeManager();
8060 CHECK_NULL_RETURN(themeManager, nullptr);
8061 return themeManager->GetThemeConstants(bundleName, moduleName);
8062 }
8063
JsHoverEffect(const JSCallbackInfo & info)8064 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
8065 {
8066 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
8067 auto jsVal = info[0];
8068 if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
8069 ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
8070 return;
8071 }
8072 if (!jsVal->IsNumber()) {
8073 return;
8074 }
8075 ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
8076 }
8077
JsOnMouse(const JSCallbackInfo & info)8078 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
8079 {
8080 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
8081 ViewAbstractModel::GetInstance()->DisableOnMouse();
8082 return;
8083 }
8084 if (!info[0]->IsFunction()) {
8085 return;
8086 }
8087
8088 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
8089 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8090 auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
8091 MouseInfo& mouseInfo) {
8092 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8093 ACE_SCORING_EVENT("onMouse");
8094 PipelineContext::SetCallBackNode(node);
8095 func->Execute(mouseInfo);
8096 };
8097 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
8098 }
8099
JsOnAxisEvent(const JSCallbackInfo & args)8100 void JSViewAbstract::JsOnAxisEvent(const JSCallbackInfo& args)
8101 {
8102 JSRef<JSVal> arg = args[0];
8103 if (arg->IsUndefined() && IsDisableEventVersion()) {
8104 ViewAbstractModel::GetInstance()->DisableOnAxisEvent();
8105 return;
8106 }
8107 if (!arg->IsFunction()) {
8108 return;
8109 }
8110 EcmaVM* vm = args.GetVm();
8111 CHECK_NULL_VOID(vm);
8112 auto jsOnAxisEventFunc = JSRef<JSFunc>::Cast(args[0]);
8113 if (jsOnAxisEventFunc->IsEmpty()) {
8114 return;
8115 }
8116 auto jsOnAxisFuncLocalHandle = jsOnAxisEventFunc->GetLocalHandle();
8117 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8118 auto onAxisEvent = [vm, execCtx = args.GetExecutionContext(),
8119 func = panda::CopyableGlobal(vm, jsOnAxisFuncLocalHandle),
8120 node = frameNode](Ace::AxisInfo& info) {
8121 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8122 ACE_SCORING_EVENT("onAxis");
8123 PipelineContext::SetCallBackNode(node);
8124 auto eventObj = NG::CommonBridge::CreateAxisEventInfo(vm, info);
8125 panda::Local<panda::JSValueRef> params[1] = { eventObj };
8126 func->Call(vm, func.ToLocal(), params, 1);
8127 };
8128 ViewAbstractModel::GetInstance()->SetOnAxisEvent(std::move(onAxisEvent));
8129 }
8130
JsOnHover(const JSCallbackInfo & info)8131 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
8132 {
8133 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
8134 ViewAbstractModel::GetInstance()->DisableOnHover();
8135 return;
8136 }
8137 if (!info[0]->IsFunction()) {
8138 return;
8139 }
8140
8141 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
8142 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8143 auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
8144 bool isHover, HoverInfo& hoverInfo) {
8145 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8146 ACE_SCORING_EVENT("onHover");
8147 PipelineContext::SetCallBackNode(node);
8148 func->HoverExecute(isHover, hoverInfo);
8149 };
8150 ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
8151 }
8152
JsOnHoverMove(const JSCallbackInfo & info)8153 void JSViewAbstract::JsOnHoverMove(const JSCallbackInfo& info)
8154 {
8155 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
8156 ViewAbstractModel::GetInstance()->DisableOnHoverMove();
8157 return;
8158 }
8159 if (!info[0]->IsFunction()) {
8160 return;
8161 }
8162
8163 RefPtr<JsHoverFunction> jsOnHoverMoveFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
8164 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8165 auto onHoverMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverMoveFunc), node = frameNode](
8166 HoverInfo& hoverInfo) {
8167 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8168 ACE_SCORING_EVENT("onHoverMove");
8169 PipelineContext::SetCallBackNode(node);
8170 func->HoverMoveExecute(hoverInfo);
8171 };
8172 ViewAbstractModel::GetInstance()->SetOnHoverMove(std::move(onHoverMove));
8173 }
8174
JsOnAccessibilityHover(const JSCallbackInfo & info)8175 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
8176 {
8177 if (info[0]->IsUndefined()) {
8178 ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
8179 return;
8180 }
8181 if (!info[0]->IsFunction()) {
8182 return;
8183 }
8184
8185 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
8186 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8187 auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
8188 node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
8189 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8190 ACE_SCORING_EVENT("onAccessibilityHover");
8191 PipelineContext::SetCallBackNode(node);
8192 func->AccessibilityHoverExecute(isHover, hoverInfo);
8193 };
8194 ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
8195 }
8196
JsOnClick(const JSCallbackInfo & info)8197 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
8198 {
8199 auto arg = info[0];
8200 if (arg->IsUndefined() && IsDisableEventVersion()) {
8201 ViewAbstractModel::GetInstance()->DisableOnClick();
8202 return;
8203 }
8204 if (!arg->IsFunction()) {
8205 return;
8206 }
8207
8208 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
8209 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8210 auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
8211 BaseEventInfo* info) {
8212 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8213 auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
8214 ACE_SCORING_EVENT("onClick");
8215 PipelineContext::SetCallBackNode(node);
8216 func->Execute(*tapInfo);
8217 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
8218 JSInteractableView::ReportClickEvent(node);
8219 #endif
8220 };
8221 auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
8222 auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
8223 const ClickInfo* info) {
8224 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8225 ACE_SCORING_EVENT("onClick");
8226 PipelineContext::SetCallBackNode(node);
8227 func->Execute(*info);
8228 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
8229 JSInteractableView::ReportClickEvent(node);
8230 #endif
8231 };
8232
8233 double distanceThreshold = std::numeric_limits<double>::infinity();
8234 if (info.Length() > 1 && info[1]->IsNumber()) {
8235 distanceThreshold = info[1]->ToNumber<double>();
8236 if (distanceThreshold < 0) {
8237 distanceThreshold = std::numeric_limits<double>::infinity();
8238 }
8239 }
8240 distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
8241 ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
8242 }
8243
JsOnGestureJudgeBegin(const JSCallbackInfo & info)8244 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
8245 {
8246 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8247 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
8248 return;
8249 }
8250
8251 auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
8252 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8253 auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
8254 const RefPtr<NG::GestureInfo>& gestureInfo,
8255 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
8256 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
8257 ACE_SCORING_EVENT("onGestureJudgeBegin");
8258 PipelineContext::SetCallBackNode(node);
8259 return func->Execute(gestureInfo, info);
8260 };
8261 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
8262 }
8263
JsOnTouchIntercept(const JSCallbackInfo & info)8264 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
8265 {
8266 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8267 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
8268 return;
8269 }
8270
8271 auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
8272 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8273 auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
8274 TouchEventInfo& info) -> NG::HitTestMode {
8275 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
8276 ACE_SCORING_EVENT("onTouchIntercept");
8277 PipelineContext::SetCallBackNode(node);
8278 return func->Execute(info);
8279 };
8280 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
8281 }
8282
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)8283 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
8284 {
8285 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8286 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
8287 return;
8288 }
8289
8290 auto jsParallelInnerGestureToFunc =
8291 AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
8292 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8293 auto shouldBuiltInRecognizerParallelWithFunc =
8294 [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
8295 const RefPtr<NG::NGGestureRecognizer>& current,
8296 const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
8297 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
8298 ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
8299 PipelineContext::SetCallBackNode(node);
8300 return func->Execute(current, others);
8301 };
8302 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
8303 std::move(shouldBuiltInRecognizerParallelWithFunc));
8304 }
8305
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)8306 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
8307 {
8308 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
8309 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
8310 return;
8311 }
8312
8313 auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
8314 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8315 auto onGestureRecognizerJudgefunc =
8316 [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
8317 const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
8318 const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
8319 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
8320 ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
8321 PipelineContext::SetCallBackNode(node);
8322 return func->Execute(info, current, others);
8323 };
8324
8325 bool exposeInnerGestureFlag = false;
8326 if (info.Length() > 1 && info[1]->IsBoolean()) {
8327 exposeInnerGestureFlag = info[1]->ToBoolean();
8328 }
8329 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
8330 std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
8331 }
8332
JsClickEffect(const JSCallbackInfo & info)8333 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
8334 {
8335 JSRef<JSVal> arg = info[0];
8336 if (arg->IsUndefined() || arg->IsNull()) {
8337 ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
8338 return;
8339 }
8340 if (!arg->IsObject()) {
8341 return;
8342 }
8343 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
8344 JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
8345 int32_t clickEffectLevelValue = 0;
8346 if (clickEffectLevel->IsNumber()) {
8347 clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
8348 if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
8349 clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
8350 clickEffectLevelValue = 0;
8351 }
8352 }
8353
8354 JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
8355 float scaleNumberValue = DEFAULT_SCALE_LIGHT;
8356 if (!scaleNumber->IsNumber()) {
8357 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
8358 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
8359 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
8360 }
8361 ViewAbstractModel::GetInstance()->SetClickEffectLevel(
8362 (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
8363 return;
8364 }
8365
8366 scaleNumberValue = scaleNumber->ToNumber<float>();
8367 if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
8368 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
8369 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
8370 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
8371 } else {
8372 scaleNumberValue = DEFAULT_SCALE_LIGHT;
8373 }
8374 }
8375
8376 ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
8377 }
8378
JsOnVisibleAreaChange(const JSCallbackInfo & info)8379 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
8380 {
8381 if (info.Length() != 2) {
8382 return;
8383 }
8384
8385 if (!info[0]->IsArray() || !info[1]->IsFunction()) {
8386 return;
8387 }
8388
8389 auto ratioArray = JSRef<JSArray>::Cast(info[0]);
8390 size_t size = ratioArray->Length();
8391 std::vector<double> ratioVec(size);
8392 ratioVec.clear();
8393 for (size_t i = 0; i < size; i++) {
8394 double ratio = 0.0;
8395 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
8396 if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
8397 ratio = VISIBLE_RATIO_MIN;
8398 }
8399
8400 if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
8401 ratio = VISIBLE_RATIO_MAX;
8402 }
8403 ratioVec.push_back(ratio);
8404 }
8405
8406 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
8407 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8408 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
8409 bool visible, double ratio) {
8410 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8411 ACE_SCORING_EVENT("onVisibleAreaChange");
8412
8413 JSRef<JSVal> params[2];
8414 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
8415 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
8416 PipelineContext::SetCallBackNode(node);
8417 func->ExecuteJS(2, params);
8418 };
8419 ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
8420 }
8421
JsOnVisibleAreaApproximateChange(const JSCallbackInfo & info)8422 void JSViewAbstract::JsOnVisibleAreaApproximateChange(const JSCallbackInfo& info)
8423 {
8424 if (info.Length() != PARAMETER_LENGTH_SECOND) {
8425 return;
8426 }
8427
8428 if (!info[0]->IsObject() || !info[1]->IsFunction()) {
8429 return;
8430 }
8431
8432 const auto& options = info[0];
8433 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(options);
8434 JSRef<JSVal> ratios = optionObj->GetProperty("ratios");
8435 if (!ratios->IsArray()) {
8436 return;
8437 }
8438 auto ratioArray = JSRef<JSArray>::Cast(ratios);
8439 size_t size = ratioArray->Length();
8440 std::vector<double> ratioVec(size);
8441 for (size_t i = 0; i < size; i++) {
8442 double ratio = 0.0;
8443 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
8444 ratio = std::clamp(ratio, VISIBLE_RATIO_MIN, VISIBLE_RATIO_MAX);
8445 ratioVec.push_back(ratio);
8446 }
8447 int32_t expectedUpdateInterval = DEFAULT_DURATION;
8448 JSRef<JSVal> expectedUpdateIntervalVal = optionObj->GetProperty("expectedUpdateInterval");
8449 if (expectedUpdateIntervalVal->IsNumber()) {
8450 JSViewAbstract::ParseJsInteger(expectedUpdateIntervalVal, expectedUpdateInterval);
8451 }
8452 if (expectedUpdateInterval < 0) {
8453 expectedUpdateInterval = DEFAULT_DURATION;
8454 }
8455
8456 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
8457 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8458 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
8459 bool visible, double ratio) {
8460 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8461 ACE_SCORING_EVENT("onVisibleAreaApproximateChange");
8462
8463 JSRef<JSVal> params[2];
8464 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
8465 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
8466 PipelineContext::SetCallBackNode(node);
8467 func->ExecuteJS(2, params);
8468 };
8469 ViewAbstractModel::GetInstance()->SetOnVisibleAreaApproximateChange(
8470 std::move(onVisibleChange), ratioVec, expectedUpdateInterval);
8471 }
8472
JsHitTestBehavior(const JSCallbackInfo & info)8473 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
8474 {
8475 if (info.Length() != 1 || !info[0]->IsNumber()) {
8476 return;
8477 }
8478
8479 NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
8480 hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
8481 ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
8482 }
8483
JsOnChildTouchTest(const JSCallbackInfo & info)8484 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
8485 {
8486 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8487 auto jsVal = info[0];
8488 if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
8489 return;
8490 }
8491
8492 RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
8493 AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
8494
8495 auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
8496 const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
8497 NG::TouchResult touchRes;
8498 NG::TouchResult defaultRes;
8499 defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
8500 defaultRes.id = "";
8501 auto ret = func->Execute(touchInfo);
8502 if (!ret->IsObject()) {
8503 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
8504 return defaultRes;
8505 }
8506
8507 auto retObj = JSRef<JSObject>::Cast(ret);
8508 auto strategy = retObj->GetProperty("strategy");
8509 if (!strategy->IsNumber()) {
8510 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
8511 return defaultRes;
8512 }
8513 touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
8514 auto id = retObj->GetProperty("id");
8515 if (!id->IsString()) {
8516 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
8517 return defaultRes;
8518 }
8519 touchRes.id = id->ToString();
8520 return touchRes;
8521 };
8522 ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
8523 }
8524
JsForegroundColor(const JSCallbackInfo & info)8525 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
8526 {
8527 Color foregroundColor = Color::TRANSPARENT;
8528 ForegroundColorStrategy strategy;
8529 if (ParseJsColorStrategy(info[0], strategy)) {
8530 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
8531 return;
8532 }
8533 ParseJsColor(info[0], foregroundColor);
8534 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
8535 }
8536
JsKeyboardShortcut(const JSCallbackInfo & info)8537 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
8538 {
8539 // KeyboardShortcut only allows 2 or 3 params.
8540 if (info.Length() < 2 || info.Length() > 3) {
8541 return;
8542 }
8543 if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
8544 // clear shortcut key
8545 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
8546 return;
8547 }
8548
8549 std::string value;
8550 if (info[0]->IsString()) {
8551 // common letter/number/symbol
8552 value = info[0]->ToString();
8553 if (value.size() != 1) {
8554 // clear shortcut key
8555 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
8556 return;
8557 }
8558 } else {
8559 // function keys such as F1-F10/ESC
8560 FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
8561 value = GetFunctionKeyName(functionkey);
8562 }
8563
8564 auto keysArray = JSRef<JSArray>::Cast(info[1]);
8565 size_t size = keysArray->Length();
8566 std::vector<ModifierKey> keys(size);
8567 keys.clear();
8568 for (size_t i = 0; i < size; i++) {
8569 JSRef<JSVal> key = keysArray->GetValueAt(i);
8570 if (key->IsNumber()) {
8571 keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
8572 }
8573 }
8574
8575 // KeyboardShortcut allows 3 params, the third param is function callback.
8576 if (info.Length() == 3 && info[2]->IsFunction()) {
8577 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
8578 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8579 auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
8580 node = frameNode]() {
8581 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8582 ACE_SCORING_EVENT("onKeyboardShortcutAction");
8583 PipelineContext::SetCallBackNode(node);
8584 func->ExecuteJS();
8585 };
8586 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
8587 return;
8588 }
8589 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
8590 }
8591
JsOnFocusAxisEvent(const JSCallbackInfo & args)8592 void JSViewAbstract::JsOnFocusAxisEvent(const JSCallbackInfo& args)
8593 {
8594 JSRef<JSVal> arg = args[0];
8595 if (arg->IsUndefined() && IsDisableEventVersion()) {
8596 ViewAbstractModel::GetInstance()->DisableOnFocusAxisEvent();
8597 return;
8598 }
8599 if (!arg->IsFunction()) {
8600 return;
8601 }
8602 EcmaVM* vm = args.GetVm();
8603 CHECK_NULL_VOID(vm);
8604 auto jsOnFocusAxisEventFunc = JSRef<JSFunc>::Cast(arg);
8605 if (jsOnFocusAxisEventFunc->IsEmpty()) {
8606 return;
8607 }
8608 auto jsOnFocusAxisFuncLocalHandle = jsOnFocusAxisEventFunc->GetLocalHandle();
8609 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8610 auto onFocusAxisEvent = [vm, execCtx = args.GetExecutionContext(),
8611 func = panda::CopyableGlobal(vm, jsOnFocusAxisFuncLocalHandle),
8612 node = frameNode](NG::FocusAxisEventInfo& info) {
8613 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8614 ACE_SCORING_EVENT("onFocusAxis");
8615 PipelineContext::SetCallBackNode(node);
8616 auto eventObj = NG::CommonBridge::CreateFocusAxisEventInfo(vm, info);
8617 panda::Local<panda::JSValueRef> params[1] = { eventObj };
8618 func->Call(vm, func.ToLocal(), params, 1);
8619 };
8620 ViewAbstractModel::GetInstance()->SetOnFocusAxisEvent(std::move(onFocusAxisEvent));
8621 }
8622
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)8623 bool JSViewAbstract::CheckColor(
8624 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
8625 {
8626 // Color is undefined or null
8627 if (jsValue->IsUndefined() || jsValue->IsNull()) {
8628 return false;
8629 }
8630 // input type is not in [number, string, Resource]
8631 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
8632 return false;
8633 }
8634 // Correct type, incorrect value parsing
8635 if (!ParseJsColor(jsValue, result)) {
8636 return false;
8637 }
8638 return true;
8639 }
8640
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)8641 bool JSViewAbstract::CheckLength(
8642 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
8643 {
8644 // Length is undefined or null
8645 if (jsValue->IsUndefined() || jsValue->IsNull()) {
8646 return false;
8647 }
8648 // input type is not in [number, string, Resource]
8649 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
8650 return false;
8651 }
8652 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
8653 return ParseJsDimensionVpNG(jsValue, result);
8654 }
8655 // Correct type, incorrect value parsing
8656 if (!ParseJsDimensionVp(jsValue, result)) {
8657 return false;
8658 }
8659 return true;
8660 }
8661
8662 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)8663 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
8664 {
8665 JSRef<JSVal> arg = info[0];
8666 if (arg->IsUndefined() || arg->IsNull()) {
8667 std::vector<ObscuredReasons> reasons(0);
8668 ViewAbstractModel::GetInstance()->SetObscured(reasons);
8669 return;
8670 }
8671 if (!arg->IsArray()) {
8672 return;
8673 }
8674
8675 auto obscuredArray = JSRef<JSArray>::Cast(arg);
8676 size_t size = obscuredArray->Length();
8677 std::vector<ObscuredReasons> reasons(size);
8678 reasons.clear();
8679 for (size_t i = 0; i < size; i++) {
8680 JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
8681 if (reason->IsNumber()) {
8682 reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
8683 }
8684 }
8685
8686 ViewAbstractModel::GetInstance()->SetObscured(reasons);
8687 }
8688
8689 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)8690 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
8691 {
8692 auto sensitiveInfo = info[0];
8693 if (sensitiveInfo->IsUndefined()) {
8694 ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
8695 return;
8696 }
8697 bool sensitive = false;
8698 if (sensitiveInfo->IsBoolean()) {
8699 sensitive = sensitiveInfo->ToBoolean();
8700 }
8701 ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
8702 }
8703
JSRenderGroup(const JSCallbackInfo & info)8704 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
8705 {
8706 if (info.Length() != 1) {
8707 return;
8708 }
8709 bool isRenderGroup = false;
8710 if (info[0]->IsBoolean()) {
8711 isRenderGroup = info[0]->ToBoolean();
8712 }
8713 ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
8714 }
8715
JSRenderFit(const JSCallbackInfo & info)8716 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
8717 {
8718 if (info.Length() != 1) {
8719 return;
8720 }
8721 RenderFit renderFit = RenderFit::TOP_LEFT;
8722 if (info[0]->IsNumber()) {
8723 int32_t fitNumber = info[0]->ToNumber<int32_t>();
8724 if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
8725 fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
8726 renderFit = static_cast<RenderFit>(fitNumber);
8727 }
8728 }
8729 // how content fills the node duration implicit animation
8730 ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
8731 }
8732
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)8733 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
8734 {
8735 if (!jsValue->IsObject() || jsValue->IsString()) {
8736 return false;
8737 }
8738 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
8739 if (!jsObj->IsUndefined()) {
8740 JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
8741 JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
8742 if (bundle->IsString() && module->IsString()) {
8743 bundleName = bundle->ToString();
8744 moduleName = module->ToString();
8745 return true;
8746 }
8747 }
8748 return false;
8749 }
8750
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)8751 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
8752 {
8753 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8754 return false;
8755 }
8756 Color borderColor;
8757 if (ParseJsColor(args, borderColor)) {
8758 colorProperty.SetColor(borderColor);
8759 return true;
8760 } else if (args->IsObject()) {
8761 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
8762 CommonColor commonColor;
8763 auto isLocalizedEdgeColor = ParseCommonEdgeColors(obj, commonColor);
8764 colorProperty.topColor = commonColor.top;
8765 colorProperty.bottomColor = commonColor.bottom;
8766 if (isLocalizedEdgeColor) {
8767 colorProperty.startColor = commonColor.left;
8768 colorProperty.endColor = commonColor.right;
8769 } else {
8770 colorProperty.leftColor = commonColor.left;
8771 colorProperty.rightColor = commonColor.right;
8772 }
8773 colorProperty.multiValued = true;
8774 return true;
8775 }
8776 return false;
8777 }
8778
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)8779 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
8780 {
8781 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8782 return false;
8783 }
8784 CalcDimension borderWidth;
8785 if (ParseJsDimensionVpNG(args, borderWidth, true)) {
8786 if (borderWidth.IsNegative()) {
8787 borderWidth.Reset();
8788 }
8789 borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth,
8790 std::nullopt, std::nullopt});
8791 return true;
8792 } else if (args->IsObject()) {
8793 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
8794 CommonCalcDimension commonCalcDimension;
8795 ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
8796 borderWidthProperty.topDimen = commonCalcDimension.top;
8797 borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
8798 borderWidthProperty.leftDimen = commonCalcDimension.left;
8799 borderWidthProperty.rightDimen = commonCalcDimension.right;
8800 borderWidthProperty.multiValued = true;
8801 return true;
8802 }
8803 return false;
8804 }
8805
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)8806 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
8807 {
8808 if (!args->IsObject() && !args->IsNumber()) {
8809 return false;
8810 }
8811 if (args->IsObject()) {
8812 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
8813 auto leftValue = obj->GetProperty("left");
8814 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
8815 ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
8816 }
8817 auto rightValue = obj->GetProperty("right");
8818 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
8819 ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
8820 }
8821 auto topValue = obj->GetProperty("top");
8822 if (!topValue->IsUndefined() && topValue->IsNumber()) {
8823 ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
8824 }
8825 auto bottomValue = obj->GetProperty("bottom");
8826 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
8827 ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
8828 }
8829 borderStyleProperty.multiValued = true;
8830 return true;
8831 }
8832 std::optional<BorderStyle> borderStyle;
8833 if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
8834 borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
8835 return true;
8836 }
8837 return false;
8838 }
8839
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)8840 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
8841 {
8842 std::optional<CalcDimension> radiusTopLeft;
8843 std::optional<CalcDimension> radiusTopRight;
8844 std::optional<CalcDimension> radiusBottomLeft;
8845 std::optional<CalcDimension> radiusBottomRight;
8846 CalcDimension topLeft;
8847 if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) {
8848 radiusTopLeft = topLeft;
8849 }
8850 CalcDimension topRight;
8851 if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) {
8852 radiusTopRight = topRight;
8853 }
8854 CalcDimension bottomLeft;
8855 if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) {
8856 radiusBottomLeft = bottomLeft;
8857 }
8858 CalcDimension bottomRight;
8859 if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) {
8860 radiusBottomRight = bottomRight;
8861 }
8862 CheckLengthMetrics(object);
8863 radius.radiusTopLeft = radiusTopLeft;
8864 radius.radiusTopRight = radiusTopRight;
8865 radius.radiusBottomLeft = radiusBottomLeft;
8866 radius.radiusBottomRight = radiusBottomRight;
8867 radius.multiValued = true;
8868 return;
8869 }
8870
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)8871 void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
8872 {
8873 if (CheckLengthMetrics(object)) {
8874 std::optional<CalcDimension> radiusTopStart;
8875 std::optional<CalcDimension> radiusTopEnd;
8876 std::optional<CalcDimension> radiusBottomStart;
8877 std::optional<CalcDimension> radiusBottomEnd;
8878 if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
8879 JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
8880 CalcDimension calcDimension;
8881 if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
8882 CheckDimensionUnit(calcDimension, false, true);
8883 radiusTopStart = calcDimension;
8884 }
8885 }
8886 if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
8887 JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
8888 CalcDimension calcDimension;
8889 if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
8890 CheckDimensionUnit(calcDimension, false, true);
8891 radiusTopEnd = calcDimension;
8892 }
8893 }
8894 if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
8895 JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
8896 CalcDimension calcDimension;
8897 if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
8898 CheckDimensionUnit(calcDimension, false, true);
8899 radiusBottomStart = calcDimension;
8900 }
8901 }
8902 if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
8903 JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
8904 CalcDimension calcDimension;
8905 if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
8906 CheckDimensionUnit(calcDimension, false, true);
8907 radiusBottomEnd = calcDimension;
8908 }
8909 }
8910 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
8911 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
8912 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
8913 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
8914 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
8915 radius.multiValued = true;
8916 return;
8917 }
8918 ParseBorderRadiusProps(object, radius);
8919 }
8920
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)8921 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
8922 {
8923 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8924 return false;
8925 }
8926 CalcDimension borderRadius;
8927 if (ParseJsDimensionVpNG(args, borderRadius, true)) {
8928 radius = NG::BorderRadiusProperty(borderRadius);
8929 radius.multiValued = false;
8930 } else if (args->IsObject()) {
8931 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
8932 ParseCommonBorderRadiusProps(object, radius);
8933 } else {
8934 return false;
8935 }
8936 return true;
8937 }
8938
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)8939 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
8940 {
8941 JSRef<JSVal> arg = info[0];
8942 if (!arg->IsObject()) {
8943 return;
8944 }
8945 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
8946 auto vm = info.GetVm();
8947 auto globalObj = JSNApi::GetGlobalObject(vm);
8948 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
8949 JsiValue jsiValue(globalFunc);
8950 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
8951 if (globalFuncRef->IsFunction()) {
8952 auto modifierObj = obj->GetProperty("modifier");
8953 if (modifierObj->IsUndefined()) {
8954 option.onApply = nullptr;
8955 } else {
8956 RefPtr<JsFunction> jsFunc =
8957 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
8958 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
8959 modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
8960 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8961 auto node = frameNode.Upgrade();
8962 JSRef<JSVal> params[SECOND_INDEX];
8963 params[0] = modifier;
8964 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
8965 PipelineContext::SetCallBackNode(node);
8966 func->ExecuteJS(SECOND_INDEX, params);
8967 };
8968 option.onApply = onApply;
8969 }
8970 }
8971 }
8972
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)8973 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
8974 {
8975 if (!info[0]->IsObject()) {
8976 return;
8977 }
8978 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
8979 auto numberBadge = obj->GetProperty("numberBadge");
8980 if (!numberBadge->IsEmpty()) {
8981 if (numberBadge->IsNumber()) {
8982 int64_t number = numberBadge->ToNumber<int64_t>();
8983 if (number < 0 || number > INT_MAX) {
8984 option.isNumber = false;
8985 option.isShowBadge = true;
8986 } else {
8987 option.isNumber = true;
8988 option.badgeNumber = numberBadge->ToNumber<int>();
8989 }
8990 } else if (numberBadge->IsBoolean()) {
8991 option.isNumber = false;
8992 option.isShowBadge = numberBadge->ToBoolean();
8993 }
8994 } else {
8995 option.isNumber = false;
8996 option.isShowBadge = true;
8997 }
8998 }
8999
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)9000 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
9001 {
9002 // Parse cornerRadius.
9003 auto cornerRadiusValue = obj->GetProperty("cornerRadius");
9004 NG::BorderRadiusProperty radius;
9005 if (ParseBorderRadius(cornerRadiusValue, radius)) {
9006 properties.borderRadius = radius;
9007 }
9008 // Parse border width
9009 auto borderWidthValue = obj->GetProperty("borderWidth");
9010 NG::BorderWidthProperty borderWidth;
9011 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
9012 properties.borderWidth = borderWidth;
9013 auto colorValue = obj->GetProperty("borderColor");
9014 NG::BorderColorProperty borderColor;
9015 if (ParseBorderColorProps(colorValue, borderColor)) {
9016 properties.borderColor = borderColor;
9017 } else {
9018 borderColor.SetColor(Color::BLACK);
9019 properties.borderColor = borderColor;
9020 }
9021 // Parse border style
9022 auto styleValue = obj->GetProperty("borderStyle");
9023 NG::BorderStyleProperty borderStyle;
9024 if (ParseBorderStyleProps(styleValue, borderStyle)) {
9025 properties.borderStyle = borderStyle;
9026 } else {
9027 properties.borderStyle = NG::BorderStyleProperty(
9028 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
9029 }
9030 }
9031 auto shadowValue = obj->GetProperty("shadow");
9032 Shadow shadow;
9033 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
9034 properties.shadow = shadow;
9035 }
9036 auto widthValue = obj->GetProperty("width");
9037 CalcDimension width;
9038 if (ParseJsDimensionVpNG(widthValue, width, true)) {
9039 properties.width = width;
9040 }
9041 auto heightValue = obj->GetProperty("height");
9042 CalcDimension height;
9043 if (ParseJsDimensionVpNG(heightValue, height, true)) {
9044 properties.height = height;
9045 }
9046 }
9047
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx,JSRef<JSObject> modifier)9048 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
9049 const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx, JSRef<JSObject> modifier)
9050 {
9051 std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx, modifier](
9052 NG::DrawingContext& context) -> void {
9053 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
9054 if (modifier->IsEmpty()) {
9055 return;
9056 }
9057 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
9058 objectTemplate->SetInternalFieldCount(1);
9059 JSRef<JSObject> contextObj = objectTemplate->NewInstance();
9060 JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
9061 sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
9062 sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
9063 contextObj->SetPropertyObject("size", sizeObj);
9064
9065 JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
9066 sizeInPxObj->SetProperty<float>("height", context.height);
9067 sizeInPxObj->SetProperty<float>("width", context.width);
9068 contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
9069
9070 auto engine = EngineHelper::GetCurrentEngine();
9071 CHECK_NULL_VOID(engine);
9072 NativeEngine* nativeEngine = engine->GetNativeEngine();
9073 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
9074 ScopeRAII scope(env);
9075
9076 auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
9077 OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
9078 napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
9079 if (unwrapCanvas) {
9080 unwrapCanvas->SaveCanvas();
9081 unwrapCanvas->ClipCanvas(context.width, context.height);
9082 }
9083 JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
9084 contextObj->SetPropertyObject("canvas", jsCanvasVal);
9085
9086 auto jsVal = JSRef<JSVal>::Cast(contextObj);
9087 panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
9088 JSValueWrapper valueWrapper = value;
9089 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
9090
9091 napi_wrap(
9092 env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
9093
9094 JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
9095 if (unwrapCanvas) {
9096 unwrapCanvas->RestoreCanvas();
9097 unwrapCanvas->ResetCanvas();
9098 }
9099 };
9100 return drawCallback;
9101 }
9102
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)9103 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
9104 {
9105 auto* vm = info.GetVm();
9106 return [vm, nodeId](const std::string& key) -> std::string {
9107 std::string resultString = std::string();
9108 CHECK_NULL_RETURN(vm, resultString);
9109 panda::LocalScope scope(vm);
9110 auto global = JSNApi::GetGlobalObject(vm);
9111 auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
9112 if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
9113 return resultString;
9114 }
9115 auto obj = getCustomProperty->ToObject(vm);
9116 panda::Local<panda::FunctionRef> func = obj;
9117 panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
9118 panda::StringRef::NewFromUtf8(vm, key.c_str()) };
9119 auto function = panda::CopyableGlobal(vm, func);
9120 auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
9121 if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
9122 return resultString;
9123 }
9124 auto value = callValue->ToString(vm)->ToString(vm);
9125 return value;
9126 };
9127 }
9128
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)9129 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
9130 {
9131 auto* vm = info.GetVm();
9132 panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
9133 info[1]->GetLocalHandle() };
9134 return [vm, params3]() -> bool {
9135 CHECK_NULL_RETURN(vm, false);
9136 panda::LocalScope scope(vm);
9137 auto global = JSNApi::GetGlobalObject(vm);
9138 auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
9139 if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
9140 return false;
9141 }
9142 auto obj = setCustomProperty->ToObject(vm);
9143 panda::Local<panda::FunctionRef> func = obj;
9144 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9145 auto nodeId = frameNode->GetId();
9146 auto function = panda::CopyableGlobal(vm, func);
9147 auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
9148 if (customPropertyExisted) {
9149 frameNode->SetCustomPropertyMapFlagByKey(params3[1]->ToString(vm)->ToString(vm));
9150 frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
9151 CHECK_NULL_VOID(vm);
9152 panda::LocalScope scope(vm);
9153 auto global = JSNApi::GetGlobalObject(vm);
9154 auto removeCustomProperty =
9155 global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
9156 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
9157 return;
9158 }
9159 auto obj = removeCustomProperty->ToObject(vm);
9160 panda::Local<panda::FunctionRef> func = obj;
9161 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
9162 auto function = panda::CopyableGlobal(vm, func);
9163 function->Call(vm, function.ToLocal(), params, 1);
9164 });
9165 }
9166 return true;
9167 };
9168 }
9169
JsCustomProperty(const JSCallbackInfo & info)9170 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
9171 {
9172 if (info[0]->GetLocalHandle()->IsUndefined()) {
9173 return;
9174 }
9175 auto* vm = info.GetVm();
9176 CHECK_NULL_VOID(vm);
9177 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9178 auto nodeId = frameNode->GetId();
9179 auto getFunc = ParseJsGetFunc(info, nodeId);
9180 auto func = ParseJsFunc(info, nodeId);
9181 frameNode->SetJSCustomProperty(func, getFunc);
9182 }
9183
JsLinearGradient(const JSCallbackInfo & info)9184 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
9185 {
9186 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
9187 auto jsVal = info[0];
9188 if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
9189 NG::Gradient newGradient;
9190 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
9191 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
9192 return;
9193 }
9194 NG::Gradient newGradient;
9195 NewJsLinearGradient(info, newGradient);
9196 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
9197 }
9198
JsGestureModifier(const JSCallbackInfo & info)9199 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
9200 {
9201 auto* vm = info.GetExecutionContext().vm_;
9202 CHECK_NULL_VOID(vm);
9203 auto global = JSNApi::GetGlobalObject(vm);
9204 auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
9205 if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
9206 return;
9207 }
9208 auto obj = gestureModifier->ToObject(vm);
9209 panda::Local<panda::FunctionRef> func = obj;
9210 auto thisObj = info.This()->GetLocalHandle();
9211 panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
9212 func->Call(vm, thisObj, params, 1);
9213 }
9214
JsBackgroundImageResizable(const JSCallbackInfo & info)9215 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
9216 {
9217 auto infoObj = info[0];
9218 ImageResizableSlice sliceResult;
9219 if (!infoObj->IsObject()) {
9220 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9221 return;
9222 }
9223 JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
9224 if (resizableObject->IsEmpty()) {
9225 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9226 return;
9227 }
9228 auto sliceValue = resizableObject->GetProperty("slice");
9229 if (!sliceValue->IsObject()) {
9230 return;
9231 }
9232 JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
9233 if (sliceObj->IsEmpty()) {
9234 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9235 return;
9236 }
9237 for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
9238 auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
9239 CalcDimension sliceDimension;
9240 if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
9241 continue;
9242 }
9243 if (!sliceDimension.IsValid()) {
9244 continue;
9245 }
9246 switch (static_cast<BorderImageDirection>(i)) {
9247 case BorderImageDirection::LEFT:
9248 sliceResult.left = sliceDimension;
9249 break;
9250 case BorderImageDirection::RIGHT:
9251 sliceResult.right = sliceDimension;
9252 break;
9253 case BorderImageDirection::TOP:
9254 sliceResult.top = sliceDimension;
9255 break;
9256 case BorderImageDirection::BOTTOM:
9257 sliceResult.bottom = sliceDimension;
9258 break;
9259 default:
9260 break;
9261 }
9262 }
9263 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
9264 }
9265
JsOnFocus(const JSCallbackInfo & args)9266 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
9267 {
9268 JSRef<JSVal> arg = args[0];
9269 if (arg->IsUndefined() && IsDisableEventVersion()) {
9270 ViewAbstractModel::GetInstance()->DisableOnFocus();
9271 return;
9272 }
9273 if (!arg->IsFunction()) {
9274 return;
9275 }
9276 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
9277 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9278 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
9279 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9280 ACE_SCORING_EVENT("onFocus");
9281 PipelineContext::SetCallBackNode(node);
9282 func->Execute();
9283 };
9284
9285 ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
9286 }
9287
JsOnBlur(const JSCallbackInfo & args)9288 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
9289 {
9290 JSRef<JSVal> arg = args[0];
9291 if (arg->IsUndefined() && IsDisableEventVersion()) {
9292 ViewAbstractModel::GetInstance()->DisableOnBlur();
9293 return;
9294 }
9295 if (!arg->IsFunction()) {
9296 return;
9297 }
9298 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
9299 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9300 auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
9301 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9302 ACE_SCORING_EVENT("onBlur");
9303 PipelineContext::SetCallBackNode(node);
9304 func->Execute();
9305 };
9306
9307 ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
9308 }
9309
JsTabIndex(const JSCallbackInfo & info)9310 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
9311 {
9312 JSRef<JSVal> arg = info[0];
9313 if (!arg->IsNumber()) {
9314 return;
9315 }
9316 ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
9317 }
9318
JsFocusOnTouch(const JSCallbackInfo & info)9319 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
9320 {
9321 JSRef<JSVal> arg = info[0];
9322 if (!arg->IsBoolean()) {
9323 return;
9324 }
9325 auto isFocusOnTouch = arg->ToBoolean();
9326 ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
9327 }
9328
JsDefaultFocus(const JSCallbackInfo & info)9329 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
9330 {
9331 JSRef<JSVal> arg = info[0];
9332 if (!arg->IsBoolean()) {
9333 return;
9334 }
9335 auto isDefaultFocus = arg->ToBoolean();
9336 ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
9337 }
9338
JsGroupDefaultFocus(const JSCallbackInfo & info)9339 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
9340 {
9341 JSRef<JSVal> arg = info[0];
9342 if (!arg->IsBoolean()) {
9343 return;
9344 }
9345 auto isGroupDefaultFocus = arg->ToBoolean();
9346 ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
9347 }
9348
JsKey(const std::string & key)9349 void JSViewAbstract::JsKey(const std::string& key)
9350 {
9351 ViewAbstractModel::GetInstance()->SetInspectorId(key);
9352 }
9353
JsId(const JSCallbackInfo & info)9354 void JSViewAbstract::JsId(const JSCallbackInfo& info)
9355 {
9356 JSRef<JSVal> arg = info[0];
9357 if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
9358 return;
9359 }
9360 std::string id = arg->ToString();
9361 if (id.empty()) {
9362 return;
9363 }
9364 JsKey(id);
9365 }
9366
JsRestoreId(int32_t restoreId)9367 void JSViewAbstract::JsRestoreId(int32_t restoreId)
9368 {
9369 ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
9370 }
9371
JsDebugLine(const JSCallbackInfo & info)9372 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
9373 {
9374 std::string debugLine;
9375 auto length = info.Length();
9376 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
9377
9378 if (length == 1) { // deprecated version of debug line
9379 auto jsVal = info[0];
9380 if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
9381 return;
9382 }
9383 debugLine = jsVal->ToString();
9384 } else if (length == 2) { // debug line with extra package name
9385 auto line = info[0];
9386 auto packageName = info[1];
9387 if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
9388 !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
9389 return;
9390 }
9391 auto json = JsonUtil::Create(true);
9392 json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
9393 json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
9394 debugLine = json->ToString();
9395 }
9396
9397 ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
9398 }
9399
JsOpacityPassThrough(const JSCallbackInfo & info)9400 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
9401 {
9402 double opacity = 1.0;
9403 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
9404 if (ParseJsDouble(info[0], opacity)) {
9405 opacity = std::clamp(opacity, 0.0, 1.0);
9406 }
9407 } else {
9408 if (!ParseJsDouble(info[0], opacity)) {
9409 return;
9410 }
9411 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
9412 opacity = 1.0;
9413 }
9414 }
9415
9416 ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
9417 }
9418
JsTransitionPassThrough(const JSCallbackInfo & info)9419 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
9420 {
9421 if (info.Length() == 0) {
9422 ViewAbstractModel::GetInstance()->SetTransition(
9423 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
9424 return;
9425 }
9426 if (!info[0]->IsObject()) {
9427 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
9428 ViewAbstractModel::GetInstance()->CleanTransition();
9429 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
9430 }
9431 return;
9432 }
9433 auto obj = JSRef<JSObject>::Cast(info[0]);
9434 if (!obj->GetProperty("successor_")->IsUndefined()) {
9435 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
9436 std::function<void(bool)> finishCallback;
9437 if (info.Length() > 1 && info[1]->IsFunction()) {
9438 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
9439 }
9440 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
9441 return;
9442 }
9443 auto options = ParseJsTransition(obj);
9444 ViewAbstractModel::GetInstance()->SetTransition(options, true);
9445 }
9446
JsFocusScopeId(const JSCallbackInfo & info)9447 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
9448 {
9449 if (info.Length() == 0) {
9450 return;
9451 }
9452
9453 std::string focusScopeId;
9454 if (info[0]->IsString()) {
9455 focusScopeId = info[0]->ToString();
9456 }
9457
9458 bool isGroup = false;
9459 if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
9460 info[1]->IsBoolean()) {
9461 isGroup = info[1]->ToBoolean();
9462 }
9463 bool arrowKeyStepOut = true;
9464 if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() && // 2:args index.
9465 info[2]->IsBoolean()) { // 2:args index.
9466 arrowKeyStepOut = info[2]->ToBoolean(); // 2:args index.
9467 }
9468 ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
9469 }
9470
JsFocusScopePriority(const JSCallbackInfo & info)9471 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
9472 {
9473 if (info.Length() == 0) {
9474 return;
9475 }
9476
9477 if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
9478 return;
9479 }
9480 std::string focusScopeId = info[0]->ToString();
9481
9482 int32_t focusPriority = 0;
9483 if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
9484 info[1]->IsNumber()) {
9485 focusPriority = info[1]->ToNumber<int32_t>();
9486 }
9487 ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
9488 }
9489
JsBackground(const JSCallbackInfo & info)9490 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
9491 {
9492 // Check the parameters
9493 if (info.Length() <= 0 || !info[0]->IsObject()) {
9494 return;
9495 }
9496 JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
9497 auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
9498 if (!builder->IsFunction()) {
9499 return;
9500 }
9501 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9502 CHECK_NULL_VOID(builderFunc);
9503 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9504 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
9505 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9506 ACE_SCORING_EVENT("BindBackground");
9507 PipelineContext::SetCallBackNode(node);
9508 func->Execute();
9509 };
9510 Alignment alignment = Alignment::CENTER;
9511 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
9512 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
9513 auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
9514 auto value = align->ToNumber<int32_t>();
9515 alignment = ParseAlignment(value);
9516 }
9517 ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
9518 }
9519
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)9520 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
9521 std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
9522 {
9523 auto vm = info.GetVm();
9524 auto globalObj = JSNApi::GetGlobalObject(vm);
9525 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
9526 JsiValue jsiValue(globalFunc);
9527 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
9528 if (globalFuncRef->IsFunction()) {
9529 RefPtr<JsFunction> jsFunc =
9530 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
9531 if (!modifierObj->IsObject()) {
9532 symbolApply = nullptr;
9533 } else {
9534 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
9535 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
9536 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9537 auto node = frameNode.Upgrade();
9538 CHECK_NULL_VOID(node);
9539 JSRef<JSVal> params[2];
9540 params[0] = modifierParam;
9541 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
9542 PipelineContext::SetCallBackNode(node);
9543 func->ExecuteJS(2, params);
9544 };
9545 symbolApply = onApply;
9546 }
9547 }
9548 }
9549
ParseJsPropertyId(const JSRef<JSVal> & jsValue)9550 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
9551 {
9552 int32_t resId = 0;
9553 if (jsValue->IsObject()) {
9554 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9555 JSRef<JSVal> tmp = jsObj->GetProperty("id");
9556 if (!tmp->IsNull() && tmp->IsNumber()) {
9557 resId = tmp->ToNumber<int32_t>();
9558 }
9559 }
9560 return resId;
9561 }
9562
JsVisualEffect(const JSCallbackInfo & info)9563 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
9564 {
9565 if (!info[0]->IsObject()) {
9566 return;
9567 }
9568 auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
9569 ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
9570 }
9571
JsBackgroundFilter(const JSCallbackInfo & info)9572 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
9573 {
9574 if (!info[0]->IsObject()) {
9575 return;
9576 }
9577 auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
9578 ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
9579 }
9580
JsForegroundFilter(const JSCallbackInfo & info)9581 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
9582 {
9583 if (!info[0]->IsObject()) {
9584 return;
9585 }
9586 auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
9587 ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
9588 }
9589
JsCompositingFilter(const JSCallbackInfo & info)9590 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
9591 {
9592 if (!info[0]->IsObject()) {
9593 return;
9594 }
9595 auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
9596 ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
9597 }
9598
ParseMenuItems(const JSRef<JSArray> & menuItemsArray)9599 std::vector<NG::MenuOptionsParam> JSViewAbstract::ParseMenuItems(const JSRef<JSArray>& menuItemsArray)
9600 {
9601 std::vector<NG::MenuOptionsParam> menuParams;
9602 for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
9603 auto menuItem = menuItemsArray->GetValueAt(i);
9604 if (!menuItem->IsObject()) {
9605 continue;
9606 }
9607 auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
9608 NG::MenuOptionsParam menuOptionsParam;
9609 auto jsContent = menuItemObject->GetProperty("content");
9610 std::string content;
9611 ParseJsString(jsContent, content);
9612 menuOptionsParam.content = content;
9613 auto jsStartIcon = menuItemObject->GetProperty("icon");
9614 std::string icon;
9615 ParseJsMedia(jsStartIcon, icon);
9616 menuOptionsParam.icon = icon;
9617 auto jsTextMenuId = menuItemObject->GetProperty("id");
9618 std::string id;
9619 if (jsTextMenuId->IsObject()) {
9620 auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
9621 auto jsId = textMenuIdObject->GetProperty("id_");
9622 ParseJsString(jsId, id);
9623 }
9624 menuOptionsParam.id = id;
9625 auto jsLabelInfo = menuItemObject->GetProperty("labelInfo");
9626 std::string labelInfo;
9627 ParseJsString(jsLabelInfo, labelInfo);
9628 if (jsLabelInfo->IsString() || jsLabelInfo->IsObject()) {
9629 menuOptionsParam.labelInfo = labelInfo;
9630 }
9631 menuParams.emplace_back(menuOptionsParam);
9632 }
9633 return menuParams;
9634 }
9635
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)9636 void JSViewAbstract::ParseOnCreateMenu(
9637 const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
9638 {
9639 if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
9640 return;
9641 }
9642 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9643 auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
9644 JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
9645 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
9646 instanceId = Container::CurrentId(), node = frameNode](
9647 const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
9648 ContainerScope scope(instanceId);
9649 std::vector<NG::MenuOptionsParam> menuParams;
9650 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
9651 auto pipelineContext = PipelineContext::GetCurrentContext();
9652 CHECK_NULL_RETURN(pipelineContext, menuParams);
9653 pipelineContext->UpdateCurrentActiveNode(node);
9654 auto modifiedSystemMenuItems = systemMenuItems;
9655 UpdateOptionsLabelInfo(modifiedSystemMenuItems);
9656 auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
9657 if (!menuItem->IsArray()) {
9658 return menuParams;
9659 }
9660 auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
9661 menuParams = ParseMenuItems(menuItemsArray);
9662 return menuParams;
9663 };
9664 onCreateMenuCallback = jsCallback;
9665 }
9666
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)9667 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
9668 {
9669 JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
9670 uint32_t idx = 0;
9671 for (const auto& item : systemMenuItems) {
9672 systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
9673 }
9674 return systemMenuItemsArray;
9675 }
9676
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)9677 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
9678 NG::OnMenuItemClickCallback& onMenuItemClick)
9679 {
9680 auto tmpInfo = info[0];
9681 if (info.Length() != 1 || !tmpInfo->IsObject()) {
9682 return false;
9683 }
9684 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9685 auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
9686 auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
9687 ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
9688
9689 auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
9690 if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
9691 return false;
9692 }
9693 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
9694 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
9695 onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
9696 node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
9697 ContainerScope scope(instanceId);
9698 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
9699 auto pipelineContext = PipelineContext::GetCurrentContext();
9700 CHECK_NULL_RETURN(pipelineContext, false);
9701 pipelineContext->UpdateCurrentActiveNode(node);
9702 auto paramArray = onMenuItemCallback(menuOptionsParam);
9703 if (paramArray->Length() != 2) {
9704 return false;
9705 }
9706 JSRef<JSVal> params[2];
9707 params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
9708 params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
9709 auto ret = func->ExecuteJS(2, params);
9710 if (ret->IsBoolean()) {
9711 return ret->ToBoolean();
9712 }
9713 return false;
9714 };
9715 onMenuItemClick = jsCallback;
9716 return true;
9717 }
9718
CreateJsTextMenuId(const std::string & id)9719 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
9720 {
9721 JSRef<JSObject> empty;
9722 auto engine = EngineHelper::GetCurrentEngine();
9723 CHECK_NULL_RETURN(engine, empty);
9724 NativeEngine* nativeEngine = engine->GetNativeEngine();
9725 CHECK_NULL_RETURN(nativeEngine, empty);
9726 auto env = reinterpret_cast<napi_env>(nativeEngine);
9727
9728 napi_value global;
9729 napi_status ret = napi_get_global(env, &global);
9730 if (ret != napi_ok) {
9731 return empty;
9732 }
9733 napi_value constructor;
9734 ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
9735 if (ret != napi_ok) {
9736 return empty;
9737 }
9738
9739 napi_value obj;
9740 napi_value menuId = nullptr;
9741
9742 ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
9743 if (ret != napi_ok) {
9744 return empty;
9745 }
9746 ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
9747 if (ret != napi_ok) {
9748 return empty;
9749 }
9750
9751 JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
9752 if (!value->IsObject()) {
9753 return empty;
9754 }
9755
9756 return JSRef<JSObject>::Cast(value);
9757 }
9758
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)9759 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
9760 {
9761 JSRef<JSArray> params = JSRef<JSArray>::New();
9762 params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
9763 params->SetValueAt(1, CreateJsTextRange(menuItemParam));
9764 return params;
9765 }
9766
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)9767 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
9768 {
9769 JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
9770 TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
9771 JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
9772 TextMenuItem->SetPropertyObject("id", obj);
9773 TextMenuItem->SetProperty<std::string>("labelInfo", menuItemParam.menuOptionsParam.labelInfo.value_or(""));
9774 return JSRef<JSVal>::Cast(TextMenuItem);
9775 }
9776
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)9777 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
9778 {
9779 JSRef<JSObject> textRange = JSRef<JSObject>::New();
9780 textRange->SetProperty<int32_t>("start", menuItemParam.start);
9781 textRange->SetProperty<int32_t>("end", menuItemParam.end);
9782 return JSRef<JSVal>::Cast(textRange);
9783 }
9784
OHOS_ACE_ParseJsMedia(void * value,void * resource)9785 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
9786 {
9787 napi_value napiValue = reinterpret_cast<napi_value>(value);
9788 ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
9789 if (!napiValue || !res) {
9790 return;
9791 }
9792 JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
9793 std::string src;
9794 std::string bundleName;
9795 std::string moduleName;
9796 JSViewAbstract::ParseJsMedia(jsVal, src);
9797 JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
9798 res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
9799 res->src = src;
9800 res->bundleName = bundleName;
9801 res->moduleName = moduleName;
9802 }
9803
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)9804 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
9805 std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
9806 {
9807 if (!modifierObj->IsObject()) {
9808 textStyleApply = nullptr;
9809 return;
9810 }
9811 auto vm = info.GetVm();
9812 auto globalObj = JSNApi::GetGlobalObject(vm);
9813 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
9814 JsiValue jsiValue(globalFunc);
9815 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
9816 if (!globalFuncRef->IsFunction()) {
9817 textStyleApply = nullptr;
9818 return;
9819 }
9820 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
9821 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
9822 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
9823 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9824 auto node = frameNode.Upgrade();
9825 CHECK_NULL_VOID(node);
9826 JSRef<JSVal> params[2];
9827 params[0] = modifierParam;
9828 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
9829 PipelineContext::SetCallBackNode(node);
9830 func->ExecuteJS(2, params);
9831 };
9832 textStyleApply = onApply;
9833 }
9834
SetPixelRoundMode(const JSCallbackInfo & info)9835 void JSViewAbstract::SetPixelRoundMode(const JSCallbackInfo& info)
9836 {
9837 if (info.Length() < 1) {
9838 return;
9839 }
9840 if (!info[0]->IsNumber()) {
9841 return;
9842 }
9843 auto index = info[0]->ToNumber<uint8_t>();
9844 auto size = sizeof(PixelRoundMode) / sizeof(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
9845 if (index < 0 || index > size) {
9846 return;
9847 }
9848 PixelRoundMode pixelRoundMode = static_cast<PixelRoundMode>(index);
9849 auto pipeline = PipelineBase::GetCurrentContext();
9850 CHECK_NULL_VOID(pipeline);
9851 pipeline->SetPixelRoundMode(pixelRoundMode);
9852 }
9853
GetPixelRoundMode()9854 uint8_t JSViewAbstract::GetPixelRoundMode()
9855 {
9856 auto pipeline = PipelineBase::GetCurrentContext();
9857 return pipeline ? static_cast<uint8_t>(pipeline->GetPixelRoundMode())
9858 : static_cast<uint8_t>(PixelRoundMode::PIXEL_ROUND_ON_LAYOUT_FINISH);
9859 }
9860 } // namespace OHOS::Ace::Framework
9861