1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
17
18 #include <algorithm>
19 #include <cstdint>
20 #include <functional>
21 #include <memory>
22 #include <optional>
23 #include <regex>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 #include <unordered_map>
28
29 #include "base/geometry/calc_dimension.h"
30 #include "base/geometry/dimension.h"
31 #include "base/geometry/matrix4.h"
32 #include "base/geometry/ng/offset_t.h"
33 #include "base/geometry/ng/vector.h"
34 #include "base/geometry/shape.h"
35 #include "base/json/json_util.h"
36 #include "base/log/ace_scoring_log.h"
37 #include "base/log/log.h"
38 #include "base/memory/ace_type.h"
39 #include "base/memory/referenced.h"
40 #include "base/utils/utils.h"
41 #include "bridge/common/utils/engine_helper.h"
42 #include "bridge/common/utils/utils.h"
43 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
44 #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h"
45 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_on_child_touch_test_function.h"
47 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
48 #include "bridge/declarative_frontend/engine/functions/js_function.h"
49 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
50 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
51 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
52 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
53 #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h"
54 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
55 #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h"
56 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
57 #include "bridge/js_frontend/engine/jsi/ark_js_value.h"
58 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
59 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
60 #include "bridge/declarative_frontend/engine/js_converter.h"
61 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
62 #include "bridge/declarative_frontend/engine/js_types.h"
63 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
64 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
65 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
66 #include "bridge/declarative_frontend/jsview/js_utils.h"
67 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
68 #include "bridge/declarative_frontend/jsview/js_view_context.h"
69 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
70 #include "canvas_napi/js_canvas.h"
71 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
72 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
73 #endif
74 #include "core/common/resource/resource_manager.h"
75 #include "core/common/resource/resource_object.h"
76 #include "core/components/common/layout/constants.h"
77 #include "core/components/common/layout/position_param.h"
78 #include "core/components/common/layout/screen_system_manager.h"
79 #include "core/components/common/properties/animation_option.h"
80 #include "core/components/common/properties/border_image.h"
81 #include "core/components/common/properties/color.h"
82 #include "core/components/common/properties/decoration.h"
83 #include "core/components/common/properties/shadow.h"
84 #include "core/components/common/properties/invert.h"
85 #include "core/components/common/properties/shadow_config.h"
86 #include "core/components/theme/resource_adapter.h"
87 #include "core/components/theme/shadow_theme.h"
88 #include "core/components_ng/base/view_abstract.h"
89 #include "core/components_ng/base/view_abstract_model.h"
90 #include "core/components_ng/base/view_stack_processor.h"
91 #include "core/components_ng/event/focus_box.h"
92 #include "core/components_ng/gestures/base_gesture_event.h"
93 #include "core/components_ng/pattern/menu/menu_pattern.h"
94 #include "core/components_ng/pattern/overlay/modal_style.h"
95 #include "core/components_ng/pattern/overlay/sheet_style.h"
96 #include "core/components_ng/property/grid_property.h"
97 #include "core/components_ng/property/safe_area_insets.h"
98 #include "core/gestures/gesture_info.h"
99 #include "core/image/image_source_info.h"
100 #ifdef PLUGIN_COMPONENT_SUPPORTED
101 #include "core/common/plugin_manager.h"
102 #endif
103 #include "interfaces/native/node/resource.h"
104
105 #include "core/common/card_scope.h"
106 #include "core/common/container.h"
107 #include "core/common/resource/resource_configuration.h"
108 #include "core/components/progress/progress_theme.h"
109 #include "core/components_ng/base/view_abstract_model_ng.h"
110 #include "core/components_ng/base/view_stack_model.h"
111 #include "core/components_ng/property/progress_mask_property.h"
112
113 namespace OHOS::Ace {
114 namespace {
115 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
116 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
117 constexpr int32_t DIRECTION_COUNT = 4;
118 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
119 constexpr int NUM1 = 1;
120 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
121 HoverModeAreaType::BOTTOM_SCREEN };
122 } // namespace
123
124 std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr;
125 std::mutex ViewAbstractModel::mutex_;
126 using DoubleBindCallback = std::function<void(const std::string&)>;
127
GetInstance()128 ViewAbstractModel* ViewAbstractModel::GetInstance()
129 {
130 if (!instance_) {
131 std::lock_guard<std::mutex> lock(mutex_);
132 if (!instance_) {
133 #ifdef NG_BUILD
134 instance_.reset(new NG::ViewAbstractModelNG());
135 #else
136 if (Container::IsCurrentUseNewPipeline()) {
137 instance_.reset(new NG::ViewAbstractModelNG());
138 } else {
139 instance_.reset(new Framework::ViewAbstractModelImpl());
140 }
141 #endif
142 }
143 }
144 return instance_.get();
145 }
146
147 } // namespace OHOS::Ace
148
149 namespace OHOS::Ace::Framework {
150 namespace {
151
152 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
153 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
154 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
155 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
156 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
157 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
158 constexpr int32_t MAX_ALIGN_VALUE = 8;
159 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
160 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
161 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
162 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
163 constexpr double FULL_DIMENSION = 100.0;
164 constexpr double HALF_DIMENSION = 50.0;
165 constexpr double ROUND_UNIT = 360.0;
166 constexpr double VISIBLE_RATIO_MIN = 0.0;
167 constexpr double VISIBLE_RATIO_MAX = 1.0;
168 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
169 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
170 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
171 constexpr int32_t SECOND_INDEX = 2;
172 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
173 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
174 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
175 constexpr float MAX_ANGLE = 360.0f;
176 constexpr float DEFAULT_BIAS = 0.5f;
177 constexpr float DEFAULT_LAYOUT_WEIGHT = 0.0f;
178 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
179 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
180 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
181 const std::string SHEET_HEIGHT_MEDIUM = "medium";
182 const std::string SHEET_HEIGHT_LARGE = "large";
183 const std::string SHEET_HEIGHT_AUTO = "auto";
184 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
185 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
186 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
187 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
188 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
189 const std::vector<int32_t> LENGTH_METRICS_KEYS {
190 static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
191 static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
192 const char* START_PROPERTY = "start";
193 const char* END_PROPERTY = "end";
194 const char* TOP_PROPERTY = "top";
195 const char* BOTTOM_PROPERTY = "bottom";
196 const char* LEFT_PROPERTY = "left";
197 const char* RIGHT_PROPERTY = "right";
198 const char* TOP_START_PROPERTY = "topStart";
199 const char* TOP_END_PROPERTY = "topEnd";
200 const char* BOTTOM_START_PROPERTY = "bottomStart";
201 const char* BOTTOM_END_PROPERTY = "bottomEnd";
202 const char* DEBUG_LINE_INFO_LINE = "$line";
203 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
204
205 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
206 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
207 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
208
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)209 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
210 CalcDimension& centerX, CalcDimension& centerY)
211 {
212 double xVal = 1.0;
213 double yVal = 1.0;
214 double zVal = 1.0;
215 if (!jsValue->IsObject()) {
216 scaleX = static_cast<float>(xVal);
217 scaleY = static_cast<float>(yVal);
218 scaleZ = static_cast<float>(zVal);
219 CalcDimension length;
220 centerX = length;
221 centerY = length;
222 return;
223 }
224 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
225 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
226 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
227 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
228 scaleX = static_cast<float>(xVal);
229 scaleY = static_cast<float>(yVal);
230 scaleZ = static_cast<float>(zVal);
231 // if specify centerX
232 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
233 // if specify centerY
234 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
235 }
236
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)237 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
238 CalcDimension& translateZ)
239 {
240 if (!jsValue->IsObject()) {
241 return;
242 }
243 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
244 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
245 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
246 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
247 }
248
GetDefaultRotateVector(double & dx,double & dy,double & dz)249 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
250 {
251 dx = 0.0;
252 dy = 0.0;
253 dz = 0.0;
254 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
255 dz = 1.0;
256 }
257 }
258
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)259 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
260 {
261 if (!jsValue->IsObject()) {
262 return;
263 }
264 // default: dx, dy, dz (0.0, 0.0, 0.0)
265 double dxVal = 0.0;
266 double dyVal = 0.0;
267 double dzVal = 0.0;
268 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
269 auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
270 auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
271 auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
272 if (jsRotateX->IsUndefined()
273 && jsRotateY->IsUndefined()
274 && jsRotateZ->IsUndefined()) {
275 GetDefaultRotateVector(dxVal, dyVal, dzVal);
276 } else {
277 JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
278 JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
279 JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
280 }
281 rotate.xDirection = static_cast<float>(dxVal);
282 rotate.yDirection = static_cast<float>(dyVal);
283 rotate.zDirection = static_cast<float>(dzVal);
284 // if specify centerX
285 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
286 rotate.centerX)) {
287 rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
288 }
289 // if specify centerY
290 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
291 rotate.centerY)) {
292 rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
293 }
294 // if specify centerZ
295 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
296 rotate.centerZ)) {
297 rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
298 }
299 // if specify angle
300 JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
301 rotate.perspective = 0.0f;
302 JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
303 }
304
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)305 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
306 {
307 if (!jsValue->IsObject()) {
308 return false;
309 }
310
311 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
312 auto path = jsObj->GetPropertyValue<std::string>("path", "");
313 if (path.empty()) {
314 return false;
315 }
316 option.SetPath(path);
317 double from = 0.0;
318 double to = 1.0;
319 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
320 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
321 if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
322 from = 0.0;
323 }
324 if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
325 to = 1.0;
326 } else if (to < from) {
327 to = from;
328 }
329 option.SetBegin(static_cast<float>(from));
330 option.SetEnd(static_cast<float>(to));
331 option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
332 return true;
333 }
334
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)335 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
336 {
337 if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::AUTO)) {
338 previewOption.ResetDragPreviewMode();
339 isAuto = true;
340 return;
341 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE)) {
342 previewOption.isScaleEnabled = false;
343 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW)) {
344 previewOption.isDefaultShadowEnabled = true;
345 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS)) {
346 previewOption.isDefaultRadiusEnabled = true;
347 }
348 isAuto = false;
349 }
350
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)351 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
352 BackgroundImagePosition& bgImgPosition)
353 {
354 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
355 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
356 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
357 }
358
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)359 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
360 {
361 auto index = pos + containCount;
362 if (index < 0) {
363 return std::string();
364 }
365
366 JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
367 if (type == "d") {
368 if (item->IsNumber()) {
369 return std::to_string(item->ToNumber<int32_t>());
370 } else if (item->IsObject()) {
371 int32_t result = 0;
372 JSViewAbstract::ParseJsInteger(item, result);
373 return std::to_string(result);
374 }
375 } else if (type == "s") {
376 if (item->IsString()) {
377 return item->ToString();
378 } else if (item->IsObject()) {
379 std::string result;
380 JSViewAbstract::ParseJsString(item, result);
381 return result;
382 }
383 } else if (type == "f") {
384 if (item->IsNumber()) {
385 return std::to_string(item->ToNumber<float>());
386 } else if (item->IsObject()) {
387 double result = 0.0;
388 JSViewAbstract::ParseJsDouble(item, result);
389 return std::to_string(result);
390 }
391 }
392 return std::string();
393 }
394
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)395 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
396 {
397 auto size = static_cast<int32_t>(params->Length());
398 if (containCount == size) {
399 return;
400 }
401 std::string::const_iterator start = originStr.begin();
402 std::string::const_iterator end = originStr.end();
403 std::smatch matches;
404 bool shortHolderType = false;
405 bool firstMatch = true;
406 int searchTime = 0;
407 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
408 std::string pos = matches[2];
409 std::string type = matches[4];
410 if (firstMatch) {
411 firstMatch = false;
412 shortHolderType = pos.length() == 0;
413 } else {
414 if (shortHolderType ^ (pos.length() == 0)) {
415 return;
416 }
417 }
418
419 std::string replaceContentStr;
420 if (shortHolderType) {
421 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
422 } else {
423 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
424 }
425
426 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
427 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
428 end = originStr.end();
429 searchTime++;
430 }
431 }
432
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)433 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y)
434 {
435 JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
436 JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
437 bool hasX = false;
438 bool hasY = false;
439 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
440 hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP);
441 hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP);
442 } else {
443 hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
444 hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
445 }
446 return hasX || hasY;
447 }
448
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)449 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
450 {
451 bool useEdges = false;
452 CalcDimension top;
453 CalcDimension left;
454 CalcDimension bottom;
455 CalcDimension right;
456 JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
457 JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
458 JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
459 JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
460 if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) {
461 edges.SetTop(top);
462 useEdges = true;
463 }
464 if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) {
465 edges.SetLeft(left);
466 useEdges = true;
467 }
468 if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) {
469 edges.SetBottom(bottom);
470 useEdges = true;
471 }
472 if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) {
473 edges.SetRight(right);
474 useEdges = true;
475 }
476 return useEdges;
477 }
478
ParseJsLengthMetrics(const JSRef<JSObject> & obj,CalcDimension & result)479 bool ParseJsLengthMetrics(const JSRef<JSObject>& obj, CalcDimension& result)
480 {
481 auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
482 if (!value->IsNumber()) {
483 return false;
484 }
485 auto unit = DimensionUnit::VP;
486 auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
487 if (jsUnit->IsNumber()) {
488 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
489 }
490 CalcDimension dimension(value->ToNumber<double>(), unit);
491 result = dimension;
492 return true;
493 }
494
CheckLengthMetrics(const JSRef<JSObject> & object)495 bool CheckLengthMetrics(const JSRef<JSObject>& object)
496 {
497 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
498 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
499 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
500 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
501 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
502 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
503 return true;
504 }
505 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
506 if (jsTop->IsObject()) {
507 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
508 if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
509 return true;
510 }
511 }
512 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
513 if (jsBottom->IsObject()) {
514 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
515 if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
516 return true;
517 }
518 }
519 return false;
520 }
521
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)522 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
523 {
524 bool useLocalizedEdges = false;
525 CalcDimension start;
526 CalcDimension end;
527 CalcDimension top;
528 CalcDimension bottom;
529
530 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
531 if (startVal->IsObject()) {
532 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
533 ParseJsLengthMetrics(startObj, start);
534 edges.SetLeft(start);
535 useLocalizedEdges = true;
536 }
537 JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
538 if (endVal->IsObject()) {
539 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
540 ParseJsLengthMetrics(endObj, end);
541 edges.SetRight(end);
542 useLocalizedEdges = true;
543 }
544 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
545 if (topVal->IsObject()) {
546 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
547 ParseJsLengthMetrics(topObj, top);
548 edges.SetTop(top);
549 useLocalizedEdges = true;
550 }
551 JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
552 if (bottomVal->IsObject()) {
553 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(bottomVal);
554 ParseJsLengthMetrics(bottomObj, bottom);
555 edges.SetBottom(bottom);
556 useLocalizedEdges = true;
557 }
558 return useLocalizedEdges;
559 }
560
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)561 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
562 {
563 bool useMarkAnchorPosition = false;
564 CalcDimension start;
565 CalcDimension top;
566
567 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
568 if (startVal->IsObject()) {
569 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
570 ParseJsLengthMetrics(startObj, start);
571 x = start;
572 useMarkAnchorPosition = true;
573 }
574 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
575 if (topVal->IsObject()) {
576 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
577 ParseJsLengthMetrics(topObj, top);
578 y = top;
579 useMarkAnchorPosition = true;
580 }
581 return useMarkAnchorPosition;
582 }
583
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)584 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
585 {
586 JSRef<JSVal> builder;
587 if (info->IsObject()) {
588 auto builderObj = JSRef<JSObject>::Cast(info);
589 builder = builderObj->GetProperty("builder");
590 } else if (info->IsFunction()) {
591 builder = info;
592 } else {
593 return nullptr;
594 }
595
596 if (!builder->IsFunction()) {
597 return nullptr;
598 }
599
600 return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
601 }
602
603 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
604 const JSRef<JSObject>& object, const JSExecutionContext& context);
605
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)606 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
607 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
608 {
609 RefPtr<NG::ChainedTransitionEffect> effect;
610 if (effectOption->IsObject()) {
611 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
612 std::optional<float> angle;
613 ParseJsRotate(effectOption, rotate, angle);
614 if (angle.has_value()) {
615 rotate.angle = angle.value();
616 return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
617 }
618 }
619 return nullptr;
620 }
621
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)622 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
623 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
624 {
625 double opacity = 1.0;
626 if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
627 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
628 if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
629 opacity = 1.0;
630 }
631 } else {
632 opacity = std::clamp(opacity, 0.0, 1.0);
633 }
634 return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
635 }
636 return nullptr;
637 }
638
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)639 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
640 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
641 {
642 if (effectOption->IsObject()) {
643 // default: x, y, z (0.0, 0.0, 0.0)
644 NG::TranslateOptions translate;
645 ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
646 return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
647 }
648 return nullptr;
649 }
650
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)651 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
652 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
653 {
654 if (effectOption->IsObject()) {
655 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
656 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
657 ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
658 return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
659 }
660 return nullptr;
661 }
662
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)663 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
664 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
665 {
666 int32_t edge = 0;
667 if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
668 if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
669 edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
670 edge = static_cast<int32_t>(NG::TransitionEdge::START);
671 }
672 return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
673 }
674 return nullptr;
675 }
676
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)677 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
678 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
679 {
680 if (effectOption->IsObject()) {
681 auto effectObj = JSRef<JSObject>::Cast(effectOption);
682 auto appearJsVal = effectObj->GetProperty("appear");
683 auto disappearJsVal = effectObj->GetProperty("disappear");
684 RefPtr<NG::ChainedTransitionEffect> appearEffect;
685 RefPtr<NG::ChainedTransitionEffect> disappearEffect;
686 if (appearJsVal->IsObject()) {
687 auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
688 appearEffect = ParseChainedTransition(appearObj, context);
689 }
690 if (disappearJsVal->IsObject()) {
691 auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
692 disappearEffect = ParseChainedTransition(disappearObj, context);
693 }
694 return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
695 }
696 return nullptr;
697 }
698
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)699 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
700 {
701 CHECK_NULL_RETURN(pipelineContext, 0);
702 return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
703 }
704
705 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
706 const JSRef<JSVal>&, const JSExecutionContext&);
707
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)708 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
709 const JSRef<JSObject>& object, const JSExecutionContext& context)
710 {
711 auto propType = object->GetProperty("type_");
712 if (!propType->IsString()) {
713 return nullptr;
714 }
715 std::string type = propType->ToString();
716 auto propEffectOption = object->GetProperty("effect_");
717 auto propAnimationOption = object->GetProperty("animation_");
718 auto propSuccessor = object->GetProperty("successor_");
719 static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
720 { "asymmetric", ParseChainedAsymmetricTransition },
721 { "identity",
722 [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
723 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
724 { "move", ParseChainedMoveTransition },
725 { "opacity", ParseChainedOpacityTransition },
726 { "rotate", ParseChainedRotateTransition },
727 { "scale", ParseChainedScaleTransition },
728 { "slideSwitch",
729 [](const JSRef<JSVal>& effectOption,
730 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
731 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
732 } },
733 { "translate", ParseChainedTranslateTransition },
734 };
735 int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
736 if (index < 0) {
737 return nullptr;
738 }
739 RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
740 if (!result) {
741 return nullptr;
742 }
743 if (propAnimationOption->IsObject()) {
744 auto container = Container::Current();
745 CHECK_NULL_RETURN(container, nullptr);
746 auto pipelineContext = container->GetPipelineContext();
747 CHECK_NULL_RETURN(pipelineContext, nullptr);
748 auto animationOptionResult = std::make_shared<AnimationOption>(
749 JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRender()));
750 // The maximum of the form-animation-playback duration value is 1000 ms.
751 if (pipelineContext->IsFormRender() && pipelineContext->IsFormAnimation()) {
752 auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
753 // If the duration exceeds 1000ms, init it to 0 ms.
754 if (formAnimationTimeInterval > DEFAULT_DURATION) {
755 animationOptionResult->SetDuration(0);
756 } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
757 // If remaining time is less than 1000ms, check for update duration.
758 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
759 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form Transition SetDuration: %{public}lld ms",
760 static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
761 }
762 }
763 auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
764 JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
765 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
766 if (onFinish->IsFunction()) {
767 RefPtr<JsFunction> jsFunc =
768 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
769 std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
770 id = Container::CurrentId(), node = targetNode]() {
771 ContainerScope scope(id);
772 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
773 PipelineContext::SetCallBackNode(node);
774 func->Execute();
775 };
776 animationOptionResult->SetOnFinishEvent(onFinishEvent);
777 }
778 result->SetAnimationOption(animationOptionResult);
779 }
780 if (propSuccessor->IsObject()) {
781 result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
782 }
783 return result;
784 }
785
786 #ifndef WEARABLE_PRODUCT
787 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
788 Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP,
789 Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM };
790
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)791 DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj)
792 {
793 JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent");
794 if (!changeEvent->IsFunction()) {
795 return {};
796 }
797 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent));
798 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
799 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
800 const std::string& param) {
801 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
802 if (param != "true" && param != "false") {
803 return;
804 }
805 PipelineContext::SetCallBackNode(node);
806 bool newValue = StringToBool(param);
807 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
808 func->ExecuteJS(1, &newJSVal);
809 };
810 return callback;
811 }
812
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)813 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
814 {
815 auto colorValue = messageOptionsObj->GetProperty("textColor");
816 Color textColor;
817 if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
818 if (popupParam) {
819 popupParam->SetTextColor(textColor);
820 }
821 }
822
823 auto font = messageOptionsObj->GetProperty("font");
824 if (!font->IsNull() && font->IsObject()) {
825 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
826 auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
827 CalcDimension fontSize;
828 if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
829 if (popupParam && fontSize.IsValid()) {
830 popupParam->SetFontSize(fontSize);
831 }
832 }
833 auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
834 if (fontWeightValue->IsString()) {
835 if (popupParam) {
836 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
837 }
838 }
839 auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
840 if (fontStyleValue->IsNumber()) {
841 int32_t value = fontStyleValue->ToNumber<int32_t>();
842 if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
843 return;
844 }
845 if (popupParam) {
846 popupParam->SetFontStyle(FONT_STYLES[value]);
847 }
848 }
849 }
850 }
851
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)852 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
853 {
854 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
855 if (placementOnTopVal->IsBoolean() && popupParam) {
856 popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
857 }
858 }
859
IsPopupCreated()860 bool IsPopupCreated()
861 {
862 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
863 CHECK_NULL_RETURN(targetNode, false);
864 auto targetId = targetNode->GetId();
865 auto container = Container::Current();
866 CHECK_NULL_RETURN(container, false);
867 auto pipelineContext = container->GetPipelineContext();
868 CHECK_NULL_RETURN(pipelineContext, false);
869 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
870 CHECK_NULL_RETURN(context, false);
871 auto overlayManager = context->GetOverlayManager();
872 CHECK_NULL_RETURN(overlayManager, false);
873 auto popupInfo = overlayManager->GetPopupInfo(targetId);
874 if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
875 return false;
876 }
877 return true;
878 }
879
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)880 void ParsePopupCommonParam(
881 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
882 {
883 auto arrowOffset = popupObj->GetProperty("arrowOffset");
884 CalcDimension offset;
885 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
886 if (popupParam) {
887 popupParam->SetArrowOffset(offset);
888 }
889 }
890
891 auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
892 if (arrowPointPosition->IsString()) {
893 char* pEnd = nullptr;
894 auto arrowString = arrowPointPosition->ToString();
895 std::strtod(arrowString.c_str(), &pEnd);
896 if (pEnd != nullptr) {
897 if (std::strcmp(pEnd, "Start") == 0) {
898 offset = ARROW_ZERO_PERCENT_VALUE;
899 }
900 if (std::strcmp(pEnd, "Center") == 0) {
901 offset = ARROW_HALF_PERCENT_VALUE;
902 }
903 if (std::strcmp(pEnd, "End") == 0) {
904 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
905 }
906 if (popupParam) {
907 popupParam->SetArrowOffset(offset);
908 }
909 }
910 }
911
912 auto targetSpace = popupObj->GetProperty("targetSpace");
913 if (!targetSpace->IsNull()) {
914 CalcDimension space;
915 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
916 if (popupParam) {
917 popupParam->SetTargetSpace(space);
918 }
919 }
920 }
921
922 JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
923 if (showInSubWindowValue->IsBoolean()) {
924 bool showInSubBoolean = showInSubWindowValue->ToBoolean();
925 #if defined(PREVIEW)
926 if (showInSubBoolean) {
927 LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
928 showInSubBoolean = false;
929 }
930 #endif
931 if (popupParam) {
932 popupParam->SetShowInSubWindow(showInSubBoolean);
933 }
934 }
935
936 auto placementValue = popupObj->GetProperty("placement");
937 if (placementValue->IsNumber()) {
938 auto placement = placementValue->ToNumber<int32_t>();
939 if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
940 popupParam->SetPlacement(PLACEMENT[placement]);
941 }
942 } else {
943 SetPlacementOnTopVal(popupObj, popupParam);
944 }
945
946 auto enableArrowValue = popupObj->GetProperty("enableArrow");
947 if (enableArrowValue->IsBoolean()) {
948 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
949 }
950
951 auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
952 if (followTransformOfTargetValue->IsBoolean()) {
953 popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
954 }
955
956 JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
957 if (maskValue->IsBoolean()) {
958 if (popupParam) {
959 popupParam->SetBlockEvent(maskValue->ToBoolean());
960 }
961 }
962 if (maskValue->IsObject()) {
963 auto maskObj = JSRef<JSObject>::Cast(maskValue);
964 auto colorValue = maskObj->GetProperty("color");
965 Color maskColor;
966 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
967 popupParam->SetMaskColor(maskColor);
968 }
969 }
970
971 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
972 if (onStateChangeVal->IsFunction()) {
973 std::vector<std::string> keys = { "isVisible" };
974 RefPtr<JsFunction> jsFunc =
975 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
976 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
977 if (popupParam) {
978 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
979 node = targetNode](const std::string& param) {
980 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
981 ACE_SCORING_EVENT("Popup.onStateChange");
982 PipelineContext::SetCallBackNode(node);
983 func->Execute(keys, param);
984 };
985 popupParam->SetOnStateChange(onStateChangeCallback);
986 }
987 }
988
989 auto offsetVal = popupObj->GetProperty("offset");
990 if (offsetVal->IsObject()) {
991 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
992 auto xVal = offsetObj->GetProperty("x");
993 auto yVal = offsetObj->GetProperty("y");
994 Offset popupOffset;
995 CalcDimension dx;
996 CalcDimension dy;
997 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
998 popupOffset.SetX(dx.ConvertToPx());
999 }
1000 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
1001 popupOffset.SetY(dy.ConvertToPx());
1002 }
1003 if (popupParam) {
1004 popupParam->SetTargetOffset(popupOffset);
1005 }
1006 }
1007
1008 Color backgroundColor;
1009 auto popupColorVal = popupObj->GetProperty("popupColor");
1010 if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
1011 popupParam->SetBackgroundColor(backgroundColor);
1012 }
1013
1014 auto autoCancelVal = popupObj->GetProperty("autoCancel");
1015 if (autoCancelVal->IsBoolean()) {
1016 popupParam->SetHasAction(!autoCancelVal->ToBoolean());
1017 }
1018
1019 auto childWidthVal = popupObj->GetProperty("width");
1020 if (!childWidthVal->IsNull()) {
1021 CalcDimension width;
1022 if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
1023 if (width.Value() > 0) {
1024 popupParam->SetChildWidth(width);
1025 }
1026 }
1027 }
1028
1029 auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
1030 if (!arrowWidthVal->IsNull()) {
1031 bool setError = true;
1032 CalcDimension arrowWidth;
1033 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
1034 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
1035 popupParam->SetArrowWidth(arrowWidth);
1036 setError = false;
1037 }
1038 }
1039 popupParam->SetErrorArrowWidth(setError);
1040 }
1041
1042 auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
1043 if (!arrowHeightVal->IsNull()) {
1044 bool setError = true;
1045 CalcDimension arrowHeight;
1046 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
1047 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
1048 popupParam->SetArrowHeight(arrowHeight);
1049 setError = false;
1050 }
1051 }
1052 popupParam->SetErrorArrowHeight(setError);
1053 }
1054
1055 auto radiusVal = popupObj->GetProperty("radius");
1056 if (!radiusVal->IsNull()) {
1057 bool setError = true;
1058 CalcDimension radius;
1059 if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
1060 if (radius.Value() >= 0) {
1061 popupParam->SetRadius(radius);
1062 setError = false;
1063 }
1064 }
1065 popupParam->SetErrorRadius(setError);
1066 }
1067
1068 Shadow shadow;
1069 auto shadowVal = popupObj->GetProperty("shadow");
1070 if (shadowVal->IsObject() || shadowVal->IsNumber()) {
1071 auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
1072 if (!ret) {
1073 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1074 }
1075 } else {
1076 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1077 }
1078 popupParam->SetShadow(shadow);
1079
1080 auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
1081 if (blurStyleValue->IsNumber()) {
1082 auto blurStyle = blurStyleValue->ToNumber<int32_t>();
1083 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1084 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1085 popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
1086 }
1087 }
1088
1089 auto popupTransition = popupObj->GetProperty("transition");
1090 if (popupTransition->IsObject()) {
1091 popupParam->SetHasTransition(true);
1092 auto obj = JSRef<JSObject>::Cast(popupTransition);
1093 auto effects = ParseChainedTransition(obj, info.GetExecutionContext());
1094 popupParam->SetTransitionEffects(effects);
1095 }
1096 }
1097
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1098 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1099 {
1100 ParsePopupCommonParam(info, popupObj, popupParam);
1101 JSRef<JSVal> messageVal = popupObj->GetProperty("message");
1102 if (popupParam) {
1103 popupParam->SetMessage(messageVal->ToString());
1104 }
1105
1106 auto messageOptions = popupObj->GetProperty("messageOptions");
1107 JSRef<JSObject> messageOptionsObj;
1108 if (!messageOptions->IsNull() && messageOptions->IsObject()) {
1109 messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
1110 SetPopupMessageOptions(messageOptionsObj, popupParam);
1111 }
1112
1113 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
1114 if (primaryButtonVal->IsObject()) {
1115 ButtonProperties properties;
1116 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
1117 JSRef<JSVal> value = obj->GetProperty("value");
1118 if (value->IsString()) {
1119 properties.value = value->ToString();
1120 }
1121
1122 JSRef<JSVal> actionValue = obj->GetProperty("action");
1123 if (actionValue->IsFunction()) {
1124 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1125 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1126 if (popupParam) {
1127 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1128 node = targetNode](GestureEvent& info) {
1129 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1130 ACE_SCORING_EVENT("primaryButton.action");
1131 PipelineContext::SetCallBackNode(node);
1132 func->Execute(info);
1133 };
1134 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1135 }
1136 }
1137 properties.showButton = true;
1138 if (popupParam) {
1139 popupParam->SetPrimaryButtonProperties(properties);
1140 }
1141 }
1142
1143 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
1144 if (secondaryButtonVal->IsObject()) {
1145 ButtonProperties properties;
1146 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
1147 JSRef<JSVal> value = obj->GetProperty("value");
1148 if (value->IsString()) {
1149 properties.value = value->ToString();
1150 }
1151
1152 JSRef<JSVal> actionValue = obj->GetProperty("action");
1153 if (actionValue->IsFunction()) {
1154 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1155 auto targetNode =
1156 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1157 if (popupParam) {
1158 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1159 node = targetNode](GestureEvent& info) {
1160 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1161 ACE_SCORING_EVENT("secondaryButton.action");
1162 PipelineContext::SetCallBackNode(node);
1163 func->Execute(info);
1164 };
1165 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1166 }
1167 }
1168 properties.showButton = true;
1169 if (popupParam) {
1170 popupParam->SetSecondaryButtonProperties(properties);
1171 }
1172 }
1173 }
1174
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1175 void ParseCustomPopupParam(
1176 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1177 {
1178 auto builderValue = popupObj->GetProperty("builder");
1179 if (!builderValue->IsObject()) {
1180 return;
1181 }
1182 if (!builderValue->IsFunction()) {
1183 JSRef<JSObject> builderObj;
1184 builderObj = JSRef<JSObject>::Cast(builderValue);
1185 auto builder = builderObj->GetProperty("builder");
1186 if (!builder->IsFunction()) {
1187 return;
1188 }
1189 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1190 if (!builderFunc) {
1191 return;
1192 }
1193 }
1194 if (popupParam) {
1195 popupParam->SetUseCustomComponent(true);
1196 }
1197
1198 auto focusableValue = popupObj->GetProperty("focusable");
1199 if (focusableValue->IsBoolean()) {
1200 popupParam->SetFocusable(focusableValue->ToBoolean());
1201 }
1202
1203 ParsePopupCommonParam(info, popupObj, popupParam);
1204 }
1205 #endif
1206
GetBundleNameFromContainer()1207 std::string GetBundleNameFromContainer()
1208 {
1209 auto container = Container::Current();
1210 CHECK_NULL_RETURN(container, "");
1211 return container->GetBundleName();
1212 }
1213
GetModuleNameFromContainer()1214 std::string GetModuleNameFromContainer()
1215 {
1216 auto container = Container::Current();
1217 CHECK_NULL_RETURN(container, "");
1218 return container->GetModuleName();
1219 }
1220
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)1221 void CompleteResourceObjectFromParams(
1222 int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
1223 {
1224 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
1225 int32_t typeNum = -1;
1226 if (type->IsNumber()) {
1227 typeNum = type->ToNumber<int32_t>();
1228 }
1229
1230 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1231 if (!args->IsArray()) {
1232 return;
1233 }
1234 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1235 if (resId != UNKNOWN_RESOURCE_ID) {
1236 return;
1237 }
1238 JSRef<JSVal> identity = params->GetValueAt(0);
1239
1240 bool isParseDollarResourceSuccess =
1241 JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
1242 if (!isParseDollarResourceSuccess) {
1243 return;
1244 }
1245
1246 std::regex resNameRegex(RESOURCE_NAME_PATTERN);
1247 std::smatch resNameResults;
1248 if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
1249 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
1250 }
1251
1252 if (typeNum == UNKNOWN_RESOURCE_TYPE) {
1253 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1254 }
1255 }
1256
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)1257 void CompleteResourceObjectFromId(
1258 JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
1259 {
1260 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1261 if (!args->IsArray()) {
1262 return;
1263 }
1264 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1265 auto paramCount = params->Length();
1266 JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
1267 if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
1268 std::vector<JSRef<JSVal>> tmpParams;
1269 for (uint32_t i = 0; i < paramCount; i++) {
1270 auto param = params->GetValueAt(i);
1271 tmpParams.insert(tmpParams.end(), param);
1272 }
1273 params->SetValueAt(0, name);
1274 uint32_t paramIndex = 1;
1275 if (!type->IsEmpty()) {
1276 params->SetValueAt(paramIndex, type);
1277 paramIndex++;
1278 }
1279 for (auto tmpParam : tmpParams) {
1280 params->SetValueAt(paramIndex, tmpParam);
1281 paramIndex++;
1282 }
1283 } else {
1284 params->SetValueAt(0, name);
1285 }
1286 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
1287 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1288 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
1289 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1290 }
1291 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
1292 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1293 }
1294 }
1295
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)1296 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
1297 {
1298 if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
1299 checkDimension.Reset();
1300 return;
1301 }
1302 if (notNegative && checkDimension.IsNegative()) {
1303 checkDimension.Reset();
1304 return;
1305 }
1306 }
1307
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1308 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1309 {
1310 Color left;
1311 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1312 commonColor.left = left;
1313 }
1314 Color right;
1315 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1316 commonColor.right = right;
1317 }
1318 Color top;
1319 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1320 commonColor.top = top;
1321 }
1322 Color bottom;
1323 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1324 commonColor.bottom = bottom;
1325 }
1326 }
1327
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1328 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
1329 {
1330 Color start;
1331 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) {
1332 localizedColor.start = start;
1333 }
1334 Color end;
1335 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) {
1336 localizedColor.end = end;
1337 }
1338 Color top;
1339 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1340 localizedColor.top = top;
1341 }
1342 Color bottom;
1343 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1344 localizedColor.bottom = bottom;
1345 }
1346 }
1347
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1348 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1349 {
1350 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
1351 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
1352 LocalizedColor localizedColor;
1353 ParseLocalizedEdgeColors(object, localizedColor);
1354 commonColor.top = localizedColor.top;
1355 commonColor.bottom = localizedColor.bottom;
1356 commonColor.left = localizedColor.start;
1357 commonColor.right = localizedColor.end;
1358 return true;
1359 }
1360 ParseEdgeColors(object, commonColor);
1361 return false;
1362 }
1363
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1364 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1365 {
1366 CalcDimension left;
1367 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(LEFT_PROPERTY), left)) {
1368 CheckDimensionUnit(left, true, notNegative);
1369 commonCalcDimension.left = left;
1370 }
1371 CalcDimension right;
1372 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(RIGHT_PROPERTY), right)) {
1373 CheckDimensionUnit(right, true, notNegative);
1374 commonCalcDimension.right = right;
1375 }
1376 CalcDimension top;
1377 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(TOP_PROPERTY), top)) {
1378 CheckDimensionUnit(top, true, notNegative);
1379 commonCalcDimension.top = top;
1380 }
1381 CalcDimension bottom;
1382 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(BOTTOM_PROPERTY), bottom)) {
1383 CheckDimensionUnit(bottom, true, notNegative);
1384 commonCalcDimension.bottom = bottom;
1385 }
1386 }
1387
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1388 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
1389 bool notNegative, CalcDimension defaultValue)
1390 {
1391 CalcDimension left;
1392 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) {
1393 CheckDimensionUnit(left, notPercent, notNegative);
1394 commonCalcDimension.left = left;
1395 } else {
1396 commonCalcDimension.left = defaultValue;
1397 }
1398 CalcDimension right;
1399 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) {
1400 CheckDimensionUnit(right, notPercent, notNegative);
1401 commonCalcDimension.right = right;
1402 } else {
1403 commonCalcDimension.right = defaultValue;
1404 }
1405 CalcDimension top;
1406 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) {
1407 CheckDimensionUnit(top, notPercent, notNegative);
1408 commonCalcDimension.top = top;
1409 } else {
1410 commonCalcDimension.top = defaultValue;
1411 }
1412 CalcDimension bottom;
1413 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) {
1414 CheckDimensionUnit(bottom, false, true);
1415 commonCalcDimension.bottom = bottom;
1416 } else {
1417 commonCalcDimension.bottom = defaultValue;
1418 }
1419 }
1420
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)1421 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
1422 bool notNegative)
1423 {
1424 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
1425 if (jsStart->IsObject()) {
1426 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
1427 CalcDimension calcDimension;
1428 if (ParseJsLengthMetrics(startObj, calcDimension)) {
1429 CheckDimensionUnit(calcDimension, true, notNegative);
1430 localizedCalcDimension.start = calcDimension;
1431 }
1432 }
1433 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
1434 if (jsEnd->IsObject()) {
1435 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
1436 CalcDimension calcDimension;
1437 if (ParseJsLengthMetrics(endObj, calcDimension)) {
1438 CheckDimensionUnit(calcDimension, true, notNegative);
1439 localizedCalcDimension.end = calcDimension;
1440 }
1441 }
1442 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
1443 if (jsTop->IsObject()) {
1444 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
1445 CalcDimension calcDimension;
1446 if (ParseJsLengthMetrics(topObj, calcDimension)) {
1447 CheckDimensionUnit(calcDimension, true, notNegative);
1448 localizedCalcDimension.top = calcDimension;
1449 }
1450 }
1451 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
1452 if (jsBottom->IsObject()) {
1453 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
1454 CalcDimension calcDimension;
1455 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1456 CheckDimensionUnit(calcDimension, true, notNegative);
1457 localizedCalcDimension.bottom = calcDimension;
1458 }
1459 }
1460 }
1461
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)1462 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
1463 {
1464 if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
1465 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
1466 CalcDimension calcDimension;
1467 if (ParseJsLengthMetrics(startObj, calcDimension)) {
1468 CheckDimensionUnit(calcDimension, false, true);
1469 localizedCalcDimension.start = calcDimension;
1470 }
1471 }
1472 if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
1473 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
1474 CalcDimension calcDimension;
1475 if (ParseJsLengthMetrics(endObj, calcDimension)) {
1476 CheckDimensionUnit(calcDimension, false, true);
1477 localizedCalcDimension.end = calcDimension;
1478 }
1479 }
1480 if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
1481 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
1482 CalcDimension calcDimension;
1483 if (ParseJsLengthMetrics(topObj, calcDimension)) {
1484 CheckDimensionUnit(calcDimension, false, true);
1485 localizedCalcDimension.top = calcDimension;
1486 }
1487 }
1488 if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
1489 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
1490 CalcDimension calcDimension;
1491 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1492 CheckDimensionUnit(calcDimension, false, true);
1493 localizedCalcDimension.bottom = calcDimension;
1494 }
1495 }
1496 }
1497
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1498 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1499 {
1500 if (CheckLengthMetrics(object)) {
1501 LocalizedCalcDimension localizedCalcDimension;
1502 ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
1503 commonCalcDimension.top = localizedCalcDimension.top;
1504 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1505 commonCalcDimension.left = localizedCalcDimension.start;
1506 commonCalcDimension.right = localizedCalcDimension.end;
1507 return true;
1508 }
1509 ParseEdgeWidths(object, commonCalcDimension, notNegative);
1510 return false;
1511 }
1512
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1513 void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1514 {
1515 if (CheckLengthMetrics(object)) {
1516 LocalizedCalcDimension localizedCalcDimension;
1517 ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
1518 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1519 commonCalcDimension.top = localizedCalcDimension.top;
1520 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1521 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1522 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1523 return;
1524 }
1525 ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1526 }
1527
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1528 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1529 {
1530 if (CheckLengthMetrics(object)) {
1531 LocalizedCalcDimension localizedCalcDimension;
1532 ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1533 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1534 commonCalcDimension.top = localizedCalcDimension.top;
1535 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1536 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1537 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1538 return;
1539 }
1540 ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1541 }
1542
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1543 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1544 {
1545 auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1546 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1547 auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1548 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1549 NG::PipelineContext::SetCallBackNode(targetNode);
1550 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1551 jsFuncFinish->ExecuteJS(1, &newJSVal);
1552 };
1553 return finishCallback;
1554 }
1555 } // namespace
1556
GetResourceObject(const JSRef<JSObject> & jsObj)1557 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1558 {
1559 auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1560 auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1561 auto args = jsObj->GetProperty("params");
1562
1563 std::string bundleName;
1564 std::string moduleName;
1565 auto bundle = jsObj->GetProperty("bundleName");
1566 auto module = jsObj->GetProperty("moduleName");
1567 if (bundle->IsString() && module->IsString()) {
1568 bundleName = bundle->ToString();
1569 moduleName = module->ToString();
1570 }
1571 if (!args->IsArray()) {
1572 return nullptr;
1573 }
1574 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1575 std::vector<ResourceObjectParams> resObjParamsList;
1576 auto size = static_cast<int32_t>(params->Length());
1577 for (int32_t i = 0; i < size; i++) {
1578 auto item = params->GetValueAt(i);
1579 ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1580 if (item->IsString()) {
1581 resObjParams.type = ResourceObjectParamType::STRING;
1582 } else if (item->IsNumber()) {
1583 if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1584 resObjParams.type = ResourceObjectParamType::FLOAT;
1585 } else {
1586 resObjParams.type = ResourceObjectParamType::INT;
1587 }
1588 }
1589 resObjParamsList.push_back(resObjParams);
1590 }
1591 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName);
1592 return resourceObject;
1593 }
1594
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1595 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1596 {
1597 auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1598 auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1599 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName);
1600 return resourceObject;
1601 }
1602
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1603 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1604 {
1605 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1606 RefPtr<ThemeConstants> themeConstants = nullptr;
1607 if (SystemProperties::GetResourceDecoupling()) {
1608 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1609 if (!resourceAdapter) {
1610 return nullptr;
1611 }
1612 } else {
1613 themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1614 if (!themeConstants) {
1615 return nullptr;
1616 }
1617 }
1618 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1619 return resourceWrapper;
1620 }
1621
CreateResourceWrapper()1622 RefPtr<ResourceWrapper> CreateResourceWrapper()
1623 {
1624 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1625 RefPtr<ThemeConstants> themeConstants = nullptr;
1626 if (SystemProperties::GetResourceDecoupling()) {
1627 resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter();
1628 if (!resourceAdapter) {
1629 return nullptr;
1630 }
1631 } else {
1632 themeConstants = JSViewAbstract::GetThemeConstants();
1633 if (!themeConstants) {
1634 return nullptr;
1635 }
1636 }
1637 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1638 return resourceWrapper;
1639 }
1640
ColorAlphaAdapt(uint32_t origin)1641 uint32_t ColorAlphaAdapt(uint32_t origin)
1642 {
1643 uint32_t result = origin;
1644 if (origin >> COLOR_ALPHA_OFFSET == 0) {
1645 result = origin | COLOR_ALPHA_VALUE;
1646 }
1647 return result;
1648 }
1649
JsScale(const JSCallbackInfo & info)1650 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1651 {
1652 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1653 auto jsVal = info[0];
1654 if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1655 SetDefaultScale();
1656 return;
1657 }
1658
1659 if (jsVal->IsObject()) {
1660 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1661 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1662 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1663 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1664 // default: x, y, z (1.0, 1.0, 1.0)
1665 auto scaleX = 1.0f;
1666 auto scaleY = 1.0f;
1667 auto scaleZ = 1.0f;
1668 // default centerX, centerY 50% 50%;
1669 CalcDimension centerX = 0.5_pct;
1670 CalcDimension centerY = 0.5_pct;
1671 ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1672 ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1673 ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1674 return;
1675 } else {
1676 SetDefaultScale();
1677 }
1678 }
1679 double scale = 0.0;
1680 if (ParseJsDouble(jsVal, scale)) {
1681 ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1682 }
1683 }
1684
SetDefaultScale()1685 void JSViewAbstract::SetDefaultScale()
1686 {
1687 ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1688 ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1689 }
1690
JsScaleX(const JSCallbackInfo & info)1691 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1692 {
1693 double scaleVal = 0.0;
1694 if (!ParseJsDouble(info[0], scaleVal)) {
1695 return;
1696 }
1697 ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1698 }
1699
JsScaleY(const JSCallbackInfo & info)1700 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1701 {
1702 double scaleVal = 0.0;
1703 if (!ParseJsDouble(info[0], scaleVal)) {
1704 return;
1705 }
1706 ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1707 }
1708
JsOpacity(const JSCallbackInfo & info)1709 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1710 {
1711 double opacity = 0.0;
1712 if (!ParseJsDouble(info[0], opacity)) {
1713 ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1714 return;
1715 }
1716 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1717 opacity = std::clamp(opacity, 0.0, 1.0);
1718 } else {
1719 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1720 opacity = 1.0;
1721 }
1722 }
1723 ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1724 }
1725
JsTranslate(const JSCallbackInfo & info)1726 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1727 {
1728 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1729 JSCallbackInfoType::OBJECT };
1730 auto jsVal = info[0];
1731 if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
1732 SetDefaultTranslate();
1733 return;
1734 }
1735
1736 if (jsVal->IsObject()) {
1737 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1738 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1739 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1740 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1741 // default: x, y, z (0.0, 0.0, 0.0)
1742 auto translateX = CalcDimension(0.0);
1743 auto translateY = CalcDimension(0.0);
1744 auto translateZ = CalcDimension(0.0);
1745 ParseJsTranslate(jsVal, translateX, translateY, translateZ);
1746 ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1747 return;
1748 } else {
1749 SetDefaultTranslate();
1750 }
1751 }
1752 CalcDimension value;
1753 if (ParseJsDimensionVp(jsVal, value)) {
1754 ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1755 }
1756 }
1757
SetDefaultTranslate()1758 void JSViewAbstract::SetDefaultTranslate()
1759 {
1760 ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1761 }
1762
JsTranslateX(const JSCallbackInfo & info)1763 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1764 {
1765 CalcDimension value;
1766 if (!ParseJsDimensionVp(info[0], value)) {
1767 return;
1768 }
1769 ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1770 }
1771
JsTranslateY(const JSCallbackInfo & info)1772 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1773 {
1774 CalcDimension value;
1775 if (!ParseJsDimensionVp(info[0], value)) {
1776 return;
1777 }
1778 ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1779 }
1780
JsRotate(const JSCallbackInfo & info)1781 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1782 {
1783 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1784 auto jsVal = info[0];
1785 if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
1786 SetDefaultRotate();
1787 return;
1788 }
1789
1790 if (jsVal->IsObject()) {
1791 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1792 std::optional<float> angle;
1793 ParseJsRotate(jsVal, rotate, angle);
1794 if (angle) {
1795 ViewAbstractModel::GetInstance()->SetRotate(
1796 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1797 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1798 } else {
1799 SetDefaultRotate();
1800 }
1801 return;
1802 }
1803 double rotateZ;
1804 if (ParseJsDouble(jsVal, rotateZ)) {
1805 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1806 }
1807 }
1808
SetDefaultRotate()1809 void JSViewAbstract::SetDefaultRotate()
1810 {
1811 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1812 ViewAbstractModel::GetInstance()->SetRotate(
1813 rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1814 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1815 }
1816
JsRotateX(const JSCallbackInfo & info)1817 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1818 {
1819 double rotateVal = 0.0;
1820 if (!ParseJsDouble(info[0], rotateVal)) {
1821 return;
1822 }
1823 ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1824 }
1825
JsRotateY(const JSCallbackInfo & info)1826 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1827 {
1828 double rotateVal = 0.0;
1829 if (!ParseJsDouble(info[0], rotateVal)) {
1830 return;
1831 }
1832 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1833 }
1834
JsTransform(const JSCallbackInfo & info)1835 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1836 {
1837 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1838 auto jsVal = info[0];
1839 if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
1840 SetDefaultTransform();
1841 return;
1842 }
1843 JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
1844 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1845 if (!array->IsArray()) {
1846 return;
1847 }
1848 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1849 if (jsArray->Length() != matrix4Len) {
1850 return;
1851 }
1852 std::vector<float> matrix(matrix4Len);
1853 for (int32_t i = 0; i < matrix4Len; i++) {
1854 double value = 0.0;
1855 ParseJsDouble(jsArray->GetValueAt(i), value);
1856 matrix[i] = static_cast<float>(value);
1857 }
1858 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1859 }
1860
SetDefaultTransform()1861 void JSViewAbstract::SetDefaultTransform()
1862 {
1863 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1864 std::vector<float> matrix(matrix4Len);
1865 const int32_t initPosition = 5;
1866 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1867 double value = 1.0;
1868 matrix[i] = static_cast<float>(value);
1869 }
1870 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1871 }
1872
ParseJsTransition(const JSRef<JSObject> & jsObj)1873 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
1874 {
1875 NG::TransitionOptions transitionOption;
1876 bool hasEffect = false;
1877 transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1878 if (jsObj->HasProperty("opacity")) {
1879 double opacity = 1.0;
1880 ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1881 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1882 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1883 opacity = 1.0;
1884 }
1885 } else {
1886 opacity = std::clamp(opacity, 0.0, 1.0);
1887 }
1888 transitionOption.UpdateOpacity(static_cast<float>(opacity));
1889 hasEffect = true;
1890 }
1891 if (jsObj->HasProperty("translate")) {
1892 // default: x, y, z (0.0, 0.0, 0.0)
1893 NG::TranslateOptions translate;
1894 ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1895 transitionOption.UpdateTranslate(translate);
1896 hasEffect = true;
1897 }
1898 if (jsObj->HasProperty("scale")) {
1899 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1900 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1901 ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1902 scale.centerX, scale.centerY);
1903 transitionOption.UpdateScale(scale);
1904 hasEffect = true;
1905 }
1906 if (jsObj->HasProperty("rotate")) {
1907 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1908 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1909 std::optional<float> angle;
1910 ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1911 if (angle.has_value()) {
1912 rotate.angle = angle.value();
1913 transitionOption.UpdateRotate(rotate);
1914 hasEffect = true;
1915 }
1916 }
1917 if (!hasEffect) {
1918 // default transition
1919 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1920 }
1921 return transitionOption;
1922 }
1923
ParseJsTransitionEffect(const JSCallbackInfo & info)1924 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
1925 {
1926 JSRef<JSVal> arg = info[0];
1927 if (!arg->IsObject()) {
1928 return nullptr;
1929 }
1930 auto obj = JSRef<JSObject>::Cast(arg);
1931 auto transitionVal = obj->GetProperty("transition");
1932
1933 if (!transitionVal->IsObject()) {
1934 return nullptr;
1935 }
1936
1937 auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
1938 auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
1939 return chainedEffect;
1940 }
1941
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)1942 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
1943 const JSExecutionContext& context)
1944 {
1945 auto chainedEffect = ParseChainedTransition(object, context);
1946 return chainedEffect;
1947 }
1948
JsTransition(const JSCallbackInfo & info)1949 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
1950 {
1951 if (info.Length() < 1 || !info[0]->IsObject()) {
1952 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
1953 ViewAbstractModel::GetInstance()->CleanTransition();
1954 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
1955 }
1956 return;
1957 }
1958 auto obj = JSRef<JSObject>::Cast(info[0]);
1959 if (!obj->GetProperty("successor_")->IsUndefined()) {
1960 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
1961 std::function<void(bool)> finishCallback;
1962 if (info.Length() > 1 && info[1]->IsFunction()) {
1963 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
1964 }
1965 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
1966 return;
1967 }
1968 auto options = ParseJsTransition(obj);
1969 ViewAbstractModel::GetInstance()->SetTransition(options);
1970 }
1971
JsWidth(const JSCallbackInfo & info)1972 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
1973 {
1974 JsWidth(info[0]);
1975 }
1976
JsWidth(const JSRef<JSVal> & jsValue)1977 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
1978 {
1979 CalcDimension value;
1980 if (jsValue->IsUndefined()) {
1981 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1982 return true;
1983 }
1984 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1985 if (!ParseJsDimensionVpNG(jsValue, value)) {
1986 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1987 return false;
1988 }
1989 } else if (!ParseJsDimensionVp(jsValue, value)) {
1990 return false;
1991 }
1992
1993 if (LessNotEqual(value.Value(), 0.0)) {
1994 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1995 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1996 return true;
1997 } else {
1998 value.SetValue(0.0);
1999 }
2000 }
2001
2002 ViewAbstractModel::GetInstance()->SetWidth(value);
2003 return true;
2004 }
2005
JsHeight(const JSCallbackInfo & info)2006 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
2007 {
2008 JsHeight(info[0]);
2009 }
2010
JsHeight(const JSRef<JSVal> & jsValue)2011 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
2012 {
2013 CalcDimension value;
2014 if (jsValue->IsUndefined()) {
2015 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2016 return true;
2017 }
2018 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2019 if (!ParseJsDimensionVpNG(jsValue, value)) {
2020 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2021 return false;
2022 }
2023 } else if (!ParseJsDimensionVp(jsValue, value)) {
2024 return false;
2025 }
2026
2027 if (LessNotEqual(value.Value(), 0.0)) {
2028 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2029 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2030 return true;
2031 } else {
2032 value.SetValue(0.0);
2033 }
2034 }
2035
2036 ViewAbstractModel::GetInstance()->SetHeight(value);
2037 return true;
2038 }
2039
JsResponseRegion(const JSCallbackInfo & info)2040 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
2041 {
2042 std::vector<DimensionRect> result;
2043 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2044 ViewAbstractModel::GetInstance()->SetResponseRegion({});
2045 return;
2046 }
2047
2048 ViewAbstractModel::GetInstance()->SetResponseRegion(result);
2049 }
2050
JsMouseResponseRegion(const JSCallbackInfo & info)2051 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
2052 {
2053 std::vector<DimensionRect> result;
2054 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2055 ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
2056 return;
2057 }
2058 ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
2059 }
2060
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2061 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
2062 {
2063 result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
2064 result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
2065 if (!jsValue->IsObject()) {
2066 return true;
2067 }
2068
2069 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
2070 JSRef<JSVal> x = obj->GetProperty("x");
2071 JSRef<JSVal> y = obj->GetProperty("y");
2072 JSRef<JSVal> width = obj->GetProperty("width");
2073 JSRef<JSVal> height = obj->GetProperty("height");
2074 CalcDimension xDimen = result.GetOffset().GetX();
2075 CalcDimension yDimen = result.GetOffset().GetY();
2076 CalcDimension widthDimen = result.GetWidth();
2077 CalcDimension heightDimen = result.GetHeight();
2078 auto s1 = width->ToString();
2079 auto s2 = height->ToString();
2080 if (s1.find('-') != std::string::npos) {
2081 width = JSRef<JSVal>::Make(ToJSValue("100%"));
2082 }
2083 if (s2.find('-') != std::string::npos) {
2084 height = JSRef<JSVal>::Make(ToJSValue("100%"));
2085 }
2086 if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
2087 auto offset = result.GetOffset();
2088 offset.SetX(xDimen);
2089 result.SetOffset(offset);
2090 }
2091 if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
2092 auto offset = result.GetOffset();
2093 offset.SetY(yDimen);
2094 result.SetOffset(offset);
2095 }
2096 if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
2097 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
2098 return true;
2099 }
2100 result.SetWidth(widthDimen);
2101 }
2102 if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
2103 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
2104 return true;
2105 }
2106 result.SetHeight(heightDimen);
2107 }
2108 return true;
2109 }
2110
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2111 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
2112 {
2113 if (!jsValue->IsArray() && !jsValue->IsObject()) {
2114 return false;
2115 }
2116
2117 if (jsValue->IsArray()) {
2118 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2119 for (size_t i = 0; i < array->Length(); i++) {
2120 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2121 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2122 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2123 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2124 DimensionOffset offsetDimen(xDimen, yDimen);
2125 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2126 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
2127 result.emplace_back(dimenRect);
2128 } else {
2129 return false;
2130 }
2131 }
2132 return true;
2133 }
2134
2135 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2136 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2137 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2138 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2139 DimensionOffset offsetDimen(xDimen, yDimen);
2140 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2141 if (ParseJsDimensionRect(jsValue, dimenRect)) {
2142 result.emplace_back(dimenRect);
2143 return true;
2144 } else {
2145 return false;
2146 }
2147 }
2148
JsSize(const JSCallbackInfo & info)2149 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
2150 {
2151 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2152 auto jsVal = info[0];
2153 if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
2154 return;
2155 }
2156
2157 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2158 JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
2159 JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
2160 }
2161
JsConstraintSize(const JSCallbackInfo & info)2162 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
2163 {
2164 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2165 auto jsVal = info[0];
2166 if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
2167 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2168 ViewAbstractModel::GetInstance()->ResetMinSize(true);
2169 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2170 ViewAbstractModel::GetInstance()->ResetMinSize(false);
2171 return;
2172 }
2173
2174 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2175
2176 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
2177 CalcDimension minWidth;
2178 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
2179 CalcDimension maxWidth;
2180 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
2181 CalcDimension minHeight;
2182 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
2183 CalcDimension maxHeight;
2184 bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
2185 if (ParseJsDimensionVp(minWidthValue, minWidth)) {
2186 ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
2187 } else if (version10OrLarger) {
2188 ViewAbstractModel::GetInstance()->ResetMinSize(true);
2189 }
2190
2191 if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
2192 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
2193 } else if (version10OrLarger) {
2194 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2195 }
2196
2197 if (ParseJsDimensionVp(minHeightValue, minHeight)) {
2198 ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
2199 } else if (version10OrLarger) {
2200 ViewAbstractModel::GetInstance()->ResetMinSize(false);
2201 }
2202
2203 if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
2204 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
2205 } else if (version10OrLarger) {
2206 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2207 }
2208 }
2209
JsLayoutPriority(const JSCallbackInfo & info)2210 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
2211 {
2212 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2213 auto jsVal = info[0];
2214 if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
2215 return;
2216 }
2217
2218 int32_t priority;
2219 if (jsVal->IsNumber()) {
2220 priority = jsVal->ToNumber<int32_t>();
2221 } else {
2222 priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
2223 }
2224 ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
2225 }
2226
JsPixelRound(const JSCallbackInfo & info)2227 void JSViewAbstract::JsPixelRound(const JSCallbackInfo& info)
2228 {
2229 uint16_t value = 0;
2230 JSRef<JSVal> arg = info[0];
2231 if (!arg->IsObject()) {
2232 return;
2233 }
2234 JSRef<JSObject> object = JSRef<JSObject>::Cast(arg);
2235 JSRef<JSVal> jsStartValue = object->GetProperty("start");
2236 if (jsStartValue->IsNumber()) {
2237 int32_t startValue = jsStartValue->ToNumber<int32_t>();
2238 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(startValue)) {
2239 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_START);
2240 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(startValue)) {
2241 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_START);
2242 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(startValue)) {
2243 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_START);
2244 }
2245 }
2246 JSRef<JSVal> jsTopValue = object->GetProperty("top");
2247 if (jsTopValue->IsNumber()) {
2248 int32_t topValue = jsTopValue->ToNumber<int32_t>();
2249 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(topValue)) {
2250 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
2251 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(topValue)) {
2252 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
2253 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(topValue)) {
2254 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_TOP);
2255 }
2256 }
2257 JSRef<JSVal> jsEndValue = object->GetProperty("end");
2258 if (jsEndValue->IsNumber()) {
2259 int32_t endValue = jsEndValue->ToNumber<int32_t>();
2260 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(endValue)) {
2261 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_END);
2262 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(endValue)) {
2263 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_END);
2264 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(endValue)) {
2265 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_END);
2266 }
2267 }
2268 JSRef<JSVal> jsBottomValue = object->GetProperty("bottom");
2269 if (jsBottomValue->IsNumber()) {
2270 int32_t bottomValue = jsBottomValue->ToNumber<int32_t>();
2271 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2272 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
2273 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2274 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
2275 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2276 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_BOTTOM);
2277 }
2278 }
2279 ViewAbstractModel::GetInstance()->SetPixelRound(value);
2280 }
2281
JsLayoutWeight(const JSCallbackInfo & info)2282 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
2283 {
2284 float value = 0.0f;
2285 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2286 auto jsVal = info[0];
2287 if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
2288 if (!jsVal->IsUndefined()) {
2289 return;
2290 }
2291 }
2292
2293 if (jsVal->IsNumber()) {
2294 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2295 value = jsVal->ToNumber<float>();
2296 } else {
2297 value = jsVal->ToNumber<int32_t>();
2298 }
2299 } else {
2300 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2301 value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
2302 } else {
2303 value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
2304 }
2305 }
2306
2307 ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
2308 }
2309
JsChainWeight(const JSCallbackInfo & info)2310 void JSViewAbstract::JsChainWeight(const JSCallbackInfo& info)
2311 {
2312 NG::LayoutWeightPair layoutWeightPair(DEFAULT_LAYOUT_WEIGHT, DEFAULT_LAYOUT_WEIGHT);
2313 auto jsVal = info[0];
2314 if (jsVal->IsObject()) {
2315 JSRef<JSObject> val = JSRef<JSObject>::Cast(jsVal);
2316 auto weightX = val->GetProperty("horizontal");
2317 auto weightY = val->GetProperty("vertical");
2318 if (weightX->IsNumber()) {
2319 layoutWeightPair.first = weightX->ToNumber<float>();
2320 }
2321 if (weightY->IsNumber()) {
2322 layoutWeightPair.second = weightY->ToNumber<float>();
2323 }
2324 }
2325 ViewAbstractModel::GetInstance()->SetLayoutWeight(layoutWeightPair);
2326 }
2327
JsAlign(const JSCallbackInfo & info)2328 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
2329 {
2330 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2331 auto jsVal = info[0];
2332 if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
2333 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2334 ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
2335 return;
2336 }
2337 auto value = jsVal->ToNumber<int32_t>();
2338 Alignment alignment = ParseAlignment(value);
2339 ViewAbstractModel::GetInstance()->SetAlign(alignment);
2340 }
2341
JsPosition(const JSCallbackInfo & info)2342 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
2343 {
2344 CalcDimension x;
2345 CalcDimension y;
2346 OHOS::Ace::EdgesParam edges;
2347
2348 auto jsArg = info[0];
2349 if (jsArg->IsObject()) {
2350 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2351 if (ParseLocationProps(jsObj, x, y)) {
2352 return ViewAbstractModel::GetInstance()->SetPosition(x, y);
2353 } else if (ParseLocalizedEdges(jsObj, edges)) {
2354 ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
2355 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2356 } else if (ParseLocationPropsEdges(jsObj, edges)) {
2357 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2358 }
2359 }
2360 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2361 ViewAbstractModel::GetInstance()->ResetPosition();
2362 } else {
2363 ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
2364 }
2365 }
2366
JsMarkAnchor(const JSCallbackInfo & info)2367 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
2368 {
2369 CalcDimension x;
2370 CalcDimension y;
2371
2372 auto jsArg = info[0];
2373 if (jsArg->IsObject()) {
2374 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2375 if (ParseMarkAnchorPosition(jsObj, x, y)) {
2376 ViewAbstractModel::GetInstance()->SetLocalizedMarkAnchor(true);
2377 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2378 } else if (ParseLocationProps(jsObj, x, y)) {
2379 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2380 }
2381 }
2382 ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
2383 }
2384
JsOffset(const JSCallbackInfo & info)2385 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
2386 {
2387 CalcDimension x;
2388 CalcDimension y;
2389 OHOS::Ace::EdgesParam edges;
2390 auto jsArg = info[0];
2391 if (jsArg->IsObject()) {
2392 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2393 if (ParseLocalizedEdges(jsObj, edges)) {
2394 ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
2395 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2396 } else if (ParseLocationProps(jsObj, x, y)) {
2397 return ViewAbstractModel::GetInstance()->SetOffset(x, y);
2398 } else if (ParseLocationPropsEdges(jsObj, edges)) {
2399 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2400 }
2401 }
2402
2403 ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
2404 }
2405
JsEnabled(const JSCallbackInfo & info)2406 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
2407 {
2408 auto arg = info[0];
2409 if (!arg->IsBoolean()) {
2410 ViewAbstractModel::GetInstance()->SetEnabled(true);
2411 } else {
2412 ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
2413 }
2414 }
2415
JsAspectRatio(const JSCallbackInfo & info)2416 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
2417 {
2418 double value = 0.0;
2419 auto jsAspectRatio = info[0];
2420 if (!ParseJsDouble(jsAspectRatio, value)) {
2421 // add version protection, undefined use default value
2422 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
2423 (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
2424 ViewAbstractModel::GetInstance()->ResetAspectRatio();
2425 return;
2426 } else {
2427 return;
2428 }
2429 }
2430
2431 // negative use default value.
2432 if (LessOrEqual(value, 0.0)) {
2433 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2434 ViewAbstractModel::GetInstance()->ResetAspectRatio();
2435 return;
2436 } else {
2437 value = 1.0;
2438 }
2439 }
2440
2441 ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
2442 }
2443
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2444 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
2445 std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
2446 {
2447 if (info[0]->IsString()) {
2448 std::string text = info[0]->ToString();
2449 ViewAbstractModel::GetInstance()->SetOverlay(
2450 text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
2451 } else if (info[0]->IsObject()) {
2452 JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
2453 auto builder = overlayObject->GetProperty("builder");
2454 if (builder->IsFunction()) {
2455 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2456 CHECK_NULL_VOID(builderFunc);
2457 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2458 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
2459 node = targetNode]() {
2460 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2461 ACE_SCORING_EVENT("Overlay");
2462 PipelineContext::SetCallBackNode(node);
2463 func->Execute();
2464 };
2465 ViewAbstractModel::GetInstance()->SetOverlay(
2466 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
2467 return;
2468 }
2469
2470 JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
2471 if (!builderNode->IsObject()) {
2472 return;
2473 }
2474 auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2475 JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2476 if (nodePtr.IsEmpty()) {
2477 return;
2478 }
2479 const auto* vm = nodePtr->GetEcmaVM();
2480 auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
2481 auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2482 CHECK_NULL_VOID(frameNode);
2483 RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2484 ViewAbstractModel::GetInstance()->SetOverlay(
2485 "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2486 }
2487 }
2488
JsOverlay(const JSCallbackInfo & info)2489 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2490 {
2491 if (info.Length() > 0 && (info[0]->IsUndefined())) {
2492 ViewAbstractModel::GetInstance()->SetOverlay(
2493 "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2494 return;
2495 }
2496
2497 if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2498 return;
2499 }
2500 std::optional<Alignment> align;
2501 std::optional<CalcDimension> offsetX;
2502 std::optional<CalcDimension> offsetY;
2503
2504 if (info[1]->IsObject()) {
2505 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2506 JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2507 auto value = alignVal->ToNumber<int32_t>();
2508 Alignment alignment = ParseAlignment(value);
2509 align = alignment;
2510
2511 JSRef<JSVal> val = optionObj->GetProperty("offset");
2512 if (val->IsObject()) {
2513 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2514 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2515 CalcDimension x;
2516 if (ParseJsDimensionVp(xVal, x)) {
2517 offsetX = x;
2518 }
2519 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2520 CalcDimension y;
2521 if (ParseJsDimensionVp(yVal, y)) {
2522 offsetY = y;
2523 }
2524 }
2525 }
2526
2527 ParseOverlayFirstParam(info, align, offsetX, offsetY);
2528 }
2529
ParseAlignment(int32_t align)2530 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2531 {
2532 Alignment alignment = Alignment::CENTER;
2533 switch (align) {
2534 case 0:
2535 alignment = Alignment::TOP_LEFT;
2536 break;
2537 case 1:
2538 alignment = Alignment::TOP_CENTER;
2539 break;
2540 case 2:
2541 alignment = Alignment::TOP_RIGHT;
2542 break;
2543 case 3:
2544 alignment = Alignment::CENTER_LEFT;
2545 break;
2546 case 4:
2547 alignment = Alignment::CENTER;
2548 break;
2549 case 5:
2550 alignment = Alignment::CENTER_RIGHT;
2551 break;
2552 case 6:
2553 alignment = Alignment::BOTTOM_LEFT;
2554 break;
2555 case 7:
2556 alignment = Alignment::BOTTOM_CENTER;
2557 break;
2558 case 8:
2559 alignment = Alignment::BOTTOM_RIGHT;
2560 break;
2561 default:
2562 break;
2563 }
2564 return alignment;
2565 }
2566
SetVisibility(const JSCallbackInfo & info)2567 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2568 {
2569 int32_t visible = 0;
2570 JSRef<JSVal> arg = info[0];
2571 if (arg->IsNull() || arg->IsUndefined()) {
2572 // undefined value use default value.
2573 visible = 0;
2574 } else if (!arg->IsNumber()) {
2575 return;
2576 } else {
2577 visible = arg->ToNumber<int32_t>();
2578 }
2579
2580 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2581 (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
2582 visible = 0;
2583 }
2584
2585 if (info.Length() > 1 && info[1]->IsFunction()) {
2586 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2587 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2588 auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2589 int32_t visible) {
2590 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2591 ACE_SCORING_EVENT("onVisibilityChange");
2592 PipelineContext::SetCallBackNode(node);
2593 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2594 func->ExecuteJS(1, &newJSVal);
2595 };
2596 ViewAbstractModel::GetInstance()->SetVisibility(
2597 static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2598 } else {
2599 ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2600 }
2601 }
2602
JsSetFreeze(const JSCallbackInfo & info)2603 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2604 {
2605 if (info[0]->IsBoolean()) {
2606 ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2607 }
2608 }
2609
JsFlexBasis(const JSCallbackInfo & info)2610 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2611 {
2612 CalcDimension value;
2613 if (!ParseJsDimensionVp(info[0], value)) {
2614 value.SetUnit(DimensionUnit::AUTO);
2615 }
2616 // flexbasis don't support percent case.
2617 if (value.Unit() == DimensionUnit::PERCENT) {
2618 value.SetUnit(DimensionUnit::AUTO);
2619 }
2620 ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2621 }
2622
JsFlexGrow(const JSCallbackInfo & info)2623 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2624 {
2625 double value = 0.0;
2626 if (!ParseJsDouble(info[0], value)) {
2627 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2628 // undefined use default value.
2629 value = 0.0;
2630 } else {
2631 return;
2632 }
2633 }
2634 // negative use default value.
2635 if (value < 0.0) {
2636 value = 0.0;
2637 }
2638 ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2639 }
2640
JsFlexShrink(const JSCallbackInfo & info)2641 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2642 {
2643 double value = 0.0;
2644 if (!ParseJsDouble(info[0], value)) {
2645 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2646 // undefined use default value.
2647 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2648 return;
2649 } else {
2650 return;
2651 }
2652 }
2653 // negative use default value.
2654 if (value < 0.0) {
2655 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2656 return;
2657 }
2658 ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2659 }
2660
JsDisplayPriority(const JSCallbackInfo & info)2661 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2662 {
2663 double value = 0.0;
2664 if (!ParseJsDouble(info[0], value)) {
2665 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2666 ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
2667 }
2668 return;
2669 }
2670 ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2671 }
2672
JsSharedTransition(const JSCallbackInfo & info)2673 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2674 {
2675 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2676 auto jsVal = info[0];
2677 if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
2678 return;
2679 }
2680 // id
2681 auto id = jsVal->ToString();
2682 if (id.empty()) {
2683 return;
2684 }
2685 std::shared_ptr<SharedTransitionOption> sharedOption;
2686
2687 // options
2688 if (info.Length() > 1 && info[1]->IsObject()) {
2689 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2690 sharedOption = std::make_shared<SharedTransitionOption>();
2691 // default: duration: 1000
2692 sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2693 if (sharedOption->duration < 0) {
2694 sharedOption->duration = DEFAULT_DURATION;
2695 }
2696 // default: delay: 0
2697 sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2698 if (sharedOption->delay < 0) {
2699 sharedOption->delay = 0;
2700 }
2701 // default: LinearCurve
2702 RefPtr<Curve> curve;
2703 JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2704 if (curveArgs->IsString()) {
2705 curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2706 } else if (curveArgs->IsObject()) {
2707 JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2708 if (!curveString->IsString()) {
2709 return;
2710 }
2711 curve = CreateCurve(curveString->ToString(), false);
2712 }
2713 if (!curve) {
2714 curve = Curves::LINEAR;
2715 }
2716 sharedOption->curve = curve;
2717 // motionPath
2718 if (jsObj->HasProperty("motionPath")) {
2719 MotionPathOption motionPathOption;
2720 if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2721 sharedOption->motionPathOption = motionPathOption;
2722 }
2723 }
2724 // zIndex
2725 sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2726 // type
2727 int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2728 static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2729 sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2730 }
2731 ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2732 }
2733
JsGeometryTransition(const JSCallbackInfo & info)2734 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2735 {
2736 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2737 auto jsVal = info[0];
2738 if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
2739 return;
2740 }
2741 // id
2742 auto id = jsVal->ToString();
2743 // follow flag
2744 bool followWithOutTransition = false;
2745 // hierarchy flag
2746 bool doRegisterSharedTransition = true;
2747 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
2748 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2749 ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2750
2751 auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
2752 ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
2753 switch (transitionHierarchyStrategy) {
2754 case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
2755 doRegisterSharedTransition = false;
2756 break;
2757 case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
2758 doRegisterSharedTransition = true;
2759 break;
2760 default:
2761 break;
2762 }
2763 }
2764 ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
2765 }
2766
JsAlignSelf(const JSCallbackInfo & info)2767 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2768 {
2769 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2770 auto jsVal = info[0];
2771 if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
2772 ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2773 return;
2774 }
2775 auto alignVal = jsVal->ToNumber<int32_t>();
2776
2777 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2778 ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2779 }
2780 }
2781
JsBackgroundColor(const JSCallbackInfo & info)2782 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2783 {
2784 Color backgroundColor;
2785 if (!ParseJsColor(info[0], backgroundColor)) {
2786 backgroundColor = Color::TRANSPARENT;
2787 }
2788
2789 ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2790 }
2791
JsBackgroundImage(const JSCallbackInfo & info)2792 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2793 {
2794 int32_t resId = 0;
2795 std::string src;
2796 std::string bundle;
2797 std::string module;
2798 RefPtr<PixelMap> pixmap = nullptr;
2799 auto jsBackgroundImage = info[0];
2800 GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
2801 if (jsBackgroundImage->IsString()) {
2802 src = jsBackgroundImage->ToString();
2803 ViewAbstractModel::GetInstance()->SetBackgroundImage(
2804 ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2805 } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) {
2806 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2807 } else {
2808 #if defined(PIXEL_MAP_SUPPORTED)
2809 if (IsDrawable(jsBackgroundImage)) {
2810 pixmap = GetDrawablePixmap(jsBackgroundImage);
2811 } else {
2812 pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
2813 }
2814 #endif
2815 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2816 }
2817
2818 int32_t repeatIndex = 0;
2819 if (info.Length() == 2) {
2820 auto jsImageRepeat = info[1];
2821 if (jsImageRepeat->IsNumber()) {
2822 repeatIndex = jsImageRepeat->ToNumber<int32_t>();
2823 }
2824 }
2825 auto repeat = static_cast<ImageRepeat>(repeatIndex);
2826 ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2827 }
2828
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2829 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2830 {
2831 if (jsBlurOption->GetProperty("grayscale")->IsArray()) {
2832 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsBlurOption->GetProperty("grayscale"));
2833 auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2834 auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2835 std::vector<float> greyVec(2); // 2 number
2836 greyVec[0] = grey1;
2837 greyVec[1] = grey2;
2838 blurOption.grayscale = greyVec;
2839 }
2840 }
2841
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)2842 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
2843 {
2844 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2845 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2846 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2847 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2848 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2849 }
2850 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2851 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2852 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2853 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2854 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2855 }
2856
2857 // policy
2858 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2859 ParseJsInt32(jsOption->GetProperty("policy"), policy);
2860 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2861 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2862 styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2863 }
2864
2865 // blurType
2866 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2867 ParseJsInt32(jsOption->GetProperty("type"), blurType);
2868 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2869 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2870 styleOption.blurType = static_cast<BlurType>(blurType);
2871 }
2872
2873 // inactiveColor
2874 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor)) {
2875 styleOption.isValidColor = true;
2876 }
2877
2878 // scale
2879 if (jsOption->GetProperty("scale")->IsNumber()) {
2880 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2881 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2882 }
2883
2884 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2885 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2886 BlurOption blurOption;
2887 ParseBlurOption(jsBlurOption, blurOption);
2888 styleOption.blurOption = blurOption;
2889 }
2890 }
2891
JsBackgroundBlurStyle(const JSCallbackInfo & info)2892 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2893 {
2894 if (info.Length() == 0) {
2895 return;
2896 }
2897 BlurStyleOption styleOption;
2898 if (info[0]->IsNumber()) {
2899 auto blurStyle = info[0]->ToNumber<int32_t>();
2900 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2901 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2902 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2903 }
2904 }
2905 if (info.Length() > 1 && info[1]->IsObject()) {
2906 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2907 ParseBlurStyleOption(jsOption, styleOption);
2908 }
2909 ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption);
2910 }
2911
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2912 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
2913 {
2914 double rate = 1.0f;
2915 if (jsOption->GetProperty("rate")->IsNumber()) {
2916 rate = jsOption->GetProperty("rate")->ToNumber<double>();
2917 }
2918 double lightUpDegree = 0.0f;
2919 if (jsOption->GetProperty("lightUpDegree")->IsNumber()) {
2920 lightUpDegree = jsOption->GetProperty("lightUpDegree")->ToNumber<double>();
2921 }
2922 double cubicCoeff = 0.0f;
2923 if (jsOption->GetProperty("cubicCoeff")->IsNumber()) {
2924 cubicCoeff = jsOption->GetProperty("cubicCoeff")->ToNumber<double>();
2925 }
2926 double quadCoeff = 0.0f;
2927 if (jsOption->GetProperty("quadCoeff")->IsNumber()) {
2928 quadCoeff = jsOption->GetProperty("quadCoeff")->ToNumber<double>();
2929 }
2930 double saturation = 1.0f;
2931 if (jsOption->GetProperty("saturation")->IsNumber()) {
2932 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2933 }
2934 std::vector<float> posRGB(3, 0.0);
2935 if (jsOption->GetProperty("posRGB")->IsArray()) {
2936 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("posRGB"));
2937 auto r = params->GetValueAt(0)->ToNumber<double>();
2938 auto g = params->GetValueAt(1)->ToNumber<double>();
2939 auto b = params->GetValueAt(2)->ToNumber<double>();
2940 posRGB[0] = r;
2941 posRGB[1] = g;
2942 posRGB[2] = b;
2943 }
2944 std::vector<float> negRGB(3, 0.0);
2945 if (jsOption->GetProperty("negRGB")->IsArray()) {
2946 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("negRGB"));
2947 auto r = params->GetValueAt(0)->ToNumber<double>();
2948 auto g = params->GetValueAt(1)->ToNumber<double>();
2949 auto b = params->GetValueAt(2)->ToNumber<double>();
2950 negRGB[0] = r;
2951 negRGB[1] = g;
2952 negRGB[2] = b;
2953 }
2954 double fraction = 1.0f;
2955 if (jsOption->GetProperty("fraction")->IsNumber()) {
2956 fraction = jsOption->GetProperty("fraction")->ToNumber<double>();
2957 fraction = std::clamp(fraction, 0.0, 1.0);
2958 }
2959 brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
2960 }
2961
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)2962 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
2963 {
2964 CalcDimension radius;
2965 if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
2966 radius.SetValue(0.0f);
2967 }
2968 effectOption.radius = radius;
2969
2970 double saturation = 1.0f;
2971 if (jsOption->GetProperty("saturation")->IsNumber()) {
2972 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2973 saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
2974 }
2975 effectOption.saturation = saturation;
2976
2977 double brightness = 1.0f;
2978 if (jsOption->GetProperty("brightness")->IsNumber()) {
2979 brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
2980 brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
2981 }
2982 effectOption.brightness = brightness;
2983
2984 ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
2985
2986 auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2987 auto adaptiveColor = AdaptiveColor::DEFAULT;
2988 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
2989 if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2990 adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2991 adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
2992 }
2993 effectOption.adaptiveColor = adaptiveColor;
2994
2995 // policy
2996 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2997 ParseJsInt32(jsOption->GetProperty("policy"), policy);
2998 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2999 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3000 effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3001 }
3002
3003 // blurType
3004 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3005 ParseJsInt32(jsOption->GetProperty("type"), blurType);
3006 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3007 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3008 effectOption.blurType = static_cast<BlurType>(blurType);
3009 }
3010
3011 // inactiveColor
3012 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
3013 effectOption.isValidColor = true;
3014 }
3015
3016 BlurOption blurOption;
3017 if (jsOption->GetProperty("blurOptions")->IsObject()) {
3018 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3019 ParseBlurOption(jsBlurOption, blurOption);
3020 effectOption.blurOption = blurOption;
3021 }
3022 }
3023
JsForegroundEffect(const JSCallbackInfo & info)3024 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
3025 {
3026 if (info.Length() == 0) {
3027 return;
3028 }
3029 float radius = 0.0;
3030 if (info[0]->IsObject()) {
3031 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3032 if (jsOption->GetProperty("radius")->IsNumber()) {
3033 radius = jsOption->GetProperty("radius")->ToNumber<float>();
3034 }
3035 }
3036 radius = std::max(radius, 0.0f);
3037 ViewAbstractModel::GetInstance()->SetForegroundEffect(radius);
3038 }
3039
JsBackgroundEffect(const JSCallbackInfo & info)3040 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
3041 {
3042 if (info.Length() == 0) {
3043 return;
3044 }
3045 EffectOption option;
3046 if (info[0]->IsObject()) {
3047 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3048 ParseEffectOption(jsOption, option);
3049 }
3050 ViewAbstractModel::GetInstance()->SetBackgroundEffect(option);
3051 }
3052
JsForegroundBlurStyle(const JSCallbackInfo & info)3053 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
3054 {
3055 if (info.Length() == 0) {
3056 return;
3057 }
3058 BlurStyleOption styleOption;
3059 if (info[0]->IsNumber()) {
3060 auto blurStyle = info[0]->ToNumber<int32_t>();
3061 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3062 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3063 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3064 }
3065 }
3066 if (info.Length() > 1 && info[1]->IsObject()) {
3067 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3068 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3069 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3070 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3071 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3072 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3073 }
3074 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3075 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3076 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3077 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3078 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3079 }
3080 if (jsOption->GetProperty("scale")->IsNumber()) {
3081 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3082 styleOption.scale = std::clamp(scale, 0.0, 1.0);
3083 }
3084
3085 if (jsOption->GetProperty("blurOptions")->IsObject()) {
3086 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3087 BlurOption blurOption;
3088 ParseBlurOption(jsBlurOption, blurOption);
3089 styleOption.blurOption = blurOption;
3090 }
3091 }
3092 ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption);
3093 }
3094
JsSphericalEffect(const JSCallbackInfo & info)3095 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
3096 {
3097 auto radio = 0.0;
3098 if (info[0]->IsNumber()) {
3099 radio = info[0]->ToNumber<double>();
3100 }
3101 ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
3102 }
3103
JsPixelStretchEffect(const JSCallbackInfo & info)3104 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
3105 {
3106 if (!info[0]->IsObject()) {
3107 PixStretchEffectOption option;
3108 option.ResetValue();
3109 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3110 return;
3111 }
3112 auto jsObject = JSRef<JSObject>::Cast(info[0]);
3113 CalcDimension left;
3114 ParseJsDimensionVp(jsObject->GetProperty("left"), left);
3115 CalcDimension right;
3116 ParseJsDimensionVp(jsObject->GetProperty("right"), right);
3117 CalcDimension top;
3118 ParseJsDimensionVp(jsObject->GetProperty("top"), top);
3119 CalcDimension bottom;
3120 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
3121
3122 PixStretchEffectOption option;
3123 bool illegalInput = false;
3124 if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
3125 top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
3126 if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
3127 (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
3128 (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
3129 (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
3130 left.SetUnit(DimensionUnit::PERCENT);
3131 top.SetUnit(DimensionUnit::PERCENT);
3132 right.SetUnit(DimensionUnit::PERCENT);
3133 bottom.SetUnit(DimensionUnit::PERCENT);
3134 } else {
3135 illegalInput = true;
3136 }
3137 }
3138 if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
3139 (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
3140 option.left = left;
3141 option.top = top;
3142 option.right = right;
3143 option.bottom = bottom;
3144 } else {
3145 illegalInput = true;
3146 }
3147 if (illegalInput) {
3148 option.ResetValue();
3149 }
3150 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3151 }
3152
JsLightUpEffect(const JSCallbackInfo & info)3153 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
3154 {
3155 auto radio = 1.0;
3156 if (info[0]->IsNumber()) {
3157 radio = info[0]->ToNumber<double>();
3158 }
3159 ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
3160 }
3161
JsBackgroundImageSize(const JSCallbackInfo & info)3162 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
3163 {
3164 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3165 BackgroundImageSize bgImgSize;
3166 auto jsVal = info[0];
3167 if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
3168 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
3169 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
3170 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3171 return;
3172 }
3173 if (jsVal->IsNumber()) {
3174 auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
3175 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3176 (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
3177 sizeType = BackgroundImageSizeType::AUTO;
3178 }
3179 bgImgSize.SetSizeTypeX(sizeType);
3180 bgImgSize.SetSizeTypeY(sizeType);
3181 } else {
3182 CalcDimension width;
3183 CalcDimension height;
3184 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3185 ParseJsDimensionVp(object->GetProperty("width"), width);
3186 ParseJsDimensionVp(object->GetProperty("height"), height);
3187 double valueWidth = width.ConvertToPx();
3188 double valueHeight = height.ConvertToPx();
3189 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
3190 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
3191 if (width.Unit() == DimensionUnit::PERCENT) {
3192 typeWidth = BackgroundImageSizeType::PERCENT;
3193 valueWidth = width.Value() * FULL_DIMENSION;
3194 }
3195 if (height.Unit() == DimensionUnit::PERCENT) {
3196 typeHeight = BackgroundImageSizeType::PERCENT;
3197 valueHeight = height.Value() * FULL_DIMENSION;
3198 }
3199 bgImgSize.SetSizeTypeX(typeWidth);
3200 bgImgSize.SetSizeValueX(valueWidth);
3201 bgImgSize.SetSizeTypeY(typeHeight);
3202 bgImgSize.SetSizeValueY(valueHeight);
3203 }
3204
3205 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3206 }
3207
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3208 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
3209 {
3210 if (align > 8 || align < 0) {
3211 return;
3212 }
3213 std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
3214 { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
3215 { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
3216 SetBgImgPosition(
3217 DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
3218 }
3219
JsBackgroundImagePosition(const JSCallbackInfo & info)3220 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
3221 {
3222 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3223 BackgroundImagePosition bgImgPosition;
3224 auto jsVal = info[0];
3225 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
3226 SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
3227 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3228 return;
3229 }
3230 if (jsVal->IsNumber()) {
3231 int32_t align = jsVal->ToNumber<int32_t>();
3232 bgImgPosition.SetIsAlign(true);
3233 SetBgImgPositionWithAlign(bgImgPosition, align);
3234 } else {
3235 CalcDimension x;
3236 CalcDimension y;
3237 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3238 ParseJsDimensionVp(object->GetProperty("x"), x);
3239 ParseJsDimensionVp(object->GetProperty("y"), y);
3240 double valueX = x.Value();
3241 double valueY = y.Value();
3242 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3243 valueX = x.ConvertToPx();
3244 valueY = y.ConvertToPx();
3245 }
3246 DimensionUnit typeX = DimensionUnit::PX;
3247 DimensionUnit typeY = DimensionUnit::PX;
3248 if (x.Unit() == DimensionUnit::PERCENT) {
3249 valueX = x.Value();
3250 typeX = DimensionUnit::PERCENT;
3251 }
3252 if (y.Unit() == DimensionUnit::PERCENT) {
3253 valueY = y.Value();
3254 typeY = DimensionUnit::PERCENT;
3255 }
3256 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
3257 }
3258
3259 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3260 }
3261
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)3262 std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
3263 {
3264 JSRef<JSVal> arg = info[optionIndex];
3265 if (!arg->IsArray()) {
3266 return std::vector<NG::OptionParam>();
3267 }
3268 auto paramArray = JSRef<JSArray>::Cast(arg);
3269 auto paramArrayLength = paramArray->Length();
3270 std::vector<NG::OptionParam> params(paramArrayLength);
3271 // parse paramArray
3272 for (size_t i = 0; i < paramArrayLength; ++i) {
3273 if (!paramArray->GetValueAt(i)->IsObject()) {
3274 return std::vector<NG::OptionParam>();
3275 }
3276 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
3277 JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
3278 params[i].value);
3279 auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
3280 if (!actionFunc->IsFunction()) {
3281 return params;
3282 }
3283 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
3284 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3285 // set onClick function
3286 params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
3287 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
3288 ACE_SCORING_EVENT("menu.action");
3289 PipelineContext::SetCallBackNode(node);
3290 if (func) {
3291 func->Execute();
3292 }
3293 };
3294 std::string iconPath;
3295 if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
3296 params[i].icon = iconPath;
3297 }
3298 if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
3299 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
3300 JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
3301 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
3302 params[i].symbol = symbolApply;
3303 }
3304 auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
3305 if (enabled->IsBoolean()) {
3306 params[i].enabled = enabled->ToBoolean();
3307 }
3308 }
3309 return params;
3310 }
3311
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3312 void ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3313 {
3314 auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
3315 NG::BorderRadiusProperty menuBorderRadius;
3316 CalcDimension borderRadius;
3317 if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) {
3318 if (borderRadius.Unit() != DimensionUnit::PERCENT && GreatOrEqual(borderRadius.Value(), 0.0f)) {
3319 menuBorderRadius.SetRadius(borderRadius);
3320 menuBorderRadius.multiValued = false;
3321 menuParam.borderRadius = menuBorderRadius;
3322 };
3323 } else if (borderRadiusValue->IsObject()) {
3324 JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
3325 CalcDimension topLeft;
3326 CalcDimension topRight;
3327 CalcDimension bottomLeft;
3328 CalcDimension bottomRight;
3329 bool hasSetBorderRadius =
3330 JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
3331 if (LessNotEqual(topLeft.Value(), 0.0f)) {
3332 topLeft.Reset();
3333 }
3334 if (LessNotEqual(topRight.Value(), 0.0f)) {
3335 topRight.Reset();
3336 }
3337 if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
3338 bottomLeft.Reset();
3339 }
3340 if (LessNotEqual(bottomRight.Value(), 0.0f)) {
3341 bottomRight.Reset();
3342 }
3343 auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
3344 menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
3345 menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight;
3346 menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
3347 menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
3348 menuBorderRadius.multiValued = true;
3349 menuParam.borderRadius = menuBorderRadius;
3350 }
3351 }
3352
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3353 void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3354 {
3355 auto enableArrowValue = menuOptions->GetProperty("enableArrow");
3356 if (enableArrowValue->IsBoolean()) {
3357 menuParam.enableArrow = enableArrowValue->ToBoolean();
3358 }
3359
3360 auto arrowOffset = menuOptions->GetProperty("arrowOffset");
3361 CalcDimension offset;
3362 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
3363 menuParam.arrowOffset = offset;
3364 }
3365
3366 // if enableArrow is true and placement not set, set placement default value to top.
3367 if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
3368 menuParam.placement = Placement::TOP;
3369 }
3370 }
3371
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)3372 void ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
3373 {
3374 CalcDimension dimension;
3375 if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
3376 return;
3377 }
3378
3379 if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
3380 calcDimension = dimension;
3381 }
3382 }
3383
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3384 void ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3385 {
3386 auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
3387 if (!marginVal->IsObject()) {
3388 return;
3389 }
3390
3391 CommonCalcDimension commonCalcDimension;
3392 auto object = JSRef<JSObject>::Cast(marginVal);
3393 ParseLayoutRegionMargin(object->GetProperty(TOP_PROPERTY), commonCalcDimension.top);
3394 ParseLayoutRegionMargin(object->GetProperty(BOTTOM_PROPERTY), commonCalcDimension.bottom);
3395 ParseLayoutRegionMargin(object->GetProperty(LEFT_PROPERTY), commonCalcDimension.left);
3396 ParseLayoutRegionMargin(object->GetProperty(RIGHT_PROPERTY), commonCalcDimension.right);
3397
3398 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3399 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3400 menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
3401 commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3402 }
3403 }
3404
GetMenuShowInSubwindow(NG::MenuParam & menuParam)3405 void GetMenuShowInSubwindow(NG::MenuParam& menuParam)
3406 {
3407 menuParam.isShowInSubWindow = false;
3408 auto pipeline = PipelineBase::GetCurrentContext();
3409 CHECK_NULL_VOID(pipeline);
3410 auto theme = pipeline->GetTheme<SelectTheme>();
3411 CHECK_NULL_VOID(theme);
3412 menuParam.isShowInSubWindow = theme->GetExpandDisplay();
3413 }
3414
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3415 void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3416 {
3417 auto offsetVal = menuOptions->GetProperty("offset");
3418 if (offsetVal->IsObject()) {
3419 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
3420 JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
3421 JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
3422 CalcDimension dx;
3423 CalcDimension dy;
3424 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
3425 menuParam.positionOffset.SetX(dx.ConvertToPx());
3426 }
3427 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
3428 menuParam.positionOffset.SetY(dy.ConvertToPx());
3429 }
3430 }
3431
3432 auto placementValue = menuOptions->GetProperty("placement");
3433 if (placementValue->IsNumber()) {
3434 auto placement = placementValue->ToNumber<int32_t>();
3435 if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
3436 menuParam.placement = PLACEMENT[placement];
3437 }
3438 }
3439
3440 auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
3441 Color backgroundColor;
3442 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
3443 menuParam.backgroundColor = backgroundColor;
3444 }
3445
3446 auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
3447 if (backgroundBlurStyle->IsNumber()) {
3448 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
3449 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3450 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3451 menuParam.backgroundBlurStyle = blurStyle;
3452 }
3453 }
3454 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3455 auto onAppearValue = menuOptions->GetProperty("onAppear");
3456 if (onAppearValue->IsFunction()) {
3457 RefPtr<JsFunction> jsOnAppearFunc =
3458 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
3459 auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
3460 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3461 ACE_SCORING_EVENT("onAppear");
3462 PipelineContext::SetCallBackNode(node);
3463 func->Execute();
3464 };
3465 menuParam.onAppear = std::move(onAppear);
3466 }
3467
3468 auto onDisappearValue = menuOptions->GetProperty("onDisappear");
3469 if (onDisappearValue->IsFunction()) {
3470 RefPtr<JsFunction> jsOnDisAppearFunc =
3471 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
3472 auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
3473 node = frameNode]() {
3474 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3475 ACE_SCORING_EVENT("onDisappear");
3476 PipelineContext::SetCallBackNode(node);
3477 func->Execute();
3478 };
3479 menuParam.onDisappear = std::move(onDisappear);
3480 }
3481 auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
3482 if (aboutToAppearValue->IsFunction()) {
3483 RefPtr<JsFunction> jsAboutToAppearFunc =
3484 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
3485 auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
3486 node = frameNode]() {
3487 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3488 ACE_SCORING_EVENT("aboutToAppear");
3489 PipelineContext::SetCallBackNode(node);
3490 func->Execute();
3491 };
3492 menuParam.aboutToAppear = std::move(aboutToAppear);
3493 }
3494
3495 auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
3496 if (aboutToDisAppearValue->IsFunction()) {
3497 RefPtr<JsFunction> jsAboutToDisAppearFunc =
3498 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
3499 auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
3500 node = frameNode]() {
3501 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3502 ACE_SCORING_EVENT("aboutToDisappear");
3503 PipelineContext::SetCallBackNode(node);
3504 func->Execute();
3505 };
3506 menuParam.aboutToDisappear = std::move(aboutToDisappear);
3507 }
3508
3509 auto menuTransition = menuOptions->GetProperty("transition");
3510 menuParam.hasTransitionEffect = false;
3511 if (menuTransition->IsObject()) {
3512 auto obj = JSRef<JSObject>::Cast(menuTransition);
3513 menuParam.hasTransitionEffect = true;
3514 menuParam.transition = ParseChainedTransition(obj, info.GetExecutionContext());
3515 }
3516
3517 JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
3518 GetMenuShowInSubwindow(menuParam);
3519 if (menuParam.isShowInSubWindow) {
3520 if (showInSubWindowValue->IsBoolean()) {
3521 menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
3522 }
3523 }
3524 ParseMenuArrowParam(menuOptions, menuParam);
3525 ParseMenuBorderRadius(menuOptions, menuParam);
3526 ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
3527 }
3528
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)3529 void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
3530 {
3531 if (!info[optionIndex]->IsObject()) {
3532 return;
3533 }
3534 auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
3535 JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
3536 ParseMenuParam(info, menuOptions, menuParam);
3537 }
3538
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)3539 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
3540 {
3541 constexpr int scaleArraySize = 2;
3542 if (scaleArray->Length() == scaleArraySize) {
3543 auto scalePropertyFrom = scaleArray->GetValueAt(0);
3544 if (scalePropertyFrom->IsNumber()) {
3545 auto scaleFrom = scalePropertyFrom->ToNumber<float>();
3546 options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
3547 }
3548 auto scalePropertyTo = scaleArray->GetValueAt(1);
3549 if (scalePropertyTo->IsNumber()) {
3550 auto scaleTo = scalePropertyTo->ToNumber<float>();
3551 options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
3552 }
3553 }
3554 }
3555
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)3556 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
3557 NG::MenuParam& menuParam)
3558 {
3559 menuParam.previewAnimationOptions.scaleFrom = -1.0f;
3560 menuParam.previewAnimationOptions.scaleTo = -1.0f;
3561
3562 auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
3563 if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
3564 auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
3565 auto scaleProperty = animationOptionsObj->GetProperty("scale");
3566 if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
3567 JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
3568 ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
3569 }
3570 auto previewTransition = animationOptionsObj->GetProperty("transition");
3571 menuParam.hasPreviewTransitionEffect = false;
3572 if (previewTransition->IsObject()) {
3573 auto obj = JSRef<JSObject>::Cast(previewTransition);
3574 menuParam.hasPreviewTransitionEffect = true;
3575 menuParam.previewTransition = ParseChainedTransition(obj, info.GetExecutionContext());
3576 }
3577 if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
3578 menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect ||
3579 menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
3580 return;
3581 }
3582 auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
3583 menuParam.isShowHoverImage = false;
3584 menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
3585 menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
3586 if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
3587 JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
3588 ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
3589 menuParam.isShowHoverImage = true;
3590 }
3591 }
3592 }
3593
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)3594 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
3595 std::function<void()>& previewBuildFunc)
3596 {
3597 if (!args->IsObject()) {
3598 return;
3599 }
3600 auto menuContentOptions = JSRef<JSObject>::Cast(args);
3601 ParseMenuParam(info, menuContentOptions, menuParam);
3602 RefPtr<JsFunction> previewBuilderFunc;
3603 auto preview = menuContentOptions->GetProperty("preview");
3604 if (!preview->IsFunction() && !preview->IsNumber()) {
3605 return;
3606 }
3607
3608 if (preview->IsNumber()) {
3609 if (preview->ToNumber<int32_t>() == 1) {
3610 menuParam.previewMode = MenuPreviewMode::IMAGE;
3611 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3612 }
3613 } else {
3614 previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
3615 CHECK_NULL_VOID(previewBuilderFunc);
3616 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3617 previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
3618 node = frameNode]() {
3619 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3620 ACE_SCORING_EVENT("BuildContextMenuPreviwer");
3621 PipelineContext::SetCallBackNode(node);
3622 func->Execute();
3623 };
3624 menuParam.previewMode = MenuPreviewMode::CUSTOM;
3625 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3626 }
3627 }
3628
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)3629 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
3630 {
3631 size_t builderIndex = 0;
3632 if (info[0]->IsBoolean()) {
3633 menuParam.isShow = info[0]->ToBoolean();
3634 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3635 menuParam.placement = Placement::BOTTOM_LEFT;
3636 builderIndex = 1;
3637 } else if (info[0]->IsObject()) {
3638 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
3639 menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3640 auto isShowObj = callbackObj->GetProperty("value");
3641 if (isShowObj->IsBoolean()) {
3642 menuParam.isShow = isShowObj->IsBoolean();
3643 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3644 builderIndex = 1;
3645 }
3646 }
3647 return builderIndex;
3648 }
3649
JsBindMenu(const JSCallbackInfo & info)3650 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
3651 {
3652 NG::MenuParam menuParam;
3653 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
3654 menuParam.placement = Placement::BOTTOM_LEFT;
3655 }
3656 size_t builderIndex = 0;
3657 GetMenuShowInSubwindow(menuParam);
3658 if (info.Length() > PARAMETER_LENGTH_FIRST) {
3659 auto jsVal = info[0];
3660 if (jsVal->IsBoolean()) {
3661 menuParam.isShow = jsVal->ToBoolean();
3662 menuParam.setShow = true;
3663 builderIndex = 1;
3664 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3665 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3666 }
3667 } else if (jsVal->IsUndefined()) {
3668 menuParam.setShow = true;
3669 menuParam.isShow = false;
3670 builderIndex = 1;
3671 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3672 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3673 }
3674 } else if (jsVal->IsObject()) {
3675 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
3676 menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3677 auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
3678 if (isShowObj->IsBoolean()) {
3679 menuParam.isShow = isShowObj->ToBoolean();
3680 menuParam.setShow = true;
3681 builderIndex = 1;
3682 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3683 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3684 }
3685 } else {
3686 builderIndex = 0;
3687 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3688 }
3689 }
3690 }
3691
3692 if (info[builderIndex]->IsArray()) {
3693 std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info, builderIndex);
3694 ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
3695 } else if (info[builderIndex]->IsObject()) {
3696 // CustomBuilder
3697 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
3698 auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
3699 if (!builder->IsFunction()) {
3700 return;
3701 }
3702 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
3703
3704 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3705 CHECK_NULL_VOID(builderFunc);
3706 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
3707 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3708 ACE_SCORING_EVENT("BuildMenu");
3709 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3710 func->Execute();
3711 };
3712 ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
3713 }
3714 }
3715
JsPadding(const JSCallbackInfo & info)3716 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
3717 {
3718 ParseMarginOrPadding(info, EdgeType::PADDING);
3719 }
3720
JsMargin(const JSCallbackInfo & info)3721 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
3722 {
3723 ParseMarginOrPadding(info, EdgeType::MARGIN);
3724 }
3725
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)3726 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
3727 {
3728 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3729 JSCallbackInfoType::NUMBER };
3730 auto jsVal = info[0];
3731 if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
3732 auto resetDimension = CalcDimension(0.0);
3733 if (type == EdgeType::MARGIN) {
3734 ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
3735 } else if (type == EdgeType::PADDING) {
3736 ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
3737 } else if (type == EdgeType::SAFE_AREA_PADDING) {
3738 ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
3739 }
3740 return;
3741 }
3742
3743 if (jsVal->IsObject()) {
3744 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
3745
3746 CalcDimension length;
3747 if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
3748 ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
3749 return;
3750 }
3751
3752 CommonCalcDimension commonCalcDimension;
3753 auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
3754 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3755 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3756 if (type == EdgeType::MARGIN) {
3757 if (useLengthMetrics) {
3758 ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
3759 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3760 } else {
3761 ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
3762 commonCalcDimension.left, commonCalcDimension.right);
3763 }
3764 } else if (type == EdgeType::PADDING) {
3765 if (useLengthMetrics) {
3766 ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
3767 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3768 } else {
3769 ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
3770 commonCalcDimension.left, commonCalcDimension.right);
3771 }
3772 } else if (type == EdgeType::SAFE_AREA_PADDING) {
3773 if (useLengthMetrics) {
3774 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
3775 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3776 } else {
3777 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
3778 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3779 }
3780 }
3781 return;
3782 }
3783 }
3784
3785 CalcDimension length;
3786 if (!ParseJsDimensionVp(jsVal, length)) {
3787 // use default value.
3788 length.Reset();
3789 }
3790 if (type == EdgeType::MARGIN) {
3791 ViewAbstractModel::GetInstance()->SetMargin(length);
3792 } else if (type == EdgeType::PADDING) {
3793 ViewAbstractModel::GetInstance()->SetPadding(length);
3794 }
3795 }
3796
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)3797 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
3798 const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
3799 const std::optional<CalcDimension>& end)
3800 {
3801 NG::PaddingProperty paddings;
3802 if (start.has_value()) {
3803 if (start.value().Unit() == DimensionUnit::CALC) {
3804 paddings.start = NG::CalcLength(start.value().CalcValue());
3805 } else {
3806 paddings.start = NG::CalcLength(start.value());
3807 }
3808 }
3809 if (bottom.has_value()) {
3810 if (bottom.value().Unit() == DimensionUnit::CALC) {
3811 paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
3812 } else {
3813 paddings.bottom = NG::CalcLength(bottom.value());
3814 }
3815 }
3816 if (end.has_value()) {
3817 if (end.value().Unit() == DimensionUnit::CALC) {
3818 paddings.end = NG::CalcLength(end.value().CalcValue());
3819 } else {
3820 paddings.end = NG::CalcLength(end.value());
3821 }
3822 }
3823 if (top.has_value()) {
3824 if (top.value().Unit() == DimensionUnit::CALC) {
3825 paddings.top = NG::CalcLength(top.value().CalcValue());
3826 } else {
3827 paddings.top = NG::CalcLength(top.value());
3828 }
3829 }
3830 return paddings;
3831 }
3832
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)3833 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
3834 std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
3835 {
3836 CalcDimension leftDimen;
3837 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
3838 left = leftDimen;
3839 }
3840 CalcDimension rightDimen;
3841 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
3842 right = rightDimen;
3843 }
3844 CalcDimension topDimen;
3845 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
3846 top = topDimen;
3847 }
3848 CalcDimension bottomDimen;
3849 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
3850 bottom = bottomDimen;
3851 }
3852 }
3853
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3854 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
3855 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3856 {
3857 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
3858 if (jsStart->IsObject()) {
3859 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
3860 CalcDimension calcDimension;
3861 if (ParseJsLengthMetrics(startObj, calcDimension)) {
3862 localizedCalcDimension.start = calcDimension;
3863 }
3864 }
3865 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
3866 if (jsEnd->IsObject()) {
3867 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
3868 CalcDimension calcDimension;
3869 if (ParseJsLengthMetrics(endObj, calcDimension)) {
3870 localizedCalcDimension.end = calcDimension;
3871 }
3872 }
3873 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3874 if (jsTop->IsObject()) {
3875 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
3876 CalcDimension calcDimension;
3877 if (ParseJsLengthMetrics(topObj, calcDimension)) {
3878 localizedCalcDimension.top = calcDimension;
3879 }
3880 }
3881 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3882 if (jsBottom->IsObject()) {
3883 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
3884 CalcDimension calcDimension;
3885 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
3886 localizedCalcDimension.bottom = calcDimension;
3887 }
3888 }
3889 }
3890
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3891 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
3892 const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
3893 {
3894 if (CheckLengthMetrics(object)) {
3895 LocalizedCalcDimension localizedCalcDimension;
3896 ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
3897 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
3898 commonCalcDimension.top = localizedCalcDimension.top;
3899 commonCalcDimension.bottom = localizedCalcDimension.bottom;
3900 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
3901 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
3902 return true;
3903 }
3904 ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
3905 commonCalcDimension.right);
3906 return false;
3907 }
3908
JsOutline(const JSCallbackInfo & info)3909 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
3910 {
3911 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3912 auto jsVal = info[0];
3913 if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
3914 CalcDimension borderWidth;
3915 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3916 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3917 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
3918 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3919 return;
3920 }
3921 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3922 auto valueOuterWidth = object->GetProperty("width");
3923 if (!valueOuterWidth->IsUndefined()) {
3924 ParseOuterBorderWidth(valueOuterWidth);
3925 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3926 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3927 }
3928
3929 // use default value when undefined.
3930 ParseOuterBorderColor(object->GetProperty("color"));
3931
3932 auto valueOuterRadius = object->GetProperty("radius");
3933 if (!valueOuterRadius->IsUndefined()) {
3934 ParseOuterBorderRadius(valueOuterRadius);
3935 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3936 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3937 }
3938 // use default value when undefined.
3939 ParseOuterBorderStyle(object->GetProperty("style"));
3940 info.ReturnSelf();
3941 }
3942
JsOutlineWidth(const JSCallbackInfo & info)3943 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
3944 {
3945 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3946 JSCallbackInfoType::OBJECT };
3947 auto jsVal = info[0];
3948 if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
3949 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3950 return;
3951 }
3952 ParseOuterBorderWidth(jsVal);
3953 }
3954
JsOutlineColor(const JSCallbackInfo & info)3955 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
3956 {
3957 ParseOuterBorderColor(info[0]);
3958 }
3959
JsOutlineRadius(const JSCallbackInfo & info)3960 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
3961 {
3962 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3963 JSCallbackInfoType::OBJECT };
3964 auto jsVal = info[0];
3965 if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
3966 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3967 return;
3968 }
3969 ParseOuterBorderRadius(jsVal);
3970 }
3971
JsOutlineStyle(const JSCallbackInfo & info)3972 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
3973 {
3974 ParseOuterBorderStyle(info[0]);
3975 }
3976
JsBorder(const JSCallbackInfo & info)3977 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
3978 {
3979 if (!info[0]->IsObject()) {
3980 CalcDimension borderWidth;
3981 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3982 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3983 ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
3984 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3985 ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
3986 ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
3987 return;
3988 }
3989 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
3990
3991 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
3992 if (!valueWidth->IsUndefined()) {
3993 ParseBorderWidth(valueWidth);
3994 }
3995
3996 // use default value when undefined.
3997 ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
3998
3999 auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
4000 if (!valueRadius->IsUndefined()) {
4001 ParseBorderRadius(valueRadius);
4002 }
4003 // use default value when undefined.
4004 ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
4005
4006 auto dashGap = object->GetProperty("dashGap");
4007 if (!dashGap->IsUndefined()) {
4008 ParseDashGap(dashGap);
4009 }
4010 auto dashWidth = object->GetProperty("dashWidth");
4011 if (!dashWidth->IsUndefined()) {
4012 ParseDashWidth(dashWidth);
4013 }
4014
4015 info.ReturnSelf();
4016 }
4017
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)4018 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
4019 {
4020 if (!args->IsObject()) {
4021 return false;
4022 }
4023 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4024 if (obj->IsUndefined()) {
4025 return true;
4026 }
4027 // filter dynamic $r raw input
4028 if (obj->HasProperty("id")) {
4029 return false;
4030 }
4031 if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
4032 (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
4033 (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
4034 (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
4035 (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
4036 (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
4037 return true;
4038 }
4039
4040 return false;
4041 }
4042
JsBorderWidth(const JSCallbackInfo & info)4043 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
4044 {
4045 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4046 JSCallbackInfoType::OBJECT };
4047 auto jsVal = info[0];
4048 if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
4049 ViewAbstractModel::GetInstance()->SetBorderWidth({});
4050 return;
4051 }
4052 ParseBorderWidth(jsVal);
4053 }
4054
ParseBorderWidth(const JSRef<JSVal> & args)4055 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
4056 {
4057 CalcDimension borderWidth;
4058 if (ParseJsDimensionVp(args, borderWidth)) {
4059 if (borderWidth.IsNegative()) {
4060 borderWidth.Reset();
4061 }
4062 if (borderWidth.Unit() == DimensionUnit::PERCENT) {
4063 borderWidth.Reset();
4064 }
4065 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4066 } else if (args->IsObject()) {
4067 if (IsBorderWidthObjUndefined(args)) {
4068 ViewAbstractModel::GetInstance()->SetBorderWidth({});
4069 return;
4070 }
4071 CommonCalcDimension commonCalcDimension;
4072 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4073 if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
4074 ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
4075 commonCalcDimension.top, commonCalcDimension.bottom, true);
4076 return;
4077 }
4078 ViewAbstractModel::GetInstance()->SetBorderWidth(
4079 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4080 } else {
4081 return;
4082 }
4083 }
4084
ParseDashGap(const JSRef<JSVal> & args)4085 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
4086 {
4087 CalcDimension dashGap;
4088 if (ParseLengthMetricsToDimension(args, dashGap)) {
4089 if (dashGap.Unit() == DimensionUnit::PERCENT) {
4090 dashGap.Reset();
4091 }
4092 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4093 } else if (args->IsObject()) {
4094 CommonCalcDimension commonCalcDimension;
4095 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4096 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4097 ViewAbstractModel::GetInstance()->SetDashGap(
4098 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4099 } else {
4100 dashGap.Reset();
4101 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4102 }
4103 }
4104
ParseDashWidth(const JSRef<JSVal> & args)4105 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
4106 {
4107 CalcDimension dashWidth;
4108 if (ParseLengthMetricsToDimension(args, dashWidth)) {
4109 if (dashWidth.Unit() == DimensionUnit::PERCENT) {
4110 dashWidth.Reset();
4111 }
4112 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4113 } else if (args->IsObject()) {
4114 CommonCalcDimension commonCalcDimension;
4115 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4116 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4117 ViewAbstractModel::GetInstance()->SetDashWidth(
4118 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4119 } else {
4120 dashWidth.Reset();
4121 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4122 }
4123 }
4124
ParseOuterBorderWidth(const JSRef<JSVal> & args)4125 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
4126 {
4127 CalcDimension borderWidth;
4128 if (ParseJsDimensionVp(args, borderWidth)) {
4129 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4130 borderWidth.Reset();
4131 }
4132 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4133 } else if (args->IsObject()) {
4134 std::optional<CalcDimension> leftDimen;
4135 std::optional<CalcDimension> rightDimen;
4136 std::optional<CalcDimension> topDimen;
4137 std::optional<CalcDimension> bottomDimen;
4138 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4139 CalcDimension left;
4140 if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
4141 if (left.Unit() == DimensionUnit::PERCENT) {
4142 left.Reset();
4143 }
4144 leftDimen = left;
4145 }
4146 CalcDimension right;
4147 if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
4148 if (right.Unit() == DimensionUnit::PERCENT) {
4149 right.Reset();
4150 }
4151 rightDimen = right;
4152 }
4153 CalcDimension top;
4154 if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
4155 if (top.Unit() == DimensionUnit::PERCENT) {
4156 top.Reset();
4157 }
4158 topDimen = top;
4159 }
4160 CalcDimension bottom;
4161 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
4162 if (bottom.Unit() == DimensionUnit::PERCENT) {
4163 bottom.Reset();
4164 }
4165 bottomDimen = bottom;
4166 }
4167 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
4168 } else {
4169 return;
4170 }
4171 }
4172
JsBorderImage(const JSCallbackInfo & info)4173 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
4174 {
4175 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4176 auto jsVal = info[0];
4177 if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
4178 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4179 uint8_t imageBorderBitsets = 0;
4180 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4181 return;
4182 }
4183 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4184 CHECK_NULL_VOID(!object->IsEmpty());
4185
4186 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4187 uint8_t imageBorderBitsets = 0;
4188
4189 auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
4190 CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
4191 std::string srcResult;
4192 std::string bundleName;
4193 std::string moduleName;
4194 GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
4195 borderImage->SetBundleName(bundleName);
4196 borderImage->SetModuleName(moduleName);
4197 if (valueSource->IsString() && !valueSource->ToString().empty()) {
4198 borderImage->SetSrc(valueSource->ToString());
4199 imageBorderBitsets |= BorderImage::SOURCE_BIT;
4200 } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
4201 borderImage->SetSrc(srcResult);
4202 imageBorderBitsets |= BorderImage::SOURCE_BIT;
4203 } else if (valueSource->IsObject()) {
4204 ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
4205 }
4206 auto valueOutset = object->GetProperty("outset");
4207 if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
4208 imageBorderBitsets |= BorderImage::OUTSET_BIT;
4209 ParseBorderImageOutset(valueOutset, borderImage);
4210 }
4211 auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
4212 if (!valueRepeat->IsNull()) {
4213 imageBorderBitsets |= BorderImage::REPEAT_BIT;
4214 ParseBorderImageRepeat(valueRepeat, borderImage);
4215 }
4216 auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
4217 if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
4218 imageBorderBitsets |= BorderImage::SLICE_BIT;
4219 ParseBorderImageSlice(valueSlice, borderImage);
4220 }
4221 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4222 if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
4223 imageBorderBitsets |= BorderImage::WIDTH_BIT;
4224 ParseBorderImageWidth(valueWidth, borderImage);
4225 }
4226 auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
4227 if (needFill->IsBoolean()) {
4228 borderImage->SetNeedFillCenter(needFill->ToBoolean());
4229 }
4230 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4231 info.ReturnSelf();
4232 }
4233
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4234 bool JSViewAbstract::ParseBorderImageDimension(
4235 const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
4236 {
4237 if (!args->IsObject()) {
4238 return false;
4239 }
4240 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4241 if (CheckLengthMetrics(object)) {
4242 LocalizedCalcDimension localizedCalcDimension;
4243 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4244 borderImageDimension.topDimension = localizedCalcDimension.top;
4245 borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
4246 borderImageDimension.startDimension = localizedCalcDimension.start;
4247 borderImageDimension.endDimension = localizedCalcDimension.end;
4248 return true;
4249 }
4250 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4251 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4252 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4253 for (uint32_t i = 0; i < keys.size(); i++) {
4254 CalcDimension currentDimension;
4255 auto dimensionValue = object->GetProperty(keys.at(i));
4256 if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
4257 auto direction = static_cast<BorderImageDirection>(i);
4258 switch (direction) {
4259 case BorderImageDirection::LEFT:
4260 borderImageDimension.leftDimension = currentDimension;
4261 break;
4262 case BorderImageDirection::RIGHT:
4263 borderImageDimension.rightDimension = currentDimension;
4264 break;
4265 case BorderImageDirection::TOP:
4266 borderImageDimension.topDimension = currentDimension;
4267 break;
4268 case BorderImageDirection::BOTTOM:
4269 borderImageDimension.bottomDimension = currentDimension;
4270 break;
4271 default:
4272 break;
4273 }
4274 }
4275 }
4276 return false;
4277 }
4278
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4279 void JSViewAbstract::ParseBorderImageLengthMetrics(
4280 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4281 {
4282 for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
4283 auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
4284 if (!jsVal->IsObject()) {
4285 continue;
4286 }
4287 JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
4288 CalcDimension calcDimension;
4289 if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
4290 auto direction = static_cast<BorderImageDirection>(i);
4291 switch (direction) {
4292 case BorderImageDirection::LEFT:
4293 localizedCalcDimension.start = calcDimension;
4294 break;
4295 case BorderImageDirection::RIGHT:
4296 localizedCalcDimension.end = calcDimension;
4297 break;
4298 case BorderImageDirection::TOP:
4299 localizedCalcDimension.top = calcDimension;
4300 break;
4301 case BorderImageDirection::BOTTOM:
4302 localizedCalcDimension.bottom = calcDimension;
4303 break;
4304 default:
4305 break;
4306 }
4307 }
4308 }
4309 }
4310
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4311 bool JSViewAbstract::CheckJSCallbackInfo(
4312 const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
4313 {
4314 bool typeVerified = false;
4315 std::string unrecognizedType;
4316 for (const auto& infoType : infoTypes) {
4317 switch (infoType) {
4318 case JSCallbackInfoType::STRING:
4319 if (tmpInfo->IsString()) {
4320 typeVerified = true;
4321 } else {
4322 unrecognizedType += "string|";
4323 }
4324 break;
4325 case JSCallbackInfoType::NUMBER:
4326 if (tmpInfo->IsNumber()) {
4327 typeVerified = true;
4328 } else {
4329 unrecognizedType += "number|";
4330 }
4331 break;
4332 case JSCallbackInfoType::OBJECT:
4333 if (tmpInfo->IsObject()) {
4334 typeVerified = true;
4335 } else {
4336 unrecognizedType += "object|";
4337 }
4338 break;
4339 case JSCallbackInfoType::FUNCTION:
4340 if (tmpInfo->IsFunction()) {
4341 typeVerified = true;
4342 } else {
4343 unrecognizedType += "Function|";
4344 }
4345 break;
4346 default:
4347 break;
4348 }
4349 }
4350 if (!typeVerified) {
4351 LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
4352 unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
4353 }
4354 return typeVerified || infoTypes.size() == 0;
4355 }
4356
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4357 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
4358 {
4359 switch (direction) {
4360 case NG::GradientDirection::LEFT:
4361 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4362 break;
4363 case NG::GradientDirection::RIGHT:
4364 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4365 break;
4366 case NG::GradientDirection::TOP:
4367 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4368 break;
4369 case NG::GradientDirection::BOTTOM:
4370 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4371 break;
4372 case NG::GradientDirection::LEFT_TOP:
4373 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4374 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4375 break;
4376 case NG::GradientDirection::LEFT_BOTTOM:
4377 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4378 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4379 break;
4380 case NG::GradientDirection::RIGHT_TOP:
4381 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4382 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4383 break;
4384 case NG::GradientDirection::RIGHT_BOTTOM:
4385 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4386 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4387 break;
4388 case NG::GradientDirection::NONE:
4389 case NG::GradientDirection::START_TO_END:
4390 case NG::GradientDirection::END_TO_START:
4391 default:
4392 break;
4393 }
4394 }
4395
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)4396 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
4397 {
4398 if (!args->IsObject()) {
4399 return;
4400 }
4401 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
4402 NG::Gradient lineGradient;
4403 lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
4404 // angle
4405 std::optional<float> degree;
4406 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4407 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
4408 } else {
4409 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
4410 }
4411 if (degree) {
4412 lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
4413 degree.reset();
4414 }
4415 // direction
4416 auto direction = static_cast<NG::GradientDirection>(
4417 jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
4418 static_cast<int32_t>(NG::GradientDirection::NONE)));
4419 UpdateGradientWithDirection(lineGradient, direction);
4420 auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
4421 lineGradient.SetRepeat(repeating);
4422 NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
4423 ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
4424 bitset |= BorderImage::GRADIENT_BIT;
4425 }
4426
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4427 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4428 {
4429 auto repeatString = args->ToString();
4430 if (repeatString == "Repeat") {
4431 borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
4432 } else if (repeatString == "Round") {
4433 borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
4434 } else if (repeatString == "Space") {
4435 borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
4436 } else {
4437 borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
4438 }
4439 }
4440
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4441 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4442 {
4443 CalcDimension outsetDimension;
4444 if (ParseJsDimensionVp(args, outsetDimension)) {
4445 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
4446 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
4447 borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
4448 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
4449 return;
4450 }
4451 BorderImage::BorderImageOption option;
4452 ParseBorderImageDimension(args, option);
4453 if (option.startDimension.has_value()) {
4454 borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
4455 }
4456 if (option.endDimension.has_value()) {
4457 borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
4458 }
4459 if (option.leftDimension.has_value()) {
4460 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
4461 }
4462 if (option.rightDimension.has_value()) {
4463 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
4464 }
4465 if (option.topDimension.has_value()) {
4466 borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
4467 }
4468 if (option.bottomDimension.has_value()) {
4469 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4470 }
4471 }
4472
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4473 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4474 {
4475 CalcDimension sliceDimension;
4476 if (ParseJsDimensionVp(args, sliceDimension)) {
4477 borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
4478 borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
4479 borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
4480 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
4481 return;
4482 }
4483 if (!args->IsObject()) {
4484 return;
4485 }
4486 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4487 if (CheckLengthMetrics(object)) {
4488 LocalizedCalcDimension localizedCalcDimension;
4489 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4490 if (localizedCalcDimension.top.has_value()) {
4491 borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
4492 }
4493 if (localizedCalcDimension.bottom.has_value()) {
4494 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
4495 }
4496 if (localizedCalcDimension.start.has_value()) {
4497 borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
4498 }
4499 if (localizedCalcDimension.end.has_value()) {
4500 borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
4501 }
4502 return;
4503 }
4504 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4505 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4506 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4507 for (uint32_t i = 0; i < keys.size(); i++) {
4508 auto dimensionValue = object->GetProperty(keys.at(i));
4509 if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
4510 borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
4511 }
4512 }
4513 }
4514
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4515 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4516 {
4517 CalcDimension widthDimension;
4518 if (ParseJsDimensionVp(args, widthDimension)) {
4519 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
4520 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
4521 borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
4522 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
4523 return;
4524 }
4525
4526 BorderImage::BorderImageOption option;
4527 ParseBorderImageDimension(args, option);
4528 if (option.startDimension.has_value()) {
4529 borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
4530 }
4531 if (option.endDimension.has_value()) {
4532 borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
4533 }
4534 if (option.leftDimension.has_value()) {
4535 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
4536 }
4537 if (option.rightDimension.has_value()) {
4538 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
4539 }
4540 if (option.topDimension.has_value()) {
4541 borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
4542 }
4543 if (option.bottomDimension.has_value()) {
4544 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4545 }
4546 }
4547
JsBorderColor(const JSCallbackInfo & info)4548 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
4549 {
4550 ParseBorderColor(info[0]);
4551 }
4552
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)4553 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
4554 const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
4555 const std::optional<Color>& colorBottom)
4556 {
4557 NG::BorderColorProperty borderColors;
4558 borderColors.startColor = colorStart;
4559 borderColors.endColor = colorEnd;
4560 borderColors.topColor = colorTop;
4561 borderColors.bottomColor = colorBottom;
4562 borderColors.multiValued = true;
4563 return borderColors;
4564 }
4565
ParseBorderColor(const JSRef<JSVal> & args)4566 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
4567 {
4568 Color borderColor;
4569 if (ParseJsColor(args, borderColor)) {
4570 ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
4571 } else if (args->IsObject()) {
4572 CommonColor commonColor;
4573 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4574 if (ParseCommonEdgeColors(object, commonColor)) {
4575 ViewAbstractModel::GetInstance()->SetBorderColor(
4576 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4577 return;
4578 }
4579 ViewAbstractModel::GetInstance()->SetBorderColor(
4580 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4581 } else {
4582 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4583 }
4584 }
4585
ParseOuterBorderColor(const JSRef<JSVal> & args)4586 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
4587 {
4588 Color borderColor;
4589 if (ParseJsColor(args, borderColor)) {
4590 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
4591 } else if (args->IsObject()) {
4592 CommonColor commonColor;
4593 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4594 if (ParseCommonEdgeColors(object, commonColor)) {
4595 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4596 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4597 return;
4598 }
4599 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4600 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4601 } else {
4602 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
4603 }
4604 }
4605
JsBorderRadius(const JSCallbackInfo & info)4606 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
4607 {
4608 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4609 JSCallbackInfoType::OBJECT };
4610 auto jsVal = info[0];
4611 if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
4612 ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
4613 return;
4614 }
4615 ParseBorderRadius(jsVal);
4616 }
4617
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)4618 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
4619 const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
4620 const std::optional<Dimension>& radiusBottomEnd)
4621 {
4622 NG::BorderRadiusProperty borderRadius;
4623 borderRadius.radiusTopStart = radiusTopStart;
4624 borderRadius.radiusTopEnd = radiusTopEnd;
4625 borderRadius.radiusBottomStart = radiusBottomStart;
4626 borderRadius.radiusBottomEnd = radiusBottomEnd;
4627 borderRadius.multiValued = true;
4628 return borderRadius;
4629 }
4630
ParseBorderRadius(const JSRef<JSVal> & args)4631 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
4632 {
4633 CalcDimension borderRadius;
4634 if (ParseJsDimensionVp(args, borderRadius)) {
4635 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
4636 } else if (args->IsObject()) {
4637 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4638 CalcDimension topLeft;
4639 CalcDimension topRight;
4640 CalcDimension bottomLeft;
4641 CalcDimension bottomRight;
4642 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4643 ViewAbstractModel::GetInstance()->SetBorderRadius(
4644 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4645 return;
4646 }
4647 ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4648 }
4649 }
4650
ParseOuterBorderRadius(const JSRef<JSVal> & args)4651 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
4652 {
4653 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
4654 return;
4655 }
4656 CalcDimension borderRadius;
4657 if (ParseJsDimensionVp(args, borderRadius)) {
4658 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
4659 borderRadius.Reset();
4660 }
4661 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
4662 } else if (args->IsObject()) {
4663 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4664 CalcDimension topLeft;
4665 CalcDimension topRight;
4666 CalcDimension bottomLeft;
4667 CalcDimension bottomRight;
4668 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4669 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
4670 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4671 }
4672 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4673 }
4674 }
4675
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4676 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4677 {
4678 ParseJsDimensionVp(object->GetProperty(key), radius);
4679 }
4680
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4681 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4682 {
4683 if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
4684 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
4685 ParseJsLengthMetrics(startObj, radius);
4686 }
4687 }
4688
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)4689 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
4690 CalcDimension& bottomLeft, CalcDimension& bottomRight)
4691 {
4692 if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
4693 object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
4694 CalcDimension topStart;
4695 CalcDimension topEnd;
4696 CalcDimension bottomStart;
4697 CalcDimension bottomEnd;
4698 GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
4699 GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
4700 GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
4701 GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
4702 topLeft = topStart;
4703 topRight = topEnd;
4704 bottomLeft = bottomStart;
4705 bottomRight = bottomEnd;
4706 return true;
4707 }
4708 GetBorderRadius("topLeft", object, topLeft);
4709 GetBorderRadius("topRight", object, topRight);
4710 GetBorderRadius("bottomLeft", object, bottomLeft);
4711 GetBorderRadius("bottomRight", object, bottomRight);
4712 return false;
4713 }
4714
JsBorderStyle(const JSCallbackInfo & info)4715 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
4716 {
4717 ParseBorderStyle(info[0]);
4718 }
4719 namespace {
ConvertBorderStyle(int32_t value)4720 BorderStyle ConvertBorderStyle(int32_t value)
4721 {
4722 auto style = static_cast<BorderStyle>(value);
4723 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4724 style = BorderStyle::SOLID;
4725 }
4726 return style;
4727 }
4728
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)4729 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
4730 {
4731 style = static_cast<BorderStyle>(value);
4732 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4733 return false;
4734 }
4735 return true;
4736 }
4737 } // namespace
4738
ParseBorderStyle(const JSRef<JSVal> & args)4739 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
4740 {
4741 if (args->IsObject()) {
4742 std::optional<BorderStyle> styleLeft;
4743 std::optional<BorderStyle> styleRight;
4744 std::optional<BorderStyle> styleTop;
4745 std::optional<BorderStyle> styleBottom;
4746 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4747 auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
4748 if (leftValue->IsNumber()) {
4749 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4750 }
4751 auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
4752 if (rightValue->IsNumber()) {
4753 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4754 }
4755 auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
4756 if (topValue->IsNumber()) {
4757 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4758 }
4759 auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
4760 if (bottomValue->IsNumber()) {
4761 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4762 }
4763 ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4764 return;
4765 }
4766 if (args->IsNumber()) {
4767 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4768 ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
4769 return;
4770 }
4771 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4772 }
4773
ParseOuterBorderStyle(const JSRef<JSVal> & args)4774 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
4775 {
4776 if (!args->IsObject() && !args->IsNumber()) {
4777 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
4778 return;
4779 }
4780 if (args->IsObject()) {
4781 std::optional<BorderStyle> styleLeft;
4782 std::optional<BorderStyle> styleRight;
4783 std::optional<BorderStyle> styleTop;
4784 std::optional<BorderStyle> styleBottom;
4785 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4786 auto leftValue = object->GetProperty("left");
4787 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
4788 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4789 }
4790 auto rightValue = object->GetProperty("right");
4791 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
4792 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4793 }
4794 auto topValue = object->GetProperty("top");
4795 if (!topValue->IsUndefined() && topValue->IsNumber()) {
4796 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4797 }
4798 auto bottomValue = object->GetProperty("bottom");
4799 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
4800 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4801 }
4802 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4803 return;
4804 }
4805 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4806 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
4807 }
4808
JsBlur(const JSCallbackInfo & info)4809 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
4810 {
4811 if (info.Length() == 0) {
4812 return;
4813 }
4814 double blur = 0.0;
4815 if (!ParseJsDouble(info[0], blur)) {
4816 return;
4817 }
4818
4819 BlurOption blurOption;
4820 if (info.Length() > 1 && info[1]->IsObject()) {
4821 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4822 ParseBlurOption(jsBlurOption, blurOption);
4823 }
4824 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4825 ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption);
4826 info.SetReturnValue(info.This());
4827 }
4828
JsMotionBlur(const JSCallbackInfo & info)4829 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
4830 {
4831 if (!info[0]->IsObject()) {
4832 return;
4833 }
4834 MotionBlurOption option;
4835 double x = 0.0;
4836 double y = 0.0;
4837 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4838 JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
4839 if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
4840 JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
4841 ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
4842 ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
4843 }
4844 double radius = 0.0;
4845 if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
4846 radius = 0.0;
4847 }
4848 if (LessNotEqual(x, 0.0)) {
4849 x = 0.0;
4850 }
4851 if (LessNotEqual(y, 0.0)) {
4852 y = 0.0;
4853 }
4854 option.radius = radius;
4855 option.anchor.x = std::clamp(x, 0.0, 1.0);
4856 option.anchor.y = std::clamp(y, 0.0, 1.0);
4857 ViewAbstractModel::GetInstance()->SetMotionBlur(option);
4858 }
4859
JsColorBlend(const JSCallbackInfo & info)4860 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
4861 {
4862 Color colorBlend;
4863 if (info[0]->IsUndefined()) {
4864 colorBlend = Color::TRANSPARENT;
4865 SetColorBlend(colorBlend);
4866 return;
4867 }
4868 if (!ParseJsColor(info[0], colorBlend)) {
4869 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4870 colorBlend = Color::TRANSPARENT;
4871 SetColorBlend(colorBlend);
4872 }
4873 return;
4874 }
4875 SetColorBlend(colorBlend);
4876 info.SetReturnValue(info.This());
4877 }
4878
JsUseEffect(const JSCallbackInfo & info)4879 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
4880 {
4881 if (info[0]->IsBoolean()) {
4882 auto effectType = EffectType::DEFAULT;
4883 if (info.Length() == 2 && info[1]->IsNumber()) {
4884 effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
4885 if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
4886 effectType = EffectType::DEFAULT;
4887 }
4888 }
4889 ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
4890 }
4891 }
4892
JsUseShadowBatching(const JSCallbackInfo & info)4893 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
4894 {
4895 if (info[0]->IsBoolean()) {
4896 ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
4897 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4898 ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
4899 }
4900 }
4901
JsBackdropBlur(const JSCallbackInfo & info)4902 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
4903 {
4904 if (info.Length() == 0) {
4905 return;
4906 }
4907 double blur = 0.0;
4908 BlurOption blurOption;
4909 if (!ParseJsDouble(info[0], blur)) {
4910 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4911 return;
4912 }
4913 }
4914 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4915 if (info.Length() > 1 && info[1]->IsObject()) {
4916 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4917 ParseBlurOption(jsBlurOption, blurOption);
4918 }
4919 ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption);
4920 info.SetReturnValue(info.This());
4921 }
4922
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4923 void JSViewAbstract::GetFractionStops(
4924 std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
4925 {
4926 if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
4927 return;
4928 }
4929 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
4930 float tmpPos = -1.0f;
4931 size_t length = jsArray->Length();
4932 for (size_t i = 0; i < length; i++) {
4933 std::pair<float, float> fractionStop;
4934 JSRef<JSVal> item = jsArray->GetValueAt(i);
4935 if (!item->IsArray()) {
4936 continue;
4937 }
4938 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
4939 if (subArray->Length() < 2) {
4940 continue;
4941 }
4942
4943 double value = 0.0;
4944 if (ParseJsDouble(subArray->GetValueAt(0), value)) {
4945 value = std::clamp(value, 0.0, 1.0);
4946 fractionStop.first = static_cast<float>(value);
4947 }
4948 value = 0.0;
4949 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
4950 value = std::clamp(value, 0.0, 1.0);
4951 fractionStop.second = static_cast<float>(value);
4952 }
4953
4954 if (fractionStop.second <= tmpPos) {
4955 fractionStops.clear();
4956 return;
4957 }
4958 tmpPos = fractionStop.second;
4959 fractionStops.push_back(fractionStop);
4960 }
4961 }
JsLinearGradientBlur(const JSCallbackInfo & info)4962 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
4963 {
4964 if (info.Length() < 2) { // 2 represents the least para num;
4965 return;
4966 }
4967 double blurRadius = 0.0;
4968 ParseJsDouble(info[0], blurRadius);
4969
4970 std::vector<std::pair<float, float>> fractionStops;
4971 auto direction = GradientDirection::BOTTOM;
4972 if (info[1]->IsObject()) {
4973 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
4974 GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
4975 auto directionValue =
4976 jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
4977 if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
4978 directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
4979 directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
4980 }
4981 direction = static_cast<GradientDirection>(directionValue);
4982 }
4983 if (static_cast<int32_t>(fractionStops.size()) <= 1) {
4984 fractionStops.clear();
4985 fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
4986 fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
4987 }
4988 // Parse direction
4989 CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
4990 NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
4991 SetLinearGradientBlur(blurPara);
4992 }
4993
JsBackgroundBrightness(const JSCallbackInfo & info)4994 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
4995 {
4996 double rate = 0.0;
4997 double lightUpDegree = 0.0;
4998 if (info[0]->IsObject()) {
4999 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5000 ParseJsDouble(jsObj->GetProperty("rate"), rate);
5001 ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
5002 }
5003 SetDynamicLightUp(rate, lightUpDegree);
5004 }
5005
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)5006 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
5007 {
5008 if (info.Length() == 0) {
5009 return;
5010 }
5011 BrightnessOption option;
5012 if (info[0]->IsObject()) {
5013 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5014 ParseBrightnessOption(jsOption, option);
5015 }
5016 SetBgDynamicBrightness(option);
5017 }
5018
JsForegroundBrightness(const JSCallbackInfo & info)5019 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
5020 {
5021 if (info.Length() == 0) {
5022 return;
5023 }
5024 BrightnessOption option;
5025 if (info[0]->IsObject()) {
5026 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5027 ParseBrightnessOption(jsOption, option);
5028 }
5029 SetFgDynamicBrightness(option);
5030 }
5031
JsWindowBlur(const JSCallbackInfo & info)5032 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
5033 {
5034 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5035 auto jsVal = info[0];
5036 if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
5037 return;
5038 }
5039
5040 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
5041 double progress = 0.0;
5042 ParseJsDouble(jsObj->GetProperty("percent"), progress);
5043 auto style = jsObj->GetPropertyValue<int32_t>("style",
5044 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
5045
5046 progress = std::clamp(progress, 0.0, 1.0);
5047 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
5048 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
5049
5050 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
5051 info.SetReturnValue(info.This());
5052 }
5053
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)5054 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
5055 std::string& resName, bool isParseType)
5056 {
5057 if (!jsValue->IsString()) {
5058 return false;
5059 }
5060 std::string resPath = jsValue->ToString();
5061 std::smatch results;
5062 std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
5063 if (!std::regex_match(resPath, results, tokenRegex)) {
5064 return false;
5065 }
5066 targetModule = results[1];
5067 if (isParseType && !ConvertResourceType(results[2], resType)) {
5068 return false;
5069 }
5070 resName = resPath;
5071 return true;
5072 }
5073
ConvertResourceType(const std::string & typeName,ResourceType & resType)5074 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
5075 {
5076 static const std::unordered_map<std::string, ResourceType> resTypeMap {
5077 { "color", ResourceType::COLOR },
5078 { "media", ResourceType::MEDIA },
5079 { "float", ResourceType::FLOAT },
5080 { "string", ResourceType::STRING },
5081 { "plural", ResourceType::PLURAL },
5082 { "pattern", ResourceType::PATTERN },
5083 { "boolean", ResourceType::BOOLEAN },
5084 { "integer", ResourceType::INTEGER },
5085 { "strarray", ResourceType::STRARRAY },
5086 { "intarray", ResourceType::INTARRAY },
5087 };
5088 auto it = resTypeMap.find(typeName);
5089 if (it == resTypeMap.end()) {
5090 return false;
5091 }
5092 resType = it->second;
5093 return true;
5094 }
5095
CompleteResourceObject(JSRef<JSObject> & jsObj)5096 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
5097 {
5098 std::string bundleName;
5099 std::string moduleName;
5100 int32_t resId = -1;
5101 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5102 }
5103
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)5104 void JSViewAbstract::CompleteResourceObjectWithBundleName(
5105 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
5106 {
5107 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5108 }
5109
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)5110 void JSViewAbstract::CompleteResourceObjectInner(
5111 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
5112 {
5113 // dynamic $r raw input format is
5114 // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
5115 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5116 ResourceType resType;
5117
5118 std::string targetModule;
5119 std::string resName;
5120 if (resId->IsString()) {
5121 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
5122 int32_t typeNum = -1;
5123 if (type->IsNumber()) {
5124 typeNum = type->ToNumber<int32_t>();
5125 }
5126 if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
5127 return;
5128 }
5129 CompleteResourceObjectFromId(type, jsObj, resType, resName);
5130 } else if (resId->IsNumber()) {
5131 resIdValue = resId->ToNumber<int32_t>();
5132 if (resIdValue == -1) {
5133 CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
5134 }
5135 }
5136
5137 JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
5138 if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
5139 bundleName = GetBundleNameFromContainer();
5140 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
5141 }
5142 if (moduleName == DEFAULT_HAR_MODULE_NAME) {
5143 moduleName = GetModuleNameFromContainer();
5144 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
5145 }
5146 }
5147
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)5148 bool JSViewAbstract::ParseJsDimensionNG(
5149 const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
5150 {
5151 if (jsValue->IsNumber()) {
5152 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5153 return true;
5154 }
5155 if (jsValue->IsString()) {
5156 auto value = jsValue->ToString();
5157 if (!isSupportPercent && value.back() == '%') {
5158 return false;
5159 }
5160 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5161 }
5162 if (jsValue->IsObject()) {
5163 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5164 CompleteResourceObject(jsObj);
5165 JSRef<JSVal> resId = jsObj->GetProperty("id");
5166 if (!resId->IsNumber()) {
5167 return false;
5168 }
5169 auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5170 if (resType == UNKNOWN_RESOURCE_TYPE) {
5171 return false;
5172 }
5173
5174 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5175 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5176 if (!resourceWrapper) {
5177 return false;
5178 }
5179
5180 auto resIdNum = resId->ToNumber<int32_t>();
5181 if (resIdNum == -1) {
5182 if (!IsGetResourceByName(jsObj)) {
5183 return false;
5184 }
5185 JSRef<JSVal> args = jsObj->GetProperty("params");
5186 if (!args->IsArray()) {
5187 return false;
5188 }
5189 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5190 auto param = params->GetValueAt(0);
5191 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5192 auto value = resourceWrapper->GetStringByName(param->ToString());
5193 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5194 }
5195 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5196 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5197 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5198 return true;
5199 }
5200 result = resourceWrapper->GetDimensionByName(param->ToString());
5201 return true;
5202 }
5203
5204 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5205 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5206 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5207 }
5208 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5209 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5210 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5211 return true;
5212 }
5213
5214 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5215 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
5216 return true;
5217 }
5218 }
5219
5220 return false;
5221 }
5222
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)5223 bool JSViewAbstract::ParseJsLengthNG(
5224 const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
5225 {
5226 if (jsValue->IsNumber()) {
5227 if (std::isnan(jsValue->ToNumber<double>())) {
5228 return false;
5229 }
5230 result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
5231 return true;
5232 } else if (jsValue->IsObject()) {
5233 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5234 JSRef<JSVal> value = jsObj->GetProperty("value");
5235 if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
5236 return false;
5237 }
5238 DimensionUnit unit = defaultUnit;
5239 JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
5240 if (jsUnit->IsNumber()) {
5241 if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
5242 return false;
5243 }
5244 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
5245 }
5246 result = NG::CalcLength(value->ToNumber<double>(), unit);
5247 return true;
5248 }
5249
5250 return false;
5251 }
5252
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)5253 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
5254 {
5255 // 'vp' -> the value varies with pixel density of device.
5256 return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5257 }
5258
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)5259 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
5260 {
5261 if (jsValue->IsNumber()) {
5262 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5263 return true;
5264 }
5265 if (jsValue->IsString()) {
5266 result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
5267 return true;
5268 }
5269 if (!jsValue->IsObject()) {
5270 return false;
5271 }
5272 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5273 CompleteResourceObject(jsObj);
5274 JSRef<JSVal> resId = jsObj->GetProperty("id");
5275 if (!resId->IsNumber()) {
5276 return false;
5277 }
5278
5279 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5280 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5281 if (!resourceWrapper) {
5282 return false;
5283 }
5284
5285 auto resIdNum = resId->ToNumber<int32_t>();
5286 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5287 if (resType == UNKNOWN_RESOURCE_TYPE) {
5288 return false;
5289 }
5290
5291 if (resIdNum == -1) {
5292 if (!IsGetResourceByName(jsObj)) {
5293 return false;
5294 }
5295 JSRef<JSVal> args = jsObj->GetProperty("params");
5296 if (!args->IsArray()) {
5297 return false;
5298 }
5299 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5300 auto param = params->GetValueAt(0);
5301 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5302 auto value = resourceWrapper->GetStringByName(param->ToString());
5303 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5304 return true;
5305 }
5306 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5307 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5308 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5309 return true;
5310 }
5311 result = resourceWrapper->GetDimensionByName(param->ToString());
5312 return true;
5313 }
5314
5315 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5316 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5317 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5318 return true;
5319 }
5320 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5321 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5322 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5323 return true;
5324 }
5325 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
5326 return true;
5327 }
5328
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5329 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5330 {
5331 // 'vp' -> the value varies with pixel density of device.
5332 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5333 }
5334
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)5335 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5336 {
5337 // 'vp' -> the value varies with pixel density of device.
5338 return ParseJsDimension(jsValue, result, DimensionUnit::VP);
5339 }
5340
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)5341 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5342 {
5343 // the 'fp' unit is used for text scenes.
5344 return ParseJsDimension(jsValue, result, DimensionUnit::FP);
5345 }
5346
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5347 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5348 {
5349 // the 'fp' unit is used for text scenes.
5350 return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
5351 }
5352
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)5353 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
5354 {
5355 return ParseJsDimension(jsValue, result, DimensionUnit::PX);
5356 }
5357
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)5358 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
5359 {
5360 if (!jsValue->IsObject()) {
5361 return false;
5362 }
5363 auto colorObj = JSRef<JSObject>::Cast(jsValue);
5364 auto toNumericProp = colorObj->GetProperty("toNumeric");
5365 if (toNumericProp->IsFunction()) {
5366 auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
5367 result.SetValue(colorVal->ToNumber<uint32_t>());
5368 return true;
5369 }
5370 return false;
5371 }
5372
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5373 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5374 {
5375 if (jsValue->IsNumber()) {
5376 result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
5377 return true;
5378 }
5379 if (jsValue->IsString()) {
5380 auto value = jsValue->ToString();
5381 return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
5382 }
5383 if (jsValue->IsObject()) {
5384 auto jsObj = JSRef<JSObject>::Cast(jsValue);
5385 auto valObj = jsObj->GetProperty("value");
5386 if (valObj->IsUndefined() || valObj->IsNull()) {
5387 return false;
5388 }
5389 double value = valObj->ToNumber<double>();
5390 auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
5391 result = CalcDimension(value, unit);
5392 return true;
5393 }
5394 return false;
5395 }
5396
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5397 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5398 {
5399 return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
5400 }
5401
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)5402 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
5403 {
5404 if (!jsValue->IsObject()) {
5405 return false;
5406 }
5407 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5408 CompleteResourceObject(jsObj);
5409 if (jsObj->IsEmpty()) {
5410 return false;
5411 }
5412 JSRef<JSVal> id = jsObj->GetProperty("id");
5413 if (!id->IsNumber()) {
5414 return false;
5415 }
5416
5417 auto resId = id->ToNumber<int32_t>();
5418 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5419 if (resType == UNKNOWN_RESOURCE_TYPE) {
5420 return false;
5421 }
5422
5423 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5424 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5425 if (!resourceWrapper) {
5426 return false;
5427 }
5428
5429 if (resId == -1) {
5430 if (!IsGetResourceByName(jsObj)) {
5431 return false;
5432 }
5433 JSRef<JSVal> args = jsObj->GetProperty("params");
5434 if (!args->IsArray()) {
5435 return false;
5436 }
5437 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5438 auto param = params->GetValueAt(0);
5439 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5440 auto numberString = resourceWrapper->GetStringByName(param->ToString());
5441 return StringUtils::StringToDouble(numberString, result);
5442 }
5443 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5444 result = resourceWrapper->GetIntByName(param->ToString());
5445 return true;
5446 }
5447 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5448 result = resourceWrapper->GetDoubleByName(param->ToString());
5449 return true;
5450 }
5451 return false;
5452 }
5453 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5454 auto numberString = resourceWrapper->GetString(resId);
5455 return StringUtils::StringToDouble(numberString, result);
5456 }
5457 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5458 result = resourceWrapper->GetInt(resId);
5459 return true;
5460 }
5461 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5462 result = resourceWrapper->GetDouble(resId);
5463 return true;
5464 }
5465 return false;
5466 }
5467
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)5468 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
5469 {
5470 if (jsValue->IsNumber()) {
5471 result = jsValue->ToNumber<double>();
5472 return true;
5473 }
5474 if (jsValue->IsString()) {
5475 return StringUtils::StringToDouble(jsValue->ToString(), result);
5476 }
5477 if (jsValue->IsObject()) {
5478 return ParseResourceToDouble(jsValue, result);
5479 }
5480 return false;
5481 }
5482
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)5483 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
5484 {
5485 if (jsValue->IsNumber()) {
5486 result = jsValue->ToNumber<int32_t>();
5487 return true;
5488 }
5489 if (jsValue->IsString()) {
5490 result = StringUtils::StringToInt(jsValue->ToString());
5491 return true;
5492 }
5493 if (!jsValue->IsObject()) {
5494 return false;
5495 }
5496 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5497 CompleteResourceObject(jsObj);
5498 JSRef<JSVal> resId = jsObj->GetProperty("id");
5499 if (!resId->IsNumber()) {
5500 return false;
5501 }
5502
5503 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5504 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5505 if (!resourceWrapper) {
5506 return false;
5507 }
5508
5509 auto resIdNum = resId->ToNumber<int32_t>();
5510 if (resIdNum == -1) {
5511 if (!IsGetResourceByName(jsObj)) {
5512 return false;
5513 }
5514 JSRef<JSVal> args = jsObj->GetProperty("params");
5515 if (!args->IsArray()) {
5516 return false;
5517 }
5518 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5519 auto param = params->GetValueAt(0);
5520 result = resourceWrapper->GetIntByName(param->ToString());
5521 return true;
5522 }
5523 result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5524 return true;
5525 }
5526
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)5527 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
5528 {
5529 if (!jsValue->IsObject()) {
5530 return false;
5531 }
5532 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5533 CompleteResourceObject(jsObj);
5534
5535 auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result);
5536 if (ok) {
5537 JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
5538 if (jsOpacityRatio->IsNumber()) {
5539 double opacityRatio = jsOpacityRatio->ToNumber<double>();
5540 result = result.BlendOpacity(opacityRatio);
5541 }
5542 }
5543 return ok;
5544 }
5545
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)5546 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result)
5547 {
5548 JSRef<JSVal> resId = jsObj->GetProperty("id");
5549 if (!resId->IsNumber()) {
5550 return false;
5551 }
5552
5553 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5554 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5555 if (!resourceWrapper) {
5556 return false;
5557 }
5558
5559 auto resIdNum = resId->ToNumber<int32_t>();
5560 if (resIdNum == -1) {
5561 if (!IsGetResourceByName(jsObj)) {
5562 return false;
5563 }
5564 JSRef<JSVal> args = jsObj->GetProperty("params");
5565 if (!args->IsArray()) {
5566 return false;
5567 }
5568 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5569 auto param = params->GetValueAt(0);
5570 result = resourceWrapper->GetColorByName(param->ToString());
5571 return true;
5572 }
5573
5574 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5575 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5576 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5577 return Color::ParseColorString(value, result);
5578 }
5579 if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5580 auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5581 result = Color(ColorAlphaAdapt(value));
5582 return true;
5583 }
5584 if (type == static_cast<int32_t>(ResourceType::COLOR)) {
5585 result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
5586 result.SetResourceId(resId->ToNumber<uint32_t>());
5587 return true;
5588 }
5589 return false;
5590 }
5591
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)5592 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
5593 {
5594 if (jsValue->IsNumber()) {
5595 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5596 return true;
5597 }
5598 if (jsValue->IsString()) {
5599 return Color::ParseColorString(jsValue->ToString(), result);
5600 }
5601 if (jsValue->IsObject()) {
5602 return ParseJsColorFromResource(jsValue, result);
5603 }
5604 return false;
5605 }
5606
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)5607 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
5608 {
5609 if (jsValue->IsNumber()) {
5610 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5611 return true;
5612 }
5613 if (jsValue->IsString()) {
5614 return Color::ParseColorString(jsValue->ToString(), result, defaultColor);
5615 }
5616 if (!jsValue->IsObject()) {
5617 return false;
5618 }
5619 return ParseJsColorFromResource(jsValue, result);
5620 }
5621
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)5622 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
5623 {
5624 if (jsValue->IsString()) {
5625 std::string colorStr = jsValue->ToString();
5626 if (colorStr.compare("invert") == 0) {
5627 strategy = ForegroundColorStrategy::INVERT;
5628 return true;
5629 }
5630 }
5631 return false;
5632 }
5633
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)5634 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
5635 {
5636 if (jsValue->IsString()) {
5637 std::string colorStr = jsValue->ToString();
5638 if (colorStr.compare("average") == 0) {
5639 strategy = ShadowColorStrategy::AVERAGE;
5640 return true;
5641 } else if (colorStr.compare("primary") == 0) {
5642 strategy = ShadowColorStrategy::PRIMARY;
5643 return true;
5644 }
5645 }
5646 return false;
5647 }
5648
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)5649 bool JSViewAbstract::ParseJsSymbolId(
5650 const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
5651 {
5652 if (jsValue->IsNull() || jsValue->IsUndefined()) {
5653 symbolId = 0;
5654 return false;
5655 }
5656 if (!jsValue->IsObject()) {
5657 return false;
5658 }
5659 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5660 CompleteResourceObject(jsObj);
5661 JSRef<JSVal> resId = jsObj->GetProperty("id");
5662 if (resId->IsNull() || !resId->IsNumber()) {
5663 return false;
5664 }
5665 auto resourceObject = GetResourceObject(jsObj);
5666 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5667 symbolResourceObject = resourceObject;
5668 if (!resourceWrapper) {
5669 return false;
5670 }
5671 if (!resourceObject) {
5672 return false;
5673 }
5674
5675 auto resIdNum = resId->ToNumber<int32_t>();
5676 if (resIdNum == -1) {
5677 if (!IsGetResourceByName(jsObj)) {
5678 return false;
5679 }
5680 JSRef<JSVal> args = jsObj->GetProperty("params");
5681 if (!args->IsArray()) {
5682 return false;
5683 }
5684 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5685 auto param = params->GetValueAt(0);
5686 auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
5687 if (!symbol) {
5688 return false;
5689 }
5690 symbolId = symbol;
5691 return true;
5692 }
5693
5694 auto symbol = resourceWrapper->GetSymbolById(resIdNum);
5695 if (!symbol) {
5696 return false;
5697 }
5698 symbolId = symbol;
5699 return true;
5700 }
5701
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)5702 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
5703 {
5704 if (!jsValue->IsArray()) {
5705 return false;
5706 }
5707 if (jsValue->IsArray()) {
5708 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5709 for (size_t i = 0; i < array->Length(); i++) {
5710 JSRef<JSVal> value = array->GetValueAt(i);
5711 if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
5712 return false;
5713 }
5714 if (value->IsNumber()) {
5715 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
5716 continue;
5717 } else if (value->IsString()) {
5718 Color color;
5719 Color::ParseColorString(value->ToString(), color);
5720 result.emplace_back(color);
5721 continue;
5722 } else {
5723 Color color;
5724 ParseJsColorFromResource(value, color);
5725 result.emplace_back(color);
5726 }
5727 }
5728 return true;
5729 }
5730 return false;
5731 }
5732
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5733 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
5734 {
5735 result.clear();
5736 if (!jsValue->IsString() && !jsValue->IsObject()) {
5737 return false;
5738 }
5739 if (jsValue->IsString()) {
5740 result = ConvertStrToFontFamilies(jsValue->ToString());
5741 return true;
5742 }
5743 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5744 CompleteResourceObject(jsObj);
5745 JSRef<JSVal> resId = jsObj->GetProperty("id");
5746 if (!resId->IsNumber()) {
5747 return false;
5748 }
5749
5750 auto resourceObject = GetResourceObject(jsObj);
5751 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5752 if (!resourceWrapper) {
5753 return false;
5754 }
5755
5756 auto resIdNum = resId->ToNumber<int32_t>();
5757 if (resIdNum == -1) {
5758 if (!IsGetResourceByName(jsObj)) {
5759 return false;
5760 }
5761 JSRef<JSVal> args = jsObj->GetProperty("params");
5762 if (!args->IsArray()) {
5763 return false;
5764 }
5765 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5766 auto param = params->GetValueAt(0);
5767 result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
5768 return true;
5769 }
5770 result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
5771 return true;
5772 }
5773
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5774 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
5775 {
5776 if (jsValue->IsString()) {
5777 result = jsValue->ToString();
5778 return true;
5779 }
5780
5781 if (!jsValue->IsObject()) {
5782 return false;
5783 }
5784
5785 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5786 CompleteResourceObject(jsObj);
5787
5788 JSRef<JSVal> resId = jsObj->GetProperty("id");
5789 if (!resId->IsNumber()) {
5790 return false;
5791 }
5792 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5793 if (type == UNKNOWN_RESOURCE_TYPE) {
5794 return false;
5795 }
5796
5797 JSRef<JSVal> args = jsObj->GetProperty("params");
5798 if (!args->IsArray()) {
5799 return false;
5800 }
5801
5802 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5803 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5804 if (!resourceWrapper) {
5805 return false;
5806 }
5807
5808 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5809 auto resIdNum = resId->ToNumber<int32_t>();
5810 if (resIdNum == -1) {
5811 if (!IsGetResourceByName(jsObj)) {
5812 return false;
5813 }
5814 auto param = params->GetValueAt(0);
5815 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5816 auto originStr = resourceWrapper->GetStringByName(param->ToString());
5817 ReplaceHolder(originStr, params, 1);
5818 result = originStr;
5819 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5820 auto countJsVal = params->GetValueAt(1);
5821 int count = 0;
5822 if (!countJsVal->IsNumber()) {
5823 return false;
5824 }
5825 count = countJsVal->ToNumber<int>();
5826 auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
5827 ReplaceHolder(pluralStr, params, 2);
5828 result = pluralStr;
5829 } else {
5830 return false;
5831 }
5832 return true;
5833 }
5834 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5835 auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5836 ReplaceHolder(originStr, params, 0);
5837 result = originStr;
5838 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5839 auto countJsVal = params->GetValueAt(0);
5840 int count = 0;
5841 if (!countJsVal->IsNumber()) {
5842 return false;
5843 }
5844 count = countJsVal->ToNumber<int>();
5845 auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
5846 ReplaceHolder(pluralStr, params, 1);
5847 result = pluralStr;
5848 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
5849 result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
5850 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5851 result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5852 } else {
5853 return false;
5854 }
5855 return true;
5856 }
5857
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5858 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
5859 {
5860 if (!jsValue->IsObject() && !jsValue->IsString()) {
5861 return false;
5862 }
5863 if (jsValue->IsString()) {
5864 result = jsValue->ToString();
5865 return true;
5866 }
5867 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5868 CompleteResourceObject(jsObj);
5869 return ParseJSMediaInternal(jsObj, result);
5870 }
5871
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5872 bool JSViewAbstract::ParseJsMediaWithBundleName(
5873 const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
5874 {
5875 if (!jsValue->IsObject() && !jsValue->IsString()) {
5876 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5877 }
5878 if (jsValue->IsString()) {
5879 result = jsValue->ToString();
5880 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5881 }
5882 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5883 CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
5884 return ParseJSMediaInternal(jsObj, result);
5885 }
5886
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5887 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result)
5888 {
5889 int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5890 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5891 if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
5892 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5893 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5894 CHECK_NULL_RETURN(resourceWrapper, false);
5895 if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
5896 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5897 if (!args->IsArray()) {
5898 return false;
5899 }
5900 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5901 auto fileName = params->GetValueAt(0);
5902 if (!fileName->IsString()) {
5903 return false;
5904 }
5905 result = resourceWrapper->GetRawfile(fileName->ToString());
5906 return true;
5907 }
5908 auto resIdNum = resId->ToNumber<int32_t>();
5909 if (resIdNum == -1) {
5910 if (!IsGetResourceByName(jsObj)) {
5911 return false;
5912 }
5913 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5914 if (!args->IsArray()) {
5915 return false;
5916 }
5917 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5918 auto param = params->GetValueAt(0);
5919 if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5920 result = resourceWrapper->GetMediaPathByName(param->ToString());
5921 return true;
5922 }
5923 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5924 result = resourceWrapper->GetStringByName(param->ToString());
5925 return true;
5926 }
5927 return false;
5928 } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5929 result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
5930 return true;
5931 } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
5932 result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5933 return true;
5934 }
5935 }
5936 return false;
5937 }
5938
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5939 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
5940 const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
5941 {
5942 auto vm = info.GetVm();
5943 auto globalObj = JSNApi::GetGlobalObject(vm);
5944 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
5945 JsiValue jsiValue(globalFunc);
5946 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
5947 if (!globalFuncRef->IsFunction()) {
5948 return;
5949 }
5950 if (modifierNormalObj->IsUndefined()) {
5951 symbolApply.onApply = nullptr;
5952 } else {
5953 RefPtr<JsFunction> jsFunc =
5954 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
5955 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
5956 modifierNormal = std::move(modifierNormalObj),
5957 modifierSelected = std::move(modifierSelectedObj)](
5958 WeakPtr<NG::FrameNode> frameNode, std::string type) {
5959 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5960 auto node = frameNode.Upgrade();
5961 CHECK_NULL_VOID(node);
5962 JSRef<JSVal> params[SECOND_INDEX];
5963 if (type == "normal") {
5964 params[0] = modifierNormal;
5965 } else if (!modifierSelected->IsUndefined()) {
5966 params[0] = modifierSelected;
5967 }
5968 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
5969 PipelineContext::SetCallBackNode(node);
5970 func->ExecuteJS(SECOND_INDEX, params);
5971 };
5972 symbolApply.onApply = onApply;
5973 }
5974 }
5975
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)5976 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
5977 {
5978 if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
5979 return false;
5980 }
5981
5982 if (jsValue->IsBoolean()) {
5983 result = jsValue->ToBoolean();
5984 return true;
5985 }
5986
5987 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5988 CompleteResourceObject(jsObj);
5989 int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5990 if (resType == UNKNOWN_RESOURCE_TYPE) {
5991 return false;
5992 }
5993
5994 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5995 if (!resId->IsNumber()) {
5996 return false;
5997 }
5998
5999 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6000 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6001 if (!resourceWrapper) {
6002 return false;
6003 }
6004
6005 auto resIdNum = resId->ToNumber<int32_t>();
6006 if (resIdNum == -1) {
6007 if (!IsGetResourceByName(jsObj)) {
6008 return false;
6009 }
6010 JSRef<JSVal> args = jsObj->GetProperty("params");
6011 if (!args->IsArray()) {
6012 return false;
6013 }
6014 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6015 auto param = params->GetValueAt(0);
6016 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6017 result = resourceWrapper->GetBooleanByName(param->ToString());
6018 return true;
6019 }
6020 return false;
6021 }
6022
6023 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6024 result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
6025 return true;
6026 }
6027 return false;
6028 }
6029
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)6030 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
6031 {
6032 return ParseJsInteger<uint32_t>(jsValue, result);
6033 }
6034
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)6035 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
6036 {
6037 return ParseJsInteger<int32_t>(jsValue, result);
6038 }
6039
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)6040 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
6041 {
6042 if (!jsValue->IsArray() && !jsValue->IsObject()) {
6043 return false;
6044 }
6045
6046 if (jsValue->IsArray()) {
6047 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6048 for (size_t i = 0; i < array->Length(); i++) {
6049 JSRef<JSVal> value = array->GetValueAt(i);
6050 if (value->IsNumber()) {
6051 result.emplace_back(value->ToNumber<uint32_t>());
6052 } else if (value->IsObject()) {
6053 uint32_t singleResInt;
6054 if (ParseJsInteger(value, singleResInt)) {
6055 result.emplace_back(singleResInt);
6056 } else {
6057 return false;
6058 }
6059 } else {
6060 return false;
6061 }
6062 }
6063 return true;
6064 }
6065
6066 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6067 CompleteResourceObject(jsObj);
6068 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6069 if (resType == UNKNOWN_RESOURCE_TYPE) {
6070 return false;
6071 }
6072
6073 JSRef<JSVal> resId = jsObj->GetProperty("id");
6074 if (!resId->IsNumber()) {
6075 return false;
6076 }
6077
6078 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6079 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6080 if (!resourceWrapper) {
6081 return false;
6082 }
6083
6084 auto resIdNum = resId->ToNumber<int32_t>();
6085 if (resIdNum == -1) {
6086 if (!IsGetResourceByName(jsObj)) {
6087 return false;
6088 }
6089 JSRef<JSVal> args = jsObj->GetProperty("params");
6090 if (!args->IsArray()) {
6091 return false;
6092 }
6093 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6094 auto param = params->GetValueAt(0);
6095 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6096 result = resourceWrapper->GetIntArrayByName(param->ToString());
6097 return true;
6098 }
6099 return false;
6100 }
6101
6102 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6103 result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
6104 return true;
6105 }
6106 return false;
6107 }
6108
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)6109 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
6110 {
6111 if (!jsValue->IsArray() && !jsValue->IsObject()) {
6112 return false;
6113 }
6114
6115 if (jsValue->IsArray()) {
6116 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6117 for (size_t i = 0; i < array->Length(); i++) {
6118 JSRef<JSVal> value = array->GetValueAt(i);
6119 if (value->IsString()) {
6120 result.emplace_back(value->ToString());
6121 } else if (value->IsObject()) {
6122 std::string singleResStr;
6123 if (ParseJsString(value, singleResStr)) {
6124 result.emplace_back(singleResStr);
6125 } else {
6126 return false;
6127 }
6128 } else {
6129 return false;
6130 }
6131 }
6132 return true;
6133 }
6134
6135 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6136 CompleteResourceObject(jsObj);
6137 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6138 if (resType == UNKNOWN_RESOURCE_TYPE) {
6139 return false;
6140 }
6141
6142 JSRef<JSVal> resId = jsObj->GetProperty("id");
6143 if (!resId->IsNumber()) {
6144 return false;
6145 }
6146
6147 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6148 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6149 if (!resourceWrapper) {
6150 return false;
6151 }
6152
6153 auto resIdNum = resId->ToNumber<int32_t>();
6154 if (resIdNum == -1) {
6155 if (!IsGetResourceByName(jsObj)) {
6156 return false;
6157 }
6158 JSRef<JSVal> args = jsObj->GetProperty("params");
6159 if (!args->IsArray()) {
6160 return false;
6161 }
6162 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6163 auto param = params->GetValueAt(0);
6164 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6165 result = resourceWrapper->GetStringArrayByName(param->ToString());
6166 return true;
6167 }
6168 return false;
6169 }
6170
6171 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6172 result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
6173 return true;
6174 }
6175 return false;
6176 }
6177
IsGetResourceByName(const JSRef<JSObject> & jsObj)6178 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
6179 {
6180 JSRef<JSVal> resId = jsObj->GetProperty("id");
6181 if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
6182 return false;
6183 }
6184 JSRef<JSVal> args = jsObj->GetProperty("params");
6185 if (!args->IsArray()) {
6186 return false;
6187 }
6188 JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
6189 JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
6190 if (!bundleName->IsString() || !moduleName->IsString()) {
6191 return false;
6192 }
6193 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6194 if (params->IsEmpty()) {
6195 return false;
6196 }
6197 return true;
6198 }
6199
ParseSize(const JSCallbackInfo & info)6200 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
6201 {
6202 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6203 auto jsVal = info[0];
6204 if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
6205 return std::pair<CalcDimension, CalcDimension>();
6206 }
6207 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
6208 CalcDimension width;
6209 CalcDimension height;
6210 if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
6211 !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
6212 return std::pair<CalcDimension, CalcDimension>();
6213 }
6214 return std::pair<CalcDimension, CalcDimension>(width, height);
6215 }
6216
JsUseAlign(const JSCallbackInfo & info)6217 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
6218 {
6219 if (info.Length() < 2) {
6220 return;
6221 }
6222
6223 if (!info[0]->IsObject() && !info[1]->IsObject()) {
6224 return;
6225 }
6226
6227 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
6228 if (declaration == nullptr) {
6229 return;
6230 }
6231
6232 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6233 JSRef<JSVal> side = obj->GetProperty("side");
6234 JSRef<JSVal> offset = obj->GetProperty("offset");
6235
6236 if (!side->IsNumber()) {
6237 return;
6238 }
6239
6240 auto sideValue = side->ToNumber<int32_t>();
6241
6242 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
6243 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
6244 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
6245 return;
6246 }
6247 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
6248 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
6249 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
6250 return;
6251 }
6252 }
6253
6254 std::optional<CalcDimension> optOffset;
6255 CalcDimension offsetDimension;
6256 if (ParseJsDimensionVp(offset, offsetDimension)) {
6257 optOffset = offsetDimension;
6258 }
6259 ViewAbstractModel::GetInstance()->SetUseAlign(
6260 declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
6261 }
6262
JsGridSpan(const JSCallbackInfo & info)6263 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
6264 {
6265 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6266 auto jsVal = info[0];
6267 if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
6268 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6269 ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
6270 }
6271 return;
6272 }
6273 auto span = jsVal->ToNumber<int32_t>();
6274 ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
6275 }
6276
JsGridOffset(const JSCallbackInfo & info)6277 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
6278 {
6279 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6280 auto jsVal = info[0];
6281 if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
6282 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6283 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
6284 }
6285 return;
6286 }
6287 auto offset = jsVal->ToNumber<int32_t>();
6288 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
6289 }
6290
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)6291 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
6292 {
6293 // {lg: 4}
6294 if (val->IsNumber()) {
6295 span = val->ToNumber<uint32_t>();
6296 return true;
6297 }
6298
6299 if (!val->IsObject()) {
6300 return false;
6301 }
6302
6303 // {lg: {span: 1, offset: 2}}
6304 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
6305 span = obj->GetProperty("span")->ToNumber<uint32_t>();
6306 offset = obj->GetProperty("offset")->ToNumber<int32_t>();
6307 return true;
6308 }
6309
JsUseSizeType(const JSCallbackInfo & info)6310 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
6311 {
6312 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6313 auto jsVal = info[0];
6314 if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
6315 return;
6316 }
6317 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
6318 for (auto values : SCREEN_SIZE_VALUES) {
6319 JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
6320 if (val->IsNull() || val->IsEmpty()) {
6321 continue;
6322 }
6323 uint32_t span = 0;
6324 int32_t offset = 0;
6325 if (ParseSpanAndOffset(val, span, offset)) {
6326 ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
6327 }
6328 }
6329 }
6330
JsZIndex(const JSCallbackInfo & info)6331 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
6332 {
6333 int zIndex = 0;
6334 if (info[0]->IsNumber()) {
6335 zIndex = info[0]->ToNumber<int>();
6336 }
6337
6338 ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
6339 }
6340
Pop()6341 void JSViewAbstract::Pop()
6342 {
6343 ViewStackModel::GetInstance()->Pop();
6344 }
6345
JsSetDraggable(bool draggable)6346 void JSViewAbstract::JsSetDraggable(bool draggable)
6347 {
6348 ViewAbstractModel::GetInstance()->SetDraggable(draggable);
6349 }
6350
ParseDragPreviewOptions(const JSCallbackInfo & info)6351 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
6352 {
6353 NG::DragPreviewOption previewOption;
6354 if (!info[0]->IsObject()) {
6355 return previewOption;
6356 }
6357 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
6358 auto mode = obj->GetProperty("mode");
6359 bool isAuto = true;
6360 if (mode->IsNumber()) {
6361 ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
6362 } else if (mode->IsArray()) {
6363 JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
6364 for (size_t i = 0; i < array->Length(); i++) {
6365 JSRef<JSVal> value = array->GetValueAt(i);
6366 if (value->IsNumber()) {
6367 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
6368 }
6369 if (isAuto) {
6370 break;
6371 }
6372 }
6373 }
6374
6375 JSViewAbstract::SetDragNumberBadge(info, previewOption);
6376
6377 if (info.Length() > 1 && info[1]->IsObject()) {
6378 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
6379 auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
6380 if (multiSelection->IsBoolean()) {
6381 previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
6382 }
6383 auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
6384 if (defaultAnimation->IsBoolean()) {
6385 previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
6386 }
6387 auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
6388 if (dragPreview->IsBoolean()) {
6389 previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
6390 }
6391 }
6392
6393 JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
6394
6395 return previewOption;
6396 }
6397
JsSetDragPreviewOptions(const JSCallbackInfo & info)6398 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
6399 {
6400 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6401 auto jsVal = info[0];
6402 if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
6403 return;
6404 }
6405 NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
6406 ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
6407 }
6408
JsOnDragStart(const JSCallbackInfo & info)6409 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
6410 {
6411 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6412 auto jsVal = info[0];
6413 if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
6414 return;
6415 }
6416
6417 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6418
6419 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6420 auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
6421 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
6422 NG::DragDropBaseInfo dragDropInfo;
6423 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
6424 PipelineContext::SetCallBackNode(node);
6425 auto ret = func->Execute(info, extraParams);
6426 if (!ret->IsObject()) {
6427 return dragDropInfo;
6428 }
6429
6430 dragDropInfo.node = ParseDragNode(ret);
6431 auto builderObj = JSRef<JSObject>::Cast(ret);
6432 #if defined(PIXEL_MAP_SUPPORTED)
6433 auto pixmap = builderObj->GetProperty("pixelMap");
6434 dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
6435 #endif
6436 auto extraInfo = builderObj->GetProperty("extraInfo");
6437 ParseJsString(extraInfo, dragDropInfo.extraInfo);
6438 return dragDropInfo;
6439 };
6440 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
6441 }
6442
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)6443 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
6444 {
6445 auto node = ParseDragNode(info);
6446 if (!node) {
6447 return false;
6448 }
6449 dragInfo.node = node;
6450 return true;
6451 }
6452
ParseDragNode(const JSRef<JSVal> & info)6453 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
6454 {
6455 auto builderFunc = ParseDragStartBuilderFunc(info);
6456 if (!builderFunc) {
6457 return nullptr;
6458 }
6459 // use another VSP instance while executing the builder function
6460 ViewStackModel::GetInstance()->NewScope();
6461 {
6462 ACE_SCORING_EVENT("onDragStart.builder");
6463 builderFunc->Execute();
6464 }
6465
6466 return ViewStackModel::GetInstance()->Finish();
6467 }
6468
JsOnDragEnter(const JSCallbackInfo & info)6469 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
6470 {
6471 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6472 auto jsVal = info[0];
6473 if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
6474 return;
6475 }
6476 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6477 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6478 auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
6479 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6480 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6481 ACE_SCORING_EVENT("onDragEnter");
6482 PipelineContext::SetCallBackNode(node);
6483 func->Execute(info, extraParams);
6484 };
6485
6486 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
6487 }
6488
JsOnDragEnd(const JSCallbackInfo & info)6489 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
6490 {
6491 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6492 auto jsVal = info[0];
6493 if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
6494 return;
6495 }
6496 RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6497 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6498 auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
6499 const RefPtr<OHOS::Ace::DragEvent>& info) {
6500 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6501 ACE_SCORING_EVENT("onDragEnd");
6502 auto extraParams = JsonUtil::Create(true);
6503 PipelineContext::SetCallBackNode(node);
6504 func->Execute(info, extraParams->ToString());
6505 };
6506
6507 ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
6508 }
6509
JsOnDragMove(const JSCallbackInfo & info)6510 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
6511 {
6512 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6513 auto jsVal = info[0];
6514 if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
6515 return;
6516 }
6517 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6518 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6519 auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
6520 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6521 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6522 ACE_SCORING_EVENT("onDragMove");
6523 PipelineContext::SetCallBackNode(node);
6524 func->Execute(info, extraParams);
6525 };
6526
6527 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
6528 }
6529
JsOnDragLeave(const JSCallbackInfo & info)6530 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
6531 {
6532 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6533 auto jsVal = info[0];
6534 if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
6535 return;
6536 }
6537 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6538 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6539 auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
6540 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6541 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6542 ACE_SCORING_EVENT("onDragLeave");
6543 PipelineContext::SetCallBackNode(node);
6544 func->Execute(info, extraParams);
6545 };
6546
6547 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
6548 }
6549
JsOnDrop(const JSCallbackInfo & info)6550 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
6551 {
6552 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6553 auto jsVal = info[0];
6554 if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
6555 return;
6556 }
6557 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6558 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6559 auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
6560 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6561 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6562 ACE_SCORING_EVENT("onDrop");
6563 PipelineContext::SetCallBackNode(node);
6564 func->Execute(info, extraParams);
6565 };
6566
6567 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
6568 }
6569
JsOnAreaChange(const JSCallbackInfo & info)6570 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
6571 {
6572 auto jsVal = info[0];
6573 if (jsVal->IsUndefined() && IsDisableEventVersion()) {
6574 ViewAbstractModel::GetInstance()->DisableOnAreaChange();
6575 return;
6576 }
6577 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6578 if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
6579 return;
6580 }
6581 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6582
6583 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6584 auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
6585 node = frameNode](
6586 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
6587 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6588 ACE_SCORING_EVENT("onAreaChange");
6589 PipelineContext::SetCallBackNode(node);
6590 func->Execute(oldRect, oldOrigin, rect, origin);
6591 };
6592 ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
6593 }
6594
JsOnSizeChange(const JSCallbackInfo & info)6595 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
6596 {
6597 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6598 auto jsVal = info[0];
6599 if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
6600 return;
6601 }
6602 auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6603
6604 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6605 auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
6606 node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
6607 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6608 ACE_SCORING_EVENT("onSizeChange");
6609 PipelineContext::SetCallBackNode(node);
6610 func->Execute(oldRect, rect);
6611 };
6612 ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
6613 }
6614
6615 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)6616 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
6617 {
6618 if (info.Length() < 2) {
6619 return;
6620 }
6621 if ((!info[0]->IsBoolean() && !info[0]->IsObject()) || !info[1]->IsObject()) {
6622 return;
6623 }
6624 auto popupParam = AceType::MakeRefPtr<PopupParam>();
6625 // Set IsShow to popupParam
6626 if (info[0]->IsBoolean()) {
6627 popupParam->SetIsShow(info[0]->ToBoolean());
6628 } else {
6629 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
6630 auto callback = ParseDoubleBindCallback(info, showObj);
6631 popupParam->SetOnStateChange(std::move(callback));
6632 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
6633 }
6634 // Set popup to popupParam
6635 auto popupObj = JSRef<JSObject>::Cast(info[1]);
6636 SetPopupDismiss(info, popupObj, popupParam);
6637 if (popupObj->GetProperty("message")->IsString()) {
6638 ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
6639 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6640 } else if (!popupObj->GetProperty("builder").IsEmpty()) {
6641 ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
6642 auto builderValue = popupObj->GetProperty("builder");
6643 auto builder = builderValue;
6644 if (!builderValue->IsObject()) {
6645 return;
6646 }
6647 if (!builderValue->IsFunction()) {
6648 JSRef<JSObject> builderObj;
6649 builderObj = JSRef<JSObject>::Cast(builderValue);
6650 builder = builderObj->GetProperty("builder");
6651 if (!builder->IsFunction()) {
6652 return;
6653 }
6654 }
6655 if (popupParam->IsShow() && !IsPopupCreated()) {
6656 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
6657 CHECK_NULL_VOID(builderFunc);
6658 ViewStackModel::GetInstance()->NewScope();
6659 builderFunc->Execute();
6660 auto customNode = ViewStackModel::GetInstance()->Finish();
6661 ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
6662 } else {
6663 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6664 }
6665 } else {
6666 return;
6667 }
6668 }
6669
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)6670 void JSViewAbstract::SetPopupDismiss(
6671 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
6672 {
6673 auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
6674 if (onWillDismissFunc->IsBoolean()) {
6675 bool onWillDismissBool = onWillDismissFunc->ToBoolean();
6676 popupParam->SetInteractiveDismiss(onWillDismissBool);
6677 popupParam->SetOnWillDismiss(nullptr);
6678 if (onWillDismissBool) {
6679 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6680 }
6681 } else if (onWillDismissFunc->IsFunction()) {
6682 auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
6683 popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
6684 popupParam->SetInteractiveDismiss(true);
6685 if (onWillDismissCallback != nullptr) {
6686 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6687 }
6688 }
6689 }
6690
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)6691 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
6692 {
6693 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6694 if (!onWillDismissFunc->IsFunction()) {
6695 return PopupOnWillDismiss();
6696 }
6697 RefPtr<JsFunction> jsFunc =
6698 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6699 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6700 auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
6701 node = frameNode](int32_t reason) {
6702 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6703 ACE_SCORING_EVENT("Bindpopup.dismiss");
6704 PipelineContext::SetCallBackNode(node);
6705
6706 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6707 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6708 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6709 dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
6710 dismissObj->SetProperty<int32_t>("reason", reason);
6711 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6712
6713 func->ExecuteJS(1, &newJSVal);
6714 };
6715 return onWillDismiss;
6716 }
6717
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)6718 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6719 {
6720 ViewAbstractModel::GetInstance()->DismissPopup();
6721 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6722 }
6723 #endif
6724
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info)> & onWillDismiss)6725 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
6726 std::function<void(const int32_t& info)>& onWillDismiss)
6727 {
6728 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6729 if (onWillDismissFunc->IsFunction()) {
6730 auto jsFunc =
6731 AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6732 onWillDismiss = [func = std::move(jsFunc)](const int32_t& info) {
6733 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6734 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6735 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6736 dismissObj->SetPropertyObject(
6737 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
6738 dismissObj->SetProperty<int32_t>("reason", info);
6739 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6740 func->ExecuteJS(1, &newJSVal);
6741 };
6742 }
6743 }
6744
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)6745 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6746 {
6747 ViewAbstractModel::GetInstance()->DismissDialog();
6748 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6749 }
6750
JsLinearGradient(const JSCallbackInfo & info)6751 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
6752 {
6753 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6754 auto jsVal = info[0];
6755 if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
6756 NG::Gradient newGradient;
6757 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6758 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6759 return;
6760 }
6761 NG::Gradient newGradient;
6762 NewJsLinearGradient(info, newGradient);
6763 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6764 }
6765
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6766 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6767 {
6768 if (!info[0]->IsObject()) {
6769 return;
6770 }
6771 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
6772 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6773 // angle
6774 std::optional<float> degree;
6775 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6776 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
6777 } else {
6778 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
6779 }
6780 if (degree) {
6781 newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
6782 degree.reset();
6783 }
6784 // direction
6785 auto direction = static_cast<GradientDirection>(
6786 jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
6787 switch (direction) {
6788 case GradientDirection::LEFT:
6789 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6790 break;
6791 case GradientDirection::RIGHT:
6792 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6793 break;
6794 case GradientDirection::TOP:
6795 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6796 break;
6797 case GradientDirection::BOTTOM:
6798 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6799 break;
6800 case GradientDirection::LEFT_TOP:
6801 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6802 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6803 break;
6804 case GradientDirection::LEFT_BOTTOM:
6805 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6806 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6807 break;
6808 case GradientDirection::RIGHT_TOP:
6809 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6810 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6811 break;
6812 case GradientDirection::RIGHT_BOTTOM:
6813 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6814 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6815 break;
6816 case GradientDirection::NONE:
6817 case GradientDirection::START_TO_END:
6818 case GradientDirection::END_TO_START:
6819 default:
6820 break;
6821 }
6822 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6823 newGradient.SetRepeat(repeating);
6824 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6825 }
6826
JsRadialGradient(const JSCallbackInfo & info)6827 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
6828 {
6829 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6830 auto jsVal = info[0];
6831 if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
6832 NG::Gradient newGradient;
6833 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6834 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6835 return;
6836 }
6837 NG::Gradient newGradient;
6838 NewJsRadialGradient(info, newGradient);
6839 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6840 }
6841
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6842 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6843 {
6844 JSRef<JSVal> arg = info[0];
6845 if (!arg->IsObject()) {
6846 return;
6847 }
6848 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6849 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6850 // center
6851 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6852 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6853 CalcDimension value;
6854 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6855 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6856 newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
6857 if (value.Unit() == DimensionUnit::PERCENT) {
6858 // [0,1] -> [0, 100]
6859 newGradient.GetRadialGradient()->radialCenterX =
6860 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6861 }
6862 }
6863 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6864 newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
6865 if (value.Unit() == DimensionUnit::PERCENT) {
6866 // [0,1] -> [0, 100]
6867 newGradient.GetRadialGradient()->radialCenterY =
6868 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6869 }
6870 }
6871 }
6872 // radius
6873 CalcDimension radius;
6874 if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) {
6875 newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
6876 newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
6877 }
6878 // repeating
6879 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6880 newGradient.SetRepeat(repeating);
6881 // color stops
6882 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6883 }
6884
JsSweepGradient(const JSCallbackInfo & info)6885 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
6886 {
6887 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6888 auto jsVal = info[0];
6889 if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
6890 NG::Gradient newGradient;
6891 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6892 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6893 return;
6894 }
6895
6896 NG::Gradient newGradient;
6897 NewJsSweepGradient(info, newGradient);
6898 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6899 }
6900
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6901 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6902 {
6903 JSRef<JSVal> arg = info[0];
6904 if (!arg->IsObject()) {
6905 return;
6906 }
6907 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6908 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6909 // center
6910 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6911 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6912 CalcDimension value;
6913 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6914 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6915 newGradient.GetSweepGradient()->centerX = CalcDimension(value);
6916 if (value.Unit() == DimensionUnit::PERCENT) {
6917 // [0,1] -> [0, 100]
6918 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6919 }
6920 }
6921 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6922 newGradient.GetSweepGradient()->centerY = CalcDimension(value);
6923 if (value.Unit() == DimensionUnit::PERCENT) {
6924 // [0,1] -> [0, 100]
6925 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6926 }
6927 }
6928 }
6929 // start, end and rotation
6930 ParseSweepGradientPartly(jsObj, newGradient);
6931 // repeating
6932 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6933 newGradient.SetRepeat(repeating);
6934 // color stops
6935 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6936 }
6937
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)6938 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
6939 {
6940 std::optional<float> degreeStart;
6941 std::optional<float> degreeEnd;
6942 std::optional<float> degreeRotation;
6943 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6944 GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
6945 GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
6946 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
6947 } else {
6948 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
6949 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
6950 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
6951 }
6952 if (degreeStart) {
6953 CheckAngle(degreeStart);
6954 newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
6955 }
6956 if (degreeEnd) {
6957 CheckAngle(degreeEnd);
6958 newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
6959 }
6960 if (degreeRotation) {
6961 CheckAngle(degreeRotation);
6962 newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
6963 }
6964 }
6965
JsMotionPath(const JSCallbackInfo & info)6966 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
6967 {
6968 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6969 auto jsVal = info[0];
6970 if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
6971 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6972 return;
6973 }
6974 MotionPathOption motionPathOption;
6975 if (ParseMotionPath(jsVal, motionPathOption)) {
6976 ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
6977 } else {
6978 TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
6979 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
6980 }
6981 }
6982
JsShadow(const JSCallbackInfo & info)6983 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
6984 {
6985 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
6986 auto jsVal = info[0];
6987 if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
6988 Shadow shadow;
6989 std::vector<Shadow> shadows { shadow };
6990 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6991 return;
6992 }
6993 Shadow shadow;
6994 if (!ParseShadowProps(jsVal, shadow)) {
6995 info.ReturnSelf();
6996 return;
6997 }
6998 std::vector<Shadow> shadows { shadow };
6999 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
7000 }
7001
JsBlendMode(const JSCallbackInfo & info)7002 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
7003 {
7004 if (info.Length() == 0) {
7005 return;
7006 }
7007 BlendMode blendMode = BlendMode::NONE;
7008 BlendApplyType blendApplyType = BlendApplyType::FAST;
7009 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7010 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7011 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7012 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7013 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7014 if (info[0]->IsNumber()) {
7015 auto blendModeNum = info[0]->ToNumber<int32_t>();
7016 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7017 blendMode = static_cast<BlendMode>(blendModeNum);
7018 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7019 // backward compatibility code, will remove soon
7020 blendMode = BlendMode::SRC_OVER;
7021 blendApplyType = BlendApplyType::OFFSCREEN;
7022 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7023 // backward compatibility code, will remove soon
7024 blendMode = BlendMode::SRC_IN;
7025 blendApplyType = BlendApplyType::OFFSCREEN;
7026 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7027 // backward compatibility code, will remove soon
7028 blendMode = BlendMode::DST_IN;
7029 blendApplyType = BlendApplyType::OFFSCREEN;
7030 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7031 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7032 }
7033 }
7034 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7035 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7036 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7037 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7038 }
7039 }
7040 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7041 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7042 }
7043
JsAdvancedBlendMode(const JSCallbackInfo & info)7044 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
7045 {
7046 if (info.Length() == 0) {
7047 return;
7048 }
7049 BlendMode blendMode = BlendMode::NONE;
7050 BlendApplyType blendApplyType = BlendApplyType::FAST;
7051 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7052 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7053 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7054 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7055 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7056 if (info[0]->IsNumber()) {
7057 auto blendModeNum = info[0]->ToNumber<int32_t>();
7058 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7059 blendMode = static_cast<BlendMode>(blendModeNum);
7060 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7061 // backward compatibility code, will remove soon
7062 blendMode = BlendMode::SRC_OVER;
7063 blendApplyType = BlendApplyType::OFFSCREEN;
7064 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7065 // backward compatibility code, will remove soon
7066 blendMode = BlendMode::SRC_IN;
7067 blendApplyType = BlendApplyType::OFFSCREEN;
7068 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7069 // backward compatibility code, will remove soon
7070 blendMode = BlendMode::DST_IN;
7071 blendApplyType = BlendApplyType::OFFSCREEN;
7072 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7073 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7074 }
7075 } else if (info[0]->IsObject()) {
7076 auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]);
7077 ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender);
7078 }
7079 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7080 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7081 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7082 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7083 }
7084 }
7085 if (!info[0]->IsObject()) {
7086 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7087 }
7088 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7089 }
7090
JsGrayScale(const JSCallbackInfo & info)7091 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
7092 {
7093 CalcDimension value;
7094 if (!ParseJsDimensionVp(info[0], value)) {
7095 value.SetValue(0.0);
7096 ViewAbstractModel::GetInstance()->SetGrayScale(value);
7097 return;
7098 }
7099
7100 if (LessNotEqual(value.Value(), 0.0)) {
7101 value.SetValue(0.0);
7102 }
7103
7104 if (GreatNotEqual(value.Value(), 1.0)) {
7105 value.SetValue(1.0);
7106 }
7107
7108 ViewAbstractModel::GetInstance()->SetGrayScale(value);
7109 }
7110
JsBrightness(const JSCallbackInfo & info)7111 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
7112 {
7113 CalcDimension value;
7114 if (!ParseJsDimensionVp(info[0], value)) {
7115 value.SetValue(1.0);
7116 ViewAbstractModel::GetInstance()->SetBrightness(value);
7117 return;
7118 }
7119
7120 ViewAbstractModel::GetInstance()->SetBrightness(value);
7121 }
7122
JsContrast(const JSCallbackInfo & info)7123 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
7124 {
7125 CalcDimension value;
7126 if (!ParseJsDimensionVp(info[0], value)) {
7127 value.SetValue(1.0);
7128 ViewAbstractModel::GetInstance()->SetContrast(value);
7129 return;
7130 }
7131
7132 if (LessNotEqual(value.Value(), 0.0)) {
7133 value.SetValue(0.0);
7134 }
7135
7136 ViewAbstractModel::GetInstance()->SetContrast(value);
7137 }
7138
JsSaturate(const JSCallbackInfo & info)7139 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
7140 {
7141 CalcDimension value;
7142 if (!ParseJsDimensionVp(info[0], value)) {
7143 value.SetValue(1.0);
7144 ViewAbstractModel::GetInstance()->SetSaturate(value);
7145 return;
7146 }
7147
7148 if (LessNotEqual(value.Value(), 0.0)) {
7149 value.SetValue(0.0);
7150 }
7151
7152 ViewAbstractModel::GetInstance()->SetSaturate(value);
7153 }
7154
JsSepia(const JSCallbackInfo & info)7155 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
7156 {
7157 CalcDimension value;
7158 if (!ParseJsDimensionVp(info[0], value)) {
7159 value.SetValue(0.0);
7160 ViewAbstractModel::GetInstance()->SetSepia(value);
7161 return;
7162 }
7163
7164 if (LessNotEqual(value.Value(), 0.0)) {
7165 value.SetValue(0.0);
7166 }
7167
7168 ViewAbstractModel::GetInstance()->SetSepia(value);
7169 }
7170
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)7171 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
7172 {
7173 double invertValue = 0.0;
7174 if (ParseJsDouble(jsValue, invertValue)) {
7175 invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
7176 return true;
7177 }
7178 auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
7179 if (!argsPtrItem || argsPtrItem->IsNull()) {
7180 return false;
7181 }
7182 InvertOption option;
7183 double low = 0.0;
7184 if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
7185 option.low_ = std::clamp(low, 0.0, 1.0);
7186 }
7187 double high = 0.0;
7188 if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
7189 option.high_ = std::clamp(high, 0.0, 1.0);
7190 }
7191 double threshold = 0.0;
7192 if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
7193 option.threshold_ = std::clamp(threshold, 0.0, 1.0);
7194 }
7195 double thresholdRange = 0.0;
7196 if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
7197 option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
7198 }
7199 invert = option;
7200 return true;
7201 }
7202
JsInvert(const JSCallbackInfo & info)7203 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
7204 {
7205 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
7206 InvertVariant invert = 0.0f;
7207 auto jsVal = info[0];
7208 if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
7209 ViewAbstractModel::GetInstance()->SetInvert(invert);
7210 return;
7211 }
7212 if (ParseInvertProps(jsVal, invert)) {
7213 ViewAbstractModel::GetInstance()->SetInvert(invert);
7214 }
7215 ViewAbstractModel::GetInstance()->SetInvert(invert);
7216 }
7217
JsSystemBarEffect(const JSCallbackInfo & info)7218 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
7219 {
7220 ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
7221 }
7222
JsHueRotate(const JSCallbackInfo & info)7223 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
7224 {
7225 std::optional<float> degree;
7226 JSRef<JSVal> arg = info[0];
7227 if (arg->IsString()) {
7228 degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
7229 } else if (arg->IsNumber()) {
7230 degree = static_cast<float>(arg->ToNumber<int32_t>());
7231 } else {
7232 ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
7233 return;
7234 }
7235 float deg = 0.0f;
7236 if (degree) {
7237 deg = degree.value();
7238 degree.reset();
7239 }
7240 deg = std::fmod(deg, ROUND_UNIT);
7241 if (deg < 0.0f) {
7242 deg += ROUND_UNIT;
7243 }
7244 ViewAbstractModel::GetInstance()->SetHueRotate(deg);
7245 }
7246
JsClip(const JSCallbackInfo & info)7247 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
7248 {
7249 JSRef<JSVal> arg = info[0];
7250 if (arg->IsUndefined()) {
7251 ViewAbstractModel::GetInstance()->SetClipEdge(false);
7252 return;
7253 }
7254 if (arg->IsObject()) {
7255 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7256 if (clipShape == nullptr) {
7257 return;
7258 }
7259 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7260 } else if (arg->IsBoolean()) {
7261 ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
7262 }
7263 }
7264
JsClipShape(const JSCallbackInfo & info)7265 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
7266 {
7267 if (info[0]->IsObject()) {
7268 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7269 if (clipShape == nullptr) {
7270 return;
7271 }
7272 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7273 }
7274 }
7275
JsMask(const JSCallbackInfo & info)7276 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
7277 {
7278 JSRef<JSVal> arg = info[0];
7279 if (!arg->IsObject()) {
7280 ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
7281 return;
7282 }
7283 auto paramObject = JSRef<JSObject>::Cast(arg);
7284 JSRef<JSVal> typeParam = paramObject->GetProperty("type");
7285 if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
7286 typeParam->ToString() == "ProgressMask") {
7287 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
7288 JSRef<JSVal> jValue = paramObject->GetProperty("value");
7289 auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
7290 if (value < 0.0f) {
7291 value = 0.0f;
7292 }
7293 progressMask->SetValue(value);
7294 JSRef<JSVal> jTotal = paramObject->GetProperty("total");
7295 auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
7296 if (total < 0.0f) {
7297 total = DEFAULT_PROGRESS_TOTAL;
7298 }
7299 progressMask->SetMaxValue(total);
7300 JSRef<JSVal> jColor = paramObject->GetProperty("color");
7301 Color colorVal;
7302 if (ParseJsColor(jColor, colorVal)) {
7303 progressMask->SetColor(colorVal);
7304 } else {
7305 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
7306 progressMask->SetColor(theme->GetMaskColor());
7307 }
7308 JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
7309 if (jEnableBreathe->IsBoolean()) {
7310 progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
7311 }
7312 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
7313 } else {
7314 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7315 if (maskShape == nullptr) {
7316 return;
7317 };
7318 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7319 }
7320 }
7321
JsMaskShape(const JSCallbackInfo & info)7322 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
7323 {
7324 if (!info[0]->IsObject()) {
7325 return;
7326 }
7327
7328 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7329 if (maskShape == nullptr) {
7330 return;
7331 };
7332 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7333 }
7334
JsFocusable(const JSCallbackInfo & info)7335 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
7336 {
7337 if (!info[0]->IsBoolean()) {
7338 return;
7339 }
7340 ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
7341 }
7342
JsTabStop(const JSCallbackInfo & info)7343 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
7344 {
7345 if (!info[0]->IsBoolean()) {
7346 ViewAbstractModel::GetInstance()->SetTabStop(false);
7347 return;
7348 }
7349 ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
7350 }
7351
JsFocusBox(const JSCallbackInfo & info)7352 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
7353 {
7354 if (!info[0]->IsObject() || info.Length() != 1) {
7355 return;
7356 }
7357 auto obj = JSRef<JSObject>::Cast(info[0]);
7358 NG::FocusBoxStyle style;
7359
7360 CalcDimension margin;
7361 if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) {
7362 style.margin = margin;
7363 }
7364 CalcDimension strokeWidth;
7365 if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) {
7366 style.strokeWidth = strokeWidth;
7367 }
7368 Color strokeColor;
7369 if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) {
7370 style.strokeColor = strokeColor;
7371 }
7372
7373 ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
7374 }
7375
JsOnFocusMove(const JSCallbackInfo & args)7376 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
7377 {
7378 JSRef<JSVal> arg = args[0];
7379 if (arg->IsFunction()) {
7380 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7381 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7382 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
7383 int info) {
7384 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7385 ACE_SCORING_EVENT("onFocusMove");
7386 PipelineContext::SetCallBackNode(node);
7387 func->Execute(info);
7388 };
7389 ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
7390 }
7391 }
7392
JsOnKeyEvent(const JSCallbackInfo & args)7393 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
7394 {
7395 JSRef<JSVal> arg = args[0];
7396 if (arg->IsUndefined() && IsDisableEventVersion()) {
7397 ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
7398 return;
7399 }
7400 if (!arg->IsFunction()) {
7401 return;
7402 }
7403 RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
7404 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7405 auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
7406 KeyEventInfo& info) -> bool {
7407 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
7408 ACE_SCORING_EVENT("onKey");
7409 PipelineContext::SetCallBackNode(node);
7410 auto ret = func->ExecuteWithValue(info);
7411 return ret->IsBoolean() ? ret->ToBoolean() : false;
7412 };
7413 ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
7414 }
7415
JsOnFocus(const JSCallbackInfo & args)7416 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
7417 {
7418 JSRef<JSVal> arg = args[0];
7419 if (arg->IsUndefined() && IsDisableEventVersion()) {
7420 ViewAbstractModel::GetInstance()->DisableOnFocus();
7421 return;
7422 }
7423 if (!arg->IsFunction()) {
7424 return;
7425 }
7426 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7427 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7428 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
7429 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7430 ACE_SCORING_EVENT("onFocus");
7431 PipelineContext::SetCallBackNode(node);
7432 func->Execute();
7433 };
7434
7435 ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
7436 }
7437
JsOnBlur(const JSCallbackInfo & args)7438 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
7439 {
7440 JSRef<JSVal> arg = args[0];
7441 if (arg->IsUndefined() && IsDisableEventVersion()) {
7442 ViewAbstractModel::GetInstance()->DisableOnBlur();
7443 return;
7444 }
7445 if (!arg->IsFunction()) {
7446 return;
7447 }
7448 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7449 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7450 auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
7451 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7452 ACE_SCORING_EVENT("onBlur");
7453 PipelineContext::SetCallBackNode(node);
7454 func->Execute();
7455 };
7456
7457 ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
7458 }
7459
JsTabIndex(const JSCallbackInfo & info)7460 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
7461 {
7462 JSRef<JSVal> arg = info[0];
7463 if (!arg->IsNumber()) {
7464 return;
7465 }
7466 ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
7467 }
7468
JsFocusOnTouch(const JSCallbackInfo & info)7469 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
7470 {
7471 JSRef<JSVal> arg = info[0];
7472 if (!arg->IsBoolean()) {
7473 return;
7474 }
7475 auto isFocusOnTouch = arg->ToBoolean();
7476 ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
7477 }
7478
JsDefaultFocus(const JSCallbackInfo & info)7479 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
7480 {
7481 JSRef<JSVal> arg = info[0];
7482 if (!arg->IsBoolean()) {
7483 return;
7484 }
7485 auto isDefaultFocus = arg->ToBoolean();
7486 ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
7487 }
7488
JsGroupDefaultFocus(const JSCallbackInfo & info)7489 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
7490 {
7491 JSRef<JSVal> arg = info[0];
7492 if (!arg->IsBoolean()) {
7493 return;
7494 }
7495 auto isGroupDefaultFocus = arg->ToBoolean();
7496 ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
7497 }
7498
JsKey(const std::string & key)7499 void JSViewAbstract::JsKey(const std::string& key)
7500 {
7501 ViewAbstractModel::GetInstance()->SetInspectorId(key);
7502 }
7503
JsId(const JSCallbackInfo & info)7504 void JSViewAbstract::JsId(const JSCallbackInfo& info)
7505 {
7506 JSRef<JSVal> arg = info[0];
7507 if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
7508 return;
7509 }
7510 std::string id = arg->ToString();
7511 if (id.empty()) {
7512 return;
7513 }
7514 JsKey(id);
7515 }
7516
JsRestoreId(int32_t restoreId)7517 void JSViewAbstract::JsRestoreId(int32_t restoreId)
7518 {
7519 ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
7520 }
7521
JsDebugLine(const JSCallbackInfo & info)7522 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
7523 {
7524 std::string debugLine;
7525 auto length = info.Length();
7526 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
7527
7528 if (length == 1) { // deprecated version of debug line
7529 auto jsVal = info[0];
7530 if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
7531 return;
7532 }
7533 debugLine = jsVal->ToString();
7534 } else if (length == 2) { // debug line with extra package name
7535 auto line = info[0];
7536 auto packageName = info[1];
7537 if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
7538 !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
7539 return;
7540 }
7541 auto json = JsonUtil::Create(true);
7542 json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
7543 json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
7544 debugLine = json->ToString();
7545 }
7546
7547 ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
7548 }
7549
JsOpacityPassThrough(const JSCallbackInfo & info)7550 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
7551 {
7552 double opacity = 1.0;
7553 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7554 if (ParseJsDouble(info[0], opacity)) {
7555 opacity = std::clamp(opacity, 0.0, 1.0);
7556 }
7557 } else {
7558 if (!ParseJsDouble(info[0], opacity)) {
7559 return;
7560 }
7561 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
7562 opacity = 1.0;
7563 }
7564 }
7565
7566 ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
7567 }
7568
JsTransitionPassThrough(const JSCallbackInfo & info)7569 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
7570 {
7571 if (info.Length() == 0) {
7572 ViewAbstractModel::GetInstance()->SetTransition(
7573 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
7574 return;
7575 }
7576 if (!info[0]->IsObject()) {
7577 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7578 ViewAbstractModel::GetInstance()->CleanTransition();
7579 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
7580 }
7581 return;
7582 }
7583 auto obj = JSRef<JSObject>::Cast(info[0]);
7584 if (!obj->GetProperty("successor_")->IsUndefined()) {
7585 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
7586 std::function<void(bool)> finishCallback;
7587 if (info.Length() > 1 && info[1]->IsFunction()) {
7588 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
7589 }
7590 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
7591 return;
7592 }
7593 auto options = ParseJsTransition(obj);
7594 ViewAbstractModel::GetInstance()->SetTransition(options, true);
7595 }
7596
JsAccessibilityGroup(const JSCallbackInfo & info)7597 void JSViewAbstract::JsAccessibilityGroup(const JSCallbackInfo& info)
7598 {
7599 bool isGroup = false;
7600 if (info[0]->IsBoolean()) {
7601 isGroup = info[0]->ToBoolean();
7602 }
7603 ViewAbstractModel::GetInstance()->SetAccessibilityGroup(isGroup);
7604
7605 if (info.Length() > 1 && info[1]->IsObject()) {
7606 auto obj = JSRef<JSObject>::Cast(info[1]);
7607
7608 auto preferAccessibilityTextObj = obj->GetProperty("accessibilityPreferred");
7609 auto preferAccessibilityText = preferAccessibilityTextObj->IsBoolean() ? preferAccessibilityTextObj->ToBoolean() : false;
7610 ViewAbstractModel::GetInstance()->SetAccessibilityTextPreferred(preferAccessibilityText);
7611 }
7612 }
7613
JsAccessibilityText(const JSCallbackInfo & info)7614 void JSViewAbstract::JsAccessibilityText(const JSCallbackInfo& info)
7615 {
7616 const JSRef<JSVal>& jsValue = info[0];
7617 std::string text;
7618 if (!ParseJsString(jsValue, text)) {
7619 return;
7620 }
7621 ViewAbstractModel::GetInstance()->SetAccessibilityText(text);
7622 }
7623
JsAccessibilityTextHint(const std::string & text)7624 void JSViewAbstract::JsAccessibilityTextHint(const std::string& text)
7625 {
7626 ViewAbstractModel::GetInstance()->SetAccessibilityTextHint(text);
7627 }
7628
JsAccessibilityDescription(const JSCallbackInfo & info)7629 void JSViewAbstract::JsAccessibilityDescription(const JSCallbackInfo& info)
7630 {
7631 const JSRef<JSVal>& jsValue = info[0];
7632 std::string description;
7633 if (!ParseJsString(jsValue, description)) {
7634 return;
7635 }
7636 std::pair<bool, std::string> autoEventPair(false, "");
7637 std::pair<bool, std::string> descriptionPair(false, "");
7638 ParseAccessibilityDescriptionJson(description, autoEventPair, descriptionPair);
7639 if (descriptionPair.first) {
7640 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(descriptionPair.second);
7641 } else {
7642 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description);
7643 }
7644 if (autoEventPair.first) {
7645 ViewAbstractModel::GetInstance()->SetAutoEventParam(autoEventPair.second);
7646 }
7647 }
7648
ParseAccessibilityDescriptionJson(const std::string & description,std::pair<bool,std::string> & autoEventPair,std::pair<bool,std::string> & descriptionPair)7649 void JSViewAbstract::ParseAccessibilityDescriptionJson(const std::string& description,
7650 std::pair<bool, std::string>& autoEventPair, std::pair<bool, std::string>& descriptionPair)
7651 {
7652 if (description.empty()) {
7653 return;
7654 }
7655 if (!StartWith(description, "{") || !EndWith(description, "}")) {
7656 return;
7657 }
7658 auto jsonObj = JsonUtil::ParseJsonString(description);
7659 if (!jsonObj || !jsonObj->IsValid() || !jsonObj->IsObject()) {
7660 return;
7661 }
7662 if (jsonObj->Contains("$autoEventParam")) {
7663 auto param = jsonObj->GetValue("$autoEventParam");
7664 if (param) {
7665 autoEventPair = std::make_pair(true, param->ToString());
7666 }
7667 }
7668 if (jsonObj->Contains("$accessibilityDescription")) {
7669 descriptionPair = std::make_pair(true, jsonObj->GetString("$accessibilityDescription"));
7670 } else if (jsonObj->Contains("$autoEventParam")) {
7671 descriptionPair = std::make_pair(true, "");
7672 }
7673 }
7674
JsAccessibilityImportance(const std::string & importance)7675 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
7676 {
7677 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance);
7678 }
7679
JsAccessibilityLevel(const std::string & level)7680 void JSViewAbstract::JsAccessibilityLevel(const std::string& level)
7681 {
7682 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level);
7683 }
7684
JsAccessibilityVirtualNode(const JSCallbackInfo & info)7685 void JSViewAbstract::JsAccessibilityVirtualNode(const JSCallbackInfo& info)
7686 {
7687 // parse builder
7688 if (!info[0]->IsObject()) {
7689 return;
7690 }
7691 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7692 auto builder = obj->GetProperty("builder");
7693 if (builder->IsFunction()) {
7694 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7695 CHECK_NULL_VOID(builderFunc);
7696 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
7697 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7698 ACE_SCORING_EVENT("AccessibilityVirtualNode");
7699 func->Execute();
7700 };
7701 NG::ViewAbstractModelNG::GetInstance()->SetAccessibilityVirtualNode(std::move(buildFunc));
7702 }
7703 }
7704
JsAccessibilitySelected(const JSCallbackInfo & info)7705 void JSViewAbstract::JsAccessibilitySelected(const JSCallbackInfo& info)
7706 {
7707 bool selected = false;
7708 bool resetValue = false;
7709 JSRef<JSVal> arg = info[0];
7710 if (arg->IsUndefined()) {
7711 resetValue = true;
7712 } else if (arg->IsBoolean()) {
7713 selected = arg->ToBoolean();
7714 } else {
7715 return;
7716 }
7717
7718 ViewAbstractModel::GetInstance()->SetAccessibilitySelected(selected, resetValue);
7719 }
7720
JsAccessibilityChecked(const JSCallbackInfo & info)7721 void JSViewAbstract::JsAccessibilityChecked(const JSCallbackInfo& info)
7722 {
7723 bool checked = false;
7724 bool resetValue = false;
7725 JSRef<JSVal> arg = info[0];
7726 if (arg->IsUndefined()) {
7727 resetValue = true;
7728 } else if (arg->IsBoolean()) {
7729 checked = arg->ToBoolean();
7730 } else {
7731 return;
7732 }
7733
7734 ViewAbstractModel::GetInstance()->SetAccessibilityChecked(checked, resetValue);
7735 }
7736
JsBackground(const JSCallbackInfo & info)7737 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
7738 {
7739 // Check the parameters
7740 if (info.Length() <= 0 || !info[0]->IsObject()) {
7741 return;
7742 }
7743 JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
7744 auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
7745 if (!builder->IsFunction()) {
7746 return;
7747 }
7748 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7749 CHECK_NULL_VOID(builderFunc);
7750 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7751 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7752 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7753 ACE_SCORING_EVENT("BindBackground");
7754 PipelineContext::SetCallBackNode(node);
7755 func->Execute();
7756 };
7757 Alignment alignment = Alignment::CENTER;
7758 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
7759 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
7760 auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
7761 auto value = align->ToNumber<int32_t>();
7762 alignment = ParseAlignment(value);
7763 }
7764 ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
7765 }
7766
JsBindContextMenu(const JSCallbackInfo & info)7767 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
7768 {
7769 NG::MenuParam menuParam;
7770 // Check the parameters
7771 if (info.Length() <= 0) {
7772 return;
7773 }
7774 size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
7775 if (!info[builderIndex]->IsObject()) {
7776 return;
7777 }
7778
7779 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
7780 auto builder = menuObj->GetProperty("builder");
7781 if (!builder->IsFunction()) {
7782 return;
7783 }
7784 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7785 CHECK_NULL_VOID(builderFunc);
7786
7787 ResponseType responseType = ResponseType::LONG_PRESS;
7788 if (!info[0]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7789 auto response = info[1]->ToNumber<int32_t>();
7790 responseType = static_cast<ResponseType>(response);
7791 }
7792 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7793 std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
7794 node = frameNode]() {
7795 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7796 ACE_SCORING_EVENT("BuildContextMenu");
7797 PipelineContext::SetCallBackNode(node);
7798 func->Execute();
7799 };
7800
7801 menuParam.previewMode = MenuPreviewMode::NONE;
7802 std::function<void()> previewBuildFunc = nullptr;
7803 if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) {
7804 ParseBindContentOptionParam(info, info[2], menuParam, previewBuildFunc);
7805 }
7806
7807 if (responseType != ResponseType::LONG_PRESS) {
7808 menuParam.previewMode = MenuPreviewMode::NONE;
7809 menuParam.isShowHoverImage = false;
7810 menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
7811 }
7812 menuParam.type = NG::MenuType::CONTEXT_MENU;
7813 ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
7814 ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
7815 }
7816
ParseBindContentCoverIsShow(const JSCallbackInfo & info)7817 bool ParseBindContentCoverIsShow(const JSCallbackInfo& info)
7818 {
7819 bool isShow = false;
7820 if (info[0]->IsBoolean()) {
7821 isShow = info[0]->ToBoolean();
7822 } else if (info[0]->IsObject()) {
7823 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7824 auto isShowObj = callbackObj->GetProperty("value");
7825 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7826 }
7827 TAG_LOGD(AceLogTag::ACE_SHEET, "ContentCover get isShow is: %{public}d", isShow);
7828 return isShow;
7829 }
7830
JsBindContentCover(const JSCallbackInfo & info)7831 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
7832 {
7833 // parse isShow
7834 bool isShow = ParseBindContentCoverIsShow(info);
7835 DoubleBindCallback callback = nullptr;
7836 if (info[0]->IsObject()) {
7837 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7838 callback = ParseDoubleBindCallback(info, callbackObj);
7839 }
7840
7841 // parse builder
7842 if (!info[1]->IsObject()) {
7843 return;
7844 }
7845 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7846 auto builder = obj->GetProperty("builder");
7847 if (!builder->IsFunction()) {
7848 return;
7849 }
7850 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7851 CHECK_NULL_VOID(builderFunc);
7852 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7853 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7854 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7855 ACE_SCORING_EVENT("BindContentCover");
7856 PipelineContext::SetCallBackNode(node);
7857 func->Execute();
7858 };
7859
7860 // parse ModalTransition
7861 NG::ModalStyle modalStyle;
7862 modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
7863 std::function<void()> onShowCallback;
7864 std::function<void()> onDismissCallback;
7865 std::function<void()> onWillShowCallback;
7866 std::function<void()> onWillDismissCallback;
7867 NG::ContentCoverParam contentCoverParam;
7868 std::function<void(const int32_t&)> onWillDismissFunc;
7869 if (info.Length() == 3) {
7870 if (info[2]->IsObject()) {
7871 ParseOverlayCallback(info[2], onShowCallback, onDismissCallback, onWillShowCallback, /* 2:args index */
7872 onWillDismissCallback, onWillDismissFunc);
7873 ParseModalStyle(info[2], modalStyle);
7874 contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
7875 ParseModalTransitonEffect(info[2], contentCoverParam, info.GetExecutionContext()); /* 2:args index */
7876 } else if (info[2]->IsNumber()) {
7877 auto transitionNumber = info[2]->ToNumber<int32_t>();
7878 if (transitionNumber >= 0 && transitionNumber <= 2) {
7879 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7880 }
7881 }
7882 }
7883 ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
7884 std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
7885 std::move(onWillDismissCallback), contentCoverParam);
7886 }
7887
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)7888 void JSViewAbstract::ParseModalTransitonEffect(
7889 const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
7890 {
7891 auto transitionEffectValue = paramObj->GetProperty("transition");
7892 if (transitionEffectValue->IsObject()) {
7893 JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
7894 contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
7895 }
7896 }
7897
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)7898 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
7899 {
7900 auto modalTransition = paramObj->GetProperty("modalTransition");
7901 auto backgroundColor = paramObj->GetProperty("backgroundColor");
7902 if (modalTransition->IsNumber()) {
7903 auto transitionNumber = modalTransition->ToNumber<int32_t>();
7904 if (transitionNumber >= 0 && transitionNumber <= 2) {
7905 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7906 }
7907 }
7908 Color color;
7909 if (ParseJsColor(backgroundColor, color)) {
7910 modalStyle.backgroundColor = color;
7911 }
7912 }
7913
ParseSheetIsShow(const JSCallbackInfo & info,bool & isShow,std::function<void (const std::string &)> & callback)7914 void JSViewAbstract::ParseSheetIsShow(
7915 const JSCallbackInfo& info, bool& isShow, std::function<void(const std::string&)>& callback)
7916 {
7917 if (info[0]->IsBoolean()) {
7918 isShow = info[0]->ToBoolean();
7919 } else if (info[0]->IsObject()) {
7920 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7921 callback = ParseDoubleBindCallback(info, callbackObj);
7922 auto isShowObj = callbackObj->GetProperty("value");
7923 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7924 }
7925 TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet get isShow is: %{public}d", isShow);
7926 }
7927
JsBindSheet(const JSCallbackInfo & info)7928 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
7929 {
7930 // parse isShow and builder
7931 bool isShow = false;
7932 DoubleBindCallback callback = nullptr;
7933 ParseSheetIsShow(info, isShow, callback);
7934 if (!info[1]->IsObject())
7935 return;
7936 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7937 auto builder = obj->GetProperty("builder");
7938 if (!builder->IsFunction())
7939 return;
7940 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7941 CHECK_NULL_VOID(builderFunc);
7942 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7943 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7944 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7945 ACE_SCORING_EVENT("BindSheet");
7946 PipelineContext::SetCallBackNode(node);
7947 func->Execute();
7948 };
7949 // parse SheetStyle and callbacks
7950 NG::SheetStyle sheetStyle;
7951 sheetStyle.sheetMode = NG::SheetMode::LARGE;
7952 sheetStyle.showDragBar = true;
7953 sheetStyle.showCloseIcon = true;
7954 sheetStyle.showInPage = false;
7955 std::function<void()> onAppearCallback;
7956 std::function<void()> onDisappearCallback;
7957 std::function<void()> onWillAppearCallback;
7958 std::function<void()> onWillDisappearCallback ;
7959 std::function<void()> shouldDismissFunc;
7960 std::function<void(const int32_t)> onWillDismissCallback;
7961 std::function<void(const float)> onHeightDidChangeCallback;
7962 std::function<void(const float)> onDetentsDidChangeCallback;
7963 std::function<void(const float)> onWidthDidChangeCallback;
7964 std::function<void(const float)> onTypeDidChangeCallback;
7965 std::function<void()> titleBuilderFunction;
7966 std::function<void()> sheetSpringBackFunc;
7967 if (info.Length() == PARAMETER_LENGTH_THIRD && info[SECOND_INDEX]->IsObject()) {
7968 ParseSheetCallback(info[SECOND_INDEX], onAppearCallback, onDisappearCallback, shouldDismissFunc,
7969 onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
7970 onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
7971 ParseSheetStyle(info[2], sheetStyle);
7972 ParseSheetTitle(info[2], sheetStyle, titleBuilderFunction);
7973 }
7974 ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
7975 std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
7976 std::move(shouldDismissFunc), std::move(onWillDismissCallback), std::move(onWillAppearCallback),
7977 std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
7978 std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
7979 }
7980
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)7981 void JSViewAbstract::ParseSheetStyle(
7982 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
7983 {
7984 auto height = paramObj->GetProperty("height");
7985 auto showDragBar = paramObj->GetProperty("dragBar");
7986 auto backgroundColor = paramObj->GetProperty("backgroundColor");
7987 auto maskColor = paramObj->GetProperty("maskColor");
7988 auto sheetDetents = paramObj->GetProperty("detents");
7989 auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
7990 auto showCloseIcon = paramObj->GetProperty("showClose");
7991 auto type = paramObj->GetProperty("preferType");
7992 auto interactive = paramObj->GetProperty("enableOutsideInteractive");
7993 auto showMode = paramObj->GetProperty("mode");
7994 auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
7995 auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
7996 auto uiContextObj = paramObj->GetProperty("uiContext");
7997 if (uiContextObj->IsObject()) {
7998 JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
7999 auto prop = obj->GetProperty("instanceId_");
8000 if (prop->IsNumber()) {
8001 sheetStyle.instanceId = prop->ToNumber<int32_t>();
8002 }
8003 }
8004 NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
8005 if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
8006 sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
8007 }
8008
8009 std::vector<NG::SheetHeight> detents;
8010 if (ParseSheetDetents(sheetDetents, detents)) {
8011 sheetStyle.detents = detents;
8012 }
8013 BlurStyleOption styleOption;
8014 if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
8015 sheetStyle.backgroundBlurStyle = styleOption;
8016 }
8017 bool showClose = true;
8018 if (ParseJsBool(showCloseIcon, showClose)) {
8019 sheetStyle.showCloseIcon = showClose;
8020 } else if (!isPartialUpdate) {
8021 sheetStyle.showCloseIcon = true;
8022 }
8023
8024 bool isInteractive = false;
8025 if (ParseJsBool(interactive, isInteractive)) {
8026 sheetStyle.interactive = isInteractive;
8027 }
8028
8029 if (showDragBar->IsBoolean()) {
8030 sheetStyle.showDragBar = showDragBar->ToBoolean();
8031 } else if (isPartialUpdate) {
8032 sheetStyle.showDragBar.reset();
8033 } else {
8034 sheetStyle.showDragBar = true;
8035 }
8036
8037 if (type->IsNull() || type->IsUndefined()) {
8038 sheetStyle.sheetType.reset();
8039 } else {
8040 if (type->IsNumber()) {
8041 auto sheetType = type->ToNumber<int32_t>();
8042 if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
8043 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
8044 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
8045 }
8046 }
8047 }
8048 if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
8049 sheetStyle.scrollSizeMode.reset();
8050 } else if (scrollSizeMode->IsNumber()) {
8051 auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
8052 if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
8053 sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
8054 sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
8055 }
8056 }
8057
8058 if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
8059 sheetStyle.sheetKeyboardAvoidMode.reset();
8060 } else if (keyboardAvoidMode->IsNumber()) {
8061 auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
8062 if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
8063 sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) {
8064 sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
8065 }
8066 }
8067
8068 Color color;
8069 if (ParseJsColor(backgroundColor, color)) {
8070 sheetStyle.backgroundColor = color;
8071 }
8072 // parse maskColor
8073 Color parseMaskColor;
8074 if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
8075 sheetStyle.maskColor = std::move(parseMaskColor);
8076 }
8077
8078 // Parse border width
8079 auto borderWidthValue = paramObj->GetProperty("borderWidth");
8080 NG::BorderWidthProperty borderWidth;
8081 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
8082 sheetStyle.borderWidth = borderWidth;
8083 // Parse border color
8084 auto colorValue = paramObj->GetProperty("borderColor");
8085 NG::BorderColorProperty borderColor;
8086 if (ParseBorderColorProps(colorValue, borderColor)) {
8087 sheetStyle.borderColor = borderColor;
8088 } else {
8089 sheetStyle.borderColor =
8090 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
8091 }
8092 // Parse border style
8093 auto styleValue = paramObj->GetProperty("borderStyle");
8094 NG::BorderStyleProperty borderStyle;
8095 if (ParseBorderStyleProps(styleValue, borderStyle)) {
8096 sheetStyle.borderStyle = borderStyle;
8097 } else {
8098 sheetStyle.borderStyle = NG::BorderStyleProperty(
8099 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
8100 }
8101 }
8102 if (isPartialUpdate) {
8103 auto colorValue = paramObj->GetProperty("borderColor");
8104 NG::BorderColorProperty borderColor;
8105 if (ParseBorderColorProps(colorValue, borderColor)) {
8106 sheetStyle.borderColor = borderColor;
8107 } else {
8108 sheetStyle.borderColor.reset();
8109 }
8110 auto styleValue = paramObj->GetProperty("borderStyle");
8111 NG::BorderStyleProperty borderStyle;
8112 if (ParseBorderStyleProps(styleValue, borderStyle)) {
8113 sheetStyle.borderStyle = borderStyle;
8114 } else {
8115 sheetStyle.borderStyle.reset();
8116 }
8117 }
8118
8119 // Parse shadow
8120 Shadow shadow;
8121 auto shadowValue = paramObj->GetProperty("shadow");
8122 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
8123 sheetStyle.shadow = shadow;
8124 }
8125
8126 // Parse hoverMode
8127 auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode");
8128 if (enableHoverModeValue->IsBoolean()) {
8129 sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean();
8130 }
8131 auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea");
8132 if (hoverModeAreaValue->IsNumber()) {
8133 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
8134 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
8135 sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
8136 }
8137 }
8138
8139 auto widthValue = paramObj->GetProperty("width");
8140 CalcDimension width;
8141 if (ParseJsDimensionVpNG(widthValue, width, true)) {
8142 sheetStyle.width = width;
8143 }
8144
8145 CalcDimension sheetHeight;
8146 if (height->IsString()) {
8147 std::string heightStr = height->ToString();
8148 // Remove all " ".
8149 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8150 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8151 if (heightStr == SHEET_HEIGHT_MEDIUM) {
8152 sheetStyle.sheetMode = NG::SheetMode::MEDIUM;
8153 sheetStyle.height.reset();
8154 return;
8155 }
8156 if (heightStr == SHEET_HEIGHT_LARGE) {
8157 sheetStyle.sheetMode = NG::SheetMode::LARGE;
8158 sheetStyle.height.reset();
8159 return;
8160 }
8161 if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8162 sheetStyle.sheetMode = NG::SheetMode::AUTO;
8163 sheetStyle.height.reset();
8164 return;
8165 }
8166 if (heightStr.find("calc") != std::string::npos) {
8167 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8168 } else {
8169 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8170 }
8171 if (sheetHeight.Value() < 0) {
8172 sheetStyle.sheetMode = NG::SheetMode::LARGE;
8173 sheetStyle.height.reset();
8174 return;
8175 }
8176 }
8177 if (!ParseJsDimensionVpNG(height, sheetHeight)) {
8178 if (isPartialUpdate) {
8179 sheetStyle.sheetMode.reset();
8180 } else {
8181 sheetStyle.sheetMode = NG::SheetMode::LARGE;
8182 }
8183 sheetStyle.height.reset();
8184 } else {
8185 sheetStyle.height = sheetHeight;
8186 sheetStyle.sheetMode.reset();
8187 }
8188 }
8189
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)8190 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
8191 {
8192 if (!args->IsArray()) {
8193 return false;
8194 }
8195 JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
8196 NG::SheetHeight sheetDetent;
8197 for (size_t i = 0; i < array->Length(); i++) {
8198 ParseSheetDetentHeight(array->GetValueAt(i), sheetDetent);
8199 if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
8200 continue;
8201 }
8202 sheetDetents.emplace_back(sheetDetent);
8203 sheetDetent.height.reset();
8204 sheetDetent.sheetMode.reset();
8205 }
8206 return true;
8207 }
8208
ParseSheetDetentHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent)8209 void JSViewAbstract::ParseSheetDetentHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent)
8210 {
8211 CalcDimension sheetHeight;
8212 if (args->IsString()) {
8213 std::string heightStr = args->ToString();
8214 // Remove all " ".
8215 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8216 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8217 if (heightStr == SHEET_HEIGHT_MEDIUM) {
8218 detent.sheetMode = NG::SheetMode::MEDIUM;
8219 detent.height.reset();
8220 return;
8221 }
8222 if (heightStr == SHEET_HEIGHT_LARGE) {
8223 detent.sheetMode = NG::SheetMode::LARGE;
8224 detent.height.reset();
8225 return;
8226 }
8227 if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8228 detent.sheetMode = NG::SheetMode::AUTO;
8229 detent.height.reset();
8230 return;
8231 }
8232 if (heightStr.find("calc") != std::string::npos) {
8233 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8234 } else {
8235 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8236 }
8237 if (sheetHeight.Value() < 0) {
8238 detent.sheetMode = NG::SheetMode::LARGE;
8239 detent.height.reset();
8240 return;
8241 }
8242 }
8243 if (!ParseJsDimensionVpNG(args, sheetHeight)) {
8244 detent.sheetMode = NG::SheetMode::LARGE;
8245 detent.height.reset();
8246 } else {
8247 detent.height = sheetHeight;
8248 detent.sheetMode.reset();
8249 }
8250 }
8251
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)8252 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
8253 {
8254 if (args->IsNumber()) {
8255 auto sheetBlurStyle = args->ToNumber<int32_t>();
8256 if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
8257 sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
8258 blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
8259 } else {
8260 return false;
8261 }
8262 } else {
8263 return false;
8264 }
8265 return true;
8266 }
8267
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)8268 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
8269 {
8270 if (!args->IsNumber()) {
8271 return false;
8272 }
8273 auto sheetMode = args->ToNumber<int32_t>();
8274 if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
8275 sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
8276 sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
8277 return true;
8278 }
8279 return false;
8280 }
8281
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)8282 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
8283 std::function<void(const float)>& callbackDidChange, const char* prop)
8284 {
8285 auto callBack = paramObj->GetProperty(prop);
8286 if (callBack->IsFunction()) {
8287 RefPtr<JsFunction> jsFunc =
8288 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
8289 callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
8290 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
8291 func->ExecuteJS(1, ¶m);
8292 };
8293 }
8294 }
8295
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)8296 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
8297 std::function<void()>& lifeCycleCallBack, const char* prop)
8298 {
8299 auto callback = paramObj->GetProperty(prop);
8300 if (callback->IsFunction()) {
8301 RefPtr<JsFunction> jsFunc =
8302 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8303 lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
8304 }
8305 }
8306
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)8307 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
8308 std::function<void()>& sheetSpringBack, const char* prop)
8309 {
8310 auto sheetSpringBackCallback = paramObj->GetProperty(prop);
8311 if (sheetSpringBackCallback->IsFunction()) {
8312 RefPtr<JsFunction> jsFunc =
8313 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
8314 sheetSpringBack = [func = std::move(jsFunc)]() {
8315 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8316 objectTemplate->SetInternalFieldCount(1);
8317 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8318 dismissObj->SetPropertyObject(
8319 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
8320 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8321 func->ExecuteJS(1, &newJSVal);
8322 };
8323 }
8324 }
8325
ParseSheetCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & shouldDismiss,std::function<void (const int32_t info)> & onWillDismiss,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const float)> & onHeightDidChange,std::function<void (const float)> & onDetentsDidChange,std::function<void (const float)> & onWidthDidChange,std::function<void (const float)> & onTypeDidChange,std::function<void ()> & sheetSpringBack)8326 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8327 std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
8328 std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
8329 std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
8330 std::function<void(const float)>& onDetentsDidChange,
8331 std::function<void(const float)>& onWidthDidChange,
8332 std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
8333 {
8334 auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
8335 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8336 ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
8337 ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
8338 ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
8339 ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
8340 if (shouldDismissFunc->IsFunction()) {
8341 RefPtr<JsFunction> jsFunc =
8342 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
8343 shouldDismiss = [func = std::move(jsFunc)]() {
8344 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8345 objectTemplate->SetInternalFieldCount(1);
8346 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8347 dismissObj->SetPropertyObject(
8348 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8349 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8350 func->ExecuteJS(1, &newJSVal);
8351 };
8352 }
8353 if (onWillDismissFunc->IsFunction()) {
8354 RefPtr<JsFunction> jsFunc =
8355 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8356 onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
8357 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8358 objectTemplate->SetInternalFieldCount(1);
8359 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8360 dismissObj->SetPropertyObject(
8361 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8362 dismissObj->SetProperty<int32_t>("reason", info);
8363 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8364 func->ExecuteJS(1, &newJSVal);
8365 };
8366 }
8367 ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
8368 ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
8369 ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
8370 ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
8371 ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
8372 }
8373
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)8374 void JSViewAbstract::ParseSheetTitle(
8375 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
8376 {
8377 auto title = paramObj->GetProperty("title");
8378 std::string mainTitle;
8379 std::string subtitle;
8380 if (title->IsFunction()) {
8381 sheetStyle.isTitleBuilder = true;
8382 auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
8383 CHECK_NULL_VOID(titleBuilderFunc);
8384 titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
8385 ACE_SCORING_EVENT("BindSheet");
8386 func->Execute();
8387 };
8388 } else if (title->IsObject()) {
8389 JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
8390 sheetStyle.isTitleBuilder = false;
8391 auto sheetTitle = obj->GetProperty("title");
8392 auto sheetSubtitle = obj->GetProperty("subtitle");
8393 if (ParseJsString(sheetTitle, mainTitle)) {
8394 sheetStyle.sheetTitle = mainTitle;
8395 }
8396 if (ParseJsString(sheetSubtitle, subtitle)) {
8397 sheetStyle.sheetSubtitle = subtitle;
8398 }
8399 }
8400 }
8401
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)8402 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8403 {
8404 ViewAbstractModel::GetInstance()->DismissSheet();
8405 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8406 }
8407
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)8408 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8409 {
8410 ViewAbstractModel::GetInstance()->DismissContentCover();
8411 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8412 }
8413
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)8414 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8415 {
8416 ViewAbstractModel::GetInstance()->SheetSpringBack();
8417 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8418 }
8419
ParseOverlayCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const int32_t & info)> & onWillDismiss)8420 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8421 std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
8422 std::function<void(const int32_t& info)>& onWillDismiss)
8423 {
8424 auto showCallback = paramObj->GetProperty("onAppear");
8425 auto dismissCallback = paramObj->GetProperty("onDisappear");
8426 auto willShowCallback = paramObj->GetProperty("onWillAppear");
8427 auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
8428 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8429 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8430 if (showCallback->IsFunction()) {
8431 RefPtr<JsFunction> jsFunc =
8432 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
8433 onAppear = [func = std::move(jsFunc), node = frameNode]() {
8434 PipelineContext::SetCallBackNode(node);
8435 func->Execute();
8436 };
8437 }
8438 if (dismissCallback->IsFunction()) {
8439 RefPtr<JsFunction> jsFunc =
8440 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
8441 onDisappear = [func = std::move(jsFunc), node = frameNode]() {
8442 PipelineContext::SetCallBackNode(node);
8443 func->Execute();
8444 };
8445 }
8446 if (willShowCallback->IsFunction()) {
8447 RefPtr<JsFunction> jsFunc =
8448 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
8449 onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
8450 }
8451 if (willDismissCallback->IsFunction()) {
8452 RefPtr<JsFunction> jsFunc =
8453 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
8454 onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
8455 }
8456 if (onWillDismissFunc->IsFunction()) {
8457 RefPtr<JsFunction> jsFunc =
8458 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8459 onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
8460 ACE_SCORING_EVENT("contentCover.dismiss");
8461 PipelineContext::SetCallBackNode(node);
8462 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8463 objectTemplate->SetInternalFieldCount(1);
8464 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8465 dismissObj->SetPropertyObject(
8466 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
8467 dismissObj->SetProperty<int32_t>("reason", info);
8468 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8469 func->ExecuteJS(1, &newJSVal);
8470 };
8471 }
8472 }
8473
JSCreateAnimatableProperty(const JSCallbackInfo & info)8474 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
8475 {
8476 if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
8477 return;
8478 }
8479
8480 JSRef<JSVal> callback = info[2]; /* 2:args index */
8481 if (!callback->IsFunction()) {
8482 return;
8483 }
8484 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8485 std::string propertyName = info[0]->ToString();
8486 if (info[1]->IsNumber()) {
8487 float numValue = info[1]->ToNumber<float>();
8488 std::function<void(float)> onCallbackEvent;
8489 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8490 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8491 node = frameNode](const float val) {
8492 ContainerScope scope(id);
8493 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8494 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
8495 PipelineContext::SetCallBackNode(node);
8496 func->ExecuteJS(1, &newJSVal);
8497 };
8498 ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
8499 } else if (info[1]->IsObject()) {
8500 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8501 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8502 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8503 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8504 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8505 std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
8506 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8507 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8508 node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
8509 ContainerScope scope(id);
8510 RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
8511 if (!impl) {
8512 return;
8513 }
8514 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8515 auto newJSVal = JSRef<JSVal>(impl->GetObject());
8516 PipelineContext::SetCallBackNode(node);
8517 func->ExecuteJS(1, &newJSVal);
8518 };
8519 ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
8520 propertyName, animatableArithmetic, onCallbackEvent);
8521 }
8522 }
8523
JSUpdateAnimatableProperty(const JSCallbackInfo & info)8524 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
8525 {
8526 if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
8527 return;
8528 }
8529
8530 std::string propertyName = info[0]->ToString();
8531 float numValue = 0.0;
8532 if (info[1]->IsNumber()) {
8533 numValue = info[1]->ToNumber<float>();
8534 ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
8535 } else if (info[1]->IsObject()) {
8536 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8537 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8538 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8539 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8540 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8541 ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
8542 }
8543 }
8544
JsExpandSafeArea(const JSCallbackInfo & info)8545 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
8546 {
8547 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
8548 if (info.Length() >= 1 && info[0]->IsArray()) {
8549 auto paramArray = JSRef<JSArray>::Cast(info[0]);
8550 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
8551 for (size_t i = 0; i < paramArray->Length(); ++i) {
8552 if (!paramArray->GetValueAt(i)->IsNumber() ||
8553 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
8554 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
8555 break;
8556 }
8557 safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8558 }
8559 opts.type = safeAreaType;
8560 }
8561 if (info.Length() >= 2 && info[1]->IsArray()) {
8562 auto paramArray = JSRef<JSArray>::Cast(info[1]);
8563 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
8564 for (size_t i = 0; i < paramArray->Length(); ++i) {
8565 if (!paramArray->GetValueAt(i)->IsNumber() ||
8566 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
8567 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
8568 break;
8569 }
8570 safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8571 }
8572 opts.edges = safeAreaEdge;
8573 }
8574
8575 ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
8576 }
8577
ParseJSLightSource(JSRef<JSObject> & lightSource)8578 void ParseJSLightSource(JSRef<JSObject>& lightSource)
8579 {
8580 if (lightSource->IsUndefined()) {
8581 return;
8582 }
8583 JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
8584 JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
8585 JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
8586 JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
8587 JSRef<JSVal> color = lightSource->GetProperty("color");
8588
8589 CalcDimension dimPositionX;
8590 CalcDimension dimPositionY;
8591 CalcDimension dimPositionZ;
8592 if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
8593 JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
8594 JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
8595 ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
8596 }
8597
8598 if (intensity->IsNumber()) {
8599 float intensityValue = intensity->ToNumber<float>();
8600 ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
8601 }
8602
8603 Color lightColor;
8604 if (JSViewAbstract::ParseJsColor(color, lightColor)) {
8605 ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
8606 }
8607 }
8608
JsPointLight(const JSCallbackInfo & info)8609 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
8610 {
8611 #ifdef POINT_LIGHT_ENABLE
8612 if (!info[0]->IsObject()) {
8613 return;
8614 }
8615
8616 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
8617 JSRef<JSObject> lightSource = object->GetProperty("lightSource");
8618 ParseJSLightSource(lightSource);
8619
8620 auto resourceWrapper = CreateResourceWrapper();
8621 if (!resourceWrapper) {
8622 return;
8623 }
8624 double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
8625 Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
8626 Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
8627
8628 JSRef<JSVal> illuminated = object->GetProperty("illuminated");
8629 if (illuminated->IsNumber()) {
8630 uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
8631 ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
8632 ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
8633 }
8634
8635 JSRef<JSVal> bloom = object->GetProperty("bloom");
8636 if (bloom->IsNumber()) {
8637 float bloomValue = bloom->ToNumber<float>();
8638 ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
8639
8640 Shadow shadow;
8641 shadow.SetBlurRadius(bloomValue * bloomRadius);
8642 shadow.SetColor(bloomColor);
8643 std::vector<Shadow> shadows { shadow };
8644 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8645 }
8646 #endif
8647 }
8648
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)8649 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
8650 {
8651 if (info[0]->IsBoolean()) {
8652 ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
8653 }
8654 }
8655
JSBind(BindingTarget globalObj)8656 void JSViewAbstract::JSBind(BindingTarget globalObj)
8657 {
8658 JSClass<JSViewAbstract>::Declare("JSViewAbstract");
8659
8660 // static methods
8661 MethodOptions opt = MethodOptions::NONE;
8662 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
8663
8664 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
8665 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
8666 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
8667 JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
8668 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
8669 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
8670 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
8671 JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSViewAbstract::JsPixelRound);
8672 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
8673 JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSViewAbstract::JsChainWeight);
8674
8675 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
8676 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
8677 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
8678 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
8679 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
8680
8681 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
8682 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
8683 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
8684 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
8685 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
8686 JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
8687
8688 JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
8689 JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
8690 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
8691 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
8692 JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
8693 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
8694 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
8695 JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
8696 JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
8697 JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
8698 JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
8699 JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
8700 JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
8701 JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
8702 JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
8703 JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
8704 JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
8705 JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
8706 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
8707 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
8708 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
8709 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
8710 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
8711 JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
8712
8713 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
8714 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
8715 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
8716 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
8717 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
8718 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
8719 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
8720 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
8721 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
8722 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
8723 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
8724 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
8725
8726 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
8727 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
8728 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
8729 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
8730 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
8731 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
8732 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
8733
8734 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
8735 JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
8736 JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
8737 JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
8738 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
8739 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
8740 JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
8741 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
8742 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal",
8743 &JSViewAbstract::JsBackgroundBrightnessInternal);
8744 JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
8745 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
8746 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
8747 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
8748 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
8749 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
8750 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
8751 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
8752 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
8753 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
8754 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
8755 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
8756 #ifndef WEARABLE_PRODUCT
8757 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
8758 #endif
8759
8760 JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
8761 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
8762 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
8763 JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
8764 JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
8765 JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
8766 JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
8767 JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
8768 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
8769 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
8770 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
8771 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
8772 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
8773 JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
8774
8775 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
8776 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
8777 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
8778 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
8779 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
8780 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
8781 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
8782 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
8783 JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
8784 JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
8785 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
8786 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
8787 JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
8788 JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
8789 JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
8790 JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
8791 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
8792 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
8793 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
8794 JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
8795 JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
8796 JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
8797 JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
8798 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
8799 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
8800 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
8801 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
8802 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
8803 JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
8804 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
8805 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
8806 JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
8807 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
8808 JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
8809 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
8810 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
8811 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
8812 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
8813 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
8814 JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
8815 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
8816 JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
8817 JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
8818 JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
8819 JSClass<JSViewAbstract>::StaticMethod(
8820 "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
8821 JSClass<JSViewAbstract>::StaticMethod(
8822 "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
8823 JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
8824 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
8825 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
8826 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
8827 JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
8828 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
8829 JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
8830
8831 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
8832 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
8833 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
8834 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
8835 JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
8836 JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
8837 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
8838 JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
8839 JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
8840
8841 JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
8842 JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
8843 JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
8844 JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
8845 JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
8846 JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
8847 JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
8848 JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
8849 JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
8850 JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
8851 JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
8852
8853 JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
8854 JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
8855 JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
8856 JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
8857
8858 JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
8859
8860 JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
8861
8862 JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
8863 JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
8864 JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
8865
8866 JSClass<JSViewAbstract>::StaticMethod(
8867 "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
8868
8869 JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
8870 JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
8871
8872 JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
8873 JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
8874 JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
8875 JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
8876
8877 JSClass<JSViewAbstract>::Bind(globalObj);
8878 }
8879
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)8880 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
8881 {
8882 auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
8883 auto vm = info->GetVM();
8884 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
8885 Local<JSValueRef> thisObj = info->GetFunctionRef();
8886 auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
8887 if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
8888 return panda::JSValueRef::Undefined(vm);
8889 }
8890
8891 auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
8892 if (weak->Invalid()) {
8893 return panda::JSValueRef::Undefined(vm);
8894 }
8895
8896 auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
8897 if (frameNode) {
8898 const auto& extensionHandler = frameNode->GetExtensionHandler();
8899 if (extensionHandler) {
8900 extensionHandler->InvalidateRender();
8901 } else {
8902 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
8903 }
8904 }
8905
8906 return panda::JSValueRef::Undefined(vm);
8907 };
8908 auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
8909 if (frameNode) {
8910 const auto& extensionHandler = frameNode->GetExtensionHandler();
8911 if (extensionHandler) {
8912 extensionHandler->InvalidateRender();
8913 } else {
8914 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
8915 }
8916 }
8917 auto vm = jsInvalidate->GetEcmaVM();
8918 auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
8919 jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
8920 jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
8921 jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
8922 }
8923
JsDrawModifier(const JSCallbackInfo & info)8924 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
8925 {
8926 if (!info[0]->IsObject()) {
8927 return;
8928 }
8929
8930 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
8931 bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
8932 if (!IsSupportDrawModifier) {
8933 return;
8934 }
8935 auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
8936 RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
8937 auto execCtx = info.GetExecutionContext();
8938 auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
8939 JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
8940 if (!drawMethod->IsFunction()) {
8941 return nullptr;
8942 }
8943
8944 auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
8945 JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
8946
8947 return GetDrawCallback(jsDrawFunc, execCtx);
8948 };
8949
8950 drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
8951 drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
8952 drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
8953
8954 ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
8955 AddInvalidateFunc(jsDrawModifier, frameNode);
8956 }
8957
JsAllowDrop(const JSCallbackInfo & info)8958 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
8959 {
8960 std::set<std::string> allowDropSet;
8961 allowDropSet.clear();
8962 if (!info[0]->IsUndefined() && info[0]->IsArray()) {
8963 auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
8964 std::string allowDrop;
8965 for (size_t i = 0; i < allowDropArray->Length(); i++) {
8966 allowDrop = allowDropArray->GetValueAt(i)->ToString();
8967 allowDropSet.insert(allowDrop);
8968 }
8969 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
8970 } else if (info[0]->IsNull()) {
8971 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
8972 } else {
8973 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
8974 }
8975 ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
8976 }
8977
JsOnPreDrag(const JSCallbackInfo & info)8978 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
8979 {
8980 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
8981 auto jsVal = info[0];
8982 if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
8983 return;
8984 }
8985 RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
8986 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8987 auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
8988 const PreDragStatus preDragStatus) {
8989 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8990 ACE_SCORING_EVENT("onPreDrag");
8991 PipelineContext::SetCallBackNode(node);
8992 func->PreDragExecute(preDragStatus);
8993 };
8994 ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
8995 }
8996
JsDragPreview(const JSCallbackInfo & info)8997 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
8998 {
8999 auto jsVal = info[0];
9000 if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
9001 return;
9002 }
9003 NG::DragDropInfo dragPreviewInfo;
9004 JSRef<JSVal> builder;
9005 JSRef<JSVal> pixelMap;
9006 JSRef<JSVal> extraInfo;
9007 if (jsVal->IsFunction()) {
9008 builder = jsVal;
9009 } else if (jsVal->IsObject()) {
9010 auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
9011 builder = dragItemInfo->GetProperty("builder");
9012 #if defined(PIXEL_MAP_SUPPORTED)
9013 pixelMap = dragItemInfo->GetProperty("pixelMap");
9014 dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
9015 #endif
9016 extraInfo = dragItemInfo->GetProperty("extraInfo");
9017 ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
9018 } else if (jsVal->IsString()) {
9019 auto inspectorId = jsVal;
9020 ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
9021 } else {
9022 return;
9023 }
9024
9025 if (builder->IsFunction()) {
9026 RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9027 if (builderFunc != nullptr) {
9028 ViewStackModel::GetInstance()->NewScope();
9029 {
9030 ACE_SCORING_EVENT("dragPreview.builder");
9031 builderFunc->Execute();
9032 }
9033 RefPtr<AceType> node = ViewStackModel::GetInstance()->Finish();
9034 dragPreviewInfo.customNode = AceType::DynamicCast<NG::UINode>(node);
9035 }
9036 }
9037 ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
9038 }
9039
JsAlignRules(const JSCallbackInfo & info)9040 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
9041 {
9042 if (!info[0]->IsObject()) {
9043 return;
9044 }
9045
9046 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
9047 if (valueObj->IsEmpty()) {
9048 return;
9049 }
9050 const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
9051 std::map<AlignDirection, AlignRule> alignRules;
9052 BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
9053 for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
9054 auto rule = valueObj->GetProperty(keys[i]);
9055 if (rule->IsObject()) {
9056 JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
9057 JSRef<JSVal> align = val->GetProperty("align");
9058 AlignRule alignRule;
9059 alignRule.anchor = val->GetProperty("anchor")->ToString();
9060 if (i < HORIZONTAL_DIRECTION_RANGE) {
9061 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9062 } else {
9063 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9064 }
9065 if (i < VERTICAL_DIRECTION_RANGE) {
9066 alignRules[static_cast<AlignDirection>(i)] = alignRule;
9067 } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
9068 alignRules[AlignDirection::LEFT] = alignRule;
9069 } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
9070 alignRules[AlignDirection::RIGHT] = alignRule;
9071 }
9072 auto biasX = val->GetProperty("horizontal");
9073 if (biasX->IsNumber()) {
9074 biasPair.first = biasX->ToNumber<float>();
9075 }
9076 auto biasY = val->GetProperty("vertical");
9077 if (biasY->IsNumber()) {
9078 biasPair.second = biasY->ToNumber<float>();
9079 }
9080 }
9081 }
9082
9083 ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
9084 ViewAbstractModel::GetInstance()->SetBias(biasPair);
9085 }
9086
JsChainMode(const JSCallbackInfo & info)9087 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
9088 {
9089 ChainInfo chainInfo;
9090 if (info.Length() >= 1) {
9091 auto tmpDirection = info[0];
9092 if (tmpDirection->IsUndefined()) {
9093 chainInfo.direction = std::nullopt;
9094 } else if (tmpDirection->IsNumber()) {
9095 auto direction = tmpDirection->ToNumber<int32_t>();
9096 chainInfo.direction = static_cast<LineDirection>(direction);
9097 }
9098 }
9099
9100 if (info.Length() >= 2) { // 2 : two args
9101 auto tmpStyle = info[1];
9102 if (tmpStyle->IsUndefined()) {
9103 chainInfo.style = std::nullopt;
9104 } else if (tmpStyle->IsNumber()) {
9105 auto style = tmpStyle->ToNumber<int32_t>();
9106 chainInfo.style = static_cast<ChainStyle>(style);
9107 }
9108 }
9109 ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
9110 }
9111
SetMarginTop(const JSCallbackInfo & info)9112 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
9113 {
9114 CalcDimension value;
9115 if (!ParseJsDimensionVp(info[0], value)) {
9116 return;
9117 }
9118 ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
9119 }
9120
SetMarginBottom(const JSCallbackInfo & info)9121 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
9122 {
9123 CalcDimension value;
9124 if (!ParseJsDimensionVp(info[0], value)) {
9125 return;
9126 }
9127 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
9128 }
9129
SetMarginLeft(const JSCallbackInfo & info)9130 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
9131 {
9132 CalcDimension value;
9133 if (!ParseJsDimensionVp(info[0], value)) {
9134 return;
9135 }
9136 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
9137 }
9138
SetMarginRight(const JSCallbackInfo & info)9139 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
9140 {
9141 CalcDimension value;
9142 if (!ParseJsDimensionVp(info[0], value)) {
9143 return;
9144 }
9145 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
9146 }
9147
SetPaddingTop(const JSCallbackInfo & info)9148 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
9149 {
9150 CalcDimension value;
9151 if (!ParseJsDimensionVp(info[0], value)) {
9152 return;
9153 }
9154 ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
9155 }
9156
SetPaddingBottom(const JSCallbackInfo & info)9157 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
9158 {
9159 CalcDimension value;
9160 if (!ParseJsDimensionVp(info[0], value)) {
9161 return;
9162 }
9163 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
9164 }
9165
SetPaddingLeft(const JSCallbackInfo & info)9166 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
9167 {
9168 CalcDimension value;
9169 if (!ParseJsDimensionVp(info[0], value)) {
9170 return;
9171 }
9172 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
9173 }
9174
SetPaddingRight(const JSCallbackInfo & info)9175 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
9176 {
9177 CalcDimension value;
9178 if (!ParseJsDimensionVp(info[0], value)) {
9179 return;
9180 }
9181 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
9182 }
9183
SetSafeAreaPadding(const JSCallbackInfo & info)9184 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
9185 {
9186 ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
9187 }
9188
SetColorBlend(Color color)9189 void JSViewAbstract::SetColorBlend(Color color)
9190 {
9191 ViewAbstractModel::GetInstance()->SetColorBlend(color);
9192 }
9193
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)9194 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
9195 {
9196 ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
9197 }
9198
SetDynamicLightUp(float rate,float lightUpDegree)9199 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
9200 {
9201 ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
9202 }
9203
SetBgDynamicBrightness(BrightnessOption brightnessOption)9204 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
9205 {
9206 ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
9207 }
9208
SetFgDynamicBrightness(BrightnessOption brightnessOption)9209 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
9210 {
9211 ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
9212 }
9213
SetWindowBlur(float progress,WindowBlurStyle blurStyle)9214 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
9215 {
9216 ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
9217 }
9218
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)9219 bool JSViewAbstract::ParseJsonDimension(
9220 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
9221 {
9222 if (!jsonValue || jsonValue->IsNull()) {
9223 return false;
9224 }
9225 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9226 return false;
9227 }
9228 if (jsonValue->IsNumber()) {
9229 result = Dimension(jsonValue->GetDouble(), defaultUnit);
9230 return true;
9231 }
9232 if (jsonValue->IsString()) {
9233 if (checkIllegal) {
9234 return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
9235 }
9236 result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
9237 return true;
9238 }
9239 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9240 auto resId = resVal->GetValue("id");
9241 if (!resId || !resId->IsNumber()) {
9242 return false;
9243 }
9244
9245 auto resourceWrapper = CreateResourceWrapper();
9246 if (!resourceWrapper) {
9247 return false;
9248 }
9249 result = resourceWrapper->GetDimension(resId->GetUInt());
9250 return true;
9251 }
9252
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)9253 bool JSViewAbstract::ParseJsonDimensionVp(
9254 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
9255 {
9256 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9257 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
9258 }
9259 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
9260 }
9261
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)9262 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
9263 {
9264 if (!jsonValue || jsonValue->IsNull()) {
9265 return false;
9266 }
9267 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9268 return false;
9269 }
9270 if (jsonValue->IsNumber()) {
9271 result = jsonValue->GetDouble();
9272 return true;
9273 }
9274 if (jsonValue->IsString()) {
9275 result = StringUtils::StringToDouble(jsonValue->GetString());
9276 return true;
9277 }
9278 // parse json Resource
9279 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9280 auto resId = resVal->GetValue("id");
9281 CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
9282 auto id = resId->GetUInt();
9283 auto resType = resVal->GetValue("type");
9284 CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
9285 auto type = resType->GetUInt();
9286
9287 auto resourceWrapper = CreateResourceWrapper();
9288 if (!resourceWrapper) {
9289 return false;
9290 }
9291 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9292 auto numberString = resourceWrapper->GetString(id);
9293 return StringUtils::StringToDouble(numberString, result);
9294 }
9295 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9296 result = resourceWrapper->GetInt(id);
9297 return true;
9298 }
9299 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9300 result = resourceWrapper->GetDouble(id);
9301 return true;
9302 }
9303 return false;
9304 }
9305
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)9306 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
9307 {
9308 if (!jsonValue || jsonValue->IsNull()) {
9309 return false;
9310 }
9311 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9312 return false;
9313 }
9314 if (jsonValue->IsNumber()) {
9315 result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
9316 return true;
9317 }
9318
9319 bool isSetColor = false;
9320 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
9321 isSetColor = jsonValue->IsString();
9322 } else {
9323 isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
9324 }
9325 if (isSetColor) {
9326 result = Color::FromString(jsonValue->GetString());
9327 return true;
9328 }
9329 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9330 auto resId = resVal->GetValue("id");
9331 if (!resId || !resId->IsNumber()) {
9332 return false;
9333 }
9334 auto resourceWrapper = CreateResourceWrapper();
9335 if (!resourceWrapper) {
9336 return false;
9337 }
9338 result = resourceWrapper->GetColor(resId->GetUInt());
9339 return true;
9340 }
9341
ParseShadowOffsetX(const JSRef<JSObject> & jsObj,CalcDimension & offsetX,Shadow & shadow)9342 void JSViewAbstract::ParseShadowOffsetX(const JSRef<JSObject>& jsObj, CalcDimension& offsetX, Shadow& shadow)
9343 {
9344 auto jsOffsetX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_X));
9345 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
9346 if (ParseJsResource(jsOffsetX, offsetX)) {
9347 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9348 shadow.SetOffsetX(xValue);
9349 } else {
9350 if (ParseJsDimensionVp(jsOffsetX, offsetX)) {
9351 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9352 shadow.SetOffsetX(xValue);
9353 }
9354 }
9355 }
9356
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)9357 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
9358 {
9359 int32_t shadowStyle = 0;
9360 if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
9361 auto style = static_cast<ShadowStyle>(shadowStyle);
9362 return GetShadowFromTheme(style, shadow);
9363 }
9364 if (!jsValue->IsObject()) {
9365 return false;
9366 }
9367 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9368 double radius = 0.0;
9369 ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius);
9370 if (LessNotEqual(radius, 0.0)) {
9371 radius = 0.0;
9372 }
9373 shadow.SetBlurRadius(radius);
9374 CalcDimension offsetX;
9375 ParseShadowOffsetX(jsObj, offsetX, shadow);
9376 CalcDimension offsetY;
9377 auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
9378 if (ParseJsResource(jsOffsetY, offsetY)) {
9379 shadow.SetOffsetY(offsetY.Value());
9380 } else {
9381 if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
9382 shadow.SetOffsetY(offsetY.Value());
9383 }
9384 }
9385 Color color;
9386 ShadowColorStrategy shadowColorStrategy;
9387 auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
9388 if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
9389 shadow.SetShadowColorStrategy(shadowColorStrategy);
9390 } else if (ParseJsColor(jsColor, color)) {
9391 shadow.SetColor(color);
9392 }
9393 int32_t type = static_cast<int32_t>(ShadowType::COLOR);
9394 JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
9395 if (type != static_cast<int32_t>(ShadowType::BLUR)) {
9396 type = static_cast<int32_t>(ShadowType::COLOR);
9397 }
9398 shadow.SetShadowType(static_cast<ShadowType>(type));
9399 bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
9400 shadow.SetIsFilled(isFilled);
9401 return true;
9402 }
9403
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)9404 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
9405 {
9406 auto colorMode = SystemProperties::GetColorMode();
9407 if (shadowStyle == ShadowStyle::None) {
9408 return true;
9409 }
9410
9411 auto container = Container::Current();
9412 CHECK_NULL_RETURN(container, false);
9413 auto pipelineContext = container->GetPipelineContext();
9414 CHECK_NULL_RETURN(pipelineContext, false);
9415
9416 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
9417 if (!shadowTheme) {
9418 return false;
9419 }
9420
9421 shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
9422 return true;
9423 }
9424
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)9425 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
9426 {
9427 if (!jsValue->IsObject()) {
9428 return false;
9429 }
9430 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9431 uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
9432 if (type == 0) {
9433 return false;
9434 }
9435 auto resourceWrapper = CreateResourceWrapper();
9436 CHECK_NULL_RETURN(resourceWrapper, false);
9437 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9438 auto value = resourceWrapper->GetString(
9439 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9440 return StringUtils::StringToCalcDimensionNG(value, result, false);
9441 }
9442 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9443 auto value = std::to_string(
9444 resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
9445 StringUtils::StringToDimensionWithUnitNG(value, result);
9446 return true;
9447 }
9448
9449 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9450 result = resourceWrapper->GetDimension(
9451 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9452 return true;
9453 }
9454 return false;
9455 }
9456
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)9457 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
9458 {
9459 JSRef<JSVal> arg = info[0];
9460 if (!arg->IsObject()) {
9461 return false;
9462 }
9463 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
9464 JSRef<JSVal> typeValue = obj->GetProperty("types");
9465 if (!typeValue->IsArray()) {
9466 return false;
9467 }
9468 JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
9469 for (size_t i = 0; i < array->Length(); i++) {
9470 JSRef<JSVal> value = array->GetValueAt(i);
9471 auto index = value->ToNumber<int32_t>();
9472 if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
9473 return false;
9474 }
9475 if (i != 0) {
9476 textDetectConfig.types.append(",");
9477 }
9478 textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
9479 }
9480 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9481 JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
9482 if (resultCallback->IsFunction()) {
9483 auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
9484 textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
9485 const std::string& result) {
9486 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9487 PipelineContext::SetCallBackNode(node);
9488 func->Execute(result);
9489 };
9490 }
9491
9492 return ParseAIEntityColor(obj, textDetectConfig);
9493 }
9494
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)9495 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
9496 {
9497 JSRef<JSVal> entityColorValue = obj->GetProperty("color");
9498 ParseJsColor(entityColorValue, textDetectConfig.entityColor);
9499
9500 JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
9501 if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
9502 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9503 return true;
9504 }
9505 JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
9506 JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
9507 JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
9508 JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
9509
9510 if (typeValue->IsNumber()) {
9511 textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
9512 } else {
9513 textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
9514 }
9515 if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) {
9516 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9517 }
9518 if (styleValue->IsNumber()) {
9519 textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
9520 } else {
9521 textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
9522 }
9523
9524 return true;
9525 }
9526
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)9527 void JSViewAbstract::GetAngle(
9528 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
9529 {
9530 auto value = jsonValue->GetValue(key);
9531 if (value && value->IsString()) {
9532 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
9533 } else if (value && value->IsNumber()) {
9534 angle = static_cast<float>(value->GetDouble());
9535 }
9536 }
9537
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)9538 void JSViewAbstract::GetJsAngle(
9539 int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
9540 {
9541 if (!jsValue->IsObject()) {
9542 return;
9543 }
9544 JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
9545 if (value->IsString()) {
9546 angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
9547 } else if (value->IsNumber()) {
9548 angle = value->ToNumber<float>();
9549 }
9550 }
9551
9552 // 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)9553 void JSViewAbstract::GetJsAngleWithDefault(
9554 int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
9555 {
9556 JSRef<JSVal> value = jsObj->GetProperty(key);
9557 if (value->IsString()) {
9558 double temp = 0.0;
9559 if (StringUtils::StringToDegree(value->ToString(), temp)) {
9560 angle = static_cast<float>(temp);
9561 } else {
9562 angle = defaultValue;
9563 }
9564 } else if (value->IsNumber()) {
9565 angle = value->ToNumber<float>();
9566 }
9567 }
9568
CheckAngle(std::optional<float> & angle)9569 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
9570 {
9571 angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
9572 }
9573
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)9574 void JSViewAbstract::GetPerspective(
9575 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
9576 {
9577 auto value = jsonValue->GetValue(key);
9578 if (value && value->IsNumber()) {
9579 perspective = static_cast<float>(value->GetDouble());
9580 }
9581 }
9582
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)9583 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
9584 {
9585 auto value = jsValue->GetProperty(key);
9586 if (value->IsNumber()) {
9587 perspective = value->ToNumber<float>();
9588 }
9589 }
9590
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9591 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9592 {
9593 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9594 return;
9595 }
9596
9597 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9598 GradientColor gradientColor;
9599 auto item = colorStops->GetArrayItem(i);
9600 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9601 auto colorParams = item->GetArrayItem(0);
9602 // color
9603 Color color;
9604 if (!ParseJsonColor(colorParams, color)) {
9605 continue;
9606 }
9607 gradientColor.SetColor(color);
9608 gradientColor.SetHasValue(false);
9609 // stop value
9610 if (item->GetArraySize() <= 1) {
9611 continue;
9612 }
9613 auto stopValue = item->GetArrayItem(1);
9614 double value = 0.0;
9615 if (ParseJsonDouble(stopValue, value)) {
9616 value = std::clamp(value, 0.0, 1.0);
9617 gradientColor.SetHasValue(true);
9618 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9619 }
9620 gradient.AddColor(gradientColor);
9621 }
9622 }
9623 }
9624
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9625 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9626 {
9627 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9628 return;
9629 }
9630
9631 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9632 NG::GradientColor gradientColor;
9633 auto item = colorStops->GetArrayItem(i);
9634 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9635 auto colorParams = item->GetArrayItem(0);
9636 // color
9637 Color color;
9638 if (!ParseJsonColor(colorParams, color)) {
9639 continue;
9640 }
9641 gradientColor.SetColor(color);
9642 gradientColor.SetHasValue(false);
9643 // stop value
9644 if (item->GetArraySize() <= 1) {
9645 continue;
9646 }
9647 auto stopValue = item->GetArrayItem(1);
9648 double value = 0.0;
9649 if (ParseJsonDouble(stopValue, value)) {
9650 value = std::clamp(value, 0.0, 1.0);
9651 gradientColor.SetHasValue(true);
9652 // [0, 1] -> [0, 100.0];
9653 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9654 }
9655 gradient.AddColor(gradientColor);
9656 }
9657 }
9658 }
9659
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)9660 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
9661 {
9662 if (!colorStops->IsArray()) {
9663 return;
9664 }
9665
9666 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
9667 size_t length = jsArray->Length();
9668 for (size_t i = 0; i < length; i++) {
9669 NG::GradientColor gradientColor;
9670 JSRef<JSVal> item = jsArray->GetValueAt(i);
9671 if (!item->IsArray()) {
9672 continue;
9673 }
9674 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
9675 if (subArray->Length() < 2) {
9676 continue;
9677 }
9678 // color
9679 Color color;
9680 if (!ParseJsColor(subArray->GetValueAt(0), color)) {
9681 continue;
9682 }
9683 gradientColor.SetColor(color);
9684 gradientColor.SetHasValue(false);
9685 // stop value
9686 double value = 0.0;
9687 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
9688 value = std::clamp(value, 0.0, 1.0);
9689 gradientColor.SetHasValue(true);
9690 }
9691 // [0, 1] -> [0, 100.0];
9692 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9693 gradient.AddColor(gradientColor);
9694 }
9695 }
9696
SetDirection(const std::string & dir)9697 void JSViewAbstract::SetDirection(const std::string& dir)
9698 {
9699 TextDirection direction = TextDirection::AUTO;
9700 if (dir == "Ltr") {
9701 direction = TextDirection::LTR;
9702 } else if (dir == "Rtl") {
9703 direction = TextDirection::RTL;
9704 } else if (dir == "Auto") {
9705 direction = TextDirection::AUTO;
9706 } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9707 direction = TextDirection::AUTO;
9708 }
9709 ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
9710 }
9711
GetThemeConstants(const JSRef<JSObject> & jsObj)9712 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
9713 {
9714 std::string bundleName;
9715 std::string moduleName;
9716 if (!jsObj->IsUndefined()) {
9717 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
9718 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
9719 if (bundle->IsString() && module->IsString()) {
9720 bundleName = bundle->ToString();
9721 moduleName = module->ToString();
9722 }
9723 }
9724
9725 auto cardId = CardScope::CurrentId();
9726 if (cardId != INVALID_CARD_ID) {
9727 auto container = Container::Current();
9728 auto weak = container->GetCardPipeline(cardId);
9729 auto cardPipelineContext = weak.Upgrade();
9730 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
9731 auto cardThemeManager = cardPipelineContext->GetThemeManager();
9732 CHECK_NULL_RETURN(cardThemeManager, nullptr);
9733 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
9734 }
9735
9736 #ifdef PLUGIN_COMPONENT_SUPPORTED
9737 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
9738 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
9739 if (!pluginContainer) {
9740 return nullptr;
9741 }
9742 auto pluginPipelineContext = pluginContainer->GetPipelineContext();
9743 if (!pluginPipelineContext) {
9744 return nullptr;
9745 }
9746 auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
9747 if (!pluginThemeManager) {
9748 return nullptr;
9749 }
9750 return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
9751 }
9752 #endif
9753 auto container = Container::Current();
9754 CHECK_NULL_RETURN(container, nullptr);
9755 auto pipelineContext = container->GetPipelineContext();
9756 CHECK_NULL_RETURN(pipelineContext, nullptr);
9757 auto themeManager = pipelineContext->GetThemeManager();
9758 CHECK_NULL_RETURN(themeManager, nullptr);
9759 return themeManager->GetThemeConstants(bundleName, moduleName);
9760 }
9761
JsHoverEffect(const JSCallbackInfo & info)9762 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
9763 {
9764 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
9765 auto jsVal = info[0];
9766 if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
9767 ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
9768 return;
9769 }
9770 if (!jsVal->IsNumber()) {
9771 return;
9772 }
9773 ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
9774 }
9775
JsOnMouse(const JSCallbackInfo & info)9776 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
9777 {
9778 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9779 ViewAbstractModel::GetInstance()->DisableOnMouse();
9780 return;
9781 }
9782 if (!info[0]->IsFunction()) {
9783 return;
9784 }
9785
9786 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
9787 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9788 auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
9789 MouseInfo& mouseInfo) {
9790 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9791 ACE_SCORING_EVENT("onMouse");
9792 PipelineContext::SetCallBackNode(node);
9793 func->Execute(mouseInfo);
9794 };
9795 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
9796 }
9797
JsOnHover(const JSCallbackInfo & info)9798 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
9799 {
9800 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9801 ViewAbstractModel::GetInstance()->DisableOnHover();
9802 return;
9803 }
9804 if (!info[0]->IsFunction()) {
9805 return;
9806 }
9807
9808 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
9809 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9810 auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
9811 bool isHover, HoverInfo& hoverInfo) {
9812 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9813 ACE_SCORING_EVENT("onHover");
9814 PipelineContext::SetCallBackNode(node);
9815 func->HoverExecute(isHover, hoverInfo);
9816 };
9817 ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
9818 }
9819
JsOnAccessibilityHover(const JSCallbackInfo & info)9820 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
9821 {
9822 if (info[0]->IsUndefined()) {
9823 ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
9824 return;
9825 }
9826 if (!info[0]->IsFunction()) {
9827 return;
9828 }
9829
9830 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
9831 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9832 auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
9833 node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
9834 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9835 ACE_SCORING_EVENT("onAccessibilityHover");
9836 PipelineContext::SetCallBackNode(node);
9837 func->AccessibilityHoverExecute(isHover, hoverInfo);
9838 };
9839 ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
9840 }
9841
JsOnClick(const JSCallbackInfo & info)9842 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
9843 {
9844 auto arg = info[0];
9845 if (arg->IsUndefined() && IsDisableEventVersion()) {
9846 ViewAbstractModel::GetInstance()->DisableOnClick();
9847 return;
9848 }
9849 if (!arg->IsFunction()) {
9850 return;
9851 }
9852
9853 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
9854 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9855 auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
9856 BaseEventInfo* info) {
9857 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9858 auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
9859 ACE_SCORING_EVENT("onClick");
9860 PipelineContext::SetCallBackNode(node);
9861 func->Execute(*tapInfo);
9862 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
9863 JSInteractableView::ReportClickEvent(node);
9864 #endif
9865 };
9866 auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
9867 auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
9868 const ClickInfo* info) {
9869 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9870 ACE_SCORING_EVENT("onClick");
9871 PipelineContext::SetCallBackNode(node);
9872 func->Execute(*info);
9873 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
9874 JSInteractableView::ReportClickEvent(node);
9875 #endif
9876 };
9877
9878 double distanceThreshold = std::numeric_limits<double>::infinity();
9879 if (info.Length() > 1 && info[1]->IsNumber()) {
9880 distanceThreshold = info[1]->ToNumber<double>();
9881 if (distanceThreshold < 0) {
9882 distanceThreshold = std::numeric_limits<double>::infinity();
9883 }
9884 }
9885 distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
9886 ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
9887 }
9888
JsOnGestureJudgeBegin(const JSCallbackInfo & info)9889 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
9890 {
9891 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9892 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
9893 return;
9894 }
9895
9896 auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
9897 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9898 auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
9899 const RefPtr<NG::GestureInfo>& gestureInfo,
9900 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
9901 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
9902 ACE_SCORING_EVENT("onGestureJudgeBegin");
9903 return func->Execute(gestureInfo, info);
9904 };
9905 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
9906 }
9907
JsOnTouchIntercept(const JSCallbackInfo & info)9908 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
9909 {
9910 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9911 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
9912 return;
9913 }
9914
9915 auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
9916 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9917 auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
9918 TouchEventInfo& info) -> NG::HitTestMode {
9919 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
9920 ACE_SCORING_EVENT("onTouchIntercept");
9921 PipelineContext::SetCallBackNode(node);
9922 return func->Execute(info);
9923 };
9924 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
9925 }
9926
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)9927 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
9928 {
9929 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9930 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
9931 return;
9932 }
9933
9934 auto jsParallelInnerGestureToFunc =
9935 AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
9936 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9937 auto shouldBuiltInRecognizerParallelWithFunc =
9938 [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
9939 const RefPtr<NG::NGGestureRecognizer>& current,
9940 const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
9941 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
9942 ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
9943 PipelineContext::SetCallBackNode(node);
9944 return func->Execute(current, others);
9945 };
9946 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
9947 std::move(shouldBuiltInRecognizerParallelWithFunc));
9948 }
9949
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)9950 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
9951 {
9952 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
9953 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
9954 return;
9955 }
9956
9957 auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
9958 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9959 auto onGestureRecognizerJudgefunc =
9960 [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
9961 const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
9962 const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
9963 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
9964 ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
9965 PipelineContext::SetCallBackNode(node);
9966 return func->Execute(info, current, others);
9967 };
9968
9969 bool exposeInnerGestureFlag = false;
9970 if (info.Length() > 1 && info[1]->IsBoolean()) {
9971 exposeInnerGestureFlag = info[1]->ToBoolean();
9972 }
9973 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
9974 std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
9975 }
9976
JsClickEffect(const JSCallbackInfo & info)9977 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
9978 {
9979 JSRef<JSVal> arg = info[0];
9980 if (arg->IsUndefined() || arg->IsNull()) {
9981 ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
9982 return;
9983 }
9984 if (!arg->IsObject()) {
9985 return;
9986 }
9987 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
9988 JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
9989 int32_t clickEffectLevelValue = 0;
9990 if (clickEffectLevel->IsNumber()) {
9991 clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
9992 if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
9993 clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
9994 clickEffectLevelValue = 0;
9995 }
9996 }
9997
9998 JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
9999 float scaleNumberValue = DEFAULT_SCALE_LIGHT;
10000 if (!scaleNumber->IsNumber()) {
10001 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10002 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10003 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10004 }
10005 ViewAbstractModel::GetInstance()->SetClickEffectLevel(
10006 (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10007 return;
10008 }
10009
10010 scaleNumberValue = scaleNumber->ToNumber<float>();
10011 if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
10012 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10013 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10014 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10015 } else {
10016 scaleNumberValue = DEFAULT_SCALE_LIGHT;
10017 }
10018 }
10019
10020 ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10021 }
10022
JsOnVisibleAreaChange(const JSCallbackInfo & info)10023 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
10024 {
10025 if (info.Length() != 2) {
10026 return;
10027 }
10028
10029 if (!info[0]->IsArray() || !info[1]->IsFunction()) {
10030 return;
10031 }
10032
10033 auto ratioArray = JSRef<JSArray>::Cast(info[0]);
10034 size_t size = ratioArray->Length();
10035 std::vector<double> ratioVec(size);
10036 ratioVec.clear();
10037 for (size_t i = 0; i < size; i++) {
10038 double ratio = 0.0;
10039 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
10040 if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
10041 ratio = VISIBLE_RATIO_MIN;
10042 }
10043
10044 if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
10045 ratio = VISIBLE_RATIO_MAX;
10046 }
10047 ratioVec.push_back(ratio);
10048 }
10049
10050 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
10051 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10052 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
10053 bool visible, double ratio) {
10054 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10055 ACE_SCORING_EVENT("onVisibleAreaChange");
10056
10057 JSRef<JSVal> params[2];
10058 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
10059 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
10060 PipelineContext::SetCallBackNode(node);
10061 func->ExecuteJS(2, params);
10062 };
10063 ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
10064 }
10065
JsHitTestBehavior(const JSCallbackInfo & info)10066 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
10067 {
10068 if (info.Length() != 1 || !info[0]->IsNumber()) {
10069 return;
10070 }
10071
10072 NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
10073 hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
10074 ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
10075 }
10076
JsOnChildTouchTest(const JSCallbackInfo & info)10077 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
10078 {
10079 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
10080 auto jsVal = info[0];
10081 if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
10082 return;
10083 }
10084
10085 RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
10086 AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
10087
10088 auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
10089 const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
10090 NG::TouchResult touchRes;
10091 NG::TouchResult defaultRes;
10092 defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
10093 defaultRes.id = "";
10094 auto ret = func->Execute(touchInfo);
10095 if (!ret->IsObject()) {
10096 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
10097 return defaultRes;
10098 }
10099
10100 auto retObj = JSRef<JSObject>::Cast(ret);
10101 auto strategy = retObj->GetProperty("strategy");
10102 if (!strategy->IsNumber()) {
10103 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
10104 return defaultRes;
10105 }
10106 touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
10107 auto id = retObj->GetProperty("id");
10108 if (!id->IsString()) {
10109 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
10110 return defaultRes;
10111 }
10112 touchRes.id = id->ToString();
10113 return touchRes;
10114 };
10115 ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
10116 }
10117
JsForegroundColor(const JSCallbackInfo & info)10118 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
10119 {
10120 Color foregroundColor = Color::TRANSPARENT;
10121 ForegroundColorStrategy strategy;
10122 if (ParseJsColorStrategy(info[0], strategy)) {
10123 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
10124 return;
10125 }
10126 ParseJsColor(info[0], foregroundColor);
10127 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
10128 }
10129
JsKeyboardShortcut(const JSCallbackInfo & info)10130 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
10131 {
10132 // KeyboardShortcut only allows 2 or 3 params.
10133 if (info.Length() < 2 || info.Length() > 3) {
10134 return;
10135 }
10136 if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
10137 // clear shortcut key
10138 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10139 return;
10140 }
10141
10142 std::string value;
10143 if (info[0]->IsString()) {
10144 // common letter/number/symbol
10145 value = info[0]->ToString();
10146 if (value.size() != 1) {
10147 // clear shortcut key
10148 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10149 return;
10150 }
10151 } else {
10152 // function keys such as F1-F10/ESC
10153 FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
10154 value = GetFunctionKeyName(functionkey);
10155 }
10156
10157 auto keysArray = JSRef<JSArray>::Cast(info[1]);
10158 size_t size = keysArray->Length();
10159 std::vector<ModifierKey> keys(size);
10160 keys.clear();
10161 for (size_t i = 0; i < size; i++) {
10162 JSRef<JSVal> key = keysArray->GetValueAt(i);
10163 if (key->IsNumber()) {
10164 keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
10165 }
10166 }
10167
10168 // KeyboardShortcut allows 3 params, the third param is function callback.
10169 if (info.Length() == 3 && info[2]->IsFunction()) {
10170 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
10171 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10172 auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10173 node = frameNode]() {
10174 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10175 ACE_SCORING_EVENT("onKeyboardShortcutAction");
10176 PipelineContext::SetCallBackNode(node);
10177 func->ExecuteJS();
10178 };
10179 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
10180 return;
10181 }
10182 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
10183 }
10184
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)10185 bool JSViewAbstract::CheckColor(
10186 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
10187 {
10188 // Color is undefined or null
10189 if (jsValue->IsUndefined() || jsValue->IsNull()) {
10190 return false;
10191 }
10192 // input type is not in [number, string, Resource]
10193 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10194 return false;
10195 }
10196 // Correct type, incorrect value parsing
10197 if (!ParseJsColor(jsValue, result)) {
10198 return false;
10199 }
10200 return true;
10201 }
10202
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)10203 bool JSViewAbstract::CheckLength(
10204 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
10205 {
10206 // Length is undefined or null
10207 if (jsValue->IsUndefined() || jsValue->IsNull()) {
10208 return false;
10209 }
10210 // input type is not in [number, string, Resource]
10211 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10212 return false;
10213 }
10214 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10215 return ParseJsDimensionVpNG(jsValue, result);
10216 }
10217 // Correct type, incorrect value parsing
10218 if (!ParseJsDimensionVp(jsValue, result)) {
10219 return false;
10220 }
10221 return true;
10222 }
10223
10224 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)10225 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
10226 {
10227 JSRef<JSVal> arg = info[0];
10228 if (arg->IsUndefined() || arg->IsNull()) {
10229 std::vector<ObscuredReasons> reasons(0);
10230 ViewAbstractModel::GetInstance()->SetObscured(reasons);
10231 return;
10232 }
10233 if (!arg->IsArray()) {
10234 return;
10235 }
10236
10237 auto obscuredArray = JSRef<JSArray>::Cast(arg);
10238 size_t size = obscuredArray->Length();
10239 std::vector<ObscuredReasons> reasons(size);
10240 reasons.clear();
10241 for (size_t i = 0; i < size; i++) {
10242 JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
10243 if (reason->IsNumber()) {
10244 reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
10245 }
10246 }
10247
10248 ViewAbstractModel::GetInstance()->SetObscured(reasons);
10249 }
10250
10251 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)10252 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
10253 {
10254 auto sensitiveInfo = info[0];
10255 if (sensitiveInfo->IsUndefined()) {
10256 ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
10257 return;
10258 }
10259 bool sensitive = false;
10260 if (sensitiveInfo->IsBoolean()) {
10261 sensitive = sensitiveInfo->ToBoolean();
10262 }
10263 ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
10264 }
10265
JSRenderGroup(const JSCallbackInfo & info)10266 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
10267 {
10268 if (info.Length() != 1) {
10269 return;
10270 }
10271 bool isRenderGroup = false;
10272 if (info[0]->IsBoolean()) {
10273 isRenderGroup = info[0]->ToBoolean();
10274 }
10275 ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
10276 }
10277
JSRenderFit(const JSCallbackInfo & info)10278 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
10279 {
10280 if (info.Length() != 1) {
10281 return;
10282 }
10283 RenderFit renderFit = RenderFit::TOP_LEFT;
10284 if (info[0]->IsNumber()) {
10285 int32_t fitNumber = info[0]->ToNumber<int32_t>();
10286 if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
10287 fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
10288 renderFit = static_cast<RenderFit>(fitNumber);
10289 }
10290 }
10291 // how content fills the node duration implicit animation
10292 ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
10293 }
10294
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)10295 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
10296 {
10297 if (!jsValue->IsObject() || jsValue->IsString()) {
10298 return false;
10299 }
10300 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10301 if (!jsObj->IsUndefined()) {
10302 JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
10303 JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
10304 if (bundle->IsString() && module->IsString()) {
10305 bundleName = bundle->ToString();
10306 moduleName = module->ToString();
10307 return true;
10308 }
10309 }
10310 return false;
10311 }
10312
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)10313 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
10314 const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
10315 {
10316 std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx](
10317 NG::DrawingContext& context) -> void {
10318 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
10319
10320 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
10321 objectTemplate->SetInternalFieldCount(1);
10322 JSRef<JSObject> contextObj = objectTemplate->NewInstance();
10323 JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
10324 sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
10325 sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
10326 contextObj->SetPropertyObject("size", sizeObj);
10327
10328 JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
10329 sizeInPxObj->SetProperty<float>("height", context.height);
10330 sizeInPxObj->SetProperty<float>("width", context.width);
10331 contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
10332
10333 auto engine = EngineHelper::GetCurrentEngine();
10334 CHECK_NULL_VOID(engine);
10335 NativeEngine* nativeEngine = engine->GetNativeEngine();
10336 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
10337 ScopeRAII scope(env);
10338
10339 auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
10340 OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
10341 napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
10342 if (unwrapCanvas) {
10343 unwrapCanvas->SaveCanvas();
10344 unwrapCanvas->ClipCanvas(context.width, context.height);
10345 }
10346 JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
10347 contextObj->SetPropertyObject("canvas", jsCanvasVal);
10348
10349 auto jsVal = JSRef<JSVal>::Cast(contextObj);
10350 panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
10351 JSValueWrapper valueWrapper = value;
10352 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
10353
10354 napi_wrap(
10355 env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
10356
10357 JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
10358 if (unwrapCanvas) {
10359 unwrapCanvas->RestoreCanvas();
10360 unwrapCanvas->ResetCanvas();
10361 }
10362 };
10363 return drawCallback;
10364 }
10365
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)10366 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
10367 {
10368 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10369 return false;
10370 }
10371 Color borderColor;
10372 if (ParseJsColor(args, borderColor)) {
10373 colorProperty.SetColor(borderColor);
10374 return true;
10375 } else if (args->IsObject()) {
10376 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10377 CommonColor commonColor;
10378 ParseCommonEdgeColors(obj, commonColor);
10379 colorProperty.topColor = commonColor.top;
10380 colorProperty.bottomColor = commonColor.bottom;
10381 colorProperty.leftColor = commonColor.left;
10382 colorProperty.rightColor = commonColor.right;
10383 colorProperty.multiValued = true;
10384 return true;
10385 }
10386 return false;
10387 }
10388
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)10389 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
10390 {
10391 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10392 return false;
10393 }
10394 CalcDimension borderWidth;
10395 if (ParseJsDimensionVpNG(args, borderWidth, true)) {
10396 if (borderWidth.IsNegative()) {
10397 borderWidth.Reset();
10398 }
10399 borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth });
10400 return true;
10401 } else if (args->IsObject()) {
10402 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10403 CommonCalcDimension commonCalcDimension;
10404 ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
10405 borderWidthProperty.topDimen = commonCalcDimension.top;
10406 borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
10407 borderWidthProperty.leftDimen = commonCalcDimension.left;
10408 borderWidthProperty.rightDimen = commonCalcDimension.right;
10409 borderWidthProperty.multiValued = true;
10410 return true;
10411 }
10412 return false;
10413 }
10414
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)10415 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
10416 {
10417 if (!args->IsObject() && !args->IsNumber()) {
10418 return false;
10419 }
10420 if (args->IsObject()) {
10421 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10422 auto leftValue = obj->GetProperty("left");
10423 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
10424 ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
10425 }
10426 auto rightValue = obj->GetProperty("right");
10427 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
10428 ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
10429 }
10430 auto topValue = obj->GetProperty("top");
10431 if (!topValue->IsUndefined() && topValue->IsNumber()) {
10432 ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
10433 }
10434 auto bottomValue = obj->GetProperty("bottom");
10435 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
10436 ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
10437 }
10438 borderStyleProperty.multiValued = true;
10439 return true;
10440 }
10441 std::optional<BorderStyle> borderStyle;
10442 if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
10443 borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
10444 return true;
10445 }
10446 return false;
10447 }
10448
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10449 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10450 {
10451 std::optional<CalcDimension> radiusTopLeft;
10452 std::optional<CalcDimension> radiusTopRight;
10453 std::optional<CalcDimension> radiusBottomLeft;
10454 std::optional<CalcDimension> radiusBottomRight;
10455 CalcDimension topLeft;
10456 if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) {
10457 radiusTopLeft = topLeft;
10458 }
10459 CalcDimension topRight;
10460 if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) {
10461 radiusTopRight = topRight;
10462 }
10463 CalcDimension bottomLeft;
10464 if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) {
10465 radiusBottomLeft = bottomLeft;
10466 }
10467 CalcDimension bottomRight;
10468 if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) {
10469 radiusBottomRight = bottomRight;
10470 }
10471 CheckLengthMetrics(object);
10472 radius.radiusTopLeft = radiusTopLeft;
10473 radius.radiusTopRight = radiusTopRight;
10474 radius.radiusBottomLeft = radiusBottomLeft;
10475 radius.radiusBottomRight = radiusBottomRight;
10476 radius.multiValued = true;
10477 return;
10478 }
10479
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10480 void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10481 {
10482 if (CheckLengthMetrics(object)) {
10483 std::optional<CalcDimension> radiusTopStart;
10484 std::optional<CalcDimension> radiusTopEnd;
10485 std::optional<CalcDimension> radiusBottomStart;
10486 std::optional<CalcDimension> radiusBottomEnd;
10487 if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
10488 JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
10489 CalcDimension calcDimension;
10490 if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
10491 CheckDimensionUnit(calcDimension, false, true);
10492 radiusTopStart = calcDimension;
10493 }
10494 }
10495 if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
10496 JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
10497 CalcDimension calcDimension;
10498 if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
10499 CheckDimensionUnit(calcDimension, false, true);
10500 radiusTopEnd = calcDimension;
10501 }
10502 }
10503 if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
10504 JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
10505 CalcDimension calcDimension;
10506 if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
10507 CheckDimensionUnit(calcDimension, false, true);
10508 radiusBottomStart = calcDimension;
10509 }
10510 }
10511 if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
10512 JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
10513 CalcDimension calcDimension;
10514 if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
10515 CheckDimensionUnit(calcDimension, false, true);
10516 radiusBottomEnd = calcDimension;
10517 }
10518 }
10519 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
10520 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
10521 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
10522 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
10523 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
10524 radius.multiValued = true;
10525 return;
10526 }
10527 ParseBorderRadiusProps(object, radius);
10528 }
10529
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)10530 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
10531 {
10532 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10533 return false;
10534 }
10535 CalcDimension borderRadius;
10536 if (ParseJsDimensionVpNG(args, borderRadius, true)) {
10537 radius = NG::BorderRadiusProperty(borderRadius);
10538 radius.multiValued = false;
10539 } else if (args->IsObject()) {
10540 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
10541 ParseCommonBorderRadiusProps(object, radius);
10542 } else {
10543 return false;
10544 }
10545 return true;
10546 }
10547
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)10548 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10549 {
10550 JSRef<JSVal> arg = info[0];
10551 if (!arg->IsObject()) {
10552 return;
10553 }
10554 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
10555 auto vm = info.GetVm();
10556 auto globalObj = JSNApi::GetGlobalObject(vm);
10557 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
10558 JsiValue jsiValue(globalFunc);
10559 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
10560 if (globalFuncRef->IsFunction()) {
10561 auto modifierObj = obj->GetProperty("modifier");
10562 if (modifierObj->IsUndefined()) {
10563 option.onApply = nullptr;
10564 } else {
10565 RefPtr<JsFunction> jsFunc =
10566 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
10567 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10568 modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
10569 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10570 auto node = frameNode.Upgrade();
10571 JSRef<JSVal> params[PARAMETER_LENGTH_SECOND];
10572 params[0] = modifier;
10573 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
10574 PipelineContext::SetCallBackNode(node);
10575 func->ExecuteJS(PARAMETER_LENGTH_SECOND, params);
10576 };
10577 option.onApply = onApply;
10578 }
10579 }
10580 }
10581
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)10582 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10583 {
10584 if (!info[0]->IsObject()) {
10585 return;
10586 }
10587 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
10588 auto numberBadge = obj->GetProperty("numberBadge");
10589 if (!numberBadge->IsEmpty()) {
10590 if (numberBadge->IsNumber()) {
10591 int64_t number = numberBadge->ToNumber<int64_t>();
10592 if (number < 0 || number > INT_MAX) {
10593 option.isNumber = false;
10594 option.isShowBadge = true;
10595 } else {
10596 option.isNumber = true;
10597 option.badgeNumber = numberBadge->ToNumber<int>();
10598 }
10599 } else if (numberBadge->IsBoolean()) {
10600 option.isNumber = false;
10601 option.isShowBadge = numberBadge->ToBoolean();
10602 }
10603 } else {
10604 option.isNumber = false;
10605 option.isShowBadge = true;
10606 }
10607 }
10608
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10609 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10610 {
10611 // Parse cornerRadius.
10612 auto cornerRadiusValue = obj->GetProperty("cornerRadius");
10613 NG::BorderRadiusProperty radius;
10614 if (ParseBorderRadius(cornerRadiusValue, radius)) {
10615 properties.borderRadius = radius;
10616 }
10617 // Parse border width
10618 auto borderWidthValue = obj->GetProperty("borderWidth");
10619 NG::BorderWidthProperty borderWidth;
10620 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
10621 properties.borderWidth = borderWidth;
10622 auto colorValue = obj->GetProperty("borderColor");
10623 NG::BorderColorProperty borderColor;
10624 if (ParseBorderColorProps(colorValue, borderColor)) {
10625 properties.borderColor = borderColor;
10626 } else {
10627 borderColor.SetColor(Color::BLACK);
10628 properties.borderColor = borderColor;
10629 }
10630 // Parse border style
10631 auto styleValue = obj->GetProperty("borderStyle");
10632 NG::BorderStyleProperty borderStyle;
10633 if (ParseBorderStyleProps(styleValue, borderStyle)) {
10634 properties.borderStyle = borderStyle;
10635 } else {
10636 properties.borderStyle = NG::BorderStyleProperty(
10637 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
10638 }
10639 }
10640 auto shadowValue = obj->GetProperty("shadow");
10641 Shadow shadow;
10642 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
10643 properties.shadow = shadow;
10644 }
10645 auto widthValue = obj->GetProperty("width");
10646 CalcDimension width;
10647 if (ParseJsDimensionVpNG(widthValue, width, true)) {
10648 properties.width = width;
10649 }
10650 auto heightValue = obj->GetProperty("height");
10651 CalcDimension height;
10652 if (ParseJsDimensionVpNG(heightValue, height, true)) {
10653 properties.height = height;
10654 }
10655 }
10656
SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10657 void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10658 {
10659 auto enableHoverModeValue = obj->GetProperty("enableHoverMode");
10660 if (enableHoverModeValue->IsBoolean()) {
10661 properties.enableHoverMode = enableHoverModeValue->ToBoolean();
10662 }
10663
10664 // Parse hoverModeArea
10665 auto hoverModeAreaValue = obj->GetProperty("hoverModeArea");
10666 if (hoverModeAreaValue->IsNumber()) {
10667 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
10668 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
10669 properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
10670 }
10671 }
10672 }
10673
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)10674 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
10675 {
10676 auto* vm = info.GetVm();
10677 return [vm, nodeId](const std::string& key) -> std::string {
10678 std::string resultString = std::string();
10679 CHECK_NULL_RETURN(vm, resultString);
10680 panda::LocalScope scope(vm);
10681 auto global = JSNApi::GetGlobalObject(vm);
10682 auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
10683 if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
10684 return resultString;
10685 }
10686 auto obj = getCustomProperty->ToObject(vm);
10687 panda::Local<panda::FunctionRef> func = obj;
10688 panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
10689 panda::StringRef::NewFromUtf8(vm, key.c_str()) };
10690 auto function = panda::CopyableGlobal(vm, func);
10691 auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
10692 if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
10693 return resultString;
10694 }
10695 auto value = callValue->ToString(vm)->ToString(vm);
10696 return value;
10697 };
10698 }
10699
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)10700 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
10701 {
10702 auto* vm = info.GetVm();
10703 panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
10704 info[1]->GetLocalHandle() };
10705 return [vm, params3]() -> bool {
10706 CHECK_NULL_RETURN(vm, false);
10707 panda::LocalScope scope(vm);
10708 auto global = JSNApi::GetGlobalObject(vm);
10709 auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
10710 if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
10711 return false;
10712 }
10713 auto obj = setCustomProperty->ToObject(vm);
10714 panda::Local<panda::FunctionRef> func = obj;
10715 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10716 auto nodeId = frameNode->GetId();
10717 auto function = panda::CopyableGlobal(vm, func);
10718 auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
10719 if (customPropertyExisted) {
10720 frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
10721 CHECK_NULL_VOID(vm);
10722 panda::LocalScope scope(vm);
10723 auto global = JSNApi::GetGlobalObject(vm);
10724 auto removeCustomProperty =
10725 global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
10726 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
10727 return;
10728 }
10729 auto obj = removeCustomProperty->ToObject(vm);
10730 panda::Local<panda::FunctionRef> func = obj;
10731 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
10732 auto function = panda::CopyableGlobal(vm, func);
10733 function->Call(vm, function.ToLocal(), params, 1);
10734 });
10735 }
10736 return true;
10737 };
10738 }
10739
JsCustomProperty(const JSCallbackInfo & info)10740 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
10741 {
10742 if (info[0]->GetLocalHandle()->IsUndefined()) {
10743 return;
10744 }
10745 auto* vm = info.GetVm();
10746 CHECK_NULL_VOID(vm);
10747 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10748 auto nodeId = frameNode->GetId();
10749 auto getFunc = ParseJsGetFunc(info, nodeId);
10750 auto func = ParseJsFunc(info, nodeId);
10751 frameNode->SetJSCustomProperty(func, getFunc);
10752 }
10753
JsGestureModifier(const JSCallbackInfo & info)10754 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
10755 {
10756 auto* vm = info.GetExecutionContext().vm_;
10757 CHECK_NULL_VOID(vm);
10758 auto global = JSNApi::GetGlobalObject(vm);
10759 auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
10760 if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
10761 return;
10762 }
10763 auto obj = gestureModifier->ToObject(vm);
10764 panda::Local<panda::FunctionRef> func = obj;
10765 auto thisObj = info.This()->GetLocalHandle();
10766 panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
10767 func->Call(vm, thisObj, params, 1);
10768 }
10769
JsBackgroundImageResizable(const JSCallbackInfo & info)10770 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
10771 {
10772 auto infoObj = info[0];
10773 ImageResizableSlice sliceResult;
10774 if (!infoObj->IsObject()) {
10775 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10776 return;
10777 }
10778 JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
10779 if (resizableObject->IsEmpty()) {
10780 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10781 return;
10782 }
10783 auto sliceValue = resizableObject->GetProperty("slice");
10784 if (!sliceValue->IsObject()) {
10785 return;
10786 }
10787 JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
10788 if (sliceObj->IsEmpty()) {
10789 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10790 return;
10791 }
10792 for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
10793 auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
10794 CalcDimension sliceDimension;
10795 if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
10796 continue;
10797 }
10798 if (!sliceDimension.IsValid()) {
10799 continue;
10800 }
10801 switch (static_cast<BorderImageDirection>(i)) {
10802 case BorderImageDirection::LEFT:
10803 sliceResult.left = sliceDimension;
10804 break;
10805 case BorderImageDirection::RIGHT:
10806 sliceResult.right = sliceDimension;
10807 break;
10808 case BorderImageDirection::TOP:
10809 sliceResult.top = sliceDimension;
10810 break;
10811 case BorderImageDirection::BOTTOM:
10812 sliceResult.bottom = sliceDimension;
10813 break;
10814 default:
10815 break;
10816 }
10817 }
10818 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
10819 }
10820
JsFocusScopeId(const JSCallbackInfo & info)10821 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
10822 {
10823 if (info.Length() == 0) {
10824 return;
10825 }
10826
10827 std::string focusScopeId;
10828 if (info[0]->IsString()) {
10829 focusScopeId = info[0]->ToString();
10830 }
10831
10832 bool isGroup = false;
10833 if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
10834 info[1]->IsBoolean()) {
10835 isGroup = info[1]->ToBoolean();
10836 }
10837 bool arrowKeyStepOut = true;
10838 if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() &&
10839 info[2]->IsBoolean()) {
10840 arrowKeyStepOut = info[2]->ToBoolean();
10841 }
10842 ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
10843 }
10844
JsFocusScopePriority(const JSCallbackInfo & info)10845 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
10846 {
10847 if (info.Length() == 0) {
10848 return;
10849 }
10850
10851 if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
10852 return;
10853 }
10854 std::string focusScopeId = info[0]->ToString();
10855
10856 int32_t focusPriority = 0;
10857 if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
10858 info[1]->IsNumber()) {
10859 focusPriority = info[1]->ToNumber<int32_t>();
10860 }
10861 ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
10862 }
10863
ParseJsPropertyId(const JSRef<JSVal> & jsValue)10864 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
10865 {
10866 int32_t resId = 0;
10867 if (jsValue->IsObject()) {
10868 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10869 JSRef<JSVal> tmp = jsObj->GetProperty("id");
10870 if (!tmp->IsNull() && tmp->IsNumber()) {
10871 resId = tmp->ToNumber<int32_t>();
10872 }
10873 }
10874 return resId;
10875 }
10876
JsVisualEffect(const JSCallbackInfo & info)10877 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
10878 {
10879 if (!info[0]->IsObject()) {
10880 return;
10881 }
10882 auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
10883 ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
10884 }
10885
JsBackgroundFilter(const JSCallbackInfo & info)10886 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
10887 {
10888 if (!info[0]->IsObject()) {
10889 return;
10890 }
10891 auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
10892 ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
10893 }
10894
JsForegroundFilter(const JSCallbackInfo & info)10895 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
10896 {
10897 if (!info[0]->IsObject()) {
10898 return;
10899 }
10900 auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
10901 ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
10902 }
10903
JsCompositingFilter(const JSCallbackInfo & info)10904 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
10905 {
10906 if (!info[0]->IsObject()) {
10907 return;
10908 }
10909 auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
10910 ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
10911 }
10912
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)10913 void JSViewAbstract::ParseOnCreateMenu(
10914 const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
10915 {
10916 if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
10917 return;
10918 }
10919 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10920 auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
10921 JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
10922 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
10923 instanceId = Container::CurrentId(), node = frameNode](
10924 const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
10925 ContainerScope scope(instanceId);
10926 std::vector<NG::MenuOptionsParam> menuParams;
10927 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
10928 auto pipelineContext = PipelineContext::GetCurrentContext();
10929 CHECK_NULL_RETURN(pipelineContext, menuParams);
10930
10931 pipelineContext->UpdateCurrentActiveNode(node);
10932 auto menuItem = func->ExecuteWithValue(systemMenuItems);
10933 if (!menuItem->IsArray()) {
10934 return menuParams;
10935 }
10936 auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
10937 for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
10938 auto menuItem = menuItemsArray->GetValueAt(i);
10939 if (!menuItem->IsObject()) {
10940 continue;
10941 }
10942 auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
10943 NG::MenuOptionsParam menuOptionsParam;
10944 auto jsContent = menuItemObject->GetProperty("content");
10945 std::string content;
10946 ParseJsString(jsContent, content);
10947 menuOptionsParam.content = content;
10948 auto jsStartIcon = menuItemObject->GetProperty("icon");
10949 std::string icon;
10950 ParseJsMedia(jsStartIcon, icon);
10951 menuOptionsParam.icon = icon;
10952 auto jsTextMenuId = menuItemObject->GetProperty("id");
10953 std::string id;
10954 if (jsTextMenuId->IsObject()) {
10955 auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
10956 auto jsId = textMenuIdObject->GetProperty("id_");
10957 ParseJsString(jsId, id);
10958 }
10959 menuOptionsParam.id = id;
10960 menuParams.emplace_back(menuOptionsParam);
10961 }
10962 return menuParams;
10963 };
10964 onCreateMenuCallback = jsCallback;
10965 }
10966
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)10967 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
10968 {
10969 JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
10970 uint32_t idx = 0;
10971 for (const auto& item : systemMenuItems) {
10972 systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
10973 }
10974 return systemMenuItemsArray;
10975 }
10976
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)10977 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
10978 NG::OnMenuItemClickCallback& onMenuItemClick)
10979 {
10980 auto tmpInfo = info[0];
10981 if (info.Length() != 1 || !tmpInfo->IsObject()) {
10982 return false;
10983 }
10984 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10985 auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
10986 auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
10987 ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
10988
10989 auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
10990 if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
10991 return false;
10992 }
10993 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
10994 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10995 onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
10996 node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
10997 ContainerScope scope(instanceId);
10998 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
10999 auto pipelineContext = PipelineContext::GetCurrentContext();
11000 CHECK_NULL_RETURN(pipelineContext, false);
11001 pipelineContext->UpdateCurrentActiveNode(node);
11002 auto paramArray = onMenuItemCallback(menuOptionsParam);
11003 if (paramArray->Length() != 2) {
11004 return false;
11005 }
11006 JSRef<JSVal> params[2];
11007 params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
11008 params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
11009 auto ret = func->ExecuteJS(2, params);
11010 if (ret->IsBoolean()) {
11011 return ret->ToBoolean();
11012 }
11013 return false;
11014 };
11015 onMenuItemClick = jsCallback;
11016 return true;
11017 }
11018
CreateJsTextMenuId(const std::string & id)11019 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
11020 {
11021 JSRef<JSObject> empty;
11022 auto engine = EngineHelper::GetCurrentEngine();
11023 CHECK_NULL_RETURN(engine, empty);
11024 NativeEngine* nativeEngine = engine->GetNativeEngine();
11025 CHECK_NULL_RETURN(nativeEngine, empty);
11026 auto env = reinterpret_cast<napi_env>(nativeEngine);
11027
11028 napi_value global;
11029 napi_status ret = napi_get_global(env, &global);
11030 if (ret != napi_ok) {
11031 return empty;
11032 }
11033 napi_value constructor;
11034 ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
11035 if (ret != napi_ok) {
11036 return empty;
11037 }
11038
11039 napi_value obj;
11040 napi_value menuId = nullptr;
11041
11042 ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
11043 if (ret != napi_ok) {
11044 return empty;
11045 }
11046 ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
11047 if (ret != napi_ok) {
11048 return empty;
11049 }
11050
11051 JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
11052 if (!value->IsObject()) {
11053 return empty;
11054 }
11055
11056 return JSRef<JSObject>::Cast(value);
11057 }
11058
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)11059 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
11060 {
11061 JSRef<JSArray> params = JSRef<JSArray>::New();
11062 params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
11063 params->SetValueAt(1, CreateJsTextRange(menuItemParam));
11064 return params;
11065 }
11066
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)11067 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
11068 {
11069 JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
11070 TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
11071 JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
11072 TextMenuItem->SetPropertyObject("id", obj);
11073 return JSRef<JSVal>::Cast(TextMenuItem);
11074 }
11075
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)11076 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
11077 {
11078 JSRef<JSObject> textRange = JSRef<JSObject>::New();
11079 textRange->SetProperty<int32_t>("start", menuItemParam.start);
11080 textRange->SetProperty<int32_t>("end", menuItemParam.end);
11081 return JSRef<JSVal>::Cast(textRange);
11082 }
11083
OHOS_ACE_ParseJsMedia(void * value,void * resource)11084 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
11085 {
11086 napi_value napiValue = reinterpret_cast<napi_value>(value);
11087 ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
11088 if (!napiValue || !res) {
11089 return;
11090 }
11091 JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
11092 std::string src;
11093 std::string bundleName;
11094 std::string moduleName;
11095 JSViewAbstract::ParseJsMedia(jsVal, src);
11096 JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
11097 res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
11098 res->src = src;
11099 res->bundleName = bundleName;
11100 res->moduleName = moduleName;
11101 }
11102
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)11103 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
11104 std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
11105 {
11106 if (!modifierObj->IsObject()) {
11107 textStyleApply = nullptr;
11108 return;
11109 }
11110 auto vm = info.GetVm();
11111 auto globalObj = JSNApi::GetGlobalObject(vm);
11112 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
11113 JsiValue jsiValue(globalFunc);
11114 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11115 if (!globalFuncRef->IsFunction()) {
11116 textStyleApply = nullptr;
11117 return;
11118 }
11119 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11120 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11121 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11122 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11123 auto node = frameNode.Upgrade();
11124 CHECK_NULL_VOID(node);
11125 JSRef<JSVal> params[2];
11126 params[0] = modifierParam;
11127 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11128 PipelineContext::SetCallBackNode(node);
11129 func->ExecuteJS(2, params);
11130 };
11131 textStyleApply = onApply;
11132 }
11133
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)11134 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
11135 std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
11136 {
11137 auto vm = info.GetVm();
11138 auto globalObj = JSNApi::GetGlobalObject(vm);
11139 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
11140 JsiValue jsiValue(globalFunc);
11141 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11142 if (globalFuncRef->IsFunction()) {
11143 RefPtr<JsFunction> jsFunc =
11144 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11145 if (!modifierObj->IsObject()) {
11146 symbolApply = nullptr;
11147 } else {
11148 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11149 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11150 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11151 auto node = frameNode.Upgrade();
11152 CHECK_NULL_VOID(node);
11153 JSRef<JSVal> params[2];
11154 params[0] = modifierParam;
11155 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11156 PipelineContext::SetCallBackNode(node);
11157 func->ExecuteJS(2, params);
11158 };
11159 symbolApply = onApply;
11160 }
11161 }
11162 }
11163 } // namespace OHOS::Ace::Framework
11164