1 /*
2 * Copyright (c) 2021-2023 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/utils.h"
42 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
43 #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h"
44 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
45 #include "bridge/declarative_frontend/engine/functions/js_on_child_touch_test_function.h"
46 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h"
47 #include "bridge/declarative_frontend/engine/functions/js_function.h"
48 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
49 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h"
50 #include "bridge/declarative_frontend/engine/functions/js_key_function.h"
51 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h"
52 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
53 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h"
54 #include "bridge/declarative_frontend/jsview/js_grid_container.h"
55 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
56 #include "bridge/declarative_frontend/jsview/js_utils.h"
57 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
58 #include "bridge/declarative_frontend/jsview/js_view_context.h"
59 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
60 #include "core/common/resource/resource_manager.h"
61 #include "core/common/resource/resource_object.h"
62 #include "core/components/common/layout/constants.h"
63 #include "core/components/common/layout/screen_system_manager.h"
64 #include "core/components/common/properties/animation_option.h"
65 #include "core/components/common/properties/border_image.h"
66 #include "core/components/common/properties/color.h"
67 #include "core/components/common/properties/decoration.h"
68 #include "core/components/common/properties/invert.h"
69 #include "core/components/common/properties/shadow.h"
70 #include "core/components/common/properties/shadow_config.h"
71 #include "core/components/theme/resource_adapter.h"
72 #include "core/components/theme/shadow_theme.h"
73 #include "core/components_ng/base/view_abstract_model.h"
74 #include "core/components_ng/base/view_stack_processor.h"
75 #include "core/components_ng/gestures/base_gesture_event.h"
76 #include "core/components_ng/pattern/menu/menu_pattern.h"
77 #include "core/components_ng/pattern/overlay/modal_style.h"
78 #include "core/components_ng/property/safe_area_insets.h"
79 #include "core/gestures/gesture_info.h"
80 #include "core/image/image_source_info.h"
81 #ifdef PLUGIN_COMPONENT_SUPPORTED
82 #include "core/common/plugin_manager.h"
83 #endif
84 #include "core/common/card_scope.h"
85 #include "core/common/container.h"
86 #include "core/components/progress/progress_theme.h"
87 #include "core/components_ng/base/view_abstract_model_ng.h"
88 #include "core/components_ng/base/view_stack_model.h"
89 #include "core/components_ng/property/progress_mask_property.h"
90
91 namespace OHOS::Ace {
92
93 std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr;
94 std::mutex ViewAbstractModel::mutex_;
95 using DoubleBindCallback = std::function<void(const std::string&)>;
96
GetInstance()97 ViewAbstractModel* ViewAbstractModel::GetInstance()
98 {
99 if (!instance_) {
100 std::lock_guard<std::mutex> lock(mutex_);
101 if (!instance_) {
102 #ifdef NG_BUILD
103 instance_.reset(new NG::ViewAbstractModelNG());
104 #else
105 if (Container::IsCurrentUseNewPipeline()) {
106 instance_.reset(new NG::ViewAbstractModelNG());
107 } else {
108 instance_.reset(new Framework::ViewAbstractModelImpl());
109 }
110 #endif
111 }
112 }
113 return instance_.get();
114 }
115
116 } // namespace OHOS::Ace
117
118 namespace OHOS::Ace::Framework {
119 namespace {
120
121 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
122 constexpr int64_t MICROSEC_TO_MILLISEC = 1000;
123 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
124 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
125 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
126 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
127 constexpr int32_t MAX_ALIGN_VALUE = 8;
128 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
129 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
130 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
131 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
132 constexpr double FULL_DIMENSION = 100.0;
133 constexpr double HALF_DIMENSION = 50.0;
134 constexpr double ROUND_UNIT = 360.0;
135 constexpr double VISIBLE_RATIO_MIN = 0.0;
136 constexpr double VISIBLE_RATIO_MAX = 1.0;
137 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
138 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
139 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
140 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
141 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
142 constexpr float MAX_ANGLE = 360.0f;
143 constexpr float DEFAULT_BIAS = 0.5f;
144 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
145 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location" };
146 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
147 const std::string SHEET_HEIGHT_MEDIUM = "medium";
148 const std::string SHEET_HEIGHT_LARGE = "large";
149 const std::string SHEET_HEIGHT_AUTO = "auto";
150 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
151 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius";
152 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color";
153 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width";
154
155 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
156 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
157 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
158
CheckJSCallbackInfo(const std::string & callerName,const JSCallbackInfo & info,std::vector<JSCallbackInfoType> & infoTypes)159 bool CheckJSCallbackInfo(
160 const std::string& callerName, const JSCallbackInfo& info, std::vector<JSCallbackInfoType>& infoTypes)
161 {
162 bool typeVerified = false;
163 std::string unrecognizedType;
164 auto tmpInfo = info[0];
165 for (const auto& infoType : infoTypes) {
166 switch (infoType) {
167 case JSCallbackInfoType::STRING:
168 if (tmpInfo->IsString()) {
169 typeVerified = true;
170 } else {
171 unrecognizedType += "string|";
172 }
173 break;
174 case JSCallbackInfoType::NUMBER:
175 if (tmpInfo->IsNumber()) {
176 typeVerified = true;
177 } else {
178 unrecognizedType += "number|";
179 }
180 break;
181 case JSCallbackInfoType::OBJECT:
182 if (tmpInfo->IsObject()) {
183 typeVerified = true;
184 } else {
185 unrecognizedType += "object|";
186 }
187 break;
188 case JSCallbackInfoType::FUNCTION:
189 if (tmpInfo->IsFunction()) {
190 typeVerified = true;
191 } else {
192 unrecognizedType += "Function|";
193 }
194 break;
195 default:
196 break;
197 }
198 }
199 if (!typeVerified) {
200 LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(),
201 unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str());
202 }
203 return typeVerified || infoTypes.size() == 0;
204 }
205
ParseJsonScale(std::unique_ptr<JsonValue> & argsPtrItem,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)206 void ParseJsonScale(std::unique_ptr<JsonValue>& argsPtrItem, float& scaleX, float& scaleY, float& scaleZ,
207 CalcDimension& centerX, CalcDimension& centerY)
208 {
209 double xVal = 1.0;
210 double yVal = 1.0;
211 double zVal = 1.0;
212 if (!argsPtrItem->IsObject() && !argsPtrItem->IsNumber() && !argsPtrItem->IsString()) {
213 scaleX = static_cast<float>(xVal);
214 scaleY = static_cast<float>(yVal);
215 scaleZ = static_cast<float>(zVal);
216 CalcDimension length;
217 centerX = length;
218 centerY = length;
219 return;
220 }
221 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), xVal);
222 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), yVal);
223 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), zVal);
224 scaleX = static_cast<float>(xVal);
225 scaleY = static_cast<float>(yVal);
226 scaleZ = static_cast<float>(zVal);
227 // if specify centerX
228 CalcDimension length;
229 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length)) {
230 centerX = length;
231 }
232 // if specify centerY
233 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length)) {
234 centerY = length;
235 }
236 }
237
ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)238 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ,
239 CalcDimension& centerX, CalcDimension& centerY)
240 {
241 double xVal = 1.0;
242 double yVal = 1.0;
243 double zVal = 1.0;
244 if (!jsValue->IsObject()) {
245 scaleX = static_cast<float>(xVal);
246 scaleY = static_cast<float>(yVal);
247 scaleZ = static_cast<float>(zVal);
248 CalcDimension length;
249 centerX = length;
250 centerY = length;
251 return;
252 }
253 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
254 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("x"), xVal);
255 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("y"), yVal);
256 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("z"), zVal);
257 scaleX = static_cast<float>(xVal);
258 scaleY = static_cast<float>(yVal);
259 scaleZ = static_cast<float>(zVal);
260 // if specify centerX
261 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("centerX"), centerX);
262 // if specify centerY
263 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("centerY"), centerY);
264 }
265
ParseJsonTranslate(std::unique_ptr<JsonValue> & argsPtrItem,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)266 void ParseJsonTranslate(std::unique_ptr<JsonValue>& argsPtrItem, CalcDimension& translateX, CalcDimension& translateY,
267 CalcDimension& translateZ)
268 {
269 CalcDimension length;
270 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("x"), length)) {
271 translateX = length;
272 }
273 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("y"), length)) {
274 translateY = length;
275 }
276 if (JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("z"), length)) {
277 translateZ = length;
278 }
279 }
280
ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)281 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY,
282 CalcDimension& translateZ)
283 {
284 if (!jsValue->IsObject()) {
285 return;
286 }
287 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
288 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("x"), translateX);
289 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("y"), translateY);
290 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("z"), translateZ);
291 }
292
GetDefaultRotateVector(double & dx,double & dy,double & dz)293 void GetDefaultRotateVector(double& dx, double& dy, double& dz)
294 {
295 dx = 0.0;
296 dy = 0.0;
297 dz = 0.0;
298 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) {
299 dz = 1.0;
300 }
301 }
302
ParseJsonRotate(std::unique_ptr<JsonValue> & argsPtrItem,NG::RotateOptions & rotate,std::optional<float> & angle)303 void ParseJsonRotate(std::unique_ptr<JsonValue>& argsPtrItem, NG::RotateOptions& rotate, std::optional<float>& angle)
304 {
305 // default: dx, dy, dz (0.0, 0.0, 0.0)
306 double dxVal = 0.0;
307 double dyVal = 0.0;
308 double dzVal = 0.0;
309 if (!argsPtrItem->Contains("x") && !argsPtrItem->Contains("y") && !argsPtrItem->Contains("z")) {
310 GetDefaultRotateVector(dxVal, dyVal, dzVal);
311 }
312 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("x"), dxVal);
313 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("y"), dyVal);
314 JSViewAbstract::ParseJsonDouble(argsPtrItem->GetValue("z"), dzVal);
315 rotate.xDirection = static_cast<float>(dxVal);
316 rotate.yDirection = static_cast<float>(dyVal);
317 rotate.zDirection = static_cast<float>(dzVal);
318 // if specify centerX
319 CalcDimension length;
320 if (!JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerX"), length, true)) {
321 length = Dimension(0.5f, DimensionUnit::PERCENT);
322 }
323 rotate.centerX = length;
324 // if specify centerY
325
326 if (!JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerY"), length, true)) {
327 length = Dimension(0.5f, DimensionUnit::PERCENT);
328 }
329 rotate.centerY = length;
330
331 // if specify centerZ
332 if (!JSViewAbstract::ParseJsonDimensionVp(argsPtrItem->GetValue("centerZ"), length, true)) {
333 length = Dimension(0.5f, DimensionUnit::PERCENT);
334 }
335 rotate.centerZ = length;
336 // if specify angle
337 JSViewAbstract::GetAngle("angle", argsPtrItem, angle);
338 float perspective = 0.0f;
339 JSViewAbstract::GetPerspective("perspective", argsPtrItem, perspective);
340 rotate.perspective = perspective;
341 }
342
ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)343 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle)
344 {
345 if (!jsValue->IsObject()) {
346 return;
347 }
348 // default: dx, dy, dz (0.0, 0.0, 0.0)
349 double dxVal = 0.0;
350 double dyVal = 0.0;
351 double dzVal = 0.0;
352 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
353 if (!jsObj->HasProperty("x") && !jsObj->HasProperty("y") && !jsObj->HasProperty("z")) {
354 GetDefaultRotateVector(dxVal, dyVal, dzVal);
355 } else {
356 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("x"), dxVal);
357 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("y"), dyVal);
358 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("z"), dzVal);
359 }
360 rotate.xDirection = static_cast<float>(dxVal);
361 rotate.yDirection = static_cast<float>(dyVal);
362 rotate.zDirection = static_cast<float>(dzVal);
363 // if specify centerX
364 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("centerX"), rotate.centerX)) {
365 rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT);
366 }
367 // if specify centerY
368 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("centerY"), rotate.centerY)) {
369 rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT);
370 }
371 // if specify centerZ
372 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("centerZ"), rotate.centerZ)) {
373 rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT);
374 }
375 // if specify angle
376 JSViewAbstract::GetJsAngle("angle", jsObj, angle);
377 rotate.perspective = 0.0f;
378 JSViewAbstract::GetJsPerspective("perspective", jsObj, rotate.perspective);
379 }
380
ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)381 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option)
382 {
383 if (!jsValue->IsObject()) {
384 return false;
385 }
386
387 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
388 auto path = jsObj->GetPropertyValue<std::string>("path", "");
389 if (path.empty()) {
390 return false;
391 }
392 option.SetPath(path);
393 double from = 0.0;
394 double to = 1.0;
395 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from);
396 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to);
397 if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) {
398 from = 0.0;
399 }
400 if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) {
401 to = 1.0;
402 } else if (to < from) {
403 to = from;
404 }
405 option.SetBegin(static_cast<float>(from));
406 option.SetEnd(static_cast<float>(to));
407 option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false));
408 return true;
409 }
410
SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)411 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY,
412 BackgroundImagePosition& bgImgPosition)
413 {
414 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
415 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option));
416 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option));
417 }
418
GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)419 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount)
420 {
421 JSRef<JSVal> item = params->GetValueAt(pos + containCount);
422 if (type == "d") {
423 if (item->IsNumber()) {
424 return std::to_string(item->ToNumber<uint32_t>());
425 }
426 } else if (type == "s") {
427 if (item->IsString()) {
428 return item->ToString();
429 }
430 } else if (type == "f") {
431 if (item->IsNumber()) {
432 return std::to_string(item->ToNumber<float>());
433 }
434 }
435 return std::string();
436 }
437
ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)438 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount)
439 {
440 auto size = static_cast<int32_t>(params->Length());
441 if (containCount == size) {
442 return;
443 }
444 std::string::const_iterator start = originStr.begin();
445 std::string::const_iterator end = originStr.end();
446 std::smatch matches;
447 bool shortHolderType = false;
448 bool firstMatch = true;
449 int searchTime = 0;
450 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
451 std::string pos = matches[2];
452 std::string type = matches[4];
453 if (firstMatch) {
454 firstMatch = false;
455 shortHolderType = pos.length() == 0;
456 } else {
457 if (shortHolderType ^ (pos.length() == 0)) {
458 return;
459 }
460 }
461
462 std::string replaceContentStr;
463 if (shortHolderType) {
464 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
465 } else {
466 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount);
467 }
468
469 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
470 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
471 end = originStr.end();
472 searchTime++;
473 }
474 }
475
ParseLocationProps(const JSCallbackInfo & info,CalcDimension & x,CalcDimension & y)476 bool ParseLocationProps(const JSCallbackInfo& info, CalcDimension& x, CalcDimension& y)
477 {
478 JSRef<JSVal> arg = info[0];
479 if (!arg->IsObject()) {
480 return false;
481 }
482 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(arg);
483 JSRef<JSVal> xVal = sizeObj->GetProperty("x");
484 JSRef<JSVal> yVal = sizeObj->GetProperty("y");
485 bool hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP);
486 bool hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP);
487 return hasX || hasY;
488 }
489
ParseDragStartBuilderFunc(const JSRef<JSVal> & info)490 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info)
491 {
492 JSRef<JSVal> builder;
493 if (info->IsObject()) {
494 auto builderObj = JSRef<JSObject>::Cast(info);
495 builder = builderObj->GetProperty("builder");
496 } else if (info->IsFunction()) {
497 builder = info;
498 } else {
499 return nullptr;
500 }
501
502 if (!builder->IsFunction()) {
503 return nullptr;
504 }
505
506 return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
507 }
508
509 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
510 const JSRef<JSObject>& object, const JSExecutionContext& context);
511
ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)512 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition(
513 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
514 {
515 RefPtr<NG::ChainedTransitionEffect> effect;
516 if (effectOption->IsObject()) {
517 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
518 std::optional<float> angle;
519 ParseJsRotate(effectOption, rotate, angle);
520 if (angle.has_value()) {
521 rotate.angle = angle.value();
522 return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate);
523 }
524 }
525 return nullptr;
526 }
527
ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)528 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition(
529 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
530 {
531 double opacity = 1.0;
532 if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) {
533 if ((LessNotEqual(opacity, 0.0)) || opacity > 1.0) {
534 opacity = 1.0;
535 }
536 return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity);
537 }
538 return nullptr;
539 }
540
ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)541 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition(
542 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
543 {
544 if (effectOption->IsObject()) {
545 // default: x, y, z (0.0, 0.0, 0.0)
546 NG::TranslateOptions translate;
547 ParseJsTranslate(effectOption, translate.x, translate.y, translate.z);
548 return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate);
549 }
550 return nullptr;
551 }
552
ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)553 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition(
554 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
555 {
556 if (effectOption->IsObject()) {
557 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
558 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
559 ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
560 return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale);
561 }
562 return nullptr;
563 }
564
ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)565 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition(
566 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
567 {
568 int32_t edge = 0;
569 if (JSViewAbstract::ParseJsInt32(effectOption, edge)) {
570 if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) ||
571 edge > static_cast<int32_t>(NG::TransitionEdge::END)) {
572 edge = static_cast<int32_t>(NG::TransitionEdge::START);
573 }
574 return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge));
575 }
576 return nullptr;
577 }
578
ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)579 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition(
580 const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
581 {
582 if (effectOption->IsObject()) {
583 auto effectObj = JSRef<JSObject>::Cast(effectOption);
584 auto appearJsVal = effectObj->GetProperty("appear");
585 auto disappearJsVal = effectObj->GetProperty("disappear");
586 RefPtr<NG::ChainedTransitionEffect> appearEffect;
587 RefPtr<NG::ChainedTransitionEffect> disappearEffect;
588 if (appearJsVal->IsObject()) {
589 auto appearObj = JSRef<JSObject>::Cast(appearJsVal);
590 appearEffect = ParseChainedTransition(appearObj, context);
591 }
592 if (disappearJsVal->IsObject()) {
593 auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal);
594 disappearEffect = ParseChainedTransition(disappearObj, context);
595 }
596 return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect);
597 }
598 return nullptr;
599 }
600
GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)601 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext)
602 {
603 CHECK_NULL_RETURN(pipelineContext, 0);
604 return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC;
605 }
606
607 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)(
608 const JSRef<JSVal>&, const JSExecutionContext&);
609
ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)610 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition(
611 const JSRef<JSObject>& object, const JSExecutionContext& context)
612 {
613 auto propType = object->GetProperty("type_");
614 if (!propType->IsString()) {
615 return nullptr;
616 }
617 std::string type = propType->ToString();
618 auto propEffectOption = object->GetProperty("effect_");
619 auto propAnimationOption = object->GetProperty("animation_");
620 auto propSuccessor = object->GetProperty("successor_");
621 static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = {
622 { "asymmetric", ParseChainedAsymmetricTransition },
623 { "identity",
624 [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context)
625 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } },
626 { "move", ParseChainedMoveTransition },
627 { "opacity", ParseChainedOpacityTransition },
628 { "rotate", ParseChainedRotateTransition },
629 { "scale", ParseChainedScaleTransition },
630 { "slideSwitch",
631 [](const JSRef<JSVal>& effectOption,
632 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> {
633 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>();
634 } },
635 { "translate", ParseChainedTranslateTransition },
636 };
637 int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str());
638 if (index < 0) {
639 return nullptr;
640 }
641 RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context);
642 if (!result) {
643 return nullptr;
644 }
645 if (propAnimationOption->IsObject()) {
646 auto container = Container::Current();
647 CHECK_NULL_RETURN(container, nullptr);
648 auto pipelineContext = container->GetPipelineContext();
649 CHECK_NULL_RETURN(pipelineContext, nullptr);
650 auto animationOptionResult = std::make_shared<AnimationOption>(
651 JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRender()));
652 // The maximum of the form-animation-playback duration value is 1000 ms.
653 if (pipelineContext->IsFormRender() && pipelineContext->IsFormAnimation()) {
654 auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext);
655 // If the duration exceeds 1000ms, init it to 0 ms.
656 if (formAnimationTimeInterval > DEFAULT_DURATION) {
657 animationOptionResult->SetDuration(0);
658 } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) {
659 // If remaining time is less than 1000ms, check for update duration.
660 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval);
661 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form Transition SetDuration: %{public}lld ms",
662 static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval));
663 }
664 }
665 auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption);
666 JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish");
667 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
668 if (onFinish->IsFunction()) {
669 RefPtr<JsFunction> jsFunc =
670 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
671 std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc),
672 id = Container::CurrentId(), node = targetNode]() {
673 ContainerScope scope(id);
674 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
675 PipelineContext::SetCallBackNode(node);
676 func->Execute();
677 };
678 animationOptionResult->SetOnFinishEvent(onFinishEvent);
679 }
680 result->SetAnimationOption(animationOptionResult);
681 }
682 if (propSuccessor->IsObject()) {
683 result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context));
684 }
685 return result;
686 }
687
688 #ifndef WEARABLE_PRODUCT
689 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM,
690 Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP,
691 Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM };
692
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)693 DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj)
694 {
695 JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent");
696 if (!changeEvent->IsFunction()) {
697 return {};
698 }
699 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent));
700 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
701 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
702 const std::string& param) {
703 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
704 if (param != "true" && param != "false") {
705 return;
706 }
707 PipelineContext::SetCallBackNode(node);
708 bool newValue = StringToBool(param);
709 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
710 func->ExecuteJS(1, &newJSVal);
711 };
712 return callback;
713 }
714
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)715 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
716 {
717 auto colorValue = messageOptionsObj->GetProperty("textColor");
718 Color textColor;
719 if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
720 if (popupParam) {
721 popupParam->SetTextColor(textColor);
722 }
723 }
724
725 auto font = messageOptionsObj->GetProperty("font");
726 if (!font->IsNull() && font->IsObject()) {
727 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
728 auto fontSizeValue = fontObj->GetProperty("size");
729 CalcDimension fontSize;
730 if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
731 if (popupParam) {
732 popupParam->SetFontSize(fontSize);
733 }
734 }
735 auto fontWeightValue = fontObj->GetProperty("weight");
736 if (fontWeightValue->IsString()) {
737 if (popupParam) {
738 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
739 }
740 }
741 auto fontStyleValue = fontObj->GetProperty("style");
742 if (fontStyleValue->IsNumber()) {
743 int32_t value = fontStyleValue->ToNumber<int32_t>();
744 if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
745 return;
746 }
747 if (popupParam) {
748 popupParam->SetFontStyle(FONT_STYLES[value]);
749 }
750 }
751 }
752 }
753
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)754 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
755 {
756 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
757 if (placementOnTopVal->IsBoolean() && popupParam) {
758 popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
759 }
760 }
761
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)762 void ParsePopupCommonParam(
763 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
764 {
765 auto arrowOffset = popupObj->GetProperty("arrowOffset");
766 CalcDimension offset;
767 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
768 if (popupParam) {
769 popupParam->SetArrowOffset(offset);
770 }
771 }
772
773 auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
774 if (arrowPointPosition->IsString()) {
775 char* pEnd = nullptr;
776 std::strtod(arrowPointPosition->ToString().c_str(), &pEnd);
777 if (pEnd != nullptr) {
778 if (std::strcmp(pEnd, "Start") == 0) {
779 offset = ARROW_ZERO_PERCENT_VALUE;
780 }
781 if (std::strcmp(pEnd, "Center") == 0) {
782 offset = ARROW_HALF_PERCENT_VALUE;
783 }
784 if (std::strcmp(pEnd, "End") == 0) {
785 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
786 }
787 if (popupParam) {
788 popupParam->SetArrowOffset(offset);
789 }
790 }
791 }
792
793 auto targetSpace = popupObj->GetProperty("targetSpace");
794 if (!targetSpace->IsNull()) {
795 CalcDimension space;
796 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
797 if (popupParam) {
798 popupParam->SetTargetSpace(space);
799 }
800 }
801 }
802
803 JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
804 if (showInSubWindowValue->IsBoolean()) {
805 bool showInSubBoolean = showInSubWindowValue->ToBoolean();
806 #if defined(PREVIEW)
807 if (showInSubBoolean) {
808 LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
809 showInSubBoolean = false;
810 }
811 #endif
812 if (popupParam) {
813 popupParam->SetShowInSubWindow(showInSubBoolean);
814 }
815 }
816
817 auto placementValue = popupObj->GetProperty("placement");
818 if (placementValue->IsNumber()) {
819 auto placement = placementValue->ToNumber<int32_t>();
820 if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) {
821 popupParam->SetPlacement(PLACEMENT[placement]);
822 }
823 } else {
824 SetPlacementOnTopVal(popupObj, popupParam);
825 }
826
827 auto enableArrowValue = popupObj->GetProperty("enableArrow");
828 if (enableArrowValue->IsBoolean()) {
829 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
830 }
831
832 JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
833 if (maskValue->IsBoolean()) {
834 if (popupParam) {
835 popupParam->SetBlockEvent(maskValue->ToBoolean());
836 }
837 }
838 if (maskValue->IsObject()) {
839 auto maskObj = JSRef<JSObject>::Cast(maskValue);
840 auto colorValue = maskObj->GetProperty("color");
841 Color maskColor;
842 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
843 popupParam->SetMaskColor(maskColor);
844 }
845 }
846
847 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
848 if (onStateChangeVal->IsFunction()) {
849 std::vector<std::string> keys = { "isVisible" };
850 RefPtr<JsFunction> jsFunc =
851 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
852 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
853 if (popupParam) {
854 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
855 node = targetNode](const std::string& param) {
856 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
857 ACE_SCORING_EVENT("Popup.onStateChange");
858 PipelineContext::SetCallBackNode(node);
859 func->Execute(keys, param);
860 };
861 popupParam->SetOnStateChange(onStateChangeCallback);
862 }
863 }
864
865 auto offsetVal = popupObj->GetProperty("offset");
866 if (offsetVal->IsObject()) {
867 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
868 auto xVal = offsetObj->GetProperty("x");
869 auto yVal = offsetObj->GetProperty("y");
870 Offset popupOffset;
871 CalcDimension dx;
872 CalcDimension dy;
873 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
874 popupOffset.SetX(dx.ConvertToPx());
875 }
876 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
877 popupOffset.SetY(dy.ConvertToPx());
878 }
879 if (popupParam) {
880 popupParam->SetTargetOffset(popupOffset);
881 }
882 }
883
884 Color backgroundColor;
885 auto popupColorVal = popupObj->GetProperty("popupColor");
886 if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
887 popupParam->SetBackgroundColor(backgroundColor);
888 }
889
890 auto autoCancelVal = popupObj->GetProperty("autoCancel");
891 if (autoCancelVal->IsBoolean()) {
892 popupParam->SetHasAction(!autoCancelVal->ToBoolean());
893 }
894
895 auto childWidthVal = popupObj->GetProperty("width");
896 if (!childWidthVal->IsNull()) {
897 CalcDimension width;
898 if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
899 if (width.Value() > 0) {
900 popupParam->SetChildWidth(width);
901 }
902 }
903 }
904
905 auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
906 if (!arrowWidthVal->IsNull()) {
907 bool setError = true;
908 CalcDimension arrowWidth;
909 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
910 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
911 popupParam->SetArrowWidth(arrowWidth);
912 setError = false;
913 }
914 }
915 popupParam->SetErrorArrowWidth(setError);
916 }
917
918 auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
919 if (!arrowHeightVal->IsNull()) {
920 bool setError = true;
921 CalcDimension arrowHeight;
922 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
923 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
924 popupParam->SetArrowHeight(arrowHeight);
925 setError = false;
926 }
927 }
928 popupParam->SetErrorArrowHeight(setError);
929 }
930
931 auto radiusVal = popupObj->GetProperty("radius");
932 if (!radiusVal->IsNull()) {
933 bool setError = true;
934 CalcDimension radius;
935 if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
936 if (radius.Value() >= 0) {
937 popupParam->SetRadius(radius);
938 setError = false;
939 }
940 }
941 popupParam->SetErrorRadius(setError);
942 }
943
944 Shadow shadow;
945 auto shadowVal = popupObj->GetProperty("shadow");
946 if (shadowVal->IsObject() || shadowVal->IsNumber()) {
947 auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
948 if (!ret) {
949 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
950 }
951 } else {
952 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow);
953 }
954 popupParam->SetShadow(shadow);
955
956 auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
957 if (blurStyleValue->IsNumber()) {
958 auto blurStyle = blurStyleValue->ToNumber<int32_t>();
959 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
960 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
961 popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
962 }
963 }
964 }
965
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)966 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
967 {
968 ParsePopupCommonParam(info, popupObj, popupParam);
969 JSRef<JSVal> messageVal = popupObj->GetProperty("message");
970 if (popupParam) {
971 popupParam->SetMessage(messageVal->ToString());
972 }
973
974 auto messageOptions = popupObj->GetProperty("messageOptions");
975 JSRef<JSObject> messageOptionsObj;
976 if (!messageOptions->IsNull() && messageOptions->IsObject()) {
977 messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
978 SetPopupMessageOptions(messageOptionsObj, popupParam);
979 }
980
981 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
982 if (primaryButtonVal->IsObject()) {
983 ButtonProperties properties;
984 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
985 JSRef<JSVal> value = obj->GetProperty("value");
986 if (value->IsString()) {
987 properties.value = value->ToString();
988 }
989
990 JSRef<JSVal> actionValue = obj->GetProperty("action");
991 if (actionValue->IsFunction()) {
992 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
993 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
994 if (popupParam) {
995 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
996 node = targetNode](GestureEvent& info) {
997 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
998 ACE_SCORING_EVENT("primaryButton.action");
999 PipelineContext::SetCallBackNode(node);
1000 func->Execute(info);
1001 };
1002 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1003 }
1004 }
1005 properties.showButton = true;
1006 if (popupParam) {
1007 popupParam->SetPrimaryButtonProperties(properties);
1008 }
1009 }
1010
1011 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
1012 if (secondaryButtonVal->IsObject()) {
1013 ButtonProperties properties;
1014 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
1015 JSRef<JSVal> value = obj->GetProperty("value");
1016 if (value->IsString()) {
1017 properties.value = value->ToString();
1018 }
1019
1020 JSRef<JSVal> actionValue = obj->GetProperty("action");
1021 if (actionValue->IsFunction()) {
1022 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
1023 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
1024 if (popupParam) {
1025 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
1026 node = targetNode](GestureEvent& info) {
1027 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1028 ACE_SCORING_EVENT("secondaryButton.action");
1029 PipelineContext::SetCallBackNode(node);
1030 func->Execute(info);
1031 };
1032 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
1033 }
1034 }
1035 properties.showButton = true;
1036 if (popupParam) {
1037 popupParam->SetSecondaryButtonProperties(properties);
1038 }
1039 }
1040 }
1041
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1042 void ParseCustomPopupParam(
1043 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1044 {
1045 auto builderValue = popupObj->GetProperty("builder");
1046 if (!builderValue->IsObject()) {
1047 return;
1048 }
1049 if (!builderValue->IsFunction()) {
1050 JSRef<JSObject> builderObj;
1051 builderObj = JSRef<JSObject>::Cast(builderValue);
1052 auto builder = builderObj->GetProperty("builder");
1053 if (!builder->IsFunction()) {
1054 return;
1055 }
1056 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1057 if (!builderFunc) {
1058 return;
1059 }
1060 }
1061 if (popupParam) {
1062 popupParam->SetUseCustomComponent(true);
1063 }
1064
1065 auto focusableValue = popupObj->GetProperty("focusable");
1066 if (focusableValue->IsBoolean()) {
1067 popupParam->SetFocusable(focusableValue->ToBoolean());
1068 }
1069
1070 ParsePopupCommonParam(info, popupObj, popupParam);
1071 }
1072 #endif
1073
1074 } // namespace
1075
GetResourceObject(const JSRef<JSObject> & jsObj)1076 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj)
1077 {
1078 auto id = jsObj->GetProperty("id")->ToNumber<uint32_t>();
1079 auto type = jsObj->GetProperty("type")->ToNumber<uint32_t>();
1080 auto args = jsObj->GetProperty("params");
1081
1082 std::string bundleName;
1083 std::string moduleName;
1084 auto bundle = jsObj->GetProperty("bundleName");
1085 auto module = jsObj->GetProperty("moduleName");
1086 if (bundle->IsString() && module->IsString()) {
1087 bundleName = bundle->ToString();
1088 moduleName = module->ToString();
1089 }
1090
1091 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
1092 std::vector<ResourceObjectParams> resObjParamsList;
1093 auto size = static_cast<int32_t>(params->Length());
1094 for (int32_t i = 0; i < size; i++) {
1095 auto item = params->GetValueAt(i);
1096 ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
1097 if (item->IsString()) {
1098 resObjParams.type = ResourceObjectParamType::STRING;
1099 } else if (item->IsNumber()) {
1100 if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
1101 resObjParams.type = ResourceObjectParamType::FLOAT;
1102 } else {
1103 resObjParams.type = ResourceObjectParamType::INT;
1104 }
1105 }
1106 resObjParamsList.push_back(resObjParams);
1107 }
1108 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName);
1109 return resourceObject;
1110 }
1111
GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1112 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj)
1113 {
1114 auto bundleName = jsObj->GetPropertyValue<std::string>("bundleName", "");
1115 auto moduleName = jsObj->GetPropertyValue<std::string>("moduleName", "");
1116 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName);
1117 return resourceObject;
1118 }
1119
CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1120 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject)
1121 {
1122 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1123 RefPtr<ThemeConstants> themeConstants = nullptr;
1124 if (SystemProperties::GetResourceDecoupling()) {
1125 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject);
1126 if (!resourceAdapter) {
1127 return nullptr;
1128 }
1129 } else {
1130 themeConstants = JSViewAbstract::GetThemeConstants(jsObj);
1131 if (!themeConstants) {
1132 return nullptr;
1133 }
1134 }
1135 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1136 return resourceWrapper;
1137 }
1138
CreateResourceWrapper()1139 RefPtr<ResourceWrapper> CreateResourceWrapper()
1140 {
1141 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
1142 RefPtr<ThemeConstants> themeConstants = nullptr;
1143 if (SystemProperties::GetResourceDecoupling()) {
1144 resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter();
1145 if (!resourceAdapter) {
1146 return nullptr;
1147 }
1148 } else {
1149 themeConstants = JSViewAbstract::GetThemeConstants();
1150 if (!themeConstants) {
1151 return nullptr;
1152 }
1153 }
1154 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
1155 return resourceWrapper;
1156 }
1157
ColorAlphaAdapt(uint32_t origin)1158 uint32_t ColorAlphaAdapt(uint32_t origin)
1159 {
1160 uint32_t result = origin;
1161 if (origin >> COLOR_ALPHA_OFFSET == 0) {
1162 result = origin | COLOR_ALPHA_VALUE;
1163 }
1164 return result;
1165 }
1166
JsScale(const JSCallbackInfo & info)1167 void JSViewAbstract::JsScale(const JSCallbackInfo& info)
1168 {
1169 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1170 if (!CheckJSCallbackInfo("JsScale", info, checkList)) {
1171 SetDefaultScale();
1172 return;
1173 }
1174
1175 if (info[0]->IsObject()) {
1176 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
1177 if (jsObj->HasProperty("x") || jsObj->HasProperty("y") || jsObj->HasProperty("z")) {
1178 // default: x, y, z (1.0, 1.0, 1.0)
1179 auto scaleX = 1.0f;
1180 auto scaleY = 1.0f;
1181 auto scaleZ = 1.0f;
1182 // default centerX, centerY 50% 50%;
1183 CalcDimension centerX = 0.5_pct;
1184 CalcDimension centerY = 0.5_pct;
1185 ParseJsScale(info[0], scaleX, scaleY, scaleZ, centerX, centerY);
1186 ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ);
1187 ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp);
1188 return;
1189 } else {
1190 SetDefaultScale();
1191 }
1192 }
1193 double scale = 0.0;
1194 if (ParseJsDouble(info[0], scale)) {
1195 ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f);
1196 }
1197 }
1198
SetDefaultScale()1199 void JSViewAbstract::SetDefaultScale()
1200 {
1201 ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f);
1202 ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp);
1203 }
1204
JsScaleX(const JSCallbackInfo & info)1205 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info)
1206 {
1207 double scaleVal = 0.0;
1208 if (!ParseJsDouble(info[0], scaleVal)) {
1209 return;
1210 }
1211 ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f);
1212 }
1213
JsScaleY(const JSCallbackInfo & info)1214 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info)
1215 {
1216 double scaleVal = 0.0;
1217 if (!ParseJsDouble(info[0], scaleVal)) {
1218 return;
1219 }
1220 ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f);
1221 }
1222
JsOpacity(const JSCallbackInfo & info)1223 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info)
1224 {
1225 double opacity = 0.0;
1226 if (!ParseJsDouble(info[0], opacity)) {
1227 ViewAbstractModel::GetInstance()->SetOpacity(1.0f);
1228 return;
1229 }
1230 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1231 opacity = std::clamp(opacity, 0.0, 1.0);
1232 } else {
1233 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1234 opacity = 1.0;
1235 }
1236 }
1237 ViewAbstractModel::GetInstance()->SetOpacity(opacity);
1238 }
1239
JsTranslate(const JSCallbackInfo & info)1240 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info)
1241 {
1242 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
1243 JSCallbackInfoType::OBJECT };
1244 if (!CheckJSCallbackInfo("JsTranslate", info, checkList)) {
1245 SetDefaultTranslate();
1246 return;
1247 }
1248
1249 if (info[0]->IsObject()) {
1250 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
1251 if (jsObj->HasProperty("x") || jsObj->HasProperty("y") || jsObj->HasProperty("z")) {
1252 // default: x, y, z (0.0, 0.0, 0.0)
1253 auto translateX = CalcDimension(0.0);
1254 auto translateY = CalcDimension(0.0);
1255 auto translateZ = CalcDimension(0.0);
1256 ParseJsTranslate(info[0], translateX, translateY, translateZ);
1257 ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ);
1258 return;
1259 } else {
1260 SetDefaultTranslate();
1261 }
1262 }
1263 CalcDimension value;
1264 if (ParseJsDimensionVp(info[0], value)) {
1265 ViewAbstractModel::GetInstance()->SetTranslate(value, value, value);
1266 }
1267 }
1268
SetDefaultTranslate()1269 void JSViewAbstract::SetDefaultTranslate()
1270 {
1271 ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0));
1272 }
1273
JsTranslateX(const JSCallbackInfo & info)1274 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info)
1275 {
1276 CalcDimension value;
1277 if (!ParseJsDimensionVp(info[0], value)) {
1278 return;
1279 }
1280 ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px);
1281 }
1282
JsTranslateY(const JSCallbackInfo & info)1283 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info)
1284 {
1285 CalcDimension value;
1286 if (!ParseJsDimensionVp(info[0], value)) {
1287 return;
1288 }
1289 ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px);
1290 }
1291
JsRotate(const JSCallbackInfo & info)1292 void JSViewAbstract::JsRotate(const JSCallbackInfo& info)
1293 {
1294 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
1295 if (!CheckJSCallbackInfo("JsRotate", info, checkList)) {
1296 SetDefaultRotate();
1297 return;
1298 }
1299
1300 if (info[0]->IsObject()) {
1301 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1302 std::optional<float> angle;
1303 ParseJsRotate(info[0], rotate, angle);
1304 if (angle) {
1305 ViewAbstractModel::GetInstance()->SetRotate(
1306 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective);
1307 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1308 } else {
1309 SetDefaultRotate();
1310 }
1311 return;
1312 }
1313 double rotateZ;
1314 if (ParseJsDouble(info[0], rotateZ)) {
1315 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ);
1316 }
1317 }
1318
SetDefaultRotate()1319 void JSViewAbstract::SetDefaultRotate()
1320 {
1321 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f);
1322 ViewAbstractModel::GetInstance()->SetRotate(
1323 rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective);
1324 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ);
1325 }
1326
JsRotateX(const JSCallbackInfo & info)1327 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info)
1328 {
1329 double rotateVal = 0.0;
1330 if (!ParseJsDouble(info[0], rotateVal)) {
1331 return;
1332 }
1333 ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal);
1334 }
1335
JsRotateY(const JSCallbackInfo & info)1336 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info)
1337 {
1338 double rotateVal = 0.0;
1339 if (!ParseJsDouble(info[0], rotateVal)) {
1340 return;
1341 }
1342 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal);
1343 }
1344
JsTransform(const JSCallbackInfo & info)1345 void JSViewAbstract::JsTransform(const JSCallbackInfo& info)
1346 {
1347 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1348 if (!CheckJSCallbackInfo("JsTransform", info, checkList)) {
1349 SetDefaultTransform();
1350 return;
1351 }
1352 JSRef<JSVal> array = JSRef<JSObject>::Cast(info[0])->GetProperty("matrix4x4");
1353 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1354 if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() != matrix4Len) {
1355 return;
1356 }
1357 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
1358 std::vector<float> matrix(matrix4Len);
1359 for (int32_t i = 0; i < matrix4Len; i++) {
1360 double value = 0.0;
1361 ParseJsDouble(jsArray->GetValueAt(i), value);
1362 matrix[i] = static_cast<float>(value);
1363 }
1364 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1365 }
1366
SetDefaultTransform()1367 void JSViewAbstract::SetDefaultTransform()
1368 {
1369 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
1370 std::vector<float> matrix(matrix4Len);
1371 const int32_t initPosition = 5;
1372 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
1373 double value = 1.0;
1374 matrix[i] = static_cast<float>(value);
1375 }
1376 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix);
1377 }
1378
ParseTransition(std::unique_ptr<JsonValue> & transitionArgs)1379 NG::TransitionOptions JSViewAbstract::ParseTransition(std::unique_ptr<JsonValue>& transitionArgs)
1380 {
1381 bool hasEffect = false;
1382 NG::TransitionOptions transitionOption;
1383 transitionOption.Type = ParseTransitionType(transitionArgs->GetString("type", "All"));
1384 if (transitionArgs->Contains("opacity")) {
1385 double opacity = 1.0;
1386 ParseJsonDouble(transitionArgs->GetValue("opacity"), opacity);
1387 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1388 opacity = 1.0;
1389 }
1390 transitionOption.UpdateOpacity(static_cast<float>(opacity));
1391 hasEffect = true;
1392 }
1393 if (transitionArgs->Contains("translate")) {
1394 auto translateArgs = transitionArgs->GetObject("translate");
1395 // default: x, y, z (0.0, 0.0, 0.0)
1396 NG::TranslateOptions translate;
1397 ParseJsonTranslate(translateArgs, translate.x, translate.y, translate.z);
1398 transitionOption.UpdateTranslate(translate);
1399 hasEffect = true;
1400 }
1401 if (transitionArgs->Contains("scale")) {
1402 auto scaleArgs = transitionArgs->GetObject("scale");
1403 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1404 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1405 ParseJsonScale(scaleArgs, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY);
1406 transitionOption.UpdateScale(scale);
1407 hasEffect = true;
1408 }
1409 if (transitionArgs->Contains("rotate")) {
1410 auto rotateArgs = transitionArgs->GetObject("rotate");
1411 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1412 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1413 std::optional<float> angle;
1414 ParseJsonRotate(rotateArgs, rotate, angle);
1415 if (angle.has_value()) {
1416 rotate.angle = angle.value();
1417 transitionOption.UpdateRotate(rotate);
1418 hasEffect = true;
1419 }
1420 }
1421 if (!hasEffect) {
1422 // default transition
1423 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1424 }
1425 return transitionOption;
1426 }
1427
ParseJsTransition(const JSRef<JSVal> & transitionArgs)1428 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSVal>& transitionArgs)
1429 {
1430 NG::TransitionOptions transitionOption;
1431 if (!transitionArgs->IsObject()) {
1432 return transitionOption;
1433 }
1434
1435 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(transitionArgs);
1436 bool hasEffect = false;
1437 transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All"));
1438 if (jsObj->HasProperty("opacity")) {
1439 double opacity = 1.0;
1440 ParseJsDouble(jsObj->GetProperty("opacity"), opacity);
1441 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1442 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) {
1443 opacity = 1.0;
1444 }
1445 } else {
1446 opacity = std::clamp(opacity, 0.0, 1.0);
1447 }
1448 transitionOption.UpdateOpacity(static_cast<float>(opacity));
1449 hasEffect = true;
1450 }
1451 if (jsObj->HasProperty("translate")) {
1452 // default: x, y, z (0.0, 0.0, 0.0)
1453 NG::TranslateOptions translate;
1454 ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z);
1455 transitionOption.UpdateTranslate(translate);
1456 hasEffect = true;
1457 }
1458 if (jsObj->HasProperty("scale")) {
1459 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%;
1460 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct);
1461 ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale,
1462 scale.centerX, scale.centerY);
1463 transitionOption.UpdateScale(scale);
1464 hasEffect = true;
1465 }
1466 if (jsObj->HasProperty("rotate")) {
1467 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%;
1468 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct);
1469 std::optional<float> angle;
1470 ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle);
1471 if (angle.has_value()) {
1472 rotate.angle = angle.value();
1473 transitionOption.UpdateRotate(rotate);
1474 hasEffect = true;
1475 }
1476 }
1477 if (!hasEffect) {
1478 // default transition
1479 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type);
1480 }
1481 return transitionOption;
1482 }
1483
JsTransition(const JSCallbackInfo & info)1484 void JSViewAbstract::JsTransition(const JSCallbackInfo& info)
1485 {
1486 if (info.Length() > 1) {
1487 return;
1488 }
1489 if (info.Length() == 0) {
1490 ViewAbstractModel::GetInstance()->SetTransition(
1491 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
1492 return;
1493 }
1494 if (!info[0]->IsObject()) {
1495 return;
1496 }
1497 auto obj = JSRef<JSObject>::Cast(info[0]);
1498 if (!obj->GetProperty("successor_")->IsUndefined()) {
1499 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
1500 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect);
1501 return;
1502 }
1503 auto options = ParseJsTransition(info[0]);
1504 ViewAbstractModel::GetInstance()->SetTransition(options);
1505 }
1506
JsWidth(const JSCallbackInfo & info)1507 void JSViewAbstract::JsWidth(const JSCallbackInfo& info)
1508 {
1509 JsWidth(info[0]);
1510 }
1511
JsWidth(const JSRef<JSVal> & jsValue)1512 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue)
1513 {
1514 CalcDimension value;
1515 if (jsValue->IsUndefined()) {
1516 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1517 return true;
1518 }
1519 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1520 if (!ParseJsDimensionVpNG(jsValue, value)) {
1521 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true);
1522 return false;
1523 }
1524 } else if (!ParseJsDimensionVp(jsValue, value)) {
1525 return false;
1526 }
1527
1528 if (LessNotEqual(value.Value(), 0.0)) {
1529 value.SetValue(0.0);
1530 }
1531
1532 ViewAbstractModel::GetInstance()->SetWidth(value);
1533 return true;
1534 }
1535
JsHeight(const JSCallbackInfo & info)1536 void JSViewAbstract::JsHeight(const JSCallbackInfo& info)
1537 {
1538 JsHeight(info[0]);
1539 }
1540
JsHeight(const JSRef<JSVal> & jsValue)1541 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue)
1542 {
1543 CalcDimension value;
1544 if (jsValue->IsUndefined()) {
1545 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1546 return true;
1547 }
1548 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1549 if (!ParseJsDimensionVpNG(jsValue, value)) {
1550 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false);
1551 return false;
1552 }
1553 } else if (!ParseJsDimensionVp(jsValue, value)) {
1554 return false;
1555 }
1556
1557 if (LessNotEqual(value.Value(), 0.0)) {
1558 value.SetValue(0.0);
1559 }
1560
1561 ViewAbstractModel::GetInstance()->SetHeight(value);
1562 return true;
1563 }
1564
JsResponseRegion(const JSCallbackInfo & info)1565 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info)
1566 {
1567 std::vector<DimensionRect> result;
1568 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1569 ViewAbstractModel::GetInstance()->SetResponseRegion({});
1570 return;
1571 }
1572
1573 ViewAbstractModel::GetInstance()->SetResponseRegion(result);
1574 }
1575
JsMouseResponseRegion(const JSCallbackInfo & info)1576 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info)
1577 {
1578 std::vector<DimensionRect> result;
1579 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) {
1580 ViewAbstractModel::GetInstance()->SetMouseResponseRegion({});
1581 return;
1582 }
1583 ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result);
1584 }
1585
ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)1586 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result)
1587 {
1588 if (!jsValue->IsObject()) {
1589 return false;
1590 }
1591
1592 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
1593 JSRef<JSVal> x = obj->GetProperty("x");
1594 JSRef<JSVal> y = obj->GetProperty("y");
1595 JSRef<JSVal> width = obj->GetProperty("width");
1596 JSRef<JSVal> height = obj->GetProperty("height");
1597 CalcDimension xDimen = result.GetOffset().GetX();
1598 CalcDimension yDimen = result.GetOffset().GetY();
1599 CalcDimension widthDimen = result.GetWidth();
1600 CalcDimension heightDimen = result.GetHeight();
1601 auto s1 = width->ToString();
1602 auto s2 = height->ToString();
1603 if (s1.find('-') != std::string::npos) {
1604 width = JSRef<JSVal>::Make(ToJSValue("100%"));
1605 }
1606 if (s2.find('-') != std::string::npos) {
1607 height = JSRef<JSVal>::Make(ToJSValue("100%"));
1608 }
1609 if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) {
1610 auto offset = result.GetOffset();
1611 offset.SetX(xDimen);
1612 result.SetOffset(offset);
1613 }
1614 if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) {
1615 auto offset = result.GetOffset();
1616 offset.SetY(yDimen);
1617 result.SetOffset(offset);
1618 }
1619 if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) {
1620 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) {
1621 return true;
1622 }
1623 result.SetWidth(widthDimen);
1624 }
1625 if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) {
1626 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) {
1627 return true;
1628 }
1629 result.SetHeight(heightDimen);
1630 }
1631 return true;
1632 }
1633
ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)1634 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result)
1635 {
1636 if (!jsValue->IsArray() && !jsValue->IsObject()) {
1637 return false;
1638 }
1639
1640 if (jsValue->IsArray()) {
1641 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
1642 for (size_t i = 0; i < array->Length(); i++) {
1643 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1644 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1645 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1646 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1647 DimensionOffset offsetDimen(xDimen, yDimen);
1648 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1649 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) {
1650 result.emplace_back(dimenRect);
1651 } else {
1652 return false;
1653 }
1654 }
1655 return true;
1656 }
1657
1658 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
1659 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
1660 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
1661 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
1662 DimensionOffset offsetDimen(xDimen, yDimen);
1663 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
1664 if (ParseJsDimensionRect(jsValue, dimenRect)) {
1665 result.emplace_back(dimenRect);
1666 return true;
1667 } else {
1668 return false;
1669 }
1670 }
1671
JsSize(const JSCallbackInfo & info)1672 void JSViewAbstract::JsSize(const JSCallbackInfo& info)
1673 {
1674 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1675 if (!CheckJSCallbackInfo("JsSize", info, checkList)) {
1676 return;
1677 }
1678
1679 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1680 JsWidth(sizeObj->GetProperty("width"));
1681 JsHeight(sizeObj->GetProperty("height"));
1682 }
1683
JsConstraintSize(const JSCallbackInfo & info)1684 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info)
1685 {
1686 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1687 if (!CheckJSCallbackInfo("JsConstraintSize", info, checkList)) {
1688 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1689 ViewAbstractModel::GetInstance()->ResetMinSize(true);
1690 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1691 ViewAbstractModel::GetInstance()->ResetMinSize(false);
1692 return;
1693 }
1694
1695 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1696
1697 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
1698 CalcDimension minWidth;
1699 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
1700 CalcDimension maxWidth;
1701 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
1702 CalcDimension minHeight;
1703 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
1704 CalcDimension maxHeight;
1705 bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
1706 if (ParseJsDimensionVp(minWidthValue, minWidth)) {
1707 ViewAbstractModel::GetInstance()->SetMinWidth(minWidth);
1708 } else if (version10OrLarger) {
1709 ViewAbstractModel::GetInstance()->ResetMinSize(true);
1710 }
1711
1712 if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
1713 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth);
1714 } else if (version10OrLarger) {
1715 ViewAbstractModel::GetInstance()->ResetMaxSize(true);
1716 }
1717
1718 if (ParseJsDimensionVp(minHeightValue, minHeight)) {
1719 ViewAbstractModel::GetInstance()->SetMinHeight(minHeight);
1720 } else if (version10OrLarger) {
1721 ViewAbstractModel::GetInstance()->ResetMinSize(false);
1722 }
1723
1724 if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
1725 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight);
1726 } else if (version10OrLarger) {
1727 ViewAbstractModel::GetInstance()->ResetMaxSize(false);
1728 }
1729 }
1730
JsLayoutPriority(const JSCallbackInfo & info)1731 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info)
1732 {
1733 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1734 if (!CheckJSCallbackInfo("JsLayoutPriority", info, checkList)) {
1735 return;
1736 }
1737
1738 int32_t priority;
1739 if (info[0]->IsNumber()) {
1740 priority = info[0]->ToNumber<int32_t>();
1741 } else {
1742 priority = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1743 }
1744 ViewAbstractModel::GetInstance()->SetLayoutPriority(priority);
1745 }
1746
JsPixelRound(const JSCallbackInfo & info)1747 void JSViewAbstract::JsPixelRound(const JSCallbackInfo& info)
1748 {
1749 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
1750 if (!CheckJSCallbackInfo("JsPixelRound", info, checkList)) {
1751 return;
1752 }
1753 uint8_t value = 0;
1754 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
1755 JSRef<JSVal> jsStartValue = object->GetProperty("start");
1756 if (jsStartValue->IsNumber()) {
1757 int32_t startValue = jsStartValue->ToNumber<int32_t>();
1758 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(startValue)) {
1759 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_START);
1760 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(startValue)) {
1761 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_START);
1762 }
1763 }
1764 JSRef<JSVal> jsTopValue = object->GetProperty("top");
1765 if (jsTopValue->IsNumber()) {
1766 int32_t topValue = jsTopValue->ToNumber<int32_t>();
1767 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(topValue)) {
1768 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
1769 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(topValue)) {
1770 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
1771 }
1772 }
1773 JSRef<JSVal> jsEndValue = object->GetProperty("end");
1774 if (jsEndValue->IsNumber()) {
1775 int32_t endValue = jsEndValue->ToNumber<int32_t>();
1776 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(endValue)) {
1777 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_END);
1778 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(endValue)) {
1779 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_END);
1780 }
1781 }
1782 JSRef<JSVal> jsBottomValue = object->GetProperty("bottom");
1783 if (jsBottomValue->IsNumber()) {
1784 int32_t bottomValue = jsBottomValue->ToNumber<int32_t>();
1785 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
1786 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
1787 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(bottomValue)) {
1788 value |= static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
1789 }
1790 }
1791 ViewAbstractModel::GetInstance()->SetPixelRound(value);
1792 }
1793
JsLayoutWeight(const JSCallbackInfo & info)1794 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info)
1795 {
1796 float value = 0.0f;
1797 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER };
1798 if (!CheckJSCallbackInfo("JsLayoutWeight", info, checkList)) {
1799 if (!info[0]->IsUndefined()) {
1800 return;
1801 }
1802 }
1803
1804 if (info[0]->IsNumber()) {
1805 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1806 value = info[0]->ToNumber<float>();
1807 } else {
1808 value = info[0]->ToNumber<int32_t>();
1809 }
1810 } else {
1811 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1812 value = static_cast<float>(StringUtils::StringToUint(info[0]->ToString()));
1813 } else {
1814 value = static_cast<int32_t>(StringUtils::StringToUint(info[0]->ToString()));
1815 }
1816 }
1817
1818 ViewAbstractModel::GetInstance()->SetLayoutWeight(value);
1819 }
1820
JsAlign(const JSCallbackInfo & info)1821 void JSViewAbstract::JsAlign(const JSCallbackInfo& info)
1822 {
1823 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
1824 if (!CheckJSCallbackInfo("JsAlign", info, checkList) &&
1825 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1826 ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER);
1827 return;
1828 }
1829 auto value = info[0]->ToNumber<int32_t>();
1830 Alignment alignment = ParseAlignment(value);
1831 ViewAbstractModel::GetInstance()->SetAlign(alignment);
1832 }
1833
JsPosition(const JSCallbackInfo & info)1834 void JSViewAbstract::JsPosition(const JSCallbackInfo& info)
1835 {
1836 CalcDimension x;
1837 CalcDimension y;
1838 if (ParseLocationProps(info, x, y)) {
1839 ViewAbstractModel::GetInstance()->SetPosition(x, y);
1840 } else {
1841 ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp);
1842 }
1843 }
1844
JsMarkAnchor(const JSCallbackInfo & info)1845 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info)
1846 {
1847 CalcDimension x;
1848 CalcDimension y;
1849 if (ParseLocationProps(info, x, y)) {
1850 ViewAbstractModel::GetInstance()->MarkAnchor(x, y);
1851 } else {
1852 ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp);
1853 }
1854 }
1855
JsOffset(const JSCallbackInfo & info)1856 void JSViewAbstract::JsOffset(const JSCallbackInfo& info)
1857 {
1858 CalcDimension x;
1859 CalcDimension y;
1860 if (ParseLocationProps(info, x, y)) {
1861 ViewAbstractModel::GetInstance()->SetOffset(x, y);
1862 } else {
1863 ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp);
1864 }
1865 }
1866
JsEnabled(const JSCallbackInfo & info)1867 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info)
1868 {
1869 auto arg = info[0];
1870 if (!arg->IsBoolean()) {
1871 ViewAbstractModel::GetInstance()->SetEnabled(true);
1872 } else {
1873 ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean());
1874 }
1875 }
1876
JsAspectRatio(const JSCallbackInfo & info)1877 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info)
1878 {
1879 double value = 0.0;
1880 if (!ParseJsDouble(info[0], value)) {
1881 // add version protection, undefined use default value
1882 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) &&
1883 (info[0]->IsNull() || info[0]->IsUndefined())) {
1884 ViewAbstractModel::GetInstance()->ResetAspectRatio();
1885 return;
1886 } else {
1887 return;
1888 }
1889 }
1890
1891 // negative use default value.
1892 if (LessOrEqual(value, 0.0)) {
1893 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
1894 ViewAbstractModel::GetInstance()->ResetAspectRatio();
1895 return;
1896 } else {
1897 value = 1.0;
1898 }
1899 }
1900
1901 ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value));
1902 }
1903
JsOverlay(const JSCallbackInfo & info)1904 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info)
1905 {
1906 if (info.Length() > 0 && (info[0]->IsUndefined())) {
1907 ViewAbstractModel::GetInstance()->SetOverlay(
1908 "", nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0));
1909 return;
1910 }
1911
1912 if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) {
1913 return;
1914 }
1915 std::optional<Alignment> align;
1916 std::optional<CalcDimension> offsetX;
1917 std::optional<CalcDimension> offsetY;
1918
1919 if (info[1]->IsObject()) {
1920 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]);
1921 JSRef<JSVal> alignVal = optionObj->GetProperty("align");
1922 auto value = alignVal->ToNumber<int32_t>();
1923 Alignment alignment = ParseAlignment(value);
1924 align = alignment;
1925
1926 JSRef<JSVal> val = optionObj->GetProperty("offset");
1927 if (val->IsObject()) {
1928 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val);
1929 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
1930 CalcDimension x;
1931 if (ParseJsDimensionVp(xVal, x)) {
1932 offsetX = x;
1933 }
1934 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
1935 CalcDimension y;
1936 if (ParseJsDimensionVp(yVal, y)) {
1937 offsetY = y;
1938 }
1939 }
1940 }
1941
1942 if (info[0]->IsString()) {
1943 std::string text = info[0]->ToString();
1944 ViewAbstractModel::GetInstance()->SetOverlay(text, nullptr, align, offsetX, offsetY);
1945 } else if (info[0]->IsObject()) {
1946 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[0]);
1947 auto builder = menuObj->GetProperty("builder");
1948 if (!builder->IsFunction()) {
1949 return;
1950 }
1951 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1952 CHECK_NULL_VOID(builderFunc);
1953 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
1954 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = targetNode]() {
1955 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1956 ACE_SCORING_EVENT("Overlay");
1957 PipelineContext::SetCallBackNode(node);
1958 func->Execute();
1959 };
1960 ViewAbstractModel::GetInstance()->SetOverlay("", std::move(buildFunc), align, offsetX, offsetY);
1961 }
1962 }
1963
ParseAlignment(int32_t align)1964 Alignment JSViewAbstract::ParseAlignment(int32_t align)
1965 {
1966 Alignment alignment = Alignment::CENTER;
1967 switch (align) {
1968 case 0:
1969 alignment = Alignment::TOP_LEFT;
1970 break;
1971 case 1:
1972 alignment = Alignment::TOP_CENTER;
1973 break;
1974 case 2:
1975 alignment = Alignment::TOP_RIGHT;
1976 break;
1977 case 3:
1978 alignment = Alignment::CENTER_LEFT;
1979 break;
1980 case 4:
1981 alignment = Alignment::CENTER;
1982 break;
1983 case 5:
1984 alignment = Alignment::CENTER_RIGHT;
1985 break;
1986 case 6:
1987 alignment = Alignment::BOTTOM_LEFT;
1988 break;
1989 case 7:
1990 alignment = Alignment::BOTTOM_CENTER;
1991 break;
1992 case 8:
1993 alignment = Alignment::BOTTOM_RIGHT;
1994 break;
1995 default:
1996 break;
1997 }
1998 return alignment;
1999 }
2000
SetVisibility(const JSCallbackInfo & info)2001 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info)
2002 {
2003 int32_t visible = 0;
2004 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2005 // undefined value use default value.
2006 visible = 0;
2007 } else if (!info[0]->IsNumber()) {
2008 return;
2009 } else {
2010 visible = info[0]->ToNumber<int32_t>();
2011 }
2012
2013 if (info.Length() > 1 && info[1]->IsFunction()) {
2014 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
2015 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2016 auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
2017 int32_t visible) {
2018 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2019 ACE_SCORING_EVENT("onVisibilityChange");
2020 PipelineContext::SetCallBackNode(node);
2021 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible));
2022 func->ExecuteJS(1, &newJSVal);
2023 };
2024 ViewAbstractModel::GetInstance()->SetVisibility(
2025 static_cast<VisibleType>(visible), std::move(onVisibilityChange));
2026 } else {
2027 ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {});
2028 }
2029 }
2030
JsSetFreeze(const JSCallbackInfo & info)2031 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info)
2032 {
2033 if (info[0]->IsBoolean()) {
2034 ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean());
2035 }
2036 }
2037
JsFlexBasis(const JSCallbackInfo & info)2038 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info)
2039 {
2040 CalcDimension value;
2041 if (!ParseJsDimensionVp(info[0], value)) {
2042 value.SetUnit(DimensionUnit::AUTO);
2043 }
2044 // flexbasis don't support percent case.
2045 if (value.Unit() == DimensionUnit::PERCENT) {
2046 value.SetUnit(DimensionUnit::AUTO);
2047 }
2048 ViewAbstractModel::GetInstance()->SetFlexBasis(value);
2049 }
2050
JsFlexGrow(const JSCallbackInfo & info)2051 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info)
2052 {
2053 double value = 0.0;
2054 if (!ParseJsDouble(info[0], value)) {
2055 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2056 // undefined use default value.
2057 value = 0.0;
2058 } else {
2059 return;
2060 }
2061 }
2062 // negative use default value.
2063 if (value < 0.0) {
2064 value = 0.0;
2065 }
2066 ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value));
2067 }
2068
JsFlexShrink(const JSCallbackInfo & info)2069 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info)
2070 {
2071 double value = 0.0;
2072 if (!ParseJsDouble(info[0], value)) {
2073 if (info[0]->IsNull() || info[0]->IsUndefined()) {
2074 // undefined use default value.
2075 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2076 return;
2077 } else {
2078 return;
2079 }
2080 }
2081 // negative use default value.
2082 if (value < 0.0) {
2083 ViewAbstractModel::GetInstance()->ResetFlexShrink();
2084 return;
2085 }
2086 ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value));
2087 }
2088
JsDisplayPriority(const JSCallbackInfo & info)2089 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info)
2090 {
2091 double value = 0.0;
2092 if (!ParseJsDouble(info[0], value)) {
2093 return;
2094 }
2095 ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value));
2096 }
2097
JsSharedTransition(const JSCallbackInfo & info)2098 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info)
2099 {
2100 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2101 if (!CheckJSCallbackInfo("JsSharedTransition", info, checkList)) {
2102 return;
2103 }
2104 // id
2105 auto id = info[0]->ToString();
2106 if (id.empty()) {
2107 return;
2108 }
2109 std::shared_ptr<SharedTransitionOption> sharedOption;
2110
2111 // options
2112 if (info.Length() > 1 && info[1]->IsObject()) {
2113 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
2114 sharedOption = std::make_shared<SharedTransitionOption>();
2115 // default: duration: 1000
2116 sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION);
2117 if (sharedOption->duration < 0) {
2118 sharedOption->duration = DEFAULT_DURATION;
2119 }
2120 // default: delay: 0
2121 sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
2122 if (sharedOption->delay < 0) {
2123 sharedOption->delay = 0;
2124 }
2125 // default: LinearCurve
2126 RefPtr<Curve> curve;
2127 JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
2128 if (curveArgs->IsString()) {
2129 curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false);
2130 } else if (curveArgs->IsObject()) {
2131 JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
2132 if (!curveString->IsString()) {
2133 return;
2134 }
2135 curve = CreateCurve(curveString->ToString(), false);
2136 }
2137 if (!curve) {
2138 curve = Curves::LINEAR;
2139 }
2140 sharedOption->curve = curve;
2141 // motionPath
2142 if (jsObj->HasProperty("motionPath")) {
2143 MotionPathOption motionPathOption;
2144 if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) {
2145 sharedOption->motionPathOption = motionPathOption;
2146 }
2147 }
2148 // zIndex
2149 sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0);
2150 // type
2151 int32_t type = jsObj->GetPropertyValue<int32_t>("type",
2152 static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE));
2153 sharedOption->type = static_cast<SharedTransitionEffectType>(type);
2154 }
2155 ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption);
2156 }
2157
JsGeometryTransition(const JSCallbackInfo & info)2158 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info)
2159 {
2160 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
2161 if (!CheckJSCallbackInfo("JsGeometryTransition", info, checkList)) {
2162 return;
2163 }
2164 // id
2165 auto id = info[0]->ToString();
2166 // follow flag
2167 bool followWithOutTransition = false;
2168 if (info.Length() >= PARAMETER_LENGTH_SECOND) {
2169 if (info[1]->IsBoolean()) {
2170 followWithOutTransition = info[1]->ToBoolean();
2171 } else if (info[1]->IsObject()) {
2172 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2173 ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition);
2174 }
2175 }
2176 ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition);
2177 }
2178
JsAlignSelf(const JSCallbackInfo & info)2179 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info)
2180 {
2181 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
2182 if (!CheckJSCallbackInfo("JsAlignSelf", info, checkList)) {
2183 ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO);
2184 return;
2185 }
2186 auto alignVal = info[0]->ToNumber<int32_t>();
2187
2188 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) {
2189 ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal));
2190 }
2191 }
2192
JsBackgroundColor(const JSCallbackInfo & info)2193 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info)
2194 {
2195 Color backgroundColor;
2196 if (!ParseJsColor(info[0], backgroundColor)) {
2197 backgroundColor = Color::TRANSPARENT;
2198 }
2199
2200 ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor);
2201 }
2202
JsBackgroundImage(const JSCallbackInfo & info)2203 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info)
2204 {
2205 std::string src;
2206 std::string bundle;
2207 std::string module;
2208 RefPtr<PixelMap> pixmap = nullptr;
2209 GetJsMediaBundleInfo(info[0], bundle, module);
2210 if (info[0]->IsString()) {
2211 src = info[0]->ToString();
2212 ViewAbstractModel::GetInstance()->SetBackgroundImage(
2213 ImageSourceInfo { src, bundle, module }, GetThemeConstants());
2214 } else if (ParseJsMedia(info[0], src)) {
2215 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr);
2216 } else {
2217 #if defined(PIXEL_MAP_SUPPORTED)
2218 if (IsDrawable(info[0])) {
2219 pixmap = GetDrawablePixmap(info[0]);
2220 } else {
2221 pixmap = CreatePixelMapFromNapiValue(info[0]);
2222 }
2223 #endif
2224 CHECK_NULL_VOID(pixmap);
2225 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr);
2226 }
2227
2228 int32_t repeatIndex = 0;
2229 if (info.Length() == 2 && info[1]->IsNumber()) {
2230 repeatIndex = info[1]->ToNumber<int32_t>();
2231 }
2232 auto repeat = static_cast<ImageRepeat>(repeatIndex);
2233 ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat);
2234 }
2235
ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2236 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption)
2237 {
2238 if (jsBlurOption->GetProperty("grayscale")->IsArray()) {
2239 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsBlurOption->GetProperty("grayscale"));
2240 auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>();
2241 auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>();
2242 std::vector<float> greyVec(2); // 2 number
2243 greyVec[0] = grey1;
2244 greyVec[1] = grey2;
2245 blurOption.grayscale = greyVec;
2246 }
2247 }
2248
JsBackgroundBlurStyle(const JSCallbackInfo & info)2249 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info)
2250 {
2251 if (info.Length() == 0) {
2252 return;
2253 }
2254 BlurStyleOption styleOption;
2255 if (info[0]->IsNumber()) {
2256 auto blurStyle = info[0]->ToNumber<int32_t>();
2257 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2258 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2259 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2260 }
2261 }
2262 if (info.Length() > 1 && info[1]->IsObject()) {
2263 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2264 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2265 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2266 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2267 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2268 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2269 }
2270 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2271 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2272 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2273 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2274 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2275 }
2276 if (jsOption->GetProperty("scale")->IsNumber()) {
2277 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2278 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2279 }
2280
2281 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2282 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2283 BlurOption blurOption;
2284 ParseBlurOption(jsBlurOption, blurOption);
2285 styleOption.blurOption = blurOption;
2286 }
2287 }
2288 ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption);
2289 }
2290
ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)2291 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption)
2292 {
2293 CalcDimension radius;
2294 if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) {
2295 radius.SetValue(0.0f);
2296 }
2297 double saturation = 1.0f;
2298 if (jsOption->GetProperty("saturation")->IsNumber()) {
2299 saturation = jsOption->GetProperty("saturation")->ToNumber<double>();
2300 saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f;
2301 }
2302 double brightness = 1.0f;
2303 if (jsOption->GetProperty("brightness")->IsNumber()) {
2304 brightness = jsOption->GetProperty("brightness")->ToNumber<double>();
2305 brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f;
2306 }
2307 Color color = Color::TRANSPARENT;
2308 if (!ParseJsColor(jsOption->GetProperty("color"), color)) {
2309 color.SetValue(Color::TRANSPARENT.GetValue());
2310 }
2311 auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2312 auto adaptiveColor = AdaptiveColor::DEFAULT;
2313 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue);
2314 if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2315 adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2316 adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue);
2317 }
2318
2319 BlurOption blurOption;
2320 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2321 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2322 ParseBlurOption(jsBlurOption, blurOption);
2323 }
2324 effectOption = { radius, saturation, brightness, color, adaptiveColor, blurOption };
2325 }
2326
JsBackgroundEffect(const JSCallbackInfo & info)2327 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info)
2328 {
2329 if (info.Length() == 0) {
2330 return;
2331 }
2332 EffectOption option;
2333 if (info[0]->IsObject()) {
2334 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]);
2335 ParseEffectOption(jsOption, option);
2336 }
2337 ViewAbstractModel::GetInstance()->SetBackgroundEffect(option);
2338 }
2339
JsForegroundBlurStyle(const JSCallbackInfo & info)2340 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info)
2341 {
2342 if (info.Length() == 0) {
2343 return;
2344 }
2345 BlurStyleOption styleOption;
2346 if (info[0]->IsNumber()) {
2347 auto blurStyle = info[0]->ToNumber<int32_t>();
2348 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2349 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2350 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
2351 }
2352 }
2353 if (info.Length() > 1 && info[1]->IsObject()) {
2354 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]);
2355 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM);
2356 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode);
2357 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) &&
2358 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) {
2359 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode);
2360 }
2361 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT);
2362 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor);
2363 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) &&
2364 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) {
2365 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor);
2366 }
2367 if (jsOption->GetProperty("scale")->IsNumber()) {
2368 double scale = jsOption->GetProperty("scale")->ToNumber<double>();
2369 styleOption.scale = std::clamp(scale, 0.0, 1.0);
2370 }
2371
2372 if (jsOption->GetProperty("blurOptions")->IsObject()) {
2373 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions"));
2374 BlurOption blurOption;
2375 ParseBlurOption(jsBlurOption, blurOption);
2376 styleOption.blurOption = blurOption;
2377 }
2378 }
2379 ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption);
2380 }
2381
JsSphericalEffect(const JSCallbackInfo & info)2382 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info)
2383 {
2384 auto radio = 0.0;
2385 if (info[0]->IsNumber()) {
2386 radio = info[0]->ToNumber<double>();
2387 }
2388 ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0));
2389 }
2390
JsPixelStretchEffect(const JSCallbackInfo & info)2391 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info)
2392 {
2393 if (!info[0]->IsObject()) {
2394 PixStretchEffectOption option;
2395 option.ResetValue();
2396 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2397 return;
2398 }
2399 auto jsObject = JSRef<JSObject>::Cast(info[0]);
2400 CalcDimension left;
2401 ParseJsDimensionVp(jsObject->GetProperty("left"), left);
2402 CalcDimension right;
2403 ParseJsDimensionVp(jsObject->GetProperty("right"), right);
2404 CalcDimension top;
2405 ParseJsDimensionVp(jsObject->GetProperty("top"), top);
2406 CalcDimension bottom;
2407 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom);
2408
2409 PixStretchEffectOption option;
2410 bool illegalInput = false;
2411 if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT ||
2412 top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) {
2413 if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) &&
2414 (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) &&
2415 (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) &&
2416 (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) {
2417 left.SetUnit(DimensionUnit::PERCENT);
2418 top.SetUnit(DimensionUnit::PERCENT);
2419 right.SetUnit(DimensionUnit::PERCENT);
2420 bottom.SetUnit(DimensionUnit::PERCENT);
2421 } else {
2422 illegalInput = true;
2423 }
2424 }
2425 if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) ||
2426 (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) {
2427 option.left = left;
2428 option.top = top;
2429 option.right = right;
2430 option.bottom = bottom;
2431 } else {
2432 illegalInput = true;
2433 }
2434 if (illegalInput) {
2435 option.ResetValue();
2436 }
2437 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option);
2438 }
2439
JsLightUpEffect(const JSCallbackInfo & info)2440 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info)
2441 {
2442 auto radio = 1.0;
2443 if (info[0]->IsNumber()) {
2444 radio = info[0]->ToNumber<double>();
2445 }
2446 ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0));
2447 }
2448
JsBackgroundImageSize(const JSCallbackInfo & info)2449 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info)
2450 {
2451 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2452 BackgroundImageSize bgImgSize;
2453 if (!CheckJSCallbackInfo("JsBackgroundImageSize", info, checkList)) {
2454 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
2455 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
2456 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2457 return;
2458 }
2459 if (info[0]->IsNumber()) {
2460 auto sizeType = static_cast<BackgroundImageSizeType>(info[0]->ToNumber<int32_t>());
2461 bgImgSize.SetSizeTypeX(sizeType);
2462 bgImgSize.SetSizeTypeY(sizeType);
2463 } else {
2464 CalcDimension width;
2465 CalcDimension height;
2466 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
2467 ParseJsDimensionVp(object->GetProperty("width"), width);
2468 ParseJsDimensionVp(object->GetProperty("height"), height);
2469 double valueWidth = width.ConvertToPx();
2470 double valueHeight = height.ConvertToPx();
2471 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH;
2472 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH;
2473 if (width.Unit() == DimensionUnit::PERCENT) {
2474 typeWidth = BackgroundImageSizeType::PERCENT;
2475 valueWidth = width.Value() * FULL_DIMENSION;
2476 }
2477 if (height.Unit() == DimensionUnit::PERCENT) {
2478 typeHeight = BackgroundImageSizeType::PERCENT;
2479 valueHeight = height.Value() * FULL_DIMENSION;
2480 }
2481 bgImgSize.SetSizeTypeX(typeWidth);
2482 bgImgSize.SetSizeValueX(valueWidth);
2483 bgImgSize.SetSizeTypeY(typeHeight);
2484 bgImgSize.SetSizeValueY(valueHeight);
2485 }
2486
2487 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize);
2488 }
2489
JsBackgroundImagePosition(const JSCallbackInfo & info)2490 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info)
2491 {
2492 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT };
2493 BackgroundImagePosition bgImgPosition;
2494 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", info, checkList)) {
2495 SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition);
2496 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2497 return;
2498 }
2499 if (info[0]->IsNumber()) {
2500 int32_t align = info[0]->ToNumber<int32_t>();
2501 bgImgPosition.SetIsAlign(true);
2502 switch (align) {
2503 case 0:
2504 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, 0.0, 0.0, bgImgPosition);
2505 break;
2506 case 1:
2507 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, HALF_DIMENSION, 0.0, bgImgPosition);
2508 break;
2509 case 2:
2510 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, FULL_DIMENSION, 0.0, bgImgPosition);
2511 break;
2512 case 3:
2513 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, 0.0, HALF_DIMENSION, bgImgPosition);
2514 break;
2515 case 4:
2516 SetBgImgPosition(
2517 DimensionUnit::PERCENT, DimensionUnit::PERCENT, HALF_DIMENSION, HALF_DIMENSION, bgImgPosition);
2518 break;
2519 case 5:
2520 SetBgImgPosition(
2521 DimensionUnit::PERCENT, DimensionUnit::PERCENT, FULL_DIMENSION, HALF_DIMENSION, bgImgPosition);
2522 break;
2523 case 6:
2524 SetBgImgPosition(DimensionUnit::PERCENT, DimensionUnit::PERCENT, 0.0, FULL_DIMENSION, bgImgPosition);
2525 break;
2526 case 7:
2527 SetBgImgPosition(
2528 DimensionUnit::PERCENT, DimensionUnit::PERCENT, HALF_DIMENSION, FULL_DIMENSION, bgImgPosition);
2529 break;
2530 case 8:
2531 SetBgImgPosition(
2532 DimensionUnit::PERCENT, DimensionUnit::PERCENT, FULL_DIMENSION, FULL_DIMENSION, bgImgPosition);
2533 break;
2534 default:
2535 break;
2536 }
2537 } else {
2538 CalcDimension x;
2539 CalcDimension y;
2540 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
2541 ParseJsDimensionVp(object->GetProperty("x"), x);
2542 ParseJsDimensionVp(object->GetProperty("y"), y);
2543 double valueX = x.Value();
2544 double valueY = y.Value();
2545 DimensionUnit typeX = DimensionUnit::PX;
2546 DimensionUnit typeY = DimensionUnit::PX;
2547 if (x.Unit() == DimensionUnit::PERCENT) {
2548 valueX = x.Value();
2549 typeX = DimensionUnit::PERCENT;
2550 }
2551 if (y.Unit() == DimensionUnit::PERCENT) {
2552 valueY = y.Value();
2553 typeY = DimensionUnit::PERCENT;
2554 }
2555 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition);
2556 }
2557
2558 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition);
2559 }
2560
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)2561 std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
2562 {
2563 auto paramArray = JSRef<JSArray>::Cast(info[optionIndex]);
2564 std::vector<NG::OptionParam> params(paramArray->Length());
2565 // parse paramArray
2566 for (size_t i = 0; i < paramArray->Length(); ++i) {
2567 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
2568 JSViewAbstract::ParseJsString(indexObject->GetProperty("value"), params[i].value);
2569 auto actionFunc = indexObject->GetProperty("action");
2570 if (!actionFunc->IsFunction()) {
2571 return params;
2572 }
2573 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
2574 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2575 // set onClick function
2576 params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
2577 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
2578 ACE_SCORING_EVENT("menu.action");
2579 PipelineContext::SetCallBackNode(node);
2580 if (func) {
2581 func->Execute();
2582 }
2583 };
2584 std::string iconPath;
2585 if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty("icon"), iconPath)) {
2586 params[i].icon = iconPath;
2587 }
2588 auto enabled = indexObject->GetProperty("enabled");
2589 if (enabled->IsBoolean()) {
2590 params[i].enabled = enabled->ToBoolean();
2591 }
2592 }
2593 return params;
2594 }
2595
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)2596 void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
2597 {
2598 auto enableArrowValue = menuOptions->GetProperty("enableArrow");
2599 if (enableArrowValue->IsBoolean()) {
2600 menuParam.enableArrow = enableArrowValue->ToBoolean();
2601 }
2602
2603 auto arrowOffset = menuOptions->GetProperty("arrowOffset");
2604 CalcDimension offset;
2605 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
2606 menuParam.arrowOffset = offset;
2607 }
2608
2609 // if enableArrow is true and placement not set, set placement default value to top.
2610 if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
2611 menuParam.placement = Placement::TOP;
2612 }
2613 }
2614
GetMenuShowInSubwindow(NG::MenuParam & menuParam)2615 void GetMenuShowInSubwindow(NG::MenuParam& menuParam)
2616 {
2617 menuParam.isShowInSubWindow = false;
2618 auto pipeline = PipelineBase::GetCurrentContext();
2619 CHECK_NULL_VOID(pipeline);
2620 auto theme = pipeline->GetTheme<SelectTheme>();
2621 CHECK_NULL_VOID(theme);
2622 menuParam.isShowInSubWindow = theme->GetExpandDisplay();
2623 }
2624
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)2625 void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
2626 {
2627 auto offsetVal = menuOptions->GetProperty("offset");
2628 if (offsetVal->IsObject()) {
2629 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
2630 JSRef<JSVal> xVal = offsetObj->GetProperty("x");
2631 JSRef<JSVal> yVal = offsetObj->GetProperty("y");
2632 CalcDimension dx;
2633 CalcDimension dy;
2634 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
2635 menuParam.positionOffset.SetX(dx.ConvertToPx());
2636 }
2637 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
2638 menuParam.positionOffset.SetY(dy.ConvertToPx());
2639 }
2640 }
2641
2642 auto placementValue = menuOptions->GetProperty("placement");
2643 if (placementValue->IsNumber()) {
2644 auto placement = placementValue->ToNumber<int32_t>();
2645 if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) {
2646 menuParam.placement = PLACEMENT[placement];
2647 }
2648 }
2649
2650 auto backgroundColorValue = menuOptions->GetProperty("backgroundColor");
2651 Color backgroundColor;
2652 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
2653 menuParam.backgroundColor = backgroundColor;
2654 }
2655
2656 auto backgroundBlurStyle = menuOptions->GetProperty("backgroundBlurStyle");
2657 BlurStyleOption styleOption;
2658 if (backgroundBlurStyle->IsNumber()) {
2659 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
2660 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2661 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2662 menuParam.backgroundBlurStyle = blurStyle;
2663 }
2664 }
2665 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2666 auto onAppearValue = menuOptions->GetProperty("onAppear");
2667 if (onAppearValue->IsFunction()) {
2668 RefPtr<JsFunction> jsOnAppearFunc =
2669 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
2670 auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
2671 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2672 ACE_SCORING_EVENT("onAppear");
2673 PipelineContext::SetCallBackNode(node);
2674 func->Execute();
2675 };
2676 menuParam.onAppear = std::move(onAppear);
2677 }
2678
2679 auto onDisappearValue = menuOptions->GetProperty("onDisappear");
2680 if (onDisappearValue->IsFunction()) {
2681 RefPtr<JsFunction> jsOnDisAppearFunc =
2682 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
2683 auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
2684 node = frameNode]() {
2685 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2686 ACE_SCORING_EVENT("onDisappear");
2687 PipelineContext::SetCallBackNode(node);
2688 func->Execute();
2689 };
2690 menuParam.onDisappear = std::move(onDisappear);
2691 }
2692 auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
2693 if (aboutToAppearValue->IsFunction()) {
2694 RefPtr<JsFunction> jsAboutToAppearFunc =
2695 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
2696 auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
2697 node = frameNode]() {
2698 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2699 ACE_SCORING_EVENT("aboutToAppear");
2700 PipelineContext::SetCallBackNode(node);
2701 func->Execute();
2702 };
2703 menuParam.aboutToAppear = std::move(aboutToAppear);
2704 }
2705
2706 auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
2707 if (aboutToDisAppearValue->IsFunction()) {
2708 RefPtr<JsFunction> jsAboutToDisAppearFunc =
2709 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
2710 auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
2711 node = frameNode]() {
2712 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2713 ACE_SCORING_EVENT("aboutToDisappear");
2714 PipelineContext::SetCallBackNode(node);
2715 func->Execute();
2716 };
2717 menuParam.aboutToDisappear = std::move(aboutToDisappear);
2718 }
2719
2720 JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
2721 GetMenuShowInSubwindow(menuParam);
2722 if (menuParam.isShowInSubWindow) {
2723 if (showInSubWindowValue->IsBoolean()) {
2724 menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
2725 }
2726 }
2727 ParseMenuArrowParam(menuOptions, menuParam);
2728 }
2729
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)2730 void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
2731 {
2732 auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
2733 JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
2734 ParseMenuParam(info, menuOptions, menuParam);
2735 }
2736
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,NG::MenuParam & menuParam)2737 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, NG::MenuParam& menuParam)
2738 {
2739 constexpr int scaleArraySize = 2;
2740 if (scaleArray->Length() == scaleArraySize) {
2741 auto scalePropertyFrom = scaleArray->GetValueAt(0);
2742 if (scalePropertyFrom->IsNumber()) {
2743 auto scaleFrom = scalePropertyFrom->ToNumber<float>();
2744 menuParam.previewAnimationOptions.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
2745 }
2746 auto scalePropertyTo = scaleArray->GetValueAt(1);
2747 if (scalePropertyTo->IsNumber()) {
2748 auto scaleTo = scalePropertyTo->ToNumber<float>();
2749 menuParam.previewAnimationOptions.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
2750 }
2751 }
2752 }
2753
ParseContentPreviewAnimationOptionsParam(const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)2754 void ParseContentPreviewAnimationOptionsParam(const JSRef<JSObject>& menuContentOptions, NG::MenuParam& menuParam)
2755 {
2756 menuParam.previewAnimationOptions.scaleFrom = -1.0f;
2757 menuParam.previewAnimationOptions.scaleTo = -1.0f;
2758
2759 auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
2760 if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
2761 auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
2762 auto scaleProperty = animationOptionsObj->GetProperty("scale");
2763 if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
2764 JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
2765 ParseAnimationScaleArray(scaleArray, menuParam);
2766 }
2767 }
2768 }
2769
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)2770 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
2771 std::function<void()>& previewBuildFunc)
2772 {
2773 auto menuContentOptions = JSRef<JSObject>::Cast(args);
2774 ParseMenuParam(info, menuContentOptions, menuParam);
2775 RefPtr<JsFunction> previewBuilderFunc;
2776 auto preview = menuContentOptions->GetProperty("preview");
2777 if (!preview->IsFunction() && !preview->IsNumber()) {
2778 return;
2779 }
2780
2781 if (preview->IsNumber()) {
2782 if (preview->ToNumber<int32_t>() == 1) {
2783 menuParam.previewMode = MenuPreviewMode::IMAGE;
2784 ParseContentPreviewAnimationOptionsParam(menuContentOptions, menuParam);
2785 }
2786 } else {
2787 previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
2788 CHECK_NULL_VOID(previewBuilderFunc);
2789 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2790 previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
2791 node = frameNode]() {
2792 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2793 ACE_SCORING_EVENT("BuildContextMenuPreviwer");
2794 PipelineContext::SetCallBackNode(node);
2795 func->Execute();
2796 };
2797 menuParam.previewMode = MenuPreviewMode::CUSTOM;
2798 ParseContentPreviewAnimationOptionsParam(menuContentOptions, menuParam);
2799 }
2800 }
2801
JsBindMenu(const JSCallbackInfo & info)2802 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
2803 {
2804 NG::MenuParam menuParam;
2805 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2806 menuParam.placement = Placement::BOTTOM_LEFT;
2807 }
2808 size_t builderIndex = 0;
2809 GetMenuShowInSubwindow(menuParam);
2810 if (info.Length() > PARAMETER_LENGTH_FIRST) {
2811 if (info[0]->IsBoolean()) {
2812 menuParam.isShow = info[0]->ToBoolean();
2813 menuParam.setShow = true;
2814 builderIndex = 1;
2815 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2816 ParseBindOptionParam(info, menuParam, builderIndex + 1);
2817 }
2818 } else if (info[0]->IsUndefined()) {
2819 menuParam.setShow = true;
2820 menuParam.isShow = false;
2821 builderIndex = 1;
2822 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2823 ParseBindOptionParam(info, menuParam, builderIndex + 1);
2824 }
2825 } else {
2826 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
2827 menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj);
2828 auto isShowObj = callbackObj->GetProperty("value");
2829 if (isShowObj->IsBoolean()) {
2830 menuParam.isShow = isShowObj->ToBoolean();
2831 menuParam.setShow = true;
2832 builderIndex = 1;
2833 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2834 ParseBindOptionParam(info, menuParam, builderIndex + 1);
2835 }
2836 } else {
2837 builderIndex = 0;
2838 ParseBindOptionParam(info, menuParam, builderIndex + 1);
2839 }
2840 }
2841 }
2842 if (info[builderIndex]->IsArray()) {
2843 std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info, builderIndex);
2844 ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
2845 } else if (info[builderIndex]->IsObject()) {
2846 // CustomBuilder
2847 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
2848 auto builder = obj->GetProperty("builder");
2849 if (!builder->IsFunction()) {
2850 return;
2851 }
2852 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2853
2854 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2855 CHECK_NULL_VOID(builderFunc);
2856 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
2857 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2858 ACE_SCORING_EVENT("BuildMenu");
2859 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
2860 func->Execute();
2861 };
2862 ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
2863 }
2864 }
2865
JsPadding(const JSCallbackInfo & info)2866 void JSViewAbstract::JsPadding(const JSCallbackInfo& info)
2867 {
2868 ParseMarginOrPadding(info, false);
2869 }
2870
JsMargin(const JSCallbackInfo & info)2871 void JSViewAbstract::JsMargin(const JSCallbackInfo& info)
2872 {
2873 ParseMarginOrPadding(info, true);
2874 }
2875
ParseMarginOrPadding(const JSCallbackInfo & info,bool isMargin)2876 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, bool isMargin)
2877 {
2878 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING,
2879 JSCallbackInfoType::NUMBER };
2880 if (!CheckJSCallbackInfo("MarginOrPadding", info, checkList)) {
2881 auto resetDimension = CalcDimension(0.0);
2882 if (isMargin) {
2883 ViewAbstractModel::GetInstance()->SetMargin(resetDimension);
2884 } else {
2885 ViewAbstractModel::GetInstance()->SetPadding(resetDimension);
2886 }
2887 return;
2888 }
2889 auto tmpInfo = info[0];
2890 if (tmpInfo->IsObject()) {
2891 std::optional<CalcDimension> left;
2892 std::optional<CalcDimension> right;
2893 std::optional<CalcDimension> top;
2894 std::optional<CalcDimension> bottom;
2895 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(tmpInfo);
2896 ParseMarginOrPaddingCorner(paddingObj, top, bottom, left, right);
2897 if (left.has_value() || right.has_value() || top.has_value() || bottom.has_value()) {
2898 if (isMargin) {
2899 ViewAbstractModel::GetInstance()->SetMargins(top, bottom, left, right);
2900 } else {
2901 ViewAbstractModel::GetInstance()->SetPaddings(top, bottom, left, right);
2902 }
2903 return;
2904 }
2905 }
2906
2907 CalcDimension length;
2908 if (!ParseJsDimensionVp(tmpInfo, length)) {
2909 // use default value.
2910 length.Reset();
2911 }
2912 if (isMargin) {
2913 ViewAbstractModel::GetInstance()->SetMargin(length);
2914 } else {
2915 ViewAbstractModel::GetInstance()->SetPadding(length);
2916 }
2917 }
2918
ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)2919 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top,
2920 std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right)
2921 {
2922 CalcDimension leftDimen;
2923 if (ParseJsDimensionVp(obj->GetProperty("left"), leftDimen)) {
2924 left = leftDimen;
2925 }
2926 CalcDimension rightDimen;
2927 if (ParseJsDimensionVp(obj->GetProperty("right"), rightDimen)) {
2928 right = rightDimen;
2929 }
2930 CalcDimension topDimen;
2931 if (ParseJsDimensionVp(obj->GetProperty("top"), topDimen)) {
2932 top = topDimen;
2933 }
2934 CalcDimension bottomDimen;
2935 if (ParseJsDimensionVp(obj->GetProperty("bottom"), bottomDimen)) {
2936 bottom = bottomDimen;
2937 }
2938 }
2939
JsOutline(const JSCallbackInfo & info)2940 void JSViewAbstract::JsOutline(const JSCallbackInfo& info)
2941 {
2942 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
2943 if (!CheckJSCallbackInfo("JsOutline", info, checkList)) {
2944 CalcDimension borderWidth;
2945 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
2946 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
2947 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth);
2948 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
2949 return;
2950 }
2951 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
2952 auto valueOuterWidth = object->GetProperty("width");
2953 if (!valueOuterWidth->IsUndefined()) {
2954 ParseOuterBorderWidth(valueOuterWidth);
2955 }
2956
2957 // use default value when undefined.
2958 ParseOuterBorderColor(object->GetProperty("color"));
2959
2960 auto valueOuterRadius = object->GetProperty("radius");
2961 if (!valueOuterRadius->IsUndefined()) {
2962 ParseOuterBorderRadius(valueOuterRadius);
2963 }
2964 // use default value when undefined.
2965 ParseOuterBorderStyle(object->GetProperty("style"));
2966 info.ReturnSelf();
2967 }
2968
JsOutlineWidth(const JSCallbackInfo & info)2969 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info)
2970 {
2971 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
2972 JSCallbackInfoType::OBJECT };
2973 if (!CheckJSCallbackInfo("JsOutlineWidth", info, checkList)) {
2974 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({});
2975 return;
2976 }
2977 ParseOuterBorderWidth(info[0]);
2978 }
2979
JsOutlineColor(const JSCallbackInfo & info)2980 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info)
2981 {
2982 ParseOuterBorderColor(info[0]);
2983 }
2984
JsOutlineRadius(const JSCallbackInfo & info)2985 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info)
2986 {
2987 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
2988 JSCallbackInfoType::OBJECT };
2989 if (!CheckJSCallbackInfo("JsOutlineRadius", info, checkList)) {
2990 ViewAbstractModel::GetInstance()->SetOuterBorderRadius({});
2991 return;
2992 }
2993 ParseOuterBorderRadius(info[0]);
2994 }
2995
JsOutlineStyle(const JSCallbackInfo & info)2996 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info)
2997 {
2998 ParseOuterBorderStyle(info[0]);
2999 }
3000
JsBorder(const JSCallbackInfo & info)3001 void JSViewAbstract::JsBorder(const JSCallbackInfo& info)
3002 {
3003 if (!info[0]->IsObject()) {
3004 CalcDimension borderWidth;
3005 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3006 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3007 ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth);
3008 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3009 return;
3010 }
3011 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
3012
3013 auto valueWidth = object->GetProperty("width");
3014 if (!valueWidth->IsUndefined()) {
3015 ParseBorderWidth(valueWidth);
3016 }
3017
3018 // use default value when undefined.
3019 ParseBorderColor(object->GetProperty("color"));
3020
3021 auto valueRadius = object->GetProperty("radius");
3022 if (!valueRadius->IsUndefined()) {
3023 ParseBorderRadius(valueRadius);
3024 }
3025 // use default value when undefined.
3026 ParseBorderStyle(object->GetProperty("style"));
3027
3028 info.ReturnSelf();
3029 }
3030
JsBorderWidth(const JSCallbackInfo & info)3031 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info)
3032 {
3033 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3034 JSCallbackInfoType::OBJECT };
3035 if (!CheckJSCallbackInfo("JsBorderWidth", info, checkList)) {
3036 ViewAbstractModel::GetInstance()->SetBorderWidth({});
3037 return;
3038 }
3039 ParseBorderWidth(info[0]);
3040 }
3041
ParseBorderWidth(const JSRef<JSVal> & args)3042 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args)
3043 {
3044 CalcDimension borderWidth;
3045 if (ParseJsDimensionVp(args, borderWidth)) {
3046 if (borderWidth.IsNegative()) {
3047 borderWidth.Reset();
3048 }
3049 if (borderWidth.Unit() == DimensionUnit::PERCENT) {
3050 borderWidth.Reset();
3051 }
3052 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth);
3053 } else if (args->IsObject()) {
3054 std::optional<CalcDimension> leftDimen;
3055 std::optional<CalcDimension> rightDimen;
3056 std::optional<CalcDimension> topDimen;
3057 std::optional<CalcDimension> bottomDimen;
3058 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3059 CalcDimension left;
3060 if (ParseJsDimensionVp(object->GetProperty("left"), left)) {
3061 if (left.Unit() == DimensionUnit::PERCENT || left.IsNegative()) {
3062 left.Reset();
3063 }
3064 leftDimen = left;
3065 }
3066 CalcDimension right;
3067 if (ParseJsDimensionVp(object->GetProperty("right"), right)) {
3068 if (right.Unit() == DimensionUnit::PERCENT || right.IsNegative()) {
3069 right.Reset();
3070 }
3071 rightDimen = right;
3072 }
3073 CalcDimension top;
3074 if (ParseJsDimensionVp(object->GetProperty("top"), top)) {
3075 if (top.Unit() == DimensionUnit::PERCENT || top.IsNegative()) {
3076 top.Reset();
3077 }
3078 topDimen = top;
3079 }
3080 CalcDimension bottom;
3081 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom)) {
3082 if (bottom.Unit() == DimensionUnit::PERCENT || bottom.IsNegative()) {
3083 bottom.Reset();
3084 }
3085 bottomDimen = bottom;
3086 }
3087 ViewAbstractModel::GetInstance()->SetBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
3088 } else {
3089 return;
3090 }
3091 }
3092
ParseOuterBorderWidth(const JSRef<JSVal> & args)3093 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args)
3094 {
3095 CalcDimension borderWidth;
3096 if (ParseJsDimensionVp(args, borderWidth)) {
3097 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
3098 borderWidth.Reset();
3099 }
3100 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth);
3101 } else if (args->IsObject()) {
3102 std::optional<CalcDimension> leftDimen;
3103 std::optional<CalcDimension> rightDimen;
3104 std::optional<CalcDimension> topDimen;
3105 std::optional<CalcDimension> bottomDimen;
3106 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3107 CalcDimension left;
3108 if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) {
3109 if (left.Unit() == DimensionUnit::PERCENT) {
3110 left.Reset();
3111 }
3112 leftDimen = left;
3113 }
3114 CalcDimension right;
3115 if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) {
3116 if (right.Unit() == DimensionUnit::PERCENT) {
3117 right.Reset();
3118 }
3119 rightDimen = right;
3120 }
3121 CalcDimension top;
3122 if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) {
3123 if (top.Unit() == DimensionUnit::PERCENT) {
3124 top.Reset();
3125 }
3126 topDimen = top;
3127 }
3128 CalcDimension bottom;
3129 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) {
3130 if (bottom.Unit() == DimensionUnit::PERCENT) {
3131 bottom.Reset();
3132 }
3133 bottomDimen = bottom;
3134 }
3135 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen);
3136 } else {
3137 return;
3138 }
3139 }
3140
ParseMenuOptions(const JSCallbackInfo & info,const JSRef<JSArray> & jsArray,std::vector<NG::MenuOptionsParam> & items)3141 void JSViewAbstract::ParseMenuOptions(
3142 const JSCallbackInfo& info, const JSRef<JSArray>& jsArray, std::vector<NG::MenuOptionsParam>& items)
3143 {
3144 auto length = jsArray->Length();
3145 for (size_t i = 0; i < length; i++) {
3146 auto item = jsArray->GetValueAt(i);
3147 if (!item->IsObject()) {
3148 continue;
3149 }
3150 auto itemObject = JSRef<JSObject>::Cast(item);
3151 NG::MenuOptionsParam menuOptionItem;
3152 std::string value;
3153 std::string icon;
3154 auto menuOptionsValue = itemObject->GetProperty("content");
3155 auto menuOptionsIcon = itemObject->GetProperty("icon");
3156
3157 if (!ParseJsString(menuOptionsValue, value)) {
3158 return;
3159 }
3160 ParseJsMedia(menuOptionsIcon, icon);
3161 menuOptionItem.content = value;
3162 menuOptionItem.icon = icon;
3163
3164 auto itemActionValue = itemObject->GetProperty("action");
3165 if (itemActionValue->IsFunction()) {
3166 JsEventCallback<void(const std::string&)> callback(
3167 info.GetExecutionContext(), JSRef<JSFunc>::Cast(itemActionValue));
3168 menuOptionItem.action = callback;
3169 }
3170 items.emplace_back(menuOptionItem);
3171 }
3172 }
3173
JsBorderImage(const JSCallbackInfo & info)3174 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info)
3175 {
3176 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3177 if (!CheckJSCallbackInfo("JsBorderImage", info, checkList)) {
3178 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
3179 uint8_t imageBorderBitsets = 0;
3180 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
3181 return;
3182 }
3183 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
3184 if (object->IsEmpty()) {
3185 return;
3186 }
3187
3188 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>();
3189 uint8_t imageBorderBitsets = 0;
3190
3191 auto valueSource = object->GetProperty("source");
3192 if (!valueSource->IsString() && !valueSource->IsObject()) {
3193 return;
3194 }
3195 std::string srcResult;
3196 if (valueSource->IsString()) {
3197 srcResult = valueSource->ToString();
3198 if (!srcResult.empty()) {
3199 borderImage->SetSrc(srcResult);
3200 imageBorderBitsets |= BorderImage::SOURCE_BIT;
3201 }
3202 } else if (valueSource->IsObject()) {
3203 if (ParseJsMedia(valueSource, srcResult)) {
3204 borderImage->SetSrc(srcResult);
3205 imageBorderBitsets |= BorderImage::SOURCE_BIT;
3206 } else {
3207 ParseBorderImageLinearGradient(valueSource, imageBorderBitsets);
3208 }
3209 }
3210 auto valueOutset = object->GetProperty("outset");
3211 if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) {
3212 imageBorderBitsets |= BorderImage::OUTSET_BIT;
3213 ParseBorderImageOutset(valueOutset, borderImage);
3214 }
3215 auto valueRepeat = object->GetProperty("repeat");
3216 if (!valueRepeat->IsNull()) {
3217 imageBorderBitsets |= BorderImage::REPEAT_BIT;
3218 ParseBorderImageRepeat(valueRepeat, borderImage);
3219 }
3220 auto valueSlice = object->GetProperty("slice");
3221 if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) {
3222 imageBorderBitsets |= BorderImage::SLICE_BIT;
3223 ParseBorderImageSlice(valueSlice, borderImage);
3224 }
3225 auto valueWidth = object->GetProperty("width");
3226 if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) {
3227 imageBorderBitsets |= BorderImage::WIDTH_BIT;
3228 ParseBorderImageWidth(valueWidth, borderImage);
3229 }
3230 auto needFill = object->GetProperty("fill");
3231 if (needFill->IsBoolean()) {
3232 borderImage->SetNeedFillCenter(needFill->ToBoolean());
3233 }
3234 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets);
3235 info.ReturnSelf();
3236 }
3237
ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)3238 void JSViewAbstract::ParseBorderImageDimension(
3239 const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension)
3240 {
3241 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3242 static std::array<std::string, 4> keys = { "left", "right", "top", "bottom" };
3243 for (uint32_t i = 0; i < keys.size(); i++) {
3244 CalcDimension currentDimension;
3245 auto dimensionValue = object->GetProperty(keys.at(i).c_str());
3246 if (ParseJsDimensionVp(dimensionValue, currentDimension)) {
3247 auto direction = static_cast<BorderImageDirection>(i);
3248 switch (direction) {
3249 case BorderImageDirection::LEFT:
3250 borderImageDimension.leftDimension = currentDimension;
3251 break;
3252 case BorderImageDirection::RIGHT:
3253 borderImageDimension.rightDimension = currentDimension;
3254 break;
3255 case BorderImageDirection::TOP:
3256 borderImageDimension.topDimension = currentDimension;
3257 break;
3258 case BorderImageDirection::BOTTOM:
3259 borderImageDimension.bottomDimension = currentDimension;
3260 break;
3261 default:
3262 break;
3263 }
3264 }
3265 }
3266 }
3267
ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)3268 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset)
3269 {
3270 if (!args->IsObject()) {
3271 return;
3272 }
3273 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args);
3274 NG::Gradient lineGradient;
3275 lineGradient.CreateGradientWithType(NG::GradientType::LINEAR);
3276 // angle
3277 std::optional<float> degree;
3278 GetJsAngle("angle", jsObj, degree);
3279 if (degree) {
3280 lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
3281 degree.reset();
3282 }
3283 // direction
3284 auto direction = static_cast<NG::GradientDirection>(
3285 jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(NG::GradientDirection::NONE)));
3286 switch (direction) {
3287 case NG::GradientDirection::LEFT:
3288 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3289 break;
3290 case NG::GradientDirection::RIGHT:
3291 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3292 break;
3293 case NG::GradientDirection::TOP:
3294 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3295 break;
3296 case NG::GradientDirection::BOTTOM:
3297 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3298 break;
3299 case NG::GradientDirection::LEFT_TOP:
3300 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3301 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3302 break;
3303 case NG::GradientDirection::LEFT_BOTTOM:
3304 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
3305 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3306 break;
3307 case NG::GradientDirection::RIGHT_TOP:
3308 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3309 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
3310 break;
3311 case NG::GradientDirection::RIGHT_BOTTOM:
3312 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
3313 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
3314 break;
3315 case NG::GradientDirection::NONE:
3316 case NG::GradientDirection::START_TO_END:
3317 case NG::GradientDirection::END_TO_START:
3318 default:
3319 break;
3320 }
3321 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
3322 lineGradient.SetRepeat(repeating);
3323 NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty("colors"));
3324 ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient);
3325 bitset |= BorderImage::GRADIENT_BIT;
3326 }
3327
ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3328 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3329 {
3330 auto repeatString = args->ToString();
3331 if (repeatString == "Repeat") {
3332 borderImage->SetRepeatMode(BorderImageRepeat::REPEAT);
3333 } else if (repeatString == "Round") {
3334 borderImage->SetRepeatMode(BorderImageRepeat::ROUND);
3335 } else if (repeatString == "Space") {
3336 borderImage->SetRepeatMode(BorderImageRepeat::SPACE);
3337 } else {
3338 borderImage->SetRepeatMode(BorderImageRepeat::STRETCH);
3339 }
3340 }
3341
ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3342 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3343 {
3344 CalcDimension outsetDimension;
3345 if (ParseJsDimensionVp(args, outsetDimension)) {
3346 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension);
3347 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension);
3348 borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension);
3349 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension);
3350 return;
3351 }
3352 BorderImage::BorderImageOption option;
3353 ParseBorderImageDimension(args, option);
3354 if (option.leftDimension.has_value()) {
3355 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value());
3356 }
3357 if (option.rightDimension.has_value()) {
3358 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value());
3359 }
3360 if (option.topDimension.has_value()) {
3361 borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value());
3362 }
3363 if (option.bottomDimension.has_value()) {
3364 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value());
3365 }
3366 }
3367
ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3368 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3369 {
3370 CalcDimension sliceDimension;
3371 if (ParseJsDimensionVp(args, sliceDimension)) {
3372 borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension);
3373 borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension);
3374 borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension);
3375 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension);
3376 return;
3377 }
3378
3379 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3380 static std::array<std::string, 4> keys = { "left", "right", "top", "bottom" };
3381 for (uint32_t i = 0; i < keys.size(); i++) {
3382 auto dimensionValue = object->GetProperty(keys.at(i).c_str());
3383 if (ParseJsDimensionVp(dimensionValue, sliceDimension)) {
3384 borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension);
3385 }
3386 }
3387 }
3388
ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)3389 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage)
3390 {
3391 CalcDimension widthDimension;
3392 if (ParseJsDimensionVp(args, widthDimension)) {
3393 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension);
3394 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension);
3395 borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension);
3396 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension);
3397 return;
3398 }
3399
3400 BorderImage::BorderImageOption option;
3401 ParseBorderImageDimension(args, option);
3402 if (option.leftDimension.has_value()) {
3403 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value());
3404 }
3405 if (option.rightDimension.has_value()) {
3406 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value());
3407 }
3408 if (option.topDimension.has_value()) {
3409 borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value());
3410 }
3411 if (option.bottomDimension.has_value()) {
3412 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value());
3413 }
3414 }
3415
JsBorderColor(const JSCallbackInfo & info)3416 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info)
3417 {
3418 ParseBorderColor(info[0]);
3419 }
3420
ParseBorderColor(const JSRef<JSVal> & args)3421 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args)
3422 {
3423 Color borderColor;
3424 if (ParseJsColor(args, borderColor)) {
3425 ViewAbstractModel::GetInstance()->SetBorderColor(borderColor);
3426 } else if (args->IsObject()) {
3427 std::optional<Color> leftColor;
3428 std::optional<Color> rightColor;
3429 std::optional<Color> topColor;
3430 std::optional<Color> bottomColor;
3431 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3432 Color left;
3433 if (ParseJsColor(object->GetProperty("left"), left)) {
3434 leftColor = left;
3435 }
3436 Color right;
3437 if (ParseJsColor(object->GetProperty("right"), right)) {
3438 rightColor = right;
3439 }
3440 Color top;
3441 if (ParseJsColor(object->GetProperty("top"), top)) {
3442 topColor = top;
3443 }
3444 Color bottom;
3445 if (ParseJsColor(object->GetProperty("bottom"), bottom)) {
3446 bottomColor = bottom;
3447 }
3448
3449 ViewAbstractModel::GetInstance()->SetBorderColor(leftColor, rightColor, topColor, bottomColor);
3450 } else {
3451 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK);
3452 }
3453 }
3454
ParseOuterBorderColor(const JSRef<JSVal> & args)3455 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args)
3456 {
3457 Color borderColor;
3458 if (ParseJsColor(args, borderColor)) {
3459 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
3460 } else if (args->IsObject()) {
3461 std::optional<Color> leftColor;
3462 std::optional<Color> rightColor;
3463 std::optional<Color> topColor;
3464 std::optional<Color> bottomColor;
3465 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3466 Color left;
3467 if (ParseJsColor(object->GetProperty("left"), left)) {
3468 leftColor = left;
3469 }
3470 Color right;
3471 if (ParseJsColor(object->GetProperty("right"), right)) {
3472 rightColor = right;
3473 }
3474 Color top;
3475 if (ParseJsColor(object->GetProperty("top"), top)) {
3476 topColor = top;
3477 }
3478 Color bottom;
3479 if (ParseJsColor(object->GetProperty("bottom"), bottom)) {
3480 bottomColor = bottom;
3481 }
3482
3483 ViewAbstractModel::GetInstance()->SetOuterBorderColor(leftColor, rightColor, topColor, bottomColor);
3484 } else {
3485 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK);
3486 }
3487 }
3488
JsBorderRadius(const JSCallbackInfo & info)3489 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info)
3490 {
3491 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
3492 JSCallbackInfoType::OBJECT };
3493 if (!CheckJSCallbackInfo("JsBorderRadius", info, checkList)) {
3494 ViewAbstractModel::GetInstance()->SetBorderRadius({});
3495 return;
3496 }
3497 ParseBorderRadius(info[0]);
3498 }
3499
ParseBorderRadius(const JSRef<JSVal> & args)3500 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args)
3501 {
3502 CalcDimension borderRadius;
3503 if (ParseJsDimensionVp(args, borderRadius)) {
3504 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
3505 borderRadius.Reset();
3506 }
3507 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
3508 } else if (args->IsObject()) {
3509 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3510 CalcDimension topLeft;
3511 CalcDimension topRight;
3512 CalcDimension bottomLeft;
3513 CalcDimension bottomRight;
3514 ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
3515 ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
3516 }
3517 }
3518
ParseOuterBorderRadius(const JSRef<JSVal> & args)3519 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args)
3520 {
3521 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
3522 return;
3523 }
3524 CalcDimension borderRadius;
3525 if (ParseJsDimensionVp(args, borderRadius)) {
3526 if (borderRadius.Unit() == DimensionUnit::PERCENT) {
3527 borderRadius.Reset();
3528 }
3529 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius);
3530 } else if (args->IsObject()) {
3531 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3532 CalcDimension topLeft;
3533 CalcDimension topRight;
3534 CalcDimension bottomLeft;
3535 CalcDimension bottomRight;
3536 ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
3537 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
3538 }
3539 }
3540
GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)3541 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius)
3542 {
3543 if (ParseJsDimensionVp(object->GetProperty(key), radius)) {
3544 if ((radius.Unit() == DimensionUnit::PERCENT)) {
3545 radius.Reset();
3546 }
3547 }
3548 }
3549
ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)3550 void JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight,
3551 CalcDimension& bottomLeft, CalcDimension& bottomRight)
3552 {
3553 GetBorderRadius("topLeft", object, topLeft);
3554 GetBorderRadius("topRight", object, topRight);
3555 GetBorderRadius("bottomLeft", object, bottomLeft);
3556 GetBorderRadius("bottomRight", object, bottomRight);
3557 }
3558
JsBorderStyle(const JSCallbackInfo & info)3559 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info)
3560 {
3561 ParseBorderStyle(info[0]);
3562 }
3563 namespace {
ConvertBorderStyle(int32_t value)3564 BorderStyle ConvertBorderStyle(int32_t value)
3565 {
3566 auto style = static_cast<BorderStyle>(value);
3567 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) {
3568 style = BorderStyle::SOLID;
3569 }
3570 return style;
3571 }
3572 } // namespace
3573
ParseBorderStyle(const JSRef<JSVal> & args)3574 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args)
3575 {
3576 if (args->IsObject()) {
3577 std::optional<BorderStyle> styleLeft;
3578 std::optional<BorderStyle> styleRight;
3579 std::optional<BorderStyle> styleTop;
3580 std::optional<BorderStyle> styleBottom;
3581 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3582 auto leftValue = object->GetProperty("left");
3583 if (leftValue->IsNumber()) {
3584 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
3585 }
3586 auto rightValue = object->GetProperty("right");
3587 if (rightValue->IsNumber()) {
3588 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
3589 }
3590 auto topValue = object->GetProperty("top");
3591 if (topValue->IsNumber()) {
3592 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
3593 }
3594 auto bottomValue = object->GetProperty("bottom");
3595 if (bottomValue->IsNumber()) {
3596 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
3597 }
3598 ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
3599 return;
3600 }
3601 if (args->IsNumber()) {
3602 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
3603 ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle);
3604 return;
3605 }
3606 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID);
3607 }
3608
ParseOuterBorderStyle(const JSRef<JSVal> & args)3609 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args)
3610 {
3611 if (!args->IsObject() && !args->IsNumber()) {
3612 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID);
3613 return;
3614 }
3615 if (args->IsObject()) {
3616 std::optional<BorderStyle> styleLeft;
3617 std::optional<BorderStyle> styleRight;
3618 std::optional<BorderStyle> styleTop;
3619 std::optional<BorderStyle> styleBottom;
3620 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3621 auto leftValue = object->GetProperty("left");
3622 if (!leftValue->IsUndefined() && leftValue->IsNumber()) {
3623 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>());
3624 }
3625 auto rightValue = object->GetProperty("right");
3626 if (!rightValue->IsUndefined() && rightValue->IsNumber()) {
3627 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>());
3628 }
3629 auto topValue = object->GetProperty("top");
3630 if (!topValue->IsUndefined() && topValue->IsNumber()) {
3631 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>());
3632 }
3633 auto bottomValue = object->GetProperty("bottom");
3634 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) {
3635 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>());
3636 }
3637 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom);
3638 return;
3639 }
3640 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>());
3641 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle);
3642 }
3643
JsBlur(const JSCallbackInfo & info)3644 void JSViewAbstract::JsBlur(const JSCallbackInfo& info)
3645 {
3646 if (info.Length() == 0) {
3647 return;
3648 }
3649 double blur = 0.0;
3650 if (!ParseJsDouble(info[0], blur)) {
3651 return;
3652 }
3653
3654 BlurOption blurOption;
3655 if (info.Length() > 1 && info[1]->IsObject()) {
3656 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
3657 ParseBlurOption(jsBlurOption, blurOption);
3658 }
3659 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
3660 ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption);
3661 info.SetReturnValue(info.This());
3662 }
3663
JsColorBlend(const JSCallbackInfo & info)3664 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info)
3665 {
3666 Color colorBlend;
3667 if (info[0]->IsUndefined()) {
3668 colorBlend = Color::TRANSPARENT;
3669 SetColorBlend(colorBlend);
3670 return;
3671 }
3672 if (!ParseJsColor(info[0], colorBlend)) {
3673 return;
3674 }
3675 SetColorBlend(colorBlend);
3676 info.SetReturnValue(info.This());
3677 }
3678
JsUseEffect(const JSCallbackInfo & info)3679 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info)
3680 {
3681 if (info[0]->IsBoolean()) {
3682 ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean());
3683 }
3684 }
3685
JsUseShadowBatching(const JSCallbackInfo & info)3686 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info)
3687 {
3688 if (info[0]->IsBoolean()) {
3689 ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean());
3690 }
3691 }
3692
JsBackdropBlur(const JSCallbackInfo & info)3693 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info)
3694 {
3695 if (info.Length() == 0) {
3696 return;
3697 }
3698 double blur = 0.0;
3699 if (!ParseJsDouble(info[0], blur)) {
3700 return;
3701 }
3702 BlurOption blurOption;
3703 if (info.Length() > 1 && info[1]->IsObject()) {
3704 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]);
3705 ParseBlurOption(jsBlurOption, blurOption);
3706 }
3707 CalcDimension dimensionRadius(blur, DimensionUnit::PX);
3708 ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption);
3709
3710 info.SetReturnValue(info.This());
3711 }
3712
GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)3713 void JSViewAbstract::GetFractionStops(
3714 std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array)
3715 {
3716 if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) {
3717 return;
3718 }
3719 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
3720 float tmpPos = -1.0f;
3721 size_t length = jsArray->Length();
3722 for (size_t i = 0; i < length; i++) {
3723 std::pair<float, float> fractionStop;
3724 JSRef<JSVal> item = jsArray->GetValueAt(i);
3725 if (!item->IsArray()) {
3726 continue;
3727 }
3728 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
3729 if (subArray->Length() < 2) {
3730 continue;
3731 }
3732
3733 double value = 0.0;
3734 if (ParseJsDouble(subArray->GetValueAt(0), value)) {
3735 value = std::clamp(value, 0.0, 1.0);
3736 fractionStop.first = static_cast<float>(value);
3737 }
3738 value = 0.0;
3739 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
3740 value = std::clamp(value, 0.0, 1.0);
3741 fractionStop.second = static_cast<float>(value);
3742 }
3743
3744 if (fractionStop.second <= tmpPos) {
3745 fractionStops.clear();
3746 return;
3747 }
3748 tmpPos = fractionStop.second;
3749 fractionStops.push_back(fractionStop);
3750 }
3751 }
JsLinearGradientBlur(const JSCallbackInfo & info)3752 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info)
3753 {
3754 if (info.Length() < 2) { // 2 represents the least para num;
3755 return;
3756 }
3757 double blurRadius = 0.0;
3758 ParseJsDouble(info[0], blurRadius);
3759
3760 std::vector<std::pair<float, float>> fractionStops;
3761 auto direction = GradientDirection::BOTTOM;
3762 if (info[1]->IsObject()) {
3763 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]);
3764 GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops"));
3765 auto directionValue =
3766 jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM));
3767 if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) ||
3768 directionValue >= static_cast<int8_t>(GradientDirection::NONE)) {
3769 directionValue = static_cast<int8_t>(GradientDirection::BOTTOM);
3770 }
3771 direction = static_cast<GradientDirection>(directionValue);
3772 }
3773 if (static_cast<int32_t>(fractionStops.size()) <= 1) {
3774 fractionStops.clear();
3775 fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f));
3776 fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f));
3777 }
3778 // Parse direction
3779 CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX);
3780 NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction));
3781 SetLinearGradientBlur(blurPara);
3782 }
3783
JsBackgroundBrightness(const JSCallbackInfo & info)3784 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info)
3785 {
3786 double rate = 0.0;
3787 double lightUpDegree = 0.0;
3788 if (info[0]->IsObject()) {
3789 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
3790 ParseJsDouble(jsObj->GetProperty("rate"), rate);
3791 ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree);
3792 }
3793 SetDynamicLightUp(rate, lightUpDegree);
3794 }
3795
JsWindowBlur(const JSCallbackInfo & info)3796 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info)
3797 {
3798 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
3799 if (!CheckJSCallbackInfo("JsWindowBlur", info, checkList)) {
3800 return;
3801 }
3802
3803 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
3804 double progress = 0.0;
3805 ParseJsDouble(jsObj->GetProperty("percent"), progress);
3806 auto style = jsObj->GetPropertyValue<int32_t>("style",
3807 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT));
3808
3809 progress = std::clamp(progress, 0.0, 1.0);
3810 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT),
3811 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK));
3812
3813 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style));
3814 info.SetReturnValue(info.This());
3815 }
3816
ParseDollarResource(const JSRef<JSVal> & jsValue,ResourceType & resType,std::string & resName)3817 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, ResourceType& resType, std::string& resName)
3818 {
3819 if (!jsValue->IsString()) {
3820 return false;
3821 }
3822 std::string resPath = jsValue->ToString();
3823 std::vector<std::string> tokens;
3824 StringUtils::StringSplitter(resPath, '.', tokens);
3825 if (static_cast<int32_t>(tokens.size()) != 3) { // $r format like app.xxx.xxx, has 3 paragraph
3826 return false;
3827 }
3828 if (std::find(RESOURCE_HEADS.begin(), RESOURCE_HEADS.end(), tokens[0]) == RESOURCE_HEADS.end()) {
3829 return false;
3830 }
3831 if (!ConvertResourceType(tokens[1], resType)) {
3832 return false;
3833 }
3834 resName = resPath;
3835 return true;
3836 }
3837
ConvertResourceType(const std::string & typeName,ResourceType & resType)3838 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType)
3839 {
3840 static const std::unordered_map<std::string, ResourceType> resTypeMap {
3841 { "color", ResourceType::COLOR },
3842 { "media", ResourceType::MEDIA },
3843 { "float", ResourceType::FLOAT },
3844 { "string", ResourceType::STRING },
3845 { "plural", ResourceType::PLURAL },
3846 { "pattern", ResourceType::PATTERN },
3847 { "boolean", ResourceType::BOOLEAN },
3848 { "integer", ResourceType::INTEGER },
3849 { "strarray", ResourceType::STRARRAY },
3850 { "intarray", ResourceType::INTARRAY },
3851 };
3852 auto it = resTypeMap.find(typeName);
3853 if (it == resTypeMap.end()) {
3854 return false;
3855 }
3856 resType = it->second;
3857 return true;
3858 }
3859
CompleteResourceObject(JSRef<JSObject> & jsObj)3860 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj)
3861 {
3862 // dynamic $r raw input format is
3863 // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"}
3864 JSRef<JSVal> resId = jsObj->GetProperty("id");
3865 ResourceType resType;
3866 std::string resName;
3867 if (!ParseDollarResource(resId, resType, resName)) {
3868 return;
3869 }
3870 JSRef<JSVal> args = jsObj->GetProperty("params");
3871 if (!args->IsArray()) {
3872 return;
3873 }
3874 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3875 auto paramCount = params->Length();
3876 JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName));
3877 if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) {
3878 std::vector<JSRef<JSVal>> tmpParams;
3879 for (uint32_t i = 0; i < paramCount; i++) {
3880 auto param = params->GetValueAt(i);
3881 tmpParams.insert(tmpParams.end(), param);
3882 }
3883 params->SetValueAt(0, name);
3884 uint32_t paramIndex = 1;
3885 auto firstParam = jsObj->GetProperty("type");
3886 if (!firstParam->IsEmpty()) {
3887 params->SetValueAt(paramIndex, firstParam);
3888 paramIndex++;
3889 }
3890 for (auto tmpParam : tmpParams) {
3891 params->SetValueAt(paramIndex, tmpParam);
3892 paramIndex++;
3893 }
3894 } else {
3895 params->SetValueAt(0, name);
3896 }
3897 jsObj->SetProperty<int32_t>("id", UNKNOWN_RESOURCE_ID);
3898 jsObj->SetProperty<int32_t>("type", static_cast<int32_t>(resType));
3899 if (!jsObj->HasProperty("bundleName")) {
3900 jsObj->SetProperty<std::string>("bundleName", "");
3901 }
3902 if (!jsObj->HasProperty("moduleName")) {
3903 jsObj->SetProperty<std::string>("moduleName", "");
3904 }
3905 }
3906
ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)3907 bool JSViewAbstract::ParseJsDimensionNG(
3908 const JSRef<JSVal> &jsValue, CalcDimension &result, DimensionUnit defaultUnit, bool isSupportPercent)
3909 {
3910 if (jsValue->IsNumber()) {
3911 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
3912 return true;
3913 }
3914 if (jsValue->IsString()) {
3915 auto value = jsValue->ToString();
3916 if (value.back() == '%' && !isSupportPercent) {
3917 return false;
3918 }
3919 return StringUtils::StringToCalcDimensionNG(jsValue->ToString(), result, false, defaultUnit);
3920 }
3921 if (jsValue->IsObject()) {
3922 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3923 CompleteResourceObject(jsObj);
3924 JSRef<JSVal> resId = jsObj->GetProperty("id");
3925 if (!resId->IsNumber()) {
3926 return false;
3927 }
3928 auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
3929 if (resType == UNKNOWN_RESOURCE_TYPE) {
3930 return false;
3931 }
3932
3933 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
3934 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
3935 if (!resourceWrapper) {
3936 return false;
3937 }
3938
3939 auto resIdNum = resId->ToNumber<int32_t>();
3940 if (resIdNum == -1) {
3941 if (!IsGetResourceByName(jsObj)) {
3942 return false;
3943 }
3944 JSRef<JSVal> args = jsObj->GetProperty("params");
3945 if (!args->IsArray()) {
3946 return false;
3947 }
3948 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
3949 auto param = params->GetValueAt(0);
3950 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
3951 auto value = resourceWrapper->GetStringByName(param->ToString());
3952 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
3953 }
3954 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
3955 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
3956 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
3957 return true;
3958 }
3959 result = resourceWrapper->GetDimensionByName(param->ToString());
3960 return true;
3961 }
3962
3963 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
3964 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
3965 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
3966 }
3967 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
3968 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
3969 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
3970 return true;
3971 }
3972
3973 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
3974 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value
3975 return true;
3976 }
3977 }
3978
3979 return false;
3980 }
3981
ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)3982 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit)
3983 {
3984 if (jsValue->IsNumber()) {
3985 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit);
3986 return true;
3987 }
3988 if (jsValue->IsString()) {
3989 result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit);
3990 return true;
3991 }
3992 if (!jsValue->IsObject()) {
3993 return false;
3994 }
3995 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
3996 CompleteResourceObject(jsObj);
3997 JSRef<JSVal> resId = jsObj->GetProperty("id");
3998 if (!resId->IsNumber()) {
3999 return false;
4000 }
4001
4002 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4003 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4004 if (!resourceWrapper) {
4005 return false;
4006 }
4007
4008 auto resIdNum = resId->ToNumber<int32_t>();
4009 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4010 if (resType == UNKNOWN_RESOURCE_TYPE) {
4011 return false;
4012 }
4013
4014 if (resIdNum == -1) {
4015 if (!IsGetResourceByName(jsObj)) {
4016 return false;
4017 }
4018 JSRef<JSVal> args = jsObj->GetProperty("params");
4019 if (!args->IsArray()) {
4020 return false;
4021 }
4022 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4023 auto param = params->GetValueAt(0);
4024 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4025 auto value = resourceWrapper->GetStringByName(param->ToString());
4026 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
4027 return true;
4028 }
4029 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4030 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString()));
4031 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
4032 return true;
4033 }
4034 result = resourceWrapper->GetDimensionByName(param->ToString());
4035 return true;
4036 }
4037
4038 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4039 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4040 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
4041 return true;
4042 }
4043 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4044 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
4045 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
4046 return true;
4047 }
4048 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>());
4049 return true;
4050 }
4051
ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)4052 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
4053 {
4054 // 'vp' -> the value varies with pixel density of device.
4055 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent);
4056 }
4057
ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)4058 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result)
4059 {
4060 // 'vp' -> the value varies with pixel density of device.
4061 return ParseJsDimension(jsValue, result, DimensionUnit::VP);
4062 }
4063
ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)4064 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result)
4065 {
4066 // the 'fp' unit is used for text scenes.
4067 return ParseJsDimension(jsValue, result, DimensionUnit::FP);
4068 }
4069
ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)4070 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent)
4071 {
4072 // the 'fp' unit is used for text scenes.
4073 return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent);
4074 }
4075
ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)4076 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result)
4077 {
4078 return ParseJsDimension(jsValue, result, DimensionUnit::PX);
4079 }
4080
ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)4081 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result)
4082 {
4083 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4084 CompleteResourceObject(jsObj);
4085 if (jsObj->IsEmpty()) {
4086 return false;
4087 }
4088 JSRef<JSVal> id = jsObj->GetProperty("id");
4089 if (!id->IsNumber()) {
4090 return false;
4091 }
4092
4093 auto resId = id->ToNumber<int32_t>();
4094 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4095 if (resType == UNKNOWN_RESOURCE_TYPE) {
4096 return false;
4097 }
4098
4099 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4100 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4101 if (!resourceWrapper) {
4102 return false;
4103 }
4104
4105 if (resId == -1) {
4106 if (!IsGetResourceByName(jsObj)) {
4107 return false;
4108 }
4109 JSRef<JSVal> args = jsObj->GetProperty("params");
4110 if (!args->IsArray()) {
4111 return false;
4112 }
4113 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4114 auto param = params->GetValueAt(0);
4115 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4116 auto numberString = resourceWrapper->GetStringByName(param->ToString());
4117 return StringUtils::StringToDouble(numberString, result);
4118 }
4119 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4120 result = resourceWrapper->GetIntByName(param->ToString());
4121 return true;
4122 }
4123 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4124 result = resourceWrapper->GetDoubleByName(param->ToString());
4125 return true;
4126 }
4127 return false;
4128 }
4129 if (resType == static_cast<int32_t>(ResourceType::STRING)) {
4130 auto numberString = resourceWrapper->GetString(resId);
4131 return StringUtils::StringToDouble(numberString, result);
4132 }
4133 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) {
4134 result = resourceWrapper->GetInt(resId);
4135 return true;
4136 }
4137 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) {
4138 result = resourceWrapper->GetDouble(resId);
4139 return true;
4140 }
4141 return false;
4142 }
4143
ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)4144 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result)
4145 {
4146 if (jsValue->IsNumber()) {
4147 result = jsValue->ToNumber<double>();
4148 return true;
4149 }
4150 if (jsValue->IsString()) {
4151 return StringUtils::StringToDouble(jsValue->ToString(), result);
4152 }
4153 if (jsValue->IsObject()) {
4154 return ParseResourceToDouble(jsValue, result);
4155 }
4156 return false;
4157 }
4158
ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)4159 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result)
4160 {
4161 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
4162 return false;
4163 }
4164 if (jsValue->IsNumber()) {
4165 result = jsValue->ToNumber<int32_t>();
4166 return true;
4167 }
4168 if (jsValue->IsString()) {
4169 result = StringUtils::StringToInt(jsValue->ToString());
4170 return true;
4171 }
4172 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4173 CompleteResourceObject(jsObj);
4174 JSRef<JSVal> resId = jsObj->GetProperty("id");
4175 if (!resId->IsNumber()) {
4176 return false;
4177 }
4178
4179 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4180 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4181 if (!resourceWrapper) {
4182 return false;
4183 }
4184
4185 auto resIdNum = resId->ToNumber<int32_t>();
4186 if (resIdNum == -1) {
4187 if (!IsGetResourceByName(jsObj)) {
4188 return false;
4189 }
4190 JSRef<JSVal> args = jsObj->GetProperty("params");
4191 if (!args->IsArray()) {
4192 return false;
4193 }
4194 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4195 auto param = params->GetValueAt(0);
4196 result = resourceWrapper->GetIntByName(param->ToString());
4197 return true;
4198 }
4199 result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
4200 return true;
4201 }
4202
ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)4203 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result)
4204 {
4205 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4206 CompleteResourceObject(jsObj);
4207 JSRef<JSVal> resId = jsObj->GetProperty("id");
4208 if (!resId->IsNumber()) {
4209 return false;
4210 }
4211
4212 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4213 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4214 if (!resourceWrapper) {
4215 return false;
4216 }
4217
4218 auto resIdNum = resId->ToNumber<int32_t>();
4219 if (resIdNum == -1) {
4220 if (!IsGetResourceByName(jsObj)) {
4221 return false;
4222 }
4223 JSRef<JSVal> args = jsObj->GetProperty("params");
4224 if (!args->IsArray()) {
4225 return false;
4226 }
4227 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4228 auto param = params->GetValueAt(0);
4229 result = resourceWrapper->GetColorByName(param->ToString());
4230 return true;
4231 }
4232 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4233 if (type == static_cast<int32_t>(ResourceType::STRING)) {
4234 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4235 return Color::ParseColorString(value, result);
4236 }
4237 if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
4238 auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>());
4239 result = Color(ColorAlphaAdapt(value));
4240 return true;
4241 }
4242 if (type == static_cast<int32_t>(ResourceType::COLOR)) {
4243 result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>());
4244 return true;
4245 }
4246 return false;
4247 }
4248
ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)4249 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result)
4250 {
4251 if (jsValue->IsNumber()) {
4252 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>()));
4253 return true;
4254 }
4255 if (jsValue->IsString()) {
4256 return Color::ParseColorString(jsValue->ToString(), result);
4257 }
4258 if (jsValue->IsObject()) {
4259 return ParseJsColorFromResource(jsValue, result);
4260 }
4261 return false;
4262 }
4263
ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)4264 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy)
4265 {
4266 if (jsValue->IsString()) {
4267 std::string colorStr = jsValue->ToString();
4268 if (colorStr.compare("invert") == 0) {
4269 strategy = ForegroundColorStrategy::INVERT;
4270 return true;
4271 }
4272 }
4273 return false;
4274 }
4275
ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)4276 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy)
4277 {
4278 if (jsValue->IsString()) {
4279 std::string colorStr = jsValue->ToString();
4280 if (colorStr.compare("average") == 0) {
4281 strategy = ShadowColorStrategy::AVERAGE;
4282 return true;
4283 } else if (colorStr.compare("primary") == 0) {
4284 strategy = ShadowColorStrategy::PRIMARY;
4285 return true;
4286 }
4287 }
4288 return false;
4289 }
4290
ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)4291 bool JSViewAbstract::ParseJsSymbolId(
4292 const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject)
4293 {
4294 if (jsValue->IsNull() || jsValue->IsUndefined()) {
4295 symbolId = 0;
4296 return false;
4297 }
4298 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4299 JSRef<JSVal> resId = jsObj->GetProperty("id");
4300 if (resId->IsNull() || !resId->IsNumber()) {
4301 return false;
4302 }
4303 auto resourceObject = GetResourceObject(jsObj);
4304 symbolResourceObject = resourceObject;
4305 if (!resourceObject) {
4306 return false;
4307 }
4308 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4309 if (!resourceWrapper) {
4310 return false;
4311 }
4312 auto symbol = resourceWrapper->GetSymbolById(resId->ToNumber<uint32_t>());
4313 if (!symbol) {
4314 return false;
4315 }
4316 symbolId = symbol;
4317 return true;
4318 }
4319
ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)4320 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result)
4321 {
4322 if (!jsValue->IsArray()) {
4323 return false;
4324 }
4325 if (jsValue->IsArray()) {
4326 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
4327 for (size_t i = 0; i < array->Length(); i++) {
4328 JSRef<JSVal> value = array->GetValueAt(i);
4329 if (!value->IsNumber() && !value->IsString() && !value->IsObject()) {
4330 return false;
4331 }
4332 if (value->IsNumber()) {
4333 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>())));
4334 continue;
4335 } else if (value->IsString()) {
4336 Color color;
4337 Color::ParseColorString(value->ToString(), color);
4338 result.emplace_back(color);
4339 continue;
4340 } else {
4341 Color color;
4342 ParseJsColorFromResource(value, color);
4343 result.emplace_back(color);
4344 }
4345 }
4346 return true;
4347 }
4348 return false;
4349 }
4350
ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)4351 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
4352 {
4353 result.clear();
4354 if (!jsValue->IsString() && !jsValue->IsObject()) {
4355 return false;
4356 }
4357 if (jsValue->IsString()) {
4358 result = ConvertStrToFontFamilies(jsValue->ToString());
4359 return true;
4360 }
4361 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4362 CompleteResourceObject(jsObj);
4363 JSRef<JSVal> resId = jsObj->GetProperty("id");
4364 if (!resId->IsNumber()) {
4365 return false;
4366 }
4367
4368 auto resourceObject = GetResourceObject(jsObj);
4369 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4370 if (!resourceWrapper) {
4371 return false;
4372 }
4373
4374 auto resIdNum = resId->ToNumber<int32_t>();
4375 if (resIdNum == -1) {
4376 if (!IsGetResourceByName(jsObj)) {
4377 return false;
4378 }
4379 JSRef<JSVal> args = jsObj->GetProperty("params");
4380 if (!args->IsArray()) {
4381 return false;
4382 }
4383 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4384 auto param = params->GetValueAt(0);
4385 result.emplace_back(resourceWrapper->GetStringByName(param->ToString()));
4386 return true;
4387 }
4388 result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>()));
4389 return true;
4390 }
4391
ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)4392 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result)
4393 {
4394 if (!jsValue->IsString() && !jsValue->IsObject()) {
4395 return false;
4396 }
4397
4398 if (jsValue->IsString()) {
4399 result = jsValue->ToString();
4400 return true;
4401 }
4402
4403 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4404 CompleteResourceObject(jsObj);
4405
4406 JSRef<JSVal> resId = jsObj->GetProperty("id");
4407 if (!resId->IsNumber()) {
4408 return false;
4409 }
4410 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4411 if (type == UNKNOWN_RESOURCE_TYPE) {
4412 return false;
4413 }
4414
4415 JSRef<JSVal> args = jsObj->GetProperty("params");
4416 if (!args->IsArray()) {
4417 return false;
4418 }
4419
4420 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4421 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4422 if (!resourceWrapper) {
4423 return false;
4424 }
4425
4426 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4427 auto resIdNum = resId->ToNumber<int32_t>();
4428 if (resIdNum == -1) {
4429 if (!IsGetResourceByName(jsObj)) {
4430 return false;
4431 }
4432 auto param = params->GetValueAt(0);
4433 if (type == static_cast<int32_t>(ResourceType::STRING)) {
4434 auto originStr = resourceWrapper->GetStringByName(param->ToString());
4435 ReplaceHolder(originStr, params, 1);
4436 result = originStr;
4437 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
4438 auto countJsVal = params->GetValueAt(1);
4439 int count = 0;
4440 if (!countJsVal->IsNumber()) {
4441 return false;
4442 }
4443 count = countJsVal->ToNumber<int>();
4444 auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count);
4445 ReplaceHolder(pluralStr, params, 2);
4446 result = pluralStr;
4447 } else {
4448 return false;
4449 }
4450 return true;
4451 }
4452 if (type == static_cast<int32_t>(ResourceType::STRING)) {
4453 auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>());
4454 ReplaceHolder(originStr, params, 0);
4455 result = originStr;
4456 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
4457 auto countJsVal = params->GetValueAt(0);
4458 int count = 0;
4459 if (!countJsVal->IsNumber()) {
4460 return false;
4461 }
4462 count = countJsVal->ToNumber<int>();
4463 auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count);
4464 ReplaceHolder(pluralStr, params, 1);
4465 result = pluralStr;
4466 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
4467 result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>()));
4468 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
4469 result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>()));
4470 } else {
4471 return false;
4472 }
4473 return true;
4474 }
4475
ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)4476 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result)
4477 {
4478 if (!jsValue->IsObject() && !jsValue->IsString()) {
4479 return false;
4480 }
4481 if (jsValue->IsString()) {
4482 result = jsValue->ToString();
4483 return true;
4484 }
4485 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4486 CompleteResourceObject(jsObj);
4487 int32_t type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4488 JSRef<JSVal> resId = jsObj->GetProperty("id");
4489 if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) {
4490 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4491 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4492 if (!resourceWrapper) {
4493 return false;
4494 }
4495
4496 if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
4497 JSRef<JSVal> args = jsObj->GetProperty("params");
4498 if (!args->IsArray()) {
4499 return false;
4500 }
4501 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4502 auto fileName = params->GetValueAt(0);
4503 if (!fileName->IsString()) {
4504 return false;
4505 }
4506 result = resourceWrapper->GetRawfile(fileName->ToString());
4507 return true;
4508 }
4509 auto resIdNum = resId->ToNumber<int32_t>();
4510 if (resIdNum == -1) {
4511 if (!IsGetResourceByName(jsObj)) {
4512 return false;
4513 }
4514 JSRef<JSVal> args = jsObj->GetProperty("params");
4515 if (!args->IsArray()) {
4516 return false;
4517 }
4518 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4519 auto param = params->GetValueAt(0);
4520 if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
4521 result = resourceWrapper->GetMediaPathByName(param->ToString());
4522 return true;
4523 }
4524 return false;
4525 }
4526 if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
4527 result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>());
4528 return true;
4529 }
4530 return false;
4531 }
4532 return false;
4533 }
4534
ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)4535 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result)
4536 {
4537 if (!jsValue->IsBoolean() && !jsValue->IsObject()) {
4538 return false;
4539 }
4540
4541 if (jsValue->IsBoolean()) {
4542 result = jsValue->ToBoolean();
4543 return true;
4544 }
4545
4546 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4547 CompleteResourceObject(jsObj);
4548 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4549 if (resType == UNKNOWN_RESOURCE_TYPE) {
4550 return false;
4551 }
4552
4553 JSRef<JSVal> resId = jsObj->GetProperty("id");
4554 if (!resId->IsNumber()) {
4555 return false;
4556 }
4557
4558 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4559 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4560 if (!resourceWrapper) {
4561 return false;
4562 }
4563
4564 auto resIdNum = resId->ToNumber<int32_t>();
4565 if (resIdNum == -1) {
4566 if (!IsGetResourceByName(jsObj)) {
4567 return false;
4568 }
4569 JSRef<JSVal> args = jsObj->GetProperty("params");
4570 if (!args->IsArray()) {
4571 return false;
4572 }
4573 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4574 auto param = params->GetValueAt(0);
4575 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
4576 result = resourceWrapper->GetBooleanByName(param->ToString());
4577 return true;
4578 }
4579 return false;
4580 }
4581
4582 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) {
4583 result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>());
4584 return true;
4585 }
4586 return false;
4587 }
4588
ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)4589 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result)
4590 {
4591 return ParseJsInteger<uint32_t>(jsValue, result);
4592 }
4593
ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)4594 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result)
4595 {
4596 return ParseJsInteger<int32_t>(jsValue, result);
4597 }
4598
ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)4599 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result)
4600 {
4601 if (!jsValue->IsArray() && !jsValue->IsObject()) {
4602 return false;
4603 }
4604
4605 if (jsValue->IsArray()) {
4606 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
4607 for (size_t i = 0; i < array->Length(); i++) {
4608 JSRef<JSVal> value = array->GetValueAt(i);
4609 if (value->IsNumber()) {
4610 result.emplace_back(value->ToNumber<uint32_t>());
4611 } else if (value->IsObject()) {
4612 uint32_t singleResInt;
4613 if (ParseJsInteger(value, singleResInt)) {
4614 result.emplace_back(singleResInt);
4615 } else {
4616 return false;
4617 }
4618 } else {
4619 return false;
4620 }
4621 }
4622 return true;
4623 }
4624
4625 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4626 CompleteResourceObject(jsObj);
4627 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4628 if (resType == UNKNOWN_RESOURCE_TYPE) {
4629 return false;
4630 }
4631
4632 JSRef<JSVal> resId = jsObj->GetProperty("id");
4633 if (!resId->IsNumber()) {
4634 return false;
4635 }
4636
4637 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4638 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4639 if (!resourceWrapper) {
4640 return false;
4641 }
4642
4643 auto resIdNum = resId->ToNumber<int32_t>();
4644 if (resIdNum == -1) {
4645 if (!IsGetResourceByName(jsObj)) {
4646 return false;
4647 }
4648 JSRef<JSVal> args = jsObj->GetProperty("params");
4649 if (!args->IsArray()) {
4650 return false;
4651 }
4652 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4653 auto param = params->GetValueAt(0);
4654 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
4655 result = resourceWrapper->GetIntArrayByName(param->ToString());
4656 return true;
4657 }
4658 return false;
4659 }
4660
4661 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
4662 result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>());
4663 return true;
4664 }
4665 return false;
4666 }
4667
ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)4668 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result)
4669 {
4670 if (!jsValue->IsArray() && !jsValue->IsObject()) {
4671 return false;
4672 }
4673
4674 if (jsValue->IsArray()) {
4675 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue);
4676 for (size_t i = 0; i < array->Length(); i++) {
4677 JSRef<JSVal> value = array->GetValueAt(i);
4678 if (value->IsString()) {
4679 result.emplace_back(value->ToString());
4680 } else if (value->IsObject()) {
4681 std::string singleResStr;
4682 if (ParseJsString(value, singleResStr)) {
4683 result.emplace_back(singleResStr);
4684 } else {
4685 return false;
4686 }
4687 } else {
4688 return false;
4689 }
4690 }
4691 return true;
4692 }
4693
4694 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
4695 CompleteResourceObject(jsObj);
4696 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE);
4697 if (resType == UNKNOWN_RESOURCE_TYPE) {
4698 return false;
4699 }
4700
4701 JSRef<JSVal> resId = jsObj->GetProperty("id");
4702 if (!resId->IsNumber()) {
4703 return false;
4704 }
4705
4706 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj);
4707 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject);
4708 if (!resourceWrapper) {
4709 return false;
4710 }
4711
4712 auto resIdNum = resId->ToNumber<int32_t>();
4713 if (resIdNum == -1) {
4714 if (!IsGetResourceByName(jsObj)) {
4715 return false;
4716 }
4717 JSRef<JSVal> args = jsObj->GetProperty("params");
4718 if (!args->IsArray()) {
4719 return false;
4720 }
4721 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4722 auto param = params->GetValueAt(0);
4723 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
4724 result = resourceWrapper->GetStringArrayByName(param->ToString());
4725 return true;
4726 }
4727 return false;
4728 }
4729
4730 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
4731 result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>());
4732 return true;
4733 }
4734 return false;
4735 }
4736
IsGetResourceByName(const JSRef<JSObject> & jsObj)4737 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj)
4738 {
4739 JSRef<JSVal> resId = jsObj->GetProperty("id");
4740 if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) {
4741 return false;
4742 }
4743 JSRef<JSVal> args = jsObj->GetProperty("params");
4744 if (!args->IsArray()) {
4745 return false;
4746 }
4747 JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName");
4748 JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName");
4749 if (!bundleName->IsString() || !moduleName->IsString()) {
4750 return false;
4751 }
4752 JSRef<JSArray> params = JSRef<JSArray>::Cast(args);
4753 if (params->IsEmpty()) {
4754 return false;
4755 }
4756 return true;
4757 }
4758
ParseSize(const JSCallbackInfo & info)4759 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info)
4760 {
4761 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4762 if (!CheckJSCallbackInfo("ParseSize", info, checkList)) {
4763 return std::pair<CalcDimension, CalcDimension>();
4764 }
4765 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
4766 CalcDimension width;
4767 CalcDimension height;
4768 if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) ||
4769 !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) {
4770 return std::pair<CalcDimension, CalcDimension>();
4771 }
4772 return std::pair<CalcDimension, CalcDimension>(width, height);
4773 }
4774
JsUseAlign(const JSCallbackInfo & info)4775 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info)
4776 {
4777 if (info.Length() < 2) {
4778 return;
4779 }
4780
4781 if (!info[0]->IsObject() && !info[1]->IsObject()) {
4782 return;
4783 }
4784
4785 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>();
4786 if (declaration == nullptr) {
4787 return;
4788 }
4789
4790 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
4791 JSRef<JSVal> side = obj->GetProperty("side");
4792 JSRef<JSVal> offset = obj->GetProperty("offset");
4793
4794 if (!side->IsNumber()) {
4795 return;
4796 }
4797
4798 auto sideValue = side->ToNumber<int32_t>();
4799
4800 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) {
4801 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) ||
4802 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) {
4803 return;
4804 }
4805 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) {
4806 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) ||
4807 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) {
4808 return;
4809 }
4810 }
4811
4812 std::optional<CalcDimension> optOffset;
4813 CalcDimension offsetDimension;
4814 if (ParseJsDimensionVp(offset, offsetDimension)) {
4815 optOffset = offsetDimension;
4816 }
4817 ViewAbstractModel::GetInstance()->SetUseAlign(
4818 declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset);
4819 }
4820
JsGridSpan(const JSCallbackInfo & info)4821 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info)
4822 {
4823 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
4824 if (!CheckJSCallbackInfo("JsGridSpan", info, checkList)) {
4825 return;
4826 }
4827 auto span = info[0]->ToNumber<int32_t>();
4828 ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt);
4829 }
4830
JsGridOffset(const JSCallbackInfo & info)4831 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info)
4832 {
4833 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
4834 if (!CheckJSCallbackInfo("JsGridOffset", info, checkList)) {
4835 return;
4836 }
4837 auto offset = info[0]->ToNumber<int32_t>();
4838 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset);
4839 }
4840
ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)4841 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset)
4842 {
4843 // {lg: 4}
4844 if (val->IsNumber()) {
4845 span = val->ToNumber<uint32_t>();
4846 return true;
4847 }
4848
4849 if (!val->IsObject()) {
4850 return false;
4851 }
4852
4853 // {lg: {span: 1, offset: 2}}
4854 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val);
4855 span = obj->GetProperty("span")->ToNumber<uint32_t>();
4856 offset = obj->GetProperty("offset")->ToNumber<int32_t>();
4857 return true;
4858 }
4859
JsUseSizeType(const JSCallbackInfo & info)4860 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info)
4861 {
4862 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4863 if (!CheckJSCallbackInfo("JsUseSizeType", info, checkList)) {
4864 return;
4865 }
4866 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
4867 for (auto values : SCREEN_SIZE_VALUES) {
4868 JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str());
4869 if (val->IsNull() || val->IsEmpty()) {
4870 continue;
4871 }
4872 uint32_t span = 0;
4873 int32_t offset = 0;
4874 if (ParseSpanAndOffset(val, span, offset)) {
4875 ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first);
4876 }
4877 }
4878 }
4879
JsZIndex(const JSCallbackInfo & info)4880 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info)
4881 {
4882 int zIndex = 0;
4883 if (info[0]->IsNumber()) {
4884 zIndex = info[0]->ToNumber<int>();
4885 }
4886
4887 ViewAbstractModel::GetInstance()->SetZIndex(zIndex);
4888 }
4889
Pop()4890 void JSViewAbstract::Pop()
4891 {
4892 ViewStackModel::GetInstance()->Pop();
4893 }
4894
JsSetDraggable(bool draggable)4895 void JSViewAbstract::JsSetDraggable(bool draggable)
4896 {
4897 ViewAbstractModel::GetInstance()->SetDraggable(draggable);
4898 }
4899
JsSetDragPreviewOptions(const JSCallbackInfo & info)4900 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info)
4901 {
4902 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
4903 if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", info, checkList)) {
4904 return;
4905 }
4906 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
4907 auto mode = obj->GetProperty("mode");
4908 if (!mode->IsNumber()) {
4909 ViewAbstractModel::GetInstance()->SetDragPreviewOptions({NG::DragPreviewMode::AUTO});
4910 return;
4911 }
4912 int32_t dragPreviewMode = mode->ToNumber<int>();
4913 if (!(dragPreviewMode >= static_cast<int32_t>(NG::DragPreviewMode::AUTO) &&
4914 dragPreviewMode <= static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE))) {
4915 dragPreviewMode = static_cast<int32_t>(NG::DragPreviewMode::AUTO);
4916 }
4917 NG::DragPreviewOption option {static_cast<NG::DragPreviewMode>(dragPreviewMode)};
4918 ViewAbstractModel::GetInstance()->SetDragPreviewOptions(option);
4919 }
4920
JsOnDragStart(const JSCallbackInfo & info)4921 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info)
4922 {
4923 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4924 if (!CheckJSCallbackInfo("JsOnDragStart", info, checkList)) {
4925 return;
4926 }
4927
4928 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4929
4930 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
4931 auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
4932 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
4933 NG::DragDropBaseInfo dragDropInfo;
4934 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo);
4935 PipelineContext::SetCallBackNode(node);
4936 auto ret = func->Execute(info, extraParams);
4937 if (!ret->IsObject()) {
4938 return dragDropInfo;
4939 }
4940
4941 dragDropInfo.node = ParseDragNode(ret);
4942 auto builderObj = JSRef<JSObject>::Cast(ret);
4943 #if defined(PIXEL_MAP_SUPPORTED)
4944 auto pixmap = builderObj->GetProperty("pixelMap");
4945 dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
4946 #endif
4947 auto extraInfo = builderObj->GetProperty("extraInfo");
4948 ParseJsString(extraInfo, dragDropInfo.extraInfo);
4949 return dragDropInfo;
4950 };
4951 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
4952 }
4953
ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)4954 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo)
4955 {
4956 auto node = ParseDragNode(info);
4957 if (!node) {
4958 return false;
4959 }
4960 dragInfo.node = node;
4961 return true;
4962 }
4963
ParseDragNode(const JSRef<JSVal> & info)4964 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info)
4965 {
4966 auto builderFunc = ParseDragStartBuilderFunc(info);
4967 if (!builderFunc) {
4968 return nullptr;
4969 }
4970 // use another VSP instance while executing the builder function
4971 ViewStackModel::GetInstance()->NewScope();
4972 {
4973 ACE_SCORING_EVENT("onDragStart.builder");
4974 builderFunc->Execute();
4975 }
4976
4977 return ViewStackModel::GetInstance()->Finish();
4978 }
4979
JsOnDragEnter(const JSCallbackInfo & info)4980 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info)
4981 {
4982 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
4983 if (!CheckJSCallbackInfo("JsOnDragEnter", info, checkList)) {
4984 return;
4985 }
4986 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
4987 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
4988 auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode](
4989 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
4990 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
4991 ACE_SCORING_EVENT("onDragEnter");
4992 PipelineContext::SetCallBackNode(node);
4993 func->Execute(info, extraParams);
4994 };
4995
4996 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
4997 }
4998
JsOnDragEnd(const JSCallbackInfo & info)4999 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info)
5000 {
5001 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5002 if (!CheckJSCallbackInfo("JsOnDragEnd", info, checkList)) {
5003 return;
5004 }
5005 RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
5006 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5007 auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode](
5008 const RefPtr<OHOS::Ace::DragEvent>& info) {
5009 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5010 ACE_SCORING_EVENT("onDragEnd");
5011 auto extraParams = JsonUtil::Create(true);
5012 PipelineContext::SetCallBackNode(node);
5013 func->Execute(info, extraParams->ToString());
5014 };
5015
5016 ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd));
5017 }
5018
JsOnDragMove(const JSCallbackInfo & info)5019 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info)
5020 {
5021 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5022 if (!CheckJSCallbackInfo("JsOnDragMove", info, checkList)) {
5023 return;
5024 }
5025 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
5026 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5027 auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode](
5028 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5029 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5030 ACE_SCORING_EVENT("onDragMove");
5031 PipelineContext::SetCallBackNode(node);
5032 func->Execute(info, extraParams);
5033 };
5034
5035 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
5036 }
5037
JsOnDragLeave(const JSCallbackInfo & info)5038 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info)
5039 {
5040 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5041 if (!CheckJSCallbackInfo("JsOnDragLeave", info, checkList)) {
5042 return;
5043 }
5044 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
5045 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5046 auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode](
5047 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5048 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5049 ACE_SCORING_EVENT("onDragLeave");
5050 PipelineContext::SetCallBackNode(node);
5051 func->Execute(info, extraParams);
5052 };
5053
5054 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
5055 }
5056
JsOnDrop(const JSCallbackInfo & info)5057 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info)
5058 {
5059 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5060 if (!CheckJSCallbackInfo("JsOnDrop", info, checkList)) {
5061 return;
5062 }
5063 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
5064 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5065 auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode](
5066 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
5067 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5068 ACE_SCORING_EVENT("onDrop");
5069 PipelineContext::SetCallBackNode(node);
5070 func->Execute(info, extraParams);
5071 };
5072
5073 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
5074 }
5075
JsOnAreaChange(const JSCallbackInfo & info)5076 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info)
5077 {
5078 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
5079 ViewAbstractModel::GetInstance()->DisableOnAreaChange();
5080 return;
5081 }
5082 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
5083 if (!CheckJSCallbackInfo("JsOnAreaChange", info, checkList)) {
5084 return;
5085 }
5086 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(info[0]));
5087
5088 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5089 auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction),
5090 node = frameNode](
5091 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) {
5092 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5093 ACE_SCORING_EVENT("onAreaChange");
5094 PipelineContext::SetCallBackNode(node);
5095 func->Execute(oldRect, oldOrigin, rect, origin);
5096 };
5097 ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged));
5098 }
5099
5100 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)5101 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
5102 {
5103 if (info.Length() < 2) {
5104 return;
5105 }
5106 if ((!info[0]->IsBoolean() && !info[0]->IsObject()) || !info[1]->IsObject()) {
5107 return;
5108 }
5109 auto popupParam = AceType::MakeRefPtr<PopupParam>();
5110 // Set IsShow to popupParam
5111 if (info[0]->IsBoolean()) {
5112 popupParam->SetIsShow(info[0]->ToBoolean());
5113 } else {
5114 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]);
5115 auto callback = ParseDoubleBindCallback(info, showObj);
5116 popupParam->SetOnStateChange(std::move(callback));
5117 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
5118 }
5119 // Set popup to popupParam
5120 auto popupObj = JSRef<JSObject>::Cast(info[1]);
5121 if (popupObj->GetProperty("message")->IsString()) {
5122 ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
5123 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
5124 } else if (!popupObj->GetProperty("builder").IsEmpty()) {
5125 ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
5126 auto builderValue = popupObj->GetProperty("builder");
5127 auto builder = builderValue;
5128 if (!builderValue->IsObject()) {
5129 return;
5130 }
5131 if (!builderValue->IsFunction()) {
5132 JSRef<JSObject> builderObj;
5133 builderObj = JSRef<JSObject>::Cast(builderValue);
5134 builder = builderObj->GetProperty("builder");
5135 if (!builder->IsFunction()) {
5136 return;
5137 }
5138 }
5139 if (popupParam->IsShow()) {
5140 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5141 CHECK_NULL_VOID(builderFunc);
5142 ViewStackModel::GetInstance()->NewScope();
5143 builderFunc->Execute();
5144 auto customNode = ViewStackModel::GetInstance()->Finish();
5145 ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
5146 } else {
5147 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
5148 }
5149 } else {
5150 return;
5151 }
5152 }
5153 #endif
5154
JsLinearGradient(const JSCallbackInfo & info)5155 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info)
5156 {
5157 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5158 if (!CheckJSCallbackInfo("LinearGradient", info, checkList)) {
5159 NG::Gradient newGradient;
5160 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
5161 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
5162 return;
5163 }
5164 NG::Gradient newGradient;
5165 NewJsLinearGradient(info, newGradient);
5166 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient);
5167 }
5168
NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)5169 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
5170 {
5171 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5172 newGradient.CreateGradientWithType(NG::GradientType::LINEAR);
5173 // angle
5174 std::optional<float> degree;
5175 GetJsAngle("angle", jsObj, degree);
5176 if (degree) {
5177 newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX);
5178 degree.reset();
5179 }
5180 // direction
5181 auto direction = static_cast<GradientDirection>(
5182 jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE)));
5183 switch (direction) {
5184 case GradientDirection::LEFT:
5185 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5186 break;
5187 case GradientDirection::RIGHT:
5188 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5189 break;
5190 case GradientDirection::TOP:
5191 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5192 break;
5193 case GradientDirection::BOTTOM:
5194 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5195 break;
5196 case GradientDirection::LEFT_TOP:
5197 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5198 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5199 break;
5200 case GradientDirection::LEFT_BOTTOM:
5201 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT;
5202 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5203 break;
5204 case GradientDirection::RIGHT_TOP:
5205 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5206 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP;
5207 break;
5208 case GradientDirection::RIGHT_BOTTOM:
5209 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT;
5210 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM;
5211 break;
5212 case GradientDirection::NONE:
5213 case GradientDirection::START_TO_END:
5214 case GradientDirection::END_TO_START:
5215 default:
5216 break;
5217 }
5218 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
5219 newGradient.SetRepeat(repeating);
5220 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty("colors"));
5221 }
5222
JsRadialGradient(const JSCallbackInfo & info)5223 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info)
5224 {
5225 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5226 if (!CheckJSCallbackInfo("JsRadialGradient", info, checkList)) {
5227 NG::Gradient newGradient;
5228 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
5229 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
5230 return;
5231 }
5232 NG::Gradient newGradient;
5233 NewJsRadialGradient(info, newGradient);
5234 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient);
5235 }
5236
NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)5237 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
5238 {
5239 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5240 newGradient.CreateGradientWithType(NG::GradientType::RADIAL);
5241 // center
5242 JSRef<JSVal> center = jsObj->GetProperty("center");
5243 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
5244 CalcDimension value;
5245 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
5246 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
5247 newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value);
5248 if (value.Unit() == DimensionUnit::PERCENT) {
5249 // [0,1] -> [0, 100]
5250 newGradient.GetRadialGradient()->radialCenterX =
5251 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
5252 }
5253 }
5254 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
5255 newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value);
5256 if (value.Unit() == DimensionUnit::PERCENT) {
5257 // [0,1] -> [0, 100]
5258 newGradient.GetRadialGradient()->radialCenterY =
5259 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
5260 }
5261 }
5262 }
5263 // radius
5264 CalcDimension radius;
5265 if (ParseJsDimensionVp(jsObj->GetProperty("radius"), radius)) {
5266 newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius);
5267 newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius);
5268 }
5269 // repeating
5270 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
5271 newGradient.SetRepeat(repeating);
5272 // color stops
5273 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty("colors"));
5274 }
5275
JsSweepGradient(const JSCallbackInfo & info)5276 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info)
5277 {
5278 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5279 if (!CheckJSCallbackInfo("JsSweepGradient", info, checkList)) {
5280 NG::Gradient newGradient;
5281 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
5282 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
5283 return;
5284 }
5285
5286 NG::Gradient newGradient;
5287 NewJsSweepGradient(info, newGradient);
5288 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient);
5289 }
5290
NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)5291 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient)
5292 {
5293 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
5294 newGradient.CreateGradientWithType(NG::GradientType::SWEEP);
5295 // center
5296 JSRef<JSVal> center = jsObj->GetProperty("center");
5297 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) {
5298 CalcDimension value;
5299 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center);
5300 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) {
5301 newGradient.GetSweepGradient()->centerX = CalcDimension(value);
5302 if (value.Unit() == DimensionUnit::PERCENT) {
5303 // [0,1] -> [0, 100]
5304 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
5305 }
5306 }
5307 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) {
5308 newGradient.GetSweepGradient()->centerY = CalcDimension(value);
5309 if (value.Unit() == DimensionUnit::PERCENT) {
5310 // [0,1] -> [0, 100]
5311 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT);
5312 }
5313 }
5314 }
5315 std::optional<float> degree;
5316 // start
5317 GetJsAngle("start", jsObj, degree);
5318 if (degree) {
5319 CheckAngle(degree);
5320 newGradient.GetSweepGradient()->startAngle = CalcDimension(degree.value(), DimensionUnit::PX);
5321 degree.reset();
5322 }
5323 // end
5324 GetJsAngle("end", jsObj, degree);
5325 if (degree) {
5326 CheckAngle(degree);
5327 newGradient.GetSweepGradient()->endAngle = CalcDimension(degree.value(), DimensionUnit::PX);
5328 degree.reset();
5329 }
5330 // rotation
5331 GetJsAngle("rotation", jsObj, degree);
5332 if (degree) {
5333 CheckAngle(degree);
5334 newGradient.GetSweepGradient()->rotation = CalcDimension(degree.value(), DimensionUnit::PX);
5335 degree.reset();
5336 }
5337 // repeating
5338 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false);
5339 newGradient.SetRepeat(repeating);
5340 // color stops
5341 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty("colors"));
5342 }
5343
JsMotionPath(const JSCallbackInfo & info)5344 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info)
5345 {
5346 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT };
5347 if (!CheckJSCallbackInfo("JsMotionPath", info, checkList)) {
5348 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
5349 return;
5350 }
5351 MotionPathOption motionPathOption;
5352 if (ParseMotionPath(info[0], motionPathOption)) {
5353 ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption);
5354 } else {
5355 LOGI("Parse animation motionPath failed. %{public}s", info[0]->ToString().c_str());
5356 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption());
5357 }
5358 }
5359
JsShadow(const JSCallbackInfo & info)5360 void JSViewAbstract::JsShadow(const JSCallbackInfo& info)
5361 {
5362 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
5363 if (!CheckJSCallbackInfo("JsShadow", info, checkList)) {
5364 Shadow shadow;
5365 std::vector<Shadow> shadows { shadow };
5366 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
5367 return;
5368 }
5369 Shadow shadow;
5370 if (!ParseShadowProps(info[0], shadow)) {
5371 info.ReturnSelf();
5372 return;
5373 }
5374 std::vector<Shadow> shadows { shadow };
5375 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
5376 }
5377
JsBlendMode(const JSCallbackInfo & info)5378 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info)
5379 {
5380 if (info.Length() == 0) {
5381 return;
5382 }
5383 BlendMode blendMode = BlendMode::NONE;
5384 BlendApplyType blendApplyType = BlendApplyType::FAST;
5385 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon
5386 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000;
5387 if (info[0]->IsNumber()) {
5388 auto blendModeNum = info[0]->ToNumber<int32_t>();
5389 if (blendModeNum >= static_cast<int>(BlendMode::NONE) &&
5390 blendModeNum <= static_cast<int>(BlendMode::LUMINOSITY)) {
5391 blendMode = static_cast<BlendMode>(blendModeNum);
5392 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) {
5393 // backward compatibility code, will remove soon
5394 blendMode = BlendMode::SRC_OVER;
5395 blendApplyType = BlendApplyType::OFFSCREEN;
5396 }
5397 }
5398 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
5399 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>();
5400 if (blendApplyTypeNum >= static_cast<int>(BlendApplyType::FAST) &&
5401 blendApplyTypeNum <= static_cast<int>(BlendApplyType::OFFSCREEN)) {
5402 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum);
5403 }
5404 }
5405 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode);
5406 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType);
5407 }
5408
JsGrayScale(const JSCallbackInfo & info)5409 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info)
5410 {
5411 CalcDimension value;
5412 if (!ParseJsDimensionVp(info[0], value)) {
5413 value.SetValue(0.0);
5414 ViewAbstractModel::GetInstance()->SetGrayScale(value);
5415 return;
5416 }
5417
5418 if (LessNotEqual(value.Value(), 0.0)) {
5419 value.SetValue(0.0);
5420 }
5421
5422 if (GreatNotEqual(value.Value(), 1.0)) {
5423 value.SetValue(1.0);
5424 }
5425
5426 ViewAbstractModel::GetInstance()->SetGrayScale(value);
5427 }
5428
JsBrightness(const JSCallbackInfo & info)5429 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info)
5430 {
5431 CalcDimension value;
5432 if (!ParseJsDimensionVp(info[0], value)) {
5433 value.SetValue(1.0);
5434 ViewAbstractModel::GetInstance()->SetBrightness(value);
5435 return;
5436 }
5437
5438 ViewAbstractModel::GetInstance()->SetBrightness(value);
5439 }
5440
JsContrast(const JSCallbackInfo & info)5441 void JSViewAbstract::JsContrast(const JSCallbackInfo& info)
5442 {
5443 CalcDimension value;
5444 if (!ParseJsDimensionVp(info[0], value)) {
5445 value.SetValue(1.0);
5446 ViewAbstractModel::GetInstance()->SetContrast(value);
5447 return;
5448 }
5449
5450 if (LessNotEqual(value.Value(), 0.0)) {
5451 value.SetValue(0.0);
5452 }
5453
5454 ViewAbstractModel::GetInstance()->SetContrast(value);
5455 }
5456
JsSaturate(const JSCallbackInfo & info)5457 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info)
5458 {
5459 CalcDimension value;
5460 if (!ParseJsDimensionVp(info[0], value)) {
5461 value.SetValue(1.0);
5462 ViewAbstractModel::GetInstance()->SetSaturate(value);
5463 return;
5464 }
5465
5466 if (LessNotEqual(value.Value(), 0.0)) {
5467 value.SetValue(0.0);
5468 }
5469
5470 ViewAbstractModel::GetInstance()->SetSaturate(value);
5471 }
5472
JsSepia(const JSCallbackInfo & info)5473 void JSViewAbstract::JsSepia(const JSCallbackInfo& info)
5474 {
5475 CalcDimension value;
5476 if (!ParseJsDimensionVp(info[0], value)) {
5477 value.SetValue(0.0);
5478 ViewAbstractModel::GetInstance()->SetSepia(value);
5479 return;
5480 }
5481
5482 if (LessNotEqual(value.Value(), 0.0)) {
5483 value.SetValue(0.0);
5484 }
5485
5486 ViewAbstractModel::GetInstance()->SetSepia(value);
5487 }
5488
ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)5489 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert)
5490 {
5491 double invertValue = 0.0;
5492 if (ParseJsDouble(jsValue, invertValue)) {
5493 invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0));
5494 return true;
5495 }
5496 auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString());
5497 if (!argsPtrItem || argsPtrItem->IsNull()) {
5498 return false;
5499 }
5500 InvertOption option;
5501 double low = 0.0;
5502 if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) {
5503 option.low_ = std::clamp(low, 0.0, 1.0);
5504 }
5505 double high = 0.0;
5506 if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) {
5507 option.high_ = std::clamp(high, 0.0, 1.0);
5508 }
5509 double threshold = 0.0;
5510 if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) {
5511 option.threshold_ = std::clamp(threshold, 0.0, 1.0);
5512 }
5513 double thresholdRange = 0.0;
5514 if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) {
5515 option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0);
5516 }
5517 invert = option;
5518 return true;
5519 }
5520
JsInvert(const JSCallbackInfo & info)5521 void JSViewAbstract::JsInvert(const JSCallbackInfo& info)
5522 {
5523 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER };
5524 InvertVariant invert = 0.0f;
5525 if (!CheckJSCallbackInfo("JsInvert", info, checkList)) {
5526 ViewAbstractModel::GetInstance()->SetInvert(invert);
5527 return;
5528 }
5529 if (ParseInvertProps(info[0], invert)) {
5530 ViewAbstractModel::GetInstance()->SetInvert(invert);
5531 }
5532 ViewAbstractModel::GetInstance()->SetInvert(invert);
5533 }
5534
JsSystemBarEffect(const JSCallbackInfo & info)5535 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info)
5536 {
5537 ViewAbstractModel::GetInstance()->SetSystemBarEffect(true);
5538 }
5539
JsHueRotate(const JSCallbackInfo & info)5540 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info)
5541 {
5542 std::optional<float> degree;
5543 JSRef<JSVal> arg = info[0];
5544 if (arg->IsString()) {
5545 degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString()));
5546 } else if (arg->IsNumber()) {
5547 degree = static_cast<float>(arg->ToNumber<int32_t>());
5548 } else {
5549 ViewAbstractModel::GetInstance()->SetHueRotate(0.0);
5550 return;
5551 }
5552 float deg = 0.0f;
5553 if (degree) {
5554 deg = degree.value();
5555 degree.reset();
5556 }
5557 deg = std::fmod(deg, ROUND_UNIT);
5558 if (deg < 0.0f) {
5559 deg += ROUND_UNIT;
5560 }
5561 ViewAbstractModel::GetInstance()->SetHueRotate(deg);
5562 }
5563
JsClip(const JSCallbackInfo & info)5564 void JSViewAbstract::JsClip(const JSCallbackInfo& info)
5565 {
5566 JSRef<JSVal> arg = info[0];
5567 if (arg->IsUndefined()) {
5568 ViewAbstractModel::GetInstance()->SetClipEdge(false);
5569 return;
5570 }
5571 if (arg->IsObject()) {
5572 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
5573 if (clipShape == nullptr) {
5574 return;
5575 }
5576 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape());
5577 } else if (arg->IsBoolean()) {
5578 ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean());
5579 }
5580 }
5581
JsMask(const JSCallbackInfo & info)5582 void JSViewAbstract::JsMask(const JSCallbackInfo& info)
5583 {
5584 JSRef<JSVal> arg = info[0];
5585 if (!arg->IsObject()) {
5586 ViewAbstractModel::GetInstance()->SetProgressMask(nullptr);
5587 return;
5588 }
5589 auto paramObject = JSRef<JSObject>::Cast(arg);
5590 JSRef<JSVal> typeParam = paramObject->GetProperty("type");
5591 if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() &&
5592 typeParam->ToString() == "ProgressMask") {
5593 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>();
5594 JSRef<JSVal> jValue = paramObject->GetProperty("value");
5595 auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f;
5596 if (value < 0.0f) {
5597 value = 0.0f;
5598 }
5599 progressMask->SetValue(value);
5600 JSRef<JSVal> jTotal = paramObject->GetProperty("total");
5601 auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL;
5602 if (total < 0.0f) {
5603 total = DEFAULT_PROGRESS_TOTAL;
5604 }
5605 progressMask->SetMaxValue(total);
5606 JSRef<JSVal> jColor = paramObject->GetProperty("color");
5607 Color colorVal;
5608 if (ParseJsColor(jColor, colorVal)) {
5609 progressMask->SetColor(colorVal);
5610 } else {
5611 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
5612 progressMask->SetColor(theme->GetMaskColor());
5613 }
5614 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask);
5615 } else {
5616 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>();
5617 if (maskShape == nullptr) {
5618 return;
5619 };
5620 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape());
5621 }
5622 }
5623
JsFocusable(const JSCallbackInfo & info)5624 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info)
5625 {
5626 if (!info[0]->IsBoolean()) {
5627 return;
5628 }
5629 ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean());
5630 }
5631
JsOnFocusMove(const JSCallbackInfo & args)5632 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args)
5633 {
5634 JSRef<JSVal> arg = args[0];
5635 if (arg->IsFunction()) {
5636 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
5637 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5638 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode](
5639 int info) {
5640 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5641 ACE_SCORING_EVENT("onFocusMove");
5642 PipelineContext::SetCallBackNode(node);
5643 func->Execute(info);
5644 };
5645 ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove));
5646 }
5647 }
5648
JsOnKeyEvent(const JSCallbackInfo & args)5649 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args)
5650 {
5651 JSRef<JSVal> arg = args[0];
5652 if (arg->IsUndefined() && IsDisableEventVersion()) {
5653 ViewAbstractModel::GetInstance()->DisableOnKeyEvent();
5654 return;
5655 }
5656 if (!arg->IsFunction()) {
5657 return;
5658 }
5659 RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg));
5660 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5661 auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode](
5662 KeyEventInfo& info) {
5663 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5664 ACE_SCORING_EVENT("onKey");
5665 PipelineContext::SetCallBackNode(node);
5666 func->Execute(info);
5667 };
5668 ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent));
5669 }
5670
JsOnFocus(const JSCallbackInfo & args)5671 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args)
5672 {
5673 JSRef<JSVal> arg = args[0];
5674 if (arg->IsUndefined() && IsDisableEventVersion()) {
5675 ViewAbstractModel::GetInstance()->DisableOnFocus();
5676 return;
5677 }
5678 if (!arg->IsFunction()) {
5679 return;
5680 }
5681 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
5682 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5683 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() {
5684 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5685 ACE_SCORING_EVENT("onFocus");
5686 PipelineContext::SetCallBackNode(node);
5687 func->Execute();
5688 };
5689
5690 ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus));
5691 }
5692
JsOnBlur(const JSCallbackInfo & args)5693 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args)
5694 {
5695 JSRef<JSVal> arg = args[0];
5696 if (arg->IsUndefined() && IsDisableEventVersion()) {
5697 ViewAbstractModel::GetInstance()->DisableOnBlur();
5698 return;
5699 }
5700 if (!arg->IsFunction()) {
5701 return;
5702 }
5703 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg));
5704 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5705 auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() {
5706 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5707 ACE_SCORING_EVENT("onBlur");
5708 PipelineContext::SetCallBackNode(node);
5709 func->Execute();
5710 };
5711
5712 ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur));
5713 }
5714
JsTabIndex(const JSCallbackInfo & info)5715 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info)
5716 {
5717 JSRef<JSVal> arg = info[0];
5718 if (!arg->IsNumber()) {
5719 return;
5720 }
5721 ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>());
5722 }
5723
JsFocusOnTouch(const JSCallbackInfo & info)5724 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info)
5725 {
5726 JSRef<JSVal> arg = info[0];
5727 if (!arg->IsBoolean()) {
5728 return;
5729 }
5730 auto isFocusOnTouch = arg->ToBoolean();
5731 ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch);
5732 }
5733
JsDefaultFocus(const JSCallbackInfo & info)5734 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info)
5735 {
5736 JSRef<JSVal> arg = info[0];
5737 if (!arg->IsBoolean()) {
5738 return;
5739 }
5740 auto isDefaultFocus = arg->ToBoolean();
5741 ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus);
5742 }
5743
JsGroupDefaultFocus(const JSCallbackInfo & info)5744 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info)
5745 {
5746 JSRef<JSVal> arg = info[0];
5747 if (!arg->IsBoolean()) {
5748 return;
5749 }
5750 auto isGroupDefaultFocus = arg->ToBoolean();
5751 ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus);
5752 }
5753
JsKey(const std::string & key)5754 void JSViewAbstract::JsKey(const std::string& key)
5755 {
5756 ViewAbstractModel::GetInstance()->SetInspectorId(key);
5757 }
5758
JsId(const JSCallbackInfo & info)5759 void JSViewAbstract::JsId(const JSCallbackInfo& info)
5760 {
5761 JSRef<JSVal> arg = info[0];
5762 if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) {
5763 return;
5764 }
5765 std::string id = arg->ToString();
5766 if (id.empty()) {
5767 return;
5768 }
5769 JsKey(id);
5770 }
5771
JsRestoreId(int32_t restoreId)5772 void JSViewAbstract::JsRestoreId(int32_t restoreId)
5773 {
5774 ViewAbstractModel::GetInstance()->SetRestoreId(restoreId);
5775 }
5776
JsDebugLine(const JSCallbackInfo & info)5777 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info)
5778 {
5779 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING };
5780 if (!CheckJSCallbackInfo("JsDebugLine", info, checkList)) {
5781 return;
5782 }
5783
5784 ViewAbstractModel::GetInstance()->SetDebugLine(info[0]->ToString());
5785 }
5786
JsOpacityPassThrough(const JSCallbackInfo & info)5787 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info)
5788 {
5789 double opacity = 0.0;
5790 if (!ParseJsDouble(info[0], opacity)) {
5791 return;
5792 }
5793
5794 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) {
5795 opacity = 1.0;
5796 }
5797
5798 ViewAbstractModel::GetInstance()->SetOpacity(opacity, true);
5799 }
5800
JsTransitionPassThrough(const JSCallbackInfo & info)5801 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info)
5802 {
5803 if (info.Length() > 1) {
5804 return;
5805 }
5806 if (info.Length() == 0) {
5807 ViewAbstractModel::GetInstance()->SetTransition(
5808 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL));
5809 return;
5810 }
5811 if (!info[0]->IsObject()) {
5812 return;
5813 }
5814 auto obj = JSRef<JSObject>::Cast(info[0]);
5815 if (!obj->GetProperty("successor_")->IsUndefined()) {
5816 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext());
5817 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect);
5818 return;
5819 }
5820 auto options = ParseJsTransition(obj);
5821 ViewAbstractModel::GetInstance()->SetTransition(options, true);
5822 }
5823
JsAccessibilityGroup(bool accessible)5824 void JSViewAbstract::JsAccessibilityGroup(bool accessible)
5825 {
5826 ViewAbstractModel::GetInstance()->SetAccessibilityGroup(accessible);
5827 }
5828
JsAccessibilityText(const std::string & text)5829 void JSViewAbstract::JsAccessibilityText(const std::string& text)
5830 {
5831 ViewAbstractModel::GetInstance()->SetAccessibilityText(text);
5832 }
5833
JsAccessibilityDescription(const std::string & description)5834 void JSViewAbstract::JsAccessibilityDescription(const std::string& description)
5835 {
5836 std::pair<bool, std::string> autoEventPair(false, "");
5837 std::pair<bool, std::string> descriptionPair(false, "");
5838 ParseAccessibilityDescriptionJson(description, autoEventPair, descriptionPair);
5839 if (descriptionPair.first) {
5840 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(descriptionPair.second);
5841 } else {
5842 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description);
5843 }
5844 if (autoEventPair.first) {
5845 ViewAbstractModel::GetInstance()->SetAutoEventParam(autoEventPair.second);
5846 }
5847 }
5848
ParseAccessibilityDescriptionJson(const std::string & description,std::pair<bool,std::string> & autoEventPair,std::pair<bool,std::string> & descriptionPair)5849 void JSViewAbstract::ParseAccessibilityDescriptionJson(const std::string& description,
5850 std::pair<bool, std::string>& autoEventPair, std::pair<bool, std::string>& descriptionPair)
5851 {
5852 if (description.empty()) {
5853 return;
5854 }
5855 if (!StartWith(description, "{") || !EndWith(description, "}")) {
5856 return;
5857 }
5858 auto jsonObj = JsonUtil::ParseJsonString(description);
5859 if (!jsonObj || !jsonObj->IsValid() || !jsonObj->IsObject()) {
5860 return;
5861 }
5862 if (jsonObj->Contains("$autoEventParam")) {
5863 auto param = jsonObj->GetValue("$autoEventParam");
5864 if (param) {
5865 autoEventPair = std::make_pair(true, param->ToString());
5866 }
5867 }
5868 if (jsonObj->Contains("$accessibilityDescription")) {
5869 descriptionPair = std::make_pair(true, jsonObj->GetString("$accessibilityDescription"));
5870 } else if (jsonObj->Contains("$autoEventParam")) {
5871 descriptionPair = std::make_pair(true, "");
5872 }
5873 }
5874
JsAccessibilityImportance(const std::string & importance)5875 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance)
5876 {
5877 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance);
5878 }
5879
JsAccessibilityLevel(const std::string & level)5880 void JSViewAbstract::JsAccessibilityLevel(const std::string& level)
5881 {
5882 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level);
5883 }
5884
JsAccessibilityVirtualNode(const JSCallbackInfo & info)5885 void JSViewAbstract::JsAccessibilityVirtualNode(const JSCallbackInfo& info)
5886 {
5887 // parse builder
5888 if (!info[0]->IsObject()) {
5889 return;
5890 }
5891 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
5892 auto builder = obj->GetProperty("builder");
5893
5894 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5895 CHECK_NULL_VOID(builderFunc);
5896 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() {
5897 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5898 ACE_SCORING_EVENT("AccessibilityVirtualNode");
5899 func->Execute();
5900 };
5901 NG::ViewAbstractModelNG::GetInstance()->SetAccessibilityVirtualNode(std::move(buildFunc));
5902 }
5903
JsBackground(const JSCallbackInfo & info)5904 void JSViewAbstract::JsBackground(const JSCallbackInfo& info)
5905 {
5906 // Check the parameters
5907 if (info.Length() <= 0 || !info[0]->IsObject()) {
5908 return;
5909 }
5910 JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]);
5911 auto builder = backgroundObj->GetProperty("builder");
5912 if (!builder->IsFunction()) {
5913 return;
5914 }
5915 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5916 CHECK_NULL_VOID(builderFunc);
5917 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5918 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
5919 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5920 ACE_SCORING_EVENT("BindBackground");
5921 PipelineContext::SetCallBackNode(node);
5922 func->Execute();
5923 };
5924 Alignment alignment = Alignment::CENTER;
5925 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) {
5926 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]);
5927 auto align = object->GetProperty("align");
5928 auto value = align->ToNumber<int32_t>();
5929 alignment = ParseAlignment(value);
5930 }
5931 ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment);
5932 }
5933
JsBindContextMenu(const JSCallbackInfo & info)5934 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
5935 {
5936 // Check the parameters
5937 if (info.Length() <= 0 || !info[0]->IsObject()) {
5938 return;
5939 }
5940 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[0]);
5941 auto builder = menuObj->GetProperty("builder");
5942 if (!builder->IsFunction()) {
5943 return;
5944 }
5945 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5946 CHECK_NULL_VOID(builderFunc);
5947
5948 ResponseType responseType = ResponseType::LONG_PRESS;
5949 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) {
5950 auto response = info[1]->ToNumber<int32_t>();
5951 responseType = static_cast<ResponseType>(response);
5952 }
5953 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
5954 std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
5955 node = frameNode]() {
5956 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
5957 ACE_SCORING_EVENT("BuildContextMenu");
5958 PipelineContext::SetCallBackNode(node);
5959 func->Execute();
5960 };
5961
5962 NG::MenuParam menuParam;
5963 menuParam.previewMode = MenuPreviewMode::NONE;
5964 std::function<void()> previewBuildFunc = nullptr;
5965 if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) {
5966 ParseBindContentOptionParam(info, info[2], menuParam, previewBuildFunc);
5967 }
5968 if (responseType != ResponseType::LONG_PRESS) {
5969 menuParam.previewMode = MenuPreviewMode::NONE;
5970 }
5971 menuParam.type = NG::MenuType::CONTEXT_MENU;
5972 ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
5973 }
5974
JsBindContentCover(const JSCallbackInfo & info)5975 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
5976 {
5977 // parse isShow
5978 bool isShow = false;
5979 DoubleBindCallback callback = nullptr;
5980 if (info[0]->IsBoolean()) {
5981 isShow = info[0]->ToBoolean();
5982 } else if (info[0]->IsObject()) {
5983 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
5984 callback = ParseDoubleBindCallback(info, callbackObj);
5985 auto isShowObj = callbackObj->GetProperty("value");
5986 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
5987 }
5988
5989 // parse builder
5990 if (!info[1]->IsObject()) {
5991 return;
5992 }
5993 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
5994 auto builder = obj->GetProperty("builder");
5995 if (!builder->IsFunction()) {
5996 return;
5997 }
5998 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
5999 CHECK_NULL_VOID(builderFunc);
6000 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
6001 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
6002 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6003 ACE_SCORING_EVENT("BindContentCover");
6004 PipelineContext::SetCallBackNode(node);
6005 func->Execute();
6006 };
6007
6008 // parse ModalTransition
6009 NG::ModalStyle modalStyle;
6010 modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
6011 std::function<void()> onShowCallback;
6012 std::function<void()> onDismissCallback;
6013 if (info.Length() == 3) {
6014 if (info[2]->IsObject()) {
6015 ParseOverlayCallback(info[2], onShowCallback, onDismissCallback);
6016 ParseModalStyle(info[2], modalStyle);
6017 } else if (info[2]->IsNumber()) {
6018 auto transitionNumber = info[2]->ToNumber<int32_t>();
6019 if (transitionNumber >= 0 && transitionNumber <= 2) {
6020 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
6021 }
6022 }
6023 }
6024 ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
6025 std::move(onShowCallback), std::move(onDismissCallback));
6026 }
6027
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)6028 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
6029 {
6030 auto modalTransition = paramObj->GetProperty("modalTransition");
6031 auto backgroundColor = paramObj->GetProperty("backgroundColor");
6032 if (modalTransition->IsNumber()) {
6033 auto transitionNumber = modalTransition->ToNumber<int32_t>();
6034 if (transitionNumber >= 0 && transitionNumber <= 2) {
6035 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
6036 }
6037 }
6038 Color color;
6039 if (ParseJsColor(backgroundColor, color)) {
6040 modalStyle.backgroundColor = color;
6041 }
6042 }
6043
JsBindSheet(const JSCallbackInfo & info)6044 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
6045 {
6046 // parse isShow
6047 bool isShow = false;
6048 DoubleBindCallback callback = nullptr;
6049 if (info[0]->IsBoolean()) {
6050 isShow = info[0]->ToBoolean();
6051 } else if (info[0]->IsObject()) {
6052 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
6053 callback = ParseDoubleBindCallback(info, callbackObj);
6054 auto isShowObj = callbackObj->GetProperty("value");
6055 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
6056 }
6057
6058 // parse builder
6059 if (!info[1]->IsObject()) {
6060 return;
6061 }
6062 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6063 auto builder = obj->GetProperty("builder");
6064 if (!builder->IsFunction()) {
6065 return;
6066 }
6067 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
6068 CHECK_NULL_VOID(builderFunc);
6069 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
6070 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
6071 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6072 ACE_SCORING_EVENT("BindSheet");
6073 PipelineContext::SetCallBackNode(node);
6074 func->Execute();
6075 };
6076
6077 // parse SheetStyle and callbacks
6078 NG::SheetStyle sheetStyle;
6079 sheetStyle.sheetMode = NG::SheetMode::LARGE;
6080 sheetStyle.showDragBar = true;
6081 sheetStyle.showCloseIcon = true;
6082 std::function<void()> onShowCallback;
6083 std::function<void()> onDismissCallback;
6084 std::function<void()> shouldDismissFunc;
6085 std::function<void()> titleBuilderFunction;
6086 if (info.Length() == 3) {
6087 if (info[2]->IsObject()) {
6088 ParseSheetCallback(info[2], onShowCallback, onDismissCallback, shouldDismissFunc);
6089 ParseSheetStyle(info[2], sheetStyle);
6090 ParseSheetTitle(info[2], sheetStyle, titleBuilderFunction);
6091 }
6092 }
6093 ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
6094 std::move(titleBuilderFunction), sheetStyle, std::move(onShowCallback), std::move(onDismissCallback),
6095 std::move(shouldDismissFunc));
6096 }
6097
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)6098 void JSViewAbstract::ParseSheetStyle(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
6099 {
6100 auto height = paramObj->GetProperty("height");
6101 auto showDragBar = paramObj->GetProperty("dragBar");
6102 auto backgroundColor = paramObj->GetProperty("backgroundColor");
6103 auto maskColor = paramObj->GetProperty("maskColor");
6104 auto sheetDetents = paramObj->GetProperty("detents");
6105 auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
6106 auto showCloseIcon = paramObj->GetProperty("showClose");
6107 auto type = paramObj->GetProperty("preferType");
6108 auto interactive = paramObj->GetProperty("enableOutsideInteractive");
6109
6110 std::vector<NG::SheetHeight> detents;
6111 if (ParseSheetDetents(sheetDetents, detents)) {
6112 sheetStyle.detents = detents;
6113 }
6114 BlurStyleOption styleOption;
6115 if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
6116 sheetStyle.backgroundBlurStyle = styleOption;
6117 }
6118 bool showClose = true;
6119 if (showCloseIcon->IsNull() || showCloseIcon->IsUndefined()) {
6120 sheetStyle.showCloseIcon = showClose;
6121 } else {
6122 if (ParseJsBool(showCloseIcon, showClose)) {
6123 sheetStyle.showCloseIcon = showClose;
6124 }
6125 }
6126 bool isInteractive = false;
6127 if (ParseJsBool(interactive, isInteractive)) {
6128 sheetStyle.interactive = isInteractive;
6129 }
6130 if (showDragBar->IsNull() || showDragBar->IsUndefined()) {
6131 sheetStyle.showDragBar = true;
6132 } else {
6133 if (showDragBar->IsBoolean()) {
6134 sheetStyle.showDragBar = showDragBar->ToBoolean();
6135 }
6136 }
6137 if (type->IsNull() || type->IsUndefined()) {
6138 sheetStyle.sheetType.reset();
6139 } else {
6140 if (type->IsNumber()) {
6141 auto sheetType = type->ToNumber<int32_t>();
6142 if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
6143 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
6144 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
6145 }
6146 }
6147 }
6148 Color color;
6149 if (ParseJsColor(backgroundColor, color)) {
6150 sheetStyle.backgroundColor = color;
6151 }
6152 // parse maskColor
6153 Color parseMaskColor;
6154 if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
6155 sheetStyle.maskColor = std::move(parseMaskColor);
6156 }
6157 CalcDimension sheetHeight;
6158 if (height->IsString()) {
6159 std::string heightStr = height->ToString();
6160 // Remove all " ".
6161 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
6162 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
6163 if (heightStr == SHEET_HEIGHT_MEDIUM) {
6164 sheetStyle.sheetMode = NG::SheetMode::MEDIUM;
6165 sheetStyle.height.reset();
6166 return;
6167 }
6168 if (heightStr == SHEET_HEIGHT_LARGE) {
6169 sheetStyle.sheetMode = NG::SheetMode::LARGE;
6170 sheetStyle.height.reset();
6171 return;
6172 }
6173 if (heightStr == SHEET_HEIGHT_FITCONTENT) {
6174 sheetStyle.sheetMode = NG::SheetMode::AUTO;
6175 sheetStyle.height.reset();
6176 return;
6177 }
6178 if (heightStr.find("calc") != std::string::npos) {
6179 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
6180 } else {
6181 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
6182 }
6183 if (sheetHeight.Value() < 0) {
6184 sheetStyle.sheetMode = NG::SheetMode::LARGE;
6185 sheetStyle.height.reset();
6186 return;
6187 }
6188 }
6189 if (!ParseJsDimensionVpNG(height, sheetHeight)) {
6190 sheetStyle.sheetMode = NG::SheetMode::LARGE;
6191 sheetStyle.height.reset();
6192 } else {
6193 sheetStyle.height = sheetHeight;
6194 sheetStyle.sheetMode.reset();
6195 }
6196 }
6197
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)6198 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
6199 {
6200 if (!args->IsArray()) {
6201 return false;
6202 }
6203 JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
6204 NG::SheetHeight sheetDetent;
6205 for (size_t i = 0; i < array->Length(); i++) {
6206 ParseSheetDetentHeight(array->GetValueAt(i), sheetDetent);
6207 if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
6208 continue;
6209 }
6210 sheetDetents.emplace_back(sheetDetent);
6211 sheetDetent.height.reset();
6212 sheetDetent.sheetMode.reset();
6213 }
6214 return true;
6215 }
6216
ParseSheetDetentHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent)6217 void JSViewAbstract::ParseSheetDetentHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent)
6218 {
6219 CalcDimension sheetHeight;
6220 if (args->IsString()) {
6221 std::string heightStr = args->ToString();
6222 // Remove all " ".
6223 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
6224 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
6225 if (heightStr == SHEET_HEIGHT_MEDIUM) {
6226 detent.sheetMode = NG::SheetMode::MEDIUM;
6227 detent.height.reset();
6228 return;
6229 }
6230 if (heightStr == SHEET_HEIGHT_LARGE) {
6231 detent.sheetMode = NG::SheetMode::LARGE;
6232 detent.height.reset();
6233 return;
6234 }
6235 if (heightStr == SHEET_HEIGHT_FITCONTENT) {
6236 detent.sheetMode = NG::SheetMode::AUTO;
6237 detent.height.reset();
6238 return;
6239 }
6240 if (heightStr.find("calc") != std::string::npos) {
6241 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
6242 } else {
6243 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
6244 }
6245 if (sheetHeight.Value() < 0) {
6246 detent.sheetMode = NG::SheetMode::LARGE;
6247 detent.height.reset();
6248 return;
6249 }
6250 }
6251 if (!ParseJsDimensionVpNG(args, sheetHeight)) {
6252 detent.sheetMode = NG::SheetMode::LARGE;
6253 detent.height.reset();
6254 } else {
6255 detent.height = sheetHeight;
6256 detent.sheetMode.reset();
6257 }
6258 }
6259
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)6260 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
6261 {
6262 if (args->IsNumber()) {
6263 auto sheetBlurStyle = args->ToNumber<int32_t>();
6264 if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
6265 sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
6266 blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
6267 } else {
6268 return false;
6269 }
6270 } else {
6271 return false;
6272 }
6273 return true;
6274 }
6275
ParseSheetCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & shouldDismiss)6276 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
6277 std::function<void()>& onDisappear, std::function<void()>& shouldDismiss)
6278 {
6279 auto showCallback = paramObj->GetProperty("onAppear");
6280 auto dismissCallback = paramObj->GetProperty("onDisappear");
6281 auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
6282 if (showCallback->IsFunction()) {
6283 RefPtr<JsFunction> jsFunc =
6284 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
6285 onAppear = [func = std::move(jsFunc)]() { func->Execute(); };
6286 }
6287 if (dismissCallback->IsFunction()) {
6288 RefPtr<JsFunction> jsFunc =
6289 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
6290 onDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
6291 }
6292 if (shouldDismissFunc->IsFunction()) {
6293 RefPtr<JsFunction> jsFunc =
6294 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
6295 shouldDismiss = [func = std::move(jsFunc)]() {
6296 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
6297 objectTemplate->SetInternalFieldCount(1);
6298 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
6299 dismissObj->SetPropertyObject(
6300 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
6301 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj);
6302 func->ExecuteJS(1, &newJSVal);
6303 };
6304 }
6305 }
6306
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)6307 void JSViewAbstract::ParseSheetTitle(
6308 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
6309 {
6310 auto title = paramObj->GetProperty("title");
6311 std::string mainTitle;
6312 std::string subtitle;
6313 if (title->IsFunction()) {
6314 sheetStyle.isTitleBuilder = true;
6315 auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
6316 CHECK_NULL_VOID(titleBuilderFunc);
6317 titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
6318 ACE_SCORING_EVENT("BindSheet");
6319 func->Execute();
6320 };
6321 } else if (title->IsObject()) {
6322 JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
6323 sheetStyle.isTitleBuilder = false;
6324 auto sheetTitle = obj->GetProperty("title");
6325 auto sheetSubtitle = obj->GetProperty("subtitle");
6326 if (ParseJsString(sheetTitle, mainTitle)) {
6327 sheetStyle.sheetTitle = mainTitle;
6328 }
6329 if (ParseJsString(sheetSubtitle, subtitle)) {
6330 sheetStyle.sheetSubtitle = subtitle;
6331 }
6332 }
6333 }
6334
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)6335 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
6336 {
6337 ViewAbstractModel::GetInstance()->DismissSheet();
6338 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
6339 }
6340
ParseOverlayCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear)6341 void JSViewAbstract::ParseOverlayCallback(
6342 const JSRef<JSObject>& paramObj, std::function<void()>& onAppear, std::function<void()>& onDisappear)
6343 {
6344 auto showCallback = paramObj->GetProperty("onAppear");
6345 auto dismissCallback = paramObj->GetProperty("onDisappear");
6346 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
6347 if (showCallback->IsFunction()) {
6348 RefPtr<JsFunction> jsFunc =
6349 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
6350 onAppear = [func = std::move(jsFunc), node = frameNode]() {
6351 PipelineContext::SetCallBackNode(node);
6352 func->Execute();
6353 };
6354 }
6355 if (dismissCallback->IsFunction()) {
6356 RefPtr<JsFunction> jsFunc =
6357 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
6358 onDisappear = [func = std::move(jsFunc), node = frameNode]() {
6359 PipelineContext::SetCallBackNode(node);
6360 func->Execute();
6361 };
6362 }
6363 }
6364
JSCreateAnimatableProperty(const JSCallbackInfo & info)6365 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info)
6366 {
6367 if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */
6368 return;
6369 }
6370
6371 JSRef<JSVal> callback = info[2]; /* 2:args index */
6372 if (!callback->IsFunction()) {
6373 return;
6374 }
6375 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
6376 std::string propertyName = info[0]->ToString();
6377 if (info[1]->IsNumber()) {
6378 float numValue = info[1]->ToNumber<float>();
6379 std::function<void(float)> onCallbackEvent;
6380 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
6381 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
6382 node = frameNode](const float val) {
6383 ContainerScope scope(id);
6384 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6385 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val));
6386 PipelineContext::SetCallBackNode(node);
6387 func->ExecuteJS(1, &newJSVal);
6388 };
6389 ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent);
6390 } else if (info[1]->IsObject()) {
6391 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6392 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
6393 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
6394 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
6395 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
6396 std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent;
6397 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
6398 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(),
6399 node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) {
6400 ContainerScope scope(id);
6401 RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value);
6402 if (!impl) {
6403 return;
6404 }
6405 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
6406 auto newJSVal = JSRef<JSVal>(impl->GetObject());
6407 PipelineContext::SetCallBackNode(node);
6408 func->ExecuteJS(1, &newJSVal);
6409 };
6410 ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty(
6411 propertyName, animatableArithmetic, onCallbackEvent);
6412 }
6413 }
6414
JSUpdateAnimatableProperty(const JSCallbackInfo & info)6415 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info)
6416 {
6417 if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */
6418 return;
6419 }
6420
6421 std::string propertyName = info[0]->ToString();
6422 float numValue = 0.0;
6423 if (info[1]->IsNumber()) {
6424 numValue = info[1]->ToNumber<float>();
6425 ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue);
6426 } else if (info[1]->IsObject()) {
6427 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]);
6428 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl =
6429 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext());
6430 RefPtr<CustomAnimatableArithmetic> animatableArithmetic =
6431 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl);
6432 ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic);
6433 }
6434 }
6435
JsExpandSafeArea(const JSCallbackInfo & info)6436 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info)
6437 {
6438 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL };
6439 if (info.Length() >= 1 && info[0]->IsArray()) {
6440 auto paramArray = JSRef<JSArray>::Cast(info[0]);
6441 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
6442 for (size_t i = 0; i < paramArray->Length(); ++i) {
6443 if (!paramArray->GetValueAt(i)->IsNumber() ||
6444 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) {
6445 safeAreaType = NG::SAFE_AREA_TYPE_ALL;
6446 break;
6447 }
6448 safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
6449 }
6450 opts.type = safeAreaType;
6451 }
6452 if (info.Length() >= 2 && info[1]->IsArray()) {
6453 auto paramArray = JSRef<JSArray>::Cast(info[1]);
6454 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
6455 for (size_t i = 0; i < paramArray->Length(); ++i) {
6456 if (!paramArray->GetValueAt(i)->IsNumber() ||
6457 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
6458 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
6459 break;
6460 }
6461 safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>());
6462 }
6463 opts.edges = safeAreaEdge;
6464 }
6465
6466 ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts);
6467 }
6468
JsPointLight(const JSCallbackInfo & info)6469 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info)
6470 {
6471 if (!info[0]->IsObject()) {
6472 return;
6473 }
6474
6475 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
6476 JSRef<JSObject> lightSource = object->GetProperty("lightSource");
6477 if (!lightSource->IsUndefined()) {
6478 JSRef<JSVal> positionX = lightSource->GetProperty("positionX");
6479 JSRef<JSVal> positionY = lightSource->GetProperty("positionY");
6480 JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ");
6481 JSRef<JSVal> intensity = lightSource->GetProperty("intensity");
6482
6483 CalcDimension dimPositionX, dimPositionY, dimPositionZ;
6484 if (ParseJsDimensionVp(positionX, dimPositionX) && ParseJsDimensionVp(positionY, dimPositionY) &&
6485 ParseJsDimensionVp(positionZ, dimPositionZ)) {
6486 ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ);
6487 }
6488
6489 if (intensity->IsNumber()) {
6490 float intensityValue = intensity->ToNumber<float>();
6491 ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue);
6492 }
6493 }
6494
6495 auto resourceWrapper = CreateResourceWrapper();
6496 if (!resourceWrapper) {
6497 return;
6498 }
6499 double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME);
6500 Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME);
6501 Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME);
6502
6503 JSRef<JSVal> illuminated = object->GetProperty("illuminated");
6504 if (illuminated->IsNumber()) {
6505 uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>();
6506 ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue);
6507 ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth);
6508 }
6509
6510 JSRef<JSVal> bloom = object->GetProperty("bloom");
6511 if (bloom->IsNumber()) {
6512 float bloomValue = bloom->ToNumber<float>();
6513 ViewAbstractModel::GetInstance()->SetBloom(bloomValue);
6514
6515 Shadow shadow;
6516 shadow.SetBlurRadius(bloomValue * bloomRadius);
6517 shadow.SetColor(bloomColor);
6518 std::vector<Shadow> shadows { shadow };
6519 ViewAbstractModel::GetInstance()->SetBackShadow(shadows);
6520 }
6521 }
6522
JSBind(BindingTarget globalObj)6523 void JSViewAbstract::JSBind(BindingTarget globalObj)
6524 {
6525 JSClass<JSViewAbstract>::Declare("JSViewAbstract");
6526
6527 // static methods
6528 MethodOptions opt = MethodOptions::NONE;
6529 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt);
6530
6531 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth);
6532 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight);
6533 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion);
6534 JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion);
6535 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize);
6536 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize);
6537 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority);
6538 JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSViewAbstract::JsPixelRound);
6539 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight);
6540
6541 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin);
6542 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt);
6543 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt);
6544 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt);
6545 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt);
6546
6547 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding);
6548 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt);
6549 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt);
6550 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt);
6551 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt);
6552
6553 JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor);
6554 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
6555 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage);
6556 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize);
6557 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition);
6558 JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle);
6559 JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect);
6560 JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle);
6561 JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect);
6562 JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect);
6563 JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect);
6564 JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline);
6565 JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth);
6566 JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle);
6567 JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor);
6568 JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius);
6569 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder);
6570 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth);
6571 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor);
6572 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius);
6573 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle);
6574 JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage);
6575
6576 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale);
6577 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX);
6578 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY);
6579 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity);
6580 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate);
6581 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX);
6582 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY);
6583 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate);
6584 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX);
6585 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY);
6586 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform);
6587 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition);
6588
6589 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign);
6590 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition);
6591 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor);
6592 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset);
6593 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled);
6594 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio);
6595 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay);
6596
6597 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur);
6598 JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect);
6599 JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching);
6600 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend);
6601 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur);
6602 JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur);
6603 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness);
6604 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur);
6605 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility);
6606 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis);
6607 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow);
6608 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink);
6609 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf);
6610 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority);
6611 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign);
6612 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex);
6613 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition);
6614 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt);
6615 #ifndef WEARABLE_PRODUCT
6616 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup);
6617 #endif
6618
6619 JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground);
6620 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu);
6621 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu);
6622 JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover);
6623 JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet);
6624 JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable);
6625 JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions);
6626 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart);
6627 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter);
6628 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove);
6629 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave);
6630 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop);
6631 JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd);
6632
6633 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient);
6634 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient);
6635 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient);
6636 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath);
6637 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan);
6638 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset);
6639 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType);
6640 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow);
6641 JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode);
6642 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale);
6643 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable);
6644 JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent);
6645 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove);
6646 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus);
6647 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur);
6648 JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex);
6649 JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch);
6650 JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus);
6651 JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus);
6652 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness);
6653 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast);
6654 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate);
6655 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia);
6656 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert);
6657 JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect);
6658 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate);
6659 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip);
6660 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask);
6661 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey);
6662 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId);
6663 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId);
6664 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
6665 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
6666 JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
6667 JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
6668 JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
6669 JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect);
6670 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine);
6671 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition);
6672 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange);
6673 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable);
6674 JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents);
6675
6676 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup);
6677 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText);
6678 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription);
6679 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance);
6680 JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel);
6681 JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode);
6682 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility);
6683 JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules);
6684 JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange);
6685 JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior);
6686 JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest);
6687 JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut);
6688 JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured);
6689 JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop);
6690 JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview);
6691
6692 JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty);
6693 JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty);
6694 JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup);
6695 JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit);
6696
6697 JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze);
6698
6699 JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea);
6700
6701 JSClass<JSViewAbstract>::Bind(globalObj);
6702 }
JsAllowDrop(const JSCallbackInfo & info)6703 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info)
6704 {
6705 std::set<std::string> allowDropSet;
6706 allowDropSet.clear();
6707 if (!info[0]->IsUndefined() && info[0]->IsArray()) {
6708 auto allowDropArray = JSRef<JSArray>::Cast(info[0]);
6709 std::string allowDrop;
6710 for (size_t i = 0; i < allowDropArray->Length(); i++) {
6711 allowDrop = allowDropArray->GetValueAt(i)->ToString();
6712 allowDropSet.insert(allowDrop);
6713 }
6714 }
6715 ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet);
6716 }
6717
JsDragPreview(const JSCallbackInfo & info)6718 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info)
6719 {
6720 if (!info[0]->IsObject()) {
6721 return;
6722 }
6723 NG::DragDropInfo dragPreviewInfo;
6724 JSRef<JSVal> builder;
6725 JSRef<JSVal> pixelMap;
6726 JSRef<JSVal> extraInfo;
6727 if (info[0]->IsFunction()) {
6728 builder = info[0];
6729 } else if (info[0]->IsObject()) {
6730 auto dragItemInfo = JSRef<JSObject>::Cast(info[0]);
6731 builder = dragItemInfo->GetProperty("builder");
6732 #if defined(PIXEL_MAP_SUPPORTED)
6733 pixelMap = dragItemInfo->GetProperty("pixelMap");
6734 dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap);
6735 #endif
6736 extraInfo = dragItemInfo->GetProperty("extraInfo");
6737 ParseJsString(extraInfo, dragPreviewInfo.extraInfo);
6738 } else {
6739 return;
6740 }
6741
6742 if (builder->IsFunction()) {
6743 RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
6744 if (builderFunc != nullptr) {
6745 ViewStackModel::GetInstance()->NewScope();
6746 {
6747 ACE_SCORING_EVENT("dragPreview.builder");
6748 builderFunc->Execute();
6749 }
6750 RefPtr<AceType> node = ViewStackModel::GetInstance()->Finish();
6751 dragPreviewInfo.customNode = AceType::DynamicCast<NG::UINode>(node);
6752 }
6753 }
6754 ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo);
6755 }
6756
JsAlignRules(const JSCallbackInfo & info)6757 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info)
6758 {
6759 if (!info[0]->IsObject()) {
6760 return;
6761 }
6762
6763 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]);
6764 if (valueObj->IsEmpty()) {
6765 return;
6766 }
6767 const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias" };
6768 std::map<AlignDirection, AlignRule> alignRules;
6769 BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS);
6770 for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) {
6771 auto rule = valueObj->GetProperty(keys[i]);
6772 if (rule->IsObject()) {
6773 JSRef<JSObject> val = JSRef<JSObject>::Cast(rule);
6774 JSRef<JSVal> align = val->GetProperty("align");
6775 AlignRule alignRule;
6776 alignRule.anchor = val->GetProperty("anchor")->ToString();
6777 if (i < HORIZONTAL_DIRECTION_RANGE) {
6778 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
6779 } else {
6780 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>());
6781 }
6782 if (i < VERTICAL_DIRECTION_RANGE) {
6783 alignRules[static_cast<AlignDirection>(i)] = alignRule;
6784 }
6785 auto biasX = val->GetProperty("horizontal");
6786 if (biasX->IsNumber()) {
6787 biasPair.first = biasX->ToNumber<float>();
6788 }
6789 auto biasY = val->GetProperty("vertical");
6790 if (biasY->IsNumber()) {
6791 biasPair.second = biasY->ToNumber<float>();
6792 }
6793 }
6794 }
6795
6796 ViewAbstractModel::GetInstance()->SetAlignRules(alignRules);
6797 ViewAbstractModel::GetInstance()->SetBias(biasPair);
6798 }
6799
SetMarginTop(const JSCallbackInfo & info)6800 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info)
6801 {
6802 CalcDimension value;
6803 if (!ParseJsDimensionVp(info[0], value)) {
6804 return;
6805 }
6806 ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt);
6807 }
6808
SetMarginBottom(const JSCallbackInfo & info)6809 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info)
6810 {
6811 CalcDimension value;
6812 if (!ParseJsDimensionVp(info[0], value)) {
6813 return;
6814 }
6815 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt);
6816 }
6817
SetMarginLeft(const JSCallbackInfo & info)6818 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info)
6819 {
6820 CalcDimension value;
6821 if (!ParseJsDimensionVp(info[0], value)) {
6822 return;
6823 }
6824 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt);
6825 }
6826
SetMarginRight(const JSCallbackInfo & info)6827 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info)
6828 {
6829 CalcDimension value;
6830 if (!ParseJsDimensionVp(info[0], value)) {
6831 return;
6832 }
6833 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value);
6834 }
6835
SetPaddingTop(const JSCallbackInfo & info)6836 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info)
6837 {
6838 CalcDimension value;
6839 if (!ParseJsDimensionVp(info[0], value)) {
6840 return;
6841 }
6842 ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt);
6843 }
6844
SetPaddingBottom(const JSCallbackInfo & info)6845 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info)
6846 {
6847 CalcDimension value;
6848 if (!ParseJsDimensionVp(info[0], value)) {
6849 return;
6850 }
6851 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt);
6852 }
6853
SetPaddingLeft(const JSCallbackInfo & info)6854 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info)
6855 {
6856 CalcDimension value;
6857 if (!ParseJsDimensionVp(info[0], value)) {
6858 return;
6859 }
6860 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
6861 }
6862
SetPaddingRight(const JSCallbackInfo & info)6863 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info)
6864 {
6865 CalcDimension value;
6866 if (!ParseJsDimensionVp(info[0], value)) {
6867 return;
6868 }
6869 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
6870 }
6871
SetColorBlend(Color color)6872 void JSViewAbstract::SetColorBlend(Color color)
6873 {
6874 ViewAbstractModel::GetInstance()->SetColorBlend(color);
6875 }
6876
SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)6877 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)
6878 {
6879 ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara);
6880 }
6881
SetDynamicLightUp(float rate,float lightUpDegree)6882 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree)
6883 {
6884 ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree);
6885 }
6886
SetWindowBlur(float progress,WindowBlurStyle blurStyle)6887 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle)
6888 {
6889 ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle);
6890 }
6891
ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)6892 bool JSViewAbstract::ParseJsonDimension(
6893 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal)
6894 {
6895 if (!jsonValue || jsonValue->IsNull()) {
6896 return false;
6897 }
6898 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
6899 return false;
6900 }
6901 if (jsonValue->IsNumber()) {
6902 result = Dimension(jsonValue->GetDouble(), defaultUnit);
6903 return true;
6904 }
6905 if (jsonValue->IsString()) {
6906 if (checkIllegal) {
6907 return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit);
6908 }
6909 result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit);
6910 return true;
6911 }
6912 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
6913 auto resId = resVal->GetValue("id");
6914 if (!resId || !resId->IsNumber()) {
6915 return false;
6916 }
6917
6918 auto resourceWrapper = CreateResourceWrapper();
6919 if (!resourceWrapper) {
6920 return false;
6921 }
6922 result = resourceWrapper->GetDimension(resId->GetUInt());
6923 return true;
6924 }
6925
ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)6926 bool JSViewAbstract::ParseJsonDimensionVp(
6927 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal)
6928 {
6929 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
6930 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true);
6931 }
6932 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal);
6933 }
6934
ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)6935 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result)
6936 {
6937 if (!jsonValue || jsonValue->IsNull()) {
6938 return false;
6939 }
6940 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
6941 return false;
6942 }
6943 if (jsonValue->IsNumber()) {
6944 result = jsonValue->GetDouble();
6945 return true;
6946 }
6947 if (jsonValue->IsString()) {
6948 result = StringUtils::StringToDouble(jsonValue->GetString());
6949 return true;
6950 }
6951 // parse json Resource
6952 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
6953 auto resId = resVal->GetValue("id");
6954 CHECK_NULL_RETURN(resId && resId->IsNumber(), false);
6955 auto id = resId->GetUInt();
6956 auto resType = resVal->GetValue("type");
6957 CHECK_NULL_RETURN(resType && resType->IsNumber(), false);
6958 auto type = resType->GetUInt();
6959
6960 auto resourceWrapper = CreateResourceWrapper();
6961 if (!resourceWrapper) {
6962 return false;
6963 }
6964 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
6965 auto numberString = resourceWrapper->GetString(id);
6966 return StringUtils::StringToDouble(numberString, result);
6967 }
6968 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
6969 result = resourceWrapper->GetInt(id);
6970 return true;
6971 }
6972 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
6973 result = resourceWrapper->GetDouble(id);
6974 return true;
6975 }
6976 return false;
6977 }
6978
ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)6979 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result)
6980 {
6981 if (!jsonValue || jsonValue->IsNull()) {
6982 return false;
6983 }
6984 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) {
6985 return false;
6986 }
6987 if (jsonValue->IsNumber()) {
6988 result = Color(ColorAlphaAdapt(jsonValue->GetUInt()));
6989 return true;
6990 }
6991
6992 bool isSetColor = false;
6993 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
6994 isSetColor = jsonValue->IsString();
6995 } else {
6996 isSetColor = jsonValue->IsString() && jsonValue->GetString() != "";
6997 }
6998 if (isSetColor) {
6999 result = Color::FromString(jsonValue->GetString());
7000 return true;
7001 }
7002 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString());
7003 auto resId = resVal->GetValue("id");
7004 if (!resId || !resId->IsNumber()) {
7005 return false;
7006 }
7007 auto resourceWrapper = CreateResourceWrapper();
7008 if (!resourceWrapper) {
7009 return false;
7010 }
7011 result = resourceWrapper->GetColor(resId->GetUInt());
7012 return true;
7013 }
7014
ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)7015 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow)
7016 {
7017 int32_t shadowStyle = 0;
7018 if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) {
7019 auto style = static_cast<ShadowStyle>(shadowStyle);
7020 return GetShadowFromTheme(style, shadow);
7021 }
7022 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7023 double radius = 0.0;
7024 ParseJsDouble(jsObj->GetProperty("radius"), radius);
7025 if (LessNotEqual(radius, 0.0)) {
7026 radius = 0.0;
7027 }
7028 shadow.SetBlurRadius(radius);
7029 CalcDimension offsetX;
7030 if (ParseJsResource(jsObj->GetProperty("offsetX"), offsetX)) {
7031 shadow.SetOffsetX(offsetX.Value());
7032 } else {
7033 if (ParseJsDimensionVp(jsObj->GetProperty("offsetX"), offsetX)) {
7034 shadow.SetOffsetX(offsetX.Value());
7035 }
7036 }
7037
7038 CalcDimension offsetY;
7039 if (ParseJsResource(jsObj->GetProperty("offsetY"), offsetY)) {
7040 shadow.SetOffsetY(offsetY.Value());
7041 } else {
7042 if (ParseJsDimensionVp(jsObj->GetProperty("offsetY"), offsetY)) {
7043 shadow.SetOffsetY(offsetY.Value());
7044 }
7045 }
7046 Color color;
7047 ShadowColorStrategy shadowColorStrategy;
7048 if (ParseJsShadowColorStrategy(jsObj->GetProperty("color"), shadowColorStrategy)) {
7049 shadow.SetShadowColorStrategy(shadowColorStrategy);
7050 } else if (ParseJsColor(jsObj->GetProperty("color"), color)) {
7051 shadow.SetColor(color);
7052 }
7053 auto type = jsObj->GetPropertyValue<int32_t>("type", static_cast<int32_t>(ShadowType::COLOR));
7054 type = std::clamp(type, static_cast<int32_t>(ShadowType::COLOR), static_cast<int32_t>(ShadowType::BLUR));
7055 shadow.SetShadowType(static_cast<ShadowType>(type));
7056 bool isFilled = jsObj->GetPropertyValue<bool>("fill", false);
7057 shadow.SetIsFilled(isFilled);
7058 return true;
7059 }
7060
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)7061 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
7062 {
7063 auto colorMode = SystemProperties::GetColorMode();
7064 if (shadowStyle == ShadowStyle::None) {
7065 return true;
7066 }
7067
7068 auto container = Container::Current();
7069 CHECK_NULL_RETURN(container, false);
7070 auto pipelineContext = container->GetPipelineContext();
7071 CHECK_NULL_RETURN(pipelineContext, false);
7072
7073 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
7074 if (!shadowTheme) {
7075 return false;
7076 }
7077
7078 shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
7079 return true;
7080 }
7081
ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)7082 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result)
7083 {
7084 if (!jsValue->IsObject()) {
7085 return false;
7086 }
7087 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7088 auto resourceWrapper = CreateResourceWrapper();
7089 CHECK_NULL_RETURN(resourceWrapper, false);
7090 uint32_t type = jsObj->GetPropertyValue<uint32_t>("type", 0);
7091 if (type == static_cast<uint32_t>(ResourceType::STRING)) {
7092 auto value = resourceWrapper->GetString(jsObj->GetPropertyValue<uint32_t>("id", 0));
7093 return StringUtils::StringToCalcDimensionNG(value, result, false);
7094 }
7095 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) {
7096 auto value = std::to_string(resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>("id", 0)));
7097 StringUtils::StringToDimensionWithUnitNG(value, result);
7098 return true;
7099 }
7100
7101 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) {
7102 result = resourceWrapper->GetDimension(jsObj->GetPropertyValue<uint32_t>("id", 0));
7103 return true;
7104 }
7105 return false;
7106 }
7107
ParseDataDetectorConfig(const JSCallbackInfo & info,std::string & types,std::function<void (const std::string &)> & onResult)7108 bool JSViewAbstract::ParseDataDetectorConfig(
7109 const JSCallbackInfo& info, std::string& types, std::function<void(const std::string&)>& onResult)
7110 {
7111 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7112 JSRef<JSVal> typeValue = obj->GetProperty("types");
7113 if (!typeValue->IsArray()) {
7114 return false;
7115 }
7116 JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue);
7117 for (size_t i = 0; i < array->Length(); i++) {
7118 JSRef<JSVal> value = array->GetValueAt(i);
7119 auto index = value->ToNumber<int32_t>();
7120 if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
7121 return false;
7122 }
7123 if (i != 0) {
7124 types.append(",");
7125 }
7126 types.append(TEXT_DETECT_TYPES[index]);
7127 }
7128 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
7129 JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate");
7130 if (resultCallback->IsFunction()) {
7131 auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback));
7132 onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
7133 const std::string& result) {
7134 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7135 PipelineContext::SetCallBackNode(node);
7136 func->Execute(result);
7137 };
7138 }
7139 return true;
7140 }
7141
GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)7142 void JSViewAbstract::GetAngle(
7143 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle)
7144 {
7145 auto value = jsonValue->GetValue(key);
7146 if (value && value->IsString()) {
7147 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString()));
7148 } else if (value && value->IsNumber()) {
7149 angle = static_cast<float>(value->GetDouble());
7150 }
7151 }
7152
GetJsAngle(const std::string & key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)7153 void JSViewAbstract::GetJsAngle(
7154 const std::string& key, const JSRef<JSVal>& jsValue, std::optional<float>& angle)
7155 {
7156 if (!jsValue->IsObject()) {
7157 return;
7158 }
7159 JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key.c_str());
7160 if (value->IsString()) {
7161 angle = static_cast<float>(StringUtils::StringToDegree(value->ToString()));
7162 } else if (value->IsNumber()) {
7163 angle = value->ToNumber<float>();
7164 }
7165 }
7166
CheckAngle(std::optional<float> & angle)7167 void JSViewAbstract::CheckAngle(std::optional<float>& angle)
7168 {
7169 if (LessNotEqual(angle.value(), 0.0f)) {
7170 angle = 0.0f;
7171 } else if (GreatNotEqual(angle.value(), MAX_ANGLE)) {
7172 angle = MAX_ANGLE;
7173 }
7174 }
7175
GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)7176 void JSViewAbstract::GetPerspective(
7177 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective)
7178 {
7179 auto value = jsonValue->GetValue(key);
7180 if (value && value->IsNumber()) {
7181 perspective = static_cast<float>(value->GetDouble());
7182 }
7183 }
7184
GetJsPerspective(const std::string & key,const JSRef<JSVal> & jsValue,float & perspective)7185 void JSViewAbstract::GetJsPerspective(const std::string& key, const JSRef<JSVal>& jsValue, float& perspective)
7186 {
7187 if (!jsValue->IsObject()) {
7188 return;
7189 }
7190 auto value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key.c_str());
7191 if (value->IsNumber()) {
7192 perspective = value->ToNumber<float>();
7193 }
7194 }
7195
GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)7196 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
7197 {
7198 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
7199 return;
7200 }
7201
7202 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
7203 GradientColor gradientColor;
7204 auto item = colorStops->GetArrayItem(i);
7205 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
7206 auto colorParams = item->GetArrayItem(0);
7207 // color
7208 Color color;
7209 if (!ParseJsonColor(colorParams, color)) {
7210 continue;
7211 }
7212 gradientColor.SetColor(color);
7213 gradientColor.SetHasValue(false);
7214 // stop value
7215 if (item->GetArraySize() <= 1) {
7216 continue;
7217 }
7218 auto stopValue = item->GetArrayItem(1);
7219 double value = 0.0;
7220 if (ParseJsonDouble(stopValue, value)) {
7221 value = std::clamp(value, 0.0, 1.0);
7222 gradientColor.SetHasValue(true);
7223 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7224 }
7225 gradient.AddColor(gradientColor);
7226 }
7227 }
7228 }
7229
NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)7230 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops)
7231 {
7232 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) {
7233 return;
7234 }
7235
7236 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) {
7237 NG::GradientColor gradientColor;
7238 auto item = colorStops->GetArrayItem(i);
7239 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) {
7240 auto colorParams = item->GetArrayItem(0);
7241 // color
7242 Color color;
7243 if (!ParseJsonColor(colorParams, color)) {
7244 continue;
7245 }
7246 gradientColor.SetColor(color);
7247 gradientColor.SetHasValue(false);
7248 // stop value
7249 if (item->GetArraySize() <= 1) {
7250 continue;
7251 }
7252 auto stopValue = item->GetArrayItem(1);
7253 double value = 0.0;
7254 if (ParseJsonDouble(stopValue, value)) {
7255 value = std::clamp(value, 0.0, 1.0);
7256 gradientColor.SetHasValue(true);
7257 // [0, 1] -> [0, 100.0];
7258 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7259 }
7260 gradient.AddColor(gradientColor);
7261 }
7262 }
7263 }
7264
NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)7265 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops)
7266 {
7267 if (!colorStops->IsArray()) {
7268 return;
7269 }
7270
7271 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops);
7272 size_t length = jsArray->Length();
7273 for (size_t i = 0; i < length; i++) {
7274 NG::GradientColor gradientColor;
7275 JSRef<JSVal> item = jsArray->GetValueAt(i);
7276 if (!item->IsArray()) {
7277 continue;
7278 }
7279 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item);
7280 if (subArray->Length() < 2) {
7281 continue;
7282 }
7283 // color
7284 Color color;
7285 if (!ParseJsColor(subArray->GetValueAt(0), color)) {
7286 continue;
7287 }
7288 gradientColor.SetColor(color);
7289 gradientColor.SetHasValue(false);
7290 // stop value
7291 double value = 0.0;
7292 if (ParseJsDouble(subArray->GetValueAt(1), value)) {
7293 value = std::clamp(value, 0.0, 1.0);
7294 gradientColor.SetHasValue(true);
7295 }
7296 // [0, 1] -> [0, 100.0];
7297 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT));
7298 gradient.AddColor(gradientColor);
7299 }
7300 }
7301
SetDirection(const std::string & dir)7302 void JSViewAbstract::SetDirection(const std::string& dir)
7303 {
7304 TextDirection direction = TextDirection::AUTO;
7305 if (dir == "Ltr") {
7306 direction = TextDirection::LTR;
7307 } else if (dir == "Rtl") {
7308 direction = TextDirection::RTL;
7309 } else if (dir == "Auto") {
7310 direction = TextDirection::AUTO;
7311 } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
7312 direction = TextDirection::AUTO;
7313 }
7314 ViewAbstractModel::GetInstance()->SetLayoutDirection(direction);
7315 }
7316
GetThemeConstants(const JSRef<JSObject> & jsObj)7317 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj)
7318 {
7319 std::string bundleName;
7320 std::string moduleName;
7321 if (!jsObj->IsUndefined()) {
7322 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
7323 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
7324 if (bundle->IsString() && module->IsString()) {
7325 bundleName = bundle->ToString();
7326 moduleName = module->ToString();
7327 }
7328 }
7329
7330 auto cardId = CardScope::CurrentId();
7331 if (cardId != INVALID_CARD_ID) {
7332 auto container = Container::Current();
7333 auto weak = container->GetCardPipeline(cardId);
7334 auto cardPipelineContext = weak.Upgrade();
7335 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
7336 auto cardThemeManager = cardPipelineContext->GetThemeManager();
7337 CHECK_NULL_RETURN(cardThemeManager, nullptr);
7338 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
7339 }
7340
7341 #ifdef PLUGIN_COMPONENT_SUPPORTED
7342 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
7343 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
7344 if (!pluginContainer) {
7345 return nullptr;
7346 }
7347 auto pluginPipelineContext = pluginContainer->GetPipelineContext();
7348 if (!pluginPipelineContext) {
7349 return nullptr;
7350 }
7351 auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
7352 if (!pluginThemeManager) {
7353 return nullptr;
7354 }
7355 return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
7356 }
7357 #endif
7358 auto container = Container::Current();
7359 CHECK_NULL_RETURN(container, nullptr);
7360 auto pipelineContext = container->GetPipelineContext();
7361 CHECK_NULL_RETURN(pipelineContext, nullptr);
7362 auto themeManager = pipelineContext->GetThemeManager();
7363 CHECK_NULL_RETURN(themeManager, nullptr);
7364 return themeManager->GetThemeConstants(bundleName, moduleName);
7365 }
7366
JsHoverEffect(const JSCallbackInfo & info)7367 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info)
7368 {
7369 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER };
7370 if (!CheckJSCallbackInfo("HoverEffect", info, checkList)) {
7371 ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO);
7372 return;
7373 }
7374 if (!info[0]->IsNumber()) {
7375 return;
7376 }
7377 ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(info[0]->ToNumber<int32_t>()));
7378 }
7379
JsOnMouse(const JSCallbackInfo & info)7380 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info)
7381 {
7382 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
7383 ViewAbstractModel::GetInstance()->DisableOnMouse();
7384 return;
7385 }
7386 if (!info[0]->IsFunction()) {
7387 return;
7388 }
7389
7390 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
7391 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
7392 auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode](
7393 MouseInfo& mouseInfo) {
7394 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7395 ACE_SCORING_EVENT("onMouse");
7396 PipelineContext::SetCallBackNode(node);
7397 func->Execute(mouseInfo);
7398 };
7399 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
7400 }
7401
JsOnHover(const JSCallbackInfo & info)7402 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
7403 {
7404 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
7405 ViewAbstractModel::GetInstance()->DisableOnHover();
7406 return;
7407 }
7408 if (!info[0]->IsFunction()) {
7409 return;
7410 }
7411
7412 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
7413 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
7414 auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode](
7415 bool isHover, HoverInfo& hoverInfo) {
7416 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7417 ACE_SCORING_EVENT("onHover");
7418 PipelineContext::SetCallBackNode(node);
7419 func->HoverExecute(isHover, hoverInfo);
7420 };
7421 ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
7422 }
7423
JsOnClick(const JSCallbackInfo & info)7424 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
7425 {
7426 if (info[0]->IsUndefined() && IsDisableEventVersion()) {
7427 ViewAbstractModel::GetInstance()->DisableOnClick();
7428 return;
7429 }
7430 if (!info[0]->IsFunction()) {
7431 return;
7432 }
7433
7434 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
7435 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
7436 auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode](
7437 GestureEvent& info) {
7438 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7439 ACE_SCORING_EVENT("onClick");
7440 PipelineContext::SetCallBackNode(node);
7441 func->Execute(info);
7442 };
7443 auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode](
7444 const ClickInfo* info) {
7445 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7446 ACE_SCORING_EVENT("onClick");
7447 PipelineContext::SetCallBackNode(node);
7448 func->Execute(*info);
7449 };
7450 ViewAbstractModel::GetInstance()->SetOnClick(std::move(onTap), std::move(onClick));
7451 }
7452
JsOnGestureJudgeBegin(const JSCallbackInfo & info)7453 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info)
7454 {
7455 if (info[0]->IsUndefined() || !info[0]->IsFunction()) {
7456 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr);
7457 return;
7458 }
7459
7460 auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0]));
7461 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
7462 auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode](
7463 const RefPtr<NG::GestureInfo>& gestureInfo,
7464 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
7465 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE);
7466 ACE_SCORING_EVENT("onGestureJudgeBegin");
7467 PipelineContext::SetCallBackNode(node);
7468 return func->Execute(gestureInfo, info);
7469 };
7470 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc));
7471 }
7472
JsClickEffect(const JSCallbackInfo & info)7473 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info)
7474 {
7475 if (info[0]->IsUndefined() || info[0]->IsNull()) {
7476 ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT);
7477 return;
7478 }
7479 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
7480 JSRef<JSVal> clickEffectLevel = obj->GetProperty("level");
7481 int32_t clickEffectLevelValue = 0;
7482 if (clickEffectLevel->IsNumber()) {
7483 clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>();
7484 if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) ||
7485 clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) {
7486 clickEffectLevelValue = 0;
7487 }
7488 }
7489
7490 JSRef<JSVal> scaleNumber = obj->GetProperty("scale");
7491 float scaleNumberValue = DEFAULT_SCALE_LIGHT;
7492 if (!scaleNumber->IsNumber()) {
7493 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
7494 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
7495 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
7496 }
7497 ViewAbstractModel::GetInstance()->SetClickEffectLevel(
7498 (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
7499 return;
7500 }
7501
7502 scaleNumberValue = scaleNumber->ToNumber<float>();
7503 if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) {
7504 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE ||
7505 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) {
7506 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY;
7507 } else {
7508 scaleNumberValue = DEFAULT_SCALE_LIGHT;
7509 }
7510 }
7511
7512 ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue);
7513 }
7514
JsOnVisibleAreaChange(const JSCallbackInfo & info)7515 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info)
7516 {
7517 if (info.Length() != 2) {
7518 return;
7519 }
7520
7521 if (!info[0]->IsArray() || !info[1]->IsFunction()) {
7522 return;
7523 }
7524
7525 auto ratioArray = JSRef<JSArray>::Cast(info[0]);
7526 size_t size = ratioArray->Length();
7527 std::vector<double> ratioVec(size);
7528 ratioVec.clear();
7529 for (size_t i = 0; i < size; i++) {
7530 double ratio = 0.0;
7531 ParseJsDouble(ratioArray->GetValueAt(i), ratio);
7532 if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) {
7533 ratio = VISIBLE_RATIO_MIN;
7534 }
7535
7536 if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) {
7537 ratio = VISIBLE_RATIO_MAX;
7538 }
7539 ratioVec.push_back(ratio);
7540 }
7541
7542 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
7543 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
7544 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
7545 bool visible, double ratio) {
7546 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7547 ACE_SCORING_EVENT("onVisibleAreaChange");
7548
7549 JSRef<JSVal> params[2];
7550 params[0] = JSRef<JSVal>::Make(ToJSValue(visible));
7551 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio));
7552 PipelineContext::SetCallBackNode(node);
7553 func->ExecuteJS(2, params);
7554 };
7555 ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec);
7556 }
7557
JsHitTestBehavior(const JSCallbackInfo & info)7558 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info)
7559 {
7560 if (info.Length() != 1) {
7561 return;
7562 }
7563
7564 NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT;
7565 hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>());
7566 ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG);
7567 }
7568
JsOnChildTouchTest(const JSCallbackInfo & info)7569 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info)
7570 {
7571 std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION };
7572 if (!CheckJSCallbackInfo("onChildTouchTest", info, checkList)) {
7573 return;
7574 }
7575
7576 RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc =
7577 AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(info[0]));
7578
7579 auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)](
7580 const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult {
7581 NG::TouchResult touchRes;
7582 NG::TouchResult defaultRes;
7583 defaultRes.strategy = NG::TouchTestStrategy::DEFAULT;
7584 defaultRes.id = "";
7585 auto ret = func->Execute(touchInfo);
7586 if (!ret->IsObject()) {
7587 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed.");
7588 return defaultRes;
7589 }
7590
7591 auto retObj = JSRef<JSObject>::Cast(ret);
7592 auto strategy = retObj->GetProperty("strategy");
7593 if (!strategy->IsNumber()) {
7594 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed.");
7595 return defaultRes;
7596 }
7597 touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>());
7598 auto id = retObj->GetProperty("id");
7599 if (!id->IsString()) {
7600 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed.");
7601 return defaultRes;
7602 }
7603 touchRes.id = id->ToString();
7604 return touchRes;
7605 };
7606 ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc));
7607 }
7608
JsForegroundColor(const JSCallbackInfo & info)7609 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info)
7610 {
7611 Color foregroundColor;
7612 ForegroundColorStrategy strategy;
7613 if (ParseJsColorStrategy(info[0], strategy)) {
7614 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy);
7615 return;
7616 }
7617 if (!ParseJsColor(info[0], foregroundColor)) {
7618 return;
7619 }
7620 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor);
7621 }
7622
JsKeyboardShortcut(const JSCallbackInfo & info)7623 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info)
7624 {
7625 // KeyboardShortcut only allows 2 or 3 params.
7626 if (info.Length() < 2 || info.Length() > 3) {
7627 return;
7628 }
7629 if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) {
7630 ViewAbstractModel::GetInstance()->SetKeyboardShortcut("", std::vector<ModifierKey>(), nullptr);
7631 return;
7632 }
7633
7634 std::string value;
7635 if (info[0]->IsString()) {
7636 value = info[0]->ToString();
7637 if (value.empty() || value.size() > 1) {
7638 ViewAbstractModel::GetInstance()->SetKeyboardShortcut("", std::vector<ModifierKey>(), nullptr);
7639 return;
7640 }
7641 } else {
7642 FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>());
7643 value = GetFunctionKeyName(functionkey);
7644 }
7645
7646 auto keysArray = JSRef<JSArray>::Cast(info[1]);
7647 size_t size = keysArray->Length();
7648 std::vector<ModifierKey> keys(size);
7649 keys.clear();
7650 for (size_t i = 0; i < size; i++) {
7651 JSRef<JSVal> key = keysArray->GetValueAt(i);
7652 if (key->IsNumber()) {
7653 keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>()));
7654 }
7655 }
7656
7657 // KeyboardShortcut allows 3 params, the third param is function callback.
7658 if (info.Length() == 3 && info[2]->IsFunction()) {
7659 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2]));
7660 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
7661 auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
7662 node = frameNode]() {
7663 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
7664 ACE_SCORING_EVENT("onKeyboardShortcutAction");
7665 PipelineContext::SetCallBackNode(node);
7666 func->ExecuteJS();
7667 };
7668 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction));
7669 return;
7670 }
7671 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr);
7672 }
7673
CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)7674 bool JSViewAbstract::CheckColor(
7675 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName)
7676 {
7677 // Color is undefined or null
7678 if (jsValue->IsUndefined() || jsValue->IsNull()) {
7679 return false;
7680 }
7681 // input type is not in [number, string, Resource]
7682 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
7683 return false;
7684 }
7685 // Correct type, incorrect value parsing
7686 if (!ParseJsColor(jsValue, result)) {
7687 return false;
7688 }
7689 return true;
7690 }
7691
CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)7692 bool JSViewAbstract::CheckLength(
7693 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName)
7694 {
7695 // Length is undefined or null
7696 if (jsValue->IsUndefined() || jsValue->IsNull()) {
7697 return false;
7698 }
7699 // input type is not in [number, string, Resource]
7700 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) {
7701 return false;
7702 }
7703 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
7704 return ParseJsDimensionVpNG(jsValue, result);
7705 }
7706 // Correct type, incorrect value parsing
7707 if (!ParseJsDimensionVp(jsValue, result)) {
7708 return false;
7709 }
7710 return true;
7711 }
7712
JsObscured(const JSCallbackInfo & info)7713 void JSViewAbstract::JsObscured(const JSCallbackInfo& info)
7714 {
7715 if (info[0]->IsUndefined()) {
7716 std::vector<ObscuredReasons> reasons(0);
7717 ViewAbstractModel::GetInstance()->SetObscured(reasons);
7718 return;
7719 }
7720 if (!info[0]->IsArray()) {
7721 return;
7722 }
7723
7724 auto obscuredArray = JSRef<JSArray>::Cast(info[0]);
7725 size_t size = obscuredArray->Length();
7726 std::vector<ObscuredReasons> reasons(size);
7727 reasons.clear();
7728 for (size_t i = 0; i < size; i++) {
7729 JSRef<JSVal> reason = obscuredArray->GetValueAt(i);
7730 if (reason->IsNumber()) {
7731 reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>()));
7732 }
7733 }
7734
7735 ViewAbstractModel::GetInstance()->SetObscured(reasons);
7736 }
7737
JSRenderGroup(const JSCallbackInfo & info)7738 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info)
7739 {
7740 if (info.Length() != 1) {
7741 return;
7742 }
7743 bool isRenderGroup = false;
7744 if (info[0]->IsBoolean()) {
7745 isRenderGroup = info[0]->ToBoolean();
7746 }
7747 ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup);
7748 }
7749
JSRenderFit(const JSCallbackInfo & info)7750 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info)
7751 {
7752 if (info.Length() != 1) {
7753 return;
7754 }
7755 RenderFit renderFit = RenderFit::TOP_LEFT;
7756 if (info[0]->IsNumber()) {
7757 int32_t fitNumber = info[0]->ToNumber<int32_t>();
7758 if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) &&
7759 fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) {
7760 renderFit = static_cast<RenderFit>(fitNumber);
7761 }
7762 }
7763 // how content fills the node duration implicit animation
7764 ViewAbstractModel::GetInstance()->SetRenderFit(renderFit);
7765 }
7766
GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)7767 void JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName)
7768 {
7769 if (!jsValue->IsObject() || jsValue->IsString()) {
7770 return;
7771 }
7772 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
7773 if (!jsObj->IsUndefined()) {
7774 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName");
7775 JSRef<JSVal> module = jsObj->GetProperty("moduleName");
7776 if (bundle->IsString() && module->IsString()) {
7777 bundleName = bundle->ToString();
7778 moduleName = module->ToString();
7779 }
7780 }
7781 }
7782
ParseImageAnalyzerSubjectOptions(const JSRef<JSVal> & optionVal,ImageAnalyzerConfig & analyzerConfig)7783 void JSViewAbstract::ParseImageAnalyzerSubjectOptions(const JSRef<JSVal>& optionVal,
7784 ImageAnalyzerConfig& analyzerConfig)
7785 {
7786 ImageAnalyzerSubjectOptions subjectOptions;
7787 auto obj = JSRef<JSObject>::Cast(optionVal);
7788 JSRef<JSVal> onAnalyzedVal = obj->GetProperty("onAnalyzed");
7789 if (onAnalyzedVal->IsFunction()) {
7790 RefPtr<JsFunction> jsOnAnalyzedFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(),
7791 JSRef<JSFunc>::Cast(onAnalyzedVal));
7792 onSubcjectAnalyzedFunc onAnalyzedCallback =
7793 [func = std::move(jsOnAnalyzedFunc)](std::string tag, std::vector<uint8_t> data) {
7794 JSRef<JSVal> params[2];
7795 params[0] = JSRef<JSVal>::Make(ToJSValue(tag));
7796 JSRef<JSArray> indexArray = JSRef<JSArray>::New();
7797 for (uint32_t i = 0; i < data.size(); i++) {
7798 indexArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(data[i])));
7799 }
7800 params[1] = JSRef<JSVal>::Cast(indexArray);
7801 func->ExecuteJS(2, params);
7802 };
7803 subjectOptions.onAnalyzedCallback = std::move(onAnalyzedCallback);
7804 }
7805
7806 JSRef<JSVal> dataVal = obj->GetProperty("analyzedData");
7807 if (dataVal->IsArray()) {
7808 JSRef<JSArray> dataArray = JSRef<JSArray>::Cast(dataVal);
7809 std::vector<uint8_t> analyzedData;
7810 for (size_t i = 0; i < dataArray->Length(); ++i) {
7811 JSRef<JSVal> value = dataArray->GetValueAt(i);
7812 if (value->IsNumber()) {
7813 analyzedData.emplace_back(value->ToNumber<uint8_t>());
7814 }
7815 }
7816 subjectOptions.analyzedData = std::move(analyzedData);
7817 }
7818
7819 #if defined(PIXEL_MAP_SUPPORTED)
7820 auto pixmapVal = obj->GetProperty("sourcePixelmap");
7821 RefPtr<PixelMap> pixmap = CreatePixelMapFromNapiValue(pixmapVal);
7822 if (pixmap != nullptr) {
7823 subjectOptions.sourcePixelmap = ConvertPixmapNapi(pixmap);
7824 }
7825 #endif
7826 analyzerConfig.subjectOptions_ = std::move(subjectOptions);
7827 }
7828
ParseImageAnalyzerTextOptions(const JSRef<JSVal> & optionVal,ImageAnalyzerConfig & analyzerConfig)7829 void JSViewAbstract::ParseImageAnalyzerTextOptions(const JSRef<JSVal>& optionVal, ImageAnalyzerConfig& analyzerConfig)
7830 {
7831 ImageAnalyzerTextOptions textOptions;
7832 auto obj = JSRef<JSObject>::Cast(optionVal);
7833 JSRef<JSVal> onAnalyzedVal = obj->GetProperty("onAnalyzed");
7834 if (onAnalyzedVal->IsFunction()) {
7835 RefPtr<JsFunction> jsFunc =
7836 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAnalyzedVal));
7837 onTextAnalyzedFunc onAnalyzedCallback = [func = std::move(jsFunc)] (
7838 std::string tag, std::string data) {
7839 JSRef<JSVal> params[2];
7840 params[0] = JSRef<JSVal>::Make(ToJSValue(tag));
7841 params[1] = JSRef<JSVal>::Make(ToJSValue(data));
7842 func->ExecuteJS(2, params);
7843 };
7844 textOptions.onAnalyzedCallback = std::move(onAnalyzedCallback);
7845 }
7846
7847 JSRef<JSVal> onTextSelected = obj->GetProperty("onTextSelected");
7848 if (onTextSelected->IsFunction()) {
7849 RefPtr<JsFunction> jsOnTextSelectedFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(),
7850 JSRef<JSFunc>::Cast(onTextSelected));
7851 onTextSelectedFunc onTextSelectedCallback =
7852 [func = std::move(jsOnTextSelectedFunc)] (std::string tag, std::string data) {
7853 JSRef<JSVal> params[2];
7854 params[0] = JSRef<JSVal>::Make(ToJSValue(tag));
7855 params[1] = JSRef<JSVal>::Make(ToJSValue(data));
7856 func->ExecuteJS(2, params);
7857 };
7858 textOptions.onTextSelected = std::move(onTextSelectedCallback);
7859 }
7860
7861 JSRef<JSVal> dataVal = obj->GetProperty("analyzedData");
7862 if (dataVal->IsArray()) {
7863 std::string analyzedData = dataVal->ToString();
7864 textOptions.analyzedData = std::move(analyzedData);
7865 }
7866 analyzerConfig.textOptions = std::move(textOptions);
7867 }
7868 } // namespace OHOS::Ace::Framework
7869