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/js_ref_ptr.h"
57 #include "bridge/declarative_frontend/engine/js_types.h"
58 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h"
59 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
60 #include "bridge/js_frontend/engine/jsi/ark_js_value.h"
61 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
62 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
63 #include "bridge/declarative_frontend/engine/js_converter.h"
64 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
65 #include "bridge/declarative_frontend/engine/js_types.h"
66 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
67 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
68 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
69 #include "bridge/declarative_frontend/jsview/js_utils.h"
70 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
71 #include "bridge/declarative_frontend/jsview/js_view_context.h"
72 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
73 #include "core/event/focus_axis_event.h"
74 #include "canvas_napi/js_canvas.h"
75 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
76 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
77 #endif
78 #include "core/common/resource/resource_manager.h"
79 #include "core/common/resource/resource_object.h"
80 #include "core/components/common/layout/constants.h"
81 #include "core/components/common/layout/position_param.h"
82 #include "core/components/common/layout/screen_system_manager.h"
83 #include "core/components/common/properties/animation_option.h"
84 #include "core/components/common/properties/border_image.h"
85 #include "core/components/common/properties/color.h"
86 #include "core/components/common/properties/decoration.h"
87 #include "core/components/common/properties/shadow.h"
88 #include "core/components/common/properties/invert.h"
89 #include "core/components/common/properties/shadow_config.h"
90 #include "core/components/text_overlay/text_overlay_theme.h"
91 #include "core/components/theme/resource_adapter.h"
92 #include "core/components/theme/shadow_theme.h"
93 #include "core/components_ng/base/view_abstract.h"
94 #include "core/components_ng/base/view_abstract_model.h"
95 #include "core/components_ng/base/view_stack_processor.h"
96 #include "core/components_ng/event/focus_box.h"
97 #include "core/components_ng/gestures/base_gesture_event.h"
98 #include "core/components_ng/pattern/menu/menu_pattern.h"
99 #include "core/components_ng/pattern/overlay/modal_style.h"
100 #include "core/components_ng/pattern/overlay/sheet_style.h"
101 #include "core/components_ng/property/grid_property.h"
102 #include "core/components_ng/property/safe_area_insets.h"
103 #include "core/gestures/gesture_info.h"
104 #include "core/image/image_source_info.h"
105 #ifdef PLUGIN_COMPONENT_SUPPORTED
106 #include "core/common/plugin_manager.h"
107 #endif
108 #include "interfaces/native/node/resource.h"
109
110 #include "core/common/card_scope.h"
111 #include "core/common/container.h"
112 #include "core/common/resource/resource_configuration.h"
113 #include "core/components/progress/progress_theme.h"
114 #include "core/components_ng/base/view_abstract_model_ng.h"
115 #include "core/components_ng/base/view_stack_model.h"
116 #include "core/components_ng/property/progress_mask_property.h"
117 #include "core/components_ng/base/inspector.h"
118 #include "core/event/key_event.h"
119
120 namespace OHOS::Ace {
121 namespace {
122 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)";
123 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]";
124 constexpr int32_t DIRECTION_COUNT = 4;
125 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId";
126 constexpr int NUM1 = 1;
127 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
128 HoverModeAreaType::BOTTOM_SCREEN };
129 } // namespace
130
131 std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr;
132 std::mutex ViewAbstractModel::mutex_;
133 using DoubleBindCallback = std::function<void(const std::string&)>;
134
GetInstance()135 ViewAbstractModel* ViewAbstractModel::GetInstance()
136 {
137 if (!instance_) {
138 std::lock_guard<std::mutex> lock(mutex_);
139 if (!instance_) {
140 #ifdef NG_BUILD
141 instance_.reset(new NG::ViewAbstractModelNG());
142 #else
143 if (Container::IsCurrentUseNewPipeline()) {
144 instance_.reset(new NG::ViewAbstractModelNG());
145 } else {
146 instance_.reset(new Framework::ViewAbstractModelImpl());
147 }
148 #endif
149 }
150 }
151 return instance_.get();
152 }
153
154 } // namespace OHOS::Ace
155
156 namespace OHOS::Ace::Framework {
157 namespace {
158
159 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
160 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
161 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
162 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
163 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
164 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
165 constexpr int32_t MAX_ALIGN_VALUE = 8;
166 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
167 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
168 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
169 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
170 constexpr double FULL_DIMENSION = 100.0;
171 constexpr double HALF_DIMENSION = 50.0;
172 constexpr double ROUND_UNIT = 360.0;
173 constexpr double VISIBLE_RATIO_MIN = 0.0;
174 constexpr double VISIBLE_RATIO_MAX = 1.0;
175 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
176 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
177 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
178 constexpr int32_t SECOND_INDEX = 2;
179 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
180 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
181 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
182 constexpr float MAX_ANGLE = 360.0f;
183 constexpr float DEFAULT_BIAS = 0.5f;
184 constexpr float DEFAULT_LAYOUT_WEIGHT = 0.0f;
185 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
186 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
187 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
188 const std::string SHEET_HEIGHT_MEDIUM = "medium";
189 const std::string SHEET_HEIGHT_LARGE = "large";
190 const std::string SHEET_HEIGHT_AUTO = "auto";
191 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
192 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
193 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
194 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
195 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" };
196 const std::vector<int32_t> LENGTH_METRICS_KEYS {
197 static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END),
198 static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) };
199 const char* START_PROPERTY = "start";
200 const char* END_PROPERTY = "end";
201 const char* TOP_PROPERTY = "top";
202 const char* BOTTOM_PROPERTY = "bottom";
203 const char* LEFT_PROPERTY = "left";
204 const char* RIGHT_PROPERTY = "right";
205 const char* TOP_START_PROPERTY = "topStart";
206 const char* TOP_END_PROPERTY = "topEnd";
207 const char* BOTTOM_START_PROPERTY = "bottomStart";
208 const char* BOTTOM_END_PROPERTY = "bottomEnd";
209 const char* DEBUG_LINE_INFO_LINE = "$line";
210 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName";
211
212 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
213 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
214 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
215
216 enum class OperationType { COPY, PASTE, CUT, SELECT_ALL, UNKNOWN };
217
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)218 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
219 CalcDimension& centerX, CalcDimension& centerY)
220 {
221 double xVal = 1.0;
222 double yVal = 1.0;
223 double zVal = 1.0;
224 if (!jsValue->IsObject()) {
225 scaleX = static_cast<float>(xVal);
226 scaleY = static_cast<float>(yVal);
227 scaleZ = static_cast<float>(zVal);
228 CalcDimension length;
229 centerX = length;
230 centerY = length;
231 return;
232 }
233 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
234 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal);
235 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal);
236 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal);
237 scaleX = static_cast<float>(xVal);
238 scaleY = static_cast<float>(yVal);
239 scaleZ = static_cast<float>(zVal);
240 // if specify centerX
241 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX);
242 // if specify centerY
243 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY);
244 }
245
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)246 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
247 CalcDimension& translateZ)
248 {
249 if (!jsValue->IsObject()) {
250 return;
251 }
252 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
253 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX);
254 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY);
255 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ);
256 }
257
GetDefaultRotateVector(double & dx,double & dy,double & dz)258 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
259 {
260 dx = 0.0;
261 dy = 0.0;
262 dz = 0.0;
263 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
264 dz = 1.0;
265 }
266 }
267
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)268 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
269 {
270 if (!jsValue->IsObject()) {
271 return;
272 }
273 // default: dx, dy, dz (0.0, 0.0, 0.0)
274 double dxVal = 0.0;
275 double dyVal = 0.0;
276 double dzVal = 0.0;
277 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
278 auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
279 auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
280 auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z));
281 if (jsRotateX->IsUndefined()
282 && jsRotateY->IsUndefined()
283 && jsRotateZ->IsUndefined()) {
284 GetDefaultRotateVector(dxVal, dyVal, dzVal);
285 } else {
286 JSViewAbstract::ParseJsDouble(jsRotateX, dxVal);
287 JSViewAbstract::ParseJsDouble(jsRotateY, dyVal);
288 JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal);
289 }
290 rotate.xDirection = static_cast<float>(dxVal);
291 rotate.yDirection = static_cast<float>(dyVal);
292 rotate.zDirection = static_cast<float>(dzVal);
293 // if specify centerX
294 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)),
295 rotate.centerX)) {
296 rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
297 }
298 // if specify centerY
299 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)),
300 rotate.centerY)) {
301 rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
302 }
303 // if specify centerZ
304 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)),
305 rotate.centerZ)) {
306 rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
307 }
308 // if specify angle
309 JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle);
310 rotate.perspective = 0.0f;
311 JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective);
312 }
313
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)314 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
315 {
316 if (!jsValue->IsObject()) {
317 return false;
318 }
319
320 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
321 auto path = jsObj->GetPropertyValue<std::string>("path", "");
322 if (path.empty()) {
323 return false;
324 }
325 option.SetPath(path);
326 double from = 0.0;
327 double to = 1.0;
328 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
329 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
330 if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
331 from = 0.0;
332 }
333 if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
334 to = 1.0;
335 } else if (to < from) {
336 to = from;
337 }
338 option.SetBegin(static_cast<float>(from));
339 option.SetEnd(static_cast<float>(to));
340 option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
341 return true;
342 }
343
ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)344 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto)
345 {
346 if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::AUTO)) {
347 previewOption.ResetDragPreviewMode();
348 isAuto = true;
349 return;
350 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE)) {
351 previewOption.isScaleEnabled = false;
352 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW)) {
353 previewOption.isDefaultShadowEnabled = true;
354 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS)) {
355 previewOption.isDefaultRadiusEnabled = true;
356 }
357 isAuto = false;
358 }
359
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)360 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
361 BackgroundImagePosition& bgImgPosition)
362 {
363 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
364 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
365 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
366 }
367
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)368 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
369 {
370 auto index = pos + containCount;
371 if (index < 0) {
372 return std::string();
373 }
374
375 JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index));
376 if (type == "d") {
377 if (item->IsNumber()) {
378 return std::to_string(item->ToNumber<int32_t>());
379 } else if (item->IsObject()) {
380 int32_t result = 0;
381 JSViewAbstract::ParseJsInteger(item, result);
382 return std::to_string(result);
383 }
384 } else if (type == "s") {
385 if (item->IsString()) {
386 return item->ToString();
387 } else if (item->IsObject()) {
388 std::string result;
389 JSViewAbstract::ParseJsString(item, result);
390 return result;
391 }
392 } else if (type == "f") {
393 if (item->IsNumber()) {
394 return std::to_string(item->ToNumber<float>());
395 } else if (item->IsObject()) {
396 double result = 0.0;
397 JSViewAbstract::ParseJsDouble(item, result);
398 return std::to_string(result);
399 }
400 }
401 return std::string();
402 }
403
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)404 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
405 {
406 auto size = static_cast<int32_t>(params->Length());
407 if (containCount == size) {
408 return;
409 }
410 std::string::const_iterator start = originStr.begin();
411 std::string::const_iterator end = originStr.end();
412 std::smatch matches;
413 bool shortHolderType = false;
414 bool firstMatch = true;
415 int searchTime = 0;
416 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
417 std::string pos = matches[2];
418 std::string type = matches[4];
419 if (firstMatch) {
420 firstMatch = false;
421 shortHolderType = pos.length() == 0;
422 } else {
423 if (shortHolderType ^ (pos.length() == 0)) {
424 return;
425 }
426 }
427
428 std::string replaceContentStr;
429 if (shortHolderType) {
430 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
431 } else {
432 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
433 }
434
435 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
436 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
437 end = originStr.end();
438 searchTime++;
439 }
440 }
441
ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)442 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y)
443 {
444 JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
445 JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
446 bool hasX = false;
447 bool hasY = false;
448 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
449 hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP);
450 hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP);
451 } else {
452 hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
453 hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
454 }
455 return hasX || hasY;
456 }
457
ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)458 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges)
459 {
460 bool useEdges = false;
461 CalcDimension top;
462 CalcDimension left;
463 CalcDimension bottom;
464 CalcDimension right;
465 JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
466 JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
467 JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
468 JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
469 if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) {
470 edges.SetTop(top);
471 useEdges = true;
472 }
473 if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) {
474 edges.SetLeft(left);
475 useEdges = true;
476 }
477 if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) {
478 edges.SetBottom(bottom);
479 useEdges = true;
480 }
481 if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) {
482 edges.SetRight(right);
483 useEdges = true;
484 }
485 return useEdges;
486 }
487
ParseJsLengthMetrics(const JSRef<JSObject> & obj,CalcDimension & result)488 bool ParseJsLengthMetrics(const JSRef<JSObject>& obj, CalcDimension& result)
489 {
490 auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
491 if (!value->IsNumber()) {
492 return false;
493 }
494 auto unit = DimensionUnit::VP;
495 auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
496 if (jsUnit->IsNumber()) {
497 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
498 }
499 CalcDimension dimension(value->ToNumber<double>(), unit);
500 result = dimension;
501 return true;
502 }
503
CheckLengthMetrics(const JSRef<JSObject> & object)504 bool CheckLengthMetrics(const JSRef<JSObject>& object)
505 {
506 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
507 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) ||
508 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) ||
509 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) ||
510 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) ||
511 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) {
512 return true;
513 }
514 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
515 if (jsTop->IsObject()) {
516 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
517 if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
518 return true;
519 }
520 }
521 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
522 if (jsBottom->IsObject()) {
523 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
524 if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) {
525 return true;
526 }
527 }
528 return false;
529 }
530
ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)531 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges)
532 {
533 bool useLocalizedEdges = false;
534 CalcDimension start;
535 CalcDimension end;
536 CalcDimension top;
537 CalcDimension bottom;
538
539 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
540 if (startVal->IsObject()) {
541 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
542 ParseJsLengthMetrics(startObj, start);
543 edges.SetLeft(start);
544 useLocalizedEdges = true;
545 }
546 JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
547 if (endVal->IsObject()) {
548 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal);
549 ParseJsLengthMetrics(endObj, end);
550 edges.SetRight(end);
551 useLocalizedEdges = true;
552 }
553 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
554 if (topVal->IsObject()) {
555 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
556 ParseJsLengthMetrics(topObj, top);
557 edges.SetTop(top);
558 useLocalizedEdges = true;
559 }
560 JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
561 if (bottomVal->IsObject()) {
562 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(bottomVal);
563 ParseJsLengthMetrics(bottomObj, bottom);
564 edges.SetBottom(bottom);
565 useLocalizedEdges = true;
566 }
567 return useLocalizedEdges;
568 }
569
ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)570 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y)
571 {
572 bool useMarkAnchorPosition = false;
573 CalcDimension start;
574 CalcDimension top;
575
576 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
577 if (startVal->IsObject()) {
578 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal);
579 ParseJsLengthMetrics(startObj, start);
580 x = start;
581 useMarkAnchorPosition = true;
582 }
583 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
584 if (topVal->IsObject()) {
585 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal);
586 ParseJsLengthMetrics(topObj, top);
587 y = top;
588 useMarkAnchorPosition = true;
589 }
590 return useMarkAnchorPosition;
591 }
592
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)593 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
594 {
595 JSRef<JSVal> builder;
596 if (info->IsObject()) {
597 auto builderObj = JSRef<JSObject>::Cast(info);
598 builder = builderObj->GetProperty("builder");
599 } else if (info->IsFunction()) {
600 builder = info;
601 } else {
602 return nullptr;
603 }
604
605 if (!builder->IsFunction()) {
606 return nullptr;
607 }
608
609 return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
610 }
611
612 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
613 const JSRef<JSObject>& object, const JSExecutionContext& context);
614
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)615 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
616 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
617 {
618 RefPtr<NG::ChainedTransitionEffect> effect;
619 if (effectOption->IsObject()) {
620 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
621 std::optional<float> angle;
622 ParseJsRotate(effectOption, rotate, angle);
623 if (angle.has_value()) {
624 rotate.angle = angle.value();
625 return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
626 }
627 }
628 return nullptr;
629 }
630
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)631 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
632 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
633 {
634 double opacity = 1.0;
635 if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
636 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
637 if (LessNotEqual(opacity, 0.0) || opacity > 1.0) {
638 opacity = 1.0;
639 }
640 } else {
641 opacity = std::clamp(opacity, 0.0, 1.0);
642 }
643 return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
644 }
645 return nullptr;
646 }
647
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)648 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
649 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
650 {
651 if (effectOption->IsObject()) {
652 // default: x, y, z (0.0, 0.0, 0.0)
653 NG::TranslateOptions translate;
654 ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
655 return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
656 }
657 return nullptr;
658 }
659
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)660 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
661 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
662 {
663 if (effectOption->IsObject()) {
664 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
665 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
666 ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
667 return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
668 }
669 return nullptr;
670 }
671
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)672 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
673 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
674 {
675 int32_t edge = 0;
676 if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
677 if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
678 edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
679 edge = static_cast<int32_t>(NG::TransitionEdge::START);
680 }
681 return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
682 }
683 return nullptr;
684 }
685
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)686 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
687 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
688 {
689 if (effectOption->IsObject()) {
690 auto effectObj = JSRef<JSObject>::Cast(effectOption);
691 auto appearJsVal = effectObj->GetProperty("appear");
692 auto disappearJsVal = effectObj->GetProperty("disappear");
693 RefPtr<NG::ChainedTransitionEffect> appearEffect;
694 RefPtr<NG::ChainedTransitionEffect> disappearEffect;
695 if (appearJsVal->IsObject()) {
696 auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
697 appearEffect = ParseChainedTransition(appearObj, context);
698 }
699 if (disappearJsVal->IsObject()) {
700 auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
701 disappearEffect = ParseChainedTransition(disappearObj, context);
702 }
703 return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
704 }
705 return nullptr;
706 }
707
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)708 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
709 {
710 CHECK_NULL_RETURN(pipelineContext, 0);
711 return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
712 }
713
714 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
715 const JSRef<JSVal>&, const JSExecutionContext&);
716
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)717 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
718 const JSRef<JSObject>& object, const JSExecutionContext& context)
719 {
720 auto propType = object->GetProperty("type_");
721 if (!propType->IsString()) {
722 return nullptr;
723 }
724 std::string type = propType->ToString();
725 auto propEffectOption = object->GetProperty("effect_");
726 auto propAnimationOption = object->GetProperty("animation_");
727 auto propSuccessor = object->GetProperty("successor_");
728 static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
729 { "asymmetric", ParseChainedAsymmetricTransition },
730 { "identity",
731 [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
732 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
733 { "move", ParseChainedMoveTransition },
734 { "opacity", ParseChainedOpacityTransition },
735 { "rotate", ParseChainedRotateTransition },
736 { "scale", ParseChainedScaleTransition },
737 { "slideSwitch",
738 [](const JSRef<JSVal>& effectOption,
739 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
740 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
741 } },
742 { "translate", ParseChainedTranslateTransition },
743 };
744 int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
745 if (index < 0) {
746 return nullptr;
747 }
748 RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
749 if (!result) {
750 return nullptr;
751 }
752 if (propAnimationOption->IsObject()) {
753 auto container = Container::Current();
754 CHECK_NULL_RETURN(container, nullptr);
755 auto pipelineContext = container->GetPipelineContext();
756 CHECK_NULL_RETURN(pipelineContext, nullptr);
757 auto animationOptionResult = std::make_shared<AnimationOption>(
758 JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRender()));
759 // The maximum of the form-animation-playback duration value is 1000 ms.
760 if (pipelineContext->IsFormRender() && pipelineContext->IsFormAnimation()) {
761 auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
762 // If the duration exceeds 1000ms, init it to 0 ms.
763 if (formAnimationTimeInterval > DEFAULT_DURATION) {
764 animationOptionResult->SetDuration(0);
765 } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
766 // If remaining time is less than 1000ms, check for update duration.
767 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
768 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form Transition SetDuration: %{public}lld ms",
769 static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
770 }
771 }
772 auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
773 JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
774 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
775 if (onFinish->IsFunction()) {
776 RefPtr<JsFunction> jsFunc =
777 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
778 std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
779 id = Container::CurrentId(), node = targetNode]() {
780 ContainerScope scope(id);
781 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
782 PipelineContext::SetCallBackNode(node);
783 func->Execute();
784 };
785 animationOptionResult->SetOnFinishEvent(onFinishEvent);
786 }
787 result->SetAnimationOption(animationOptionResult);
788 }
789 if (propSuccessor->IsObject()) {
790 result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
791 }
792 return result;
793 }
794
795 #ifndef WEARABLE_PRODUCT
796 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
797 Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP,
798 Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM };
799
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)800 DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj)
801 {
802 JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent");
803 if (!changeEvent->IsFunction()) {
804 return {};
805 }
806 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent));
807 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
808 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
809 const std::string& param) {
810 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
811 if (param != "true" && param != "false") {
812 return;
813 }
814 PipelineContext::SetCallBackNode(node);
815 bool newValue = StringToBool(param);
816 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
817 func->ExecuteJS(1, &newJSVal);
818 };
819 return callback;
820 }
821
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)822 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
823 {
824 auto colorValue = messageOptionsObj->GetProperty("textColor");
825 Color textColor;
826 if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
827 if (popupParam) {
828 popupParam->SetTextColor(textColor);
829 }
830 }
831
832 auto font = messageOptionsObj->GetProperty("font");
833 if (!font->IsNull() && font->IsObject()) {
834 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
835 auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
836 CalcDimension fontSize;
837 if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
838 if (popupParam && fontSize.IsValid()) {
839 popupParam->SetFontSize(fontSize);
840 }
841 }
842 auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
843 if (fontWeightValue->IsString()) {
844 if (popupParam) {
845 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
846 }
847 }
848 auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
849 if (fontStyleValue->IsNumber()) {
850 int32_t value = fontStyleValue->ToNumber<int32_t>();
851 if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
852 return;
853 }
854 if (popupParam) {
855 popupParam->SetFontStyle(FONT_STYLES[value]);
856 }
857 }
858 }
859 }
860
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)861 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
862 {
863 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
864 if (placementOnTopVal->IsBoolean() && popupParam) {
865 popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
866 }
867 }
868
IsPopupCreated()869 bool IsPopupCreated()
870 {
871 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
872 CHECK_NULL_RETURN(targetNode, false);
873 auto targetId = targetNode->GetId();
874 auto container = Container::Current();
875 CHECK_NULL_RETURN(container, false);
876 auto pipelineContext = container->GetPipelineContext();
877 CHECK_NULL_RETURN(pipelineContext, false);
878 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
879 CHECK_NULL_RETURN(context, false);
880 auto overlayManager = context->GetOverlayManager();
881 CHECK_NULL_RETURN(overlayManager, false);
882 auto popupInfo = overlayManager->GetPopupInfo(targetId);
883 if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
884 return false;
885 }
886 return true;
887 }
888
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)889 void ParsePopupCommonParam(
890 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
891 {
892 auto arrowOffset = popupObj->GetProperty("arrowOffset");
893 CalcDimension offset;
894 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
895 if (popupParam) {
896 popupParam->SetArrowOffset(offset);
897 }
898 }
899
900 auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
901 if (arrowPointPosition->IsString()) {
902 char* pEnd = nullptr;
903 auto arrowString = arrowPointPosition->ToString();
904 std::strtod(arrowString.c_str(), &pEnd);
905 if (pEnd != nullptr) {
906 if (std::strcmp(pEnd, "Start") == 0) {
907 offset = ARROW_ZERO_PERCENT_VALUE;
908 }
909 if (std::strcmp(pEnd, "Center") == 0) {
910 offset = ARROW_HALF_PERCENT_VALUE;
911 }
912 if (std::strcmp(pEnd, "End") == 0) {
913 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
914 }
915 if (popupParam) {
916 popupParam->SetArrowOffset(offset);
917 }
918 }
919 }
920
921 auto targetSpace = popupObj->GetProperty("targetSpace");
922 if (!targetSpace->IsNull()) {
923 CalcDimension space;
924 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
925 if (popupParam) {
926 popupParam->SetTargetSpace(space);
927 }
928 }
929 }
930
931 JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
932 if (showInSubWindowValue->IsBoolean()) {
933 bool showInSubBoolean = showInSubWindowValue->ToBoolean();
934 #if defined(PREVIEW)
935 if (showInSubBoolean) {
936 LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
937 showInSubBoolean = false;
938 }
939 #endif
940 if (popupParam) {
941 popupParam->SetShowInSubWindow(showInSubBoolean);
942 }
943 }
944
945 auto placementValue = popupObj->GetProperty("placement");
946 if (placementValue->IsNumber()) {
947 auto placement = placementValue->ToNumber<int32_t>();
948 if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
949 popupParam->SetPlacement(PLACEMENT[placement]);
950 }
951 } else {
952 SetPlacementOnTopVal(popupObj, popupParam);
953 }
954
955 auto enableArrowValue = popupObj->GetProperty("enableArrow");
956 if (enableArrowValue->IsBoolean()) {
957 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
958 }
959
960 auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
961 if (followTransformOfTargetValue->IsBoolean()) {
962 popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
963 }
964
965 JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
966 if (maskValue->IsBoolean()) {
967 if (popupParam) {
968 popupParam->SetBlockEvent(maskValue->ToBoolean());
969 }
970 }
971 if (maskValue->IsObject()) {
972 auto maskObj = JSRef<JSObject>::Cast(maskValue);
973 auto colorValue = maskObj->GetProperty("color");
974 Color maskColor;
975 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
976 popupParam->SetMaskColor(maskColor);
977 }
978 }
979
980 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
981 if (onStateChangeVal->IsFunction()) {
982 std::vector<std::string> keys = { "isVisible" };
983 RefPtr<JsFunction> jsFunc =
984 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
985 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
986 if (popupParam) {
987 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
988 node = targetNode](const std::string& param) {
989 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
990 ACE_SCORING_EVENT("Popup.onStateChange");
991 PipelineContext::SetCallBackNode(node);
992 func->Execute(keys, param);
993 };
994 popupParam->SetOnStateChange(onStateChangeCallback);
995 }
996 }
997
998 auto offsetVal = popupObj->GetProperty("offset");
999 if (offsetVal->IsObject()) {
1000 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
1001 auto xVal = offsetObj->GetProperty("x");
1002 auto yVal = offsetObj->GetProperty("y");
1003 Offset popupOffset;
1004 CalcDimension dx;
1005 CalcDimension dy;
1006 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
1007 popupOffset.SetX(dx.ConvertToPx());
1008 }
1009 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
1010 popupOffset.SetY(dy.ConvertToPx());
1011 }
1012 if (popupParam) {
1013 popupParam->SetTargetOffset(popupOffset);
1014 }
1015 }
1016
1017 Color backgroundColor;
1018 auto popupColorVal = popupObj->GetProperty("popupColor");
1019 if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
1020 popupParam->SetBackgroundColor(backgroundColor);
1021 }
1022
1023 auto autoCancelVal = popupObj->GetProperty("autoCancel");
1024 if (autoCancelVal->IsBoolean()) {
1025 popupParam->SetHasAction(!autoCancelVal->ToBoolean());
1026 }
1027
1028 auto childWidthVal = popupObj->GetProperty("width");
1029 if (!childWidthVal->IsNull()) {
1030 CalcDimension width;
1031 if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
1032 if (width.Value() > 0) {
1033 popupParam->SetChildWidth(width);
1034 }
1035 }
1036 }
1037
1038 auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
1039 if (!arrowWidthVal->IsNull()) {
1040 bool setError = true;
1041 CalcDimension arrowWidth;
1042 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
1043 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
1044 popupParam->SetArrowWidth(arrowWidth);
1045 setError = false;
1046 }
1047 }
1048 popupParam->SetErrorArrowWidth(setError);
1049 }
1050
1051 auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
1052 if (!arrowHeightVal->IsNull()) {
1053 bool setError = true;
1054 CalcDimension arrowHeight;
1055 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
1056 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
1057 popupParam->SetArrowHeight(arrowHeight);
1058 setError = false;
1059 }
1060 }
1061 popupParam->SetErrorArrowHeight(setError);
1062 }
1063
1064 auto radiusVal = popupObj->GetProperty("radius");
1065 if (!radiusVal->IsNull()) {
1066 bool setError = true;
1067 CalcDimension radius;
1068 if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
1069 if (radius.Value() >= 0) {
1070 popupParam->SetRadius(radius);
1071 setError = false;
1072 }
1073 }
1074 popupParam->SetErrorRadius(setError);
1075 }
1076
1077 Shadow shadow;
1078 auto shadowVal = popupObj->GetProperty("shadow");
1079 if (shadowVal->IsObject() || shadowVal->IsNumber()) {
1080 auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
1081 if (!ret) {
1082 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1083 }
1084 } else {
1085 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
1086 }
1087 popupParam->SetShadow(shadow);
1088
1089 auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
1090 if (blurStyleValue->IsNumber()) {
1091 auto blurStyle = blurStyleValue->ToNumber<int32_t>();
1092 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1093 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1094 popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
1095 }
1096 }
1097
1098 auto popupTransition = popupObj->GetProperty("transition");
1099 if (popupTransition->IsObject()) {
1100 popupParam->SetHasTransition(true);
1101 auto obj = JSRef<JSObject>::Cast(popupTransition);
1102 auto effects = ParseChainedTransition(obj, info.GetExecutionContext());
1103 popupParam->SetTransitionEffects(effects);
1104 }
1105
1106 auto keyboardAvoidMode = popupObj->GetProperty("keyboardAvoidMode");
1107 if (keyboardAvoidMode->IsNumber()) {
1108 auto popupKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
1109 if (popupKeyboardAvoidMode >= static_cast<int>(PopupKeyboardAvoidMode::DEFAULT) &&
1110 popupKeyboardAvoidMode <= static_cast<int>(PopupKeyboardAvoidMode::NONE)) {
1111 popupParam->SetKeyBoardAvoidMode(static_cast<PopupKeyboardAvoidMode>(popupKeyboardAvoidMode));
1112 }
1113 }
1114 }
1115
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1116 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1117 {
1118 ParsePopupCommonParam(info, popupObj, popupParam);
1119 JSRef<JSVal> messageVal = popupObj->GetProperty("message");
1120 if (popupParam) {
1121 popupParam->SetMessage(messageVal->ToString());
1122 }
1123
1124 auto messageOptions = popupObj->GetProperty("messageOptions");
1125 JSRef<JSObject> messageOptionsObj;
1126 if (!messageOptions->IsNull() && messageOptions->IsObject()) {
1127 messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
1128 SetPopupMessageOptions(messageOptionsObj, popupParam);
1129 }
1130
1131 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
1132 if (primaryButtonVal->IsObject()) {
1133 ButtonProperties properties;
1134 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
1135 JSRef<JSVal> value = obj->GetProperty("value");
1136 if (value->IsString()) {
1137 properties.value = value->ToString();
1138 }
1139
1140 JSRef<JSVal> actionValue = obj->GetProperty("action");
1141 if (actionValue->IsFunction()) {
1142 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1143 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1144 if (popupParam) {
1145 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1146 node = targetNode](GestureEvent& info) {
1147 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1148 ACE_SCORING_EVENT("primaryButton.action");
1149 PipelineContext::SetCallBackNode(node);
1150 func->Execute(info);
1151 };
1152 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1153 }
1154 }
1155 properties.showButton = true;
1156 if (popupParam) {
1157 popupParam->SetPrimaryButtonProperties(properties);
1158 }
1159 }
1160
1161 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
1162 if (secondaryButtonVal->IsObject()) {
1163 ButtonProperties properties;
1164 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
1165 JSRef<JSVal> value = obj->GetProperty("value");
1166 if (value->IsString()) {
1167 properties.value = value->ToString();
1168 }
1169
1170 JSRef<JSVal> actionValue = obj->GetProperty("action");
1171 if (actionValue->IsFunction()) {
1172 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1173 auto targetNode =
1174 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1175 if (popupParam) {
1176 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1177 node = targetNode](GestureEvent& info) {
1178 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1179 ACE_SCORING_EVENT("secondaryButton.action");
1180 PipelineContext::SetCallBackNode(node);
1181 func->Execute(info);
1182 };
1183 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1184 }
1185 }
1186 properties.showButton = true;
1187 if (popupParam) {
1188 popupParam->SetSecondaryButtonProperties(properties);
1189 }
1190 }
1191 }
1192
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1193 void ParseCustomPopupParam(
1194 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1195 {
1196 auto builderValue = popupObj->GetProperty("builder");
1197 if (!builderValue->IsObject()) {
1198 return;
1199 }
1200 if (!builderValue->IsFunction()) {
1201 JSRef<JSObject> builderObj;
1202 builderObj = JSRef<JSObject>::Cast(builderValue);
1203 auto builder = builderObj->GetProperty("builder");
1204 if (!builder->IsFunction()) {
1205 return;
1206 }
1207 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1208 if (!builderFunc) {
1209 return;
1210 }
1211 }
1212 if (popupParam) {
1213 popupParam->SetUseCustomComponent(true);
1214 }
1215
1216 auto focusableValue = popupObj->GetProperty("focusable");
1217 if (focusableValue->IsBoolean()) {
1218 popupParam->SetFocusable(focusableValue->ToBoolean());
1219 }
1220
1221 ParsePopupCommonParam(info, popupObj, popupParam);
1222 }
1223 #endif
1224
GetBundleNameFromContainer()1225 std::string GetBundleNameFromContainer()
1226 {
1227 auto container = Container::Current();
1228 CHECK_NULL_RETURN(container, "");
1229 return container->GetBundleName();
1230 }
1231
GetModuleNameFromContainer()1232 std::string GetModuleNameFromContainer()
1233 {
1234 auto container = Container::Current();
1235 CHECK_NULL_RETURN(container, "");
1236 return container->GetModuleName();
1237 }
1238
CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)1239 void CompleteResourceObjectFromParams(
1240 int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName)
1241 {
1242 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
1243 int32_t typeNum = -1;
1244 if (type->IsNumber()) {
1245 typeNum = type->ToNumber<int32_t>();
1246 }
1247
1248 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1249 if (!args->IsArray()) {
1250 return;
1251 }
1252 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1253 if (resId != UNKNOWN_RESOURCE_ID) {
1254 return;
1255 }
1256 JSRef<JSVal> identity = params->GetValueAt(0);
1257
1258 bool isParseDollarResourceSuccess =
1259 JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE);
1260 if (!isParseDollarResourceSuccess) {
1261 return;
1262 }
1263
1264 std::regex resNameRegex(RESOURCE_NAME_PATTERN);
1265 std::smatch resNameResults;
1266 if (std::regex_match(targetModule, resNameResults, resNameRegex)) {
1267 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]);
1268 }
1269
1270 if (typeNum == UNKNOWN_RESOURCE_TYPE) {
1271 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1272 }
1273 }
1274
CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)1275 void CompleteResourceObjectFromId(
1276 JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName)
1277 {
1278 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
1279 if (!args->IsArray()) {
1280 return;
1281 }
1282 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1283 auto paramCount = params->Length();
1284 JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
1285 if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
1286 std::vector<JSRef<JSVal>> tmpParams;
1287 for (uint32_t i = 0; i < paramCount; i++) {
1288 auto param = params->GetValueAt(i);
1289 tmpParams.insert(tmpParams.end(), param);
1290 }
1291 params->SetValueAt(0, name);
1292 uint32_t paramIndex = 1;
1293 if (!type->IsEmpty()) {
1294 params->SetValueAt(paramIndex, type);
1295 paramIndex++;
1296 }
1297 for (auto tmpParam : tmpParams) {
1298 params->SetValueAt(paramIndex, tmpParam);
1299 paramIndex++;
1300 }
1301 } else {
1302 params->SetValueAt(0, name);
1303 }
1304 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID);
1305 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType));
1306 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) {
1307 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1308 }
1309 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) {
1310 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1311 }
1312 }
1313
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)1314 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative)
1315 {
1316 if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
1317 checkDimension.Reset();
1318 return;
1319 }
1320 if (notNegative && checkDimension.IsNegative()) {
1321 checkDimension.Reset();
1322 return;
1323 }
1324 }
1325
ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1326 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1327 {
1328 Color left;
1329 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) {
1330 commonColor.left = left;
1331 }
1332 Color right;
1333 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) {
1334 commonColor.right = right;
1335 }
1336 Color top;
1337 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1338 commonColor.top = top;
1339 }
1340 Color bottom;
1341 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1342 commonColor.bottom = bottom;
1343 }
1344 }
1345
ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1346 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor)
1347 {
1348 Color start;
1349 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) {
1350 localizedColor.start = start;
1351 }
1352 Color end;
1353 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) {
1354 localizedColor.end = end;
1355 }
1356 Color top;
1357 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) {
1358 localizedColor.top = top;
1359 }
1360 Color bottom;
1361 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) {
1362 localizedColor.bottom = bottom;
1363 }
1364 }
1365
ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1366 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor)
1367 {
1368 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) ||
1369 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) {
1370 LocalizedColor localizedColor;
1371 ParseLocalizedEdgeColors(object, localizedColor);
1372 commonColor.top = localizedColor.top;
1373 commonColor.bottom = localizedColor.bottom;
1374 commonColor.left = localizedColor.start;
1375 commonColor.right = localizedColor.end;
1376 return true;
1377 }
1378 ParseEdgeColors(object, commonColor);
1379 return false;
1380 }
1381
ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1382 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1383 {
1384 CalcDimension left;
1385 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(LEFT_PROPERTY), left)) {
1386 CheckDimensionUnit(left, true, notNegative);
1387 commonCalcDimension.left = left;
1388 }
1389 CalcDimension right;
1390 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(RIGHT_PROPERTY), right)) {
1391 CheckDimensionUnit(right, true, notNegative);
1392 commonCalcDimension.right = right;
1393 }
1394 CalcDimension top;
1395 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(TOP_PROPERTY), top)) {
1396 CheckDimensionUnit(top, true, notNegative);
1397 commonCalcDimension.top = top;
1398 }
1399 CalcDimension bottom;
1400 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(BOTTOM_PROPERTY), bottom)) {
1401 CheckDimensionUnit(bottom, true, notNegative);
1402 commonCalcDimension.bottom = bottom;
1403 }
1404 }
1405
ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1406 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent,
1407 bool notNegative, CalcDimension defaultValue)
1408 {
1409 CalcDimension left;
1410 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) {
1411 CheckDimensionUnit(left, notPercent, notNegative);
1412 commonCalcDimension.left = left;
1413 } else {
1414 commonCalcDimension.left = defaultValue;
1415 }
1416 CalcDimension right;
1417 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) {
1418 CheckDimensionUnit(right, notPercent, notNegative);
1419 commonCalcDimension.right = right;
1420 } else {
1421 commonCalcDimension.right = defaultValue;
1422 }
1423 CalcDimension top;
1424 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) {
1425 CheckDimensionUnit(top, notPercent, notNegative);
1426 commonCalcDimension.top = top;
1427 } else {
1428 commonCalcDimension.top = defaultValue;
1429 }
1430 CalcDimension bottom;
1431 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) {
1432 CheckDimensionUnit(bottom, false, true);
1433 commonCalcDimension.bottom = bottom;
1434 } else {
1435 commonCalcDimension.bottom = defaultValue;
1436 }
1437 }
1438
ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)1439 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension,
1440 bool notNegative)
1441 {
1442 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
1443 if (jsStart->IsObject()) {
1444 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
1445 CalcDimension calcDimension;
1446 if (ParseJsLengthMetrics(startObj, calcDimension)) {
1447 CheckDimensionUnit(calcDimension, true, notNegative);
1448 localizedCalcDimension.start = calcDimension;
1449 }
1450 }
1451 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
1452 if (jsEnd->IsObject()) {
1453 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
1454 CalcDimension calcDimension;
1455 if (ParseJsLengthMetrics(endObj, calcDimension)) {
1456 CheckDimensionUnit(calcDimension, true, notNegative);
1457 localizedCalcDimension.end = calcDimension;
1458 }
1459 }
1460 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
1461 if (jsTop->IsObject()) {
1462 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
1463 CalcDimension calcDimension;
1464 if (ParseJsLengthMetrics(topObj, calcDimension)) {
1465 CheckDimensionUnit(calcDimension, true, notNegative);
1466 localizedCalcDimension.top = calcDimension;
1467 }
1468 }
1469 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
1470 if (jsBottom->IsObject()) {
1471 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
1472 CalcDimension calcDimension;
1473 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1474 CheckDimensionUnit(calcDimension, true, notNegative);
1475 localizedCalcDimension.bottom = calcDimension;
1476 }
1477 }
1478 }
1479
ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)1480 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
1481 {
1482 if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) {
1483 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY));
1484 CalcDimension calcDimension;
1485 if (ParseJsLengthMetrics(startObj, calcDimension)) {
1486 CheckDimensionUnit(calcDimension, false, true);
1487 localizedCalcDimension.start = calcDimension;
1488 }
1489 }
1490 if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) {
1491 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY));
1492 CalcDimension calcDimension;
1493 if (ParseJsLengthMetrics(endObj, calcDimension)) {
1494 CheckDimensionUnit(calcDimension, false, true);
1495 localizedCalcDimension.end = calcDimension;
1496 }
1497 }
1498 if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) {
1499 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY));
1500 CalcDimension calcDimension;
1501 if (ParseJsLengthMetrics(topObj, calcDimension)) {
1502 CheckDimensionUnit(calcDimension, false, true);
1503 localizedCalcDimension.top = calcDimension;
1504 }
1505 }
1506 if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) {
1507 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY));
1508 CalcDimension calcDimension;
1509 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
1510 CheckDimensionUnit(calcDimension, false, true);
1511 localizedCalcDimension.bottom = calcDimension;
1512 }
1513 }
1514 }
1515
ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1516 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative)
1517 {
1518 if (CheckLengthMetrics(object)) {
1519 LocalizedCalcDimension localizedCalcDimension;
1520 ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative);
1521 commonCalcDimension.top = localizedCalcDimension.top;
1522 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1523 commonCalcDimension.left = localizedCalcDimension.start;
1524 commonCalcDimension.right = localizedCalcDimension.end;
1525 return true;
1526 }
1527 ParseEdgeWidths(object, commonCalcDimension, notNegative);
1528 return false;
1529 }
1530
ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1531 void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1532 {
1533 if (CheckLengthMetrics(object)) {
1534 LocalizedCalcDimension localizedCalcDimension;
1535 ParseLocalizedEdgeWidths(object, localizedCalcDimension, false);
1536 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1537 commonCalcDimension.top = localizedCalcDimension.top;
1538 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1539 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1540 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1541 return;
1542 }
1543 ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1));
1544 }
1545
ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1546 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
1547 {
1548 if (CheckLengthMetrics(object)) {
1549 LocalizedCalcDimension localizedCalcDimension;
1550 ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension);
1551 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
1552 commonCalcDimension.top = localizedCalcDimension.top;
1553 commonCalcDimension.bottom = localizedCalcDimension.bottom;
1554 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start;
1555 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end;
1556 return;
1557 }
1558 ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp);
1559 }
1560
ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1561 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context)
1562 {
1563 auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc));
1564 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1565 auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) {
1566 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1567 NG::PipelineContext::SetCallBackNode(targetNode);
1568 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn));
1569 jsFuncFinish->ExecuteJS(1, &newJSVal);
1570 };
1571 return finishCallback;
1572 }
1573 } // namespace
1574
GetResourceObject(const JSRef<JSObject> & jsObj)1575 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1576 {
1577 auto id = jsObj->GetProperty("id")->ToNumber<int32_t>();
1578 auto type = jsObj->GetProperty("type")->ToNumber<int32_t>();
1579 auto args = jsObj->GetProperty("params");
1580
1581 std::string bundleName;
1582 std::string moduleName;
1583 auto bundle = jsObj->GetProperty("bundleName");
1584 auto module = jsObj->GetProperty("moduleName");
1585 if (bundle->IsString() && module->IsString()) {
1586 bundleName = bundle->ToString();
1587 moduleName = module->ToString();
1588 }
1589 if (!args->IsArray()) {
1590 return nullptr;
1591 }
1592 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1593 std::vector<ResourceObjectParams> resObjParamsList;
1594 auto size = static_cast<int32_t>(params->Length());
1595 for (int32_t i = 0; i < size; i++) {
1596 auto item = params->GetValueAt(i);
1597 ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1598 if (item->IsString()) {
1599 resObjParams.type = ResourceObjectParamType::STRING;
1600 } else if (item->IsNumber()) {
1601 if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1602 resObjParams.type = ResourceObjectParamType::FLOAT;
1603 } else {
1604 resObjParams.type = ResourceObjectParamType::INT;
1605 }
1606 }
1607 resObjParamsList.push_back(resObjParams);
1608 }
1609 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName);
1610 return resourceObject;
1611 }
1612
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1613 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1614 {
1615 auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), "");
1616 auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), "");
1617 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName);
1618 return resourceObject;
1619 }
1620
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1621 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1622 {
1623 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1624 RefPtr<ThemeConstants> themeConstants = nullptr;
1625 if (SystemProperties::GetResourceDecoupling()) {
1626 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1627 if (!resourceAdapter) {
1628 return nullptr;
1629 }
1630 } else {
1631 themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1632 if (!themeConstants) {
1633 return nullptr;
1634 }
1635 }
1636 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1637 return resourceWrapper;
1638 }
1639
CreateResourceWrapper()1640 RefPtr<ResourceWrapper> CreateResourceWrapper()
1641 {
1642 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1643 RefPtr<ThemeConstants> themeConstants = nullptr;
1644 if (SystemProperties::GetResourceDecoupling()) {
1645 resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter();
1646 if (!resourceAdapter) {
1647 return nullptr;
1648 }
1649 } else {
1650 themeConstants = JSViewAbstract::GetThemeConstants();
1651 if (!themeConstants) {
1652 return nullptr;
1653 }
1654 }
1655 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1656 return resourceWrapper;
1657 }
1658
ColorAlphaAdapt(uint32_t origin)1659 uint32_t ColorAlphaAdapt(uint32_t origin)
1660 {
1661 uint32_t result = origin;
1662 if (origin >> COLOR_ALPHA_OFFSET == 0) {
1663 result = origin | COLOR_ALPHA_VALUE;
1664 }
1665 return result;
1666 }
1667
StringToOperationType(const std::string & id)1668 OperationType StringToOperationType(const std::string& id)
1669 {
1670 if (id == "OH_DEFAULT_COPY") {
1671 return OperationType::COPY;
1672 } else if (id == "OH_DEFAULT_PASTE") {
1673 return OperationType::PASTE;
1674 } else if (id == "OH_DEFAULT_CUT") {
1675 return OperationType::CUT;
1676 } else if (id == "OH_DEFAULT_SELECT_ALL") {
1677 return OperationType::SELECT_ALL;
1678 } else {
1679 return OperationType::UNKNOWN;
1680 }
1681 }
1682
UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam> & params)1683 void UpdateOptionsLabelInfo(std::vector<NG::MenuItemParam>& params)
1684 {
1685 for (auto& param : params) {
1686 auto opType = StringToOperationType(param.menuOptionsParam.id);
1687 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1688 CHECK_NULL_VOID(pipeline);
1689 auto theme = pipeline->GetTheme<TextOverlayTheme>();
1690 CHECK_NULL_VOID(theme);
1691 switch (opType) {
1692 case OperationType::COPY:
1693 param.menuOptionsParam.labelInfo = theme->GetCopyLabelInfo();
1694 break;
1695 case OperationType::PASTE:
1696 param.menuOptionsParam.labelInfo = theme->GetPasteLabelInfo();
1697 break;
1698 case OperationType::CUT:
1699 param.menuOptionsParam.labelInfo = theme->GetCutLabelInfo();
1700 break;
1701 case OperationType::SELECT_ALL:
1702 param.menuOptionsParam.labelInfo = theme->GetSelectAllLabelInfo();
1703 break;
1704 default:
1705 param.menuOptionsParam.labelInfo = "";
1706 break;
1707 }
1708 }
1709 }
1710
JsScale(const JSCallbackInfo & info)1711 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1712 {
1713 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1714 auto jsVal = info[0];
1715 if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) {
1716 SetDefaultScale();
1717 return;
1718 }
1719
1720 if (jsVal->IsObject()) {
1721 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1722 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1723 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1724 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1725 // default: x, y, z (1.0, 1.0, 1.0)
1726 auto scaleX = 1.0f;
1727 auto scaleY = 1.0f;
1728 auto scaleZ = 1.0f;
1729 // default centerX, centerY 50% 50%;
1730 CalcDimension centerX = 0.5_pct;
1731 CalcDimension centerY = 0.5_pct;
1732 ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY);
1733 ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1734 ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1735 return;
1736 } else {
1737 SetDefaultScale();
1738 }
1739 }
1740 double scale = 0.0;
1741 if (ParseJsDouble(jsVal, scale)) {
1742 ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1743 }
1744 }
1745
SetDefaultScale()1746 void JSViewAbstract::SetDefaultScale()
1747 {
1748 ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1749 ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1750 }
1751
JsScaleX(const JSCallbackInfo & info)1752 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1753 {
1754 double scaleVal = 0.0;
1755 if (!ParseJsDouble(info[0], scaleVal)) {
1756 return;
1757 }
1758 ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1759 }
1760
JsScaleY(const JSCallbackInfo & info)1761 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1762 {
1763 double scaleVal = 0.0;
1764 if (!ParseJsDouble(info[0], scaleVal)) {
1765 return;
1766 }
1767 ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1768 }
1769
JsOpacity(const JSCallbackInfo & info)1770 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1771 {
1772 double opacity = 0.0;
1773 if (!ParseJsDouble(info[0], opacity)) {
1774 ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1775 return;
1776 }
1777 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1778 opacity = std::clamp(opacity, 0.0, 1.0);
1779 } else {
1780 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1781 opacity = 1.0;
1782 }
1783 }
1784 ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1785 }
1786
JsTranslate(const JSCallbackInfo & info)1787 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1788 {
1789 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1790 JSCallbackInfoType::OBJECT };
1791 auto jsVal = info[0];
1792 if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) {
1793 SetDefaultTranslate();
1794 return;
1795 }
1796
1797 if (jsVal->IsObject()) {
1798 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
1799 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) ||
1800 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) ||
1801 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) {
1802 // default: x, y, z (0.0, 0.0, 0.0)
1803 auto translateX = CalcDimension(0.0);
1804 auto translateY = CalcDimension(0.0);
1805 auto translateZ = CalcDimension(0.0);
1806 ParseJsTranslate(jsVal, translateX, translateY, translateZ);
1807 ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1808 return;
1809 } else {
1810 SetDefaultTranslate();
1811 }
1812 }
1813 CalcDimension value;
1814 if (ParseJsDimensionVp(jsVal, value)) {
1815 ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1816 }
1817 }
1818
SetDefaultTranslate()1819 void JSViewAbstract::SetDefaultTranslate()
1820 {
1821 ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1822 }
1823
JsTranslateX(const JSCallbackInfo & info)1824 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1825 {
1826 CalcDimension value;
1827 if (!ParseJsDimensionVp(info[0], value)) {
1828 return;
1829 }
1830 ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1831 }
1832
JsTranslateY(const JSCallbackInfo & info)1833 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1834 {
1835 CalcDimension value;
1836 if (!ParseJsDimensionVp(info[0], value)) {
1837 return;
1838 }
1839 ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1840 }
1841
JsRotate(const JSCallbackInfo & info)1842 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1843 {
1844 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1845 auto jsVal = info[0];
1846 if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) {
1847 SetDefaultRotate();
1848 return;
1849 }
1850
1851 if (jsVal->IsObject()) {
1852 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1853 std::optional<float> angle;
1854 ParseJsRotate(jsVal, rotate, angle);
1855 if (angle) {
1856 ViewAbstractModel::GetInstance()->SetRotate(
1857 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1858 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1859 } else {
1860 SetDefaultRotate();
1861 }
1862 return;
1863 }
1864 double rotateZ;
1865 if (ParseJsDouble(jsVal, rotateZ)) {
1866 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1867 }
1868 }
1869
SetDefaultRotate()1870 void JSViewAbstract::SetDefaultRotate()
1871 {
1872 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1873 ViewAbstractModel::GetInstance()->SetRotate(
1874 rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1875 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1876 }
1877
JsRotateX(const JSCallbackInfo & info)1878 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1879 {
1880 double rotateVal = 0.0;
1881 if (!ParseJsDouble(info[0], rotateVal)) {
1882 return;
1883 }
1884 ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1885 }
1886
JsRotateY(const JSCallbackInfo & info)1887 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1888 {
1889 double rotateVal = 0.0;
1890 if (!ParseJsDouble(info[0], rotateVal)) {
1891 return;
1892 }
1893 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1894 }
1895
JsTransform(const JSCallbackInfo & info)1896 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1897 {
1898 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1899 auto jsVal = info[0];
1900 if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) {
1901 SetDefaultTransform();
1902 return;
1903 }
1904 JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
1905 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1906 if (!array->IsArray()) {
1907 return;
1908 }
1909 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1910 if (jsArray->Length() != matrix4Len) {
1911 return;
1912 }
1913 std::vector<float> matrix(matrix4Len);
1914 for (int32_t i = 0; i < matrix4Len; i++) {
1915 double value = 0.0;
1916 ParseJsDouble(jsArray->GetValueAt(i), value);
1917 matrix[i] = static_cast<float>(value);
1918 }
1919 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1920 }
1921
SetDefaultTransform()1922 void JSViewAbstract::SetDefaultTransform()
1923 {
1924 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1925 std::vector<float> matrix(matrix4Len);
1926 const int32_t initPosition = 5;
1927 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1928 double value = 1.0;
1929 matrix[i] = static_cast<float>(value);
1930 }
1931 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1932 }
1933
ParseJsTransition(const JSRef<JSObject> & jsObj)1934 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj)
1935 {
1936 NG::TransitionOptions transitionOption;
1937 bool hasEffect = false;
1938 transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1939 if (jsObj->HasProperty("opacity")) {
1940 double opacity = 1.0;
1941 ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1942 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1943 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1944 opacity = 1.0;
1945 }
1946 } else {
1947 opacity = std::clamp(opacity, 0.0, 1.0);
1948 }
1949 transitionOption.UpdateOpacity(static_cast<float>(opacity));
1950 hasEffect = true;
1951 }
1952 if (jsObj->HasProperty("translate")) {
1953 // default: x, y, z (0.0, 0.0, 0.0)
1954 NG::TranslateOptions translate;
1955 ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1956 transitionOption.UpdateTranslate(translate);
1957 hasEffect = true;
1958 }
1959 if (jsObj->HasProperty("scale")) {
1960 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1961 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1962 ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1963 scale.centerX, scale.centerY);
1964 transitionOption.UpdateScale(scale);
1965 hasEffect = true;
1966 }
1967 if (jsObj->HasProperty("rotate")) {
1968 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1969 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1970 std::optional<float> angle;
1971 ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1972 if (angle.has_value()) {
1973 rotate.angle = angle.value();
1974 transitionOption.UpdateRotate(rotate);
1975 hasEffect = true;
1976 }
1977 }
1978 if (!hasEffect) {
1979 // default transition
1980 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1981 }
1982 return transitionOption;
1983 }
1984
ParseJsTransitionEffect(const JSCallbackInfo & info)1985 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info)
1986 {
1987 JSRef<JSVal> arg = info[0];
1988 if (!arg->IsObject()) {
1989 return nullptr;
1990 }
1991 auto obj = JSRef<JSObject>::Cast(arg);
1992 auto transitionVal = obj->GetProperty("transition");
1993
1994 if (!transitionVal->IsObject()) {
1995 return nullptr;
1996 }
1997
1998 auto transitionObj = JSRef<JSObject>::Cast(transitionVal);
1999 auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext());
2000 return chainedEffect;
2001 }
2002
ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)2003 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object,
2004 const JSExecutionContext& context)
2005 {
2006 auto chainedEffect = ParseChainedTransition(object, context);
2007 return chainedEffect;
2008 }
2009
JsTransition(const JSCallbackInfo & info)2010 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
2011 {
2012 if (info.Length() < 1 || !info[0]->IsObject()) {
2013 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
2014 ViewAbstractModel::GetInstance()->CleanTransition();
2015 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
2016 }
2017 return;
2018 }
2019 auto obj = JSRef<JSObject>::Cast(info[0]);
2020 if (!obj->GetProperty("successor_")->IsUndefined()) {
2021 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
2022 std::function<void(bool)> finishCallback;
2023 if (info.Length() > 1 && info[1]->IsFunction()) {
2024 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
2025 }
2026 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
2027 return;
2028 }
2029 auto options = ParseJsTransition(obj);
2030 ViewAbstractModel::GetInstance()->SetTransition(options);
2031 }
2032
JsWidth(const JSCallbackInfo & info)2033 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
2034 {
2035 JsWidth(info[0]);
2036 }
2037
JsWidth(const JSRef<JSVal> & jsValue)2038 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
2039 {
2040 CalcDimension value;
2041 if (jsValue->IsUndefined()) {
2042 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2043 return true;
2044 }
2045 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2046 if (!ParseJsDimensionVpNG(jsValue, value)) {
2047 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2048 return false;
2049 }
2050 } else if (!ParseJsDimensionVp(jsValue, value)) {
2051 return false;
2052 }
2053
2054 if (LessNotEqual(value.Value(), 0.0)) {
2055 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2056 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
2057 return true;
2058 } else {
2059 value.SetValue(0.0);
2060 }
2061 }
2062
2063 ViewAbstractModel::GetInstance()->SetWidth(value);
2064 return true;
2065 }
2066
JsHeight(const JSCallbackInfo & info)2067 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
2068 {
2069 JsHeight(info[0]);
2070 }
2071
JsHeight(const JSRef<JSVal> & jsValue)2072 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
2073 {
2074 CalcDimension value;
2075 if (jsValue->IsUndefined()) {
2076 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2077 return true;
2078 }
2079 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2080 if (!ParseJsDimensionVpNG(jsValue, value)) {
2081 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2082 return false;
2083 }
2084 } else if (!ParseJsDimensionVp(jsValue, value)) {
2085 return false;
2086 }
2087
2088 if (LessNotEqual(value.Value(), 0.0)) {
2089 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2090 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
2091 return true;
2092 } else {
2093 value.SetValue(0.0);
2094 }
2095 }
2096
2097 ViewAbstractModel::GetInstance()->SetHeight(value);
2098 return true;
2099 }
2100
JsResponseRegion(const JSCallbackInfo & info)2101 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
2102 {
2103 std::vector<DimensionRect> result;
2104 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2105 ViewAbstractModel::GetInstance()->SetResponseRegion({});
2106 return;
2107 }
2108
2109 ViewAbstractModel::GetInstance()->SetResponseRegion(result);
2110 }
2111
JsMouseResponseRegion(const JSCallbackInfo & info)2112 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
2113 {
2114 std::vector<DimensionRect> result;
2115 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
2116 ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
2117 return;
2118 }
2119 ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
2120 }
2121
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2122 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
2123 {
2124 result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
2125 result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
2126 if (!jsValue->IsObject()) {
2127 return true;
2128 }
2129
2130 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
2131 JSRef<JSVal> x = obj->GetProperty("x");
2132 JSRef<JSVal> y = obj->GetProperty("y");
2133 JSRef<JSVal> width = obj->GetProperty("width");
2134 JSRef<JSVal> height = obj->GetProperty("height");
2135 CalcDimension xDimen = result.GetOffset().GetX();
2136 CalcDimension yDimen = result.GetOffset().GetY();
2137 CalcDimension widthDimen = result.GetWidth();
2138 CalcDimension heightDimen = result.GetHeight();
2139 auto s1 = width->ToString();
2140 auto s2 = height->ToString();
2141 if (s1.find('-') != std::string::npos) {
2142 width = JSRef<JSVal>::Make(ToJSValue("100%"));
2143 }
2144 if (s2.find('-') != std::string::npos) {
2145 height = JSRef<JSVal>::Make(ToJSValue("100%"));
2146 }
2147 if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
2148 auto offset = result.GetOffset();
2149 offset.SetX(xDimen);
2150 result.SetOffset(offset);
2151 }
2152 if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
2153 auto offset = result.GetOffset();
2154 offset.SetY(yDimen);
2155 result.SetOffset(offset);
2156 }
2157 if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
2158 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
2159 return true;
2160 }
2161 result.SetWidth(widthDimen);
2162 }
2163 if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
2164 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
2165 return true;
2166 }
2167 result.SetHeight(heightDimen);
2168 }
2169 return true;
2170 }
2171
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2172 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
2173 {
2174 if (!jsValue->IsArray() && !jsValue->IsObject()) {
2175 return false;
2176 }
2177
2178 if (jsValue->IsArray()) {
2179 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
2180 for (size_t i = 0; i < array->Length(); i++) {
2181 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2182 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2183 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2184 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2185 DimensionOffset offsetDimen(xDimen, yDimen);
2186 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2187 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
2188 result.emplace_back(dimenRect);
2189 } else {
2190 return false;
2191 }
2192 }
2193 return true;
2194 }
2195
2196 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
2197 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
2198 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
2199 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
2200 DimensionOffset offsetDimen(xDimen, yDimen);
2201 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
2202 if (ParseJsDimensionRect(jsValue, dimenRect)) {
2203 result.emplace_back(dimenRect);
2204 return true;
2205 } else {
2206 return false;
2207 }
2208 }
2209
JsSize(const JSCallbackInfo & info)2210 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
2211 {
2212 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2213 auto jsVal = info[0];
2214 if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) {
2215 return;
2216 }
2217
2218 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2219 JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)));
2220 JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT)));
2221 }
2222
JsConstraintSize(const JSCallbackInfo & info)2223 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
2224 {
2225 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2226 auto jsVal = info[0];
2227 if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) {
2228 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2229 ViewAbstractModel::GetInstance()->ResetMinSize(true);
2230 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2231 ViewAbstractModel::GetInstance()->ResetMinSize(false);
2232 return;
2233 }
2234
2235 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
2236
2237 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
2238 CalcDimension minWidth;
2239 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
2240 CalcDimension maxWidth;
2241 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
2242 CalcDimension minHeight;
2243 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
2244 CalcDimension maxHeight;
2245 bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
2246 if (ParseJsDimensionVp(minWidthValue, minWidth)) {
2247 ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
2248 } else if (version10OrLarger) {
2249 ViewAbstractModel::GetInstance()->ResetMinSize(true);
2250 }
2251
2252 if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
2253 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
2254 } else if (version10OrLarger) {
2255 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
2256 }
2257
2258 if (ParseJsDimensionVp(minHeightValue, minHeight)) {
2259 ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
2260 } else if (version10OrLarger) {
2261 ViewAbstractModel::GetInstance()->ResetMinSize(false);
2262 }
2263
2264 if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
2265 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
2266 } else if (version10OrLarger) {
2267 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
2268 }
2269 }
2270
JsLayoutPriority(const JSCallbackInfo & info)2271 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
2272 {
2273 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2274 auto jsVal = info[0];
2275 if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) {
2276 return;
2277 }
2278
2279 int32_t priority;
2280 if (jsVal->IsNumber()) {
2281 priority = jsVal->ToNumber<int32_t>();
2282 } else {
2283 priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString()));
2284 }
2285 ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
2286 }
2287
JsPixelRound(const JSCallbackInfo & info)2288 void JSViewAbstract::JsPixelRound(const JSCallbackInfo& info)
2289 {
2290 uint16_t value = 0;
2291 JSRef<JSVal> arg = info[0];
2292 if (!arg->IsObject()) {
2293 return;
2294 }
2295 JSRef<JSObject> object = JSRef<JSObject>::Cast(arg);
2296 JSRef<JSVal> jsStartValue = object->GetProperty("start");
2297 if (jsStartValue->IsNumber()) {
2298 int32_t startValue = jsStartValue->ToNumber<int32_t>();
2299 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(startValue)) {
2300 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_START);
2301 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(startValue)) {
2302 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_START);
2303 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(startValue)) {
2304 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_START);
2305 }
2306 }
2307 JSRef<JSVal> jsTopValue = object->GetProperty("top");
2308 if (jsTopValue->IsNumber()) {
2309 int32_t topValue = jsTopValue->ToNumber<int32_t>();
2310 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(topValue)) {
2311 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
2312 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(topValue)) {
2313 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
2314 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(topValue)) {
2315 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_TOP);
2316 }
2317 }
2318 JSRef<JSVal> jsEndValue = object->GetProperty("end");
2319 if (jsEndValue->IsNumber()) {
2320 int32_t endValue = jsEndValue->ToNumber<int32_t>();
2321 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(endValue)) {
2322 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_END);
2323 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(endValue)) {
2324 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_END);
2325 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(endValue)) {
2326 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_END);
2327 }
2328 }
2329 JSRef<JSVal> jsBottomValue = object->GetProperty("bottom");
2330 if (jsBottomValue->IsNumber()) {
2331 int32_t bottomValue = jsBottomValue->ToNumber<int32_t>();
2332 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2333 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
2334 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2335 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
2336 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
2337 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_BOTTOM);
2338 }
2339 }
2340 ViewAbstractModel::GetInstance()->SetPixelRound(value);
2341 }
2342
JsLayoutWeight(const JSCallbackInfo & info)2343 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
2344 {
2345 float value = 0.0f;
2346 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
2347 auto jsVal = info[0];
2348 if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) {
2349 if (!jsVal->IsUndefined()) {
2350 return;
2351 }
2352 }
2353
2354 if (jsVal->IsNumber()) {
2355 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2356 value = jsVal->ToNumber<float>();
2357 } else {
2358 value = jsVal->ToNumber<int32_t>();
2359 }
2360 } else {
2361 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2362 value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString()));
2363 } else {
2364 value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString()));
2365 }
2366 }
2367
2368 ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
2369 }
2370
JsChainWeight(const JSCallbackInfo & info)2371 void JSViewAbstract::JsChainWeight(const JSCallbackInfo& info)
2372 {
2373 NG::LayoutWeightPair layoutWeightPair(DEFAULT_LAYOUT_WEIGHT, DEFAULT_LAYOUT_WEIGHT);
2374 auto jsVal = info[0];
2375 if (jsVal->IsObject()) {
2376 JSRef<JSObject> val = JSRef<JSObject>::Cast(jsVal);
2377 auto weightX = val->GetProperty("horizontal");
2378 auto weightY = val->GetProperty("vertical");
2379 if (weightX->IsNumber()) {
2380 layoutWeightPair.first = weightX->ToNumber<float>();
2381 }
2382 if (weightY->IsNumber()) {
2383 layoutWeightPair.second = weightY->ToNumber<float>();
2384 }
2385 }
2386 ViewAbstractModel::GetInstance()->SetLayoutWeight(layoutWeightPair);
2387 }
2388
JsAlign(const JSCallbackInfo & info)2389 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
2390 {
2391 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2392 auto jsVal = info[0];
2393 if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) &&
2394 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2395 ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
2396 return;
2397 }
2398 auto value = jsVal->ToNumber<int32_t>();
2399 Alignment alignment = ParseAlignment(value);
2400 ViewAbstractModel::GetInstance()->SetAlign(alignment);
2401 }
2402
JsPosition(const JSCallbackInfo & info)2403 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
2404 {
2405 CalcDimension x;
2406 CalcDimension y;
2407 OHOS::Ace::EdgesParam edges;
2408
2409 auto jsArg = info[0];
2410 if (jsArg->IsObject()) {
2411 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2412 if (ParseLocationProps(jsObj, x, y)) {
2413 return ViewAbstractModel::GetInstance()->SetPosition(x, y);
2414 } else if (ParseLocalizedEdges(jsObj, edges)) {
2415 ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true);
2416 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2417 } else if (ParseLocationPropsEdges(jsObj, edges)) {
2418 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges);
2419 }
2420 }
2421 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2422 ViewAbstractModel::GetInstance()->ResetPosition();
2423 } else {
2424 ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
2425 }
2426 }
2427
JsMarkAnchor(const JSCallbackInfo & info)2428 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
2429 {
2430 CalcDimension x;
2431 CalcDimension y;
2432
2433 auto jsArg = info[0];
2434 if (jsArg->IsObject()) {
2435 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2436 if (ParseMarkAnchorPosition(jsObj, x, y)) {
2437 ViewAbstractModel::GetInstance()->SetLocalizedMarkAnchor(true);
2438 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2439 } else if (ParseLocationProps(jsObj, x, y)) {
2440 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
2441 }
2442 }
2443 ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
2444 }
2445
JsOffset(const JSCallbackInfo & info)2446 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
2447 {
2448 CalcDimension x;
2449 CalcDimension y;
2450 OHOS::Ace::EdgesParam edges;
2451 auto jsArg = info[0];
2452 if (jsArg->IsObject()) {
2453 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg);
2454 if (ParseLocalizedEdges(jsObj, edges)) {
2455 ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true);
2456 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2457 } else if (ParseLocationProps(jsObj, x, y)) {
2458 return ViewAbstractModel::GetInstance()->SetOffset(x, y);
2459 } else if (ParseLocationPropsEdges(jsObj, edges)) {
2460 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges);
2461 }
2462 }
2463
2464 ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
2465 }
2466
JsEnabled(const JSCallbackInfo & info)2467 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
2468 {
2469 auto arg = info[0];
2470 if (!arg->IsBoolean()) {
2471 ViewAbstractModel::GetInstance()->SetEnabled(true);
2472 } else {
2473 ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
2474 }
2475 }
2476
JsAspectRatio(const JSCallbackInfo & info)2477 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
2478 {
2479 double value = 0.0;
2480 auto jsAspectRatio = info[0];
2481 if (!ParseJsDouble(jsAspectRatio, value)) {
2482 // add version protection, undefined use default value
2483 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
2484 (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) {
2485 ViewAbstractModel::GetInstance()->ResetAspectRatio();
2486 return;
2487 } else {
2488 return;
2489 }
2490 }
2491
2492 // negative use default value.
2493 if (LessOrEqual(value, 0.0)) {
2494 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2495 ViewAbstractModel::GetInstance()->ResetAspectRatio();
2496 return;
2497 } else {
2498 value = 1.0;
2499 }
2500 }
2501
2502 ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
2503 }
2504
ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2505 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align,
2506 std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY)
2507 {
2508 if (info[0]->IsString()) {
2509 std::string text = info[0]->ToString();
2510 ViewAbstractModel::GetInstance()->SetOverlay(
2511 text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT);
2512 } else if (info[0]->IsObject()) {
2513 JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]);
2514 auto builder = overlayObject->GetProperty("builder");
2515 if (builder->IsFunction()) {
2516 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2517 CHECK_NULL_VOID(builderFunc);
2518 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2519 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
2520 node = targetNode]() {
2521 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2522 ACE_SCORING_EVENT("Overlay");
2523 PipelineContext::SetCallBackNode(node);
2524 func->Execute();
2525 };
2526 ViewAbstractModel::GetInstance()->SetOverlay(
2527 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER);
2528 return;
2529 }
2530
2531 JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_");
2532 if (!builderNode->IsObject()) {
2533 return;
2534 }
2535 auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
2536 JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
2537 if (nodePtr.IsEmpty()) {
2538 return;
2539 }
2540 const auto* vm = nodePtr->GetEcmaVM();
2541 auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
2542 auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
2543 CHECK_NULL_VOID(frameNode);
2544 RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode);
2545 ViewAbstractModel::GetInstance()->SetOverlay(
2546 "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT);
2547 }
2548 }
2549
JsOverlay(const JSCallbackInfo & info)2550 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
2551 {
2552 if (info.Length() > 0 && (info[0]->IsUndefined())) {
2553 ViewAbstractModel::GetInstance()->SetOverlay(
2554 "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET);
2555 return;
2556 }
2557
2558 if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
2559 return;
2560 }
2561 std::optional<Alignment> align;
2562 std::optional<CalcDimension> offsetX;
2563 std::optional<CalcDimension> offsetY;
2564
2565 if (info[1]->IsObject()) {
2566 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
2567 JSRef<JSVal> alignVal = optionObj->GetProperty("align");
2568 auto value = alignVal->ToNumber<int32_t>();
2569 Alignment alignment = ParseAlignment(value);
2570 align = alignment;
2571
2572 JSRef<JSVal> val = optionObj->GetProperty("offset");
2573 if (val->IsObject()) {
2574 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
2575 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2576 CalcDimension x;
2577 if (ParseJsDimensionVp(xVal, x)) {
2578 offsetX = x;
2579 }
2580 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2581 CalcDimension y;
2582 if (ParseJsDimensionVp(yVal, y)) {
2583 offsetY = y;
2584 }
2585 }
2586 }
2587
2588 ParseOverlayFirstParam(info, align, offsetX, offsetY);
2589 }
2590
ParseAlignment(int32_t align)2591 Alignment JSViewAbstract::ParseAlignment(int32_t align)
2592 {
2593 Alignment alignment = Alignment::CENTER;
2594 switch (align) {
2595 case 0:
2596 alignment = Alignment::TOP_LEFT;
2597 break;
2598 case 1:
2599 alignment = Alignment::TOP_CENTER;
2600 break;
2601 case 2:
2602 alignment = Alignment::TOP_RIGHT;
2603 break;
2604 case 3:
2605 alignment = Alignment::CENTER_LEFT;
2606 break;
2607 case 4:
2608 alignment = Alignment::CENTER;
2609 break;
2610 case 5:
2611 alignment = Alignment::CENTER_RIGHT;
2612 break;
2613 case 6:
2614 alignment = Alignment::BOTTOM_LEFT;
2615 break;
2616 case 7:
2617 alignment = Alignment::BOTTOM_CENTER;
2618 break;
2619 case 8:
2620 alignment = Alignment::BOTTOM_RIGHT;
2621 break;
2622 default:
2623 break;
2624 }
2625 return alignment;
2626 }
2627
SetVisibility(const JSCallbackInfo & info)2628 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2629 {
2630 int32_t visible = 0;
2631 JSRef<JSVal> arg = info[0];
2632 if (arg->IsNull() || arg->IsUndefined()) {
2633 // undefined value use default value.
2634 visible = 0;
2635 } else if (!arg->IsNumber()) {
2636 return;
2637 } else {
2638 visible = arg->ToNumber<int32_t>();
2639 }
2640
2641 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
2642 (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) {
2643 visible = 0;
2644 }
2645
2646 if (info.Length() > 1 && info[1]->IsFunction()) {
2647 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2648 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2649 auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2650 int32_t visible) {
2651 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2652 ACE_SCORING_EVENT("onVisibilityChange");
2653 PipelineContext::SetCallBackNode(node);
2654 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2655 func->ExecuteJS(1, &newJSVal);
2656 };
2657 ViewAbstractModel::GetInstance()->SetVisibility(
2658 static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2659 } else {
2660 ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2661 }
2662 }
2663
JsSetFreeze(const JSCallbackInfo & info)2664 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2665 {
2666 if (info[0]->IsBoolean()) {
2667 ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2668 }
2669 }
2670
JsFlexBasis(const JSCallbackInfo & info)2671 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2672 {
2673 CalcDimension value;
2674 if (!ParseJsDimensionVp(info[0], value)) {
2675 value.SetUnit(DimensionUnit::AUTO);
2676 }
2677 // flexbasis don't support percent case.
2678 if (value.Unit() == DimensionUnit::PERCENT) {
2679 value.SetUnit(DimensionUnit::AUTO);
2680 }
2681 ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2682 }
2683
JsFlexGrow(const JSCallbackInfo & info)2684 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2685 {
2686 double value = 0.0;
2687 if (!ParseJsDouble(info[0], value)) {
2688 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2689 // undefined use default value.
2690 value = 0.0;
2691 } else {
2692 return;
2693 }
2694 }
2695 // negative use default value.
2696 if (value < 0.0) {
2697 value = 0.0;
2698 }
2699 ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2700 }
2701
JsFlexShrink(const JSCallbackInfo & info)2702 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2703 {
2704 double value = 0.0;
2705 if (!ParseJsDouble(info[0], value)) {
2706 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2707 // undefined use default value.
2708 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2709 return;
2710 } else {
2711 return;
2712 }
2713 }
2714 // negative use default value.
2715 if (value < 0.0) {
2716 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2717 return;
2718 }
2719 ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2720 }
2721
JsDisplayPriority(const JSCallbackInfo & info)2722 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2723 {
2724 double value = 0.0;
2725 if (!ParseJsDouble(info[0], value)) {
2726 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2727 ViewAbstractModel::GetInstance()->SetDisplayIndex(0);
2728 }
2729 return;
2730 }
2731 ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2732 }
2733
JsSharedTransition(const JSCallbackInfo & info)2734 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2735 {
2736 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2737 auto jsVal = info[0];
2738 if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) {
2739 return;
2740 }
2741 // id
2742 auto id = jsVal->ToString();
2743 if (id.empty()) {
2744 return;
2745 }
2746 std::shared_ptr<SharedTransitionOption> sharedOption;
2747
2748 // options
2749 if (info.Length() > 1 && info[1]->IsObject()) {
2750 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2751 sharedOption = std::make_shared<SharedTransitionOption>();
2752 // default: duration: 1000
2753 sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2754 if (sharedOption->duration < 0) {
2755 sharedOption->duration = DEFAULT_DURATION;
2756 }
2757 // default: delay: 0
2758 sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2759 if (sharedOption->delay < 0) {
2760 sharedOption->delay = 0;
2761 }
2762 // default: LinearCurve
2763 RefPtr<Curve> curve;
2764 JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2765 if (curveArgs->IsString()) {
2766 curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2767 } else if (curveArgs->IsObject()) {
2768 JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2769 if (!curveString->IsString()) {
2770 return;
2771 }
2772 curve = CreateCurve(curveString->ToString(), false);
2773 }
2774 if (!curve) {
2775 curve = Curves::LINEAR;
2776 }
2777 sharedOption->curve = curve;
2778 // motionPath
2779 if (jsObj->HasProperty("motionPath")) {
2780 MotionPathOption motionPathOption;
2781 if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2782 sharedOption->motionPathOption = motionPathOption;
2783 }
2784 }
2785 // zIndex
2786 sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2787 // type
2788 int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2789 static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2790 sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2791 }
2792 ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2793 }
2794
JsGeometryTransition(const JSCallbackInfo & info)2795 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2796 {
2797 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2798 auto jsVal = info[0];
2799 if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) {
2800 return;
2801 }
2802 // id
2803 auto id = jsVal->ToString();
2804 // follow flag
2805 bool followWithOutTransition = false;
2806 // hierarchy flag
2807 bool doRegisterSharedTransition = true;
2808 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
2809 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2810 ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2811
2812 auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE);
2813 ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy);
2814 switch (transitionHierarchyStrategy) {
2815 case static_cast<int32_t>(TransitionHierarchyStrategy::NONE):
2816 doRegisterSharedTransition = false;
2817 break;
2818 case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE):
2819 doRegisterSharedTransition = true;
2820 break;
2821 default:
2822 break;
2823 }
2824 }
2825 ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition);
2826 }
2827
JsAlignSelf(const JSCallbackInfo & info)2828 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2829 {
2830 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2831 auto jsVal = info[0];
2832 if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) {
2833 ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2834 return;
2835 }
2836 auto alignVal = jsVal->ToNumber<int32_t>();
2837
2838 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2839 ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2840 }
2841 }
2842
JsBackgroundColor(const JSCallbackInfo & info)2843 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2844 {
2845 Color backgroundColor;
2846 if (!ParseJsColor(info[0], backgroundColor)) {
2847 backgroundColor = Color::TRANSPARENT;
2848 }
2849
2850 ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2851 }
2852
JsBackgroundImage(const JSCallbackInfo & info)2853 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2854 {
2855 int32_t resId = 0;
2856 std::string src;
2857 std::string bundle;
2858 std::string module;
2859 RefPtr<PixelMap> pixmap = nullptr;
2860 auto jsBackgroundImage = info[0];
2861 GetJsMediaBundleInfo(jsBackgroundImage, bundle, module);
2862 if (jsBackgroundImage->IsString()) {
2863 src = jsBackgroundImage->ToString();
2864 ViewAbstractModel::GetInstance()->SetBackgroundImage(
2865 ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2866 } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) {
2867 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2868 } else {
2869 #if defined(PIXEL_MAP_SUPPORTED)
2870 if (IsDrawable(jsBackgroundImage)) {
2871 pixmap = GetDrawablePixmap(jsBackgroundImage);
2872 } else {
2873 pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage);
2874 }
2875 #endif
2876 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2877 }
2878
2879 int32_t repeatIndex = 0;
2880 if (info.Length() == 2) {
2881 auto jsImageRepeat = info[1];
2882 if (jsImageRepeat->IsNumber()) {
2883 repeatIndex = jsImageRepeat->ToNumber<int32_t>();
2884 }
2885 }
2886 auto repeat = static_cast<ImageRepeat>(repeatIndex);
2887 ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2888 }
2889
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2890 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2891 {
2892 if (jsBlurOption->GetProperty("grayscale")->IsArray()) {
2893 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsBlurOption->GetProperty("grayscale"));
2894 auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2895 auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2896 std::vector<float> greyVec(2); // 2 number
2897 greyVec[0] = grey1;
2898 greyVec[1] = grey2;
2899 blurOption.grayscale = greyVec;
2900 }
2901 }
2902
ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)2903 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption)
2904 {
2905 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2906 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2907 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2908 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2909 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2910 }
2911 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2912 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2913 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2914 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2915 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2916 }
2917
2918 // policy
2919 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
2920 ParseJsInt32(jsOption->GetProperty("policy"), policy);
2921 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
2922 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
2923 styleOption.policy = static_cast<BlurStyleActivePolicy>(policy);
2924 }
2925
2926 // blurType
2927 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
2928 ParseJsInt32(jsOption->GetProperty("type"), blurType);
2929 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
2930 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
2931 styleOption.blurType = static_cast<BlurType>(blurType);
2932 }
2933
2934 // inactiveColor
2935 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor)) {
2936 styleOption.isValidColor = true;
2937 }
2938
2939 // scale
2940 if (jsOption->GetProperty("scale")->IsNumber()) {
2941 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2942 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2943 }
2944
2945 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2946 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2947 BlurOption blurOption;
2948 ParseBlurOption(jsBlurOption, blurOption);
2949 styleOption.blurOption = blurOption;
2950 }
2951 }
2952
JsBackgroundBlurStyle(const JSCallbackInfo & info)2953 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2954 {
2955 if (info.Length() == 0) {
2956 return;
2957 }
2958 BlurStyleOption styleOption;
2959 if (info[0]->IsNumber()) {
2960 auto blurStyle = info[0]->ToNumber<int32_t>();
2961 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2962 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2963 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2964 }
2965 }
2966 if (info.Length() > 1 && info[1]->IsObject()) {
2967 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2968 ParseBlurStyleOption(jsOption, styleOption);
2969 }
2970 ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption);
2971 }
2972
ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2973 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption)
2974 {
2975 double rate = 1.0f;
2976 if (jsOption->GetProperty("rate")->IsNumber()) {
2977 rate = jsOption->GetProperty("rate")->ToNumber<double>();
2978 }
2979 double lightUpDegree = 0.0f;
2980 if (jsOption->GetProperty("lightUpDegree")->IsNumber()) {
2981 lightUpDegree = jsOption->GetProperty("lightUpDegree")->ToNumber<double>();
2982 }
2983 double cubicCoeff = 0.0f;
2984 if (jsOption->GetProperty("cubicCoeff")->IsNumber()) {
2985 cubicCoeff = jsOption->GetProperty("cubicCoeff")->ToNumber<double>();
2986 }
2987 double quadCoeff = 0.0f;
2988 if (jsOption->GetProperty("quadCoeff")->IsNumber()) {
2989 quadCoeff = jsOption->GetProperty("quadCoeff")->ToNumber<double>();
2990 }
2991 double saturation = 1.0f;
2992 if (jsOption->GetProperty("saturation")->IsNumber()) {
2993 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2994 }
2995 std::vector<float> posRGB(3, 0.0);
2996 if (jsOption->GetProperty("posRGB")->IsArray()) {
2997 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("posRGB"));
2998 auto r = params->GetValueAt(0)->ToNumber<double>();
2999 auto g = params->GetValueAt(1)->ToNumber<double>();
3000 auto b = params->GetValueAt(2)->ToNumber<double>();
3001 posRGB[0] = r;
3002 posRGB[1] = g;
3003 posRGB[2] = b;
3004 }
3005 std::vector<float> negRGB(3, 0.0);
3006 if (jsOption->GetProperty("negRGB")->IsArray()) {
3007 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("negRGB"));
3008 auto r = params->GetValueAt(0)->ToNumber<double>();
3009 auto g = params->GetValueAt(1)->ToNumber<double>();
3010 auto b = params->GetValueAt(2)->ToNumber<double>();
3011 negRGB[0] = r;
3012 negRGB[1] = g;
3013 negRGB[2] = b;
3014 }
3015 double fraction = 1.0f;
3016 if (jsOption->GetProperty("fraction")->IsNumber()) {
3017 fraction = jsOption->GetProperty("fraction")->ToNumber<double>();
3018 fraction = std::clamp(fraction, 0.0, 1.0);
3019 }
3020 brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction };
3021 }
3022
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)3023 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
3024 {
3025 CalcDimension radius;
3026 if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
3027 radius.SetValue(0.0f);
3028 }
3029 effectOption.radius = radius;
3030
3031 double saturation = 1.0f;
3032 if (jsOption->GetProperty("saturation")->IsNumber()) {
3033 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
3034 saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
3035 }
3036 effectOption.saturation = saturation;
3037
3038 double brightness = 1.0f;
3039 if (jsOption->GetProperty("brightness")->IsNumber()) {
3040 brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
3041 brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
3042 }
3043 effectOption.brightness = brightness;
3044
3045 ParseJsColor(jsOption->GetProperty("color"), effectOption.color);
3046
3047 auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3048 auto adaptiveColor = AdaptiveColor::DEFAULT;
3049 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
3050 if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3051 adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3052 adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
3053 }
3054 effectOption.adaptiveColor = adaptiveColor;
3055
3056 // policy
3057 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE);
3058 ParseJsInt32(jsOption->GetProperty("policy"), policy);
3059 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) &&
3060 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) {
3061 effectOption.policy = static_cast<BlurStyleActivePolicy>(policy);
3062 }
3063
3064 // blurType
3065 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW);
3066 ParseJsInt32(jsOption->GetProperty("type"), blurType);
3067 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) &&
3068 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) {
3069 effectOption.blurType = static_cast<BlurType>(blurType);
3070 }
3071
3072 // inactiveColor
3073 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) {
3074 effectOption.isValidColor = true;
3075 }
3076
3077 BlurOption blurOption;
3078 if (jsOption->GetProperty("blurOptions")->IsObject()) {
3079 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3080 ParseBlurOption(jsBlurOption, blurOption);
3081 effectOption.blurOption = blurOption;
3082 }
3083 }
3084
JsForegroundEffect(const JSCallbackInfo & info)3085 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info)
3086 {
3087 if (info.Length() == 0) {
3088 return;
3089 }
3090 float radius = 0.0;
3091 if (info[0]->IsObject()) {
3092 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3093 if (jsOption->GetProperty("radius")->IsNumber()) {
3094 radius = jsOption->GetProperty("radius")->ToNumber<float>();
3095 }
3096 }
3097 radius = std::max(radius, 0.0f);
3098 ViewAbstractModel::GetInstance()->SetForegroundEffect(radius);
3099 }
3100
JsBackgroundEffect(const JSCallbackInfo & info)3101 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
3102 {
3103 if (info.Length() == 0) {
3104 return;
3105 }
3106 EffectOption option;
3107 if (info[0]->IsObject()) {
3108 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
3109 ParseEffectOption(jsOption, option);
3110 }
3111 ViewAbstractModel::GetInstance()->SetBackgroundEffect(option);
3112 }
3113
JsForegroundBlurStyle(const JSCallbackInfo & info)3114 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
3115 {
3116 if (info.Length() == 0) {
3117 return;
3118 }
3119 BlurStyleOption styleOption;
3120 if (info[0]->IsNumber()) {
3121 auto blurStyle = info[0]->ToNumber<int32_t>();
3122 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3123 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3124 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
3125 }
3126 }
3127 if (info.Length() > 1 && info[1]->IsObject()) {
3128 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
3129 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
3130 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
3131 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
3132 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
3133 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
3134 }
3135 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
3136 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
3137 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
3138 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
3139 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
3140 }
3141 if (jsOption->GetProperty("scale")->IsNumber()) {
3142 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
3143 styleOption.scale = std::clamp(scale, 0.0, 1.0);
3144 }
3145
3146 if (jsOption->GetProperty("blurOptions")->IsObject()) {
3147 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
3148 BlurOption blurOption;
3149 ParseBlurOption(jsBlurOption, blurOption);
3150 styleOption.blurOption = blurOption;
3151 }
3152 }
3153 ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption);
3154 }
3155
JsSphericalEffect(const JSCallbackInfo & info)3156 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
3157 {
3158 auto radio = 0.0;
3159 if (info[0]->IsNumber()) {
3160 radio = info[0]->ToNumber<double>();
3161 }
3162 ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
3163 }
3164
JsPixelStretchEffect(const JSCallbackInfo & info)3165 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
3166 {
3167 if (!info[0]->IsObject()) {
3168 PixStretchEffectOption option;
3169 option.ResetValue();
3170 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3171 return;
3172 }
3173 auto jsObject = JSRef<JSObject>::Cast(info[0]);
3174 CalcDimension left;
3175 ParseJsDimensionVp(jsObject->GetProperty("left"), left);
3176 CalcDimension right;
3177 ParseJsDimensionVp(jsObject->GetProperty("right"), right);
3178 CalcDimension top;
3179 ParseJsDimensionVp(jsObject->GetProperty("top"), top);
3180 CalcDimension bottom;
3181 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
3182
3183 PixStretchEffectOption option;
3184 bool illegalInput = false;
3185 if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
3186 top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
3187 if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
3188 (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
3189 (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
3190 (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
3191 left.SetUnit(DimensionUnit::PERCENT);
3192 top.SetUnit(DimensionUnit::PERCENT);
3193 right.SetUnit(DimensionUnit::PERCENT);
3194 bottom.SetUnit(DimensionUnit::PERCENT);
3195 } else {
3196 illegalInput = true;
3197 }
3198 }
3199 if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
3200 (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
3201 option.left = left;
3202 option.top = top;
3203 option.right = right;
3204 option.bottom = bottom;
3205 } else {
3206 illegalInput = true;
3207 }
3208 if (illegalInput) {
3209 option.ResetValue();
3210 }
3211 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
3212 }
3213
JsLightUpEffect(const JSCallbackInfo & info)3214 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
3215 {
3216 auto radio = 1.0;
3217 if (info[0]->IsNumber()) {
3218 radio = info[0]->ToNumber<double>();
3219 }
3220 ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
3221 }
3222
JsBackgroundImageSize(const JSCallbackInfo & info)3223 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
3224 {
3225 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3226 BackgroundImageSize bgImgSize;
3227 auto jsVal = info[0];
3228 if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) {
3229 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
3230 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
3231 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3232 return;
3233 }
3234 if (jsVal->IsNumber()) {
3235 auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>());
3236 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) &&
3237 (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) {
3238 sizeType = BackgroundImageSizeType::AUTO;
3239 }
3240 bgImgSize.SetSizeTypeX(sizeType);
3241 bgImgSize.SetSizeTypeY(sizeType);
3242 } else {
3243 CalcDimension width;
3244 CalcDimension height;
3245 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3246 ParseJsDimensionVp(object->GetProperty("width"), width);
3247 ParseJsDimensionVp(object->GetProperty("height"), height);
3248 double valueWidth = width.ConvertToPx();
3249 double valueHeight = height.ConvertToPx();
3250 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
3251 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
3252 if (width.Unit() == DimensionUnit::PERCENT) {
3253 typeWidth = BackgroundImageSizeType::PERCENT;
3254 valueWidth = width.Value() * FULL_DIMENSION;
3255 }
3256 if (height.Unit() == DimensionUnit::PERCENT) {
3257 typeHeight = BackgroundImageSizeType::PERCENT;
3258 valueHeight = height.Value() * FULL_DIMENSION;
3259 }
3260 bgImgSize.SetSizeTypeX(typeWidth);
3261 bgImgSize.SetSizeValueX(valueWidth);
3262 bgImgSize.SetSizeTypeY(typeHeight);
3263 bgImgSize.SetSizeValueY(valueHeight);
3264 }
3265
3266 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
3267 }
3268
SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3269 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align)
3270 {
3271 if (align > 8 || align < 0) {
3272 return;
3273 }
3274 std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 },
3275 { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION },
3276 { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } };
3277 SetBgImgPosition(
3278 DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition);
3279 }
3280
JsBackgroundImagePosition(const JSCallbackInfo & info)3281 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
3282 {
3283 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
3284 BackgroundImagePosition bgImgPosition;
3285 auto jsVal = info[0];
3286 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) {
3287 SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
3288 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3289 return;
3290 }
3291 if (jsVal->IsNumber()) {
3292 int32_t align = jsVal->ToNumber<int32_t>();
3293 bgImgPosition.SetIsAlign(true);
3294 SetBgImgPositionWithAlign(bgImgPosition, align);
3295 } else {
3296 CalcDimension x;
3297 CalcDimension y;
3298 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3299 ParseJsDimensionVp(object->GetProperty("x"), x);
3300 ParseJsDimensionVp(object->GetProperty("y"), y);
3301 double valueX = x.Value();
3302 double valueY = y.Value();
3303 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3304 valueX = x.ConvertToPx();
3305 valueY = y.ConvertToPx();
3306 }
3307 DimensionUnit typeX = DimensionUnit::PX;
3308 DimensionUnit typeY = DimensionUnit::PX;
3309 if (x.Unit() == DimensionUnit::PERCENT) {
3310 valueX = x.Value();
3311 typeX = DimensionUnit::PERCENT;
3312 }
3313 if (y.Unit() == DimensionUnit::PERCENT) {
3314 valueY = y.Value();
3315 typeY = DimensionUnit::PERCENT;
3316 }
3317 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
3318 }
3319
3320 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
3321 }
3322
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)3323 std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
3324 {
3325 JSRef<JSVal> arg = info[optionIndex];
3326 if (!arg->IsArray()) {
3327 return std::vector<NG::OptionParam>();
3328 }
3329 auto paramArray = JSRef<JSArray>::Cast(arg);
3330 auto paramArrayLength = paramArray->Length();
3331 std::vector<NG::OptionParam> params(paramArrayLength);
3332 // parse paramArray
3333 for (size_t i = 0; i < paramArrayLength; ++i) {
3334 if (!paramArray->GetValueAt(i)->IsObject()) {
3335 return std::vector<NG::OptionParam>();
3336 }
3337 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
3338 JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
3339 params[i].value);
3340 auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
3341 if (!actionFunc->IsFunction()) {
3342 return params;
3343 }
3344 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
3345 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3346 // set onClick function
3347 params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
3348 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
3349 ACE_SCORING_EVENT("menu.action");
3350 PipelineContext::SetCallBackNode(node);
3351 if (func) {
3352 func->Execute();
3353 }
3354 };
3355 std::string iconPath;
3356 if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
3357 params[i].icon = iconPath;
3358 }
3359 if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
3360 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
3361 JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
3362 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
3363 params[i].symbol = symbolApply;
3364 }
3365 auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
3366 if (enabled->IsBoolean()) {
3367 params[i].enabled = enabled->ToBoolean();
3368 }
3369 }
3370 return params;
3371 }
3372
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3373 void ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3374 {
3375 auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
3376 NG::BorderRadiusProperty menuBorderRadius;
3377 CalcDimension borderRadius;
3378 if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) {
3379 if (borderRadius.Unit() != DimensionUnit::PERCENT && GreatOrEqual(borderRadius.Value(), 0.0f)) {
3380 menuBorderRadius.SetRadius(borderRadius);
3381 menuBorderRadius.multiValued = false;
3382 menuParam.borderRadius = menuBorderRadius;
3383 };
3384 } else if (borderRadiusValue->IsObject()) {
3385 JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
3386 CalcDimension topLeft;
3387 CalcDimension topRight;
3388 CalcDimension bottomLeft;
3389 CalcDimension bottomRight;
3390 bool hasSetBorderRadius =
3391 JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
3392 if (LessNotEqual(topLeft.Value(), 0.0f)) {
3393 topLeft.Reset();
3394 }
3395 if (LessNotEqual(topRight.Value(), 0.0f)) {
3396 topRight.Reset();
3397 }
3398 if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
3399 bottomLeft.Reset();
3400 }
3401 if (LessNotEqual(bottomRight.Value(), 0.0f)) {
3402 bottomRight.Reset();
3403 }
3404 auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
3405 menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
3406 menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight;
3407 menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
3408 menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
3409 menuBorderRadius.multiValued = true;
3410 menuParam.borderRadius = menuBorderRadius;
3411 }
3412 }
3413
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3414 void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3415 {
3416 auto enableArrowValue = menuOptions->GetProperty("enableArrow");
3417 if (enableArrowValue->IsBoolean()) {
3418 menuParam.enableArrow = enableArrowValue->ToBoolean();
3419 }
3420
3421 auto arrowOffset = menuOptions->GetProperty("arrowOffset");
3422 CalcDimension offset;
3423 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
3424 menuParam.arrowOffset = offset;
3425 }
3426
3427 // if enableArrow is true and placement not set, set placement default value to top.
3428 if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
3429 menuParam.placement = Placement::TOP;
3430 }
3431 }
3432
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)3433 void ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
3434 {
3435 CalcDimension dimension;
3436 if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
3437 return;
3438 }
3439
3440 if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
3441 calcDimension = dimension;
3442 }
3443 }
3444
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3445 void ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3446 {
3447 auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
3448 if (!marginVal->IsObject()) {
3449 return;
3450 }
3451
3452 CommonCalcDimension commonCalcDimension;
3453 auto object = JSRef<JSObject>::Cast(marginVal);
3454 ParseLayoutRegionMargin(object->GetProperty(TOP_PROPERTY), commonCalcDimension.top);
3455 ParseLayoutRegionMargin(object->GetProperty(BOTTOM_PROPERTY), commonCalcDimension.bottom);
3456 ParseLayoutRegionMargin(object->GetProperty(LEFT_PROPERTY), commonCalcDimension.left);
3457 ParseLayoutRegionMargin(object->GetProperty(RIGHT_PROPERTY), commonCalcDimension.right);
3458
3459 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3460 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3461 menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
3462 commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3463 }
3464 }
3465
GetMenuShowInSubwindow(NG::MenuParam & menuParam)3466 void GetMenuShowInSubwindow(NG::MenuParam& menuParam)
3467 {
3468 menuParam.isShowInSubWindow = false;
3469 auto pipeline = PipelineBase::GetCurrentContext();
3470 CHECK_NULL_VOID(pipeline);
3471 auto theme = pipeline->GetTheme<SelectTheme>();
3472 CHECK_NULL_VOID(theme);
3473 menuParam.isShowInSubWindow = theme->GetExpandDisplay();
3474 }
3475
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3476 void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
3477 {
3478 auto offsetVal = menuOptions->GetProperty("offset");
3479 if (offsetVal->IsObject()) {
3480 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
3481 JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
3482 JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
3483 CalcDimension dx;
3484 CalcDimension dy;
3485 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
3486 menuParam.positionOffset.SetX(dx.ConvertToPx());
3487 }
3488 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
3489 menuParam.positionOffset.SetY(dy.ConvertToPx());
3490 }
3491 }
3492
3493 auto placementValue = menuOptions->GetProperty("placement");
3494 if (placementValue->IsNumber()) {
3495 auto placement = placementValue->ToNumber<int32_t>();
3496 if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
3497 menuParam.placement = PLACEMENT[placement];
3498 }
3499 }
3500
3501 auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
3502 Color backgroundColor;
3503 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
3504 menuParam.backgroundColor = backgroundColor;
3505 }
3506
3507 auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
3508 if (backgroundBlurStyle->IsNumber()) {
3509 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
3510 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
3511 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
3512 menuParam.backgroundBlurStyle = blurStyle;
3513 }
3514 }
3515 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3516 auto onAppearValue = menuOptions->GetProperty("onAppear");
3517 if (onAppearValue->IsFunction()) {
3518 RefPtr<JsFunction> jsOnAppearFunc =
3519 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
3520 auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
3521 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3522 ACE_SCORING_EVENT("onAppear");
3523 PipelineContext::SetCallBackNode(node);
3524 func->Execute();
3525 };
3526 menuParam.onAppear = std::move(onAppear);
3527 }
3528
3529 auto onDisappearValue = menuOptions->GetProperty("onDisappear");
3530 if (onDisappearValue->IsFunction()) {
3531 RefPtr<JsFunction> jsOnDisAppearFunc =
3532 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
3533 auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
3534 node = frameNode]() {
3535 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3536 ACE_SCORING_EVENT("onDisappear");
3537 PipelineContext::SetCallBackNode(node);
3538 func->Execute();
3539 };
3540 menuParam.onDisappear = std::move(onDisappear);
3541 }
3542 auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
3543 if (aboutToAppearValue->IsFunction()) {
3544 RefPtr<JsFunction> jsAboutToAppearFunc =
3545 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
3546 auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
3547 node = frameNode]() {
3548 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3549 ACE_SCORING_EVENT("aboutToAppear");
3550 PipelineContext::SetCallBackNode(node);
3551 func->Execute();
3552 };
3553 menuParam.aboutToAppear = std::move(aboutToAppear);
3554 }
3555
3556 auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
3557 if (aboutToDisAppearValue->IsFunction()) {
3558 RefPtr<JsFunction> jsAboutToDisAppearFunc =
3559 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
3560 auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
3561 node = frameNode]() {
3562 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3563 ACE_SCORING_EVENT("aboutToDisappear");
3564 PipelineContext::SetCallBackNode(node);
3565 func->Execute();
3566 };
3567 menuParam.aboutToDisappear = std::move(aboutToDisappear);
3568 }
3569
3570 auto menuTransition = menuOptions->GetProperty("transition");
3571 menuParam.hasTransitionEffect = false;
3572 if (menuTransition->IsObject()) {
3573 auto obj = JSRef<JSObject>::Cast(menuTransition);
3574 menuParam.hasTransitionEffect = true;
3575 menuParam.transition = ParseChainedTransition(obj, info.GetExecutionContext());
3576 }
3577
3578 JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
3579 GetMenuShowInSubwindow(menuParam);
3580 if (menuParam.isShowInSubWindow) {
3581 if (showInSubWindowValue->IsBoolean()) {
3582 menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
3583 }
3584 }
3585 ParseMenuArrowParam(menuOptions, menuParam);
3586 ParseMenuBorderRadius(menuOptions, menuParam);
3587 ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
3588 }
3589
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)3590 void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
3591 {
3592 if (!info[optionIndex]->IsObject()) {
3593 return;
3594 }
3595 auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
3596 JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
3597 ParseMenuParam(info, menuOptions, menuParam);
3598 }
3599
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)3600 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
3601 {
3602 constexpr int scaleArraySize = 2;
3603 if (scaleArray->Length() == scaleArraySize) {
3604 auto scalePropertyFrom = scaleArray->GetValueAt(0);
3605 if (scalePropertyFrom->IsNumber()) {
3606 auto scaleFrom = scalePropertyFrom->ToNumber<float>();
3607 options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
3608 }
3609 auto scalePropertyTo = scaleArray->GetValueAt(1);
3610 if (scalePropertyTo->IsNumber()) {
3611 auto scaleTo = scalePropertyTo->ToNumber<float>();
3612 options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
3613 }
3614 }
3615 }
3616
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)3617 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
3618 NG::MenuParam& menuParam)
3619 {
3620 menuParam.previewAnimationOptions.scaleFrom = -1.0f;
3621 menuParam.previewAnimationOptions.scaleTo = -1.0f;
3622
3623 auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
3624 if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
3625 auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
3626 auto scaleProperty = animationOptionsObj->GetProperty("scale");
3627 if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
3628 JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
3629 ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
3630 }
3631 auto previewTransition = animationOptionsObj->GetProperty("transition");
3632 menuParam.hasPreviewTransitionEffect = false;
3633 if (previewTransition->IsObject()) {
3634 auto obj = JSRef<JSObject>::Cast(previewTransition);
3635 menuParam.hasPreviewTransitionEffect = true;
3636 menuParam.previewTransition = ParseChainedTransition(obj, info.GetExecutionContext());
3637 }
3638 if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
3639 menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect ||
3640 menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
3641 return;
3642 }
3643 auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
3644 menuParam.isShowHoverImage = false;
3645 menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
3646 menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
3647 if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
3648 JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
3649 ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
3650 menuParam.isShowHoverImage = true;
3651 }
3652 }
3653 }
3654
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)3655 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
3656 std::function<void()>& previewBuildFunc)
3657 {
3658 if (!args->IsObject()) {
3659 return;
3660 }
3661 auto menuContentOptions = JSRef<JSObject>::Cast(args);
3662 ParseMenuParam(info, menuContentOptions, menuParam);
3663 RefPtr<JsFunction> previewBuilderFunc;
3664 auto preview = menuContentOptions->GetProperty("preview");
3665 if (!preview->IsFunction() && !preview->IsNumber()) {
3666 return;
3667 }
3668
3669 if (preview->IsNumber()) {
3670 if (preview->ToNumber<int32_t>() == 1) {
3671 menuParam.previewMode = MenuPreviewMode::IMAGE;
3672 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3673 }
3674 } else {
3675 previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
3676 CHECK_NULL_VOID(previewBuilderFunc);
3677 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3678 previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
3679 node = frameNode]() {
3680 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3681 ACE_SCORING_EVENT("BuildContextMenuPreviwer");
3682 PipelineContext::SetCallBackNode(node);
3683 func->Execute();
3684 };
3685 menuParam.previewMode = MenuPreviewMode::CUSTOM;
3686 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
3687 }
3688 }
3689
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)3690 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
3691 {
3692 size_t builderIndex = 0;
3693 if (info[0]->IsBoolean()) {
3694 menuParam.isShow = info[0]->ToBoolean();
3695 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3696 menuParam.placement = Placement::BOTTOM_LEFT;
3697 builderIndex = 1;
3698 } else if (info[0]->IsObject()) {
3699 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
3700 menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3701 auto isShowObj = callbackObj->GetProperty("value");
3702 if (isShowObj->IsBoolean()) {
3703 menuParam.isShow = isShowObj->IsBoolean();
3704 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
3705 builderIndex = 1;
3706 }
3707 }
3708 return builderIndex;
3709 }
3710
JsBindMenu(const JSCallbackInfo & info)3711 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
3712 {
3713 NG::MenuParam menuParam;
3714 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
3715 menuParam.placement = Placement::BOTTOM_LEFT;
3716 }
3717 size_t builderIndex = 0;
3718 GetMenuShowInSubwindow(menuParam);
3719 if (info.Length() > PARAMETER_LENGTH_FIRST) {
3720 auto jsVal = info[0];
3721 if (jsVal->IsBoolean()) {
3722 menuParam.isShow = jsVal->ToBoolean();
3723 menuParam.setShow = true;
3724 builderIndex = 1;
3725 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3726 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3727 }
3728 } else if (jsVal->IsUndefined()) {
3729 menuParam.setShow = true;
3730 menuParam.isShow = false;
3731 builderIndex = 1;
3732 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3733 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3734 }
3735 } else if (jsVal->IsObject()) {
3736 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
3737 menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
3738 auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
3739 if (isShowObj->IsBoolean()) {
3740 menuParam.isShow = isShowObj->ToBoolean();
3741 menuParam.setShow = true;
3742 builderIndex = 1;
3743 if (info.Length() > PARAMETER_LENGTH_SECOND) {
3744 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3745 }
3746 } else {
3747 builderIndex = 0;
3748 ParseBindOptionParam(info, menuParam, builderIndex + 1);
3749 }
3750 }
3751 }
3752
3753 if (info[builderIndex]->IsArray()) {
3754 std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info, builderIndex);
3755 ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
3756 } else if (info[builderIndex]->IsObject()) {
3757 // CustomBuilder
3758 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
3759 auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
3760 if (!builder->IsFunction()) {
3761 return;
3762 }
3763 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
3764
3765 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3766 CHECK_NULL_VOID(builderFunc);
3767 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
3768 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
3769 ACE_SCORING_EVENT("BuildMenu");
3770 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
3771 func->Execute();
3772 };
3773 ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
3774 }
3775 }
3776
JsPadding(const JSCallbackInfo & info)3777 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
3778 {
3779 ParseMarginOrPadding(info, EdgeType::PADDING);
3780 }
3781
JsMargin(const JSCallbackInfo & info)3782 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
3783 {
3784 ParseMarginOrPadding(info, EdgeType::MARGIN);
3785 }
3786
ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)3787 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type)
3788 {
3789 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
3790 JSCallbackInfoType::NUMBER };
3791 auto jsVal = info[0];
3792 if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) {
3793 auto resetDimension = CalcDimension(0.0);
3794 if (type == EdgeType::MARGIN) {
3795 ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
3796 } else if (type == EdgeType::PADDING) {
3797 ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
3798 } else if (type == EdgeType::SAFE_AREA_PADDING) {
3799 ViewAbstractModel::GetInstance()->ResetSafeAreaPadding();
3800 }
3801 return;
3802 }
3803
3804 if (jsVal->IsObject()) {
3805 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
3806
3807 CalcDimension length;
3808 if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) {
3809 ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length);
3810 return;
3811 }
3812
3813 CommonCalcDimension commonCalcDimension;
3814 auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
3815 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
3816 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
3817 if (type == EdgeType::MARGIN) {
3818 if (useLengthMetrics) {
3819 ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top,
3820 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3821 } else {
3822 ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom,
3823 commonCalcDimension.left, commonCalcDimension.right);
3824 }
3825 } else if (type == EdgeType::PADDING) {
3826 if (useLengthMetrics) {
3827 ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top,
3828 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3829 } else {
3830 ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom,
3831 commonCalcDimension.left, commonCalcDimension.right);
3832 }
3833 } else if (type == EdgeType::SAFE_AREA_PADDING) {
3834 if (useLengthMetrics) {
3835 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top,
3836 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right));
3837 } else {
3838 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top,
3839 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
3840 }
3841 }
3842 return;
3843 }
3844 }
3845
3846 CalcDimension length;
3847 if (!ParseJsDimensionVp(jsVal, length)) {
3848 // use default value.
3849 length.Reset();
3850 }
3851 if (type == EdgeType::MARGIN) {
3852 ViewAbstractModel::GetInstance()->SetMargin(length);
3853 } else if (type == EdgeType::PADDING) {
3854 ViewAbstractModel::GetInstance()->SetPadding(length);
3855 }
3856 }
3857
GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)3858 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top,
3859 const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start,
3860 const std::optional<CalcDimension>& end)
3861 {
3862 NG::PaddingProperty paddings;
3863 if (start.has_value()) {
3864 if (start.value().Unit() == DimensionUnit::CALC) {
3865 paddings.start = NG::CalcLength(start.value().CalcValue());
3866 } else {
3867 paddings.start = NG::CalcLength(start.value());
3868 }
3869 }
3870 if (bottom.has_value()) {
3871 if (bottom.value().Unit() == DimensionUnit::CALC) {
3872 paddings.bottom = NG::CalcLength(bottom.value().CalcValue());
3873 } else {
3874 paddings.bottom = NG::CalcLength(bottom.value());
3875 }
3876 }
3877 if (end.has_value()) {
3878 if (end.value().Unit() == DimensionUnit::CALC) {
3879 paddings.end = NG::CalcLength(end.value().CalcValue());
3880 } else {
3881 paddings.end = NG::CalcLength(end.value());
3882 }
3883 }
3884 if (top.has_value()) {
3885 if (top.value().Unit() == DimensionUnit::CALC) {
3886 paddings.top = NG::CalcLength(top.value().CalcValue());
3887 } else {
3888 paddings.top = NG::CalcLength(top.value());
3889 }
3890 }
3891 return paddings;
3892 }
3893
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)3894 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
3895 std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
3896 {
3897 CalcDimension leftDimen;
3898 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) {
3899 left = leftDimen;
3900 }
3901 CalcDimension rightDimen;
3902 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) {
3903 right = rightDimen;
3904 }
3905 CalcDimension topDimen;
3906 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) {
3907 top = topDimen;
3908 }
3909 CalcDimension bottomDimen;
3910 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) {
3911 bottom = bottomDimen;
3912 }
3913 }
3914
ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3915 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner(
3916 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
3917 {
3918 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START));
3919 if (jsStart->IsObject()) {
3920 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart);
3921 CalcDimension calcDimension;
3922 if (ParseJsLengthMetrics(startObj, calcDimension)) {
3923 localizedCalcDimension.start = calcDimension;
3924 }
3925 }
3926 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END));
3927 if (jsEnd->IsObject()) {
3928 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd);
3929 CalcDimension calcDimension;
3930 if (ParseJsLengthMetrics(endObj, calcDimension)) {
3931 localizedCalcDimension.end = calcDimension;
3932 }
3933 }
3934 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
3935 if (jsTop->IsObject()) {
3936 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop);
3937 CalcDimension calcDimension;
3938 if (ParseJsLengthMetrics(topObj, calcDimension)) {
3939 localizedCalcDimension.top = calcDimension;
3940 }
3941 }
3942 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
3943 if (jsBottom->IsObject()) {
3944 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom);
3945 CalcDimension calcDimension;
3946 if (ParseJsLengthMetrics(bottomObj, calcDimension)) {
3947 localizedCalcDimension.bottom = calcDimension;
3948 }
3949 }
3950 }
3951
ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3952 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner(
3953 const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension)
3954 {
3955 if (CheckLengthMetrics(object)) {
3956 LocalizedCalcDimension localizedCalcDimension;
3957 ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension);
3958 commonCalcDimension.top = localizedCalcDimension.top;
3959 commonCalcDimension.bottom = localizedCalcDimension.bottom;
3960 commonCalcDimension.left = localizedCalcDimension.start;
3961 commonCalcDimension.right = localizedCalcDimension.end;
3962 return true;
3963 }
3964 ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
3965 commonCalcDimension.right);
3966 return false;
3967 }
3968
JsOutline(const JSCallbackInfo & info)3969 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
3970 {
3971 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3972 auto jsVal = info[0];
3973 if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) {
3974 CalcDimension borderWidth;
3975 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3976 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3977 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
3978 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3979 return;
3980 }
3981 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
3982 auto valueOuterWidth = object->GetProperty("width");
3983 if (!valueOuterWidth->IsUndefined()) {
3984 ParseOuterBorderWidth(valueOuterWidth);
3985 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3986 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
3987 }
3988
3989 // use default value when undefined.
3990 ParseOuterBorderColor(object->GetProperty("color"));
3991
3992 auto valueOuterRadius = object->GetProperty("radius");
3993 if (!valueOuterRadius->IsUndefined()) {
3994 ParseOuterBorderRadius(valueOuterRadius);
3995 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
3996 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
3997 }
3998 // use default value when undefined.
3999 ParseOuterBorderStyle(object->GetProperty("style"));
4000 info.ReturnSelf();
4001 }
4002
JsOutlineWidth(const JSCallbackInfo & info)4003 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
4004 {
4005 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4006 JSCallbackInfoType::OBJECT };
4007 auto jsVal = info[0];
4008 if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) {
4009 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
4010 return;
4011 }
4012 ParseOuterBorderWidth(jsVal);
4013 }
4014
JsOutlineColor(const JSCallbackInfo & info)4015 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
4016 {
4017 ParseOuterBorderColor(info[0]);
4018 }
4019
JsOutlineRadius(const JSCallbackInfo & info)4020 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
4021 {
4022 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4023 JSCallbackInfoType::OBJECT };
4024 auto jsVal = info[0];
4025 if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) {
4026 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {});
4027 return;
4028 }
4029 ParseOuterBorderRadius(jsVal);
4030 }
4031
JsOutlineStyle(const JSCallbackInfo & info)4032 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
4033 {
4034 ParseOuterBorderStyle(info[0]);
4035 }
4036
JsBorder(const JSCallbackInfo & info)4037 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
4038 {
4039 if (!info[0]->IsObject()) {
4040 CalcDimension borderWidth;
4041 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4042 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4043 ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
4044 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4045 ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1));
4046 ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1));
4047 return;
4048 }
4049 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
4050
4051 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4052 if (!valueWidth->IsUndefined()) {
4053 ParseBorderWidth(valueWidth);
4054 }
4055
4056 // use default value when undefined.
4057 ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)));
4058
4059 auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
4060 if (!valueRadius->IsUndefined()) {
4061 ParseBorderRadius(valueRadius);
4062 }
4063 // use default value when undefined.
4064 ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)));
4065
4066 auto dashGap = object->GetProperty("dashGap");
4067 if (!dashGap->IsUndefined()) {
4068 ParseDashGap(dashGap);
4069 }
4070 auto dashWidth = object->GetProperty("dashWidth");
4071 if (!dashWidth->IsUndefined()) {
4072 ParseDashWidth(dashWidth);
4073 }
4074
4075 info.ReturnSelf();
4076 }
4077
IsBorderWidthObjUndefined(const JSRef<JSVal> & args)4078 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args)
4079 {
4080 if (!args->IsObject()) {
4081 return false;
4082 }
4083 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4084 if (obj->IsUndefined()) {
4085 return true;
4086 }
4087 // filter dynamic $r raw input
4088 if (obj->HasProperty("id")) {
4089 return false;
4090 }
4091 if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) &&
4092 (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) &&
4093 (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) &&
4094 (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) &&
4095 (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) &&
4096 (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) {
4097 return true;
4098 }
4099
4100 return false;
4101 }
4102
JsBorderWidth(const JSCallbackInfo & info)4103 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
4104 {
4105 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4106 JSCallbackInfoType::OBJECT };
4107 auto jsVal = info[0];
4108 if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) {
4109 ViewAbstractModel::GetInstance()->SetBorderWidth({});
4110 return;
4111 }
4112 ParseBorderWidth(jsVal);
4113 }
4114
ParseBorderWidth(const JSRef<JSVal> & args)4115 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
4116 {
4117 CalcDimension borderWidth;
4118 if (ParseJsDimensionVp(args, borderWidth)) {
4119 if (borderWidth.IsNegative()) {
4120 borderWidth.Reset();
4121 }
4122 if (borderWidth.Unit() == DimensionUnit::PERCENT) {
4123 borderWidth.Reset();
4124 }
4125 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
4126 } else if (args->IsObject()) {
4127 if (IsBorderWidthObjUndefined(args)) {
4128 ViewAbstractModel::GetInstance()->SetBorderWidth({});
4129 return;
4130 }
4131 CommonCalcDimension commonCalcDimension;
4132 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4133 if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) {
4134 ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right,
4135 commonCalcDimension.top, commonCalcDimension.bottom, true);
4136 return;
4137 }
4138 ViewAbstractModel::GetInstance()->SetBorderWidth(
4139 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4140 } else {
4141 return;
4142 }
4143 }
4144
ParseDashGap(const JSRef<JSVal> & args)4145 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args)
4146 {
4147 CalcDimension dashGap;
4148 if (ParseLengthMetricsToDimension(args, dashGap)) {
4149 if (dashGap.Unit() == DimensionUnit::PERCENT) {
4150 dashGap.Reset();
4151 }
4152 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4153 } else if (args->IsObject()) {
4154 CommonCalcDimension commonCalcDimension;
4155 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4156 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4157 ViewAbstractModel::GetInstance()->SetDashGap(
4158 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4159 } else {
4160 dashGap.Reset();
4161 ViewAbstractModel::GetInstance()->SetDashGap(dashGap);
4162 }
4163 }
4164
ParseDashWidth(const JSRef<JSVal> & args)4165 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args)
4166 {
4167 CalcDimension dashWidth;
4168 if (ParseLengthMetricsToDimension(args, dashWidth)) {
4169 if (dashWidth.Unit() == DimensionUnit::PERCENT) {
4170 dashWidth.Reset();
4171 }
4172 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4173 } else if (args->IsObject()) {
4174 CommonCalcDimension commonCalcDimension;
4175 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
4176 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension);
4177 ViewAbstractModel::GetInstance()->SetDashWidth(
4178 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom);
4179 } else {
4180 dashWidth.Reset();
4181 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth);
4182 }
4183 }
4184
ParseOuterBorderWidth(const JSRef<JSVal> & args)4185 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
4186 {
4187 CalcDimension borderWidth;
4188 if (ParseJsDimensionVp(args, borderWidth)) {
4189 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
4190 borderWidth.Reset();
4191 }
4192 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
4193 } else if (args->IsObject()) {
4194 std::optional<CalcDimension> leftDimen;
4195 std::optional<CalcDimension> rightDimen;
4196 std::optional<CalcDimension> topDimen;
4197 std::optional<CalcDimension> bottomDimen;
4198 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4199 CalcDimension left;
4200 if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
4201 if (left.Unit() == DimensionUnit::PERCENT) {
4202 left.Reset();
4203 }
4204 leftDimen = left;
4205 }
4206 CalcDimension right;
4207 if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
4208 if (right.Unit() == DimensionUnit::PERCENT) {
4209 right.Reset();
4210 }
4211 rightDimen = right;
4212 }
4213 CalcDimension top;
4214 if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
4215 if (top.Unit() == DimensionUnit::PERCENT) {
4216 top.Reset();
4217 }
4218 topDimen = top;
4219 }
4220 CalcDimension bottom;
4221 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
4222 if (bottom.Unit() == DimensionUnit::PERCENT) {
4223 bottom.Reset();
4224 }
4225 bottomDimen = bottom;
4226 }
4227 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
4228 } else {
4229 return;
4230 }
4231 }
4232
JsBorderImage(const JSCallbackInfo & info)4233 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
4234 {
4235 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4236 auto jsVal = info[0];
4237 if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) {
4238 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4239 uint8_t imageBorderBitsets = 0;
4240 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4241 return;
4242 }
4243 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal);
4244 CHECK_NULL_VOID(!object->IsEmpty());
4245
4246 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
4247 uint8_t imageBorderBitsets = 0;
4248
4249 auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE));
4250 CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject()));
4251 std::string srcResult;
4252 std::string bundleName;
4253 std::string moduleName;
4254 GetJsMediaBundleInfo(valueSource, bundleName, moduleName);
4255 borderImage->SetBundleName(bundleName);
4256 borderImage->SetModuleName(moduleName);
4257 if (valueSource->IsString() && !valueSource->ToString().empty()) {
4258 borderImage->SetSrc(valueSource->ToString());
4259 imageBorderBitsets |= BorderImage::SOURCE_BIT;
4260 } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) {
4261 borderImage->SetSrc(srcResult);
4262 imageBorderBitsets |= BorderImage::SOURCE_BIT;
4263 } else if (valueSource->IsObject()) {
4264 ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
4265 }
4266 auto valueOutset = object->GetProperty("outset");
4267 if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
4268 imageBorderBitsets |= BorderImage::OUTSET_BIT;
4269 ParseBorderImageOutset(valueOutset, borderImage);
4270 }
4271 auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT));
4272 if (!valueRepeat->IsNull()) {
4273 imageBorderBitsets |= BorderImage::REPEAT_BIT;
4274 ParseBorderImageRepeat(valueRepeat, borderImage);
4275 }
4276 auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE));
4277 if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
4278 imageBorderBitsets |= BorderImage::SLICE_BIT;
4279 ParseBorderImageSlice(valueSlice, borderImage);
4280 }
4281 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH));
4282 if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
4283 imageBorderBitsets |= BorderImage::WIDTH_BIT;
4284 ParseBorderImageWidth(valueWidth, borderImage);
4285 }
4286 auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL));
4287 if (needFill->IsBoolean()) {
4288 borderImage->SetNeedFillCenter(needFill->ToBoolean());
4289 }
4290 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
4291 info.ReturnSelf();
4292 }
4293
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4294 bool JSViewAbstract::ParseBorderImageDimension(
4295 const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
4296 {
4297 if (!args->IsObject()) {
4298 return false;
4299 }
4300 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4301 if (CheckLengthMetrics(object)) {
4302 LocalizedCalcDimension localizedCalcDimension;
4303 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4304 borderImageDimension.topDimension = localizedCalcDimension.top;
4305 borderImageDimension.bottomDimension = localizedCalcDimension.bottom;
4306 borderImageDimension.startDimension = localizedCalcDimension.start;
4307 borderImageDimension.endDimension = localizedCalcDimension.end;
4308 return true;
4309 }
4310 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4311 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4312 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4313 for (uint32_t i = 0; i < keys.size(); i++) {
4314 CalcDimension currentDimension;
4315 auto dimensionValue = object->GetProperty(keys.at(i));
4316 if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
4317 auto direction = static_cast<BorderImageDirection>(i);
4318 switch (direction) {
4319 case BorderImageDirection::LEFT:
4320 borderImageDimension.leftDimension = currentDimension;
4321 break;
4322 case BorderImageDirection::RIGHT:
4323 borderImageDimension.rightDimension = currentDimension;
4324 break;
4325 case BorderImageDirection::TOP:
4326 borderImageDimension.topDimension = currentDimension;
4327 break;
4328 case BorderImageDirection::BOTTOM:
4329 borderImageDimension.bottomDimension = currentDimension;
4330 break;
4331 default:
4332 break;
4333 }
4334 }
4335 }
4336 return false;
4337 }
4338
ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4339 void JSViewAbstract::ParseBorderImageLengthMetrics(
4340 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension)
4341 {
4342 for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) {
4343 auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i));
4344 if (!jsVal->IsObject()) {
4345 continue;
4346 }
4347 JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal);
4348 CalcDimension calcDimension;
4349 if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) {
4350 auto direction = static_cast<BorderImageDirection>(i);
4351 switch (direction) {
4352 case BorderImageDirection::LEFT:
4353 localizedCalcDimension.start = calcDimension;
4354 break;
4355 case BorderImageDirection::RIGHT:
4356 localizedCalcDimension.end = calcDimension;
4357 break;
4358 case BorderImageDirection::TOP:
4359 localizedCalcDimension.top = calcDimension;
4360 break;
4361 case BorderImageDirection::BOTTOM:
4362 localizedCalcDimension.bottom = calcDimension;
4363 break;
4364 default:
4365 break;
4366 }
4367 }
4368 }
4369 }
4370
CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4371 bool JSViewAbstract::CheckJSCallbackInfo(
4372 const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes)
4373 {
4374 bool typeVerified = false;
4375 std::string unrecognizedType;
4376 for (const auto& infoType : infoTypes) {
4377 switch (infoType) {
4378 case JSCallbackInfoType::STRING:
4379 if (tmpInfo->IsString()) {
4380 typeVerified = true;
4381 } else {
4382 unrecognizedType += "string|";
4383 }
4384 break;
4385 case JSCallbackInfoType::NUMBER:
4386 if (tmpInfo->IsNumber()) {
4387 typeVerified = true;
4388 } else {
4389 unrecognizedType += "number|";
4390 }
4391 break;
4392 case JSCallbackInfoType::OBJECT:
4393 if (tmpInfo->IsObject()) {
4394 typeVerified = true;
4395 } else {
4396 unrecognizedType += "object|";
4397 }
4398 break;
4399 case JSCallbackInfoType::FUNCTION:
4400 if (tmpInfo->IsFunction()) {
4401 typeVerified = true;
4402 } else {
4403 unrecognizedType += "Function|";
4404 }
4405 break;
4406 default:
4407 break;
4408 }
4409 }
4410 if (!typeVerified) {
4411 LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
4412 unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
4413 }
4414 return typeVerified || infoTypes.size() == 0;
4415 }
4416
UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4417 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction)
4418 {
4419 switch (direction) {
4420 case NG::GradientDirection::LEFT:
4421 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4422 break;
4423 case NG::GradientDirection::RIGHT:
4424 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4425 break;
4426 case NG::GradientDirection::TOP:
4427 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4428 break;
4429 case NG::GradientDirection::BOTTOM:
4430 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4431 break;
4432 case NG::GradientDirection::LEFT_TOP:
4433 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4434 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4435 break;
4436 case NG::GradientDirection::LEFT_BOTTOM:
4437 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
4438 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4439 break;
4440 case NG::GradientDirection::RIGHT_TOP:
4441 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4442 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
4443 break;
4444 case NG::GradientDirection::RIGHT_BOTTOM:
4445 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
4446 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
4447 break;
4448 case NG::GradientDirection::NONE:
4449 case NG::GradientDirection::START_TO_END:
4450 case NG::GradientDirection::END_TO_START:
4451 default:
4452 break;
4453 }
4454 }
4455
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)4456 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
4457 {
4458 if (!args->IsObject()) {
4459 return;
4460 }
4461 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
4462 NG::Gradient lineGradient;
4463 lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
4464 // angle
4465 std::optional<float> degree;
4466 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4467 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
4468 } else {
4469 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
4470 }
4471 if (degree) {
4472 lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
4473 degree.reset();
4474 }
4475 // direction
4476 auto direction = static_cast<NG::GradientDirection>(
4477 jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION),
4478 static_cast<int32_t>(NG::GradientDirection::NONE)));
4479 UpdateGradientWithDirection(lineGradient, direction);
4480 auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false);
4481 lineGradient.SetRepeat(repeating);
4482 NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
4483 ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
4484 bitset |= BorderImage::GRADIENT_BIT;
4485 }
4486
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4487 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4488 {
4489 auto repeatString = args->ToString();
4490 if (repeatString == "Repeat") {
4491 borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
4492 } else if (repeatString == "Round") {
4493 borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
4494 } else if (repeatString == "Space") {
4495 borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
4496 } else {
4497 borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
4498 }
4499 }
4500
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4501 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4502 {
4503 CalcDimension outsetDimension;
4504 if (ParseJsDimensionVp(args, outsetDimension)) {
4505 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
4506 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
4507 borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
4508 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
4509 return;
4510 }
4511 BorderImage::BorderImageOption option;
4512 ParseBorderImageDimension(args, option);
4513 if (option.startDimension.has_value()) {
4514 borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value());
4515 }
4516 if (option.endDimension.has_value()) {
4517 borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value());
4518 }
4519 if (option.leftDimension.has_value()) {
4520 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
4521 }
4522 if (option.rightDimension.has_value()) {
4523 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
4524 }
4525 if (option.topDimension.has_value()) {
4526 borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
4527 }
4528 if (option.bottomDimension.has_value()) {
4529 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4530 }
4531 }
4532
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4533 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4534 {
4535 CalcDimension sliceDimension;
4536 if (ParseJsDimensionVp(args, sliceDimension)) {
4537 borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
4538 borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
4539 borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
4540 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
4541 return;
4542 }
4543 if (!args->IsObject()) {
4544 return;
4545 }
4546 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4547 if (CheckLengthMetrics(object)) {
4548 LocalizedCalcDimension localizedCalcDimension;
4549 ParseBorderImageLengthMetrics(object, localizedCalcDimension);
4550 if (localizedCalcDimension.top.has_value()) {
4551 borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value());
4552 }
4553 if (localizedCalcDimension.bottom.has_value()) {
4554 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value());
4555 }
4556 if (localizedCalcDimension.start.has_value()) {
4557 borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value());
4558 }
4559 if (localizedCalcDimension.end.has_value()) {
4560 borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value());
4561 }
4562 return;
4563 }
4564 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
4565 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
4566 static_cast<int32_t>(ArkUIIndex::BOTTOM) };
4567 for (uint32_t i = 0; i < keys.size(); i++) {
4568 auto dimensionValue = object->GetProperty(keys.at(i));
4569 if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
4570 borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
4571 }
4572 }
4573 }
4574
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4575 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
4576 {
4577 CalcDimension widthDimension;
4578 if (ParseJsDimensionVp(args, widthDimension)) {
4579 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
4580 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
4581 borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
4582 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
4583 return;
4584 }
4585
4586 BorderImage::BorderImageOption option;
4587 ParseBorderImageDimension(args, option);
4588 if (option.startDimension.has_value()) {
4589 borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value());
4590 }
4591 if (option.endDimension.has_value()) {
4592 borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value());
4593 }
4594 if (option.leftDimension.has_value()) {
4595 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
4596 }
4597 if (option.rightDimension.has_value()) {
4598 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
4599 }
4600 if (option.topDimension.has_value()) {
4601 borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
4602 }
4603 if (option.bottomDimension.has_value()) {
4604 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
4605 }
4606 }
4607
JsBorderColor(const JSCallbackInfo & info)4608 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
4609 {
4610 ParseBorderColor(info[0]);
4611 }
4612
GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)4613 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart,
4614 const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop,
4615 const std::optional<Color>& colorBottom)
4616 {
4617 NG::BorderColorProperty borderColors;
4618 borderColors.startColor = colorStart;
4619 borderColors.endColor = colorEnd;
4620 borderColors.topColor = colorTop;
4621 borderColors.bottomColor = colorBottom;
4622 borderColors.multiValued = true;
4623 return borderColors;
4624 }
4625
ParseBorderColor(const JSRef<JSVal> & args)4626 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
4627 {
4628 Color borderColor;
4629 if (ParseJsColor(args, borderColor)) {
4630 ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
4631 } else if (args->IsObject()) {
4632 CommonColor commonColor;
4633 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4634 if (ParseCommonEdgeColors(object, commonColor)) {
4635 ViewAbstractModel::GetInstance()->SetBorderColor(
4636 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4637 return;
4638 }
4639 ViewAbstractModel::GetInstance()->SetBorderColor(
4640 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4641 } else {
4642 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
4643 }
4644 }
4645
ParseOuterBorderColor(const JSRef<JSVal> & args)4646 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
4647 {
4648 Color borderColor;
4649 if (ParseJsColor(args, borderColor)) {
4650 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
4651 } else if (args->IsObject()) {
4652 CommonColor commonColor;
4653 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4654 if (ParseCommonEdgeColors(object, commonColor)) {
4655 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4656 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom));
4657 return;
4658 }
4659 ViewAbstractModel::GetInstance()->SetOuterBorderColor(
4660 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom);
4661 } else {
4662 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
4663 }
4664 }
4665
JsBorderRadius(const JSCallbackInfo & info)4666 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
4667 {
4668 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
4669 JSCallbackInfoType::OBJECT };
4670 auto jsVal = info[0];
4671 if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
4672 ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
4673 return;
4674 }
4675 ParseBorderRadius(jsVal);
4676 }
4677
GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)4678 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
4679 const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
4680 const std::optional<Dimension>& radiusBottomEnd)
4681 {
4682 NG::BorderRadiusProperty borderRadius;
4683 borderRadius.radiusTopStart = radiusTopStart;
4684 borderRadius.radiusTopEnd = radiusTopEnd;
4685 borderRadius.radiusBottomStart = radiusBottomStart;
4686 borderRadius.radiusBottomEnd = radiusBottomEnd;
4687 borderRadius.multiValued = true;
4688 return borderRadius;
4689 }
4690
ParseBorderRadius(const JSRef<JSVal> & args)4691 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
4692 {
4693 CalcDimension borderRadius;
4694 if (ParseJsDimensionVp(args, borderRadius)) {
4695 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
4696 } else if (args->IsObject()) {
4697 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4698 CalcDimension topLeft;
4699 CalcDimension topRight;
4700 CalcDimension bottomLeft;
4701 CalcDimension bottomRight;
4702 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4703 ViewAbstractModel::GetInstance()->SetBorderRadius(
4704 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4705 return;
4706 }
4707 ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4708 }
4709 }
4710
ParseOuterBorderRadius(const JSRef<JSVal> & args)4711 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
4712 {
4713 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
4714 return;
4715 }
4716 CalcDimension borderRadius;
4717 if (ParseJsDimensionVp(args, borderRadius)) {
4718 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
4719 borderRadius.Reset();
4720 }
4721 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
4722 } else if (args->IsObject()) {
4723 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4724 CalcDimension topLeft;
4725 CalcDimension topRight;
4726 CalcDimension bottomLeft;
4727 CalcDimension bottomRight;
4728 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
4729 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(
4730 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
4731 }
4732 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
4733 }
4734 }
4735
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4736 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4737 {
4738 ParseJsDimensionVp(object->GetProperty(key), radius);
4739 }
4740
GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4741 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
4742 {
4743 if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) {
4744 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key));
4745 ParseJsLengthMetrics(startObj, radius);
4746 }
4747 }
4748
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)4749 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
4750 CalcDimension& bottomLeft, CalcDimension& bottomRight)
4751 {
4752 if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) ||
4753 object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) {
4754 CalcDimension topStart;
4755 CalcDimension topEnd;
4756 CalcDimension bottomStart;
4757 CalcDimension bottomEnd;
4758 GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart);
4759 GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd);
4760 GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart);
4761 GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd);
4762 topLeft = topStart;
4763 topRight = topEnd;
4764 bottomLeft = bottomStart;
4765 bottomRight = bottomEnd;
4766 return true;
4767 }
4768 GetBorderRadius("topLeft", object, topLeft);
4769 GetBorderRadius("topRight", object, topRight);
4770 GetBorderRadius("bottomLeft", object, bottomLeft);
4771 GetBorderRadius("bottomRight", object, bottomRight);
4772 return false;
4773 }
4774
JsBorderStyle(const JSCallbackInfo & info)4775 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
4776 {
4777 ParseBorderStyle(info[0]);
4778 }
4779 namespace {
ConvertBorderStyle(int32_t value)4780 BorderStyle ConvertBorderStyle(int32_t value)
4781 {
4782 auto style = static_cast<BorderStyle>(value);
4783 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4784 style = BorderStyle::SOLID;
4785 }
4786 return style;
4787 }
4788
ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)4789 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style)
4790 {
4791 style = static_cast<BorderStyle>(value);
4792 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
4793 return false;
4794 }
4795 return true;
4796 }
4797 } // namespace
4798
ParseBorderStyle(const JSRef<JSVal> & args)4799 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
4800 {
4801 if (args->IsObject()) {
4802 std::optional<BorderStyle> styleLeft;
4803 std::optional<BorderStyle> styleRight;
4804 std::optional<BorderStyle> styleTop;
4805 std::optional<BorderStyle> styleBottom;
4806 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4807 auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT));
4808 if (leftValue->IsNumber()) {
4809 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4810 }
4811 auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT));
4812 if (rightValue->IsNumber()) {
4813 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4814 }
4815 auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP));
4816 if (topValue->IsNumber()) {
4817 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4818 }
4819 auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM));
4820 if (bottomValue->IsNumber()) {
4821 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4822 }
4823 ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4824 return;
4825 }
4826 if (args->IsNumber()) {
4827 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4828 ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
4829 return;
4830 }
4831 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
4832 }
4833
ParseOuterBorderStyle(const JSRef<JSVal> & args)4834 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
4835 {
4836 if (!args->IsObject() && !args->IsNumber()) {
4837 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
4838 return;
4839 }
4840 if (args->IsObject()) {
4841 std::optional<BorderStyle> styleLeft;
4842 std::optional<BorderStyle> styleRight;
4843 std::optional<BorderStyle> styleTop;
4844 std::optional<BorderStyle> styleBottom;
4845 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
4846 auto leftValue = object->GetProperty("left");
4847 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
4848 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
4849 }
4850 auto rightValue = object->GetProperty("right");
4851 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
4852 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
4853 }
4854 auto topValue = object->GetProperty("top");
4855 if (!topValue->IsUndefined() && topValue->IsNumber()) {
4856 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
4857 }
4858 auto bottomValue = object->GetProperty("bottom");
4859 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
4860 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
4861 }
4862 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
4863 return;
4864 }
4865 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
4866 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
4867 }
4868
JsBlur(const JSCallbackInfo & info)4869 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
4870 {
4871 if (info.Length() == 0) {
4872 return;
4873 }
4874 double blur = 0.0;
4875 if (!ParseJsDouble(info[0], blur)) {
4876 return;
4877 }
4878
4879 BlurOption blurOption;
4880 if (info.Length() > 1 && info[1]->IsObject()) {
4881 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4882 ParseBlurOption(jsBlurOption, blurOption);
4883 }
4884 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4885 ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption);
4886 info.SetReturnValue(info.This());
4887 }
4888
JsMotionBlur(const JSCallbackInfo & info)4889 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info)
4890 {
4891 if (!info[0]->IsObject()) {
4892 return;
4893 }
4894 MotionBlurOption option;
4895 double x = 0.0;
4896 double y = 0.0;
4897 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4898 JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor");
4899 if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) {
4900 JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor);
4901 ParseJsDouble(jsAnchorObj->GetProperty("x"), x);
4902 ParseJsDouble(jsAnchorObj->GetProperty("y"), y);
4903 }
4904 double radius = 0.0;
4905 if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) {
4906 radius = 0.0;
4907 }
4908 if (LessNotEqual(x, 0.0)) {
4909 x = 0.0;
4910 }
4911 if (LessNotEqual(y, 0.0)) {
4912 y = 0.0;
4913 }
4914 option.radius = radius;
4915 option.anchor.x = std::clamp(x, 0.0, 1.0);
4916 option.anchor.y = std::clamp(y, 0.0, 1.0);
4917 ViewAbstractModel::GetInstance()->SetMotionBlur(option);
4918 }
4919
JsColorBlend(const JSCallbackInfo & info)4920 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
4921 {
4922 Color colorBlend;
4923 if (info[0]->IsUndefined()) {
4924 colorBlend = Color::TRANSPARENT;
4925 SetColorBlend(colorBlend);
4926 return;
4927 }
4928 if (!ParseJsColor(info[0], colorBlend)) {
4929 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
4930 colorBlend = Color::TRANSPARENT;
4931 SetColorBlend(colorBlend);
4932 }
4933 return;
4934 }
4935 SetColorBlend(colorBlend);
4936 info.SetReturnValue(info.This());
4937 }
4938
JsUseEffect(const JSCallbackInfo & info)4939 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
4940 {
4941 if (info[0]->IsBoolean()) {
4942 auto effectType = EffectType::DEFAULT;
4943 if (info.Length() == 2 && info[1]->IsNumber()) {
4944 effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>());
4945 if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) {
4946 effectType = EffectType::DEFAULT;
4947 }
4948 }
4949 ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType);
4950 }
4951 }
4952
JsUseShadowBatching(const JSCallbackInfo & info)4953 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
4954 {
4955 if (info[0]->IsBoolean()) {
4956 ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
4957 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4958 ViewAbstractModel::GetInstance()->SetUseShadowBatching(false);
4959 }
4960 }
4961
JsBackdropBlur(const JSCallbackInfo & info)4962 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
4963 {
4964 if (info.Length() == 0) {
4965 return;
4966 }
4967 double blur = 0.0;
4968 BlurOption blurOption;
4969 if (!ParseJsDouble(info[0], blur)) {
4970 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
4971 return;
4972 }
4973 }
4974 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
4975 if (info.Length() > 1 && info[1]->IsObject()) {
4976 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
4977 ParseBlurOption(jsBlurOption, blurOption);
4978 }
4979 ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption);
4980 info.SetReturnValue(info.This());
4981 }
4982
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4983 void JSViewAbstract::GetFractionStops(
4984 std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
4985 {
4986 if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
4987 return;
4988 }
4989 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
4990 float tmpPos = -1.0f;
4991 size_t length = jsArray->Length();
4992 for (size_t i = 0; i < length; i++) {
4993 std::pair<float, float> fractionStop;
4994 JSRef<JSVal> item = jsArray->GetValueAt(i);
4995 if (!item->IsArray()) {
4996 continue;
4997 }
4998 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
4999 if (subArray->Length() < 2) {
5000 continue;
5001 }
5002
5003 double value = 0.0;
5004 if (ParseJsDouble(subArray->GetValueAt(0), value)) {
5005 value = std::clamp(value, 0.0, 1.0);
5006 fractionStop.first = static_cast<float>(value);
5007 }
5008 value = 0.0;
5009 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
5010 value = std::clamp(value, 0.0, 1.0);
5011 fractionStop.second = static_cast<float>(value);
5012 }
5013
5014 if (fractionStop.second <= tmpPos) {
5015 fractionStops.clear();
5016 return;
5017 }
5018 tmpPos = fractionStop.second;
5019 fractionStops.push_back(fractionStop);
5020 }
5021 }
JsLinearGradientBlur(const JSCallbackInfo & info)5022 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
5023 {
5024 if (info.Length() < 2) { // 2 represents the least para num;
5025 return;
5026 }
5027 double blurRadius = 0.0;
5028 ParseJsDouble(info[0], blurRadius);
5029
5030 std::vector<std::pair<float, float>> fractionStops;
5031 auto direction = GradientDirection::BOTTOM;
5032 if (info[1]->IsObject()) {
5033 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
5034 GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
5035 auto directionValue =
5036 jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
5037 if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
5038 directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
5039 directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
5040 }
5041 direction = static_cast<GradientDirection>(directionValue);
5042 }
5043 if (static_cast<int32_t>(fractionStops.size()) <= 1) {
5044 fractionStops.clear();
5045 fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
5046 fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
5047 }
5048 // Parse direction
5049 CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
5050 NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
5051 SetLinearGradientBlur(blurPara);
5052 }
5053
JsBackgroundBrightness(const JSCallbackInfo & info)5054 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
5055 {
5056 double rate = 0.0;
5057 double lightUpDegree = 0.0;
5058 if (info[0]->IsObject()) {
5059 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5060 ParseJsDouble(jsObj->GetProperty("rate"), rate);
5061 ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
5062 }
5063 SetDynamicLightUp(rate, lightUpDegree);
5064 }
5065
JsBackgroundBrightnessInternal(const JSCallbackInfo & info)5066 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info)
5067 {
5068 if (info.Length() == 0) {
5069 return;
5070 }
5071 BrightnessOption option;
5072 if (info[0]->IsObject()) {
5073 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5074 ParseBrightnessOption(jsOption, option);
5075 }
5076 SetBgDynamicBrightness(option);
5077 }
5078
JsForegroundBrightness(const JSCallbackInfo & info)5079 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info)
5080 {
5081 if (info.Length() == 0) {
5082 return;
5083 }
5084 BrightnessOption option;
5085 if (info[0]->IsObject()) {
5086 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
5087 ParseBrightnessOption(jsOption, option);
5088 }
5089 SetFgDynamicBrightness(option);
5090 }
5091
JsWindowBlur(const JSCallbackInfo & info)5092 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
5093 {
5094 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5095 auto jsVal = info[0];
5096 if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) {
5097 return;
5098 }
5099
5100 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
5101 double progress = 0.0;
5102 ParseJsDouble(jsObj->GetProperty("percent"), progress);
5103 auto style = jsObj->GetPropertyValue<int32_t>("style",
5104 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
5105
5106 progress = std::clamp(progress, 0.0, 1.0);
5107 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
5108 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
5109
5110 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
5111 info.SetReturnValue(info.This());
5112 }
5113
ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)5114 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType,
5115 std::string& resName, bool isParseType)
5116 {
5117 if (!jsValue->IsString()) {
5118 return false;
5119 }
5120 std::string resPath = jsValue->ToString();
5121 std::smatch results;
5122 std::regex tokenRegex(RESOURCE_TOKEN_PATTERN);
5123 if (!std::regex_match(resPath, results, tokenRegex)) {
5124 return false;
5125 }
5126 targetModule = results[1];
5127 if (isParseType && !ConvertResourceType(results[2], resType)) {
5128 return false;
5129 }
5130 resName = resPath;
5131 return true;
5132 }
5133
ConvertResourceType(const std::string & typeName,ResourceType & resType)5134 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
5135 {
5136 static const std::unordered_map<std::string, ResourceType> resTypeMap {
5137 { "color", ResourceType::COLOR },
5138 { "media", ResourceType::MEDIA },
5139 { "float", ResourceType::FLOAT },
5140 { "string", ResourceType::STRING },
5141 { "plural", ResourceType::PLURAL },
5142 { "pattern", ResourceType::PATTERN },
5143 { "boolean", ResourceType::BOOLEAN },
5144 { "integer", ResourceType::INTEGER },
5145 { "strarray", ResourceType::STRARRAY },
5146 { "intarray", ResourceType::INTARRAY },
5147 };
5148 auto it = resTypeMap.find(typeName);
5149 if (it == resTypeMap.end()) {
5150 return false;
5151 }
5152 resType = it->second;
5153 return true;
5154 }
5155
CompleteResourceObject(JSRef<JSObject> & jsObj)5156 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
5157 {
5158 std::string bundleName;
5159 std::string moduleName;
5160 int32_t resId = -1;
5161 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5162 }
5163
CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)5164 void JSViewAbstract::CompleteResourceObjectWithBundleName(
5165 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId)
5166 {
5167 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId);
5168 }
5169
CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)5170 void JSViewAbstract::CompleteResourceObjectInner(
5171 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue)
5172 {
5173 // dynamic $r raw input format is
5174 // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
5175 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5176 ResourceType resType;
5177
5178 std::string targetModule;
5179 std::string resName;
5180 if (resId->IsString()) {
5181 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE));
5182 int32_t typeNum = -1;
5183 if (type->IsNumber()) {
5184 typeNum = type->ToNumber<int32_t>();
5185 }
5186 if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) {
5187 return;
5188 }
5189 CompleteResourceObjectFromId(type, jsObj, resType, resName);
5190 } else if (resId->IsNumber()) {
5191 resIdValue = resId->ToNumber<int32_t>();
5192 if (resIdValue == -1) {
5193 CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName);
5194 }
5195 }
5196
5197 JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName);
5198 if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) {
5199 bundleName = GetBundleNameFromContainer();
5200 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName);
5201 }
5202 if (moduleName == DEFAULT_HAR_MODULE_NAME) {
5203 moduleName = GetModuleNameFromContainer();
5204 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName);
5205 }
5206 }
5207
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)5208 bool JSViewAbstract::ParseJsDimensionNG(
5209 const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
5210 {
5211 if (jsValue->IsNumber()) {
5212 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5213 return true;
5214 }
5215 if (jsValue->IsString()) {
5216 auto value = jsValue->ToString();
5217 if (!isSupportPercent && value.back() == '%') {
5218 return false;
5219 }
5220 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5221 }
5222 if (jsValue->IsObject()) {
5223 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5224 CompleteResourceObject(jsObj);
5225 JSRef<JSVal> resId = jsObj->GetProperty("id");
5226 if (!resId->IsNumber()) {
5227 return false;
5228 }
5229 auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5230 if (resType == UNKNOWN_RESOURCE_TYPE) {
5231 return false;
5232 }
5233
5234 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5235 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5236 if (!resourceWrapper) {
5237 return false;
5238 }
5239
5240 auto resIdNum = resId->ToNumber<int32_t>();
5241 if (resIdNum == -1) {
5242 if (!IsGetResourceByName(jsObj)) {
5243 return false;
5244 }
5245 JSRef<JSVal> args = jsObj->GetProperty("params");
5246 if (!args->IsArray()) {
5247 return false;
5248 }
5249 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5250 auto param = params->GetValueAt(0);
5251 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5252 auto value = resourceWrapper->GetStringByName(param->ToString());
5253 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5254 }
5255 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5256 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5257 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5258 return true;
5259 }
5260 result = resourceWrapper->GetDimensionByName(param->ToString());
5261 return true;
5262 }
5263
5264 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5265 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5266 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
5267 }
5268 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5269 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5270 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
5271 return true;
5272 }
5273
5274 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5275 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
5276 return true;
5277 }
5278 }
5279
5280 return false;
5281 }
5282
ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)5283 bool JSViewAbstract::ParseJsLengthNG(
5284 const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent)
5285 {
5286 if (jsValue->IsNumber()) {
5287 if (std::isnan(jsValue->ToNumber<double>())) {
5288 return false;
5289 }
5290 result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit);
5291 return true;
5292 } else if (jsValue->IsObject()) {
5293 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5294 JSRef<JSVal> value = jsObj->GetProperty("value");
5295 if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) {
5296 return false;
5297 }
5298 DimensionUnit unit = defaultUnit;
5299 JSRef<JSVal> jsUnit = jsObj->GetProperty("unit");
5300 if (jsUnit->IsNumber()) {
5301 if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) {
5302 return false;
5303 }
5304 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>());
5305 }
5306 result = NG::CalcLength(value->ToNumber<double>(), unit);
5307 return true;
5308 }
5309
5310 return false;
5311 }
5312
ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)5313 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent)
5314 {
5315 // 'vp' -> the value varies with pixel density of device.
5316 return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5317 }
5318
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)5319 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
5320 {
5321 if (jsValue->IsNumber()) {
5322 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
5323 return true;
5324 }
5325 if (jsValue->IsString()) {
5326 result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
5327 return true;
5328 }
5329 if (!jsValue->IsObject()) {
5330 return false;
5331 }
5332 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5333 CompleteResourceObject(jsObj);
5334 JSRef<JSVal> resId = jsObj->GetProperty("id");
5335 if (!resId->IsNumber()) {
5336 return false;
5337 }
5338
5339 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5340 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5341 if (!resourceWrapper) {
5342 return false;
5343 }
5344
5345 auto resIdNum = resId->ToNumber<int32_t>();
5346 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5347 if (resType == UNKNOWN_RESOURCE_TYPE) {
5348 return false;
5349 }
5350
5351 if (resIdNum == -1) {
5352 if (!IsGetResourceByName(jsObj)) {
5353 return false;
5354 }
5355 JSRef<JSVal> args = jsObj->GetProperty("params");
5356 if (!args->IsArray()) {
5357 return false;
5358 }
5359 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5360 auto param = params->GetValueAt(0);
5361 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5362 auto value = resourceWrapper->GetStringByName(param->ToString());
5363 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5364 return true;
5365 }
5366 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5367 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
5368 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5369 return true;
5370 }
5371 result = resourceWrapper->GetDimensionByName(param->ToString());
5372 return true;
5373 }
5374
5375 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5376 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5377 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
5378 return true;
5379 }
5380 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5381 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5382 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
5383 return true;
5384 }
5385 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
5386 return true;
5387 }
5388
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5389 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5390 {
5391 // 'vp' -> the value varies with pixel density of device.
5392 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
5393 }
5394
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)5395 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5396 {
5397 // 'vp' -> the value varies with pixel density of device.
5398 return ParseJsDimension(jsValue, result, DimensionUnit::VP);
5399 }
5400
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)5401 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
5402 {
5403 // the 'fp' unit is used for text scenes.
5404 return ParseJsDimension(jsValue, result, DimensionUnit::FP);
5405 }
5406
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5407 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
5408 {
5409 // the 'fp' unit is used for text scenes.
5410 return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
5411 }
5412
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)5413 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
5414 {
5415 return ParseJsDimension(jsValue, result, DimensionUnit::PX);
5416 }
5417
ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)5418 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result)
5419 {
5420 if (!jsValue->IsObject()) {
5421 return false;
5422 }
5423 auto colorObj = JSRef<JSObject>::Cast(jsValue);
5424 auto toNumericProp = colorObj->GetProperty("toNumeric");
5425 if (toNumericProp->IsFunction()) {
5426 auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr);
5427 result.SetValue(colorVal->ToNumber<uint32_t>());
5428 return true;
5429 }
5430 return false;
5431 }
5432
ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5433 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5434 {
5435 if (jsValue->IsNumber()) {
5436 result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP);
5437 return true;
5438 }
5439 if (jsValue->IsString()) {
5440 auto value = jsValue->ToString();
5441 return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP);
5442 }
5443 if (jsValue->IsObject()) {
5444 auto jsObj = JSRef<JSObject>::Cast(jsValue);
5445 auto valObj = jsObj->GetProperty("value");
5446 if (valObj->IsUndefined() || valObj->IsNull()) {
5447 return false;
5448 }
5449 double value = valObj->ToNumber<double>();
5450 auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>());
5451 result = CalcDimension(value, unit);
5452 return true;
5453 }
5454 return false;
5455 }
5456
ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5457 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result)
5458 {
5459 return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false;
5460 }
5461
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)5462 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
5463 {
5464 if (!jsValue->IsObject()) {
5465 return false;
5466 }
5467 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5468 CompleteResourceObject(jsObj);
5469 if (jsObj->IsEmpty()) {
5470 return false;
5471 }
5472 JSRef<JSVal> id = jsObj->GetProperty("id");
5473 if (!id->IsNumber()) {
5474 return false;
5475 }
5476
5477 auto resId = id->ToNumber<int32_t>();
5478 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5479 if (resType == UNKNOWN_RESOURCE_TYPE) {
5480 return false;
5481 }
5482
5483 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5484 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5485 if (!resourceWrapper) {
5486 return false;
5487 }
5488
5489 if (resId == -1) {
5490 if (!IsGetResourceByName(jsObj)) {
5491 return false;
5492 }
5493 JSRef<JSVal> args = jsObj->GetProperty("params");
5494 if (!args->IsArray()) {
5495 return false;
5496 }
5497 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5498 auto param = params->GetValueAt(0);
5499 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5500 auto numberString = resourceWrapper->GetStringByName(param->ToString());
5501 return StringUtils::StringToDouble(numberString, result);
5502 }
5503 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5504 result = resourceWrapper->GetIntByName(param->ToString());
5505 return true;
5506 }
5507 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5508 result = resourceWrapper->GetDoubleByName(param->ToString());
5509 return true;
5510 }
5511 return false;
5512 }
5513 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
5514 auto numberString = resourceWrapper->GetString(resId);
5515 return StringUtils::StringToDouble(numberString, result);
5516 }
5517 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
5518 result = resourceWrapper->GetInt(resId);
5519 return true;
5520 }
5521 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
5522 result = resourceWrapper->GetDouble(resId);
5523 return true;
5524 }
5525 return false;
5526 }
5527
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)5528 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
5529 {
5530 if (jsValue->IsNumber()) {
5531 result = jsValue->ToNumber<double>();
5532 return true;
5533 }
5534 if (jsValue->IsString()) {
5535 return StringUtils::StringToDouble(jsValue->ToString(), result);
5536 }
5537 if (jsValue->IsObject()) {
5538 return ParseResourceToDouble(jsValue, result);
5539 }
5540 return false;
5541 }
5542
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)5543 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
5544 {
5545 if (jsValue->IsNumber()) {
5546 result = jsValue->ToNumber<int32_t>();
5547 return true;
5548 }
5549 if (jsValue->IsString()) {
5550 result = StringUtils::StringToInt(jsValue->ToString());
5551 return true;
5552 }
5553 if (!jsValue->IsObject()) {
5554 return false;
5555 }
5556 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5557 CompleteResourceObject(jsObj);
5558 JSRef<JSVal> resId = jsObj->GetProperty("id");
5559 if (!resId->IsNumber()) {
5560 return false;
5561 }
5562
5563 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5564 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5565 if (!resourceWrapper) {
5566 return false;
5567 }
5568
5569 auto resIdNum = resId->ToNumber<int32_t>();
5570 if (resIdNum == -1) {
5571 if (!IsGetResourceByName(jsObj)) {
5572 return false;
5573 }
5574 JSRef<JSVal> args = jsObj->GetProperty("params");
5575 if (!args->IsArray()) {
5576 return false;
5577 }
5578 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5579 auto param = params->GetValueAt(0);
5580 result = resourceWrapper->GetIntByName(param->ToString());
5581 return true;
5582 }
5583 result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5584 return true;
5585 }
5586
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)5587 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
5588 {
5589 if (!jsValue->IsObject()) {
5590 return false;
5591 }
5592 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5593 CompleteResourceObject(jsObj);
5594
5595 auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result);
5596 if (ok) {
5597 JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio");
5598 if (jsOpacityRatio->IsNumber()) {
5599 double opacityRatio = jsOpacityRatio->ToNumber<double>();
5600 result = result.BlendOpacity(opacityRatio);
5601 }
5602 }
5603 return ok;
5604 }
5605
ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)5606 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result)
5607 {
5608 JSRef<JSVal> resId = jsObj->GetProperty("id");
5609 if (!resId->IsNumber()) {
5610 return false;
5611 }
5612
5613 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5614 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5615 if (!resourceWrapper) {
5616 return false;
5617 }
5618
5619 auto resIdNum = resId->ToNumber<int32_t>();
5620 if (resIdNum == -1) {
5621 if (!IsGetResourceByName(jsObj)) {
5622 return false;
5623 }
5624 JSRef<JSVal> args = jsObj->GetProperty("params");
5625 if (!args->IsArray()) {
5626 return false;
5627 }
5628 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5629 auto param = params->GetValueAt(0);
5630 result = resourceWrapper->GetColorByName(param->ToString());
5631 return true;
5632 }
5633
5634 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5635 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5636 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5637 return Color::ParseColorString(value, result);
5638 }
5639 if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5640 auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
5641 result = Color(ColorAlphaAdapt(value));
5642 return true;
5643 }
5644 if (type == static_cast<int32_t>(ResourceType::COLOR)) {
5645 result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
5646 result.SetResourceId(resId->ToNumber<uint32_t>());
5647 return true;
5648 }
5649 return false;
5650 }
5651
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)5652 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
5653 {
5654 if (jsValue->IsNumber()) {
5655 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5656 return true;
5657 }
5658 if (jsValue->IsString()) {
5659 return Color::ParseColorString(jsValue->ToString(), result);
5660 }
5661 if (jsValue->IsObject()) {
5662 return ParseJsColorFromResource(jsValue, result);
5663 }
5664 return false;
5665 }
5666
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)5667 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor)
5668 {
5669 if (jsValue->IsNumber()) {
5670 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
5671 return true;
5672 }
5673 if (jsValue->IsString()) {
5674 return Color::ParseColorString(jsValue->ToString(), result, defaultColor);
5675 }
5676 if (!jsValue->IsObject()) {
5677 return false;
5678 }
5679 return ParseJsColorFromResource(jsValue, result);
5680 }
5681
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)5682 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
5683 {
5684 if (jsValue->IsString()) {
5685 std::string colorStr = jsValue->ToString();
5686 if (colorStr.compare("invert") == 0) {
5687 strategy = ForegroundColorStrategy::INVERT;
5688 return true;
5689 }
5690 }
5691 return false;
5692 }
5693
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)5694 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
5695 {
5696 if (jsValue->IsString()) {
5697 std::string colorStr = jsValue->ToString();
5698 if (colorStr.compare("average") == 0) {
5699 strategy = ShadowColorStrategy::AVERAGE;
5700 return true;
5701 } else if (colorStr.compare("primary") == 0) {
5702 strategy = ShadowColorStrategy::PRIMARY;
5703 return true;
5704 }
5705 }
5706 return false;
5707 }
5708
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)5709 bool JSViewAbstract::ParseJsSymbolId(
5710 const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
5711 {
5712 if (jsValue->IsNull() || jsValue->IsUndefined()) {
5713 symbolId = 0;
5714 return false;
5715 }
5716 if (!jsValue->IsObject()) {
5717 return false;
5718 }
5719 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5720 CompleteResourceObject(jsObj);
5721 JSRef<JSVal> resId = jsObj->GetProperty("id");
5722 if (resId->IsNull() || !resId->IsNumber()) {
5723 return false;
5724 }
5725 auto resourceObject = GetResourceObject(jsObj);
5726 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5727 symbolResourceObject = resourceObject;
5728 if (!resourceWrapper) {
5729 return false;
5730 }
5731 if (!resourceObject) {
5732 return false;
5733 }
5734
5735 auto resIdNum = resId->ToNumber<int32_t>();
5736 if (resIdNum == -1) {
5737 if (!IsGetResourceByName(jsObj)) {
5738 return false;
5739 }
5740 JSRef<JSVal> args = jsObj->GetProperty("params");
5741 if (!args->IsArray()) {
5742 return false;
5743 }
5744 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5745 auto param = params->GetValueAt(0);
5746 auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str());
5747 if (!symbol) {
5748 return false;
5749 }
5750 symbolId = symbol;
5751 return true;
5752 }
5753
5754 auto symbol = resourceWrapper->GetSymbolById(resIdNum);
5755 if (!symbol) {
5756 return false;
5757 }
5758 symbolId = symbol;
5759 return true;
5760 }
5761
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)5762 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
5763 {
5764 if (!jsValue->IsArray()) {
5765 return false;
5766 }
5767 if (jsValue->IsArray()) {
5768 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
5769 for (size_t i = 0; i < array->Length(); i++) {
5770 JSRef<JSVal> value = array->GetValueAt(i);
5771 if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
5772 return false;
5773 }
5774 if (value->IsNumber()) {
5775 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
5776 continue;
5777 } else if (value->IsString()) {
5778 Color color;
5779 Color::ParseColorString(value->ToString(), color);
5780 result.emplace_back(color);
5781 continue;
5782 } else {
5783 Color color;
5784 ParseJsColorFromResource(value, color);
5785 result.emplace_back(color);
5786 }
5787 }
5788 return true;
5789 }
5790 return false;
5791 }
5792
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5793 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
5794 {
5795 result.clear();
5796 if (!jsValue->IsString() && !jsValue->IsObject()) {
5797 return false;
5798 }
5799 if (jsValue->IsString()) {
5800 result = ConvertStrToFontFamilies(jsValue->ToString());
5801 return true;
5802 }
5803 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5804 CompleteResourceObject(jsObj);
5805 JSRef<JSVal> resId = jsObj->GetProperty("id");
5806 if (!resId->IsNumber()) {
5807 return false;
5808 }
5809
5810 auto resourceObject = GetResourceObject(jsObj);
5811 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5812 if (!resourceWrapper) {
5813 return false;
5814 }
5815
5816 auto resIdNum = resId->ToNumber<int32_t>();
5817 if (resIdNum == -1) {
5818 if (!IsGetResourceByName(jsObj)) {
5819 return false;
5820 }
5821 JSRef<JSVal> args = jsObj->GetProperty("params");
5822 if (!args->IsArray()) {
5823 return false;
5824 }
5825 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5826 auto param = params->GetValueAt(0);
5827 result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
5828 return true;
5829 }
5830 result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
5831 return true;
5832 }
5833
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5834 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
5835 {
5836 if (jsValue->IsString()) {
5837 result = jsValue->ToString();
5838 return true;
5839 }
5840
5841 if (!jsValue->IsObject()) {
5842 return false;
5843 }
5844
5845 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5846 CompleteResourceObject(jsObj);
5847
5848 JSRef<JSVal> resId = jsObj->GetProperty("id");
5849 if (!resId->IsNumber()) {
5850 return false;
5851 }
5852 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
5853 if (type == UNKNOWN_RESOURCE_TYPE) {
5854 return false;
5855 }
5856
5857 JSRef<JSVal> args = jsObj->GetProperty("params");
5858 if (!args->IsArray()) {
5859 return false;
5860 }
5861
5862 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5863 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5864 if (!resourceWrapper) {
5865 return false;
5866 }
5867
5868 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5869 auto resIdNum = resId->ToNumber<int32_t>();
5870 if (resIdNum == -1) {
5871 if (!IsGetResourceByName(jsObj)) {
5872 return false;
5873 }
5874 auto param = params->GetValueAt(0);
5875 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5876 auto originStr = resourceWrapper->GetStringByName(param->ToString());
5877 ReplaceHolder(originStr, params, 1);
5878 result = originStr;
5879 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5880 auto countJsVal = params->GetValueAt(1);
5881 int count = 0;
5882 if (!countJsVal->IsNumber()) {
5883 return false;
5884 }
5885 count = countJsVal->ToNumber<int>();
5886 auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
5887 ReplaceHolder(pluralStr, params, 2);
5888 result = pluralStr;
5889 } else {
5890 return false;
5891 }
5892 return true;
5893 }
5894 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5895 auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5896 ReplaceHolder(originStr, params, 0);
5897 result = originStr;
5898 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
5899 auto countJsVal = params->GetValueAt(0);
5900 int count = 0;
5901 if (!countJsVal->IsNumber()) {
5902 return false;
5903 }
5904 count = countJsVal->ToNumber<int>();
5905 auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
5906 ReplaceHolder(pluralStr, params, 1);
5907 result = pluralStr;
5908 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
5909 result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
5910 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
5911 result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
5912 } else {
5913 return false;
5914 }
5915 return true;
5916 }
5917
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5918 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
5919 {
5920 if (!jsValue->IsObject() && !jsValue->IsString()) {
5921 return false;
5922 }
5923 if (jsValue->IsString()) {
5924 result = jsValue->ToString();
5925 return true;
5926 }
5927 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5928 CompleteResourceObject(jsObj);
5929 return ParseJSMediaInternal(jsObj, result);
5930 }
5931
ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5932 bool JSViewAbstract::ParseJsMediaWithBundleName(
5933 const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId)
5934 {
5935 if (!jsValue->IsObject() && !jsValue->IsString()) {
5936 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5937 }
5938 if (jsValue->IsString()) {
5939 result = jsValue->ToString();
5940 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName);
5941 }
5942 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
5943 CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId);
5944 return ParseJSMediaInternal(jsObj, result);
5945 }
5946
ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5947 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result)
5948 {
5949 int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
5950 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
5951 if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
5952 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
5953 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
5954 CHECK_NULL_RETURN(resourceWrapper, false);
5955 if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
5956 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5957 if (!args->IsArray()) {
5958 return false;
5959 }
5960 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5961 auto fileName = params->GetValueAt(0);
5962 if (!fileName->IsString()) {
5963 return false;
5964 }
5965 result = resourceWrapper->GetRawfile(fileName->ToString());
5966 return true;
5967 }
5968 auto resIdNum = resId->ToNumber<int32_t>();
5969 if (resIdNum == -1) {
5970 if (!IsGetResourceByName(jsObj)) {
5971 return false;
5972 }
5973 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS));
5974 if (!args->IsArray()) {
5975 return false;
5976 }
5977 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
5978 auto param = params->GetValueAt(0);
5979 if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5980 result = resourceWrapper->GetMediaPathByName(param->ToString());
5981 return true;
5982 }
5983 if (type == static_cast<int32_t>(ResourceType::STRING)) {
5984 result = resourceWrapper->GetStringByName(param->ToString());
5985 return true;
5986 }
5987 return false;
5988 } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
5989 result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
5990 return true;
5991 } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
5992 result = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
5993 return true;
5994 }
5995 }
5996 return false;
5997 }
5998
SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5999 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply,
6000 const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj)
6001 {
6002 auto vm = info.GetVm();
6003 auto globalObj = JSNApi::GetGlobalObject(vm);
6004 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
6005 JsiValue jsiValue(globalFunc);
6006 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
6007 if (!globalFuncRef->IsFunction()) {
6008 return;
6009 }
6010 if (modifierNormalObj->IsUndefined()) {
6011 symbolApply.onApply = nullptr;
6012 } else {
6013 RefPtr<JsFunction> jsFunc =
6014 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
6015 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
6016 modifierNormal = std::move(modifierNormalObj),
6017 modifierSelected = std::move(modifierSelectedObj)](
6018 WeakPtr<NG::FrameNode> frameNode, std::string type) {
6019 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6020 auto node = frameNode.Upgrade();
6021 CHECK_NULL_VOID(node);
6022 JSRef<JSVal> params[SECOND_INDEX];
6023 if (type == "normal") {
6024 params[0] = modifierNormal;
6025 } else if (!modifierSelected->IsUndefined()) {
6026 params[0] = modifierSelected;
6027 }
6028 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
6029 PipelineContext::SetCallBackNode(node);
6030 func->ExecuteJS(SECOND_INDEX, params);
6031 };
6032 symbolApply.onApply = onApply;
6033 }
6034 }
6035
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)6036 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
6037 {
6038 if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
6039 return false;
6040 }
6041
6042 if (jsValue->IsBoolean()) {
6043 result = jsValue->ToBoolean();
6044 return true;
6045 }
6046
6047 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6048 CompleteResourceObject(jsObj);
6049 int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE);
6050 if (resType == UNKNOWN_RESOURCE_TYPE) {
6051 return false;
6052 }
6053
6054 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID));
6055 if (!resId->IsNumber()) {
6056 return false;
6057 }
6058
6059 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6060 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6061 if (!resourceWrapper) {
6062 return false;
6063 }
6064
6065 auto resIdNum = resId->ToNumber<int32_t>();
6066 if (resIdNum == -1) {
6067 if (!IsGetResourceByName(jsObj)) {
6068 return false;
6069 }
6070 JSRef<JSVal> args = jsObj->GetProperty("params");
6071 if (!args->IsArray()) {
6072 return false;
6073 }
6074 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6075 auto param = params->GetValueAt(0);
6076 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6077 result = resourceWrapper->GetBooleanByName(param->ToString());
6078 return true;
6079 }
6080 return false;
6081 }
6082
6083 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
6084 result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
6085 return true;
6086 }
6087 return false;
6088 }
6089
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)6090 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
6091 {
6092 return ParseJsInteger<uint32_t>(jsValue, result);
6093 }
6094
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)6095 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
6096 {
6097 return ParseJsInteger<int32_t>(jsValue, result);
6098 }
6099
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)6100 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
6101 {
6102 if (!jsValue->IsArray() && !jsValue->IsObject()) {
6103 return false;
6104 }
6105
6106 if (jsValue->IsArray()) {
6107 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6108 for (size_t i = 0; i < array->Length(); i++) {
6109 JSRef<JSVal> value = array->GetValueAt(i);
6110 if (value->IsNumber()) {
6111 result.emplace_back(value->ToNumber<uint32_t>());
6112 } else if (value->IsObject()) {
6113 uint32_t singleResInt;
6114 if (ParseJsInteger(value, singleResInt)) {
6115 result.emplace_back(singleResInt);
6116 } else {
6117 return false;
6118 }
6119 } else {
6120 return false;
6121 }
6122 }
6123 return true;
6124 }
6125
6126 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6127 CompleteResourceObject(jsObj);
6128 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6129 if (resType == UNKNOWN_RESOURCE_TYPE) {
6130 return false;
6131 }
6132
6133 JSRef<JSVal> resId = jsObj->GetProperty("id");
6134 if (!resId->IsNumber()) {
6135 return false;
6136 }
6137
6138 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6139 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6140 if (!resourceWrapper) {
6141 return false;
6142 }
6143
6144 auto resIdNum = resId->ToNumber<int32_t>();
6145 if (resIdNum == -1) {
6146 if (!IsGetResourceByName(jsObj)) {
6147 return false;
6148 }
6149 JSRef<JSVal> args = jsObj->GetProperty("params");
6150 if (!args->IsArray()) {
6151 return false;
6152 }
6153 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6154 auto param = params->GetValueAt(0);
6155 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6156 result = resourceWrapper->GetIntArrayByName(param->ToString());
6157 return true;
6158 }
6159 return false;
6160 }
6161
6162 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
6163 result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
6164 return true;
6165 }
6166 return false;
6167 }
6168
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)6169 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
6170 {
6171 if (!jsValue->IsArray() && !jsValue->IsObject()) {
6172 return false;
6173 }
6174
6175 if (jsValue->IsArray()) {
6176 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
6177 for (size_t i = 0; i < array->Length(); i++) {
6178 JSRef<JSVal> value = array->GetValueAt(i);
6179 if (value->IsString()) {
6180 result.emplace_back(value->ToString());
6181 } else if (value->IsObject()) {
6182 std::string singleResStr;
6183 if (ParseJsString(value, singleResStr)) {
6184 result.emplace_back(singleResStr);
6185 } else {
6186 return false;
6187 }
6188 } else {
6189 return false;
6190 }
6191 }
6192 return true;
6193 }
6194
6195 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
6196 CompleteResourceObject(jsObj);
6197 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
6198 if (resType == UNKNOWN_RESOURCE_TYPE) {
6199 return false;
6200 }
6201
6202 JSRef<JSVal> resId = jsObj->GetProperty("id");
6203 if (!resId->IsNumber()) {
6204 return false;
6205 }
6206
6207 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
6208 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
6209 if (!resourceWrapper) {
6210 return false;
6211 }
6212
6213 auto resIdNum = resId->ToNumber<int32_t>();
6214 if (resIdNum == -1) {
6215 if (!IsGetResourceByName(jsObj)) {
6216 return false;
6217 }
6218 JSRef<JSVal> args = jsObj->GetProperty("params");
6219 if (!args->IsArray()) {
6220 return false;
6221 }
6222 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6223 auto param = params->GetValueAt(0);
6224 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6225 result = resourceWrapper->GetStringArrayByName(param->ToString());
6226 return true;
6227 }
6228 return false;
6229 }
6230
6231 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
6232 result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
6233 return true;
6234 }
6235 return false;
6236 }
6237
IsGetResourceByName(const JSRef<JSObject> & jsObj)6238 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
6239 {
6240 JSRef<JSVal> resId = jsObj->GetProperty("id");
6241 if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
6242 return false;
6243 }
6244 JSRef<JSVal> args = jsObj->GetProperty("params");
6245 if (!args->IsArray()) {
6246 return false;
6247 }
6248 JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
6249 JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
6250 if (!bundleName->IsString() || !moduleName->IsString()) {
6251 return false;
6252 }
6253 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
6254 if (params->IsEmpty()) {
6255 return false;
6256 }
6257 return true;
6258 }
6259
ParseSize(const JSCallbackInfo & info)6260 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
6261 {
6262 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6263 auto jsVal = info[0];
6264 if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) {
6265 return std::pair<CalcDimension, CalcDimension>();
6266 }
6267 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal);
6268 CalcDimension width;
6269 CalcDimension height;
6270 if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
6271 !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
6272 return std::pair<CalcDimension, CalcDimension>();
6273 }
6274 return std::pair<CalcDimension, CalcDimension>(width, height);
6275 }
6276
JsUseAlign(const JSCallbackInfo & info)6277 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
6278 {
6279 if (info.Length() < 2) {
6280 return;
6281 }
6282
6283 if (!info[0]->IsObject() && !info[1]->IsObject()) {
6284 return;
6285 }
6286
6287 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
6288 if (declaration == nullptr) {
6289 return;
6290 }
6291
6292 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6293 JSRef<JSVal> side = obj->GetProperty("side");
6294 JSRef<JSVal> offset = obj->GetProperty("offset");
6295
6296 if (!side->IsNumber()) {
6297 return;
6298 }
6299
6300 auto sideValue = side->ToNumber<int32_t>();
6301
6302 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
6303 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
6304 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
6305 return;
6306 }
6307 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
6308 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
6309 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
6310 return;
6311 }
6312 }
6313
6314 std::optional<CalcDimension> optOffset;
6315 CalcDimension offsetDimension;
6316 if (ParseJsDimensionVp(offset, offsetDimension)) {
6317 optOffset = offsetDimension;
6318 }
6319 ViewAbstractModel::GetInstance()->SetUseAlign(
6320 declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
6321 }
6322
JsGridSpan(const JSCallbackInfo & info)6323 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
6324 {
6325 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6326 auto jsVal = info[0];
6327 if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) {
6328 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6329 ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt);
6330 }
6331 return;
6332 }
6333 auto span = jsVal->ToNumber<int32_t>();
6334 ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
6335 }
6336
JsGridOffset(const JSCallbackInfo & info)6337 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
6338 {
6339 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
6340 auto jsVal = info[0];
6341 if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) {
6342 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
6343 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET);
6344 }
6345 return;
6346 }
6347 auto offset = jsVal->ToNumber<int32_t>();
6348 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
6349 }
6350
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)6351 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
6352 {
6353 // {lg: 4}
6354 if (val->IsNumber()) {
6355 span = val->ToNumber<uint32_t>();
6356 return true;
6357 }
6358
6359 if (!val->IsObject()) {
6360 return false;
6361 }
6362
6363 // {lg: {span: 1, offset: 2}}
6364 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
6365 span = obj->GetProperty("span")->ToNumber<uint32_t>();
6366 offset = obj->GetProperty("offset")->ToNumber<int32_t>();
6367 return true;
6368 }
6369
JsUseSizeType(const JSCallbackInfo & info)6370 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
6371 {
6372 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6373 auto jsVal = info[0];
6374 if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) {
6375 return;
6376 }
6377 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal);
6378 for (auto values : SCREEN_SIZE_VALUES) {
6379 JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
6380 if (val->IsNull() || val->IsEmpty()) {
6381 continue;
6382 }
6383 uint32_t span = 0;
6384 int32_t offset = 0;
6385 if (ParseSpanAndOffset(val, span, offset)) {
6386 ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
6387 }
6388 }
6389 }
6390
JsZIndex(const JSCallbackInfo & info)6391 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
6392 {
6393 int zIndex = 0;
6394 if (info[0]->IsNumber()) {
6395 zIndex = info[0]->ToNumber<int>();
6396 }
6397
6398 ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
6399 }
6400
Pop()6401 void JSViewAbstract::Pop()
6402 {
6403 ViewStackModel::GetInstance()->Pop();
6404 }
6405
JsSetDraggable(bool draggable)6406 void JSViewAbstract::JsSetDraggable(bool draggable)
6407 {
6408 ViewAbstractModel::GetInstance()->SetDraggable(draggable);
6409 }
6410
ParseDragInteractionOptions(const JSCallbackInfo & info,NG::DragPreviewOption & previewOption)6411 void JSViewAbstract::ParseDragInteractionOptions(const JSCallbackInfo& info,
6412 NG::DragPreviewOption& previewOption)
6413 {
6414 if (info.Length() > 1 && info[1]->IsObject()) {
6415 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
6416 auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled");
6417 if (multiSelection->IsBoolean()) {
6418 previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean();
6419 }
6420 auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting");
6421 if (defaultAnimation->IsBoolean()) {
6422 previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean();
6423 }
6424 auto dragPreview = interObj->GetProperty("isDragPreviewEnabled");
6425 if (dragPreview->IsBoolean()) {
6426 previewOption.isDragPreviewEnabled = dragPreview->ToBoolean();
6427 }
6428 auto isLiftingDisabled = interObj->GetProperty("isLiftingDisabled");
6429 if (isLiftingDisabled->IsBoolean()) {
6430 previewOption.isLiftingDisabled = isLiftingDisabled->ToBoolean();
6431 }
6432 }
6433 }
6434
ParseDragPreviewOptions(const JSCallbackInfo & info)6435 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info)
6436 {
6437 NG::DragPreviewOption previewOption;
6438 if (!info[0]->IsObject()) {
6439 return previewOption;
6440 }
6441 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
6442 auto mode = obj->GetProperty("mode");
6443 bool isAuto = true;
6444 if (mode->IsNumber()) {
6445 ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto);
6446 } else if (mode->IsArray()) {
6447 JSRef<JSArray> array = JSRef<JSArray>::Cast(mode);
6448 for (size_t i = 0; i < array->Length(); i++) {
6449 JSRef<JSVal> value = array->GetValueAt(i);
6450 if (value->IsNumber()) {
6451 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto);
6452 }
6453 if (isAuto) {
6454 break;
6455 }
6456 }
6457 }
6458
6459 JSViewAbstract::SetDragNumberBadge(info, previewOption);
6460
6461 ParseDragInteractionOptions(info, previewOption);
6462
6463 JSViewAbstract::SetDragPreviewOptionApply(info, previewOption);
6464
6465 return previewOption;
6466 }
6467
JsSetDragPreviewOptions(const JSCallbackInfo & info)6468 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
6469 {
6470 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6471 auto jsVal = info[0];
6472 if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) {
6473 return;
6474 }
6475 NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info);
6476 ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption);
6477 }
6478
JsOnDragStart(const JSCallbackInfo & info)6479 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
6480 {
6481 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6482 auto jsVal = info[0];
6483 if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) {
6484 return;
6485 }
6486
6487 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6488
6489 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6490 auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
6491 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
6492 NG::DragDropBaseInfo dragDropInfo;
6493 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
6494 PipelineContext::SetCallBackNode(node);
6495 auto ret = func->Execute(info, extraParams);
6496 if (!ret->IsObject()) {
6497 return dragDropInfo;
6498 }
6499
6500 dragDropInfo.node = ParseDragNode(ret);
6501 auto builderObj = JSRef<JSObject>::Cast(ret);
6502 #if defined(PIXEL_MAP_SUPPORTED)
6503 auto pixmap = builderObj->GetProperty("pixelMap");
6504 dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
6505 #endif
6506 auto extraInfo = builderObj->GetProperty("extraInfo");
6507 ParseJsString(extraInfo, dragDropInfo.extraInfo);
6508 return dragDropInfo;
6509 };
6510 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
6511 }
6512
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)6513 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
6514 {
6515 auto node = ParseDragNode(info);
6516 if (!node) {
6517 return false;
6518 }
6519 dragInfo.node = node;
6520 return true;
6521 }
6522
ParseDragNode(const JSRef<JSVal> & info)6523 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
6524 {
6525 auto builderFunc = ParseDragStartBuilderFunc(info);
6526 if (!builderFunc) {
6527 return nullptr;
6528 }
6529 // use another VSP instance while executing the builder function
6530 ViewStackModel::GetInstance()->NewScope();
6531 {
6532 ACE_SCORING_EVENT("onDragStart.builder");
6533 builderFunc->Execute();
6534 }
6535
6536 return ViewStackModel::GetInstance()->Finish();
6537 }
6538
JsOnDragEnter(const JSCallbackInfo & info)6539 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
6540 {
6541 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6542 auto jsVal = info[0];
6543 if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) {
6544 return;
6545 }
6546 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6547 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6548 auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
6549 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6550 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6551 ACE_SCORING_EVENT("onDragEnter");
6552 PipelineContext::SetCallBackNode(node);
6553 func->Execute(info, extraParams);
6554 };
6555
6556 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
6557 }
6558
JsOnDragEnd(const JSCallbackInfo & info)6559 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
6560 {
6561 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6562 auto jsVal = info[0];
6563 if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) {
6564 return;
6565 }
6566 RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6567 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6568 auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
6569 const RefPtr<OHOS::Ace::DragEvent>& info) {
6570 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6571 ACE_SCORING_EVENT("onDragEnd");
6572 auto extraParams = JsonUtil::Create(true);
6573 PipelineContext::SetCallBackNode(node);
6574 func->Execute(info, extraParams->ToString());
6575 };
6576
6577 ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
6578 }
6579
JsOnDragMove(const JSCallbackInfo & info)6580 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
6581 {
6582 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6583 auto jsVal = info[0];
6584 if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) {
6585 return;
6586 }
6587 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6588 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6589 auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
6590 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6591 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6592 ACE_SCORING_EVENT("onDragMove");
6593 PipelineContext::SetCallBackNode(node);
6594 func->Execute(info, extraParams);
6595 };
6596
6597 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
6598 }
6599
JsOnDragLeave(const JSCallbackInfo & info)6600 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
6601 {
6602 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6603 auto jsVal = info[0];
6604 if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) {
6605 return;
6606 }
6607 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6608 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6609 auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
6610 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6611 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6612 ACE_SCORING_EVENT("onDragLeave");
6613 PipelineContext::SetCallBackNode(node);
6614 func->Execute(info, extraParams);
6615 };
6616
6617 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
6618 }
6619
JsOnDrop(const JSCallbackInfo & info)6620 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
6621 {
6622 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6623 auto jsVal = info[0];
6624 if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) {
6625 return;
6626 }
6627 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
6628 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6629 auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
6630 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
6631 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6632 ACE_SCORING_EVENT("onDrop");
6633 PipelineContext::SetCallBackNode(node);
6634 func->Execute(info, extraParams);
6635 };
6636
6637 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
6638
6639 bool disableDataPrefetch = false;
6640 if (info.Length() > 1 && info[1]->IsObject()) {
6641 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]);
6642 auto jsDisableDataPrefetch = interObj->GetProperty("disableDataPrefetch");
6643 if (jsDisableDataPrefetch->IsBoolean()) {
6644 disableDataPrefetch = jsDisableDataPrefetch->ToBoolean();
6645 }
6646 }
6647 ViewAbstractModel::GetInstance()->SetDisableDataPrefetch(disableDataPrefetch);
6648 }
6649
JsOnAreaChange(const JSCallbackInfo & info)6650 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
6651 {
6652 auto jsVal = info[0];
6653 if (jsVal->IsUndefined() && IsDisableEventVersion()) {
6654 ViewAbstractModel::GetInstance()->DisableOnAreaChange();
6655 return;
6656 }
6657 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6658 if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) {
6659 return;
6660 }
6661 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6662
6663 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6664 auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
6665 node = frameNode](
6666 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
6667 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6668 ACE_SCORING_EVENT("onAreaChange");
6669 PipelineContext::SetCallBackNode(node);
6670 func->Execute(oldRect, oldOrigin, rect, origin);
6671 };
6672 ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
6673 }
6674
JsOnSizeChange(const JSCallbackInfo & info)6675 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info)
6676 {
6677 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
6678 auto jsVal = info[0];
6679 if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) {
6680 return;
6681 }
6682 auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal));
6683
6684 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6685 auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction),
6686 node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) {
6687 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6688 ACE_SCORING_EVENT("onSizeChange");
6689 PipelineContext::SetCallBackNode(node);
6690 func->Execute(oldRect, rect);
6691 };
6692 ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged));
6693 }
6694
6695 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)6696 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
6697 {
6698 if (info.Length() < 2) {
6699 return;
6700 }
6701 if ((!info[0]->IsBoolean() && !info[0]->IsObject()) || !info[1]->IsObject()) {
6702 return;
6703 }
6704 auto popupParam = AceType::MakeRefPtr<PopupParam>();
6705 // Set IsShow to popupParam
6706 if (info[0]->IsBoolean()) {
6707 popupParam->SetIsShow(info[0]->ToBoolean());
6708 } else {
6709 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
6710 auto callback = ParseDoubleBindCallback(info, showObj);
6711 popupParam->SetOnStateChange(std::move(callback));
6712 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
6713 }
6714 // Set popup to popupParam
6715 auto popupObj = JSRef<JSObject>::Cast(info[1]);
6716 SetPopupDismiss(info, popupObj, popupParam);
6717 if (popupObj->GetProperty("message")->IsString()) {
6718 ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
6719 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6720 } else if (!popupObj->GetProperty("builder").IsEmpty()) {
6721 ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
6722 auto builderValue = popupObj->GetProperty("builder");
6723 auto builder = builderValue;
6724 if (!builderValue->IsObject()) {
6725 return;
6726 }
6727 if (!builderValue->IsFunction()) {
6728 JSRef<JSObject> builderObj;
6729 builderObj = JSRef<JSObject>::Cast(builderValue);
6730 builder = builderObj->GetProperty("builder");
6731 if (!builder->IsFunction()) {
6732 return;
6733 }
6734 }
6735 if (popupParam->IsShow() && !IsPopupCreated()) {
6736 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
6737 CHECK_NULL_VOID(builderFunc);
6738 ViewStackModel::GetInstance()->NewScope();
6739 builderFunc->Execute();
6740 auto customNode = ViewStackModel::GetInstance()->Finish();
6741 ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
6742 } else {
6743 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
6744 }
6745 } else {
6746 return;
6747 }
6748 }
6749
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)6750 void JSViewAbstract::SetPopupDismiss(
6751 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
6752 {
6753 auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
6754 if (onWillDismissFunc->IsBoolean()) {
6755 bool onWillDismissBool = onWillDismissFunc->ToBoolean();
6756 popupParam->SetInteractiveDismiss(onWillDismissBool);
6757 popupParam->SetOnWillDismiss(nullptr);
6758 if (onWillDismissBool) {
6759 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6760 }
6761 } else if (onWillDismissFunc->IsFunction()) {
6762 auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
6763 popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
6764 popupParam->SetInteractiveDismiss(true);
6765 if (onWillDismissCallback != nullptr) {
6766 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
6767 }
6768 }
6769 }
6770
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)6771 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
6772 {
6773 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6774 if (!onWillDismissFunc->IsFunction()) {
6775 return PopupOnWillDismiss();
6776 }
6777 RefPtr<JsFunction> jsFunc =
6778 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6779 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
6780 auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
6781 node = frameNode](int32_t reason) {
6782 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6783 ACE_SCORING_EVENT("Bindpopup.dismiss");
6784 PipelineContext::SetCallBackNode(node);
6785
6786 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6787 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6788 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6789 dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
6790 dismissObj->SetProperty<int32_t>("reason", reason);
6791 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6792
6793 func->ExecuteJS(1, &newJSVal);
6794 };
6795 return onWillDismiss;
6796 }
6797
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)6798 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6799 {
6800 ViewAbstractModel::GetInstance()->DismissPopup();
6801 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6802 }
6803 #endif
6804
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info)> & onWillDismiss)6805 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
6806 std::function<void(const int32_t& info)>& onWillDismiss)
6807 {
6808 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
6809 if (onWillDismissFunc->IsFunction()) {
6810 auto jsFunc =
6811 AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
6812 onWillDismiss = [func = std::move(jsFunc)](const int32_t& info) {
6813 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6814 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
6815 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6816 dismissObj->SetPropertyObject(
6817 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
6818 dismissObj->SetProperty<int32_t>("reason", info);
6819 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6820 func->ExecuteJS(1, &newJSVal);
6821 };
6822 }
6823 }
6824
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)6825 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6826 {
6827 ViewAbstractModel::GetInstance()->DismissDialog();
6828 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6829 }
6830
JsLinearGradient(const JSCallbackInfo & info)6831 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
6832 {
6833 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6834 auto jsVal = info[0];
6835 if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) {
6836 NG::Gradient newGradient;
6837 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6838 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6839 return;
6840 }
6841 NG::Gradient newGradient;
6842 NewJsLinearGradient(info, newGradient);
6843 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
6844 }
6845
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6846 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6847 {
6848 if (!info[0]->IsObject()) {
6849 return;
6850 }
6851 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
6852 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
6853 // angle
6854 std::optional<float> degree;
6855 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6856 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree);
6857 } else {
6858 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f);
6859 }
6860 if (degree) {
6861 newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
6862 degree.reset();
6863 }
6864 // direction
6865 auto direction = static_cast<GradientDirection>(
6866 jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
6867 switch (direction) {
6868 case GradientDirection::LEFT:
6869 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6870 break;
6871 case GradientDirection::RIGHT:
6872 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6873 break;
6874 case GradientDirection::TOP:
6875 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6876 break;
6877 case GradientDirection::BOTTOM:
6878 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6879 break;
6880 case GradientDirection::LEFT_TOP:
6881 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6882 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6883 break;
6884 case GradientDirection::LEFT_BOTTOM:
6885 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
6886 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6887 break;
6888 case GradientDirection::RIGHT_TOP:
6889 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6890 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
6891 break;
6892 case GradientDirection::RIGHT_BOTTOM:
6893 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
6894 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
6895 break;
6896 case GradientDirection::NONE:
6897 case GradientDirection::START_TO_END:
6898 case GradientDirection::END_TO_START:
6899 default:
6900 break;
6901 }
6902 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6903 newGradient.SetRepeat(repeating);
6904 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6905 }
6906
JsRadialGradient(const JSCallbackInfo & info)6907 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
6908 {
6909 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6910 auto jsVal = info[0];
6911 if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) {
6912 NG::Gradient newGradient;
6913 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6914 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6915 return;
6916 }
6917 NG::Gradient newGradient;
6918 NewJsRadialGradient(info, newGradient);
6919 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
6920 }
6921
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6922 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6923 {
6924 JSRef<JSVal> arg = info[0];
6925 if (!arg->IsObject()) {
6926 return;
6927 }
6928 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6929 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
6930 // center
6931 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6932 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6933 CalcDimension value;
6934 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6935 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6936 newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
6937 if (value.Unit() == DimensionUnit::PERCENT) {
6938 // [0,1] -> [0, 100]
6939 newGradient.GetRadialGradient()->radialCenterX =
6940 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6941 }
6942 }
6943 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
6944 newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
6945 if (value.Unit() == DimensionUnit::PERCENT) {
6946 // [0,1] -> [0, 100]
6947 newGradient.GetRadialGradient()->radialCenterY =
6948 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6949 }
6950 }
6951 }
6952 // radius
6953 CalcDimension radius;
6954 if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) {
6955 newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
6956 newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
6957 }
6958 // repeating
6959 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
6960 newGradient.SetRepeat(repeating);
6961 // color stops
6962 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
6963 }
6964
JsSweepGradient(const JSCallbackInfo & info)6965 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
6966 {
6967 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
6968 auto jsVal = info[0];
6969 if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) {
6970 NG::Gradient newGradient;
6971 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6972 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6973 return;
6974 }
6975
6976 NG::Gradient newGradient;
6977 NewJsSweepGradient(info, newGradient);
6978 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
6979 }
6980
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6981 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
6982 {
6983 JSRef<JSVal> arg = info[0];
6984 if (!arg->IsObject()) {
6985 return;
6986 }
6987 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg);
6988 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
6989 // center
6990 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER));
6991 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
6992 CalcDimension value;
6993 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
6994 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
6995 newGradient.GetSweepGradient()->centerX = CalcDimension(value);
6996 if (value.Unit() == DimensionUnit::PERCENT) {
6997 // [0,1] -> [0, 100]
6998 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
6999 }
7000 }
7001 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
7002 newGradient.GetSweepGradient()->centerY = CalcDimension(value);
7003 if (value.Unit() == DimensionUnit::PERCENT) {
7004 // [0,1] -> [0, 100]
7005 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
7006 }
7007 }
7008 }
7009 // start, end and rotation
7010 ParseSweepGradientPartly(jsObj, newGradient);
7011 // repeating
7012 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
7013 newGradient.SetRepeat(repeating);
7014 // color stops
7015 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS)));
7016 }
7017
ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)7018 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient)
7019 {
7020 std::optional<float> degreeStart;
7021 std::optional<float> degreeEnd;
7022 std::optional<float> degreeRotation;
7023 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7024 GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart);
7025 GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd);
7026 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation);
7027 } else {
7028 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f);
7029 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f);
7030 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f);
7031 }
7032 if (degreeStart) {
7033 CheckAngle(degreeStart);
7034 newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX);
7035 }
7036 if (degreeEnd) {
7037 CheckAngle(degreeEnd);
7038 newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX);
7039 }
7040 if (degreeRotation) {
7041 CheckAngle(degreeRotation);
7042 newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX);
7043 }
7044 }
7045
JsMotionPath(const JSCallbackInfo & info)7046 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
7047 {
7048 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
7049 auto jsVal = info[0];
7050 if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) {
7051 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
7052 return;
7053 }
7054 MotionPathOption motionPathOption;
7055 if (ParseMotionPath(jsVal, motionPathOption)) {
7056 ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
7057 } else {
7058 TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str());
7059 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
7060 }
7061 }
7062
JsShadow(const JSCallbackInfo & info)7063 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
7064 {
7065 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
7066 auto jsVal = info[0];
7067 if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) {
7068 Shadow shadow;
7069 std::vector<Shadow> shadows { shadow };
7070 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
7071 return;
7072 }
7073 Shadow shadow;
7074 if (!ParseShadowProps(jsVal, shadow)) {
7075 info.ReturnSelf();
7076 return;
7077 }
7078 std::vector<Shadow> shadows { shadow };
7079 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
7080 }
7081
JsBlendMode(const JSCallbackInfo & info)7082 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
7083 {
7084 if (info.Length() == 0) {
7085 return;
7086 }
7087 BlendMode blendMode = BlendMode::NONE;
7088 BlendApplyType blendApplyType = BlendApplyType::FAST;
7089 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7090 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7091 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7092 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7093 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7094 if (info[0]->IsNumber()) {
7095 auto blendModeNum = info[0]->ToNumber<int32_t>();
7096 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7097 blendMode = static_cast<BlendMode>(blendModeNum);
7098 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7099 // backward compatibility code, will remove soon
7100 blendMode = BlendMode::SRC_OVER;
7101 blendApplyType = BlendApplyType::OFFSCREEN;
7102 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7103 // backward compatibility code, will remove soon
7104 blendMode = BlendMode::SRC_IN;
7105 blendApplyType = BlendApplyType::OFFSCREEN;
7106 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7107 // backward compatibility code, will remove soon
7108 blendMode = BlendMode::DST_IN;
7109 blendApplyType = BlendApplyType::OFFSCREEN;
7110 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7111 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7112 }
7113 }
7114 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7115 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7116 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7117 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7118 }
7119 }
7120 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7121 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7122 }
7123
JsAdvancedBlendMode(const JSCallbackInfo & info)7124 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info)
7125 {
7126 if (info.Length() == 0) {
7127 return;
7128 }
7129 BlendMode blendMode = BlendMode::NONE;
7130 BlendApplyType blendApplyType = BlendApplyType::FAST;
7131 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
7132 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
7133 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000;
7134 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000;
7135 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000;
7136 if (info[0]->IsNumber()) {
7137 auto blendModeNum = info[0]->ToNumber<int32_t>();
7138 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) {
7139 blendMode = static_cast<BlendMode>(blendModeNum);
7140 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
7141 // backward compatibility code, will remove soon
7142 blendMode = BlendMode::SRC_OVER;
7143 blendApplyType = BlendApplyType::OFFSCREEN;
7144 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) {
7145 // backward compatibility code, will remove soon
7146 blendMode = BlendMode::SRC_IN;
7147 blendApplyType = BlendApplyType::OFFSCREEN;
7148 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) {
7149 // backward compatibility code, will remove soon
7150 blendMode = BlendMode::DST_IN;
7151 blendApplyType = BlendApplyType::OFFSCREEN;
7152 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) {
7153 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN;
7154 }
7155 } else if (info[0]->IsObject()) {
7156 auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]);
7157 ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender);
7158 }
7159 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7160 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
7161 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) {
7162 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
7163 }
7164 }
7165 if (!info[0]->IsObject()) {
7166 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
7167 }
7168 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
7169 }
7170
JsGrayScale(const JSCallbackInfo & info)7171 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
7172 {
7173 CalcDimension value;
7174 if (!ParseJsDimensionVp(info[0], value)) {
7175 value.SetValue(0.0);
7176 ViewAbstractModel::GetInstance()->SetGrayScale(value);
7177 return;
7178 }
7179
7180 if (LessNotEqual(value.Value(), 0.0)) {
7181 value.SetValue(0.0);
7182 }
7183
7184 if (GreatNotEqual(value.Value(), 1.0)) {
7185 value.SetValue(1.0);
7186 }
7187
7188 ViewAbstractModel::GetInstance()->SetGrayScale(value);
7189 }
7190
JsBrightness(const JSCallbackInfo & info)7191 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
7192 {
7193 CalcDimension value;
7194 if (!ParseJsDimensionVp(info[0], value)) {
7195 value.SetValue(1.0);
7196 ViewAbstractModel::GetInstance()->SetBrightness(value);
7197 return;
7198 }
7199
7200 ViewAbstractModel::GetInstance()->SetBrightness(value);
7201 }
7202
JsContrast(const JSCallbackInfo & info)7203 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
7204 {
7205 CalcDimension value;
7206 if (!ParseJsDimensionVp(info[0], value)) {
7207 value.SetValue(1.0);
7208 ViewAbstractModel::GetInstance()->SetContrast(value);
7209 return;
7210 }
7211
7212 if (LessNotEqual(value.Value(), 0.0)) {
7213 value.SetValue(0.0);
7214 }
7215
7216 ViewAbstractModel::GetInstance()->SetContrast(value);
7217 }
7218
JsSaturate(const JSCallbackInfo & info)7219 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
7220 {
7221 CalcDimension value;
7222 if (!ParseJsDimensionVp(info[0], value)) {
7223 value.SetValue(1.0);
7224 ViewAbstractModel::GetInstance()->SetSaturate(value);
7225 return;
7226 }
7227
7228 if (LessNotEqual(value.Value(), 0.0)) {
7229 value.SetValue(0.0);
7230 }
7231
7232 ViewAbstractModel::GetInstance()->SetSaturate(value);
7233 }
7234
JsSepia(const JSCallbackInfo & info)7235 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
7236 {
7237 CalcDimension value;
7238 if (!ParseJsDimensionVp(info[0], value)) {
7239 value.SetValue(0.0);
7240 ViewAbstractModel::GetInstance()->SetSepia(value);
7241 return;
7242 }
7243
7244 if (LessNotEqual(value.Value(), 0.0)) {
7245 value.SetValue(0.0);
7246 }
7247
7248 ViewAbstractModel::GetInstance()->SetSepia(value);
7249 }
7250
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)7251 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
7252 {
7253 double invertValue = 0.0;
7254 if (ParseJsDouble(jsValue, invertValue)) {
7255 invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
7256 return true;
7257 }
7258 auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
7259 if (!argsPtrItem || argsPtrItem->IsNull()) {
7260 return false;
7261 }
7262 InvertOption option;
7263 double low = 0.0;
7264 if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
7265 option.low_ = std::clamp(low, 0.0, 1.0);
7266 }
7267 double high = 0.0;
7268 if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
7269 option.high_ = std::clamp(high, 0.0, 1.0);
7270 }
7271 double threshold = 0.0;
7272 if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
7273 option.threshold_ = std::clamp(threshold, 0.0, 1.0);
7274 }
7275 double thresholdRange = 0.0;
7276 if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
7277 option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
7278 }
7279 invert = option;
7280 return true;
7281 }
7282
JsInvert(const JSCallbackInfo & info)7283 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
7284 {
7285 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
7286 InvertVariant invert = 0.0f;
7287 auto jsVal = info[0];
7288 if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) {
7289 ViewAbstractModel::GetInstance()->SetInvert(invert);
7290 return;
7291 }
7292 if (ParseInvertProps(jsVal, invert)) {
7293 ViewAbstractModel::GetInstance()->SetInvert(invert);
7294 }
7295 ViewAbstractModel::GetInstance()->SetInvert(invert);
7296 }
7297
JsSystemBarEffect(const JSCallbackInfo & info)7298 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
7299 {
7300 ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
7301 }
7302
JsHueRotate(const JSCallbackInfo & info)7303 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
7304 {
7305 std::optional<float> degree;
7306 JSRef<JSVal> arg = info[0];
7307 if (arg->IsString()) {
7308 degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
7309 } else if (arg->IsNumber()) {
7310 degree = static_cast<float>(arg->ToNumber<int32_t>());
7311 } else {
7312 ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
7313 return;
7314 }
7315 float deg = 0.0f;
7316 if (degree) {
7317 deg = degree.value();
7318 degree.reset();
7319 }
7320 deg = std::fmod(deg, ROUND_UNIT);
7321 if (deg < 0.0f) {
7322 deg += ROUND_UNIT;
7323 }
7324 ViewAbstractModel::GetInstance()->SetHueRotate(deg);
7325 }
7326
JsClip(const JSCallbackInfo & info)7327 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
7328 {
7329 JSRef<JSVal> arg = info[0];
7330 if (arg->IsUndefined()) {
7331 ViewAbstractModel::GetInstance()->SetClipEdge(false);
7332 return;
7333 }
7334 if (arg->IsObject()) {
7335 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7336 if (clipShape == nullptr) {
7337 return;
7338 }
7339 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7340 } else if (arg->IsBoolean()) {
7341 ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
7342 }
7343 }
7344
JsClipShape(const JSCallbackInfo & info)7345 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info)
7346 {
7347 if (info[0]->IsObject()) {
7348 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7349 if (clipShape == nullptr) {
7350 return;
7351 }
7352 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
7353 }
7354 }
7355
JsMask(const JSCallbackInfo & info)7356 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
7357 {
7358 JSRef<JSVal> arg = info[0];
7359 if (!arg->IsObject()) {
7360 ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
7361 return;
7362 }
7363 auto paramObject = JSRef<JSObject>::Cast(arg);
7364 JSRef<JSVal> typeParam = paramObject->GetProperty("type");
7365 if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
7366 typeParam->ToString() == "ProgressMask") {
7367 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
7368 JSRef<JSVal> jValue = paramObject->GetProperty("value");
7369 auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
7370 if (value < 0.0f) {
7371 value = 0.0f;
7372 }
7373 progressMask->SetValue(value);
7374 JSRef<JSVal> jTotal = paramObject->GetProperty("total");
7375 auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
7376 if (total < 0.0f) {
7377 total = DEFAULT_PROGRESS_TOTAL;
7378 }
7379 progressMask->SetMaxValue(total);
7380 JSRef<JSVal> jColor = paramObject->GetProperty("color");
7381 Color colorVal;
7382 if (ParseJsColor(jColor, colorVal)) {
7383 progressMask->SetColor(colorVal);
7384 } else {
7385 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
7386 progressMask->SetColor(theme->GetMaskColor());
7387 }
7388 JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe");
7389 if (jEnableBreathe->IsBoolean()) {
7390 progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean());
7391 }
7392 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
7393 } else {
7394 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
7395 if (maskShape == nullptr) {
7396 return;
7397 };
7398 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7399 }
7400 }
7401
JsMaskShape(const JSCallbackInfo & info)7402 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info)
7403 {
7404 if (!info[0]->IsObject()) {
7405 return;
7406 }
7407
7408 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>();
7409 if (maskShape == nullptr) {
7410 return;
7411 };
7412 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
7413 }
7414
JsFocusable(const JSCallbackInfo & info)7415 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
7416 {
7417 if (!info[0]->IsBoolean()) {
7418 return;
7419 }
7420 ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
7421 }
7422
JsTabStop(const JSCallbackInfo & info)7423 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info)
7424 {
7425 if (!info[0]->IsBoolean()) {
7426 ViewAbstractModel::GetInstance()->SetTabStop(false);
7427 return;
7428 }
7429 ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean());
7430 }
7431
JsFocusBox(const JSCallbackInfo & info)7432 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info)
7433 {
7434 if (!info[0]->IsObject() || info.Length() != 1) {
7435 return;
7436 }
7437 auto obj = JSRef<JSObject>::Cast(info[0]);
7438 NG::FocusBoxStyle style;
7439
7440 CalcDimension margin;
7441 if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) {
7442 style.margin = margin;
7443 }
7444 CalcDimension strokeWidth;
7445 if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) {
7446 style.strokeWidth = strokeWidth;
7447 }
7448 Color strokeColor;
7449 if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) {
7450 style.strokeColor = strokeColor;
7451 }
7452
7453 ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style);
7454 }
7455
JsOnFocusMove(const JSCallbackInfo & args)7456 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
7457 {
7458 JSRef<JSVal> arg = args[0];
7459 if (arg->IsFunction()) {
7460 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7461 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7462 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
7463 int info) {
7464 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7465 ACE_SCORING_EVENT("onFocusMove");
7466 PipelineContext::SetCallBackNode(node);
7467 func->Execute(info);
7468 };
7469 ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
7470 }
7471 }
7472
JsOnKeyEvent(const JSCallbackInfo & args)7473 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
7474 {
7475 JSRef<JSVal> arg = args[0];
7476 if (arg->IsUndefined() && IsDisableEventVersion()) {
7477 ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
7478 return;
7479 }
7480 if (!arg->IsFunction()) {
7481 return;
7482 }
7483 RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
7484 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7485 auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
7486 KeyEventInfo& info) -> bool {
7487 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
7488 ACE_SCORING_EVENT("onKey");
7489 PipelineContext::SetCallBackNode(node);
7490 auto ret = func->ExecuteWithValue(info);
7491 return ret->IsBoolean() ? ret->ToBoolean() : false;
7492 };
7493 ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
7494 }
7495
JsDispatchKeyEvent(const JSCallbackInfo & args)7496 void JSViewAbstract::JsDispatchKeyEvent(const JSCallbackInfo& args)
7497 {
7498 JSRef<JSVal> arg = args[0];
7499 if (!(arg->IsNumber() || arg->IsString())) {
7500 return;
7501 }
7502 RefPtr<NG::FrameNode> frameNode = nullptr;
7503 if (arg->IsString()) {
7504 std::string id = arg->ToString();
7505 frameNode = NG::Inspector::GetFrameNodeByKey(id);
7506 }
7507
7508 if (arg->IsNumber()) {
7509 auto id = arg->ToNumber<int32_t>();
7510 auto node = ElementRegister::GetInstance()->GetNodeById(id);
7511 frameNode = AceType::DynamicCast<NG::FrameNode>(node);
7512 }
7513 CHECK_NULL_VOID(frameNode);
7514 auto focusHub = frameNode->GetOrCreateFocusHub();
7515 CHECK_NULL_VOID(focusHub);
7516
7517 if (!(args[1]->IsObject())) {
7518 return;
7519 }
7520 JSRef<JSObject> jsObject = JSRef<JSObject>::Cast(args[1]);
7521 auto eventInfoPtr = jsObject->Unwrap<KeyEventInfo>();
7522 CHECK_NULL_VOID(eventInfoPtr);
7523 KeyEvent keyEvent;
7524 eventInfoPtr->ParseKeyEvent(keyEvent);
7525 auto result = focusHub->HandleEvent(keyEvent);
7526 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
7527 }
7528
JsOnFocus(const JSCallbackInfo & args)7529 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
7530 {
7531 JSRef<JSVal> arg = args[0];
7532 if (arg->IsUndefined() && IsDisableEventVersion()) {
7533 ViewAbstractModel::GetInstance()->DisableOnFocus();
7534 return;
7535 }
7536 if (!arg->IsFunction()) {
7537 return;
7538 }
7539 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7540 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7541 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
7542 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7543 ACE_SCORING_EVENT("onFocus");
7544 PipelineContext::SetCallBackNode(node);
7545 func->Execute();
7546 };
7547
7548 ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
7549 }
7550
JsOnBlur(const JSCallbackInfo & args)7551 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
7552 {
7553 JSRef<JSVal> arg = args[0];
7554 if (arg->IsUndefined() && IsDisableEventVersion()) {
7555 ViewAbstractModel::GetInstance()->DisableOnBlur();
7556 return;
7557 }
7558 if (!arg->IsFunction()) {
7559 return;
7560 }
7561 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
7562 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7563 auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
7564 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7565 ACE_SCORING_EVENT("onBlur");
7566 PipelineContext::SetCallBackNode(node);
7567 func->Execute();
7568 };
7569
7570 ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
7571 }
7572
JsTabIndex(const JSCallbackInfo & info)7573 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
7574 {
7575 JSRef<JSVal> arg = info[0];
7576 if (!arg->IsNumber()) {
7577 return;
7578 }
7579 ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
7580 }
7581
JsFocusOnTouch(const JSCallbackInfo & info)7582 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
7583 {
7584 JSRef<JSVal> arg = info[0];
7585 if (!arg->IsBoolean()) {
7586 return;
7587 }
7588 auto isFocusOnTouch = arg->ToBoolean();
7589 ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
7590 }
7591
JsDefaultFocus(const JSCallbackInfo & info)7592 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
7593 {
7594 JSRef<JSVal> arg = info[0];
7595 if (!arg->IsBoolean()) {
7596 return;
7597 }
7598 auto isDefaultFocus = arg->ToBoolean();
7599 ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
7600 }
7601
JsGroupDefaultFocus(const JSCallbackInfo & info)7602 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
7603 {
7604 JSRef<JSVal> arg = info[0];
7605 if (!arg->IsBoolean()) {
7606 return;
7607 }
7608 auto isGroupDefaultFocus = arg->ToBoolean();
7609 ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
7610 }
7611
JsKey(const std::string & key)7612 void JSViewAbstract::JsKey(const std::string& key)
7613 {
7614 ViewAbstractModel::GetInstance()->SetInspectorId(key);
7615 }
7616
JsId(const JSCallbackInfo & info)7617 void JSViewAbstract::JsId(const JSCallbackInfo& info)
7618 {
7619 JSRef<JSVal> arg = info[0];
7620 if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
7621 return;
7622 }
7623 std::string id = arg->ToString();
7624 if (id.empty()) {
7625 return;
7626 }
7627 JsKey(id);
7628 }
7629
JsRestoreId(int32_t restoreId)7630 void JSViewAbstract::JsRestoreId(int32_t restoreId)
7631 {
7632 ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
7633 }
7634
JsDebugLine(const JSCallbackInfo & info)7635 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
7636 {
7637 std::string debugLine;
7638 auto length = info.Length();
7639 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
7640
7641 if (length == 1) { // deprecated version of debug line
7642 auto jsVal = info[0];
7643 if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) {
7644 return;
7645 }
7646 debugLine = jsVal->ToString();
7647 } else if (length == 2) { // debug line with extra package name
7648 auto line = info[0];
7649 auto packageName = info[1];
7650 if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) ||
7651 !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) {
7652 return;
7653 }
7654 auto json = JsonUtil::Create(true);
7655 json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str());
7656 json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str());
7657 debugLine = json->ToString();
7658 }
7659
7660 ViewAbstractModel::GetInstance()->SetDebugLine(debugLine);
7661 }
7662
JsOpacityPassThrough(const JSCallbackInfo & info)7663 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
7664 {
7665 double opacity = 1.0;
7666 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7667 if (ParseJsDouble(info[0], opacity)) {
7668 opacity = std::clamp(opacity, 0.0, 1.0);
7669 }
7670 } else {
7671 if (!ParseJsDouble(info[0], opacity)) {
7672 return;
7673 }
7674 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
7675 opacity = 1.0;
7676 }
7677 }
7678
7679 ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
7680 }
7681
JsTransitionPassThrough(const JSCallbackInfo & info)7682 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
7683 {
7684 if (info.Length() == 0) {
7685 ViewAbstractModel::GetInstance()->SetTransition(
7686 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
7687 return;
7688 }
7689 if (!info[0]->IsObject()) {
7690 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
7691 ViewAbstractModel::GetInstance()->CleanTransition();
7692 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr);
7693 }
7694 return;
7695 }
7696 auto obj = JSRef<JSObject>::Cast(info[0]);
7697 if (!obj->GetProperty("successor_")->IsUndefined()) {
7698 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
7699 std::function<void(bool)> finishCallback;
7700 if (info.Length() > 1 && info[1]->IsFunction()) {
7701 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext());
7702 }
7703 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback));
7704 return;
7705 }
7706 auto options = ParseJsTransition(obj);
7707 ViewAbstractModel::GetInstance()->SetTransition(options, true);
7708 }
7709
JsAccessibilityGroup(const JSCallbackInfo & info)7710 void JSViewAbstract::JsAccessibilityGroup(const JSCallbackInfo& info)
7711 {
7712 bool isGroup = false;
7713 if (info[0]->IsBoolean()) {
7714 isGroup = info[0]->ToBoolean();
7715 }
7716 ViewAbstractModel::GetInstance()->SetAccessibilityGroup(isGroup);
7717
7718 if (info.Length() > 1 && info[1]->IsObject()) {
7719 auto obj = JSRef<JSObject>::Cast(info[1]);
7720
7721 auto preferAccessibilityTextObj = obj->GetProperty("accessibilityPreferred");
7722 auto preferAccessibilityText = preferAccessibilityTextObj->IsBoolean() ? preferAccessibilityTextObj->ToBoolean() : false;
7723 ViewAbstractModel::GetInstance()->SetAccessibilityTextPreferred(preferAccessibilityText);
7724 }
7725 }
7726
JsAccessibilityText(const JSCallbackInfo & info)7727 void JSViewAbstract::JsAccessibilityText(const JSCallbackInfo& info)
7728 {
7729 const JSRef<JSVal>& jsValue = info[0];
7730 std::string text;
7731 if (!ParseJsString(jsValue, text)) {
7732 return;
7733 }
7734 ViewAbstractModel::GetInstance()->SetAccessibilityText(text);
7735 }
7736
JsAccessibilityTextHint(const std::string & text)7737 void JSViewAbstract::JsAccessibilityTextHint(const std::string& text)
7738 {
7739 ViewAbstractModel::GetInstance()->SetAccessibilityTextHint(text);
7740 }
7741
JsAccessibilityDescription(const JSCallbackInfo & info)7742 void JSViewAbstract::JsAccessibilityDescription(const JSCallbackInfo& info)
7743 {
7744 const JSRef<JSVal>& jsValue = info[0];
7745 std::string description;
7746 if (!ParseJsString(jsValue, description)) {
7747 return;
7748 }
7749 std::pair<bool, std::string> autoEventPair(false, "");
7750 std::pair<bool, std::string> descriptionPair(false, "");
7751 ParseAccessibilityDescriptionJson(description, autoEventPair, descriptionPair);
7752 if (descriptionPair.first) {
7753 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(descriptionPair.second);
7754 } else {
7755 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description);
7756 }
7757 if (autoEventPair.first) {
7758 ViewAbstractModel::GetInstance()->SetAutoEventParam(autoEventPair.second);
7759 }
7760 }
7761
ParseAccessibilityDescriptionJson(const std::string & description,std::pair<bool,std::string> & autoEventPair,std::pair<bool,std::string> & descriptionPair)7762 void JSViewAbstract::ParseAccessibilityDescriptionJson(const std::string& description,
7763 std::pair<bool, std::string>& autoEventPair, std::pair<bool, std::string>& descriptionPair)
7764 {
7765 if (description.empty()) {
7766 return;
7767 }
7768 if (!StartWith(description, "{") || !EndWith(description, "}")) {
7769 return;
7770 }
7771 auto jsonObj = JsonUtil::ParseJsonString(description);
7772 if (!jsonObj || !jsonObj->IsValid() || !jsonObj->IsObject()) {
7773 return;
7774 }
7775 if (jsonObj->Contains("$autoEventParam")) {
7776 auto param = jsonObj->GetValue("$autoEventParam");
7777 if (param) {
7778 autoEventPair = std::make_pair(true, param->ToString());
7779 }
7780 }
7781 if (jsonObj->Contains("$accessibilityDescription")) {
7782 descriptionPair = std::make_pair(true, jsonObj->GetString("$accessibilityDescription"));
7783 } else if (jsonObj->Contains("$autoEventParam")) {
7784 descriptionPair = std::make_pair(true, "");
7785 }
7786 }
7787
JsAccessibilityImportance(const std::string & importance)7788 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
7789 {
7790 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance);
7791 }
7792
JsAccessibilityLevel(const std::string & level)7793 void JSViewAbstract::JsAccessibilityLevel(const std::string& level)
7794 {
7795 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level);
7796 }
7797
JsAccessibilityVirtualNode(const JSCallbackInfo & info)7798 void JSViewAbstract::JsAccessibilityVirtualNode(const JSCallbackInfo& info)
7799 {
7800 // parse builder
7801 if (!info[0]->IsObject()) {
7802 return;
7803 }
7804 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7805 auto builder = obj->GetProperty("builder");
7806 if (builder->IsFunction()) {
7807 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7808 CHECK_NULL_VOID(builderFunc);
7809 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
7810 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7811 ACE_SCORING_EVENT("AccessibilityVirtualNode");
7812 func->Execute();
7813 };
7814 NG::ViewAbstractModelNG::GetInstance()->SetAccessibilityVirtualNode(std::move(buildFunc));
7815 }
7816 }
7817
JsAccessibilitySelected(const JSCallbackInfo & info)7818 void JSViewAbstract::JsAccessibilitySelected(const JSCallbackInfo& info)
7819 {
7820 bool selected = false;
7821 bool resetValue = false;
7822 JSRef<JSVal> arg = info[0];
7823 if (arg->IsUndefined()) {
7824 resetValue = true;
7825 } else if (arg->IsBoolean()) {
7826 selected = arg->ToBoolean();
7827 } else {
7828 return;
7829 }
7830
7831 ViewAbstractModel::GetInstance()->SetAccessibilitySelected(selected, resetValue);
7832 }
7833
JsAccessibilityChecked(const JSCallbackInfo & info)7834 void JSViewAbstract::JsAccessibilityChecked(const JSCallbackInfo& info)
7835 {
7836 bool checked = false;
7837 bool resetValue = false;
7838 JSRef<JSVal> arg = info[0];
7839 if (arg->IsUndefined()) {
7840 resetValue = true;
7841 } else if (arg->IsBoolean()) {
7842 checked = arg->ToBoolean();
7843 } else {
7844 return;
7845 }
7846
7847 ViewAbstractModel::GetInstance()->SetAccessibilityChecked(checked, resetValue);
7848 }
7849
JsBackground(const JSCallbackInfo & info)7850 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
7851 {
7852 // Check the parameters
7853 if (info.Length() <= 0 || !info[0]->IsObject()) {
7854 return;
7855 }
7856 JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
7857 auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
7858 if (!builder->IsFunction()) {
7859 return;
7860 }
7861 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7862 CHECK_NULL_VOID(builderFunc);
7863 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7864 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7865 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7866 ACE_SCORING_EVENT("BindBackground");
7867 PipelineContext::SetCallBackNode(node);
7868 func->Execute();
7869 };
7870 Alignment alignment = Alignment::CENTER;
7871 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
7872 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
7873 auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN));
7874 auto value = align->ToNumber<int32_t>();
7875 alignment = ParseAlignment(value);
7876 }
7877 ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
7878 }
7879
JsBindContextMenu(const JSCallbackInfo & info)7880 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
7881 {
7882 NG::MenuParam menuParam;
7883 // Check the parameters
7884 if (info.Length() <= 0) {
7885 return;
7886 }
7887 size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
7888 if (!info[builderIndex]->IsObject()) {
7889 return;
7890 }
7891
7892 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
7893 auto builder = menuObj->GetProperty("builder");
7894 if (!builder->IsFunction()) {
7895 return;
7896 }
7897 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7898 CHECK_NULL_VOID(builderFunc);
7899
7900 ResponseType responseType = ResponseType::LONG_PRESS;
7901 if (!info[0]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
7902 auto response = info[1]->ToNumber<int32_t>();
7903 responseType = static_cast<ResponseType>(response);
7904 }
7905 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7906 std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
7907 node = frameNode]() {
7908 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7909 ACE_SCORING_EVENT("BuildContextMenu");
7910 PipelineContext::SetCallBackNode(node);
7911 func->Execute();
7912 };
7913
7914 menuParam.previewMode = MenuPreviewMode::NONE;
7915 std::function<void()> previewBuildFunc = nullptr;
7916 if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) {
7917 ParseBindContentOptionParam(info, info[2], menuParam, previewBuildFunc);
7918 }
7919
7920 if (responseType != ResponseType::LONG_PRESS) {
7921 menuParam.previewMode = MenuPreviewMode::NONE;
7922 menuParam.isShowHoverImage = false;
7923 menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
7924 }
7925 menuParam.type = NG::MenuType::CONTEXT_MENU;
7926 ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
7927 ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
7928 }
7929
ParseBindContentCoverIsShow(const JSCallbackInfo & info)7930 bool ParseBindContentCoverIsShow(const JSCallbackInfo& info)
7931 {
7932 bool isShow = false;
7933 if (info[0]->IsBoolean()) {
7934 isShow = info[0]->ToBoolean();
7935 } else if (info[0]->IsObject()) {
7936 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7937 auto isShowObj = callbackObj->GetProperty("value");
7938 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
7939 }
7940 TAG_LOGD(AceLogTag::ACE_SHEET, "ContentCover get isShow is: %{public}d", isShow);
7941 return isShow;
7942 }
7943
JsBindContentCover(const JSCallbackInfo & info)7944 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
7945 {
7946 // parse isShow
7947 bool isShow = ParseBindContentCoverIsShow(info);
7948 DoubleBindCallback callback = nullptr;
7949 if (info[0]->IsObject()) {
7950 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
7951 callback = ParseDoubleBindCallback(info, callbackObj);
7952 }
7953
7954 // parse builder
7955 if (!info[1]->IsObject()) {
7956 return;
7957 }
7958 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
7959 auto builder = obj->GetProperty("builder");
7960 if (!builder->IsFunction()) {
7961 return;
7962 }
7963 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
7964 CHECK_NULL_VOID(builderFunc);
7965 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
7966 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
7967 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7968 ACE_SCORING_EVENT("BindContentCover");
7969 PipelineContext::SetCallBackNode(node);
7970 func->Execute();
7971 };
7972
7973 // parse ModalTransition
7974 NG::ModalStyle modalStyle;
7975 modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
7976 std::function<void()> onShowCallback;
7977 std::function<void()> onDismissCallback;
7978 std::function<void()> onWillShowCallback;
7979 std::function<void()> onWillDismissCallback;
7980 NG::ContentCoverParam contentCoverParam;
7981 std::function<void(const int32_t&)> onWillDismissFunc;
7982 if (info.Length() == 3) {
7983 if (info[2]->IsObject()) {
7984 ParseOverlayCallback(info[2], onShowCallback, onDismissCallback, onWillShowCallback, /* 2:args index */
7985 onWillDismissCallback, onWillDismissFunc);
7986 ParseModalStyle(info[2], modalStyle);
7987 contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
7988 ParseModalTransitonEffect(info[2], contentCoverParam, info.GetExecutionContext()); /* 2:args index */
7989 } else if (info[2]->IsNumber()) {
7990 auto transitionNumber = info[2]->ToNumber<int32_t>();
7991 if (transitionNumber >= 0 && transitionNumber <= 2) {
7992 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
7993 }
7994 }
7995 }
7996 ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
7997 std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
7998 std::move(onWillDismissCallback), contentCoverParam);
7999 }
8000
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)8001 void JSViewAbstract::ParseModalTransitonEffect(
8002 const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
8003 {
8004 auto transitionEffectValue = paramObj->GetProperty("transition");
8005 if (transitionEffectValue->IsObject()) {
8006 JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
8007 contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
8008 }
8009 }
8010
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)8011 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
8012 {
8013 auto modalTransition = paramObj->GetProperty("modalTransition");
8014 auto backgroundColor = paramObj->GetProperty("backgroundColor");
8015 if (modalTransition->IsNumber()) {
8016 auto transitionNumber = modalTransition->ToNumber<int32_t>();
8017 if (transitionNumber >= 0 && transitionNumber <= 2) {
8018 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
8019 }
8020 }
8021 Color color;
8022 if (ParseJsColor(backgroundColor, color)) {
8023 modalStyle.backgroundColor = color;
8024 }
8025 }
8026
ParseSheetIsShow(const JSCallbackInfo & info,bool & isShow,std::function<void (const std::string &)> & callback)8027 void JSViewAbstract::ParseSheetIsShow(
8028 const JSCallbackInfo& info, bool& isShow, std::function<void(const std::string&)>& callback)
8029 {
8030 if (info[0]->IsBoolean()) {
8031 isShow = info[0]->ToBoolean();
8032 } else if (info[0]->IsObject()) {
8033 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
8034 callback = ParseDoubleBindCallback(info, callbackObj);
8035 auto isShowObj = callbackObj->GetProperty("value");
8036 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
8037 }
8038 TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet get isShow is: %{public}d", isShow);
8039 }
8040
JsBindSheet(const JSCallbackInfo & info)8041 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
8042 {
8043 // parse isShow and builder
8044 bool isShow = false;
8045 DoubleBindCallback callback = nullptr;
8046 ParseSheetIsShow(info, isShow, callback);
8047 if (!info[1]->IsObject())
8048 return;
8049 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8050 auto builder = obj->GetProperty("builder");
8051 if (!builder->IsFunction())
8052 return;
8053 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
8054 CHECK_NULL_VOID(builderFunc);
8055 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8056 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
8057 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8058 ACE_SCORING_EVENT("BindSheet");
8059 PipelineContext::SetCallBackNode(node);
8060 func->Execute();
8061 };
8062 // parse SheetStyle and callbacks
8063 NG::SheetStyle sheetStyle;
8064 sheetStyle.sheetHeight.sheetMode = NG::SheetMode::LARGE;
8065 sheetStyle.showDragBar = true;
8066 sheetStyle.showCloseIcon = true;
8067 sheetStyle.showInPage = false;
8068 std::function<void()> onAppearCallback;
8069 std::function<void()> onDisappearCallback;
8070 std::function<void()> onWillAppearCallback;
8071 std::function<void()> onWillDisappearCallback ;
8072 std::function<void()> shouldDismissFunc;
8073 std::function<void(const int32_t)> onWillDismissCallback;
8074 std::function<void(const float)> onHeightDidChangeCallback;
8075 std::function<void(const float)> onDetentsDidChangeCallback;
8076 std::function<void(const float)> onWidthDidChangeCallback;
8077 std::function<void(const float)> onTypeDidChangeCallback;
8078 std::function<void()> titleBuilderFunction;
8079 std::function<void()> sheetSpringBackFunc;
8080 if (info.Length() == PARAMETER_LENGTH_THIRD && info[SECOND_INDEX]->IsObject()) {
8081 ParseSheetCallback(info[SECOND_INDEX], onAppearCallback, onDisappearCallback, shouldDismissFunc,
8082 onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
8083 onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
8084 ParseSheetStyle(info[2], sheetStyle);
8085 ParseSheetTitle(info[2], sheetStyle, titleBuilderFunction);
8086 }
8087 ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
8088 std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
8089 std::move(shouldDismissFunc), std::move(onWillDismissCallback), std::move(onWillAppearCallback),
8090 std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
8091 std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
8092 }
8093
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)8094 void JSViewAbstract::ParseSheetStyle(
8095 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
8096 {
8097 auto height = paramObj->GetProperty("height");
8098 auto showDragBar = paramObj->GetProperty("dragBar");
8099 auto backgroundColor = paramObj->GetProperty("backgroundColor");
8100 auto maskColor = paramObj->GetProperty("maskColor");
8101 auto sheetDetents = paramObj->GetProperty("detents");
8102 auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
8103 auto showCloseIcon = paramObj->GetProperty("showClose");
8104 auto type = paramObj->GetProperty("preferType");
8105 auto interactive = paramObj->GetProperty("enableOutsideInteractive");
8106 auto showMode = paramObj->GetProperty("mode");
8107 auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
8108 auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
8109 auto uiContextObj = paramObj->GetProperty("uiContext");
8110 if (uiContextObj->IsObject()) {
8111 JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
8112 auto prop = obj->GetProperty("instanceId_");
8113 if (prop->IsNumber()) {
8114 sheetStyle.instanceId = prop->ToNumber<int32_t>();
8115 }
8116 }
8117 NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
8118 if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
8119 sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
8120 }
8121
8122 std::vector<NG::SheetHeight> detents;
8123 if (ParseSheetDetents(sheetDetents, detents)) {
8124 sheetStyle.detents = detents;
8125 }
8126 BlurStyleOption styleOption;
8127 if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
8128 sheetStyle.backgroundBlurStyle = styleOption;
8129 }
8130 bool showClose = true;
8131 if (ParseJsBool(showCloseIcon, showClose)) {
8132 sheetStyle.showCloseIcon = showClose;
8133 } else if (!isPartialUpdate) {
8134 sheetStyle.showCloseIcon = true;
8135 }
8136
8137 bool isInteractive = false;
8138 if (ParseJsBool(interactive, isInteractive)) {
8139 sheetStyle.interactive = isInteractive;
8140 }
8141
8142 if (showDragBar->IsBoolean()) {
8143 sheetStyle.showDragBar = showDragBar->ToBoolean();
8144 } else if (isPartialUpdate) {
8145 sheetStyle.showDragBar.reset();
8146 } else {
8147 sheetStyle.showDragBar = true;
8148 }
8149
8150 if (type->IsNull() || type->IsUndefined()) {
8151 sheetStyle.sheetType.reset();
8152 } else {
8153 if (type->IsNumber()) {
8154 auto sheetType = type->ToNumber<int32_t>();
8155 if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
8156 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
8157 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
8158 }
8159 }
8160 }
8161 if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
8162 sheetStyle.scrollSizeMode.reset();
8163 } else if (scrollSizeMode->IsNumber()) {
8164 auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
8165 if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
8166 sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
8167 sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
8168 }
8169 }
8170
8171 if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
8172 sheetStyle.sheetKeyboardAvoidMode.reset();
8173 } else if (keyboardAvoidMode->IsNumber()) {
8174 auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
8175 if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
8176 sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) {
8177 sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
8178 }
8179 }
8180
8181 Color color;
8182 if (ParseJsColor(backgroundColor, color)) {
8183 sheetStyle.backgroundColor = color;
8184 }
8185 // parse maskColor
8186 Color parseMaskColor;
8187 if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
8188 sheetStyle.maskColor = std::move(parseMaskColor);
8189 }
8190
8191 // Parse border width
8192 auto borderWidthValue = paramObj->GetProperty("borderWidth");
8193 NG::BorderWidthProperty borderWidth;
8194 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
8195 sheetStyle.borderWidth = borderWidth;
8196 // Parse border color
8197 auto colorValue = paramObj->GetProperty("borderColor");
8198 NG::BorderColorProperty borderColor;
8199 if (ParseBorderColorProps(colorValue, borderColor)) {
8200 sheetStyle.borderColor = borderColor;
8201 } else {
8202 sheetStyle.borderColor =
8203 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
8204 }
8205 // Parse border style
8206 auto styleValue = paramObj->GetProperty("borderStyle");
8207 NG::BorderStyleProperty borderStyle;
8208 if (ParseBorderStyleProps(styleValue, borderStyle)) {
8209 sheetStyle.borderStyle = borderStyle;
8210 } else {
8211 sheetStyle.borderStyle = NG::BorderStyleProperty(
8212 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
8213 }
8214 }
8215 if (isPartialUpdate) {
8216 auto colorValue = paramObj->GetProperty("borderColor");
8217 NG::BorderColorProperty borderColor;
8218 if (ParseBorderColorProps(colorValue, borderColor)) {
8219 sheetStyle.borderColor = borderColor;
8220 } else {
8221 sheetStyle.borderColor.reset();
8222 }
8223 auto styleValue = paramObj->GetProperty("borderStyle");
8224 NG::BorderStyleProperty borderStyle;
8225 if (ParseBorderStyleProps(styleValue, borderStyle)) {
8226 sheetStyle.borderStyle = borderStyle;
8227 } else {
8228 sheetStyle.borderStyle.reset();
8229 }
8230 }
8231
8232 // Parse shadow
8233 Shadow shadow;
8234 auto shadowValue = paramObj->GetProperty("shadow");
8235 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
8236 sheetStyle.shadow = shadow;
8237 }
8238
8239 // Parse hoverMode
8240 auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode");
8241 if (enableHoverModeValue->IsBoolean()) {
8242 sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean();
8243 }
8244 auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea");
8245 if (hoverModeAreaValue->IsNumber()) {
8246 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
8247 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
8248 sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
8249 }
8250 }
8251
8252 auto widthValue = paramObj->GetProperty("width");
8253 CalcDimension width;
8254 if (ParseJsDimensionVpNG(widthValue, width, true)) {
8255 sheetStyle.width = width;
8256 }
8257
8258 auto radiusValue = paramObj->GetProperty("radius");
8259 ParseBindSheetBorderRadius(radiusValue, sheetStyle);
8260
8261 ParseDetentSelection(paramObj, sheetStyle);
8262
8263 NG::SheetHeight sheetStruct;
8264 bool parseResult = ParseSheetHeight(height, sheetStruct, isPartialUpdate);
8265 if (!parseResult) {
8266 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet height in unnormal condition");
8267 }
8268 sheetStyle.sheetHeight = sheetStruct;
8269 }
8270
ParseDetentSelection(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)8271 void JSViewAbstract::ParseDetentSelection(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
8272 {
8273 auto detentSelection = paramObj->GetProperty("detentSelection");
8274 NG::SheetHeight sheetStruct;
8275 bool parseResult = ParseSheetHeight(detentSelection, sheetStruct, true);
8276 if (!parseResult) {
8277 sheetStruct.height.reset();
8278 sheetStruct.sheetMode.reset();
8279 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent selection in unnormal condition");
8280 }
8281 sheetStyle.detentSelection = sheetStruct;
8282 }
8283
ParseBindSheetBorderRadius(const JSRef<JSVal> & args,NG::SheetStyle & sheetStyle)8284 void JSViewAbstract::ParseBindSheetBorderRadius(const JSRef<JSVal>& args, NG::SheetStyle& sheetStyle)
8285 {
8286 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
8287 TAG_LOGE(AceLogTag::ACE_SHEET, "radius is not correct type");
8288 return;
8289 }
8290 CalcDimension radius;
8291 NG::BorderRadiusProperty borderRadius;
8292 if (ParseJsLengthMetrics(args, radius)) {
8293 borderRadius.SetRadius(radius);
8294 sheetStyle.radius = borderRadius;
8295 } else if (ParseBindSheetBorderRadiusProps(args, borderRadius)) {
8296 sheetStyle.radius = borderRadius;
8297 } else {
8298 TAG_LOGW(AceLogTag::ACE_SHEET, "radius is not correct.");
8299 return;
8300 }
8301 }
8302
ParseBindSheetBorderRadiusProps(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)8303 bool JSViewAbstract::ParseBindSheetBorderRadiusProps(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
8304 {
8305 if (args->IsObject()) {
8306 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
8307 if (CheckLengthMetrics(object)) {
8308 std::optional<CalcDimension> radiusTopStart = ParseBindSheetBorderRadiusProp(object, TOP_START_PROPERTY);
8309 std::optional<CalcDimension> radiusTopEnd = ParseBindSheetBorderRadiusProp(object, TOP_END_PROPERTY);
8310 std::optional<CalcDimension> radiusBottomStart = ParseBindSheetBorderRadiusProp(object, BOTTOM_START_PROPERTY);
8311 std::optional<CalcDimension> radiusBottomEnd = ParseBindSheetBorderRadiusProp(object, BOTTOM_END_PROPERTY);
8312 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
8313 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
8314 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
8315 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
8316 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
8317 radius.multiValued = true;
8318 } else {
8319 ParseBorderRadiusProps(object, radius);
8320 }
8321 return true;
8322 }
8323 return false;
8324 }
8325
ParseBindSheetBorderRadiusProp(const JSRef<JSObject> & object,const char * prop)8326 std::optional<CalcDimension> JSViewAbstract::ParseBindSheetBorderRadiusProp(
8327 const JSRef<JSObject>& object, const char* prop)
8328 {
8329 if (object->IsEmpty()) {
8330 return std::nullopt;
8331 }
8332 if (object->HasProperty(prop) && object->GetProperty(prop)->IsObject()) {
8333 JSRef<JSObject> propObj = JSRef<JSObject>::Cast(object->GetProperty(prop));
8334 CalcDimension calcDimension;
8335 if (ParseJsLengthMetrics(propObj, calcDimension)) {
8336 return calcDimension;
8337 }
8338 }
8339 return std::nullopt;
8340 }
8341
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)8342 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
8343 {
8344 if (!args->IsArray()) {
8345 return false;
8346 }
8347 JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
8348 NG::SheetHeight sheetDetent;
8349 for (size_t i = 0; i < array->Length(); i++) {
8350 bool parseResult = ParseSheetHeight(array->GetValueAt(i), sheetDetent, false);
8351 if (!parseResult) {
8352 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent in unnormal condition");
8353 }
8354 if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
8355 continue;
8356 }
8357 sheetDetents.emplace_back(sheetDetent);
8358 sheetDetent.height.reset();
8359 sheetDetent.sheetMode.reset();
8360 }
8361 return true;
8362 }
8363
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)8364 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
8365 {
8366 if (args->IsNumber()) {
8367 auto sheetBlurStyle = args->ToNumber<int32_t>();
8368 if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
8369 sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
8370 blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
8371 } else {
8372 return false;
8373 }
8374 } else {
8375 return false;
8376 }
8377 return true;
8378 }
8379
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)8380 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
8381 {
8382 if (!args->IsNumber()) {
8383 return false;
8384 }
8385 auto sheetMode = args->ToNumber<int32_t>();
8386 if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
8387 sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
8388 sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
8389 return true;
8390 }
8391 return false;
8392 }
8393
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)8394 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
8395 std::function<void(const float)>& callbackDidChange, const char* prop)
8396 {
8397 auto callBack = paramObj->GetProperty(prop);
8398 if (callBack->IsFunction()) {
8399 RefPtr<JsFunction> jsFunc =
8400 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
8401 callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
8402 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
8403 func->ExecuteJS(1, ¶m);
8404 };
8405 }
8406 }
8407
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)8408 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
8409 std::function<void()>& lifeCycleCallBack, const char* prop)
8410 {
8411 auto callback = paramObj->GetProperty(prop);
8412 if (callback->IsFunction()) {
8413 RefPtr<JsFunction> jsFunc =
8414 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8415 lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
8416 }
8417 }
8418
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)8419 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
8420 std::function<void()>& sheetSpringBack, const char* prop)
8421 {
8422 auto sheetSpringBackCallback = paramObj->GetProperty(prop);
8423 if (sheetSpringBackCallback->IsFunction()) {
8424 RefPtr<JsFunction> jsFunc =
8425 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
8426 sheetSpringBack = [func = std::move(jsFunc)]() {
8427 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8428 objectTemplate->SetInternalFieldCount(1);
8429 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8430 dismissObj->SetPropertyObject(
8431 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
8432 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8433 func->ExecuteJS(1, &newJSVal);
8434 };
8435 }
8436 }
8437
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)8438 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8439 std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
8440 std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
8441 std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
8442 std::function<void(const float)>& onDetentsDidChange,
8443 std::function<void(const float)>& onWidthDidChange,
8444 std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
8445 {
8446 auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
8447 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8448 ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
8449 ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
8450 ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
8451 ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
8452 if (shouldDismissFunc->IsFunction()) {
8453 RefPtr<JsFunction> jsFunc =
8454 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
8455 shouldDismiss = [func = std::move(jsFunc)]() {
8456 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8457 objectTemplate->SetInternalFieldCount(1);
8458 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8459 dismissObj->SetPropertyObject(
8460 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8461 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8462 func->ExecuteJS(1, &newJSVal);
8463 };
8464 }
8465 if (onWillDismissFunc->IsFunction()) {
8466 RefPtr<JsFunction> jsFunc =
8467 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8468 onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
8469 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8470 objectTemplate->SetInternalFieldCount(1);
8471 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8472 dismissObj->SetPropertyObject(
8473 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
8474 dismissObj->SetProperty<int32_t>("reason", info);
8475 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8476 func->ExecuteJS(1, &newJSVal);
8477 };
8478 }
8479 ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
8480 ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
8481 ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
8482 ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
8483 ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
8484 }
8485
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)8486 void JSViewAbstract::ParseSheetTitle(
8487 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
8488 {
8489 auto title = paramObj->GetProperty("title");
8490 std::string mainTitle;
8491 std::string subtitle;
8492 if (title->IsFunction()) {
8493 sheetStyle.isTitleBuilder = true;
8494 auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
8495 CHECK_NULL_VOID(titleBuilderFunc);
8496 titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
8497 ACE_SCORING_EVENT("BindSheet");
8498 func->Execute();
8499 };
8500 } else if (title->IsObject()) {
8501 JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
8502 sheetStyle.isTitleBuilder = false;
8503 auto sheetTitle = obj->GetProperty("title");
8504 auto sheetSubtitle = obj->GetProperty("subtitle");
8505 if (ParseJsString(sheetTitle, mainTitle)) {
8506 sheetStyle.sheetTitle = mainTitle;
8507 }
8508 if (ParseJsString(sheetSubtitle, subtitle)) {
8509 sheetStyle.sheetSubtitle = subtitle;
8510 }
8511 }
8512 }
8513
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)8514 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8515 {
8516 ViewAbstractModel::GetInstance()->DismissSheet();
8517 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8518 }
8519
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)8520 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8521 {
8522 ViewAbstractModel::GetInstance()->DismissContentCover();
8523 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8524 }
8525
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)8526 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
8527 {
8528 ViewAbstractModel::GetInstance()->SheetSpringBack();
8529 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
8530 }
8531
ParseSheetMode(const std::string heightStr,NG::SheetHeight & detent)8532 bool JSViewAbstract::ParseSheetMode(const std::string heightStr, NG::SheetHeight& detent)
8533 {
8534 if (heightStr == SHEET_HEIGHT_MEDIUM) {
8535 detent.sheetMode = NG::SheetMode::MEDIUM;
8536 return true;
8537 }
8538
8539 if (heightStr == SHEET_HEIGHT_LARGE) {
8540 detent.sheetMode = NG::SheetMode::LARGE;
8541 return true;
8542 }
8543 if (heightStr == SHEET_HEIGHT_FITCONTENT) {
8544 detent.sheetMode = NG::SheetMode::AUTO;
8545 return true;
8546 }
8547 return false;
8548 }
8549
ParseSheetHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent,bool isReset)8550 bool JSViewAbstract::ParseSheetHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent,
8551 bool isReset)
8552 {
8553 detent.height.reset();
8554 detent.sheetMode.reset();
8555 CalcDimension sheetHeight;
8556 if (args->IsString()) {
8557 std::string heightStr = args->ToString();
8558
8559 // Remove all " ".
8560 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
8561 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
8562 if (ParseSheetMode(heightStr, detent)) {
8563 return true;
8564 }
8565 if (heightStr.find("calc") != std::string::npos) {
8566 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
8567 } else {
8568 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
8569 }
8570 if (sheetHeight.Value() < 0) {
8571 detent.sheetMode = NG::SheetMode::LARGE;
8572 return false;
8573 }
8574 }
8575 if (!ParseJsDimensionVpNG(args, sheetHeight)) {
8576 if (!isReset) {
8577 detent.sheetMode = NG::SheetMode::LARGE;
8578 }
8579 return false;
8580 }
8581 detent.height = sheetHeight;
8582 return true;
8583 }
8584
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)8585 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
8586 std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
8587 std::function<void(const int32_t& info)>& onWillDismiss)
8588 {
8589 auto showCallback = paramObj->GetProperty("onAppear");
8590 auto dismissCallback = paramObj->GetProperty("onDisappear");
8591 auto willShowCallback = paramObj->GetProperty("onWillAppear");
8592 auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
8593 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
8594 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8595 if (showCallback->IsFunction()) {
8596 RefPtr<JsFunction> jsFunc =
8597 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
8598 onAppear = [func = std::move(jsFunc), node = frameNode]() {
8599 PipelineContext::SetCallBackNode(node);
8600 func->Execute();
8601 };
8602 }
8603 if (dismissCallback->IsFunction()) {
8604 RefPtr<JsFunction> jsFunc =
8605 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
8606 onDisappear = [func = std::move(jsFunc), node = frameNode]() {
8607 PipelineContext::SetCallBackNode(node);
8608 func->Execute();
8609 };
8610 }
8611 if (willShowCallback->IsFunction()) {
8612 RefPtr<JsFunction> jsFunc =
8613 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
8614 onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
8615 }
8616 if (willDismissCallback->IsFunction()) {
8617 RefPtr<JsFunction> jsFunc =
8618 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
8619 onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
8620 }
8621 if (onWillDismissFunc->IsFunction()) {
8622 RefPtr<JsFunction> jsFunc =
8623 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
8624 onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
8625 ACE_SCORING_EVENT("contentCover.dismiss");
8626 PipelineContext::SetCallBackNode(node);
8627 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
8628 objectTemplate->SetInternalFieldCount(1);
8629 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
8630 dismissObj->SetPropertyObject(
8631 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
8632 dismissObj->SetProperty<int32_t>("reason", info);
8633 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
8634 func->ExecuteJS(1, &newJSVal);
8635 };
8636 }
8637 }
8638
JSCreateAnimatableProperty(const JSCallbackInfo & info)8639 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
8640 {
8641 if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
8642 return;
8643 }
8644
8645 JSRef<JSVal> callback = info[2]; /* 2:args index */
8646 if (!callback->IsFunction()) {
8647 return;
8648 }
8649 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
8650 std::string propertyName = info[0]->ToString();
8651 if (info[1]->IsNumber()) {
8652 float numValue = info[1]->ToNumber<float>();
8653 std::function<void(float)> onCallbackEvent;
8654 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8655 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8656 node = frameNode](const float val) {
8657 ContainerScope scope(id);
8658 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8659 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
8660 PipelineContext::SetCallBackNode(node);
8661 func->ExecuteJS(1, &newJSVal);
8662 };
8663 ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
8664 } else if (info[1]->IsObject()) {
8665 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8666 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8667 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8668 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8669 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8670 std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
8671 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
8672 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
8673 node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
8674 ContainerScope scope(id);
8675 RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
8676 if (!impl) {
8677 return;
8678 }
8679 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
8680 auto newJSVal = JSRef<JSVal>(impl->GetObject());
8681 PipelineContext::SetCallBackNode(node);
8682 func->ExecuteJS(1, &newJSVal);
8683 };
8684 ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
8685 propertyName, animatableArithmetic, onCallbackEvent);
8686 }
8687 }
8688
JSUpdateAnimatableProperty(const JSCallbackInfo & info)8689 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
8690 {
8691 if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
8692 return;
8693 }
8694
8695 std::string propertyName = info[0]->ToString();
8696 float numValue = 0.0;
8697 if (info[1]->IsNumber()) {
8698 numValue = info[1]->ToNumber<float>();
8699 ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
8700 } else if (info[1]->IsObject()) {
8701 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
8702 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
8703 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
8704 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
8705 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
8706 ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
8707 }
8708 }
8709
JsExpandSafeArea(const JSCallbackInfo & info)8710 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
8711 {
8712 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
8713 if (info.Length() >= 1 && info[0]->IsArray()) {
8714 auto paramArray = JSRef<JSArray>::Cast(info[0]);
8715 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
8716 for (size_t i = 0; i < paramArray->Length(); ++i) {
8717 if (!paramArray->GetValueAt(i)->IsNumber() ||
8718 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
8719 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
8720 break;
8721 }
8722 safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8723 }
8724 opts.type = safeAreaType;
8725 }
8726 if (info.Length() >= 2 && info[1]->IsArray()) {
8727 auto paramArray = JSRef<JSArray>::Cast(info[1]);
8728 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
8729 for (size_t i = 0; i < paramArray->Length(); ++i) {
8730 if (!paramArray->GetValueAt(i)->IsNumber() ||
8731 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
8732 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
8733 break;
8734 }
8735 safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
8736 }
8737 opts.edges = safeAreaEdge;
8738 }
8739
8740 ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
8741 }
8742
ParseJSLightSource(JSRef<JSObject> & lightSource)8743 void ParseJSLightSource(JSRef<JSObject>& lightSource)
8744 {
8745 if (lightSource->IsUndefined()) {
8746 return;
8747 }
8748 JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
8749 JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
8750 JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
8751 JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
8752 JSRef<JSVal> color = lightSource->GetProperty("color");
8753
8754 CalcDimension dimPositionX;
8755 CalcDimension dimPositionY;
8756 CalcDimension dimPositionZ;
8757 if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) &&
8758 JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) &&
8759 JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) {
8760 ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
8761 }
8762
8763 if (intensity->IsNumber()) {
8764 float intensityValue = intensity->ToNumber<float>();
8765 ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
8766 }
8767
8768 Color lightColor;
8769 if (JSViewAbstract::ParseJsColor(color, lightColor)) {
8770 ViewAbstractModel::GetInstance()->SetLightColor(lightColor);
8771 }
8772 }
8773
JsPointLight(const JSCallbackInfo & info)8774 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
8775 {
8776 #ifdef POINT_LIGHT_ENABLE
8777 if (!info[0]->IsObject()) {
8778 return;
8779 }
8780
8781 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
8782 JSRef<JSObject> lightSource = object->GetProperty("lightSource");
8783 ParseJSLightSource(lightSource);
8784
8785 auto resourceWrapper = CreateResourceWrapper();
8786 if (!resourceWrapper) {
8787 return;
8788 }
8789 double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
8790 Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
8791 Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
8792
8793 JSRef<JSVal> illuminated = object->GetProperty("illuminated");
8794 if (illuminated->IsNumber()) {
8795 uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
8796 ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
8797 ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
8798 }
8799
8800 JSRef<JSVal> bloom = object->GetProperty("bloom");
8801 if (bloom->IsNumber()) {
8802 float bloomValue = bloom->ToNumber<float>();
8803 ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
8804
8805 Shadow shadow;
8806 shadow.SetBlurRadius(bloomValue * bloomRadius);
8807 shadow.SetColor(bloomColor);
8808 std::vector<Shadow> shadows { shadow };
8809 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
8810 }
8811 #endif
8812 }
8813
JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)8814 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info)
8815 {
8816 if (info[0]->IsBoolean()) {
8817 ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean());
8818 }
8819 }
8820
JsCancelDataLoading(const std::string & key)8821 void JSViewAbstract::JsCancelDataLoading(const std::string& key)
8822 {
8823 auto ret = ViewAbstractModel::GetInstance()->CancelDataLoading(key);
8824 if (ret != 0) {
8825 JSException::Throw(ERROR_CODE_PARAM_INVALID, "%s", "Invalid input parameter.");
8826 }
8827 }
8828
JSBind(BindingTarget globalObj)8829 void JSViewAbstract::JSBind(BindingTarget globalObj)
8830 {
8831 JSClass<JSViewAbstract>::Declare("JSViewAbstract");
8832
8833 // static methods
8834 MethodOptions opt = MethodOptions::NONE;
8835 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
8836
8837 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
8838 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
8839 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
8840 JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
8841 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
8842 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
8843 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
8844 JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSViewAbstract::JsPixelRound);
8845 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
8846 JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSViewAbstract::JsChainWeight);
8847
8848 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
8849 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
8850 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
8851 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
8852 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
8853
8854 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
8855 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
8856 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
8857 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
8858 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
8859 JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt);
8860
8861 JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
8862 JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect);
8863 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
8864 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
8865 JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable);
8866 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
8867 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
8868 JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
8869 JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
8870 JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
8871 JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
8872 JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
8873 JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
8874 JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
8875 JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
8876 JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
8877 JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
8878 JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
8879 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
8880 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
8881 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
8882 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
8883 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
8884 JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
8885
8886 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
8887 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
8888 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
8889 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
8890 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
8891 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
8892 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
8893 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
8894 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
8895 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
8896 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
8897 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
8898
8899 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
8900 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
8901 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
8902 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
8903 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
8904 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
8905 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
8906
8907 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
8908 JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur);
8909 JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
8910 JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
8911 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
8912 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
8913 JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
8914 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
8915 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal",
8916 &JSViewAbstract::JsBackgroundBrightnessInternal);
8917 JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness);
8918 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
8919 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
8920 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
8921 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
8922 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
8923 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
8924 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
8925 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
8926 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
8927 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
8928 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
8929 #ifndef WEARABLE_PRODUCT
8930 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
8931 #endif
8932
8933 JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
8934 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
8935 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
8936 JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
8937 JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
8938 JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
8939 JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
8940 JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag);
8941 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
8942 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
8943 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
8944 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
8945 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
8946 JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
8947
8948 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
8949 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
8950 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
8951 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
8952 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
8953 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
8954 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
8955 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
8956 JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
8957 JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode);
8958 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
8959 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
8960 JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop);
8961 JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox);
8962 JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
8963 JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme);
8964 JSClass<JSViewAbstract>::StaticMethod("onKeyEventDispatch", &JSInteractableView::JsOnKeyEventDispatch);
8965 JSClass<JSViewAbstract>::StaticMethod("dispatchKeyEvent", &JSViewAbstract::JsDispatchKeyEvent);
8966 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
8967 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
8968 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
8969 JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
8970 JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
8971 JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
8972 JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
8973 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
8974 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
8975 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
8976 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
8977 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
8978 JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
8979 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
8980 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
8981 JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip);
8982 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
8983 JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask);
8984 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
8985 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
8986 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
8987 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
8988 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
8989 JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
8990 JSClass<JSViewAbstract>::StaticMethod("onHoverMove", &JSViewAbstract::JsOnHoverMove);
8991 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
8992 JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
8993 JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
8994 JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
8995 JSClass<JSViewAbstract>::StaticMethod(
8996 "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith);
8997 JSClass<JSViewAbstract>::StaticMethod(
8998 "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin);
8999 JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
9000 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
9001 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
9002 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
9003 JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange);
9004 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
9005 JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
9006 JSClass<JSViewAbstract>::StaticMethod("onFocusAxisEvent", &JSViewAbstract::JsOnFocusAxisEvent);
9007
9008 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
9009 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
9010 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
9011 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
9012 JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
9013 JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
9014 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
9015 JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected);
9016 JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked);
9017
9018 JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
9019 JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode);
9020 JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
9021 JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
9022 JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
9023 JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
9024 JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
9025 JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive);
9026 JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
9027 JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
9028 JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint);
9029
9030 JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
9031 JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
9032 JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
9033 JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
9034
9035 JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
9036
9037 JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
9038
9039 JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier);
9040 JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty);
9041 JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier);
9042
9043 JSClass<JSViewAbstract>::StaticMethod(
9044 "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled);
9045 JSClass<JSViewAbstract>::StaticMethod("cancelDataLoading", &JSViewAbstract::JsCancelDataLoading);
9046
9047 JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId);
9048 JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority);
9049
9050 JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect);
9051 JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter);
9052 JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter);
9053 JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter);
9054
9055 JSClass<JSViewAbstract>::Bind(globalObj);
9056 }
9057
AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)9058 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode)
9059 {
9060 auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> {
9061 auto vm = info->GetVM();
9062 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
9063 Local<JSValueRef> thisObj = info->GetFunctionRef();
9064 auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj);
9065 if (thisObjRef->GetNativePointerFieldCount(vm) < 1) {
9066 return panda::JSValueRef::Undefined(vm);
9067 }
9068
9069 auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0));
9070 if (weak->Invalid()) {
9071 return panda::JSValueRef::Undefined(vm);
9072 }
9073
9074 auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade());
9075 if (frameNode) {
9076 const auto& extensionHandler = frameNode->GetExtensionHandler();
9077 if (extensionHandler) {
9078 extensionHandler->InvalidateRender();
9079 } else {
9080 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9081 }
9082 }
9083
9084 return panda::JSValueRef::Undefined(vm);
9085 };
9086 auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate);
9087 if (frameNode) {
9088 const auto& extensionHandler = frameNode->GetExtensionHandler();
9089 if (extensionHandler) {
9090 extensionHandler->InvalidateRender();
9091 } else {
9092 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER);
9093 }
9094 }
9095 auto vm = jsInvalidate->GetEcmaVM();
9096 auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode));
9097 jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1);
9098 jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>);
9099 jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate);
9100 }
9101
JsDrawModifier(const JSCallbackInfo & info)9102 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info)
9103 {
9104 if (!info[0]->IsObject()) {
9105 return;
9106 }
9107
9108 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
9109 bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier();
9110 if (!IsSupportDrawModifier) {
9111 return;
9112 }
9113 auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]);
9114 RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>();
9115 auto execCtx = info.GetExecutionContext();
9116 auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc {
9117 JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key);
9118 if (!drawMethod->IsFunction()) {
9119 return nullptr;
9120 }
9121
9122 auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(
9123 JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod));
9124
9125 return GetDrawCallback(jsDrawFunc, execCtx);
9126 };
9127
9128 drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind");
9129 drawModifier->drawContentFunc = getDrawModifierFunc("drawContent");
9130 drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront");
9131
9132 ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier);
9133 AddInvalidateFunc(jsDrawModifier, frameNode);
9134 }
9135
JsAllowDrop(const JSCallbackInfo & info)9136 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
9137 {
9138 std::set<std::string> allowDropSet;
9139 allowDropSet.clear();
9140 if (!info[0]->IsUndefined() && info[0]->IsArray()) {
9141 auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
9142 std::string allowDrop;
9143 for (size_t i = 0; i < allowDropArray->Length(); i++) {
9144 allowDrop = allowDropArray->GetValueAt(i)->ToString();
9145 allowDropSet.insert(allowDrop);
9146 }
9147 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9148 } else if (info[0]->IsNull()) {
9149 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true);
9150 } else {
9151 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false);
9152 }
9153 ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
9154 }
9155
JsOnPreDrag(const JSCallbackInfo & info)9156 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info)
9157 {
9158 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
9159 auto jsVal = info[0];
9160 if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) {
9161 return;
9162 }
9163 RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal));
9164 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9165 auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode](
9166 const PreDragStatus preDragStatus) {
9167 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9168 ACE_SCORING_EVENT("onPreDrag");
9169 PipelineContext::SetCallBackNode(node);
9170 func->PreDragExecute(preDragStatus);
9171 };
9172 ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag);
9173 }
9174
ParseDragPreviewConfig(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9175 void JSViewAbstract::ParseDragPreviewConfig(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9176 {
9177 if (info.Length() <= 1) {
9178 return;
9179 }
9180 auto jsVal = info[1];
9181 if (!jsVal->IsObject()) {
9182 return;
9183 }
9184 auto config = JSRef<JSObject>::Cast(jsVal);
9185 ParseJsBool(config->GetProperty("onlyForLifting"), dragPreviewInfo.onlyForLifting);
9186 ParseJsBool(config->GetProperty("delayCreating"), dragPreviewInfo.delayCreating);
9187 }
9188
ParseDragPreviewValue(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo)9189 void JSViewAbstract::ParseDragPreviewValue(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo)
9190 {
9191 auto jsVal = info[0];
9192 JSRef<JSVal> builder;
9193 JSRef<JSVal> pixelMap;
9194 JSRef<JSVal> extraInfo;
9195 if (jsVal->IsFunction()) {
9196 builder = jsVal;
9197 } else if (jsVal->IsObject()) {
9198 auto dragItemInfo = JSRef<JSObject>::Cast(jsVal);
9199 builder = dragItemInfo->GetProperty("builder");
9200 #if defined(PIXEL_MAP_SUPPORTED)
9201 pixelMap = dragItemInfo->GetProperty("pixelMap");
9202 dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
9203 #endif
9204 extraInfo = dragItemInfo->GetProperty("extraInfo");
9205 ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
9206 } else if (jsVal->IsString()) {
9207 auto inspectorId = jsVal;
9208 ParseJsString(inspectorId, dragPreviewInfo.inspectorId);
9209 } else {
9210 return;
9211 }
9212 ParseDragPreviewBuilderNode(info, dragPreviewInfo, builder);
9213 }
9214
ParseDragPreviewBuilderNode(const JSCallbackInfo & info,NG::DragDropInfo & dragPreviewInfo,const JSRef<JSVal> & builder)9215 void JSViewAbstract::ParseDragPreviewBuilderNode(const JSCallbackInfo& info, NG::DragDropInfo& dragPreviewInfo,
9216 const JSRef<JSVal>& builder)
9217 {
9218 if (!builder->IsFunction()) {
9219 return;
9220 }
9221 RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
9222 CHECK_NULL_VOID(builderFunc);
9223 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9224 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
9225 node = frameNode]() -> RefPtr<NG::UINode> {
9226 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
9227 ACE_SCORING_EVENT("dragPreview.builder");
9228 PipelineContext::SetCallBackNode(node);
9229 func->Execute();
9230 auto customNode = ViewStackModel::GetInstance()->Finish();
9231 return AceType::DynamicCast<NG::UINode>(customNode);
9232 };
9233 if (!dragPreviewInfo.delayCreating) {
9234 ViewStackModel::GetInstance()->NewScope();
9235 {
9236 dragPreviewInfo.customNode = buildFunc();
9237 }
9238 } else {
9239 dragPreviewInfo.buildFunc = buildFunc;
9240 }
9241 }
9242
JsDragPreview(const JSCallbackInfo & info)9243 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
9244 {
9245 auto jsVal = info[0];
9246 if ((!jsVal->IsObject()) && (!jsVal->IsString())) {
9247 return;
9248 }
9249 NG::DragDropInfo dragPreviewInfo;
9250 ParseDragPreviewConfig(info, dragPreviewInfo);
9251 ParseDragPreviewValue(info, dragPreviewInfo);
9252 ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
9253 }
9254
JsAlignRules(const JSCallbackInfo & info)9255 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
9256 {
9257 if (!info[0]->IsObject()) {
9258 return;
9259 }
9260
9261 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
9262 if (valueObj->IsEmpty()) {
9263 return;
9264 }
9265 const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" };
9266 std::map<AlignDirection, AlignRule> alignRules;
9267 BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
9268 for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
9269 auto rule = valueObj->GetProperty(keys[i]);
9270 if (rule->IsObject()) {
9271 JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
9272 JSRef<JSVal> align = val->GetProperty("align");
9273 AlignRule alignRule;
9274 alignRule.anchor = val->GetProperty("anchor")->ToString();
9275 if (i < HORIZONTAL_DIRECTION_RANGE) {
9276 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9277 } else {
9278 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
9279 }
9280 if (i < VERTICAL_DIRECTION_RANGE) {
9281 alignRules[static_cast<AlignDirection>(i)] = alignRule;
9282 } else if (i == HORIZONTAL_DIRECTION_START_INDEX) {
9283 alignRules[AlignDirection::LEFT] = alignRule;
9284 } else if (i == HORIZONTAL_DIRECTION_END_INDEX) {
9285 alignRules[AlignDirection::RIGHT] = alignRule;
9286 }
9287 auto biasX = val->GetProperty("horizontal");
9288 if (biasX->IsNumber()) {
9289 biasPair.first = biasX->ToNumber<float>();
9290 }
9291 auto biasY = val->GetProperty("vertical");
9292 if (biasY->IsNumber()) {
9293 biasPair.second = biasY->ToNumber<float>();
9294 }
9295 }
9296 }
9297
9298 ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
9299 ViewAbstractModel::GetInstance()->SetBias(biasPair);
9300 }
9301
JsChainMode(const JSCallbackInfo & info)9302 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info)
9303 {
9304 ChainInfo chainInfo;
9305 if (info.Length() >= 1) {
9306 auto tmpDirection = info[0];
9307 if (tmpDirection->IsUndefined()) {
9308 chainInfo.direction = std::nullopt;
9309 } else if (tmpDirection->IsNumber()) {
9310 auto direction = tmpDirection->ToNumber<int32_t>();
9311 chainInfo.direction = static_cast<LineDirection>(direction);
9312 }
9313 }
9314
9315 if (info.Length() >= 2) { // 2 : two args
9316 auto tmpStyle = info[1];
9317 if (tmpStyle->IsUndefined()) {
9318 chainInfo.style = std::nullopt;
9319 } else if (tmpStyle->IsNumber()) {
9320 auto style = tmpStyle->ToNumber<int32_t>();
9321 chainInfo.style = static_cast<ChainStyle>(style);
9322 }
9323 }
9324 ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo);
9325 }
9326
SetMarginTop(const JSCallbackInfo & info)9327 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
9328 {
9329 CalcDimension value;
9330 if (!ParseJsDimensionVp(info[0], value)) {
9331 return;
9332 }
9333 ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
9334 }
9335
SetMarginBottom(const JSCallbackInfo & info)9336 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
9337 {
9338 CalcDimension value;
9339 if (!ParseJsDimensionVp(info[0], value)) {
9340 return;
9341 }
9342 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
9343 }
9344
SetMarginLeft(const JSCallbackInfo & info)9345 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
9346 {
9347 CalcDimension value;
9348 if (!ParseJsDimensionVp(info[0], value)) {
9349 return;
9350 }
9351 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
9352 }
9353
SetMarginRight(const JSCallbackInfo & info)9354 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
9355 {
9356 CalcDimension value;
9357 if (!ParseJsDimensionVp(info[0], value)) {
9358 return;
9359 }
9360 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
9361 }
9362
SetPaddingTop(const JSCallbackInfo & info)9363 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
9364 {
9365 CalcDimension value;
9366 if (!ParseJsDimensionVp(info[0], value)) {
9367 return;
9368 }
9369 ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
9370 }
9371
SetPaddingBottom(const JSCallbackInfo & info)9372 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
9373 {
9374 CalcDimension value;
9375 if (!ParseJsDimensionVp(info[0], value)) {
9376 return;
9377 }
9378 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
9379 }
9380
SetPaddingLeft(const JSCallbackInfo & info)9381 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
9382 {
9383 CalcDimension value;
9384 if (!ParseJsDimensionVp(info[0], value)) {
9385 return;
9386 }
9387 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
9388 }
9389
SetPaddingRight(const JSCallbackInfo & info)9390 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
9391 {
9392 CalcDimension value;
9393 if (!ParseJsDimensionVp(info[0], value)) {
9394 return;
9395 }
9396 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
9397 }
9398
SetSafeAreaPadding(const JSCallbackInfo & info)9399 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info)
9400 {
9401 ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING);
9402 }
9403
SetColorBlend(Color color)9404 void JSViewAbstract::SetColorBlend(Color color)
9405 {
9406 ViewAbstractModel::GetInstance()->SetColorBlend(color);
9407 }
9408
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)9409 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
9410 {
9411 ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
9412 }
9413
SetDynamicLightUp(float rate,float lightUpDegree)9414 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
9415 {
9416 ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
9417 }
9418
SetBgDynamicBrightness(BrightnessOption brightnessOption)9419 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption)
9420 {
9421 ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption);
9422 }
9423
SetFgDynamicBrightness(BrightnessOption brightnessOption)9424 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption)
9425 {
9426 ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption);
9427 }
9428
SetWindowBlur(float progress,WindowBlurStyle blurStyle)9429 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
9430 {
9431 ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
9432 }
9433
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)9434 bool JSViewAbstract::ParseJsonDimension(
9435 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
9436 {
9437 if (!jsonValue || jsonValue->IsNull()) {
9438 return false;
9439 }
9440 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9441 return false;
9442 }
9443 if (jsonValue->IsNumber()) {
9444 result = Dimension(jsonValue->GetDouble(), defaultUnit);
9445 return true;
9446 }
9447 if (jsonValue->IsString()) {
9448 if (checkIllegal) {
9449 return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
9450 }
9451 result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
9452 return true;
9453 }
9454 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9455 auto resId = resVal->GetValue("id");
9456 if (!resId || !resId->IsNumber()) {
9457 return false;
9458 }
9459
9460 auto resourceWrapper = CreateResourceWrapper();
9461 if (!resourceWrapper) {
9462 return false;
9463 }
9464 result = resourceWrapper->GetDimension(resId->GetUInt());
9465 return true;
9466 }
9467
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)9468 bool JSViewAbstract::ParseJsonDimensionVp(
9469 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
9470 {
9471 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9472 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
9473 }
9474 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
9475 }
9476
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)9477 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
9478 {
9479 if (!jsonValue || jsonValue->IsNull()) {
9480 return false;
9481 }
9482 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9483 return false;
9484 }
9485 if (jsonValue->IsNumber()) {
9486 result = jsonValue->GetDouble();
9487 return true;
9488 }
9489 if (jsonValue->IsString()) {
9490 result = StringUtils::StringToDouble(jsonValue->GetString());
9491 return true;
9492 }
9493 // parse json Resource
9494 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9495 auto resId = resVal->GetValue("id");
9496 CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
9497 auto id = resId->GetUInt();
9498 auto resType = resVal->GetValue("type");
9499 CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
9500 auto type = resType->GetUInt();
9501
9502 auto resourceWrapper = CreateResourceWrapper();
9503 if (!resourceWrapper) {
9504 return false;
9505 }
9506 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9507 auto numberString = resourceWrapper->GetString(id);
9508 return StringUtils::StringToDouble(numberString, result);
9509 }
9510 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9511 result = resourceWrapper->GetInt(id);
9512 return true;
9513 }
9514 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9515 result = resourceWrapper->GetDouble(id);
9516 return true;
9517 }
9518 return false;
9519 }
9520
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)9521 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
9522 {
9523 if (!jsonValue || jsonValue->IsNull()) {
9524 return false;
9525 }
9526 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
9527 return false;
9528 }
9529 if (jsonValue->IsNumber()) {
9530 result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
9531 return true;
9532 }
9533
9534 bool isSetColor = false;
9535 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
9536 isSetColor = jsonValue->IsString();
9537 } else {
9538 isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
9539 }
9540 if (isSetColor) {
9541 result = Color::FromString(jsonValue->GetString());
9542 return true;
9543 }
9544 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
9545 auto resId = resVal->GetValue("id");
9546 if (!resId || !resId->IsNumber()) {
9547 return false;
9548 }
9549 auto resourceWrapper = CreateResourceWrapper();
9550 if (!resourceWrapper) {
9551 return false;
9552 }
9553 result = resourceWrapper->GetColor(resId->GetUInt());
9554 return true;
9555 }
9556
ParseShadowOffsetX(const JSRef<JSObject> & jsObj,CalcDimension & offsetX,Shadow & shadow)9557 void JSViewAbstract::ParseShadowOffsetX(const JSRef<JSObject>& jsObj, CalcDimension& offsetX, Shadow& shadow)
9558 {
9559 auto jsOffsetX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_X));
9560 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
9561 if (ParseJsResource(jsOffsetX, offsetX)) {
9562 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9563 shadow.SetOffsetX(xValue);
9564 } else {
9565 if (ParseJsDimensionVp(jsOffsetX, offsetX)) {
9566 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
9567 shadow.SetOffsetX(xValue);
9568 }
9569 }
9570 }
9571
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)9572 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
9573 {
9574 int32_t shadowStyle = 0;
9575 if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
9576 auto style = static_cast<ShadowStyle>(shadowStyle);
9577 return GetShadowFromTheme(style, shadow);
9578 }
9579 if (!jsValue->IsObject()) {
9580 return false;
9581 }
9582 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9583 double radius = 0.0;
9584 ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius);
9585 if (LessNotEqual(radius, 0.0)) {
9586 radius = 0.0;
9587 }
9588 shadow.SetBlurRadius(radius);
9589 CalcDimension offsetX;
9590 ParseShadowOffsetX(jsObj, offsetX, shadow);
9591 CalcDimension offsetY;
9592 auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y));
9593 if (ParseJsResource(jsOffsetY, offsetY)) {
9594 shadow.SetOffsetY(offsetY.Value());
9595 } else {
9596 if (ParseJsDimensionVp(jsOffsetY, offsetY)) {
9597 shadow.SetOffsetY(offsetY.Value());
9598 }
9599 }
9600 Color color;
9601 ShadowColorStrategy shadowColorStrategy;
9602 auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR));
9603 if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) {
9604 shadow.SetShadowColorStrategy(shadowColorStrategy);
9605 } else if (ParseJsColor(jsColor, color)) {
9606 shadow.SetColor(color);
9607 }
9608 int32_t type = static_cast<int32_t>(ShadowType::COLOR);
9609 JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type);
9610 if (type != static_cast<int32_t>(ShadowType::BLUR)) {
9611 type = static_cast<int32_t>(ShadowType::COLOR);
9612 }
9613 shadow.SetShadowType(static_cast<ShadowType>(type));
9614 bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false);
9615 shadow.SetIsFilled(isFilled);
9616 return true;
9617 }
9618
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)9619 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
9620 {
9621 auto colorMode = SystemProperties::GetColorMode();
9622 if (shadowStyle == ShadowStyle::None) {
9623 return true;
9624 }
9625
9626 auto container = Container::Current();
9627 CHECK_NULL_RETURN(container, false);
9628 auto pipelineContext = container->GetPipelineContext();
9629 CHECK_NULL_RETURN(pipelineContext, false);
9630
9631 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
9632 if (!shadowTheme) {
9633 return false;
9634 }
9635
9636 shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
9637 return true;
9638 }
9639
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)9640 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
9641 {
9642 if (!jsValue->IsObject()) {
9643 return false;
9644 }
9645 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
9646 uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0);
9647 if (type == 0) {
9648 return false;
9649 }
9650 auto resourceWrapper = CreateResourceWrapper();
9651 CHECK_NULL_RETURN(resourceWrapper, false);
9652 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
9653 auto value = resourceWrapper->GetString(
9654 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9655 return StringUtils::StringToCalcDimensionNG(value, result, false);
9656 }
9657 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
9658 auto value = std::to_string(
9659 resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)));
9660 StringUtils::StringToDimensionWithUnitNG(value, result);
9661 return true;
9662 }
9663
9664 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
9665 result = resourceWrapper->GetDimension(
9666 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0));
9667 return true;
9668 }
9669 return false;
9670 }
9671
ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)9672 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig)
9673 {
9674 JSRef<JSVal> arg = info[0];
9675 if (!arg->IsObject()) {
9676 return false;
9677 }
9678 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
9679 JSRef<JSVal> typeValue = obj->GetProperty("types");
9680 if (!typeValue->IsArray()) {
9681 return false;
9682 }
9683 JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
9684 for (size_t i = 0; i < array->Length(); i++) {
9685 JSRef<JSVal> value = array->GetValueAt(i);
9686 auto index = value->ToNumber<int32_t>();
9687 if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
9688 return false;
9689 }
9690 if (i != 0) {
9691 textDetectConfig.types.append(",");
9692 }
9693 textDetectConfig.types.append(TEXT_DETECT_TYPES[index]);
9694 }
9695 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
9696 JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
9697 if (resultCallback->IsFunction()) {
9698 auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
9699 textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
9700 const std::string& result) {
9701 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
9702 PipelineContext::SetCallBackNode(node);
9703 func->Execute(result);
9704 };
9705 }
9706
9707 return ParseAIEntityColor(obj, textDetectConfig);
9708 }
9709
ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)9710 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig)
9711 {
9712 JSRef<JSVal> entityColorValue = obj->GetProperty("color");
9713 ParseJsColor(entityColorValue, textDetectConfig.entityColor);
9714
9715 JSRef<JSVal> decorationValue = obj->GetProperty("decoration");
9716 if (decorationValue->IsUndefined() || !decorationValue->IsObject()) {
9717 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9718 return true;
9719 }
9720 JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue);
9721 JSRef<JSVal> typeValue = decorationObj->GetProperty("type");
9722 JSRef<JSVal> colorValue = decorationObj->GetProperty("color");
9723 JSRef<JSVal> styleValue = decorationObj->GetProperty("style");
9724
9725 if (typeValue->IsNumber()) {
9726 textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>());
9727 } else {
9728 textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE;
9729 }
9730 if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) {
9731 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor;
9732 }
9733 if (styleValue->IsNumber()) {
9734 textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>());
9735 } else {
9736 textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID;
9737 }
9738
9739 return true;
9740 }
9741
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)9742 void JSViewAbstract::GetAngle(
9743 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
9744 {
9745 auto value = jsonValue->GetValue(key);
9746 if (value && value->IsString()) {
9747 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
9748 } else if (value && value->IsNumber()) {
9749 angle = static_cast<float>(value->GetDouble());
9750 }
9751 }
9752
GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)9753 void JSViewAbstract::GetJsAngle(
9754 int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
9755 {
9756 if (!jsValue->IsObject()) {
9757 return;
9758 }
9759 JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key);
9760 if (value->IsString()) {
9761 angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
9762 } else if (value->IsNumber()) {
9763 angle = value->ToNumber<float>();
9764 }
9765 }
9766
9767 // 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)9768 void JSViewAbstract::GetJsAngleWithDefault(
9769 int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue)
9770 {
9771 JSRef<JSVal> value = jsObj->GetProperty(key);
9772 if (value->IsString()) {
9773 double temp = 0.0;
9774 if (StringUtils::StringToDegree(value->ToString(), temp)) {
9775 angle = static_cast<float>(temp);
9776 } else {
9777 angle = defaultValue;
9778 }
9779 } else if (value->IsNumber()) {
9780 angle = value->ToNumber<float>();
9781 }
9782 }
9783
CheckAngle(std::optional<float> & angle)9784 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle)
9785 {
9786 angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE);
9787 }
9788
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)9789 void JSViewAbstract::GetPerspective(
9790 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
9791 {
9792 auto value = jsonValue->GetValue(key);
9793 if (value && value->IsNumber()) {
9794 perspective = static_cast<float>(value->GetDouble());
9795 }
9796 }
9797
GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)9798 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective)
9799 {
9800 auto value = jsValue->GetProperty(key);
9801 if (value->IsNumber()) {
9802 perspective = value->ToNumber<float>();
9803 }
9804 }
9805
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9806 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9807 {
9808 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9809 return;
9810 }
9811
9812 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9813 GradientColor gradientColor;
9814 auto item = colorStops->GetArrayItem(i);
9815 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9816 auto colorParams = item->GetArrayItem(0);
9817 // color
9818 Color color;
9819 if (!ParseJsonColor(colorParams, color)) {
9820 continue;
9821 }
9822 gradientColor.SetColor(color);
9823 gradientColor.SetHasValue(false);
9824 // stop value
9825 if (item->GetArraySize() <= 1) {
9826 continue;
9827 }
9828 auto stopValue = item->GetArrayItem(1);
9829 double value = 0.0;
9830 if (ParseJsonDouble(stopValue, value)) {
9831 value = std::clamp(value, 0.0, 1.0);
9832 gradientColor.SetHasValue(true);
9833 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9834 }
9835 gradient.AddColor(gradientColor);
9836 }
9837 }
9838 }
9839
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9840 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
9841 {
9842 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
9843 return;
9844 }
9845
9846 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
9847 NG::GradientColor gradientColor;
9848 auto item = colorStops->GetArrayItem(i);
9849 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
9850 auto colorParams = item->GetArrayItem(0);
9851 // color
9852 Color color;
9853 if (!ParseJsonColor(colorParams, color)) {
9854 continue;
9855 }
9856 gradientColor.SetColor(color);
9857 gradientColor.SetHasValue(false);
9858 // stop value
9859 if (item->GetArraySize() <= 1) {
9860 continue;
9861 }
9862 auto stopValue = item->GetArrayItem(1);
9863 double value = 0.0;
9864 if (ParseJsonDouble(stopValue, value)) {
9865 value = std::clamp(value, 0.0, 1.0);
9866 gradientColor.SetHasValue(true);
9867 // [0, 1] -> [0, 100.0];
9868 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9869 }
9870 gradient.AddColor(gradientColor);
9871 }
9872 }
9873 }
9874
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)9875 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
9876 {
9877 if (!colorStops->IsArray()) {
9878 return;
9879 }
9880
9881 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
9882 size_t length = jsArray->Length();
9883 for (size_t i = 0; i < length; i++) {
9884 NG::GradientColor gradientColor;
9885 JSRef<JSVal> item = jsArray->GetValueAt(i);
9886 if (!item->IsArray()) {
9887 continue;
9888 }
9889 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
9890 if (subArray->Length() < 2) {
9891 continue;
9892 }
9893 // color
9894 Color color;
9895 if (!ParseJsColor(subArray->GetValueAt(0), color)) {
9896 continue;
9897 }
9898 gradientColor.SetColor(color);
9899 gradientColor.SetHasValue(false);
9900 // stop value
9901 double value = 0.0;
9902 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
9903 value = std::clamp(value, 0.0, 1.0);
9904 gradientColor.SetHasValue(true);
9905 }
9906 // [0, 1] -> [0, 100.0];
9907 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
9908 gradient.AddColor(gradientColor);
9909 }
9910 }
9911
SetDirection(const std::string & dir)9912 void JSViewAbstract::SetDirection(const std::string& dir)
9913 {
9914 TextDirection direction = TextDirection::AUTO;
9915 if (dir == "Ltr") {
9916 direction = TextDirection::LTR;
9917 } else if (dir == "Rtl") {
9918 direction = TextDirection::RTL;
9919 } else if (dir == "Auto") {
9920 direction = TextDirection::AUTO;
9921 } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
9922 direction = TextDirection::AUTO;
9923 }
9924 ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
9925 }
9926
GetThemeConstants(const JSRef<JSObject> & jsObj)9927 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
9928 {
9929 std::string bundleName;
9930 std::string moduleName;
9931 if (!jsObj->IsUndefined()) {
9932 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
9933 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
9934 if (bundle->IsString() && module->IsString()) {
9935 bundleName = bundle->ToString();
9936 moduleName = module->ToString();
9937 }
9938 }
9939
9940 auto cardId = CardScope::CurrentId();
9941 if (cardId != INVALID_CARD_ID) {
9942 auto container = Container::Current();
9943 auto weak = container->GetCardPipeline(cardId);
9944 auto cardPipelineContext = weak.Upgrade();
9945 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
9946 auto cardThemeManager = cardPipelineContext->GetThemeManager();
9947 CHECK_NULL_RETURN(cardThemeManager, nullptr);
9948 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
9949 }
9950
9951 #ifdef PLUGIN_COMPONENT_SUPPORTED
9952 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
9953 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
9954 if (!pluginContainer) {
9955 return nullptr;
9956 }
9957 auto pluginPipelineContext = pluginContainer->GetPipelineContext();
9958 if (!pluginPipelineContext) {
9959 return nullptr;
9960 }
9961 auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
9962 if (!pluginThemeManager) {
9963 return nullptr;
9964 }
9965 return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
9966 }
9967 #endif
9968 auto container = Container::Current();
9969 CHECK_NULL_RETURN(container, nullptr);
9970 auto pipelineContext = container->GetPipelineContext();
9971 CHECK_NULL_RETURN(pipelineContext, nullptr);
9972 auto themeManager = pipelineContext->GetThemeManager();
9973 CHECK_NULL_RETURN(themeManager, nullptr);
9974 return themeManager->GetThemeConstants(bundleName, moduleName);
9975 }
9976
JsHoverEffect(const JSCallbackInfo & info)9977 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
9978 {
9979 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
9980 auto jsVal = info[0];
9981 if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) {
9982 ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
9983 return;
9984 }
9985 if (!jsVal->IsNumber()) {
9986 return;
9987 }
9988 ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>()));
9989 }
9990
JsOnMouse(const JSCallbackInfo & info)9991 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
9992 {
9993 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
9994 ViewAbstractModel::GetInstance()->DisableOnMouse();
9995 return;
9996 }
9997 if (!info[0]->IsFunction()) {
9998 return;
9999 }
10000
10001 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
10002 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10003 auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
10004 MouseInfo& mouseInfo) {
10005 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10006 ACE_SCORING_EVENT("onMouse");
10007 PipelineContext::SetCallBackNode(node);
10008 func->Execute(mouseInfo);
10009 };
10010 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
10011 }
10012
JsOnHover(const JSCallbackInfo & info)10013 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
10014 {
10015 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10016 ViewAbstractModel::GetInstance()->DisableOnHover();
10017 return;
10018 }
10019 if (!info[0]->IsFunction()) {
10020 return;
10021 }
10022
10023 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10024 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10025 auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
10026 bool isHover, HoverInfo& hoverInfo) {
10027 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10028 ACE_SCORING_EVENT("onHover");
10029 PipelineContext::SetCallBackNode(node);
10030 func->HoverExecute(isHover, hoverInfo);
10031 };
10032 ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
10033 }
10034
JsOnHoverMove(const JSCallbackInfo & info)10035 void JSViewAbstract::JsOnHoverMove(const JSCallbackInfo& info)
10036 {
10037 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
10038 ViewAbstractModel::GetInstance()->DisableOnHoverMove();
10039 return;
10040 }
10041 if (!info[0]->IsFunction()) {
10042 return;
10043 }
10044
10045 RefPtr<JsHoverFunction> jsOnHoverMoveFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10046 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10047 auto onHoverMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverMoveFunc), node = frameNode](
10048 HoverInfo& hoverInfo) {
10049 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10050 ACE_SCORING_EVENT("onHoverMove");
10051 PipelineContext::SetCallBackNode(node);
10052 func->HoverMoveExecute(hoverInfo);
10053 };
10054 ViewAbstractModel::GetInstance()->SetOnHoverMove(std::move(onHoverMove));
10055 }
10056
JsOnAccessibilityHover(const JSCallbackInfo & info)10057 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
10058 {
10059 if (info[0]->IsUndefined()) {
10060 ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
10061 return;
10062 }
10063 if (!info[0]->IsFunction()) {
10064 return;
10065 }
10066
10067 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
10068 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10069 auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
10070 node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
10071 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10072 ACE_SCORING_EVENT("onAccessibilityHover");
10073 PipelineContext::SetCallBackNode(node);
10074 func->AccessibilityHoverExecute(isHover, hoverInfo);
10075 };
10076 ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
10077 }
10078
JsOnClick(const JSCallbackInfo & info)10079 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
10080 {
10081 auto arg = info[0];
10082 if (arg->IsUndefined() && IsDisableEventVersion()) {
10083 ViewAbstractModel::GetInstance()->DisableOnClick();
10084 return;
10085 }
10086 if (!arg->IsFunction()) {
10087 return;
10088 }
10089
10090 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg));
10091 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10092 auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
10093 BaseEventInfo* info) {
10094 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10095 auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
10096 ACE_SCORING_EVENT("onClick");
10097 PipelineContext::SetCallBackNode(node);
10098 func->Execute(*tapInfo);
10099 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
10100 JSInteractableView::ReportClickEvent(node);
10101 #endif
10102 };
10103 auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); };
10104 auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
10105 const ClickInfo* info) {
10106 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10107 ACE_SCORING_EVENT("onClick");
10108 PipelineContext::SetCallBackNode(node);
10109 func->Execute(*info);
10110 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
10111 JSInteractableView::ReportClickEvent(node);
10112 #endif
10113 };
10114
10115 double distanceThreshold = std::numeric_limits<double>::infinity();
10116 if (info.Length() > 1 && info[1]->IsNumber()) {
10117 distanceThreshold = info[1]->ToNumber<double>();
10118 if (distanceThreshold < 0) {
10119 distanceThreshold = std::numeric_limits<double>::infinity();
10120 }
10121 }
10122 distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx();
10123 ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold);
10124 }
10125
JsOnGestureJudgeBegin(const JSCallbackInfo & info)10126 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
10127 {
10128 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10129 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
10130 return;
10131 }
10132
10133 auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
10134 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10135 auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
10136 const RefPtr<NG::GestureInfo>& gestureInfo,
10137 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
10138 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
10139 ACE_SCORING_EVENT("onGestureJudgeBegin");
10140 return func->Execute(gestureInfo, info);
10141 };
10142 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
10143 }
10144
JsOnTouchIntercept(const JSCallbackInfo & info)10145 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info)
10146 {
10147 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10148 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr);
10149 return;
10150 }
10151
10152 auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0]));
10153 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10154 auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode](
10155 TouchEventInfo& info) -> NG::HitTestMode {
10156 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT);
10157 ACE_SCORING_EVENT("onTouchIntercept");
10158 PipelineContext::SetCallBackNode(node);
10159 return func->Execute(info);
10160 };
10161 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc));
10162 }
10163
JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)10164 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info)
10165 {
10166 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10167 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr);
10168 return;
10169 }
10170
10171 auto jsParallelInnerGestureToFunc =
10172 AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0]));
10173 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10174 auto shouldBuiltInRecognizerParallelWithFunc =
10175 [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode](
10176 const RefPtr<NG::NGGestureRecognizer>& current,
10177 const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> {
10178 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
10179 ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith");
10180 PipelineContext::SetCallBackNode(node);
10181 return func->Execute(current, others);
10182 };
10183 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(
10184 std::move(shouldBuiltInRecognizerParallelWithFunc));
10185 }
10186
JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)10187 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info)
10188 {
10189 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
10190 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false);
10191 return;
10192 }
10193
10194 auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
10195 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10196 auto onGestureRecognizerJudgefunc =
10197 [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode](
10198 const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current,
10199 const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult {
10200 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
10201 ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin");
10202 PipelineContext::SetCallBackNode(node);
10203 return func->Execute(info, current, others);
10204 };
10205
10206 bool exposeInnerGestureFlag = false;
10207 if (info.Length() > 1 && info[1]->IsBoolean()) {
10208 exposeInnerGestureFlag = info[1]->ToBoolean();
10209 }
10210 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(
10211 std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag);
10212 }
10213
JsClickEffect(const JSCallbackInfo & info)10214 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
10215 {
10216 JSRef<JSVal> arg = info[0];
10217 if (arg->IsUndefined() || arg->IsNull()) {
10218 ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
10219 return;
10220 }
10221 if (!arg->IsObject()) {
10222 return;
10223 }
10224 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
10225 JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
10226 int32_t clickEffectLevelValue = 0;
10227 if (clickEffectLevel->IsNumber()) {
10228 clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
10229 if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
10230 clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
10231 clickEffectLevelValue = 0;
10232 }
10233 }
10234
10235 JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
10236 float scaleNumberValue = DEFAULT_SCALE_LIGHT;
10237 if (!scaleNumber->IsNumber()) {
10238 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10239 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10240 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10241 }
10242 ViewAbstractModel::GetInstance()->SetClickEffectLevel(
10243 (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10244 return;
10245 }
10246
10247 scaleNumberValue = scaleNumber->ToNumber<float>();
10248 if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
10249 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
10250 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
10251 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
10252 } else {
10253 scaleNumberValue = DEFAULT_SCALE_LIGHT;
10254 }
10255 }
10256
10257 ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
10258 }
10259
JsOnVisibleAreaChange(const JSCallbackInfo & info)10260 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
10261 {
10262 if (info.Length() != 2) {
10263 return;
10264 }
10265
10266 if (!info[0]->IsArray() || !info[1]->IsFunction()) {
10267 return;
10268 }
10269
10270 auto ratioArray = JSRef<JSArray>::Cast(info[0]);
10271 size_t size = ratioArray->Length();
10272 std::vector<double> ratioVec(size);
10273 ratioVec.clear();
10274 for (size_t i = 0; i < size; i++) {
10275 double ratio = 0.0;
10276 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
10277 if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
10278 ratio = VISIBLE_RATIO_MIN;
10279 }
10280
10281 if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
10282 ratio = VISIBLE_RATIO_MAX;
10283 }
10284 ratioVec.push_back(ratio);
10285 }
10286
10287 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
10288 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10289 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
10290 bool visible, double ratio) {
10291 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10292 ACE_SCORING_EVENT("onVisibleAreaChange");
10293
10294 JSRef<JSVal> params[2];
10295 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
10296 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
10297 PipelineContext::SetCallBackNode(node);
10298 func->ExecuteJS(2, params);
10299 };
10300 ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
10301 }
10302
JsHitTestBehavior(const JSCallbackInfo & info)10303 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
10304 {
10305 if (info.Length() != 1 || !info[0]->IsNumber()) {
10306 return;
10307 }
10308
10309 NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
10310 hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
10311 ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
10312 }
10313
JsOnChildTouchTest(const JSCallbackInfo & info)10314 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
10315 {
10316 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
10317 auto jsVal = info[0];
10318 if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) {
10319 return;
10320 }
10321
10322 RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
10323 AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal));
10324
10325 auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
10326 const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
10327 NG::TouchResult touchRes;
10328 NG::TouchResult defaultRes;
10329 defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
10330 defaultRes.id = "";
10331 auto ret = func->Execute(touchInfo);
10332 if (!ret->IsObject()) {
10333 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
10334 return defaultRes;
10335 }
10336
10337 auto retObj = JSRef<JSObject>::Cast(ret);
10338 auto strategy = retObj->GetProperty("strategy");
10339 if (!strategy->IsNumber()) {
10340 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
10341 return defaultRes;
10342 }
10343 touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
10344 auto id = retObj->GetProperty("id");
10345 if (!id->IsString()) {
10346 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
10347 return defaultRes;
10348 }
10349 touchRes.id = id->ToString();
10350 return touchRes;
10351 };
10352 ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
10353 }
10354
JsForegroundColor(const JSCallbackInfo & info)10355 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
10356 {
10357 Color foregroundColor = Color::TRANSPARENT;
10358 ForegroundColorStrategy strategy;
10359 if (ParseJsColorStrategy(info[0], strategy)) {
10360 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
10361 return;
10362 }
10363 ParseJsColor(info[0], foregroundColor);
10364 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
10365 }
10366
JsKeyboardShortcut(const JSCallbackInfo & info)10367 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
10368 {
10369 // KeyboardShortcut only allows 2 or 3 params.
10370 if (info.Length() < 2 || info.Length() > 3) {
10371 return;
10372 }
10373 if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
10374 // clear shortcut key
10375 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10376 return;
10377 }
10378
10379 std::string value;
10380 if (info[0]->IsString()) {
10381 // common letter/number/symbol
10382 value = info[0]->ToString();
10383 if (value.size() != 1) {
10384 // clear shortcut key
10385 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr);
10386 return;
10387 }
10388 } else {
10389 // function keys such as F1-F10/ESC
10390 FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
10391 value = GetFunctionKeyName(functionkey);
10392 }
10393
10394 auto keysArray = JSRef<JSArray>::Cast(info[1]);
10395 size_t size = keysArray->Length();
10396 std::vector<ModifierKey> keys(size);
10397 keys.clear();
10398 for (size_t i = 0; i < size; i++) {
10399 JSRef<JSVal> key = keysArray->GetValueAt(i);
10400 if (key->IsNumber()) {
10401 keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
10402 }
10403 }
10404
10405 // KeyboardShortcut allows 3 params, the third param is function callback.
10406 if (info.Length() == 3 && info[2]->IsFunction()) {
10407 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
10408 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10409 auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10410 node = frameNode]() {
10411 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10412 ACE_SCORING_EVENT("onKeyboardShortcutAction");
10413 PipelineContext::SetCallBackNode(node);
10414 func->ExecuteJS();
10415 };
10416 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
10417 return;
10418 }
10419 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
10420 }
10421
JsOnFocusAxisEvent(const JSCallbackInfo & args)10422 void JSViewAbstract::JsOnFocusAxisEvent(const JSCallbackInfo& args)
10423 {
10424 JSRef<JSVal> arg = args[0];
10425 if (arg->IsUndefined() && IsDisableEventVersion()) {
10426 ViewAbstractModel::GetInstance()->DisableOnFocusAxisEvent();
10427 return;
10428 }
10429 if (!arg->IsFunction()) {
10430 return;
10431 }
10432 EcmaVM* vm = args.GetVm();
10433 CHECK_NULL_VOID(vm);
10434 auto jsOnFocusAxisEventFunc = JSRef<JSFunc>::Cast(arg);
10435 if (jsOnFocusAxisEventFunc->IsEmpty()) {
10436 return;
10437 }
10438 auto jsOnFocusAxisFuncLocalHandle = jsOnFocusAxisEventFunc->GetLocalHandle();
10439 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
10440 auto onFocusAxisEvent = [vm, execCtx = args.GetExecutionContext(),
10441 func = panda::CopyableGlobal(vm, jsOnFocusAxisFuncLocalHandle),
10442 node = frameNode](NG::FocusAxisEventInfo& info) {
10443 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10444 ACE_SCORING_EVENT("onFocusAxis");
10445 PipelineContext::SetCallBackNode(node);
10446 auto eventObj = NG::CommonBridge::CreateFocusAxisEventInfo(vm, info);
10447 panda::Local<panda::JSValueRef> params[1] = { eventObj };
10448 func->Call(vm, func.ToLocal(), params, 1);
10449 };
10450 ViewAbstractModel::GetInstance()->SetOnFocusAxisEvent(std::move(onFocusAxisEvent));
10451 }
10452
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)10453 bool JSViewAbstract::CheckColor(
10454 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
10455 {
10456 // Color is undefined or null
10457 if (jsValue->IsUndefined() || jsValue->IsNull()) {
10458 return false;
10459 }
10460 // input type is not in [number, string, Resource]
10461 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10462 return false;
10463 }
10464 // Correct type, incorrect value parsing
10465 if (!ParseJsColor(jsValue, result)) {
10466 return false;
10467 }
10468 return true;
10469 }
10470
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)10471 bool JSViewAbstract::CheckLength(
10472 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
10473 {
10474 // Length is undefined or null
10475 if (jsValue->IsUndefined() || jsValue->IsNull()) {
10476 return false;
10477 }
10478 // input type is not in [number, string, Resource]
10479 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
10480 return false;
10481 }
10482 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
10483 return ParseJsDimensionVpNG(jsValue, result);
10484 }
10485 // Correct type, incorrect value parsing
10486 if (!ParseJsDimensionVp(jsValue, result)) {
10487 return false;
10488 }
10489 return true;
10490 }
10491
10492 // obscured means that the developer calls the component to be private style.
JsObscured(const JSCallbackInfo & info)10493 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
10494 {
10495 JSRef<JSVal> arg = info[0];
10496 if (arg->IsUndefined() || arg->IsNull()) {
10497 std::vector<ObscuredReasons> reasons(0);
10498 ViewAbstractModel::GetInstance()->SetObscured(reasons);
10499 return;
10500 }
10501 if (!arg->IsArray()) {
10502 return;
10503 }
10504
10505 auto obscuredArray = JSRef<JSArray>::Cast(arg);
10506 size_t size = obscuredArray->Length();
10507 std::vector<ObscuredReasons> reasons(size);
10508 reasons.clear();
10509 for (size_t i = 0; i < size; i++) {
10510 JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
10511 if (reason->IsNumber()) {
10512 reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
10513 }
10514 }
10515
10516 ViewAbstractModel::GetInstance()->SetObscured(reasons);
10517 }
10518
10519 // PrivacySensitive means that the component will change style when system calls the app to be privated.
JsPrivacySensitive(const JSCallbackInfo & info)10520 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info)
10521 {
10522 auto sensitiveInfo = info[0];
10523 if (sensitiveInfo->IsUndefined()) {
10524 ViewAbstractModel::GetInstance()->SetPrivacySensitive(false);
10525 return;
10526 }
10527 bool sensitive = false;
10528 if (sensitiveInfo->IsBoolean()) {
10529 sensitive = sensitiveInfo->ToBoolean();
10530 }
10531 ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive);
10532 }
10533
JSRenderGroup(const JSCallbackInfo & info)10534 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
10535 {
10536 if (info.Length() != 1) {
10537 return;
10538 }
10539 bool isRenderGroup = false;
10540 if (info[0]->IsBoolean()) {
10541 isRenderGroup = info[0]->ToBoolean();
10542 }
10543 ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
10544 }
10545
JSRenderFit(const JSCallbackInfo & info)10546 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
10547 {
10548 if (info.Length() != 1) {
10549 return;
10550 }
10551 RenderFit renderFit = RenderFit::TOP_LEFT;
10552 if (info[0]->IsNumber()) {
10553 int32_t fitNumber = info[0]->ToNumber<int32_t>();
10554 if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
10555 fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
10556 renderFit = static_cast<RenderFit>(fitNumber);
10557 }
10558 }
10559 // how content fills the node duration implicit animation
10560 ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
10561 }
10562
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)10563 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
10564 {
10565 if (!jsValue->IsObject() || jsValue->IsString()) {
10566 return false;
10567 }
10568 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
10569 if (!jsObj->IsUndefined()) {
10570 JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME));
10571 JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME));
10572 if (bundle->IsString() && module->IsString()) {
10573 bundleName = bundle->ToString();
10574 moduleName = module->ToString();
10575 return true;
10576 }
10577 }
10578 return false;
10579 }
10580
GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)10581 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback(
10582 const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
10583 {
10584 std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx](
10585 NG::DrawingContext& context) -> void {
10586 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
10587
10588 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
10589 objectTemplate->SetInternalFieldCount(1);
10590 JSRef<JSObject> contextObj = objectTemplate->NewInstance();
10591 JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
10592 sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
10593 sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
10594 contextObj->SetPropertyObject("size", sizeObj);
10595
10596 JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
10597 sizeInPxObj->SetProperty<float>("height", context.height);
10598 sizeInPxObj->SetProperty<float>("width", context.width);
10599 contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
10600
10601 auto engine = EngineHelper::GetCurrentEngine();
10602 CHECK_NULL_VOID(engine);
10603 NativeEngine* nativeEngine = engine->GetNativeEngine();
10604 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
10605 ScopeRAII scope(env);
10606
10607 auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
10608 OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
10609 napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
10610 if (unwrapCanvas) {
10611 unwrapCanvas->SaveCanvas();
10612 unwrapCanvas->ClipCanvas(context.width, context.height);
10613 }
10614 JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
10615 contextObj->SetPropertyObject("canvas", jsCanvasVal);
10616
10617 auto jsVal = JSRef<JSVal>::Cast(contextObj);
10618 panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
10619 JSValueWrapper valueWrapper = value;
10620 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
10621
10622 napi_wrap(
10623 env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
10624
10625 JSRef<JSVal> result = func->ExecuteJS(1, &jsVal);
10626 if (unwrapCanvas) {
10627 unwrapCanvas->RestoreCanvas();
10628 unwrapCanvas->ResetCanvas();
10629 }
10630 };
10631 return drawCallback;
10632 }
10633
ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)10634 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty)
10635 {
10636 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10637 return false;
10638 }
10639 Color borderColor;
10640 if (ParseJsColor(args, borderColor)) {
10641 colorProperty.SetColor(borderColor);
10642 return true;
10643 } else if (args->IsObject()) {
10644 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10645 CommonColor commonColor;
10646 ParseCommonEdgeColors(obj, commonColor);
10647 colorProperty.topColor = commonColor.top;
10648 colorProperty.bottomColor = commonColor.bottom;
10649 colorProperty.leftColor = commonColor.left;
10650 colorProperty.rightColor = commonColor.right;
10651 colorProperty.multiValued = true;
10652 return true;
10653 }
10654 return false;
10655 }
10656
ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)10657 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty)
10658 {
10659 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10660 return false;
10661 }
10662 CalcDimension borderWidth;
10663 if (ParseJsDimensionVpNG(args, borderWidth, true)) {
10664 if (borderWidth.IsNegative()) {
10665 borderWidth.Reset();
10666 }
10667 borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth });
10668 return true;
10669 } else if (args->IsObject()) {
10670 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10671 CommonCalcDimension commonCalcDimension;
10672 ParseCommonEdgeWidthsProps(obj, commonCalcDimension);
10673 borderWidthProperty.topDimen = commonCalcDimension.top;
10674 borderWidthProperty.bottomDimen = commonCalcDimension.bottom;
10675 borderWidthProperty.leftDimen = commonCalcDimension.left;
10676 borderWidthProperty.rightDimen = commonCalcDimension.right;
10677 borderWidthProperty.multiValued = true;
10678 return true;
10679 }
10680 return false;
10681 }
10682
ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)10683 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty)
10684 {
10685 if (!args->IsObject() && !args->IsNumber()) {
10686 return false;
10687 }
10688 if (args->IsObject()) {
10689 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args);
10690 auto leftValue = obj->GetProperty("left");
10691 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
10692 ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft);
10693 }
10694 auto rightValue = obj->GetProperty("right");
10695 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
10696 ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight);
10697 }
10698 auto topValue = obj->GetProperty("top");
10699 if (!topValue->IsUndefined() && topValue->IsNumber()) {
10700 ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop);
10701 }
10702 auto bottomValue = obj->GetProperty("bottom");
10703 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
10704 ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom);
10705 }
10706 borderStyleProperty.multiValued = true;
10707 return true;
10708 }
10709 std::optional<BorderStyle> borderStyle;
10710 if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) {
10711 borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
10712 return true;
10713 }
10714 return false;
10715 }
10716
ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10717 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10718 {
10719 std::optional<CalcDimension> radiusTopLeft;
10720 std::optional<CalcDimension> radiusTopRight;
10721 std::optional<CalcDimension> radiusBottomLeft;
10722 std::optional<CalcDimension> radiusBottomRight;
10723 CalcDimension topLeft;
10724 if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) {
10725 radiusTopLeft = topLeft;
10726 }
10727 CalcDimension topRight;
10728 if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) {
10729 radiusTopRight = topRight;
10730 }
10731 CalcDimension bottomLeft;
10732 if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) {
10733 radiusBottomLeft = bottomLeft;
10734 }
10735 CalcDimension bottomRight;
10736 if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) {
10737 radiusBottomRight = bottomRight;
10738 }
10739 CheckLengthMetrics(object);
10740 radius.radiusTopLeft = radiusTopLeft;
10741 radius.radiusTopRight = radiusTopRight;
10742 radius.radiusBottomLeft = radiusBottomLeft;
10743 radius.radiusBottomRight = radiusBottomRight;
10744 radius.multiValued = true;
10745 return;
10746 }
10747
ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10748 void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius)
10749 {
10750 if (CheckLengthMetrics(object)) {
10751 std::optional<CalcDimension> radiusTopStart;
10752 std::optional<CalcDimension> radiusTopEnd;
10753 std::optional<CalcDimension> radiusBottomStart;
10754 std::optional<CalcDimension> radiusBottomEnd;
10755 if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) {
10756 JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY));
10757 CalcDimension calcDimension;
10758 if (ParseJsLengthMetrics(topStartObj, calcDimension)) {
10759 CheckDimensionUnit(calcDimension, false, true);
10760 radiusTopStart = calcDimension;
10761 }
10762 }
10763 if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) {
10764 JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY));
10765 CalcDimension calcDimension;
10766 if (ParseJsLengthMetrics(topEndObj, calcDimension)) {
10767 CheckDimensionUnit(calcDimension, false, true);
10768 radiusTopEnd = calcDimension;
10769 }
10770 }
10771 if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) {
10772 JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY));
10773 CalcDimension calcDimension;
10774 if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) {
10775 CheckDimensionUnit(calcDimension, false, true);
10776 radiusBottomStart = calcDimension;
10777 }
10778 }
10779 if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) {
10780 JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY));
10781 CalcDimension calcDimension;
10782 if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) {
10783 CheckDimensionUnit(calcDimension, false, true);
10784 radiusBottomEnd = calcDimension;
10785 }
10786 }
10787 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
10788 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart;
10789 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd;
10790 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart;
10791 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd;
10792 radius.multiValued = true;
10793 return;
10794 }
10795 ParseBorderRadiusProps(object, radius);
10796 }
10797
ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)10798 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
10799 {
10800 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
10801 return false;
10802 }
10803 CalcDimension borderRadius;
10804 if (ParseJsDimensionVpNG(args, borderRadius, true)) {
10805 radius = NG::BorderRadiusProperty(borderRadius);
10806 radius.multiValued = false;
10807 } else if (args->IsObject()) {
10808 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
10809 ParseCommonBorderRadiusProps(object, radius);
10810 } else {
10811 return false;
10812 }
10813 return true;
10814 }
10815
SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)10816 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10817 {
10818 JSRef<JSVal> arg = info[0];
10819 if (!arg->IsObject()) {
10820 return;
10821 }
10822 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg);
10823 auto vm = info.GetVm();
10824 auto globalObj = JSNApi::GetGlobalObject(vm);
10825 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode"));
10826 JsiValue jsiValue(globalFunc);
10827 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
10828 if (globalFuncRef->IsFunction()) {
10829 auto modifierObj = obj->GetProperty("modifier");
10830 if (modifierObj->IsUndefined()) {
10831 option.onApply = nullptr;
10832 } else {
10833 RefPtr<JsFunction> jsFunc =
10834 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
10835 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
10836 modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
10837 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
10838 auto node = frameNode.Upgrade();
10839 JSRef<JSVal> params[PARAMETER_LENGTH_SECOND];
10840 params[0] = modifier;
10841 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
10842 PipelineContext::SetCallBackNode(node);
10843 func->ExecuteJS(PARAMETER_LENGTH_SECOND, params);
10844 };
10845 option.onApply = onApply;
10846 }
10847 }
10848 }
10849
SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)10850 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option)
10851 {
10852 if (!info[0]->IsObject()) {
10853 return;
10854 }
10855 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
10856 auto numberBadge = obj->GetProperty("numberBadge");
10857 if (!numberBadge->IsEmpty()) {
10858 if (numberBadge->IsNumber()) {
10859 int64_t number = numberBadge->ToNumber<int64_t>();
10860 if (number < 0 || number > INT_MAX) {
10861 option.isNumber = false;
10862 option.isShowBadge = true;
10863 } else {
10864 option.isNumber = true;
10865 option.badgeNumber = numberBadge->ToNumber<int>();
10866 }
10867 } else if (numberBadge->IsBoolean()) {
10868 option.isNumber = false;
10869 option.isShowBadge = numberBadge->ToBoolean();
10870 }
10871 } else {
10872 option.isNumber = false;
10873 option.isShowBadge = true;
10874 }
10875 }
10876
SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10877 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10878 {
10879 // Parse cornerRadius.
10880 auto cornerRadiusValue = obj->GetProperty("cornerRadius");
10881 NG::BorderRadiusProperty radius;
10882 if (ParseBorderRadius(cornerRadiusValue, radius)) {
10883 properties.borderRadius = radius;
10884 }
10885 // Parse border width
10886 auto borderWidthValue = obj->GetProperty("borderWidth");
10887 NG::BorderWidthProperty borderWidth;
10888 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
10889 properties.borderWidth = borderWidth;
10890 auto colorValue = obj->GetProperty("borderColor");
10891 NG::BorderColorProperty borderColor;
10892 if (ParseBorderColorProps(colorValue, borderColor)) {
10893 properties.borderColor = borderColor;
10894 } else {
10895 borderColor.SetColor(Color::BLACK);
10896 properties.borderColor = borderColor;
10897 }
10898 // Parse border style
10899 auto styleValue = obj->GetProperty("borderStyle");
10900 NG::BorderStyleProperty borderStyle;
10901 if (ParseBorderStyleProps(styleValue, borderStyle)) {
10902 properties.borderStyle = borderStyle;
10903 } else {
10904 properties.borderStyle = NG::BorderStyleProperty(
10905 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
10906 }
10907 }
10908 auto shadowValue = obj->GetProperty("shadow");
10909 Shadow shadow;
10910 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
10911 properties.shadow = shadow;
10912 }
10913 auto widthValue = obj->GetProperty("width");
10914 CalcDimension width;
10915 if (ParseJsDimensionVpNG(widthValue, width, true)) {
10916 properties.width = width;
10917 }
10918 auto heightValue = obj->GetProperty("height");
10919 CalcDimension height;
10920 if (ParseJsDimensionVpNG(heightValue, height, true)) {
10921 properties.height = height;
10922 }
10923 }
10924
SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10925 void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
10926 {
10927 auto enableHoverModeValue = obj->GetProperty("enableHoverMode");
10928 if (enableHoverModeValue->IsBoolean()) {
10929 properties.enableHoverMode = enableHoverModeValue->ToBoolean();
10930 }
10931
10932 // Parse hoverModeArea
10933 auto hoverModeAreaValue = obj->GetProperty("hoverModeArea");
10934 if (hoverModeAreaValue->IsNumber()) {
10935 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
10936 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
10937 properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
10938 }
10939 }
10940 }
10941
ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)10942 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId)
10943 {
10944 auto* vm = info.GetVm();
10945 return [vm, nodeId](const std::string& key) -> std::string {
10946 std::string resultString = std::string();
10947 CHECK_NULL_RETURN(vm, resultString);
10948 panda::LocalScope scope(vm);
10949 auto global = JSNApi::GetGlobalObject(vm);
10950 auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__"));
10951 if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) {
10952 return resultString;
10953 }
10954 auto obj = getCustomProperty->ToObject(vm);
10955 panda::Local<panda::FunctionRef> func = obj;
10956 panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId),
10957 panda::StringRef::NewFromUtf8(vm, key.c_str()) };
10958 auto function = panda::CopyableGlobal(vm, func);
10959 auto callValue = function->Call(vm, function.ToLocal(), params2, 2);
10960 if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) {
10961 return resultString;
10962 }
10963 auto value = callValue->ToString(vm)->ToString(vm);
10964 return value;
10965 };
10966 }
10967
ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)10968 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId)
10969 {
10970 auto* vm = info.GetVm();
10971 panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(),
10972 info[1]->GetLocalHandle() };
10973 return [vm, params3]() -> bool {
10974 CHECK_NULL_RETURN(vm, false);
10975 panda::LocalScope scope(vm);
10976 auto global = JSNApi::GetGlobalObject(vm);
10977 auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__"));
10978 if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) {
10979 return false;
10980 }
10981 auto obj = setCustomProperty->ToObject(vm);
10982 panda::Local<panda::FunctionRef> func = obj;
10983 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
10984 auto nodeId = frameNode->GetId();
10985 auto function = panda::CopyableGlobal(vm, func);
10986 auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value();
10987 if (customPropertyExisted) {
10988 frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void {
10989 CHECK_NULL_VOID(vm);
10990 panda::LocalScope scope(vm);
10991 auto global = JSNApi::GetGlobalObject(vm);
10992 auto removeCustomProperty =
10993 global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__"));
10994 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) {
10995 return;
10996 }
10997 auto obj = removeCustomProperty->ToObject(vm);
10998 panda::Local<panda::FunctionRef> func = obj;
10999 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) };
11000 auto function = panda::CopyableGlobal(vm, func);
11001 function->Call(vm, function.ToLocal(), params, 1);
11002 });
11003 }
11004 return true;
11005 };
11006 }
11007
JsCustomProperty(const JSCallbackInfo & info)11008 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info)
11009 {
11010 if (info[0]->GetLocalHandle()->IsUndefined()) {
11011 return;
11012 }
11013 auto* vm = info.GetVm();
11014 CHECK_NULL_VOID(vm);
11015 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode());
11016 auto nodeId = frameNode->GetId();
11017 auto getFunc = ParseJsGetFunc(info, nodeId);
11018 auto func = ParseJsFunc(info, nodeId);
11019 frameNode->SetJSCustomProperty(func, getFunc);
11020 }
11021
JsGestureModifier(const JSCallbackInfo & info)11022 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info)
11023 {
11024 auto* vm = info.GetExecutionContext().vm_;
11025 CHECK_NULL_VOID(vm);
11026 auto global = JSNApi::GetGlobalObject(vm);
11027 auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__"));
11028 if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) {
11029 return;
11030 }
11031 auto obj = gestureModifier->ToObject(vm);
11032 panda::Local<panda::FunctionRef> func = obj;
11033 auto thisObj = info.This()->GetLocalHandle();
11034 panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() };
11035 func->Call(vm, thisObj, params, 1);
11036 }
11037
JsBackgroundImageResizable(const JSCallbackInfo & info)11038 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info)
11039 {
11040 auto infoObj = info[0];
11041 ImageResizableSlice sliceResult;
11042 if (!infoObj->IsObject()) {
11043 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11044 return;
11045 }
11046 JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
11047 if (resizableObject->IsEmpty()) {
11048 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11049 return;
11050 }
11051 auto sliceValue = resizableObject->GetProperty("slice");
11052 if (!sliceValue->IsObject()) {
11053 return;
11054 }
11055 JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
11056 if (sliceObj->IsEmpty()) {
11057 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11058 return;
11059 }
11060 for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) {
11061 auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str());
11062 CalcDimension sliceDimension;
11063 if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
11064 continue;
11065 }
11066 if (!sliceDimension.IsValid()) {
11067 continue;
11068 }
11069 switch (static_cast<BorderImageDirection>(i)) {
11070 case BorderImageDirection::LEFT:
11071 sliceResult.left = sliceDimension;
11072 break;
11073 case BorderImageDirection::RIGHT:
11074 sliceResult.right = sliceDimension;
11075 break;
11076 case BorderImageDirection::TOP:
11077 sliceResult.top = sliceDimension;
11078 break;
11079 case BorderImageDirection::BOTTOM:
11080 sliceResult.bottom = sliceDimension;
11081 break;
11082 default:
11083 break;
11084 }
11085 }
11086 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult);
11087 }
11088
JsFocusScopeId(const JSCallbackInfo & info)11089 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info)
11090 {
11091 if (info.Length() == 0) {
11092 return;
11093 }
11094
11095 std::string focusScopeId;
11096 if (info[0]->IsString()) {
11097 focusScopeId = info[0]->ToString();
11098 }
11099
11100 bool isGroup = false;
11101 if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() &&
11102 info[1]->IsBoolean()) {
11103 isGroup = info[1]->ToBoolean();
11104 }
11105 bool arrowKeyStepOut = true;
11106 if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() &&
11107 info[2]->IsBoolean()) {
11108 arrowKeyStepOut = info[2]->ToBoolean();
11109 }
11110 ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut);
11111 }
11112
JsFocusScopePriority(const JSCallbackInfo & info)11113 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info)
11114 {
11115 if (info.Length() == 0) {
11116 return;
11117 }
11118
11119 if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) {
11120 return;
11121 }
11122 std::string focusScopeId = info[0]->ToString();
11123
11124 int32_t focusPriority = 0;
11125 if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() &&
11126 info[1]->IsNumber()) {
11127 focusPriority = info[1]->ToNumber<int32_t>();
11128 }
11129 ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority);
11130 }
11131
ParseJsPropertyId(const JSRef<JSVal> & jsValue)11132 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue)
11133 {
11134 int32_t resId = 0;
11135 if (jsValue->IsObject()) {
11136 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
11137 JSRef<JSVal> tmp = jsObj->GetProperty("id");
11138 if (!tmp->IsNull() && tmp->IsNumber()) {
11139 resId = tmp->ToNumber<int32_t>();
11140 }
11141 }
11142 return resId;
11143 }
11144
JsVisualEffect(const JSCallbackInfo & info)11145 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info)
11146 {
11147 if (!info[0]->IsObject()) {
11148 return;
11149 }
11150 auto visualEffect = CreateRSEffectFromNapiValue(info[0]);
11151 ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect);
11152 }
11153
JsBackgroundFilter(const JSCallbackInfo & info)11154 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info)
11155 {
11156 if (!info[0]->IsObject()) {
11157 return;
11158 }
11159 auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]);
11160 ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter);
11161 }
11162
JsForegroundFilter(const JSCallbackInfo & info)11163 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info)
11164 {
11165 if (!info[0]->IsObject()) {
11166 return;
11167 }
11168 auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]);
11169 ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter);
11170 }
11171
JsCompositingFilter(const JSCallbackInfo & info)11172 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info)
11173 {
11174 if (!info[0]->IsObject()) {
11175 return;
11176 }
11177 auto compositingFilter = CreateRSFilterFromNapiValue(info[0]);
11178 ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter);
11179 }
11180
ParseMenuItems(const JSRef<JSArray> & menuItemsArray)11181 std::vector<NG::MenuOptionsParam> JSViewAbstract::ParseMenuItems(const JSRef<JSArray>& menuItemsArray)
11182 {
11183 std::vector<NG::MenuOptionsParam> menuParams;
11184 for (size_t i = 0; i <= menuItemsArray->Length(); i++) {
11185 auto menuItem = menuItemsArray->GetValueAt(i);
11186 if (!menuItem->IsObject()) {
11187 continue;
11188 }
11189 auto menuItemObject = JSRef<JSObject>::Cast(menuItem);
11190 NG::MenuOptionsParam menuOptionsParam;
11191 auto jsContent = menuItemObject->GetProperty("content");
11192 std::string content;
11193 ParseJsString(jsContent, content);
11194 menuOptionsParam.content = content;
11195 auto jsStartIcon = menuItemObject->GetProperty("icon");
11196 std::string icon;
11197 ParseJsMedia(jsStartIcon, icon);
11198 menuOptionsParam.icon = icon;
11199 auto jsTextMenuId = menuItemObject->GetProperty("id");
11200 std::string id;
11201 if (jsTextMenuId->IsObject()) {
11202 auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId);
11203 auto jsId = textMenuIdObject->GetProperty("id_");
11204 ParseJsString(jsId, id);
11205 }
11206 menuOptionsParam.id = id;
11207 auto jsLabelInfo = menuItemObject->GetProperty("labelInfo");
11208 std::string labelInfo;
11209 ParseJsString(jsLabelInfo, labelInfo);
11210 if (jsLabelInfo->IsString() || jsLabelInfo->IsObject()) {
11211 menuOptionsParam.labelInfo = labelInfo;
11212 }
11213 menuParams.emplace_back(menuOptionsParam);
11214 }
11215 return menuParams;
11216 }
11217
ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)11218 void JSViewAbstract::ParseOnCreateMenu(
11219 const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback)
11220 {
11221 if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) {
11222 return;
11223 }
11224 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11225 auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>(
11226 JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems);
11227 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu),
11228 instanceId = Container::CurrentId(), node = frameNode](
11229 const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> {
11230 ContainerScope scope(instanceId);
11231 std::vector<NG::MenuOptionsParam> menuParams;
11232 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams);
11233 auto pipelineContext = PipelineContext::GetCurrentContext();
11234 CHECK_NULL_RETURN(pipelineContext, menuParams);
11235
11236 pipelineContext->UpdateCurrentActiveNode(node);
11237 auto modifiedSystemMenuItems = systemMenuItems;
11238 UpdateOptionsLabelInfo(modifiedSystemMenuItems);
11239 auto menuItem = func->ExecuteWithValue(modifiedSystemMenuItems);
11240 if (!menuItem->IsArray()) {
11241 return menuParams;
11242 }
11243 auto menuItemsArray = JSRef<JSArray>::Cast(menuItem);
11244 menuParams = ParseMenuItems(menuItemsArray);
11245 return menuParams;
11246 };
11247 onCreateMenuCallback = jsCallback;
11248 }
11249
CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)11250 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems)
11251 {
11252 JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New();
11253 uint32_t idx = 0;
11254 for (const auto& item : systemMenuItems) {
11255 systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item));
11256 }
11257 return systemMenuItemsArray;
11258 }
11259
ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)11260 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback,
11261 NG::OnMenuItemClickCallback& onMenuItemClick)
11262 {
11263 auto tmpInfo = info[0];
11264 if (info.Length() != 1 || !tmpInfo->IsObject()) {
11265 return false;
11266 }
11267 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
11268 auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo);
11269 auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu");
11270 ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback);
11271
11272 auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick");
11273 if (jsValue.IsEmpty() || !jsValue->IsFunction()) {
11274 return false;
11275 }
11276 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue));
11277 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11278 onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(),
11279 node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool {
11280 ContainerScope scope(instanceId);
11281 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
11282 auto pipelineContext = PipelineContext::GetCurrentContext();
11283 CHECK_NULL_RETURN(pipelineContext, false);
11284 pipelineContext->UpdateCurrentActiveNode(node);
11285 auto paramArray = onMenuItemCallback(menuOptionsParam);
11286 if (paramArray->Length() != 2) {
11287 return false;
11288 }
11289 JSRef<JSVal> params[2];
11290 params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0));
11291 params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1));
11292 auto ret = func->ExecuteJS(2, params);
11293 if (ret->IsBoolean()) {
11294 return ret->ToBoolean();
11295 }
11296 return false;
11297 };
11298 onMenuItemClick = jsCallback;
11299 return true;
11300 }
11301
CreateJsTextMenuId(const std::string & id)11302 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id)
11303 {
11304 JSRef<JSObject> empty;
11305 auto engine = EngineHelper::GetCurrentEngine();
11306 CHECK_NULL_RETURN(engine, empty);
11307 NativeEngine* nativeEngine = engine->GetNativeEngine();
11308 CHECK_NULL_RETURN(nativeEngine, empty);
11309 auto env = reinterpret_cast<napi_env>(nativeEngine);
11310
11311 napi_value global;
11312 napi_status ret = napi_get_global(env, &global);
11313 if (ret != napi_ok) {
11314 return empty;
11315 }
11316 napi_value constructor;
11317 ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor);
11318 if (ret != napi_ok) {
11319 return empty;
11320 }
11321
11322 napi_value obj;
11323 napi_value menuId = nullptr;
11324
11325 ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId);
11326 if (ret != napi_ok) {
11327 return empty;
11328 }
11329 ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj);
11330 if (ret != napi_ok) {
11331 return empty;
11332 }
11333
11334 JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj);
11335 if (!value->IsObject()) {
11336 return empty;
11337 }
11338
11339 return JSRef<JSObject>::Cast(value);
11340 }
11341
CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)11342 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam)
11343 {
11344 JSRef<JSArray> params = JSRef<JSArray>::New();
11345 params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam));
11346 params->SetValueAt(1, CreateJsTextRange(menuItemParam));
11347 return params;
11348 }
11349
CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)11350 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam)
11351 {
11352 JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New();
11353 TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or(""));
11354 JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id);
11355 TextMenuItem->SetPropertyObject("id", obj);
11356 TextMenuItem->SetProperty<std::string>("labelInfo", menuItemParam.menuOptionsParam.labelInfo.value_or(""));
11357 return JSRef<JSVal>::Cast(TextMenuItem);
11358 }
11359
CreateJsTextRange(const NG::MenuItemParam & menuItemParam)11360 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam)
11361 {
11362 JSRef<JSObject> textRange = JSRef<JSObject>::New();
11363 textRange->SetProperty<int32_t>("start", menuItemParam.start);
11364 textRange->SetProperty<int32_t>("end", menuItemParam.end);
11365 return JSRef<JSVal>::Cast(textRange);
11366 }
11367
OHOS_ACE_ParseJsMedia(void * value,void * resource)11368 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource)
11369 {
11370 napi_value napiValue = reinterpret_cast<napi_value>(value);
11371 ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource);
11372 if (!napiValue || !res) {
11373 return;
11374 }
11375 JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue);
11376 std::string src;
11377 std::string bundleName;
11378 std::string moduleName;
11379 JSViewAbstract::ParseJsMedia(jsVal, src);
11380 JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName);
11381 res->resId = JSViewAbstract::ParseJsPropertyId(jsVal);
11382 res->src = src;
11383 res->bundleName = bundleName;
11384 res->moduleName = moduleName;
11385 }
11386
SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)11387 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info,
11388 std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj)
11389 {
11390 if (!modifierObj->IsObject()) {
11391 textStyleApply = nullptr;
11392 return;
11393 }
11394 auto vm = info.GetVm();
11395 auto globalObj = JSNApi::GetGlobalObject(vm);
11396 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode"));
11397 JsiValue jsiValue(globalFunc);
11398 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11399 if (!globalFuncRef->IsFunction()) {
11400 textStyleApply = nullptr;
11401 return;
11402 }
11403 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11404 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11405 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11406 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11407 auto node = frameNode.Upgrade();
11408 CHECK_NULL_VOID(node);
11409 JSRef<JSVal> params[2];
11410 params[0] = modifierParam;
11411 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11412 PipelineContext::SetCallBackNode(node);
11413 func->ExecuteJS(2, params);
11414 };
11415 textStyleApply = onApply;
11416 }
11417
SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)11418 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info,
11419 std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj)
11420 {
11421 auto vm = info.GetVm();
11422 auto globalObj = JSNApi::GetGlobalObject(vm);
11423 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode"));
11424 JsiValue jsiValue(globalFunc);
11425 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue);
11426 if (globalFuncRef->IsFunction()) {
11427 RefPtr<JsFunction> jsFunc =
11428 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef));
11429 if (!modifierObj->IsObject()) {
11430 symbolApply = nullptr;
11431 } else {
11432 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
11433 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) {
11434 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
11435 auto node = frameNode.Upgrade();
11436 CHECK_NULL_VOID(node);
11437 JSRef<JSVal> params[2];
11438 params[0] = modifierParam;
11439 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node)));
11440 PipelineContext::SetCallBackNode(node);
11441 func->ExecuteJS(2, params);
11442 };
11443 symbolApply = onApply;
11444 }
11445 }
11446 }
11447 } // namespace OHOS::Ace::Framework
11448