1 /* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "bridge/declarative_frontend/jsview/js_view_abstract.h" 17 18 #include <algorithm> 19 #include <cstdint> 20 #include <functional> 21 #include <memory> 22 #include <optional> 23 #include <regex> 24 #include <string> 25 #include <utility> 26 #include <vector> 27 #include <unordered_map> 28 29 #include "base/geometry/calc_dimension.h" 30 #include "base/geometry/dimension.h" 31 #include "base/geometry/matrix4.h" 32 #include "base/geometry/ng/offset_t.h" 33 #include "base/geometry/ng/vector.h" 34 #include "base/geometry/shape.h" 35 #include "base/json/json_util.h" 36 #include "base/log/ace_scoring_log.h" 37 #include "base/log/log.h" 38 #include "base/memory/ace_type.h" 39 #include "base/memory/referenced.h" 40 #include "base/utils/utils.h" 41 #include "bridge/common/utils/engine_helper.h" 42 #include "bridge/common/utils/utils.h" 43 #include "bridge/declarative_frontend/engine/functions/js_click_function.h" 44 #include "bridge/declarative_frontend/engine/functions/js_clipboard_function.h" 45 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h" 46 #include "bridge/declarative_frontend/engine/functions/js_on_child_touch_test_function.h" 47 #include "bridge/declarative_frontend/engine/functions/js_focus_function.h" 48 #include "bridge/declarative_frontend/engine/functions/js_function.h" 49 #include "bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h" 50 #include "bridge/declarative_frontend/engine/functions/js_hover_function.h" 51 #include "bridge/declarative_frontend/engine/functions/js_key_function.h" 52 #include "bridge/declarative_frontend/engine/functions/js_on_area_change_function.h" 53 #include "bridge/declarative_frontend/engine/functions/js_on_size_change_function.h" 54 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h" 55 #include "bridge/declarative_frontend/engine/functions/js_touch_intercept_function.h" 56 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h" 57 #include "bridge/js_frontend/engine/jsi/ark_js_value.h" 58 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h" 59 #include "bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h" 60 #include "bridge/declarative_frontend/engine/js_converter.h" 61 #include "bridge/declarative_frontend/engine/js_ref_ptr.h" 62 #include "bridge/declarative_frontend/engine/js_types.h" 63 #include "bridge/declarative_frontend/jsview/js_animatable_arithmetic.h" 64 #include "bridge/declarative_frontend/jsview/js_grid_container.h" 65 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h" 66 #include "bridge/declarative_frontend/jsview/js_utils.h" 67 #include "bridge/declarative_frontend/jsview/js_view_common_def.h" 68 #include "bridge/declarative_frontend/jsview/js_view_context.h" 69 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h" 70 #include "canvas_napi/js_canvas.h" 71 #if !defined(PREVIEW) && defined(OHOS_PLATFORM) 72 #include "interfaces/inner_api/ui_session/ui_session_manager.h" 73 #endif 74 #include "core/common/resource/resource_manager.h" 75 #include "core/common/resource/resource_object.h" 76 #include "core/components/common/layout/constants.h" 77 #include "core/components/common/layout/position_param.h" 78 #include "core/components/common/layout/screen_system_manager.h" 79 #include "core/components/common/properties/animation_option.h" 80 #include "core/components/common/properties/border_image.h" 81 #include "core/components/common/properties/color.h" 82 #include "core/components/common/properties/decoration.h" 83 #include "core/components/common/properties/shadow.h" 84 #include "core/components/common/properties/invert.h" 85 #include "core/components/common/properties/shadow_config.h" 86 #include "core/components/theme/resource_adapter.h" 87 #include "core/components/theme/shadow_theme.h" 88 #include "core/components_ng/base/view_abstract.h" 89 #include "core/components_ng/base/view_abstract_model.h" 90 #include "core/components_ng/base/view_stack_processor.h" 91 #include "core/components_ng/event/focus_box.h" 92 #include "core/components_ng/gestures/base_gesture_event.h" 93 #include "core/components_ng/pattern/menu/menu_pattern.h" 94 #include "core/components_ng/pattern/overlay/modal_style.h" 95 #include "core/components_ng/pattern/overlay/sheet_style.h" 96 #include "core/components_ng/property/grid_property.h" 97 #include "core/components_ng/property/safe_area_insets.h" 98 #include "core/gestures/gesture_info.h" 99 #include "core/image/image_source_info.h" 100 #ifdef PLUGIN_COMPONENT_SUPPORTED 101 #include "core/common/plugin_manager.h" 102 #endif 103 #include "interfaces/native/node/resource.h" 104 105 #include "core/common/card_scope.h" 106 #include "core/common/container.h" 107 #include "core/common/resource/resource_configuration.h" 108 #include "core/components/progress/progress_theme.h" 109 #include "core/components_ng/base/view_abstract_model_ng.h" 110 #include "core/components_ng/base/view_stack_model.h" 111 #include "core/components_ng/property/progress_mask_property.h" 112 113 namespace OHOS::Ace { 114 namespace { 115 const std::string RESOURCE_TOKEN_PATTERN = "(app|sys|\\[.+?\\])\\.(\\S+?)\\.(\\S+)"; 116 const std::string RESOURCE_NAME_PATTERN = "\\[(.+?)\\]"; 117 constexpr int32_t DIRECTION_COUNT = 4; 118 constexpr char JS_TEXT_MENU_ID_CLASS_NAME[] = "TextMenuItemId"; 119 constexpr int NUM1 = 1; 120 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN, 121 HoverModeAreaType::BOTTOM_SCREEN }; 122 } // namespace 123 124 std::unique_ptr<ViewAbstractModel> ViewAbstractModel::instance_ = nullptr; 125 std::mutex ViewAbstractModel::mutex_; 126 using DoubleBindCallback = std::function<void(const std::string&)>; 127 GetInstance()128 ViewAbstractModel* ViewAbstractModel::GetInstance() 129 { 130 if (!instance_) { 131 std::lock_guard<std::mutex> lock(mutex_); 132 if (!instance_) { 133 #ifdef NG_BUILD 134 instance_.reset(new NG::ViewAbstractModelNG()); 135 #else 136 if (Container::IsCurrentUseNewPipeline()) { 137 instance_.reset(new NG::ViewAbstractModelNG()); 138 } else { 139 instance_.reset(new Framework::ViewAbstractModelImpl()); 140 } 141 #endif 142 } 143 } 144 return instance_.get(); 145 } 146 147 } // namespace OHOS::Ace 148 149 namespace OHOS::Ace::Framework { 150 namespace { 151 152 constexpr uint32_t DEFAULT_DURATION = 1000; // ms 153 constexpr int64_t MICROSEC_TO_MILLISEC = 1000; 154 constexpr uint32_t COLOR_ALPHA_OFFSET = 24; 155 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000; 156 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3; 157 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4; 158 constexpr int32_t MAX_ALIGN_VALUE = 8; 159 constexpr int32_t UNKNOWN_RESOURCE_ID = -1; 160 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1; 161 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase); 162 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase); 163 constexpr double FULL_DIMENSION = 100.0; 164 constexpr double HALF_DIMENSION = 50.0; 165 constexpr double ROUND_UNIT = 360.0; 166 constexpr double VISIBLE_RATIO_MIN = 0.0; 167 constexpr double VISIBLE_RATIO_MAX = 1.0; 168 constexpr int32_t PARAMETER_LENGTH_FIRST = 1; 169 constexpr int32_t PARAMETER_LENGTH_SECOND = 2; 170 constexpr int32_t PARAMETER_LENGTH_THIRD = 3; 171 constexpr int32_t SECOND_INDEX = 2; 172 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2; 173 constexpr float DEFAULT_SCALE_LIGHT = 0.9f; 174 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f; 175 constexpr float MAX_ANGLE = 360.0f; 176 constexpr float DEFAULT_BIAS = 0.5f; 177 constexpr float DEFAULT_LAYOUT_WEIGHT = 0.0f; 178 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC }; 179 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" }; 180 const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" }; 181 const std::string SHEET_HEIGHT_MEDIUM = "medium"; 182 const std::string SHEET_HEIGHT_LARGE = "large"; 183 const std::string SHEET_HEIGHT_AUTO = "auto"; 184 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content"; 185 const std::string BLOOM_RADIUS_SYS_RES_NAME = "sys.float.ohos_id_point_light_bloom_radius"; 186 const std::string BLOOM_COLOR_SYS_RES_NAME = "sys.color.ohos_id_point_light_bloom_color"; 187 const std::string ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME = "sys.float.ohos_id_point_light_illuminated_border_width"; 188 const std::vector<std::string> SLICE_KEYS = { "left", "right", "top", "bottom" }; 189 const std::vector<int32_t> LENGTH_METRICS_KEYS { 190 static_cast<int32_t>(ArkUIIndex::START), static_cast<int32_t>(ArkUIIndex::END), 191 static_cast<int32_t>(ArkUIIndex::TOP), static_cast<int32_t>(ArkUIIndex::BOTTOM) }; 192 const char* START_PROPERTY = "start"; 193 const char* END_PROPERTY = "end"; 194 const char* TOP_PROPERTY = "top"; 195 const char* BOTTOM_PROPERTY = "bottom"; 196 const char* LEFT_PROPERTY = "left"; 197 const char* RIGHT_PROPERTY = "right"; 198 const char* TOP_START_PROPERTY = "topStart"; 199 const char* TOP_END_PROPERTY = "topEnd"; 200 const char* BOTTOM_START_PROPERTY = "bottomStart"; 201 const char* BOTTOM_END_PROPERTY = "bottomEnd"; 202 const char* DEBUG_LINE_INFO_LINE = "$line"; 203 const char* DEBUG_LINE_INFO_PACKAGE_NAME = "$packageName"; 204 205 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct; 206 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct; 207 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct; 208 ParseJsScale(const JSRef<JSVal> & jsValue,float & scaleX,float & scaleY,float & scaleZ,CalcDimension & centerX,CalcDimension & centerY)209 void ParseJsScale(const JSRef<JSVal>& jsValue, float& scaleX, float& scaleY, float& scaleZ, 210 CalcDimension& centerX, CalcDimension& centerY) 211 { 212 double xVal = 1.0; 213 double yVal = 1.0; 214 double zVal = 1.0; 215 if (!jsValue->IsObject()) { 216 scaleX = static_cast<float>(xVal); 217 scaleY = static_cast<float>(yVal); 218 scaleZ = static_cast<float>(zVal); 219 CalcDimension length; 220 centerX = length; 221 centerY = length; 222 return; 223 } 224 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 225 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), xVal); 226 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), yVal); 227 JSViewAbstract::ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), zVal); 228 scaleX = static_cast<float>(xVal); 229 scaleY = static_cast<float>(yVal); 230 scaleZ = static_cast<float>(zVal); 231 // if specify centerX 232 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), centerX); 233 // if specify centerY 234 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), centerY); 235 } 236 ParseJsTranslate(const JSRef<JSVal> & jsValue,CalcDimension & translateX,CalcDimension & translateY,CalcDimension & translateZ)237 void ParseJsTranslate(const JSRef<JSVal>& jsValue, CalcDimension& translateX, CalcDimension& translateY, 238 CalcDimension& translateZ) 239 { 240 if (!jsValue->IsObject()) { 241 return; 242 } 243 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 244 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)), translateX); 245 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)), translateY); 246 JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)), translateZ); 247 } 248 GetDefaultRotateVector(double & dx,double & dy,double & dz)249 void GetDefaultRotateVector(double& dx, double& dy, double& dz) 250 { 251 dx = 0.0; 252 dy = 0.0; 253 dz = 0.0; 254 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_NINE)) { 255 dz = 1.0; 256 } 257 } 258 ParseJsRotate(const JSRef<JSVal> & jsValue,NG::RotateOptions & rotate,std::optional<float> & angle)259 void ParseJsRotate(const JSRef<JSVal>& jsValue, NG::RotateOptions& rotate, std::optional<float>& angle) 260 { 261 if (!jsValue->IsObject()) { 262 return; 263 } 264 // default: dx, dy, dz (0.0, 0.0, 0.0) 265 double dxVal = 0.0; 266 double dyVal = 0.0; 267 double dzVal = 0.0; 268 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 269 auto jsRotateX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)); 270 auto jsRotateY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)); 271 auto jsRotateZ = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Z)); 272 if (jsRotateX->IsUndefined() 273 && jsRotateY->IsUndefined() 274 && jsRotateZ->IsUndefined()) { 275 GetDefaultRotateVector(dxVal, dyVal, dzVal); 276 } else { 277 JSViewAbstract::ParseJsDouble(jsRotateX, dxVal); 278 JSViewAbstract::ParseJsDouble(jsRotateY, dyVal); 279 JSViewAbstract::ParseJsDouble(jsRotateZ, dzVal); 280 } 281 rotate.xDirection = static_cast<float>(dxVal); 282 rotate.yDirection = static_cast<float>(dyVal); 283 rotate.zDirection = static_cast<float>(dzVal); 284 // if specify centerX 285 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_X)), 286 rotate.centerX)) { 287 rotate.centerX = Dimension(0.5f, DimensionUnit::PERCENT); 288 } 289 // if specify centerY 290 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Y)), 291 rotate.centerY)) { 292 rotate.centerY = Dimension(0.5f, DimensionUnit::PERCENT); 293 } 294 // if specify centerZ 295 if (!JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER_Z)), 296 rotate.centerZ)) { 297 rotate.centerZ = Dimension(0.5f, DimensionUnit::PERCENT); 298 } 299 // if specify angle 300 JSViewAbstract::GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, angle); 301 rotate.perspective = 0.0f; 302 JSViewAbstract::GetJsPerspective(static_cast<int32_t>(ArkUIIndex::PERSPECTIVE), jsObj, rotate.perspective); 303 } 304 ParseMotionPath(const JSRef<JSVal> & jsValue,MotionPathOption & option)305 bool ParseMotionPath(const JSRef<JSVal>& jsValue, MotionPathOption& option) 306 { 307 if (!jsValue->IsObject()) { 308 return false; 309 } 310 311 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 312 auto path = jsObj->GetPropertyValue<std::string>("path", ""); 313 if (path.empty()) { 314 return false; 315 } 316 option.SetPath(path); 317 double from = 0.0; 318 double to = 1.0; 319 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("from"), from); 320 JSViewAbstract::ParseJsDouble(jsObj->GetProperty("to"), to); 321 if (GreatNotEqual(from, 1.0) || LessNotEqual(from, 0.0)) { 322 from = 0.0; 323 } 324 if (GreatNotEqual(to, 1.0) || LessNotEqual(to, 0.0)) { 325 to = 1.0; 326 } else if (to < from) { 327 to = from; 328 } 329 option.SetBegin(static_cast<float>(from)); 330 option.SetEnd(static_cast<float>(to)); 331 option.SetRotate(jsObj->GetPropertyValue<bool>("rotatable", false)); 332 return true; 333 } 334 ParseDragPreviewMode(NG::DragPreviewOption & previewOption,int32_t modeValue,bool & isAuto)335 void ParseDragPreviewMode(NG::DragPreviewOption& previewOption, int32_t modeValue, bool& isAuto) 336 { 337 if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::AUTO)) { 338 previewOption.ResetDragPreviewMode(); 339 isAuto = true; 340 return; 341 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::DISABLE_SCALE)) { 342 previewOption.isScaleEnabled = false; 343 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_SHADOW)) { 344 previewOption.isDefaultShadowEnabled = true; 345 } else if (modeValue == static_cast<int32_t>(NG::DragPreviewMode::ENABLE_DEFAULT_RADIUS)) { 346 previewOption.isDefaultRadiusEnabled = true; 347 } 348 isAuto = false; 349 } 350 SetBgImgPosition(const DimensionUnit & typeX,const DimensionUnit & typeY,const double valueX,const double valueY,BackgroundImagePosition & bgImgPosition)351 void SetBgImgPosition(const DimensionUnit& typeX, const DimensionUnit& typeY, const double valueX, const double valueY, 352 BackgroundImagePosition& bgImgPosition) 353 { 354 AnimationOption option = ViewStackModel::GetInstance()->GetImplicitAnimationOption(); 355 bgImgPosition.SetSizeX(AnimatableDimension(valueX, typeX, option)); 356 bgImgPosition.SetSizeY(AnimatableDimension(valueY, typeY, option)); 357 } 358 GetReplaceContentStr(int pos,const std::string & type,JSRef<JSArray> params,int32_t containCount)359 std::string GetReplaceContentStr(int pos, const std::string& type, JSRef<JSArray> params, int32_t containCount) 360 { 361 auto index = pos + containCount; 362 if (index < 0) { 363 return std::string(); 364 } 365 366 JSRef<JSVal> item = params->GetValueAt(static_cast<size_t>(index)); 367 if (type == "d") { 368 if (item->IsNumber()) { 369 return std::to_string(item->ToNumber<int32_t>()); 370 } else if (item->IsObject()) { 371 int32_t result = 0; 372 JSViewAbstract::ParseJsInteger(item, result); 373 return std::to_string(result); 374 } 375 } else if (type == "s") { 376 if (item->IsString()) { 377 return item->ToString(); 378 } else if (item->IsObject()) { 379 std::string result; 380 JSViewAbstract::ParseJsString(item, result); 381 return result; 382 } 383 } else if (type == "f") { 384 if (item->IsNumber()) { 385 return std::to_string(item->ToNumber<float>()); 386 } else if (item->IsObject()) { 387 double result = 0.0; 388 JSViewAbstract::ParseJsDouble(item, result); 389 return std::to_string(result); 390 } 391 } 392 return std::string(); 393 } 394 ReplaceHolder(std::string & originStr,JSRef<JSArray> params,int32_t containCount)395 void ReplaceHolder(std::string& originStr, JSRef<JSArray> params, int32_t containCount) 396 { 397 auto size = static_cast<int32_t>(params->Length()); 398 if (containCount == size) { 399 return; 400 } 401 std::string::const_iterator start = originStr.begin(); 402 std::string::const_iterator end = originStr.end(); 403 std::smatch matches; 404 bool shortHolderType = false; 405 bool firstMatch = true; 406 int searchTime = 0; 407 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) { 408 std::string pos = matches[2]; 409 std::string type = matches[4]; 410 if (firstMatch) { 411 firstMatch = false; 412 shortHolderType = pos.length() == 0; 413 } else { 414 if (shortHolderType ^ (pos.length() == 0)) { 415 return; 416 } 417 } 418 419 std::string replaceContentStr; 420 if (shortHolderType) { 421 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount); 422 } else { 423 replaceContentStr = GetReplaceContentStr(StringToInt(pos) - 1, type, params, containCount); 424 } 425 426 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr); 427 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length(); 428 end = originStr.end(); 429 searchTime++; 430 } 431 } 432 ParseLocationProps(const JSRef<JSObject> & sizeObj,CalcDimension & x,CalcDimension & y)433 bool ParseLocationProps(const JSRef<JSObject>& sizeObj, CalcDimension& x, CalcDimension& y) 434 { 435 JSRef<JSVal> xVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)); 436 JSRef<JSVal> yVal = sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)); 437 bool hasX = false; 438 bool hasY = false; 439 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 440 hasX = JSViewAbstract::ParseJsDimensionNG(xVal, x, DimensionUnit::VP); 441 hasY = JSViewAbstract::ParseJsDimensionNG(yVal, y, DimensionUnit::VP); 442 } else { 443 hasX = JSViewAbstract::ParseJsDimension(xVal, x, DimensionUnit::VP); 444 hasY = JSViewAbstract::ParseJsDimension(yVal, y, DimensionUnit::VP); 445 } 446 return hasX || hasY; 447 } 448 ParseLocationPropsEdges(const JSRef<JSObject> & edgesObj,EdgesParam & edges)449 bool ParseLocationPropsEdges(const JSRef<JSObject>& edgesObj, EdgesParam& edges) 450 { 451 bool useEdges = false; 452 CalcDimension top; 453 CalcDimension left; 454 CalcDimension bottom; 455 CalcDimension right; 456 JSRef<JSVal> topVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)); 457 JSRef<JSVal> leftVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)); 458 JSRef<JSVal> bottomVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)); 459 JSRef<JSVal> rightVal = edgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)); 460 if (JSViewAbstract::ParseJsDimensionNG(topVal, top, DimensionUnit::VP)) { 461 edges.SetTop(top); 462 useEdges = true; 463 } 464 if (JSViewAbstract::ParseJsDimensionNG(leftVal, left, DimensionUnit::VP)) { 465 edges.SetLeft(left); 466 useEdges = true; 467 } 468 if (JSViewAbstract::ParseJsDimensionNG(bottomVal, bottom, DimensionUnit::VP)) { 469 edges.SetBottom(bottom); 470 useEdges = true; 471 } 472 if (JSViewAbstract::ParseJsDimensionNG(rightVal, right, DimensionUnit::VP)) { 473 edges.SetRight(right); 474 useEdges = true; 475 } 476 return useEdges; 477 } 478 ParseJsLengthMetrics(const JSRef<JSObject> & obj,CalcDimension & result)479 bool ParseJsLengthMetrics(const JSRef<JSObject>& obj, CalcDimension& result) 480 { 481 auto value = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)); 482 if (!value->IsNumber()) { 483 return false; 484 } 485 auto unit = DimensionUnit::VP; 486 auto jsUnit = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT)); 487 if (jsUnit->IsNumber()) { 488 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>()); 489 } 490 CalcDimension dimension(value->ToNumber<double>(), unit); 491 result = dimension; 492 return true; 493 } 494 CheckLengthMetrics(const JSRef<JSObject> & object)495 bool CheckLengthMetrics(const JSRef<JSObject>& object) 496 { 497 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) || 498 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END)) || 499 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_START)) || 500 object->HasProperty(static_cast<int32_t>(ArkUIIndex::TOP_END)) || 501 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_START)) || 502 object->HasProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM_END))) { 503 return true; 504 } 505 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)); 506 if (jsTop->IsObject()) { 507 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop); 508 if (topObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) { 509 return true; 510 } 511 } 512 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)); 513 if (jsBottom->IsObject()) { 514 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom); 515 if (bottomObj->HasProperty(static_cast<int32_t>(ArkUIIndex::VALUE))) { 516 return true; 517 } 518 } 519 return false; 520 } 521 ParseLocalizedEdges(const JSRef<JSObject> & LocalizeEdgesObj,EdgesParam & edges)522 bool ParseLocalizedEdges(const JSRef<JSObject>& LocalizeEdgesObj, EdgesParam& edges) 523 { 524 bool useLocalizedEdges = false; 525 CalcDimension start; 526 CalcDimension end; 527 CalcDimension top; 528 CalcDimension bottom; 529 530 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START)); 531 if (startVal->IsObject()) { 532 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal); 533 ParseJsLengthMetrics(startObj, start); 534 edges.SetLeft(start); 535 useLocalizedEdges = true; 536 } 537 JSRef<JSVal> endVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::END)); 538 if (endVal->IsObject()) { 539 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(endVal); 540 ParseJsLengthMetrics(endObj, end); 541 edges.SetRight(end); 542 useLocalizedEdges = true; 543 } 544 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)); 545 if (topVal->IsObject()) { 546 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal); 547 ParseJsLengthMetrics(topObj, top); 548 edges.SetTop(top); 549 useLocalizedEdges = true; 550 } 551 JSRef<JSVal> bottomVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)); 552 if (bottomVal->IsObject()) { 553 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(bottomVal); 554 ParseJsLengthMetrics(bottomObj, bottom); 555 edges.SetBottom(bottom); 556 useLocalizedEdges = true; 557 } 558 return useLocalizedEdges; 559 } 560 ParseMarkAnchorPosition(const JSRef<JSObject> & LocalizeEdgesObj,CalcDimension & x,CalcDimension & y)561 bool ParseMarkAnchorPosition(const JSRef<JSObject>& LocalizeEdgesObj, CalcDimension& x, CalcDimension& y) 562 { 563 bool useMarkAnchorPosition = false; 564 CalcDimension start; 565 CalcDimension top; 566 567 JSRef<JSVal> startVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::START)); 568 if (startVal->IsObject()) { 569 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(startVal); 570 ParseJsLengthMetrics(startObj, start); 571 x = start; 572 useMarkAnchorPosition = true; 573 } 574 JSRef<JSVal> topVal = LocalizeEdgesObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)); 575 if (topVal->IsObject()) { 576 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(topVal); 577 ParseJsLengthMetrics(topObj, top); 578 y = top; 579 useMarkAnchorPosition = true; 580 } 581 return useMarkAnchorPosition; 582 } 583 ParseDragStartBuilderFunc(const JSRef<JSVal> & info)584 RefPtr<JsFunction> ParseDragStartBuilderFunc(const JSRef<JSVal>& info) 585 { 586 JSRef<JSVal> builder; 587 if (info->IsObject()) { 588 auto builderObj = JSRef<JSObject>::Cast(info); 589 builder = builderObj->GetProperty("builder"); 590 } else if (info->IsFunction()) { 591 builder = info; 592 } else { 593 return nullptr; 594 } 595 596 if (!builder->IsFunction()) { 597 return nullptr; 598 } 599 600 return AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 601 } 602 603 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition( 604 const JSRef<JSObject>& object, const JSExecutionContext& context); 605 ParseChainedRotateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)606 RefPtr<NG::ChainedTransitionEffect> ParseChainedRotateTransition( 607 const JSRef<JSVal>& effectOption, const JSExecutionContext& context) 608 { 609 RefPtr<NG::ChainedTransitionEffect> effect; 610 if (effectOption->IsObject()) { 611 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct); 612 std::optional<float> angle; 613 ParseJsRotate(effectOption, rotate, angle); 614 if (angle.has_value()) { 615 rotate.angle = angle.value(); 616 return AceType::MakeRefPtr<NG::ChainedRotateEffect>(rotate); 617 } 618 } 619 return nullptr; 620 } 621 ParseChainedOpacityTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)622 RefPtr<NG::ChainedTransitionEffect> ParseChainedOpacityTransition( 623 const JSRef<JSVal>& effectOption, const JSExecutionContext& context) 624 { 625 double opacity = 1.0; 626 if (JSViewAbstract::ParseJsDouble(effectOption, opacity)) { 627 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 628 if (LessNotEqual(opacity, 0.0) || opacity > 1.0) { 629 opacity = 1.0; 630 } 631 } else { 632 opacity = std::clamp(opacity, 0.0, 1.0); 633 } 634 return AceType::MakeRefPtr<NG::ChainedOpacityEffect>(opacity); 635 } 636 return nullptr; 637 } 638 ParseChainedTranslateTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)639 RefPtr<NG::ChainedTransitionEffect> ParseChainedTranslateTransition( 640 const JSRef<JSVal>& effectOption, const JSExecutionContext& context) 641 { 642 if (effectOption->IsObject()) { 643 // default: x, y, z (0.0, 0.0, 0.0) 644 NG::TranslateOptions translate; 645 ParseJsTranslate(effectOption, translate.x, translate.y, translate.z); 646 return AceType::MakeRefPtr<NG::ChainedTranslateEffect>(translate); 647 } 648 return nullptr; 649 } 650 ParseChainedScaleTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)651 RefPtr<NG::ChainedTransitionEffect> ParseChainedScaleTransition( 652 const JSRef<JSVal>& effectOption, const JSExecutionContext& context) 653 { 654 if (effectOption->IsObject()) { 655 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%; 656 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct); 657 ParseJsScale(effectOption, scale.xScale, scale.yScale, scale.zScale, scale.centerX, scale.centerY); 658 return AceType::MakeRefPtr<NG::ChainedScaleEffect>(scale); 659 } 660 return nullptr; 661 } 662 ParseChainedMoveTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)663 RefPtr<NG::ChainedTransitionEffect> ParseChainedMoveTransition( 664 const JSRef<JSVal>& effectOption, const JSExecutionContext& context) 665 { 666 int32_t edge = 0; 667 if (JSViewAbstract::ParseJsInt32(effectOption, edge)) { 668 if (edge < static_cast<int32_t>(NG::TransitionEdge::TOP) || 669 edge > static_cast<int32_t>(NG::TransitionEdge::END)) { 670 edge = static_cast<int32_t>(NG::TransitionEdge::START); 671 } 672 return AceType::MakeRefPtr<NG::ChainedMoveEffect>(static_cast<NG::TransitionEdge>(edge)); 673 } 674 return nullptr; 675 } 676 ParseChainedAsymmetricTransition(const JSRef<JSVal> & effectOption,const JSExecutionContext & context)677 RefPtr<NG::ChainedTransitionEffect> ParseChainedAsymmetricTransition( 678 const JSRef<JSVal>& effectOption, const JSExecutionContext& context) 679 { 680 if (effectOption->IsObject()) { 681 auto effectObj = JSRef<JSObject>::Cast(effectOption); 682 auto appearJsVal = effectObj->GetProperty("appear"); 683 auto disappearJsVal = effectObj->GetProperty("disappear"); 684 RefPtr<NG::ChainedTransitionEffect> appearEffect; 685 RefPtr<NG::ChainedTransitionEffect> disappearEffect; 686 if (appearJsVal->IsObject()) { 687 auto appearObj = JSRef<JSObject>::Cast(appearJsVal); 688 appearEffect = ParseChainedTransition(appearObj, context); 689 } 690 if (disappearJsVal->IsObject()) { 691 auto disappearObj = JSRef<JSObject>::Cast(disappearJsVal); 692 disappearEffect = ParseChainedTransition(disappearObj, context); 693 } 694 return AceType::MakeRefPtr<NG::ChainedAsymmetricEffect>(appearEffect, disappearEffect); 695 } 696 return nullptr; 697 } 698 GetFormAnimationTimeInterval(const RefPtr<PipelineBase> & pipelineContext)699 int64_t GetFormAnimationTimeInterval(const RefPtr<PipelineBase>& pipelineContext) 700 { 701 CHECK_NULL_RETURN(pipelineContext, 0); 702 return (GetMicroTickCount() - pipelineContext->GetFormAnimationStartTime()) / MICROSEC_TO_MILLISEC; 703 } 704 705 using ChainedTransitionEffectCreator = RefPtr<NG::ChainedTransitionEffect> (*)( 706 const JSRef<JSVal>&, const JSExecutionContext&); 707 ParseChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)708 RefPtr<NG::ChainedTransitionEffect> ParseChainedTransition( 709 const JSRef<JSObject>& object, const JSExecutionContext& context) 710 { 711 auto propType = object->GetProperty("type_"); 712 if (!propType->IsString()) { 713 return nullptr; 714 } 715 std::string type = propType->ToString(); 716 auto propEffectOption = object->GetProperty("effect_"); 717 auto propAnimationOption = object->GetProperty("animation_"); 718 auto propSuccessor = object->GetProperty("successor_"); 719 static const LinearMapNode<ChainedTransitionEffectCreator> creatorMap[] = { 720 { "asymmetric", ParseChainedAsymmetricTransition }, 721 { "identity", 722 [](const JSRef<JSVal>& effectOption, const JSExecutionContext& context) 723 -> RefPtr<NG::ChainedTransitionEffect> { return AceType::MakeRefPtr<NG::ChainedIdentityEffect>(); } }, 724 { "move", ParseChainedMoveTransition }, 725 { "opacity", ParseChainedOpacityTransition }, 726 { "rotate", ParseChainedRotateTransition }, 727 { "scale", ParseChainedScaleTransition }, 728 { "slideSwitch", 729 [](const JSRef<JSVal>& effectOption, 730 const JSExecutionContext& context) -> RefPtr<NG::ChainedTransitionEffect> { 731 return AceType::MakeRefPtr<NG::ChainedSlideSwitchEffect>(); 732 } }, 733 { "translate", ParseChainedTranslateTransition }, 734 }; 735 int64_t index = BinarySearchFindIndex(creatorMap, ArraySize(creatorMap), type.c_str()); 736 if (index < 0) { 737 return nullptr; 738 } 739 RefPtr<NG::ChainedTransitionEffect> result = creatorMap[index].value(propEffectOption, context); 740 if (!result) { 741 return nullptr; 742 } 743 if (propAnimationOption->IsObject()) { 744 auto container = Container::Current(); 745 CHECK_NULL_RETURN(container, nullptr); 746 auto pipelineContext = container->GetPipelineContext(); 747 CHECK_NULL_RETURN(pipelineContext, nullptr); 748 auto animationOptionResult = std::make_shared<AnimationOption>( 749 JSViewContext::CreateAnimation(propAnimationOption, pipelineContext->IsFormRender())); 750 // The maximum of the form-animation-playback duration value is 1000 ms. 751 if (pipelineContext->IsFormRender() && pipelineContext->IsFormAnimation()) { 752 auto formAnimationTimeInterval = GetFormAnimationTimeInterval(pipelineContext); 753 // If the duration exceeds 1000ms, init it to 0 ms. 754 if (formAnimationTimeInterval > DEFAULT_DURATION) { 755 animationOptionResult->SetDuration(0); 756 } else if (animationOptionResult->GetDuration() > (DEFAULT_DURATION - formAnimationTimeInterval)) { 757 // If remaining time is less than 1000ms, check for update duration. 758 animationOptionResult->SetDuration(DEFAULT_DURATION - formAnimationTimeInterval); 759 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form Transition SetDuration: %{public}lld ms", 760 static_cast<long long>(DEFAULT_DURATION - formAnimationTimeInterval)); 761 } 762 } 763 auto animationOptionObj = JSRef<JSObject>::Cast(propAnimationOption); 764 JSRef<JSVal> onFinish = animationOptionObj->GetProperty("onFinish"); 765 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 766 if (onFinish->IsFunction()) { 767 RefPtr<JsFunction> jsFunc = 768 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish)); 769 std::function<void()> onFinishEvent = [execCtx = context, func = std::move(jsFunc), 770 id = Container::CurrentId(), node = targetNode]() { 771 ContainerScope scope(id); 772 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 773 PipelineContext::SetCallBackNode(node); 774 func->Execute(); 775 }; 776 animationOptionResult->SetOnFinishEvent(onFinishEvent); 777 } 778 result->SetAnimationOption(animationOptionResult); 779 } 780 if (propSuccessor->IsObject()) { 781 result->SetNext(ParseChainedTransition(JSRef<JSObject>::Cast(propSuccessor), context)); 782 } 783 return result; 784 } 785 786 #ifndef WEARABLE_PRODUCT 787 const std::vector<Placement> PLACEMENT = { Placement::LEFT, Placement::RIGHT, Placement::TOP, Placement::BOTTOM, 788 Placement::TOP_LEFT, Placement::TOP_RIGHT, Placement::BOTTOM_LEFT, Placement::BOTTOM_RIGHT, Placement::LEFT_TOP, 789 Placement::LEFT_BOTTOM, Placement::RIGHT_TOP, Placement::RIGHT_BOTTOM }; 790 ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj)791 DoubleBindCallback ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj) 792 { 793 JSRef<JSVal> changeEvent = callbackObj->GetProperty("changeEvent"); 794 if (!changeEvent->IsFunction()) { 795 return {}; 796 } 797 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEvent)); 798 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 799 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]( 800 const std::string& param) { 801 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 802 if (param != "true" && param != "false") { 803 return; 804 } 805 PipelineContext::SetCallBackNode(node); 806 bool newValue = StringToBool(param); 807 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue)); 808 func->ExecuteJS(1, &newJSVal); 809 }; 810 return callback; 811 } 812 SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)813 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam) 814 { 815 auto colorValue = messageOptionsObj->GetProperty("textColor"); 816 Color textColor; 817 if (JSViewAbstract::ParseJsColor(colorValue, textColor)) { 818 if (popupParam) { 819 popupParam->SetTextColor(textColor); 820 } 821 } 822 823 auto font = messageOptionsObj->GetProperty("font"); 824 if (!font->IsNull() && font->IsObject()) { 825 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font); 826 auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE)); 827 CalcDimension fontSize; 828 if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) { 829 if (popupParam && fontSize.IsValid()) { 830 popupParam->SetFontSize(fontSize); 831 } 832 } 833 auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT)); 834 if (fontWeightValue->IsString()) { 835 if (popupParam) { 836 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString())); 837 } 838 } 839 auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE)); 840 if (fontStyleValue->IsNumber()) { 841 int32_t value = fontStyleValue->ToNumber<int32_t>(); 842 if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) { 843 return; 844 } 845 if (popupParam) { 846 popupParam->SetFontStyle(FONT_STYLES[value]); 847 } 848 } 849 } 850 } 851 SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)852 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam) 853 { 854 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop"); 855 if (placementOnTopVal->IsBoolean() && popupParam) { 856 popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM); 857 } 858 } 859 IsPopupCreated()860 bool IsPopupCreated() 861 { 862 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode(); 863 CHECK_NULL_RETURN(targetNode, false); 864 auto targetId = targetNode->GetId(); 865 auto container = Container::Current(); 866 CHECK_NULL_RETURN(container, false); 867 auto pipelineContext = container->GetPipelineContext(); 868 CHECK_NULL_RETURN(pipelineContext, false); 869 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext); 870 CHECK_NULL_RETURN(context, false); 871 auto overlayManager = context->GetOverlayManager(); 872 CHECK_NULL_RETURN(overlayManager, false); 873 auto popupInfo = overlayManager->GetPopupInfo(targetId); 874 if (popupInfo.popupId == -1 || !popupInfo.popupNode) { 875 return false; 876 } 877 return true; 878 } 879 ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)880 void ParsePopupCommonParam( 881 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam) 882 { 883 auto arrowOffset = popupObj->GetProperty("arrowOffset"); 884 CalcDimension offset; 885 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) { 886 if (popupParam) { 887 popupParam->SetArrowOffset(offset); 888 } 889 } 890 891 auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition"); 892 if (arrowPointPosition->IsString()) { 893 char* pEnd = nullptr; 894 auto arrowString = arrowPointPosition->ToString(); 895 std::strtod(arrowString.c_str(), &pEnd); 896 if (pEnd != nullptr) { 897 if (std::strcmp(pEnd, "Start") == 0) { 898 offset = ARROW_ZERO_PERCENT_VALUE; 899 } 900 if (std::strcmp(pEnd, "Center") == 0) { 901 offset = ARROW_HALF_PERCENT_VALUE; 902 } 903 if (std::strcmp(pEnd, "End") == 0) { 904 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE; 905 } 906 if (popupParam) { 907 popupParam->SetArrowOffset(offset); 908 } 909 } 910 } 911 912 auto targetSpace = popupObj->GetProperty("targetSpace"); 913 if (!targetSpace->IsNull()) { 914 CalcDimension space; 915 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) { 916 if (popupParam) { 917 popupParam->SetTargetSpace(space); 918 } 919 } 920 } 921 922 JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow"); 923 if (showInSubWindowValue->IsBoolean()) { 924 bool showInSubBoolean = showInSubWindowValue->ToBoolean(); 925 #if defined(PREVIEW) 926 if (showInSubBoolean) { 927 LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead."); 928 showInSubBoolean = false; 929 } 930 #endif 931 if (popupParam) { 932 popupParam->SetShowInSubWindow(showInSubBoolean); 933 } 934 } 935 936 auto placementValue = popupObj->GetProperty("placement"); 937 if (placementValue->IsNumber()) { 938 auto placement = placementValue->ToNumber<int32_t>(); 939 if (placement >= 0 && placement <= static_cast<int32_t>(PLACEMENT.size())) { 940 popupParam->SetPlacement(PLACEMENT[placement]); 941 } 942 } else { 943 SetPlacementOnTopVal(popupObj, popupParam); 944 } 945 946 auto enableArrowValue = popupObj->GetProperty("enableArrow"); 947 if (enableArrowValue->IsBoolean()) { 948 popupParam->SetEnableArrow(enableArrowValue->ToBoolean()); 949 } 950 951 auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget"); 952 if (followTransformOfTargetValue->IsBoolean()) { 953 popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean()); 954 } 955 956 JSRef<JSVal> maskValue = popupObj->GetProperty("mask"); 957 if (maskValue->IsBoolean()) { 958 if (popupParam) { 959 popupParam->SetBlockEvent(maskValue->ToBoolean()); 960 } 961 } 962 if (maskValue->IsObject()) { 963 auto maskObj = JSRef<JSObject>::Cast(maskValue); 964 auto colorValue = maskObj->GetProperty("color"); 965 Color maskColor; 966 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) { 967 popupParam->SetMaskColor(maskColor); 968 } 969 } 970 971 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange"); 972 if (onStateChangeVal->IsFunction()) { 973 std::vector<std::string> keys = { "isVisible" }; 974 RefPtr<JsFunction> jsFunc = 975 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal)); 976 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 977 if (popupParam) { 978 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys, 979 node = targetNode](const std::string& param) { 980 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 981 ACE_SCORING_EVENT("Popup.onStateChange"); 982 PipelineContext::SetCallBackNode(node); 983 func->Execute(keys, param); 984 }; 985 popupParam->SetOnStateChange(onStateChangeCallback); 986 } 987 } 988 989 auto offsetVal = popupObj->GetProperty("offset"); 990 if (offsetVal->IsObject()) { 991 auto offsetObj = JSRef<JSObject>::Cast(offsetVal); 992 auto xVal = offsetObj->GetProperty("x"); 993 auto yVal = offsetObj->GetProperty("y"); 994 Offset popupOffset; 995 CalcDimension dx; 996 CalcDimension dy; 997 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) { 998 popupOffset.SetX(dx.ConvertToPx()); 999 } 1000 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) { 1001 popupOffset.SetY(dy.ConvertToPx()); 1002 } 1003 if (popupParam) { 1004 popupParam->SetTargetOffset(popupOffset); 1005 } 1006 } 1007 1008 Color backgroundColor; 1009 auto popupColorVal = popupObj->GetProperty("popupColor"); 1010 if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) { 1011 popupParam->SetBackgroundColor(backgroundColor); 1012 } 1013 1014 auto autoCancelVal = popupObj->GetProperty("autoCancel"); 1015 if (autoCancelVal->IsBoolean()) { 1016 popupParam->SetHasAction(!autoCancelVal->ToBoolean()); 1017 } 1018 1019 auto childWidthVal = popupObj->GetProperty("width"); 1020 if (!childWidthVal->IsNull()) { 1021 CalcDimension width; 1022 if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) { 1023 if (width.Value() > 0) { 1024 popupParam->SetChildWidth(width); 1025 } 1026 } 1027 } 1028 1029 auto arrowWidthVal = popupObj->GetProperty("arrowWidth"); 1030 if (!arrowWidthVal->IsNull()) { 1031 bool setError = true; 1032 CalcDimension arrowWidth; 1033 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) { 1034 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) { 1035 popupParam->SetArrowWidth(arrowWidth); 1036 setError = false; 1037 } 1038 } 1039 popupParam->SetErrorArrowWidth(setError); 1040 } 1041 1042 auto arrowHeightVal = popupObj->GetProperty("arrowHeight"); 1043 if (!arrowHeightVal->IsNull()) { 1044 bool setError = true; 1045 CalcDimension arrowHeight; 1046 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) { 1047 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) { 1048 popupParam->SetArrowHeight(arrowHeight); 1049 setError = false; 1050 } 1051 } 1052 popupParam->SetErrorArrowHeight(setError); 1053 } 1054 1055 auto radiusVal = popupObj->GetProperty("radius"); 1056 if (!radiusVal->IsNull()) { 1057 bool setError = true; 1058 CalcDimension radius; 1059 if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) { 1060 if (radius.Value() >= 0) { 1061 popupParam->SetRadius(radius); 1062 setError = false; 1063 } 1064 } 1065 popupParam->SetErrorRadius(setError); 1066 } 1067 1068 Shadow shadow; 1069 auto shadowVal = popupObj->GetProperty("shadow"); 1070 if (shadowVal->IsObject() || shadowVal->IsNumber()) { 1071 auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow); 1072 if (!ret) { 1073 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow); 1074 } 1075 } else { 1076 JSViewAbstract::GetShadowFromTheme(ShadowStyle::OuterDefaultMD, shadow); 1077 } 1078 popupParam->SetShadow(shadow); 1079 1080 auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle"); 1081 if (blurStyleValue->IsNumber()) { 1082 auto blurStyle = blurStyleValue->ToNumber<int32_t>(); 1083 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) && 1084 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) { 1085 popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle)); 1086 } 1087 } 1088 1089 auto popupTransition = popupObj->GetProperty("transition"); 1090 if (popupTransition->IsObject()) { 1091 popupParam->SetHasTransition(true); 1092 auto obj = JSRef<JSObject>::Cast(popupTransition); 1093 auto effects = ParseChainedTransition(obj, info.GetExecutionContext()); 1094 popupParam->SetTransitionEffects(effects); 1095 } 1096 } 1097 ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1098 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam) 1099 { 1100 ParsePopupCommonParam(info, popupObj, popupParam); 1101 JSRef<JSVal> messageVal = popupObj->GetProperty("message"); 1102 if (popupParam) { 1103 popupParam->SetMessage(messageVal->ToString()); 1104 } 1105 1106 auto messageOptions = popupObj->GetProperty("messageOptions"); 1107 JSRef<JSObject> messageOptionsObj; 1108 if (!messageOptions->IsNull() && messageOptions->IsObject()) { 1109 messageOptionsObj = JSRef<JSObject>::Cast(messageOptions); 1110 SetPopupMessageOptions(messageOptionsObj, popupParam); 1111 } 1112 1113 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton"); 1114 if (primaryButtonVal->IsObject()) { 1115 ButtonProperties properties; 1116 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal); 1117 JSRef<JSVal> value = obj->GetProperty("value"); 1118 if (value->IsString()) { 1119 properties.value = value->ToString(); 1120 } 1121 1122 JSRef<JSVal> actionValue = obj->GetProperty("action"); 1123 if (actionValue->IsFunction()) { 1124 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue)); 1125 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 1126 if (popupParam) { 1127 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), 1128 node = targetNode](GestureEvent& info) { 1129 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 1130 ACE_SCORING_EVENT("primaryButton.action"); 1131 PipelineContext::SetCallBackNode(node); 1132 func->Execute(info); 1133 }; 1134 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback); 1135 } 1136 } 1137 properties.showButton = true; 1138 if (popupParam) { 1139 popupParam->SetPrimaryButtonProperties(properties); 1140 } 1141 } 1142 1143 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton"); 1144 if (secondaryButtonVal->IsObject()) { 1145 ButtonProperties properties; 1146 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal); 1147 JSRef<JSVal> value = obj->GetProperty("value"); 1148 if (value->IsString()) { 1149 properties.value = value->ToString(); 1150 } 1151 1152 JSRef<JSVal> actionValue = obj->GetProperty("action"); 1153 if (actionValue->IsFunction()) { 1154 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue)); 1155 auto targetNode = 1156 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 1157 if (popupParam) { 1158 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), 1159 node = targetNode](GestureEvent& info) { 1160 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 1161 ACE_SCORING_EVENT("secondaryButton.action"); 1162 PipelineContext::SetCallBackNode(node); 1163 func->Execute(info); 1164 }; 1165 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback); 1166 } 1167 } 1168 properties.showButton = true; 1169 if (popupParam) { 1170 popupParam->SetSecondaryButtonProperties(properties); 1171 } 1172 } 1173 } 1174 ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1175 void ParseCustomPopupParam( 1176 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam) 1177 { 1178 auto builderValue = popupObj->GetProperty("builder"); 1179 if (!builderValue->IsObject()) { 1180 return; 1181 } 1182 if (!builderValue->IsFunction()) { 1183 JSRef<JSObject> builderObj; 1184 builderObj = JSRef<JSObject>::Cast(builderValue); 1185 auto builder = builderObj->GetProperty("builder"); 1186 if (!builder->IsFunction()) { 1187 return; 1188 } 1189 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 1190 if (!builderFunc) { 1191 return; 1192 } 1193 } 1194 if (popupParam) { 1195 popupParam->SetUseCustomComponent(true); 1196 } 1197 1198 auto focusableValue = popupObj->GetProperty("focusable"); 1199 if (focusableValue->IsBoolean()) { 1200 popupParam->SetFocusable(focusableValue->ToBoolean()); 1201 } 1202 1203 ParsePopupCommonParam(info, popupObj, popupParam); 1204 } 1205 #endif 1206 GetBundleNameFromContainer()1207 std::string GetBundleNameFromContainer() 1208 { 1209 auto container = Container::Current(); 1210 CHECK_NULL_RETURN(container, ""); 1211 return container->GetBundleName(); 1212 } 1213 GetModuleNameFromContainer()1214 std::string GetModuleNameFromContainer() 1215 { 1216 auto container = Container::Current(); 1217 CHECK_NULL_RETURN(container, ""); 1218 return container->GetModuleName(); 1219 } 1220 CompleteResourceObjectFromParams(int32_t resId,JSRef<JSObject> & jsObj,std::string & targetModule,ResourceType & resType,std::string & resName)1221 void CompleteResourceObjectFromParams( 1222 int32_t resId, JSRef<JSObject>& jsObj, std::string& targetModule, ResourceType& resType, std::string& resName) 1223 { 1224 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)); 1225 int32_t typeNum = -1; 1226 if (type->IsNumber()) { 1227 typeNum = type->ToNumber<int32_t>(); 1228 } 1229 1230 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS)); 1231 if (!args->IsArray()) { 1232 return; 1233 } 1234 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 1235 if (resId != UNKNOWN_RESOURCE_ID) { 1236 return; 1237 } 1238 JSRef<JSVal> identity = params->GetValueAt(0); 1239 1240 bool isParseDollarResourceSuccess = 1241 JSViewAbstract::ParseDollarResource(identity, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE); 1242 if (!isParseDollarResourceSuccess) { 1243 return; 1244 } 1245 1246 std::regex resNameRegex(RESOURCE_NAME_PATTERN); 1247 std::smatch resNameResults; 1248 if (std::regex_match(targetModule, resNameResults, resNameRegex)) { 1249 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), resNameResults[1]); 1250 } 1251 1252 if (typeNum == UNKNOWN_RESOURCE_TYPE) { 1253 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType)); 1254 } 1255 } 1256 CompleteResourceObjectFromId(JSRef<JSVal> & type,JSRef<JSObject> & jsObj,ResourceType & resType,const std::string & resName)1257 void CompleteResourceObjectFromId( 1258 JSRef<JSVal>& type, JSRef<JSObject>& jsObj, ResourceType& resType, const std::string& resName) 1259 { 1260 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS)); 1261 if (!args->IsArray()) { 1262 return; 1263 } 1264 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 1265 auto paramCount = params->Length(); 1266 JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(resName)); 1267 if (resType == ResourceType::PLURAL || resType == ResourceType::STRING) { 1268 std::vector<JSRef<JSVal>> tmpParams; 1269 for (uint32_t i = 0; i < paramCount; i++) { 1270 auto param = params->GetValueAt(i); 1271 tmpParams.insert(tmpParams.end(), param); 1272 } 1273 params->SetValueAt(0, name); 1274 uint32_t paramIndex = 1; 1275 if (!type->IsEmpty()) { 1276 params->SetValueAt(paramIndex, type); 1277 paramIndex++; 1278 } 1279 for (auto tmpParam : tmpParams) { 1280 params->SetValueAt(paramIndex, tmpParam); 1281 paramIndex++; 1282 } 1283 } else { 1284 params->SetValueAt(0, name); 1285 } 1286 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::ID), UNKNOWN_RESOURCE_ID); 1287 jsObj->SetProperty<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), static_cast<int32_t>(resType)); 1288 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME))) { 1289 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), ""); 1290 } 1291 if (!jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME))) { 1292 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), ""); 1293 } 1294 } 1295 CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent,bool notNegative)1296 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent, bool notNegative) 1297 { 1298 if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) { 1299 checkDimension.Reset(); 1300 return; 1301 } 1302 if (notNegative && checkDimension.IsNegative()) { 1303 checkDimension.Reset(); 1304 return; 1305 } 1306 } 1307 ParseEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1308 void ParseEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor) 1309 { 1310 Color left; 1311 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left)) { 1312 commonColor.left = left; 1313 } 1314 Color right; 1315 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right)) { 1316 commonColor.right = right; 1317 } 1318 Color top; 1319 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) { 1320 commonColor.top = top; 1321 } 1322 Color bottom; 1323 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) { 1324 commonColor.bottom = bottom; 1325 } 1326 } 1327 ParseLocalizedEdgeColors(const JSRef<JSObject> & object,LocalizedColor & localizedColor)1328 void ParseLocalizedEdgeColors(const JSRef<JSObject>& object, LocalizedColor& localizedColor) 1329 { 1330 Color start; 1331 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)), start)) { 1332 localizedColor.start = start; 1333 } 1334 Color end; 1335 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)), end)) { 1336 localizedColor.end = end; 1337 } 1338 Color top; 1339 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top)) { 1340 localizedColor.top = top; 1341 } 1342 Color bottom; 1343 if (JSViewAbstract::ParseJsColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom)) { 1344 localizedColor.bottom = bottom; 1345 } 1346 } 1347 ParseCommonEdgeColors(const JSRef<JSObject> & object,CommonColor & commonColor)1348 bool ParseCommonEdgeColors(const JSRef<JSObject>& object, CommonColor& commonColor) 1349 { 1350 if (object->HasProperty(static_cast<int32_t>(ArkUIIndex::START)) || 1351 object->HasProperty(static_cast<int32_t>(ArkUIIndex::END))) { 1352 LocalizedColor localizedColor; 1353 ParseLocalizedEdgeColors(object, localizedColor); 1354 commonColor.top = localizedColor.top; 1355 commonColor.bottom = localizedColor.bottom; 1356 commonColor.left = localizedColor.start; 1357 commonColor.right = localizedColor.end; 1358 return true; 1359 } 1360 ParseEdgeColors(object, commonColor); 1361 return false; 1362 } 1363 ParseEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1364 void ParseEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative) 1365 { 1366 CalcDimension left; 1367 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(LEFT_PROPERTY), left)) { 1368 CheckDimensionUnit(left, true, notNegative); 1369 commonCalcDimension.left = left; 1370 } 1371 CalcDimension right; 1372 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(RIGHT_PROPERTY), right)) { 1373 CheckDimensionUnit(right, true, notNegative); 1374 commonCalcDimension.right = right; 1375 } 1376 CalcDimension top; 1377 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(TOP_PROPERTY), top)) { 1378 CheckDimensionUnit(top, true, notNegative); 1379 commonCalcDimension.top = top; 1380 } 1381 CalcDimension bottom; 1382 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty(BOTTOM_PROPERTY), bottom)) { 1383 CheckDimensionUnit(bottom, true, notNegative); 1384 commonCalcDimension.bottom = bottom; 1385 } 1386 } 1387 ParseEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notPercent,bool notNegative,CalcDimension defaultValue)1388 void ParseEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notPercent, 1389 bool notNegative, CalcDimension defaultValue) 1390 { 1391 CalcDimension left; 1392 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(LEFT_PROPERTY), left, true)) { 1393 CheckDimensionUnit(left, notPercent, notNegative); 1394 commonCalcDimension.left = left; 1395 } else { 1396 commonCalcDimension.left = defaultValue; 1397 } 1398 CalcDimension right; 1399 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(RIGHT_PROPERTY), right, true)) { 1400 CheckDimensionUnit(right, notPercent, notNegative); 1401 commonCalcDimension.right = right; 1402 } else { 1403 commonCalcDimension.right = defaultValue; 1404 } 1405 CalcDimension top; 1406 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(TOP_PROPERTY), top, true)) { 1407 CheckDimensionUnit(top, notPercent, notNegative); 1408 commonCalcDimension.top = top; 1409 } else { 1410 commonCalcDimension.top = defaultValue; 1411 } 1412 CalcDimension bottom; 1413 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(BOTTOM_PROPERTY), bottom, true)) { 1414 CheckDimensionUnit(bottom, false, true); 1415 commonCalcDimension.bottom = bottom; 1416 } else { 1417 commonCalcDimension.bottom = defaultValue; 1418 } 1419 } 1420 ParseLocalizedEdgeWidths(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension,bool notNegative)1421 void ParseLocalizedEdgeWidths(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension, 1422 bool notNegative) 1423 { 1424 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)); 1425 if (jsStart->IsObject()) { 1426 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart); 1427 CalcDimension calcDimension; 1428 if (ParseJsLengthMetrics(startObj, calcDimension)) { 1429 CheckDimensionUnit(calcDimension, true, notNegative); 1430 localizedCalcDimension.start = calcDimension; 1431 } 1432 } 1433 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)); 1434 if (jsEnd->IsObject()) { 1435 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd); 1436 CalcDimension calcDimension; 1437 if (ParseJsLengthMetrics(endObj, calcDimension)) { 1438 CheckDimensionUnit(calcDimension, true, notNegative); 1439 localizedCalcDimension.end = calcDimension; 1440 } 1441 } 1442 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)); 1443 if (jsTop->IsObject()) { 1444 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop); 1445 CalcDimension calcDimension; 1446 if (ParseJsLengthMetrics(topObj, calcDimension)) { 1447 CheckDimensionUnit(calcDimension, true, notNegative); 1448 localizedCalcDimension.top = calcDimension; 1449 } 1450 } 1451 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)); 1452 if (jsBottom->IsObject()) { 1453 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom); 1454 CalcDimension calcDimension; 1455 if (ParseJsLengthMetrics(bottomObj, calcDimension)) { 1456 CheckDimensionUnit(calcDimension, true, notNegative); 1457 localizedCalcDimension.bottom = calcDimension; 1458 } 1459 } 1460 } 1461 ParseLocalizedEdgeWidthsProps(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)1462 void ParseLocalizedEdgeWidthsProps(const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension) 1463 { 1464 if (object->HasProperty(START_PROPERTY) && object->GetProperty(START_PROPERTY)->IsObject()) { 1465 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(START_PROPERTY)); 1466 CalcDimension calcDimension; 1467 if (ParseJsLengthMetrics(startObj, calcDimension)) { 1468 CheckDimensionUnit(calcDimension, false, true); 1469 localizedCalcDimension.start = calcDimension; 1470 } 1471 } 1472 if (object->HasProperty(END_PROPERTY) && object->GetProperty(END_PROPERTY)->IsObject()) { 1473 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(object->GetProperty(END_PROPERTY)); 1474 CalcDimension calcDimension; 1475 if (ParseJsLengthMetrics(endObj, calcDimension)) { 1476 CheckDimensionUnit(calcDimension, false, true); 1477 localizedCalcDimension.end = calcDimension; 1478 } 1479 } 1480 if (object->HasProperty(TOP_PROPERTY) && object->GetProperty(TOP_PROPERTY)->IsObject()) { 1481 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_PROPERTY)); 1482 CalcDimension calcDimension; 1483 if (ParseJsLengthMetrics(topObj, calcDimension)) { 1484 CheckDimensionUnit(calcDimension, false, true); 1485 localizedCalcDimension.top = calcDimension; 1486 } 1487 } 1488 if (object->HasProperty(BOTTOM_PROPERTY) && object->GetProperty(BOTTOM_PROPERTY)->IsObject()) { 1489 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_PROPERTY)); 1490 CalcDimension calcDimension; 1491 if (ParseJsLengthMetrics(bottomObj, calcDimension)) { 1492 CheckDimensionUnit(calcDimension, false, true); 1493 localizedCalcDimension.bottom = calcDimension; 1494 } 1495 } 1496 } 1497 ParseCommonEdgeWidths(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension,bool notNegative)1498 bool ParseCommonEdgeWidths(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension, bool notNegative) 1499 { 1500 if (CheckLengthMetrics(object)) { 1501 LocalizedCalcDimension localizedCalcDimension; 1502 ParseLocalizedEdgeWidths(object, localizedCalcDimension, notNegative); 1503 commonCalcDimension.top = localizedCalcDimension.top; 1504 commonCalcDimension.bottom = localizedCalcDimension.bottom; 1505 commonCalcDimension.left = localizedCalcDimension.start; 1506 commonCalcDimension.right = localizedCalcDimension.end; 1507 return true; 1508 } 1509 ParseEdgeWidths(object, commonCalcDimension, notNegative); 1510 return false; 1511 } 1512 ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1513 void ParseCommonEdgeWidthsForDashParams(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension) 1514 { 1515 if (CheckLengthMetrics(object)) { 1516 LocalizedCalcDimension localizedCalcDimension; 1517 ParseLocalizedEdgeWidths(object, localizedCalcDimension, false); 1518 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft(); 1519 commonCalcDimension.top = localizedCalcDimension.top; 1520 commonCalcDimension.bottom = localizedCalcDimension.bottom; 1521 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start; 1522 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end; 1523 return; 1524 } 1525 ParseEdgeWidthsProps(object, commonCalcDimension, true, false, static_cast<CalcDimension>(-1)); 1526 } 1527 ParseCommonEdgeWidthsProps(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)1528 void ParseCommonEdgeWidthsProps(const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension) 1529 { 1530 if (CheckLengthMetrics(object)) { 1531 LocalizedCalcDimension localizedCalcDimension; 1532 ParseLocalizedEdgeWidthsProps(object, localizedCalcDimension); 1533 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft(); 1534 commonCalcDimension.top = localizedCalcDimension.top; 1535 commonCalcDimension.bottom = localizedCalcDimension.bottom; 1536 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start; 1537 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end; 1538 return; 1539 } 1540 ParseEdgeWidthsProps(object, commonCalcDimension, false, true, 0.0_vp); 1541 } 1542 ParseTransitionCallback(const JSRef<JSFunc> & jsFunc,const JSExecutionContext & context)1543 std::function<void(bool)> ParseTransitionCallback(const JSRef<JSFunc>& jsFunc, const JSExecutionContext& context) 1544 { 1545 auto jsFuncFinish = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(jsFunc)); 1546 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 1547 auto finishCallback = [execCtx = context, jsFuncFinish, targetNode](bool isTransitionIn) { 1548 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 1549 NG::PipelineContext::SetCallBackNode(targetNode); 1550 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(isTransitionIn)); 1551 jsFuncFinish->ExecuteJS(1, &newJSVal); 1552 }; 1553 return finishCallback; 1554 } 1555 } // namespace 1556 GetResourceObject(const JSRef<JSObject> & jsObj)1557 RefPtr<ResourceObject> GetResourceObject(const JSRef<JSObject>& jsObj) 1558 { 1559 auto id = jsObj->GetProperty("id")->ToNumber<int32_t>(); 1560 auto type = jsObj->GetProperty("type")->ToNumber<int32_t>(); 1561 auto args = jsObj->GetProperty("params"); 1562 1563 std::string bundleName; 1564 std::string moduleName; 1565 auto bundle = jsObj->GetProperty("bundleName"); 1566 auto module = jsObj->GetProperty("moduleName"); 1567 if (bundle->IsString() && module->IsString()) { 1568 bundleName = bundle->ToString(); 1569 moduleName = module->ToString(); 1570 } 1571 if (!args->IsArray()) { 1572 return nullptr; 1573 } 1574 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 1575 std::vector<ResourceObjectParams> resObjParamsList; 1576 auto size = static_cast<int32_t>(params->Length()); 1577 for (int32_t i = 0; i < size; i++) { 1578 auto item = params->GetValueAt(i); 1579 ResourceObjectParams resObjParams { .value = item->ToString().c_str() }; 1580 if (item->IsString()) { 1581 resObjParams.type = ResourceObjectParamType::STRING; 1582 } else if (item->IsNumber()) { 1583 if (std::regex_match(item->ToString(), FLOAT_PATTERN)) { 1584 resObjParams.type = ResourceObjectParamType::FLOAT; 1585 } else { 1586 resObjParams.type = ResourceObjectParamType::INT; 1587 } 1588 } 1589 resObjParamsList.push_back(resObjParams); 1590 } 1591 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(id, type, resObjParamsList, bundleName, moduleName); 1592 return resourceObject; 1593 } 1594 GetResourceObjectByBundleAndModule(const JSRef<JSObject> & jsObj)1595 RefPtr<ResourceObject> GetResourceObjectByBundleAndModule(const JSRef<JSObject>& jsObj) 1596 { 1597 auto bundleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), ""); 1598 auto moduleName = jsObj->GetPropertyValue<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), ""); 1599 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(bundleName, moduleName); 1600 return resourceObject; 1601 } 1602 CreateResourceWrapper(const JSRef<JSObject> & jsObj,RefPtr<ResourceObject> & resourceObject)1603 RefPtr<ResourceWrapper> CreateResourceWrapper(const JSRef<JSObject>& jsObj, RefPtr<ResourceObject>& resourceObject) 1604 { 1605 RefPtr<ResourceAdapter> resourceAdapter = nullptr; 1606 RefPtr<ThemeConstants> themeConstants = nullptr; 1607 if (SystemProperties::GetResourceDecoupling()) { 1608 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resourceObject); 1609 if (!resourceAdapter) { 1610 return nullptr; 1611 } 1612 } else { 1613 themeConstants = JSViewAbstract::GetThemeConstants(jsObj); 1614 if (!themeConstants) { 1615 return nullptr; 1616 } 1617 } 1618 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter); 1619 return resourceWrapper; 1620 } 1621 CreateResourceWrapper()1622 RefPtr<ResourceWrapper> CreateResourceWrapper() 1623 { 1624 RefPtr<ResourceAdapter> resourceAdapter = nullptr; 1625 RefPtr<ThemeConstants> themeConstants = nullptr; 1626 if (SystemProperties::GetResourceDecoupling()) { 1627 resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(); 1628 if (!resourceAdapter) { 1629 return nullptr; 1630 } 1631 } else { 1632 themeConstants = JSViewAbstract::GetThemeConstants(); 1633 if (!themeConstants) { 1634 return nullptr; 1635 } 1636 } 1637 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter); 1638 return resourceWrapper; 1639 } 1640 ColorAlphaAdapt(uint32_t origin)1641 uint32_t ColorAlphaAdapt(uint32_t origin) 1642 { 1643 uint32_t result = origin; 1644 if (origin >> COLOR_ALPHA_OFFSET == 0) { 1645 result = origin | COLOR_ALPHA_VALUE; 1646 } 1647 return result; 1648 } 1649 JsScale(const JSCallbackInfo & info)1650 void JSViewAbstract::JsScale(const JSCallbackInfo& info) 1651 { 1652 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT }; 1653 auto jsVal = info[0]; 1654 if (!CheckJSCallbackInfo("JsScale", jsVal, checkList)) { 1655 SetDefaultScale(); 1656 return; 1657 } 1658 1659 if (jsVal->IsObject()) { 1660 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal); 1661 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) || 1662 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) || 1663 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) { 1664 // default: x, y, z (1.0, 1.0, 1.0) 1665 auto scaleX = 1.0f; 1666 auto scaleY = 1.0f; 1667 auto scaleZ = 1.0f; 1668 // default centerX, centerY 50% 50%; 1669 CalcDimension centerX = 0.5_pct; 1670 CalcDimension centerY = 0.5_pct; 1671 ParseJsScale(jsVal, scaleX, scaleY, scaleZ, centerX, centerY); 1672 ViewAbstractModel::GetInstance()->SetScale(scaleX, scaleY, scaleZ); 1673 ViewAbstractModel::GetInstance()->SetPivot(centerX, centerY, 0.0_vp); 1674 return; 1675 } else { 1676 SetDefaultScale(); 1677 } 1678 } 1679 double scale = 0.0; 1680 if (ParseJsDouble(jsVal, scale)) { 1681 ViewAbstractModel::GetInstance()->SetScale(scale, scale, 1.0f); 1682 } 1683 } 1684 SetDefaultScale()1685 void JSViewAbstract::SetDefaultScale() 1686 { 1687 ViewAbstractModel::GetInstance()->SetScale(1.0f, 1.0f, 1.0f); 1688 ViewAbstractModel::GetInstance()->SetPivot(0.5_pct, 0.5_pct, 0.0_vp); 1689 } 1690 JsScaleX(const JSCallbackInfo & info)1691 void JSViewAbstract::JsScaleX(const JSCallbackInfo& info) 1692 { 1693 double scaleVal = 0.0; 1694 if (!ParseJsDouble(info[0], scaleVal)) { 1695 return; 1696 } 1697 ViewAbstractModel::GetInstance()->SetScale(scaleVal, 1.0f, 1.0f); 1698 } 1699 JsScaleY(const JSCallbackInfo & info)1700 void JSViewAbstract::JsScaleY(const JSCallbackInfo& info) 1701 { 1702 double scaleVal = 0.0; 1703 if (!ParseJsDouble(info[0], scaleVal)) { 1704 return; 1705 } 1706 ViewAbstractModel::GetInstance()->SetScale(1.0f, scaleVal, 1.0f); 1707 } 1708 JsOpacity(const JSCallbackInfo & info)1709 void JSViewAbstract::JsOpacity(const JSCallbackInfo& info) 1710 { 1711 double opacity = 0.0; 1712 if (!ParseJsDouble(info[0], opacity)) { 1713 ViewAbstractModel::GetInstance()->SetOpacity(1.0f); 1714 return; 1715 } 1716 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_ELEVEN)) { 1717 opacity = std::clamp(opacity, 0.0, 1.0); 1718 } else { 1719 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) { 1720 opacity = 1.0; 1721 } 1722 } 1723 ViewAbstractModel::GetInstance()->SetOpacity(opacity); 1724 } 1725 JsTranslate(const JSCallbackInfo & info)1726 void JSViewAbstract::JsTranslate(const JSCallbackInfo& info) 1727 { 1728 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER, 1729 JSCallbackInfoType::OBJECT }; 1730 auto jsVal = info[0]; 1731 if (!CheckJSCallbackInfo("JsTranslate", jsVal, checkList)) { 1732 SetDefaultTranslate(); 1733 return; 1734 } 1735 1736 if (jsVal->IsObject()) { 1737 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal); 1738 if (jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::X)) || 1739 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Y)) || 1740 jsObj->HasProperty(static_cast<int32_t>(ArkUIIndex::Z))) { 1741 // default: x, y, z (0.0, 0.0, 0.0) 1742 auto translateX = CalcDimension(0.0); 1743 auto translateY = CalcDimension(0.0); 1744 auto translateZ = CalcDimension(0.0); 1745 ParseJsTranslate(jsVal, translateX, translateY, translateZ); 1746 ViewAbstractModel::GetInstance()->SetTranslate(translateX, translateY, translateZ); 1747 return; 1748 } else { 1749 SetDefaultTranslate(); 1750 } 1751 } 1752 CalcDimension value; 1753 if (ParseJsDimensionVp(jsVal, value)) { 1754 ViewAbstractModel::GetInstance()->SetTranslate(value, value, value); 1755 } 1756 } 1757 SetDefaultTranslate()1758 void JSViewAbstract::SetDefaultTranslate() 1759 { 1760 ViewAbstractModel::GetInstance()->SetTranslate(CalcDimension(0.0), CalcDimension(0.0), CalcDimension(0.0)); 1761 } 1762 JsTranslateX(const JSCallbackInfo & info)1763 void JSViewAbstract::JsTranslateX(const JSCallbackInfo& info) 1764 { 1765 CalcDimension value; 1766 if (!ParseJsDimensionVp(info[0], value)) { 1767 return; 1768 } 1769 ViewAbstractModel::GetInstance()->SetTranslate(value, 0.0_px, 0.0_px); 1770 } 1771 JsTranslateY(const JSCallbackInfo & info)1772 void JSViewAbstract::JsTranslateY(const JSCallbackInfo& info) 1773 { 1774 CalcDimension value; 1775 if (!ParseJsDimensionVp(info[0], value)) { 1776 return; 1777 } 1778 ViewAbstractModel::GetInstance()->SetTranslate(0.0_px, value, 0.0_px); 1779 } 1780 JsRotate(const JSCallbackInfo & info)1781 void JSViewAbstract::JsRotate(const JSCallbackInfo& info) 1782 { 1783 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT }; 1784 auto jsVal = info[0]; 1785 if (!CheckJSCallbackInfo("JsRotate", jsVal, checkList)) { 1786 SetDefaultRotate(); 1787 return; 1788 } 1789 1790 if (jsVal->IsObject()) { 1791 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct); 1792 std::optional<float> angle; 1793 ParseJsRotate(jsVal, rotate, angle); 1794 if (angle) { 1795 ViewAbstractModel::GetInstance()->SetRotate( 1796 rotate.xDirection, rotate.yDirection, rotate.zDirection, angle.value(), rotate.perspective); 1797 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ); 1798 } else { 1799 SetDefaultRotate(); 1800 } 1801 return; 1802 } 1803 double rotateZ; 1804 if (ParseJsDouble(jsVal, rotateZ)) { 1805 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 0.0f, 1.0f, rotateZ); 1806 } 1807 } 1808 SetDefaultRotate()1809 void JSViewAbstract::SetDefaultRotate() 1810 { 1811 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct, 0.0f, 0.0f); 1812 ViewAbstractModel::GetInstance()->SetRotate( 1813 rotate.xDirection, rotate.yDirection, rotate.zDirection, 0.0f, rotate.perspective); 1814 ViewAbstractModel::GetInstance()->SetPivot(rotate.centerX, rotate.centerY, rotate.centerZ); 1815 } 1816 JsRotateX(const JSCallbackInfo & info)1817 void JSViewAbstract::JsRotateX(const JSCallbackInfo& info) 1818 { 1819 double rotateVal = 0.0; 1820 if (!ParseJsDouble(info[0], rotateVal)) { 1821 return; 1822 } 1823 ViewAbstractModel::GetInstance()->SetRotate(1.0f, 0.0f, 0.0f, rotateVal); 1824 } 1825 JsRotateY(const JSCallbackInfo & info)1826 void JSViewAbstract::JsRotateY(const JSCallbackInfo& info) 1827 { 1828 double rotateVal = 0.0; 1829 if (!ParseJsDouble(info[0], rotateVal)) { 1830 return; 1831 } 1832 ViewAbstractModel::GetInstance()->SetRotate(0.0f, 1.0f, 0.0f, rotateVal); 1833 } 1834 JsTransform(const JSCallbackInfo & info)1835 void JSViewAbstract::JsTransform(const JSCallbackInfo& info) 1836 { 1837 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 1838 auto jsVal = info[0]; 1839 if (!CheckJSCallbackInfo("JsTransform", jsVal, checkList)) { 1840 SetDefaultTransform(); 1841 return; 1842 } 1843 JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4)); 1844 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION; 1845 if (!array->IsArray()) { 1846 return; 1847 } 1848 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array); 1849 if (jsArray->Length() != matrix4Len) { 1850 return; 1851 } 1852 std::vector<float> matrix(matrix4Len); 1853 for (int32_t i = 0; i < matrix4Len; i++) { 1854 double value = 0.0; 1855 ParseJsDouble(jsArray->GetValueAt(i), value); 1856 matrix[i] = static_cast<float>(value); 1857 } 1858 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix); 1859 } 1860 SetDefaultTransform()1861 void JSViewAbstract::SetDefaultTransform() 1862 { 1863 const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION; 1864 std::vector<float> matrix(matrix4Len); 1865 const int32_t initPosition = 5; 1866 for (int32_t i = 0; i < matrix4Len; i = i + initPosition) { 1867 double value = 1.0; 1868 matrix[i] = static_cast<float>(value); 1869 } 1870 ViewAbstractModel::GetInstance()->SetTransformMatrix(matrix); 1871 } 1872 ParseJsTransition(const JSRef<JSObject> & jsObj)1873 NG::TransitionOptions JSViewAbstract::ParseJsTransition(const JSRef<JSObject>& jsObj) 1874 { 1875 NG::TransitionOptions transitionOption; 1876 bool hasEffect = false; 1877 transitionOption.Type = ParseTransitionType(jsObj->GetPropertyValue<std::string>("type", "All")); 1878 if (jsObj->HasProperty("opacity")) { 1879 double opacity = 1.0; 1880 ParseJsDouble(jsObj->GetProperty("opacity"), opacity); 1881 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) { 1882 if (opacity > 1.0 || LessNotEqual(opacity, 0.0)) { 1883 opacity = 1.0; 1884 } 1885 } else { 1886 opacity = std::clamp(opacity, 0.0, 1.0); 1887 } 1888 transitionOption.UpdateOpacity(static_cast<float>(opacity)); 1889 hasEffect = true; 1890 } 1891 if (jsObj->HasProperty("translate")) { 1892 // default: x, y, z (0.0, 0.0, 0.0) 1893 NG::TranslateOptions translate; 1894 ParseJsTranslate(jsObj->GetProperty("translate"), translate.x, translate.y, translate.z); 1895 transitionOption.UpdateTranslate(translate); 1896 hasEffect = true; 1897 } 1898 if (jsObj->HasProperty("scale")) { 1899 // default: x, y, z (1.0, 1.0, 1.0), centerX, centerY 50% 50%; 1900 NG::ScaleOptions scale(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct); 1901 ParseJsScale(jsObj->GetProperty("scale"), scale.xScale, scale.yScale, scale.zScale, 1902 scale.centerX, scale.centerY); 1903 transitionOption.UpdateScale(scale); 1904 hasEffect = true; 1905 } 1906 if (jsObj->HasProperty("rotate")) { 1907 // default: dx, dy, dz (0.0, 0.0, 0.0), angle 0, centerX, centerY 50% 50%; 1908 NG::RotateOptions rotate(0.0f, 0.0f, 0.0f, 0.0f, 0.5_pct, 0.5_pct); 1909 std::optional<float> angle; 1910 ParseJsRotate(jsObj->GetProperty("rotate"), rotate, angle); 1911 if (angle.has_value()) { 1912 rotate.angle = angle.value(); 1913 transitionOption.UpdateRotate(rotate); 1914 hasEffect = true; 1915 } 1916 } 1917 if (!hasEffect) { 1918 // default transition 1919 transitionOption = NG::TransitionOptions::GetDefaultTransition(transitionOption.Type); 1920 } 1921 return transitionOption; 1922 } 1923 ParseJsTransitionEffect(const JSCallbackInfo & info)1924 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseJsTransitionEffect(const JSCallbackInfo& info) 1925 { 1926 JSRef<JSVal> arg = info[0]; 1927 if (!arg->IsObject()) { 1928 return nullptr; 1929 } 1930 auto obj = JSRef<JSObject>::Cast(arg); 1931 auto transitionVal = obj->GetProperty("transition"); 1932 1933 if (!transitionVal->IsObject()) { 1934 return nullptr; 1935 } 1936 1937 auto transitionObj = JSRef<JSObject>::Cast(transitionVal); 1938 auto chainedEffect = ParseChainedTransition(transitionObj, info.GetExecutionContext()); 1939 return chainedEffect; 1940 } 1941 ParseNapiChainedTransition(const JSRef<JSObject> & object,const JSExecutionContext & context)1942 RefPtr<NG::ChainedTransitionEffect> JSViewAbstract::ParseNapiChainedTransition(const JSRef<JSObject>& object, 1943 const JSExecutionContext& context) 1944 { 1945 auto chainedEffect = ParseChainedTransition(object, context); 1946 return chainedEffect; 1947 } 1948 JsTransition(const JSCallbackInfo & info)1949 void JSViewAbstract::JsTransition(const JSCallbackInfo& info) 1950 { 1951 if (info.Length() < 1 || !info[0]->IsObject()) { 1952 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 1953 ViewAbstractModel::GetInstance()->CleanTransition(); 1954 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr); 1955 } 1956 return; 1957 } 1958 auto obj = JSRef<JSObject>::Cast(info[0]); 1959 if (!obj->GetProperty("successor_")->IsUndefined()) { 1960 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext()); 1961 std::function<void(bool)> finishCallback; 1962 if (info.Length() > 1 && info[1]->IsFunction()) { 1963 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext()); 1964 } 1965 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback)); 1966 return; 1967 } 1968 auto options = ParseJsTransition(obj); 1969 ViewAbstractModel::GetInstance()->SetTransition(options); 1970 } 1971 JsWidth(const JSCallbackInfo & info)1972 void JSViewAbstract::JsWidth(const JSCallbackInfo& info) 1973 { 1974 JsWidth(info[0]); 1975 } 1976 JsWidth(const JSRef<JSVal> & jsValue)1977 bool JSViewAbstract::JsWidth(const JSRef<JSVal>& jsValue) 1978 { 1979 CalcDimension value; 1980 if (jsValue->IsUndefined()) { 1981 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true); 1982 return true; 1983 } 1984 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 1985 if (!ParseJsDimensionVpNG(jsValue, value)) { 1986 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true); 1987 return false; 1988 } 1989 } else if (!ParseJsDimensionVp(jsValue, value)) { 1990 return false; 1991 } 1992 1993 if (LessNotEqual(value.Value(), 0.0)) { 1994 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 1995 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(true); 1996 return true; 1997 } else { 1998 value.SetValue(0.0); 1999 } 2000 } 2001 2002 ViewAbstractModel::GetInstance()->SetWidth(value); 2003 return true; 2004 } 2005 JsHeight(const JSCallbackInfo & info)2006 void JSViewAbstract::JsHeight(const JSCallbackInfo& info) 2007 { 2008 JsHeight(info[0]); 2009 } 2010 JsHeight(const JSRef<JSVal> & jsValue)2011 bool JSViewAbstract::JsHeight(const JSRef<JSVal>& jsValue) 2012 { 2013 CalcDimension value; 2014 if (jsValue->IsUndefined()) { 2015 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false); 2016 return true; 2017 } 2018 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 2019 if (!ParseJsDimensionVpNG(jsValue, value)) { 2020 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false); 2021 return false; 2022 } 2023 } else if (!ParseJsDimensionVp(jsValue, value)) { 2024 return false; 2025 } 2026 2027 if (LessNotEqual(value.Value(), 0.0)) { 2028 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 2029 ViewAbstractModel::GetInstance()->ClearWidthOrHeight(false); 2030 return true; 2031 } else { 2032 value.SetValue(0.0); 2033 } 2034 } 2035 2036 ViewAbstractModel::GetInstance()->SetHeight(value); 2037 return true; 2038 } 2039 JsResponseRegion(const JSCallbackInfo & info)2040 void JSViewAbstract::JsResponseRegion(const JSCallbackInfo& info) 2041 { 2042 std::vector<DimensionRect> result; 2043 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) { 2044 ViewAbstractModel::GetInstance()->SetResponseRegion({}); 2045 return; 2046 } 2047 2048 ViewAbstractModel::GetInstance()->SetResponseRegion(result); 2049 } 2050 JsMouseResponseRegion(const JSCallbackInfo & info)2051 void JSViewAbstract::JsMouseResponseRegion(const JSCallbackInfo& info) 2052 { 2053 std::vector<DimensionRect> result; 2054 if (!JSViewAbstract::ParseJsResponseRegionArray(info[0], result)) { 2055 ViewAbstractModel::GetInstance()->SetMouseResponseRegion({}); 2056 return; 2057 } 2058 ViewAbstractModel::GetInstance()->SetMouseResponseRegion(result); 2059 } 2060 ParseJsDimensionRect(const JSRef<JSVal> & jsValue,DimensionRect & result)2061 bool JSViewAbstract::ParseJsDimensionRect(const JSRef<JSVal>& jsValue, DimensionRect& result) 2062 { 2063 result.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP))); 2064 result.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT))); 2065 if (!jsValue->IsObject()) { 2066 return true; 2067 } 2068 2069 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue); 2070 JSRef<JSVal> x = obj->GetProperty("x"); 2071 JSRef<JSVal> y = obj->GetProperty("y"); 2072 JSRef<JSVal> width = obj->GetProperty("width"); 2073 JSRef<JSVal> height = obj->GetProperty("height"); 2074 CalcDimension xDimen = result.GetOffset().GetX(); 2075 CalcDimension yDimen = result.GetOffset().GetY(); 2076 CalcDimension widthDimen = result.GetWidth(); 2077 CalcDimension heightDimen = result.GetHeight(); 2078 auto s1 = width->ToString(); 2079 auto s2 = height->ToString(); 2080 if (s1.find('-') != std::string::npos) { 2081 width = JSRef<JSVal>::Make(ToJSValue("100%")); 2082 } 2083 if (s2.find('-') != std::string::npos) { 2084 height = JSRef<JSVal>::Make(ToJSValue("100%")); 2085 } 2086 if (ParseJsDimensionNG(x, xDimen, DimensionUnit::VP)) { 2087 auto offset = result.GetOffset(); 2088 offset.SetX(xDimen); 2089 result.SetOffset(offset); 2090 } 2091 if (ParseJsDimensionNG(y, yDimen, DimensionUnit::VP)) { 2092 auto offset = result.GetOffset(); 2093 offset.SetY(yDimen); 2094 result.SetOffset(offset); 2095 } 2096 if (ParseJsDimensionNG(width, widthDimen, DimensionUnit::VP)) { 2097 if (widthDimen.Unit() == DimensionUnit::PERCENT && widthDimen.Value() < 0) { 2098 return true; 2099 } 2100 result.SetWidth(widthDimen); 2101 } 2102 if (ParseJsDimensionNG(height, heightDimen, DimensionUnit::VP)) { 2103 if (heightDimen.Unit() == DimensionUnit::PERCENT && heightDimen.Value() < 0) { 2104 return true; 2105 } 2106 result.SetHeight(heightDimen); 2107 } 2108 return true; 2109 } 2110 ParseJsResponseRegionArray(const JSRef<JSVal> & jsValue,std::vector<DimensionRect> & result)2111 bool JSViewAbstract::ParseJsResponseRegionArray(const JSRef<JSVal>& jsValue, std::vector<DimensionRect>& result) 2112 { 2113 if (!jsValue->IsArray() && !jsValue->IsObject()) { 2114 return false; 2115 } 2116 2117 if (jsValue->IsArray()) { 2118 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue); 2119 for (size_t i = 0; i < array->Length(); i++) { 2120 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP); 2121 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP); 2122 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT); 2123 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT); 2124 DimensionOffset offsetDimen(xDimen, yDimen); 2125 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen); 2126 if (ParseJsDimensionRect(array->GetValueAt(i), dimenRect)) { 2127 result.emplace_back(dimenRect); 2128 } else { 2129 return false; 2130 } 2131 } 2132 return true; 2133 } 2134 2135 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP); 2136 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP); 2137 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT); 2138 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT); 2139 DimensionOffset offsetDimen(xDimen, yDimen); 2140 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen); 2141 if (ParseJsDimensionRect(jsValue, dimenRect)) { 2142 result.emplace_back(dimenRect); 2143 return true; 2144 } else { 2145 return false; 2146 } 2147 } 2148 JsSize(const JSCallbackInfo & info)2149 void JSViewAbstract::JsSize(const JSCallbackInfo& info) 2150 { 2151 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 2152 auto jsVal = info[0]; 2153 if (!CheckJSCallbackInfo("JsSize", jsVal, checkList)) { 2154 return; 2155 } 2156 2157 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal); 2158 JsWidth(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH))); 2159 JsHeight(sizeObj->GetProperty(static_cast<int32_t>(ArkUIIndex::HEIGHT))); 2160 } 2161 JsConstraintSize(const JSCallbackInfo & info)2162 void JSViewAbstract::JsConstraintSize(const JSCallbackInfo& info) 2163 { 2164 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 2165 auto jsVal = info[0]; 2166 if (!CheckJSCallbackInfo("JsConstraintSize", jsVal, checkList)) { 2167 ViewAbstractModel::GetInstance()->ResetMaxSize(true); 2168 ViewAbstractModel::GetInstance()->ResetMinSize(true); 2169 ViewAbstractModel::GetInstance()->ResetMaxSize(false); 2170 ViewAbstractModel::GetInstance()->ResetMinSize(false); 2171 return; 2172 } 2173 2174 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal); 2175 2176 JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth"); 2177 CalcDimension minWidth; 2178 JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth"); 2179 CalcDimension maxWidth; 2180 JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight"); 2181 CalcDimension minHeight; 2182 JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight"); 2183 CalcDimension maxHeight; 2184 bool version10OrLarger = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN); 2185 if (ParseJsDimensionVp(minWidthValue, minWidth)) { 2186 ViewAbstractModel::GetInstance()->SetMinWidth(minWidth); 2187 } else if (version10OrLarger) { 2188 ViewAbstractModel::GetInstance()->ResetMinSize(true); 2189 } 2190 2191 if (ParseJsDimensionVp(maxWidthValue, maxWidth)) { 2192 ViewAbstractModel::GetInstance()->SetMaxWidth(maxWidth); 2193 } else if (version10OrLarger) { 2194 ViewAbstractModel::GetInstance()->ResetMaxSize(true); 2195 } 2196 2197 if (ParseJsDimensionVp(minHeightValue, minHeight)) { 2198 ViewAbstractModel::GetInstance()->SetMinHeight(minHeight); 2199 } else if (version10OrLarger) { 2200 ViewAbstractModel::GetInstance()->ResetMinSize(false); 2201 } 2202 2203 if (ParseJsDimensionVp(maxHeightValue, maxHeight)) { 2204 ViewAbstractModel::GetInstance()->SetMaxHeight(maxHeight); 2205 } else if (version10OrLarger) { 2206 ViewAbstractModel::GetInstance()->ResetMaxSize(false); 2207 } 2208 } 2209 JsLayoutPriority(const JSCallbackInfo & info)2210 void JSViewAbstract::JsLayoutPriority(const JSCallbackInfo& info) 2211 { 2212 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER }; 2213 auto jsVal = info[0]; 2214 if (!CheckJSCallbackInfo("JsLayoutPriority", jsVal, checkList)) { 2215 return; 2216 } 2217 2218 int32_t priority; 2219 if (jsVal->IsNumber()) { 2220 priority = jsVal->ToNumber<int32_t>(); 2221 } else { 2222 priority = static_cast<int32_t>(StringUtils::StringToUint(jsVal->ToString())); 2223 } 2224 ViewAbstractModel::GetInstance()->SetLayoutPriority(priority); 2225 } 2226 JsPixelRound(const JSCallbackInfo & info)2227 void JSViewAbstract::JsPixelRound(const JSCallbackInfo& info) 2228 { 2229 uint16_t value = 0; 2230 JSRef<JSVal> arg = info[0]; 2231 if (!arg->IsObject()) { 2232 return; 2233 } 2234 JSRef<JSObject> object = JSRef<JSObject>::Cast(arg); 2235 JSRef<JSVal> jsStartValue = object->GetProperty("start"); 2236 if (jsStartValue->IsNumber()) { 2237 int32_t startValue = jsStartValue->ToNumber<int32_t>(); 2238 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(startValue)) { 2239 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_START); 2240 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(startValue)) { 2241 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_START); 2242 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(startValue)) { 2243 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_START); 2244 } 2245 } 2246 JSRef<JSVal> jsTopValue = object->GetProperty("top"); 2247 if (jsTopValue->IsNumber()) { 2248 int32_t topValue = jsTopValue->ToNumber<int32_t>(); 2249 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(topValue)) { 2250 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_TOP); 2251 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(topValue)) { 2252 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_TOP); 2253 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(topValue)) { 2254 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_TOP); 2255 } 2256 } 2257 JSRef<JSVal> jsEndValue = object->GetProperty("end"); 2258 if (jsEndValue->IsNumber()) { 2259 int32_t endValue = jsEndValue->ToNumber<int32_t>(); 2260 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(endValue)) { 2261 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_END); 2262 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(endValue)) { 2263 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_END); 2264 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(endValue)) { 2265 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_END); 2266 } 2267 } 2268 JSRef<JSVal> jsBottomValue = object->GetProperty("bottom"); 2269 if (jsBottomValue->IsNumber()) { 2270 int32_t bottomValue = jsBottomValue->ToNumber<int32_t>(); 2271 if (PixelRoundCalcPolicy::FORCE_CEIL == static_cast<PixelRoundCalcPolicy>(bottomValue)) { 2272 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM); 2273 } else if (PixelRoundCalcPolicy::FORCE_FLOOR == static_cast<PixelRoundCalcPolicy>(bottomValue)) { 2274 value |= static_cast<uint16_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM); 2275 } else if (PixelRoundCalcPolicy::NO_FORCE_ROUND == static_cast<PixelRoundCalcPolicy>(bottomValue)) { 2276 value |= static_cast<uint16_t>(PixelRoundPolicy::NO_FORCE_ROUND_BOTTOM); 2277 } 2278 } 2279 ViewAbstractModel::GetInstance()->SetPixelRound(value); 2280 } 2281 JsLayoutWeight(const JSCallbackInfo & info)2282 void JSViewAbstract::JsLayoutWeight(const JSCallbackInfo& info) 2283 { 2284 float value = 0.0f; 2285 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER }; 2286 auto jsVal = info[0]; 2287 if (!CheckJSCallbackInfo("JsLayoutWeight", jsVal, checkList)) { 2288 if (!jsVal->IsUndefined()) { 2289 return; 2290 } 2291 } 2292 2293 if (jsVal->IsNumber()) { 2294 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 2295 value = jsVal->ToNumber<float>(); 2296 } else { 2297 value = jsVal->ToNumber<int32_t>(); 2298 } 2299 } else { 2300 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 2301 value = static_cast<float>(StringUtils::StringToUintCheck(jsVal->ToString())); 2302 } else { 2303 value = static_cast<int32_t>(StringUtils::StringToUintCheck(jsVal->ToString())); 2304 } 2305 } 2306 2307 ViewAbstractModel::GetInstance()->SetLayoutWeight(value); 2308 } 2309 JsChainWeight(const JSCallbackInfo & info)2310 void JSViewAbstract::JsChainWeight(const JSCallbackInfo& info) 2311 { 2312 NG::LayoutWeightPair layoutWeightPair(DEFAULT_LAYOUT_WEIGHT, DEFAULT_LAYOUT_WEIGHT); 2313 auto jsVal = info[0]; 2314 if (jsVal->IsObject()) { 2315 JSRef<JSObject> val = JSRef<JSObject>::Cast(jsVal); 2316 auto weightX = val->GetProperty("horizontal"); 2317 auto weightY = val->GetProperty("vertical"); 2318 if (weightX->IsNumber()) { 2319 layoutWeightPair.first = weightX->ToNumber<float>(); 2320 } 2321 if (weightY->IsNumber()) { 2322 layoutWeightPair.second = weightY->ToNumber<float>(); 2323 } 2324 } 2325 ViewAbstractModel::GetInstance()->SetLayoutWeight(layoutWeightPair); 2326 } 2327 JsAlign(const JSCallbackInfo & info)2328 void JSViewAbstract::JsAlign(const JSCallbackInfo& info) 2329 { 2330 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER }; 2331 auto jsVal = info[0]; 2332 if (!CheckJSCallbackInfo("JsAlign", jsVal, checkList) && 2333 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 2334 ViewAbstractModel::GetInstance()->SetAlign(Alignment::CENTER); 2335 return; 2336 } 2337 auto value = jsVal->ToNumber<int32_t>(); 2338 Alignment alignment = ParseAlignment(value); 2339 ViewAbstractModel::GetInstance()->SetAlign(alignment); 2340 } 2341 JsPosition(const JSCallbackInfo & info)2342 void JSViewAbstract::JsPosition(const JSCallbackInfo& info) 2343 { 2344 CalcDimension x; 2345 CalcDimension y; 2346 OHOS::Ace::EdgesParam edges; 2347 2348 auto jsArg = info[0]; 2349 if (jsArg->IsObject()) { 2350 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg); 2351 if (ParseLocationProps(jsObj, x, y)) { 2352 return ViewAbstractModel::GetInstance()->SetPosition(x, y); 2353 } else if (ParseLocalizedEdges(jsObj, edges)) { 2354 ViewAbstractModel::GetInstance()->SetPositionLocalizedEdges(true); 2355 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges); 2356 } else if (ParseLocationPropsEdges(jsObj, edges)) { 2357 return ViewAbstractModel::GetInstance()->SetPositionEdges(edges); 2358 } 2359 } 2360 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 2361 ViewAbstractModel::GetInstance()->ResetPosition(); 2362 } else { 2363 ViewAbstractModel::GetInstance()->SetPosition(0.0_vp, 0.0_vp); 2364 } 2365 } 2366 JsMarkAnchor(const JSCallbackInfo & info)2367 void JSViewAbstract::JsMarkAnchor(const JSCallbackInfo& info) 2368 { 2369 CalcDimension x; 2370 CalcDimension y; 2371 2372 auto jsArg = info[0]; 2373 if (jsArg->IsObject()) { 2374 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg); 2375 if (ParseMarkAnchorPosition(jsObj, x, y)) { 2376 ViewAbstractModel::GetInstance()->SetLocalizedMarkAnchor(true); 2377 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y); 2378 } else if (ParseLocationProps(jsObj, x, y)) { 2379 return ViewAbstractModel::GetInstance()->MarkAnchor(x, y); 2380 } 2381 } 2382 ViewAbstractModel::GetInstance()->MarkAnchor(0.0_vp, 0.0_vp); 2383 } 2384 JsOffset(const JSCallbackInfo & info)2385 void JSViewAbstract::JsOffset(const JSCallbackInfo& info) 2386 { 2387 CalcDimension x; 2388 CalcDimension y; 2389 OHOS::Ace::EdgesParam edges; 2390 auto jsArg = info[0]; 2391 if (jsArg->IsObject()) { 2392 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsArg); 2393 if (ParseLocalizedEdges(jsObj, edges)) { 2394 ViewAbstractModel::GetInstance()->SetOffsetLocalizedEdges(true); 2395 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges); 2396 } else if (ParseLocationProps(jsObj, x, y)) { 2397 return ViewAbstractModel::GetInstance()->SetOffset(x, y); 2398 } else if (ParseLocationPropsEdges(jsObj, edges)) { 2399 return ViewAbstractModel::GetInstance()->SetOffsetEdges(edges); 2400 } 2401 } 2402 2403 ViewAbstractModel::GetInstance()->SetOffset(0.0_vp, 0.0_vp); 2404 } 2405 JsEnabled(const JSCallbackInfo & info)2406 void JSViewAbstract::JsEnabled(const JSCallbackInfo& info) 2407 { 2408 auto arg = info[0]; 2409 if (!arg->IsBoolean()) { 2410 ViewAbstractModel::GetInstance()->SetEnabled(true); 2411 } else { 2412 ViewAbstractModel::GetInstance()->SetEnabled(arg->ToBoolean()); 2413 } 2414 } 2415 JsAspectRatio(const JSCallbackInfo & info)2416 void JSViewAbstract::JsAspectRatio(const JSCallbackInfo& info) 2417 { 2418 double value = 0.0; 2419 auto jsAspectRatio = info[0]; 2420 if (!ParseJsDouble(jsAspectRatio, value)) { 2421 // add version protection, undefined use default value 2422 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN) && 2423 (jsAspectRatio->IsNull() || jsAspectRatio->IsUndefined())) { 2424 ViewAbstractModel::GetInstance()->ResetAspectRatio(); 2425 return; 2426 } else { 2427 return; 2428 } 2429 } 2430 2431 // negative use default value. 2432 if (LessOrEqual(value, 0.0)) { 2433 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 2434 ViewAbstractModel::GetInstance()->ResetAspectRatio(); 2435 return; 2436 } else { 2437 value = 1.0; 2438 } 2439 } 2440 2441 ViewAbstractModel::GetInstance()->SetAspectRatio(static_cast<float>(value)); 2442 } 2443 ParseOverlayFirstParam(const JSCallbackInfo & info,std::optional<Alignment> & align,std::optional<CalcDimension> & offsetX,std::optional<CalcDimension> & offsetY)2444 void ParseOverlayFirstParam(const JSCallbackInfo& info, std::optional<Alignment>& align, 2445 std::optional<CalcDimension>& offsetX, std::optional<CalcDimension>& offsetY) 2446 { 2447 if (info[0]->IsString()) { 2448 std::string text = info[0]->ToString(); 2449 ViewAbstractModel::GetInstance()->SetOverlay( 2450 text, nullptr, nullptr, align, offsetX, offsetY, NG::OverlayType::TEXT); 2451 } else if (info[0]->IsObject()) { 2452 JSRef<JSObject> overlayObject = JSRef<JSObject>::Cast(info[0]); 2453 auto builder = overlayObject->GetProperty("builder"); 2454 if (builder->IsFunction()) { 2455 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 2456 CHECK_NULL_VOID(builderFunc); 2457 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 2458 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), 2459 node = targetNode]() { 2460 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 2461 ACE_SCORING_EVENT("Overlay"); 2462 PipelineContext::SetCallBackNode(node); 2463 func->Execute(); 2464 }; 2465 ViewAbstractModel::GetInstance()->SetOverlay( 2466 "", std::move(buildFunc), nullptr, align, offsetX, offsetY, NG::OverlayType::BUILDER); 2467 return; 2468 } 2469 2470 JSRef<JSVal> builderNode = overlayObject->GetProperty("builderNode_"); 2471 if (!builderNode->IsObject()) { 2472 return; 2473 } 2474 auto builderNodeObj = JSRef<JSObject>::Cast(builderNode); 2475 JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_"); 2476 if (nodePtr.IsEmpty()) { 2477 return; 2478 } 2479 const auto* vm = nodePtr->GetEcmaVM(); 2480 auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value(); 2481 auto* frameNode = reinterpret_cast<NG::FrameNode*>(node); 2482 CHECK_NULL_VOID(frameNode); 2483 RefPtr<NG::FrameNode> contentNode = AceType::Claim(frameNode); 2484 ViewAbstractModel::GetInstance()->SetOverlay( 2485 "", nullptr, contentNode, align, offsetX, offsetY, NG::OverlayType::COMPONENT_CONTENT); 2486 } 2487 } 2488 JsOverlay(const JSCallbackInfo & info)2489 void JSViewAbstract::JsOverlay(const JSCallbackInfo& info) 2490 { 2491 if (info.Length() > 0 && (info[0]->IsUndefined())) { 2492 ViewAbstractModel::GetInstance()->SetOverlay( 2493 "", nullptr, nullptr, Alignment::TOP_LEFT, CalcDimension(0), CalcDimension(0), NG::OverlayType::RESET); 2494 return; 2495 } 2496 2497 if (info.Length() <= 0 || (!info[0]->IsString() && !info[0]->IsObject())) { 2498 return; 2499 } 2500 std::optional<Alignment> align; 2501 std::optional<CalcDimension> offsetX; 2502 std::optional<CalcDimension> offsetY; 2503 2504 if (info[1]->IsObject()) { 2505 JSRef<JSObject> optionObj = JSRef<JSObject>::Cast(info[1]); 2506 JSRef<JSVal> alignVal = optionObj->GetProperty("align"); 2507 auto value = alignVal->ToNumber<int32_t>(); 2508 Alignment alignment = ParseAlignment(value); 2509 align = alignment; 2510 2511 JSRef<JSVal> val = optionObj->GetProperty("offset"); 2512 if (val->IsObject()) { 2513 JSRef<JSObject> offsetObj = JSRef<JSObject>::Cast(val); 2514 JSRef<JSVal> xVal = offsetObj->GetProperty("x"); 2515 CalcDimension x; 2516 if (ParseJsDimensionVp(xVal, x)) { 2517 offsetX = x; 2518 } 2519 JSRef<JSVal> yVal = offsetObj->GetProperty("y"); 2520 CalcDimension y; 2521 if (ParseJsDimensionVp(yVal, y)) { 2522 offsetY = y; 2523 } 2524 } 2525 } 2526 2527 ParseOverlayFirstParam(info, align, offsetX, offsetY); 2528 } 2529 ParseAlignment(int32_t align)2530 Alignment JSViewAbstract::ParseAlignment(int32_t align) 2531 { 2532 Alignment alignment = Alignment::CENTER; 2533 switch (align) { 2534 case 0: 2535 alignment = Alignment::TOP_LEFT; 2536 break; 2537 case 1: 2538 alignment = Alignment::TOP_CENTER; 2539 break; 2540 case 2: 2541 alignment = Alignment::TOP_RIGHT; 2542 break; 2543 case 3: 2544 alignment = Alignment::CENTER_LEFT; 2545 break; 2546 case 4: 2547 alignment = Alignment::CENTER; 2548 break; 2549 case 5: 2550 alignment = Alignment::CENTER_RIGHT; 2551 break; 2552 case 6: 2553 alignment = Alignment::BOTTOM_LEFT; 2554 break; 2555 case 7: 2556 alignment = Alignment::BOTTOM_CENTER; 2557 break; 2558 case 8: 2559 alignment = Alignment::BOTTOM_RIGHT; 2560 break; 2561 default: 2562 break; 2563 } 2564 return alignment; 2565 } 2566 SetVisibility(const JSCallbackInfo & info)2567 void JSViewAbstract::SetVisibility(const JSCallbackInfo& info) 2568 { 2569 int32_t visible = 0; 2570 JSRef<JSVal> arg = info[0]; 2571 if (arg->IsNull() || arg->IsUndefined()) { 2572 // undefined value use default value. 2573 visible = 0; 2574 } else if (!arg->IsNumber()) { 2575 return; 2576 } else { 2577 visible = arg->ToNumber<int32_t>(); 2578 } 2579 2580 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) && 2581 (visible < static_cast<int32_t>(VisibleType::VISIBLE) || visible > static_cast<int32_t>(VisibleType::GONE))) { 2582 visible = 0; 2583 } 2584 2585 if (info.Length() > 1 && info[1]->IsFunction()) { 2586 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1])); 2587 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 2588 auto onVisibilityChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]( 2589 int32_t visible) { 2590 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 2591 ACE_SCORING_EVENT("onVisibilityChange"); 2592 PipelineContext::SetCallBackNode(node); 2593 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(visible)); 2594 func->ExecuteJS(1, &newJSVal); 2595 }; 2596 ViewAbstractModel::GetInstance()->SetVisibility( 2597 static_cast<VisibleType>(visible), std::move(onVisibilityChange)); 2598 } else { 2599 ViewAbstractModel::GetInstance()->SetVisibility(static_cast<VisibleType>(visible), [](int32_t visible) {}); 2600 } 2601 } 2602 JsSetFreeze(const JSCallbackInfo & info)2603 void JSViewAbstract::JsSetFreeze(const JSCallbackInfo& info) 2604 { 2605 if (info[0]->IsBoolean()) { 2606 ViewAbstractModel::GetInstance()->SetFreeze(info[0]->ToBoolean()); 2607 } 2608 } 2609 JsFlexBasis(const JSCallbackInfo & info)2610 void JSViewAbstract::JsFlexBasis(const JSCallbackInfo& info) 2611 { 2612 CalcDimension value; 2613 if (!ParseJsDimensionVp(info[0], value)) { 2614 value.SetUnit(DimensionUnit::AUTO); 2615 } 2616 // flexbasis don't support percent case. 2617 if (value.Unit() == DimensionUnit::PERCENT) { 2618 value.SetUnit(DimensionUnit::AUTO); 2619 } 2620 ViewAbstractModel::GetInstance()->SetFlexBasis(value); 2621 } 2622 JsFlexGrow(const JSCallbackInfo & info)2623 void JSViewAbstract::JsFlexGrow(const JSCallbackInfo& info) 2624 { 2625 double value = 0.0; 2626 if (!ParseJsDouble(info[0], value)) { 2627 if (info[0]->IsNull() || info[0]->IsUndefined()) { 2628 // undefined use default value. 2629 value = 0.0; 2630 } else { 2631 return; 2632 } 2633 } 2634 // negative use default value. 2635 if (value < 0.0) { 2636 value = 0.0; 2637 } 2638 ViewAbstractModel::GetInstance()->SetFlexGrow(static_cast<float>(value)); 2639 } 2640 JsFlexShrink(const JSCallbackInfo & info)2641 void JSViewAbstract::JsFlexShrink(const JSCallbackInfo& info) 2642 { 2643 double value = 0.0; 2644 if (!ParseJsDouble(info[0], value)) { 2645 if (info[0]->IsNull() || info[0]->IsUndefined()) { 2646 // undefined use default value. 2647 ViewAbstractModel::GetInstance()->ResetFlexShrink(); 2648 return; 2649 } else { 2650 return; 2651 } 2652 } 2653 // negative use default value. 2654 if (value < 0.0) { 2655 ViewAbstractModel::GetInstance()->ResetFlexShrink(); 2656 return; 2657 } 2658 ViewAbstractModel::GetInstance()->SetFlexShrink(static_cast<float>(value)); 2659 } 2660 JsDisplayPriority(const JSCallbackInfo & info)2661 void JSViewAbstract::JsDisplayPriority(const JSCallbackInfo& info) 2662 { 2663 double value = 0.0; 2664 if (!ParseJsDouble(info[0], value)) { 2665 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 2666 ViewAbstractModel::GetInstance()->SetDisplayIndex(0); 2667 } 2668 return; 2669 } 2670 ViewAbstractModel::GetInstance()->SetDisplayIndex(static_cast<int32_t>(value)); 2671 } 2672 JsSharedTransition(const JSCallbackInfo & info)2673 void JSViewAbstract::JsSharedTransition(const JSCallbackInfo& info) 2674 { 2675 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING }; 2676 auto jsVal = info[0]; 2677 if (!CheckJSCallbackInfo("JsSharedTransition", jsVal, checkList)) { 2678 return; 2679 } 2680 // id 2681 auto id = jsVal->ToString(); 2682 if (id.empty()) { 2683 return; 2684 } 2685 std::shared_ptr<SharedTransitionOption> sharedOption; 2686 2687 // options 2688 if (info.Length() > 1 && info[1]->IsObject()) { 2689 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]); 2690 sharedOption = std::make_shared<SharedTransitionOption>(); 2691 // default: duration: 1000 2692 sharedOption->duration = jsObj->GetPropertyValue<int32_t>("duration", DEFAULT_DURATION); 2693 if (sharedOption->duration < 0) { 2694 sharedOption->duration = DEFAULT_DURATION; 2695 } 2696 // default: delay: 0 2697 sharedOption->delay = jsObj->GetPropertyValue<int32_t>("delay", 0); 2698 if (sharedOption->delay < 0) { 2699 sharedOption->delay = 0; 2700 } 2701 // default: LinearCurve 2702 RefPtr<Curve> curve; 2703 JSRef<JSVal> curveArgs = jsObj->GetProperty("curve"); 2704 if (curveArgs->IsString()) { 2705 curve = CreateCurve(jsObj->GetPropertyValue<std::string>("curve", "linear"), false); 2706 } else if (curveArgs->IsObject()) { 2707 JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString"); 2708 if (!curveString->IsString()) { 2709 return; 2710 } 2711 curve = CreateCurve(curveString->ToString(), false); 2712 } 2713 if (!curve) { 2714 curve = Curves::LINEAR; 2715 } 2716 sharedOption->curve = curve; 2717 // motionPath 2718 if (jsObj->HasProperty("motionPath")) { 2719 MotionPathOption motionPathOption; 2720 if (ParseMotionPath(jsObj->GetProperty("motionPath"), motionPathOption)) { 2721 sharedOption->motionPathOption = motionPathOption; 2722 } 2723 } 2724 // zIndex 2725 sharedOption->zIndex = jsObj->GetPropertyValue<int32_t>("zIndex", 0); 2726 // type 2727 int32_t type = jsObj->GetPropertyValue<int32_t>("type", 2728 static_cast<int32_t>(SharedTransitionEffectType::SHARED_EFFECT_EXCHANGE)); 2729 sharedOption->type = static_cast<SharedTransitionEffectType>(type); 2730 } 2731 ViewAbstractModel::GetInstance()->SetSharedTransition(id, sharedOption); 2732 } 2733 JsGeometryTransition(const JSCallbackInfo & info)2734 void JSViewAbstract::JsGeometryTransition(const JSCallbackInfo& info) 2735 { 2736 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING }; 2737 auto jsVal = info[0]; 2738 if (!CheckJSCallbackInfo("JsGeometryTransition", jsVal, checkList)) { 2739 return; 2740 } 2741 // id 2742 auto id = jsVal->ToString(); 2743 // follow flag 2744 bool followWithOutTransition = false; 2745 // hierarchy flag 2746 bool doRegisterSharedTransition = true; 2747 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) { 2748 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]); 2749 ParseJsBool(jsOption->GetProperty("follow"), followWithOutTransition); 2750 2751 auto transitionHierarchyStrategy = static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE); 2752 ParseJsInt32(jsOption->GetProperty("hierarchyStrategy"), transitionHierarchyStrategy); 2753 switch (transitionHierarchyStrategy) { 2754 case static_cast<int32_t>(TransitionHierarchyStrategy::NONE): 2755 doRegisterSharedTransition = false; 2756 break; 2757 case static_cast<int32_t>(TransitionHierarchyStrategy::ADAPTIVE): 2758 doRegisterSharedTransition = true; 2759 break; 2760 default: 2761 break; 2762 } 2763 } 2764 ViewAbstractModel::GetInstance()->SetGeometryTransition(id, followWithOutTransition, doRegisterSharedTransition); 2765 } 2766 JsAlignSelf(const JSCallbackInfo & info)2767 void JSViewAbstract::JsAlignSelf(const JSCallbackInfo& info) 2768 { 2769 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER }; 2770 auto jsVal = info[0]; 2771 if (!CheckJSCallbackInfo("JsAlignSelf", jsVal, checkList)) { 2772 ViewAbstractModel::GetInstance()->SetAlignSelf(FlexAlign::AUTO); 2773 return; 2774 } 2775 auto alignVal = jsVal->ToNumber<int32_t>(); 2776 2777 if (alignVal >= 0 && alignVal <= MAX_ALIGN_VALUE) { 2778 ViewAbstractModel::GetInstance()->SetAlignSelf(static_cast<FlexAlign>(alignVal)); 2779 } 2780 } 2781 JsBackgroundColor(const JSCallbackInfo & info)2782 void JSViewAbstract::JsBackgroundColor(const JSCallbackInfo& info) 2783 { 2784 Color backgroundColor; 2785 if (!ParseJsColor(info[0], backgroundColor)) { 2786 backgroundColor = Color::TRANSPARENT; 2787 } 2788 2789 ViewAbstractModel::GetInstance()->SetBackgroundColor(backgroundColor); 2790 } 2791 JsBackgroundImage(const JSCallbackInfo & info)2792 void JSViewAbstract::JsBackgroundImage(const JSCallbackInfo& info) 2793 { 2794 int32_t resId = 0; 2795 std::string src; 2796 std::string bundle; 2797 std::string module; 2798 RefPtr<PixelMap> pixmap = nullptr; 2799 auto jsBackgroundImage = info[0]; 2800 GetJsMediaBundleInfo(jsBackgroundImage, bundle, module); 2801 if (jsBackgroundImage->IsString()) { 2802 src = jsBackgroundImage->ToString(); 2803 ViewAbstractModel::GetInstance()->SetBackgroundImage( 2804 ImageSourceInfo { src, bundle, module }, GetThemeConstants()); 2805 } else if (ParseJsMediaWithBundleName(jsBackgroundImage, src, bundle, module, resId)) { 2806 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { src, bundle, module }, nullptr); 2807 } else { 2808 #if defined(PIXEL_MAP_SUPPORTED) 2809 if (IsDrawable(jsBackgroundImage)) { 2810 pixmap = GetDrawablePixmap(jsBackgroundImage); 2811 } else { 2812 pixmap = CreatePixelMapFromNapiValue(jsBackgroundImage); 2813 } 2814 #endif 2815 ViewAbstractModel::GetInstance()->SetBackgroundImage(ImageSourceInfo { pixmap }, nullptr); 2816 } 2817 2818 int32_t repeatIndex = 0; 2819 if (info.Length() == 2) { 2820 auto jsImageRepeat = info[1]; 2821 if (jsImageRepeat->IsNumber()) { 2822 repeatIndex = jsImageRepeat->ToNumber<int32_t>(); 2823 } 2824 } 2825 auto repeat = static_cast<ImageRepeat>(repeatIndex); 2826 ViewAbstractModel::GetInstance()->SetBackgroundImageRepeat(repeat); 2827 } 2828 ParseBlurOption(const JSRef<JSObject> & jsBlurOption,BlurOption & blurOption)2829 void JSViewAbstract::ParseBlurOption(const JSRef<JSObject>& jsBlurOption, BlurOption& blurOption) 2830 { 2831 if (jsBlurOption->GetProperty("grayscale")->IsArray()) { 2832 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsBlurOption->GetProperty("grayscale")); 2833 auto grey1 = params->GetValueAt(0)->ToNumber<uint32_t>(); 2834 auto grey2 = params->GetValueAt(1)->ToNumber<uint32_t>(); 2835 std::vector<float> greyVec(2); // 2 number 2836 greyVec[0] = grey1; 2837 greyVec[1] = grey2; 2838 blurOption.grayscale = greyVec; 2839 } 2840 } 2841 ParseBlurStyleOption(const JSRef<JSObject> & jsOption,BlurStyleOption & styleOption)2842 void JSViewAbstract::ParseBlurStyleOption(const JSRef<JSObject>& jsOption, BlurStyleOption& styleOption) 2843 { 2844 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM); 2845 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode); 2846 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) && 2847 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) { 2848 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode); 2849 } 2850 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT); 2851 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor); 2852 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) && 2853 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) { 2854 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor); 2855 } 2856 2857 // policy 2858 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE); 2859 ParseJsInt32(jsOption->GetProperty("policy"), policy); 2860 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) && 2861 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) { 2862 styleOption.policy = static_cast<BlurStyleActivePolicy>(policy); 2863 } 2864 2865 // blurType 2866 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW); 2867 ParseJsInt32(jsOption->GetProperty("type"), blurType); 2868 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) && 2869 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) { 2870 styleOption.blurType = static_cast<BlurType>(blurType); 2871 } 2872 2873 // inactiveColor 2874 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), styleOption.inactiveColor)) { 2875 styleOption.isValidColor = true; 2876 } 2877 2878 // scale 2879 if (jsOption->GetProperty("scale")->IsNumber()) { 2880 double scale = jsOption->GetProperty("scale")->ToNumber<double>(); 2881 styleOption.scale = std::clamp(scale, 0.0, 1.0); 2882 } 2883 2884 if (jsOption->GetProperty("blurOptions")->IsObject()) { 2885 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions")); 2886 BlurOption blurOption; 2887 ParseBlurOption(jsBlurOption, blurOption); 2888 styleOption.blurOption = blurOption; 2889 } 2890 } 2891 JsBackgroundBlurStyle(const JSCallbackInfo & info)2892 void JSViewAbstract::JsBackgroundBlurStyle(const JSCallbackInfo& info) 2893 { 2894 if (info.Length() == 0) { 2895 return; 2896 } 2897 BlurStyleOption styleOption; 2898 if (info[0]->IsNumber()) { 2899 auto blurStyle = info[0]->ToNumber<int32_t>(); 2900 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) && 2901 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) { 2902 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle); 2903 } 2904 } 2905 if (info.Length() > 1 && info[1]->IsObject()) { 2906 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]); 2907 ParseBlurStyleOption(jsOption, styleOption); 2908 } 2909 ViewAbstractModel::GetInstance()->SetBackgroundBlurStyle(styleOption); 2910 } 2911 ParseBrightnessOption(const JSRef<JSObject> & jsOption,BrightnessOption & brightnessOption)2912 void JSViewAbstract::ParseBrightnessOption(const JSRef<JSObject>& jsOption, BrightnessOption& brightnessOption) 2913 { 2914 double rate = 1.0f; 2915 if (jsOption->GetProperty("rate")->IsNumber()) { 2916 rate = jsOption->GetProperty("rate")->ToNumber<double>(); 2917 } 2918 double lightUpDegree = 0.0f; 2919 if (jsOption->GetProperty("lightUpDegree")->IsNumber()) { 2920 lightUpDegree = jsOption->GetProperty("lightUpDegree")->ToNumber<double>(); 2921 } 2922 double cubicCoeff = 0.0f; 2923 if (jsOption->GetProperty("cubicCoeff")->IsNumber()) { 2924 cubicCoeff = jsOption->GetProperty("cubicCoeff")->ToNumber<double>(); 2925 } 2926 double quadCoeff = 0.0f; 2927 if (jsOption->GetProperty("quadCoeff")->IsNumber()) { 2928 quadCoeff = jsOption->GetProperty("quadCoeff")->ToNumber<double>(); 2929 } 2930 double saturation = 1.0f; 2931 if (jsOption->GetProperty("saturation")->IsNumber()) { 2932 saturation = jsOption->GetProperty("saturation")->ToNumber<double>(); 2933 } 2934 std::vector<float> posRGB(3, 0.0); 2935 if (jsOption->GetProperty("posRGB")->IsArray()) { 2936 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("posRGB")); 2937 auto r = params->GetValueAt(0)->ToNumber<double>(); 2938 auto g = params->GetValueAt(1)->ToNumber<double>(); 2939 auto b = params->GetValueAt(2)->ToNumber<double>(); 2940 posRGB[0] = r; 2941 posRGB[1] = g; 2942 posRGB[2] = b; 2943 } 2944 std::vector<float> negRGB(3, 0.0); 2945 if (jsOption->GetProperty("negRGB")->IsArray()) { 2946 JSRef<JSArray> params = JSRef<JSArray>::Cast(jsOption->GetProperty("negRGB")); 2947 auto r = params->GetValueAt(0)->ToNumber<double>(); 2948 auto g = params->GetValueAt(1)->ToNumber<double>(); 2949 auto b = params->GetValueAt(2)->ToNumber<double>(); 2950 negRGB[0] = r; 2951 negRGB[1] = g; 2952 negRGB[2] = b; 2953 } 2954 double fraction = 1.0f; 2955 if (jsOption->GetProperty("fraction")->IsNumber()) { 2956 fraction = jsOption->GetProperty("fraction")->ToNumber<double>(); 2957 fraction = std::clamp(fraction, 0.0, 1.0); 2958 } 2959 brightnessOption = { rate, lightUpDegree, cubicCoeff, quadCoeff, saturation, posRGB, negRGB, fraction }; 2960 } 2961 ParseEffectOption(const JSRef<JSObject> & jsOption,EffectOption & effectOption)2962 void JSViewAbstract::ParseEffectOption(const JSRef<JSObject>& jsOption, EffectOption& effectOption) 2963 { 2964 CalcDimension radius; 2965 if (!ParseJsDimensionVp(jsOption->GetProperty("radius"), radius) || LessNotEqual(radius.Value(), 0.0f)) { 2966 radius.SetValue(0.0f); 2967 } 2968 effectOption.radius = radius; 2969 2970 double saturation = 1.0f; 2971 if (jsOption->GetProperty("saturation")->IsNumber()) { 2972 saturation = jsOption->GetProperty("saturation")->ToNumber<double>(); 2973 saturation = (saturation > 0.0f || NearZero(saturation)) ? saturation : 1.0f; 2974 } 2975 effectOption.saturation = saturation; 2976 2977 double brightness = 1.0f; 2978 if (jsOption->GetProperty("brightness")->IsNumber()) { 2979 brightness = jsOption->GetProperty("brightness")->ToNumber<double>(); 2980 brightness = (brightness > 0.0f || NearZero(brightness)) ? brightness : 1.0f; 2981 } 2982 effectOption.brightness = brightness; 2983 2984 ParseJsColor(jsOption->GetProperty("color"), effectOption.color); 2985 2986 auto adaptiveColorValue = static_cast<int32_t>(AdaptiveColor::DEFAULT); 2987 auto adaptiveColor = AdaptiveColor::DEFAULT; 2988 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColorValue); 2989 if (adaptiveColorValue >= static_cast<int32_t>(AdaptiveColor::DEFAULT) && 2990 adaptiveColorValue <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) { 2991 adaptiveColor = static_cast<AdaptiveColor>(adaptiveColorValue); 2992 } 2993 effectOption.adaptiveColor = adaptiveColor; 2994 2995 // policy 2996 auto policy = static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_ACTIVE); 2997 ParseJsInt32(jsOption->GetProperty("policy"), policy); 2998 if (policy >= static_cast<int32_t>(BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) && 2999 policy <= static_cast<int32_t>(BlurStyleActivePolicy::ALWAYS_INACTIVE)) { 3000 effectOption.policy = static_cast<BlurStyleActivePolicy>(policy); 3001 } 3002 3003 // blurType 3004 auto blurType = static_cast<int32_t>(BlurType::WITHIN_WINDOW); 3005 ParseJsInt32(jsOption->GetProperty("type"), blurType); 3006 if (blurType >= static_cast<int32_t>(BlurType::WITHIN_WINDOW) && 3007 blurType <= static_cast<int32_t>(BlurType::BEHIND_WINDOW)) { 3008 effectOption.blurType = static_cast<BlurType>(blurType); 3009 } 3010 3011 // inactiveColor 3012 if (ParseJsColor(jsOption->GetProperty("inactiveColor"), effectOption.inactiveColor)) { 3013 effectOption.isValidColor = true; 3014 } 3015 3016 BlurOption blurOption; 3017 if (jsOption->GetProperty("blurOptions")->IsObject()) { 3018 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions")); 3019 ParseBlurOption(jsBlurOption, blurOption); 3020 effectOption.blurOption = blurOption; 3021 } 3022 } 3023 JsForegroundEffect(const JSCallbackInfo & info)3024 void JSViewAbstract::JsForegroundEffect(const JSCallbackInfo& info) 3025 { 3026 if (info.Length() == 0) { 3027 return; 3028 } 3029 float radius = 0.0; 3030 if (info[0]->IsObject()) { 3031 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]); 3032 if (jsOption->GetProperty("radius")->IsNumber()) { 3033 radius = jsOption->GetProperty("radius")->ToNumber<float>(); 3034 } 3035 } 3036 radius = std::max(radius, 0.0f); 3037 ViewAbstractModel::GetInstance()->SetForegroundEffect(radius); 3038 } 3039 JsBackgroundEffect(const JSCallbackInfo & info)3040 void JSViewAbstract::JsBackgroundEffect(const JSCallbackInfo& info) 3041 { 3042 if (info.Length() == 0) { 3043 return; 3044 } 3045 EffectOption option; 3046 if (info[0]->IsObject()) { 3047 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]); 3048 ParseEffectOption(jsOption, option); 3049 } 3050 ViewAbstractModel::GetInstance()->SetBackgroundEffect(option); 3051 } 3052 JsForegroundBlurStyle(const JSCallbackInfo & info)3053 void JSViewAbstract::JsForegroundBlurStyle(const JSCallbackInfo& info) 3054 { 3055 if (info.Length() == 0) { 3056 return; 3057 } 3058 BlurStyleOption styleOption; 3059 if (info[0]->IsNumber()) { 3060 auto blurStyle = info[0]->ToNumber<int32_t>(); 3061 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) && 3062 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) { 3063 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle); 3064 } 3065 } 3066 if (info.Length() > 1 && info[1]->IsObject()) { 3067 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[1]); 3068 auto colorMode = static_cast<int32_t>(ThemeColorMode::SYSTEM); 3069 ParseJsInt32(jsOption->GetProperty("colorMode"), colorMode); 3070 if (colorMode >= static_cast<int32_t>(ThemeColorMode::SYSTEM) && 3071 colorMode <= static_cast<int32_t>(ThemeColorMode::DARK)) { 3072 styleOption.colorMode = static_cast<ThemeColorMode>(colorMode); 3073 } 3074 auto adaptiveColor = static_cast<int32_t>(AdaptiveColor::DEFAULT); 3075 ParseJsInt32(jsOption->GetProperty("adaptiveColor"), adaptiveColor); 3076 if (adaptiveColor >= static_cast<int32_t>(AdaptiveColor::DEFAULT) && 3077 adaptiveColor <= static_cast<int32_t>(AdaptiveColor::AVERAGE)) { 3078 styleOption.adaptiveColor = static_cast<AdaptiveColor>(adaptiveColor); 3079 } 3080 if (jsOption->GetProperty("scale")->IsNumber()) { 3081 double scale = jsOption->GetProperty("scale")->ToNumber<double>(); 3082 styleOption.scale = std::clamp(scale, 0.0, 1.0); 3083 } 3084 3085 if (jsOption->GetProperty("blurOptions")->IsObject()) { 3086 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(jsOption->GetProperty("blurOptions")); 3087 BlurOption blurOption; 3088 ParseBlurOption(jsBlurOption, blurOption); 3089 styleOption.blurOption = blurOption; 3090 } 3091 } 3092 ViewAbstractModel::GetInstance()->SetForegroundBlurStyle(styleOption); 3093 } 3094 JsSphericalEffect(const JSCallbackInfo & info)3095 void JSViewAbstract::JsSphericalEffect(const JSCallbackInfo& info) 3096 { 3097 auto radio = 0.0; 3098 if (info[0]->IsNumber()) { 3099 radio = info[0]->ToNumber<double>(); 3100 } 3101 ViewAbstractModel::GetInstance()->SetSphericalEffect(std::clamp(radio, 0.0, 1.0)); 3102 } 3103 JsPixelStretchEffect(const JSCallbackInfo & info)3104 void JSViewAbstract::JsPixelStretchEffect(const JSCallbackInfo& info) 3105 { 3106 if (!info[0]->IsObject()) { 3107 PixStretchEffectOption option; 3108 option.ResetValue(); 3109 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option); 3110 return; 3111 } 3112 auto jsObject = JSRef<JSObject>::Cast(info[0]); 3113 CalcDimension left; 3114 ParseJsDimensionVp(jsObject->GetProperty("left"), left); 3115 CalcDimension right; 3116 ParseJsDimensionVp(jsObject->GetProperty("right"), right); 3117 CalcDimension top; 3118 ParseJsDimensionVp(jsObject->GetProperty("top"), top); 3119 CalcDimension bottom; 3120 ParseJsDimensionVp(jsObject->GetProperty("bottom"), bottom); 3121 3122 PixStretchEffectOption option; 3123 bool illegalInput = false; 3124 if (left.Unit() == DimensionUnit::PERCENT || right.Unit() == DimensionUnit::PERCENT || 3125 top.Unit() == DimensionUnit::PERCENT || bottom.Unit() == DimensionUnit::PERCENT) { 3126 if ((NearEqual(left.Value(), 0.0) || left.Unit() == DimensionUnit::PERCENT) && 3127 (NearEqual(top.Value(), 0.0) || top.Unit() == DimensionUnit::PERCENT) && 3128 (NearEqual(right.Value(), 0.0) || right.Unit() == DimensionUnit::PERCENT) && 3129 (NearEqual(bottom.Value(), 0.0) || bottom.Unit() == DimensionUnit::PERCENT)) { 3130 left.SetUnit(DimensionUnit::PERCENT); 3131 top.SetUnit(DimensionUnit::PERCENT); 3132 right.SetUnit(DimensionUnit::PERCENT); 3133 bottom.SetUnit(DimensionUnit::PERCENT); 3134 } else { 3135 illegalInput = true; 3136 } 3137 } 3138 if ((left.IsNonNegative() && top.IsNonNegative() && right.IsNonNegative() && bottom.IsNonNegative()) || 3139 (left.IsNonPositive() && top.IsNonPositive() && right.IsNonPositive() && bottom.IsNonPositive())) { 3140 option.left = left; 3141 option.top = top; 3142 option.right = right; 3143 option.bottom = bottom; 3144 } else { 3145 illegalInput = true; 3146 } 3147 if (illegalInput) { 3148 option.ResetValue(); 3149 } 3150 ViewAbstractModel::GetInstance()->SetPixelStretchEffect(option); 3151 } 3152 JsLightUpEffect(const JSCallbackInfo & info)3153 void JSViewAbstract::JsLightUpEffect(const JSCallbackInfo& info) 3154 { 3155 auto radio = 1.0; 3156 if (info[0]->IsNumber()) { 3157 radio = info[0]->ToNumber<double>(); 3158 } 3159 ViewAbstractModel::GetInstance()->SetLightUpEffect(std::clamp(radio, 0.0, 1.0)); 3160 } 3161 JsBackgroundImageSize(const JSCallbackInfo & info)3162 void JSViewAbstract::JsBackgroundImageSize(const JSCallbackInfo& info) 3163 { 3164 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT }; 3165 BackgroundImageSize bgImgSize; 3166 auto jsVal = info[0]; 3167 if (!CheckJSCallbackInfo("JsBackgroundImageSize", jsVal, checkList)) { 3168 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO); 3169 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO); 3170 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize); 3171 return; 3172 } 3173 if (jsVal->IsNumber()) { 3174 auto sizeType = static_cast<BackgroundImageSizeType>(jsVal->ToNumber<int32_t>()); 3175 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE) && 3176 (sizeType < BackgroundImageSizeType::CONTAIN || sizeType > BackgroundImageSizeType::FILL)) { 3177 sizeType = BackgroundImageSizeType::AUTO; 3178 } 3179 bgImgSize.SetSizeTypeX(sizeType); 3180 bgImgSize.SetSizeTypeY(sizeType); 3181 } else { 3182 CalcDimension width; 3183 CalcDimension height; 3184 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal); 3185 ParseJsDimensionVp(object->GetProperty("width"), width); 3186 ParseJsDimensionVp(object->GetProperty("height"), height); 3187 double valueWidth = width.ConvertToPx(); 3188 double valueHeight = height.ConvertToPx(); 3189 BackgroundImageSizeType typeWidth = BackgroundImageSizeType::LENGTH; 3190 BackgroundImageSizeType typeHeight = BackgroundImageSizeType::LENGTH; 3191 if (width.Unit() == DimensionUnit::PERCENT) { 3192 typeWidth = BackgroundImageSizeType::PERCENT; 3193 valueWidth = width.Value() * FULL_DIMENSION; 3194 } 3195 if (height.Unit() == DimensionUnit::PERCENT) { 3196 typeHeight = BackgroundImageSizeType::PERCENT; 3197 valueHeight = height.Value() * FULL_DIMENSION; 3198 } 3199 bgImgSize.SetSizeTypeX(typeWidth); 3200 bgImgSize.SetSizeValueX(valueWidth); 3201 bgImgSize.SetSizeTypeY(typeHeight); 3202 bgImgSize.SetSizeValueY(valueHeight); 3203 } 3204 3205 ViewAbstractModel::GetInstance()->SetBackgroundImageSize(bgImgSize); 3206 } 3207 SetBgImgPositionWithAlign(BackgroundImagePosition & bgImgPosition,int32_t align)3208 void SetBgImgPositionWithAlign(BackgroundImagePosition& bgImgPosition, int32_t align) 3209 { 3210 if (align > 8 || align < 0) { 3211 return; 3212 } 3213 std::vector<std::pair<double, double>> vec = { { 0.0, 0.0 }, { HALF_DIMENSION, 0.0 }, { FULL_DIMENSION, 0.0 }, 3214 { 0.0, HALF_DIMENSION }, { HALF_DIMENSION, HALF_DIMENSION }, { FULL_DIMENSION, HALF_DIMENSION }, 3215 { 0.0, FULL_DIMENSION }, { HALF_DIMENSION, FULL_DIMENSION }, { FULL_DIMENSION, FULL_DIMENSION } }; 3216 SetBgImgPosition( 3217 DimensionUnit::PERCENT, DimensionUnit::PERCENT, vec[align].first, vec[align].second, bgImgPosition); 3218 } 3219 JsBackgroundImagePosition(const JSCallbackInfo & info)3220 void JSViewAbstract::JsBackgroundImagePosition(const JSCallbackInfo& info) 3221 { 3222 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER, JSCallbackInfoType::OBJECT }; 3223 BackgroundImagePosition bgImgPosition; 3224 auto jsVal = info[0]; 3225 if (!CheckJSCallbackInfo("JsBackgroundImagePosition", jsVal, checkList)) { 3226 SetBgImgPosition(DimensionUnit::PX, DimensionUnit::PX, 0.0, 0.0, bgImgPosition); 3227 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition); 3228 return; 3229 } 3230 if (jsVal->IsNumber()) { 3231 int32_t align = jsVal->ToNumber<int32_t>(); 3232 bgImgPosition.SetIsAlign(true); 3233 SetBgImgPositionWithAlign(bgImgPosition, align); 3234 } else { 3235 CalcDimension x; 3236 CalcDimension y; 3237 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal); 3238 ParseJsDimensionVp(object->GetProperty("x"), x); 3239 ParseJsDimensionVp(object->GetProperty("y"), y); 3240 double valueX = x.Value(); 3241 double valueY = y.Value(); 3242 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 3243 valueX = x.ConvertToPx(); 3244 valueY = y.ConvertToPx(); 3245 } 3246 DimensionUnit typeX = DimensionUnit::PX; 3247 DimensionUnit typeY = DimensionUnit::PX; 3248 if (x.Unit() == DimensionUnit::PERCENT) { 3249 valueX = x.Value(); 3250 typeX = DimensionUnit::PERCENT; 3251 } 3252 if (y.Unit() == DimensionUnit::PERCENT) { 3253 valueY = y.Value(); 3254 typeY = DimensionUnit::PERCENT; 3255 } 3256 SetBgImgPosition(typeX, typeY, valueX, valueY, bgImgPosition); 3257 } 3258 3259 ViewAbstractModel::GetInstance()->SetBackgroundImagePosition(bgImgPosition); 3260 } 3261 ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)3262 std::vector<NG::OptionParam> ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex) 3263 { 3264 JSRef<JSVal> arg = info[optionIndex]; 3265 if (!arg->IsArray()) { 3266 return std::vector<NG::OptionParam>(); 3267 } 3268 auto paramArray = JSRef<JSArray>::Cast(arg); 3269 auto paramArrayLength = paramArray->Length(); 3270 std::vector<NG::OptionParam> params(paramArrayLength); 3271 // parse paramArray 3272 for (size_t i = 0; i < paramArrayLength; ++i) { 3273 if (!paramArray->GetValueAt(i)->IsObject()) { 3274 return std::vector<NG::OptionParam>(); 3275 } 3276 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i)); 3277 JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)), 3278 params[i].value); 3279 auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION)); 3280 if (!actionFunc->IsFunction()) { 3281 return params; 3282 } 3283 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc)); 3284 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 3285 // set onClick function 3286 params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() { 3287 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context); 3288 ACE_SCORING_EVENT("menu.action"); 3289 PipelineContext::SetCallBackNode(node); 3290 if (func) { 3291 func->Execute(); 3292 } 3293 }; 3294 std::string iconPath; 3295 if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) { 3296 params[i].icon = iconPath; 3297 } 3298 if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) { 3299 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply; 3300 JSViewAbstract::SetSymbolOptionApply(info, symbolApply, 3301 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))); 3302 params[i].symbol = symbolApply; 3303 } 3304 auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED)); 3305 if (enabled->IsBoolean()) { 3306 params[i].enabled = enabled->ToBoolean(); 3307 } 3308 } 3309 return params; 3310 } 3311 ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3312 void ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam) 3313 { 3314 auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS)); 3315 NG::BorderRadiusProperty menuBorderRadius; 3316 CalcDimension borderRadius; 3317 if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) { 3318 if (borderRadius.Unit() != DimensionUnit::PERCENT && GreatOrEqual(borderRadius.Value(), 0.0f)) { 3319 menuBorderRadius.SetRadius(borderRadius); 3320 menuBorderRadius.multiValued = false; 3321 menuParam.borderRadius = menuBorderRadius; 3322 }; 3323 } else if (borderRadiusValue->IsObject()) { 3324 JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue); 3325 CalcDimension topLeft; 3326 CalcDimension topRight; 3327 CalcDimension bottomLeft; 3328 CalcDimension bottomRight; 3329 bool hasSetBorderRadius = 3330 JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight); 3331 if (LessNotEqual(topLeft.Value(), 0.0f)) { 3332 topLeft.Reset(); 3333 } 3334 if (LessNotEqual(topRight.Value(), 0.0f)) { 3335 topRight.Reset(); 3336 } 3337 if (LessNotEqual(bottomLeft.Value(), 0.0f)) { 3338 bottomLeft.Reset(); 3339 } 3340 if (LessNotEqual(bottomRight.Value(), 0.0f)) { 3341 bottomRight.Reset(); 3342 } 3343 auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft(); 3344 menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft; 3345 menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight; 3346 menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft; 3347 menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight; 3348 menuBorderRadius.multiValued = true; 3349 menuParam.borderRadius = menuBorderRadius; 3350 } 3351 } 3352 ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3353 void ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam) 3354 { 3355 auto enableArrowValue = menuOptions->GetProperty("enableArrow"); 3356 if (enableArrowValue->IsBoolean()) { 3357 menuParam.enableArrow = enableArrowValue->ToBoolean(); 3358 } 3359 3360 auto arrowOffset = menuOptions->GetProperty("arrowOffset"); 3361 CalcDimension offset; 3362 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) { 3363 menuParam.arrowOffset = offset; 3364 } 3365 3366 // if enableArrow is true and placement not set, set placement default value to top. 3367 if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) { 3368 menuParam.placement = Placement::TOP; 3369 } 3370 } 3371 ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)3372 void ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension) 3373 { 3374 CalcDimension dimension; 3375 if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) { 3376 return; 3377 } 3378 3379 if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) { 3380 calcDimension = dimension; 3381 } 3382 } 3383 ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3384 void ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam) 3385 { 3386 auto marginVal = menuOptions->GetProperty("layoutRegionMargin"); 3387 if (!marginVal->IsObject()) { 3388 return; 3389 } 3390 3391 CommonCalcDimension commonCalcDimension; 3392 auto object = JSRef<JSObject>::Cast(marginVal); 3393 ParseLayoutRegionMargin(object->GetProperty(TOP_PROPERTY), commonCalcDimension.top); 3394 ParseLayoutRegionMargin(object->GetProperty(BOTTOM_PROPERTY), commonCalcDimension.bottom); 3395 ParseLayoutRegionMargin(object->GetProperty(LEFT_PROPERTY), commonCalcDimension.left); 3396 ParseLayoutRegionMargin(object->GetProperty(RIGHT_PROPERTY), commonCalcDimension.right); 3397 3398 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() || 3399 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) { 3400 menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding( 3401 commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right); 3402 } 3403 } 3404 GetMenuShowInSubwindow(NG::MenuParam & menuParam)3405 void GetMenuShowInSubwindow(NG::MenuParam& menuParam) 3406 { 3407 menuParam.isShowInSubWindow = false; 3408 auto pipeline = PipelineBase::GetCurrentContext(); 3409 CHECK_NULL_VOID(pipeline); 3410 auto theme = pipeline->GetTheme<SelectTheme>(); 3411 CHECK_NULL_VOID(theme); 3412 menuParam.isShowInSubWindow = theme->GetExpandDisplay(); 3413 } 3414 ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)3415 void ParseMenuParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam) 3416 { 3417 auto offsetVal = menuOptions->GetProperty("offset"); 3418 if (offsetVal->IsObject()) { 3419 auto offsetObj = JSRef<JSObject>::Cast(offsetVal); 3420 JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X)); 3421 JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y)); 3422 CalcDimension dx; 3423 CalcDimension dy; 3424 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) { 3425 menuParam.positionOffset.SetX(dx.ConvertToPx()); 3426 } 3427 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) { 3428 menuParam.positionOffset.SetY(dy.ConvertToPx()); 3429 } 3430 } 3431 3432 auto placementValue = menuOptions->GetProperty("placement"); 3433 if (placementValue->IsNumber()) { 3434 auto placement = placementValue->ToNumber<int32_t>(); 3435 if (placement >= 0 && placement < static_cast<int32_t>(PLACEMENT.size())) { 3436 menuParam.placement = PLACEMENT[placement]; 3437 } 3438 } 3439 3440 auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR)); 3441 Color backgroundColor; 3442 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) { 3443 menuParam.backgroundColor = backgroundColor; 3444 } 3445 3446 auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE)); 3447 if (backgroundBlurStyle->IsNumber()) { 3448 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>(); 3449 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) && 3450 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) { 3451 menuParam.backgroundBlurStyle = blurStyle; 3452 } 3453 } 3454 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 3455 auto onAppearValue = menuOptions->GetProperty("onAppear"); 3456 if (onAppearValue->IsFunction()) { 3457 RefPtr<JsFunction> jsOnAppearFunc = 3458 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue)); 3459 auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() { 3460 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 3461 ACE_SCORING_EVENT("onAppear"); 3462 PipelineContext::SetCallBackNode(node); 3463 func->Execute(); 3464 }; 3465 menuParam.onAppear = std::move(onAppear); 3466 } 3467 3468 auto onDisappearValue = menuOptions->GetProperty("onDisappear"); 3469 if (onDisappearValue->IsFunction()) { 3470 RefPtr<JsFunction> jsOnDisAppearFunc = 3471 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue)); 3472 auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc), 3473 node = frameNode]() { 3474 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 3475 ACE_SCORING_EVENT("onDisappear"); 3476 PipelineContext::SetCallBackNode(node); 3477 func->Execute(); 3478 }; 3479 menuParam.onDisappear = std::move(onDisappear); 3480 } 3481 auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear"); 3482 if (aboutToAppearValue->IsFunction()) { 3483 RefPtr<JsFunction> jsAboutToAppearFunc = 3484 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue)); 3485 auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc), 3486 node = frameNode]() { 3487 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 3488 ACE_SCORING_EVENT("aboutToAppear"); 3489 PipelineContext::SetCallBackNode(node); 3490 func->Execute(); 3491 }; 3492 menuParam.aboutToAppear = std::move(aboutToAppear); 3493 } 3494 3495 auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear"); 3496 if (aboutToDisAppearValue->IsFunction()) { 3497 RefPtr<JsFunction> jsAboutToDisAppearFunc = 3498 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue)); 3499 auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc), 3500 node = frameNode]() { 3501 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 3502 ACE_SCORING_EVENT("aboutToDisappear"); 3503 PipelineContext::SetCallBackNode(node); 3504 func->Execute(); 3505 }; 3506 menuParam.aboutToDisappear = std::move(aboutToDisappear); 3507 } 3508 3509 auto menuTransition = menuOptions->GetProperty("transition"); 3510 menuParam.hasTransitionEffect = false; 3511 if (menuTransition->IsObject()) { 3512 auto obj = JSRef<JSObject>::Cast(menuTransition); 3513 menuParam.hasTransitionEffect = true; 3514 menuParam.transition = ParseChainedTransition(obj, info.GetExecutionContext()); 3515 } 3516 3517 JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow"); 3518 GetMenuShowInSubwindow(menuParam); 3519 if (menuParam.isShowInSubWindow) { 3520 if (showInSubWindowValue->IsBoolean()) { 3521 menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean(); 3522 } 3523 } 3524 ParseMenuArrowParam(menuOptions, menuParam); 3525 ParseMenuBorderRadius(menuOptions, menuParam); 3526 ParseMenuLayoutRegionMarginParam(menuOptions, menuParam); 3527 } 3528 ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)3529 void ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex) 3530 { 3531 if (!info[optionIndex]->IsObject()) { 3532 return; 3533 } 3534 auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]); 3535 JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title); 3536 ParseMenuParam(info, menuOptions, menuParam); 3537 } 3538 ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)3539 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options) 3540 { 3541 constexpr int scaleArraySize = 2; 3542 if (scaleArray->Length() == scaleArraySize) { 3543 auto scalePropertyFrom = scaleArray->GetValueAt(0); 3544 if (scalePropertyFrom->IsNumber()) { 3545 auto scaleFrom = scalePropertyFrom->ToNumber<float>(); 3546 options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom; 3547 } 3548 auto scalePropertyTo = scaleArray->GetValueAt(1); 3549 if (scalePropertyTo->IsNumber()) { 3550 auto scaleTo = scalePropertyTo->ToNumber<float>(); 3551 options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo; 3552 } 3553 } 3554 } 3555 ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)3556 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions, 3557 NG::MenuParam& menuParam) 3558 { 3559 menuParam.previewAnimationOptions.scaleFrom = -1.0f; 3560 menuParam.previewAnimationOptions.scaleTo = -1.0f; 3561 3562 auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions"); 3563 if (!animationOptions->IsEmpty() && animationOptions->IsObject()) { 3564 auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions); 3565 auto scaleProperty = animationOptionsObj->GetProperty("scale"); 3566 if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) { 3567 JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty); 3568 ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions); 3569 } 3570 auto previewTransition = animationOptionsObj->GetProperty("transition"); 3571 menuParam.hasPreviewTransitionEffect = false; 3572 if (previewTransition->IsObject()) { 3573 auto obj = JSRef<JSObject>::Cast(previewTransition); 3574 menuParam.hasPreviewTransitionEffect = true; 3575 menuParam.previewTransition = ParseChainedTransition(obj, info.GetExecutionContext()); 3576 } 3577 if (menuParam.previewMode != MenuPreviewMode::CUSTOM || 3578 menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect || 3579 menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) { 3580 return; 3581 } 3582 auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale"); 3583 menuParam.isShowHoverImage = false; 3584 menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f; 3585 menuParam.hoverImageAnimationOptions.scaleTo = -1.0f; 3586 if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) { 3587 JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty); 3588 ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions); 3589 menuParam.isShowHoverImage = true; 3590 } 3591 } 3592 } 3593 ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)3594 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam, 3595 std::function<void()>& previewBuildFunc) 3596 { 3597 if (!args->IsObject()) { 3598 return; 3599 } 3600 auto menuContentOptions = JSRef<JSObject>::Cast(args); 3601 ParseMenuParam(info, menuContentOptions, menuParam); 3602 RefPtr<JsFunction> previewBuilderFunc; 3603 auto preview = menuContentOptions->GetProperty("preview"); 3604 if (!preview->IsFunction() && !preview->IsNumber()) { 3605 return; 3606 } 3607 3608 if (preview->IsNumber()) { 3609 if (preview->ToNumber<int32_t>() == 1) { 3610 menuParam.previewMode = MenuPreviewMode::IMAGE; 3611 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam); 3612 } 3613 } else { 3614 previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview)); 3615 CHECK_NULL_VOID(previewBuilderFunc); 3616 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 3617 previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc), 3618 node = frameNode]() { 3619 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 3620 ACE_SCORING_EVENT("BuildContextMenuPreviwer"); 3621 PipelineContext::SetCallBackNode(node); 3622 func->Execute(); 3623 }; 3624 menuParam.previewMode = MenuPreviewMode::CUSTOM; 3625 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam); 3626 } 3627 } 3628 ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)3629 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam) 3630 { 3631 size_t builderIndex = 0; 3632 if (info[0]->IsBoolean()) { 3633 menuParam.isShow = info[0]->ToBoolean(); 3634 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE; 3635 menuParam.placement = Placement::BOTTOM_LEFT; 3636 builderIndex = 1; 3637 } else if (info[0]->IsObject()) { 3638 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]); 3639 menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj); 3640 auto isShowObj = callbackObj->GetProperty("value"); 3641 if (isShowObj->IsBoolean()) { 3642 menuParam.isShow = isShowObj->IsBoolean(); 3643 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE; 3644 builderIndex = 1; 3645 } 3646 } 3647 return builderIndex; 3648 } 3649 JsBindMenu(const JSCallbackInfo & info)3650 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info) 3651 { 3652 NG::MenuParam menuParam; 3653 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 3654 menuParam.placement = Placement::BOTTOM_LEFT; 3655 } 3656 size_t builderIndex = 0; 3657 GetMenuShowInSubwindow(menuParam); 3658 if (info.Length() > PARAMETER_LENGTH_FIRST) { 3659 auto jsVal = info[0]; 3660 if (jsVal->IsBoolean()) { 3661 menuParam.isShow = jsVal->ToBoolean(); 3662 menuParam.setShow = true; 3663 builderIndex = 1; 3664 if (info.Length() > PARAMETER_LENGTH_SECOND) { 3665 ParseBindOptionParam(info, menuParam, builderIndex + 1); 3666 } 3667 } else if (jsVal->IsUndefined()) { 3668 menuParam.setShow = true; 3669 menuParam.isShow = false; 3670 builderIndex = 1; 3671 if (info.Length() > PARAMETER_LENGTH_SECOND) { 3672 ParseBindOptionParam(info, menuParam, builderIndex + 1); 3673 } 3674 } else if (jsVal->IsObject()) { 3675 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal); 3676 menuParam.onStateChange = ParseDoubleBindCallback(info, callbackObj); 3677 auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)); 3678 if (isShowObj->IsBoolean()) { 3679 menuParam.isShow = isShowObj->ToBoolean(); 3680 menuParam.setShow = true; 3681 builderIndex = 1; 3682 if (info.Length() > PARAMETER_LENGTH_SECOND) { 3683 ParseBindOptionParam(info, menuParam, builderIndex + 1); 3684 } 3685 } else { 3686 builderIndex = 0; 3687 ParseBindOptionParam(info, menuParam, builderIndex + 1); 3688 } 3689 } 3690 } 3691 3692 if (info[builderIndex]->IsArray()) { 3693 std::vector<NG::OptionParam> optionsParam = ParseBindOptionParam(info, builderIndex); 3694 ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam); 3695 } else if (info[builderIndex]->IsObject()) { 3696 // CustomBuilder 3697 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]); 3698 auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER)); 3699 if (!builder->IsFunction()) { 3700 return; 3701 } 3702 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 3703 3704 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 3705 CHECK_NULL_VOID(builderFunc); 3706 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() { 3707 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 3708 ACE_SCORING_EVENT("BuildMenu"); 3709 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 3710 func->Execute(); 3711 }; 3712 ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam); 3713 } 3714 } 3715 JsPadding(const JSCallbackInfo & info)3716 void JSViewAbstract::JsPadding(const JSCallbackInfo& info) 3717 { 3718 ParseMarginOrPadding(info, EdgeType::PADDING); 3719 } 3720 JsMargin(const JSCallbackInfo & info)3721 void JSViewAbstract::JsMargin(const JSCallbackInfo& info) 3722 { 3723 ParseMarginOrPadding(info, EdgeType::MARGIN); 3724 } 3725 ParseMarginOrPadding(const JSCallbackInfo & info,EdgeType type)3726 void JSViewAbstract::ParseMarginOrPadding(const JSCallbackInfo& info, EdgeType type) 3727 { 3728 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::STRING, 3729 JSCallbackInfoType::NUMBER }; 3730 auto jsVal = info[0]; 3731 if (!CheckJSCallbackInfo("MarginOrPadding", jsVal, checkList)) { 3732 auto resetDimension = CalcDimension(0.0); 3733 if (type == EdgeType::MARGIN) { 3734 ViewAbstractModel::GetInstance()->SetMargin(resetDimension); 3735 } else if (type == EdgeType::PADDING) { 3736 ViewAbstractModel::GetInstance()->SetPadding(resetDimension); 3737 } else if (type == EdgeType::SAFE_AREA_PADDING) { 3738 ViewAbstractModel::GetInstance()->ResetSafeAreaPadding(); 3739 } 3740 return; 3741 } 3742 3743 if (jsVal->IsObject()) { 3744 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal); 3745 3746 CalcDimension length; 3747 if (type == EdgeType::SAFE_AREA_PADDING && ParseJsLengthMetrics(paddingObj, length)) { 3748 ViewAbstractModel::GetInstance()->SetSafeAreaPadding(length); 3749 return; 3750 } 3751 3752 CommonCalcDimension commonCalcDimension; 3753 auto useLengthMetrics = ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension); 3754 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() || 3755 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) { 3756 if (type == EdgeType::MARGIN) { 3757 if (useLengthMetrics) { 3758 ViewAbstractModel::GetInstance()->SetMargins(GetLocalizedPadding(commonCalcDimension.top, 3759 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right)); 3760 } else { 3761 ViewAbstractModel::GetInstance()->SetMargins(commonCalcDimension.top, commonCalcDimension.bottom, 3762 commonCalcDimension.left, commonCalcDimension.right); 3763 } 3764 } else if (type == EdgeType::PADDING) { 3765 if (useLengthMetrics) { 3766 ViewAbstractModel::GetInstance()->SetPaddings(GetLocalizedPadding(commonCalcDimension.top, 3767 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right)); 3768 } else { 3769 ViewAbstractModel::GetInstance()->SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom, 3770 commonCalcDimension.left, commonCalcDimension.right); 3771 } 3772 } else if (type == EdgeType::SAFE_AREA_PADDING) { 3773 if (useLengthMetrics) { 3774 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(GetLocalizedPadding(commonCalcDimension.top, 3775 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right)); 3776 } else { 3777 ViewAbstractModel::GetInstance()->SetSafeAreaPaddings(commonCalcDimension.top, 3778 commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right); 3779 } 3780 } 3781 return; 3782 } 3783 } 3784 3785 CalcDimension length; 3786 if (!ParseJsDimensionVp(jsVal, length)) { 3787 // use default value. 3788 length.Reset(); 3789 } 3790 if (type == EdgeType::MARGIN) { 3791 ViewAbstractModel::GetInstance()->SetMargin(length); 3792 } else if (type == EdgeType::PADDING) { 3793 ViewAbstractModel::GetInstance()->SetPadding(length); 3794 } 3795 } 3796 GetLocalizedPadding(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & start,const std::optional<CalcDimension> & end)3797 NG::PaddingProperty JSViewAbstract::GetLocalizedPadding(const std::optional<CalcDimension>& top, 3798 const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& start, 3799 const std::optional<CalcDimension>& end) 3800 { 3801 NG::PaddingProperty paddings; 3802 if (start.has_value()) { 3803 if (start.value().Unit() == DimensionUnit::CALC) { 3804 paddings.start = NG::CalcLength(start.value().CalcValue()); 3805 } else { 3806 paddings.start = NG::CalcLength(start.value()); 3807 } 3808 } 3809 if (bottom.has_value()) { 3810 if (bottom.value().Unit() == DimensionUnit::CALC) { 3811 paddings.bottom = NG::CalcLength(bottom.value().CalcValue()); 3812 } else { 3813 paddings.bottom = NG::CalcLength(bottom.value()); 3814 } 3815 } 3816 if (end.has_value()) { 3817 if (end.value().Unit() == DimensionUnit::CALC) { 3818 paddings.end = NG::CalcLength(end.value().CalcValue()); 3819 } else { 3820 paddings.end = NG::CalcLength(end.value()); 3821 } 3822 } 3823 if (top.has_value()) { 3824 if (top.value().Unit() == DimensionUnit::CALC) { 3825 paddings.top = NG::CalcLength(top.value().CalcValue()); 3826 } else { 3827 paddings.top = NG::CalcLength(top.value()); 3828 } 3829 } 3830 return paddings; 3831 } 3832 ParseMarginOrPaddingCorner(JSRef<JSObject> obj,std::optional<CalcDimension> & top,std::optional<CalcDimension> & bottom,std::optional<CalcDimension> & left,std::optional<CalcDimension> & right)3833 void JSViewAbstract::ParseMarginOrPaddingCorner(JSRef<JSObject> obj, std::optional<CalcDimension>& top, 3834 std::optional<CalcDimension>& bottom, std::optional<CalcDimension>& left, std::optional<CalcDimension>& right) 3835 { 3836 CalcDimension leftDimen; 3837 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), leftDimen)) { 3838 left = leftDimen; 3839 } 3840 CalcDimension rightDimen; 3841 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), rightDimen)) { 3842 right = rightDimen; 3843 } 3844 CalcDimension topDimen; 3845 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), topDimen)) { 3846 top = topDimen; 3847 } 3848 CalcDimension bottomDimen; 3849 if (ParseJsDimensionVp(obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottomDimen)) { 3850 bottom = bottomDimen; 3851 } 3852 } 3853 ParseLocalizedMarginOrLocalizedPaddingCorner(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)3854 void JSViewAbstract::ParseLocalizedMarginOrLocalizedPaddingCorner( 3855 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension) 3856 { 3857 auto jsStart = object->GetProperty(static_cast<int32_t>(ArkUIIndex::START)); 3858 if (jsStart->IsObject()) { 3859 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(jsStart); 3860 CalcDimension calcDimension; 3861 if (ParseJsLengthMetrics(startObj, calcDimension)) { 3862 localizedCalcDimension.start = calcDimension; 3863 } 3864 } 3865 auto jsEnd = object->GetProperty(static_cast<int32_t>(ArkUIIndex::END)); 3866 if (jsEnd->IsObject()) { 3867 JSRef<JSObject> endObj = JSRef<JSObject>::Cast(jsEnd); 3868 CalcDimension calcDimension; 3869 if (ParseJsLengthMetrics(endObj, calcDimension)) { 3870 localizedCalcDimension.end = calcDimension; 3871 } 3872 } 3873 auto jsTop = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)); 3874 if (jsTop->IsObject()) { 3875 JSRef<JSObject> topObj = JSRef<JSObject>::Cast(jsTop); 3876 CalcDimension calcDimension; 3877 if (ParseJsLengthMetrics(topObj, calcDimension)) { 3878 localizedCalcDimension.top = calcDimension; 3879 } 3880 } 3881 auto jsBottom = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)); 3882 if (jsBottom->IsObject()) { 3883 JSRef<JSObject> bottomObj = JSRef<JSObject>::Cast(jsBottom); 3884 CalcDimension calcDimension; 3885 if (ParseJsLengthMetrics(bottomObj, calcDimension)) { 3886 localizedCalcDimension.bottom = calcDimension; 3887 } 3888 } 3889 } 3890 ParseCommonMarginOrPaddingCorner(const JSRef<JSObject> & object,CommonCalcDimension & commonCalcDimension)3891 bool JSViewAbstract::ParseCommonMarginOrPaddingCorner( 3892 const JSRef<JSObject>& object, CommonCalcDimension& commonCalcDimension) 3893 { 3894 if (CheckLengthMetrics(object)) { 3895 LocalizedCalcDimension localizedCalcDimension; 3896 ParseLocalizedMarginOrLocalizedPaddingCorner(object, localizedCalcDimension); 3897 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft(); 3898 commonCalcDimension.top = localizedCalcDimension.top; 3899 commonCalcDimension.bottom = localizedCalcDimension.bottom; 3900 commonCalcDimension.left = isRightToLeft ? localizedCalcDimension.end : localizedCalcDimension.start; 3901 commonCalcDimension.right = isRightToLeft ? localizedCalcDimension.start : localizedCalcDimension.end; 3902 return true; 3903 } 3904 ParseMarginOrPaddingCorner(object, commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, 3905 commonCalcDimension.right); 3906 return false; 3907 } 3908 JsOutline(const JSCallbackInfo & info)3909 void JSViewAbstract::JsOutline(const JSCallbackInfo& info) 3910 { 3911 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 3912 auto jsVal = info[0]; 3913 if (!CheckJSCallbackInfo("JsOutline", jsVal, checkList)) { 3914 CalcDimension borderWidth; 3915 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth); 3916 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK); 3917 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderWidth); 3918 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID); 3919 return; 3920 } 3921 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal); 3922 auto valueOuterWidth = object->GetProperty("width"); 3923 if (!valueOuterWidth->IsUndefined()) { 3924 ParseOuterBorderWidth(valueOuterWidth); 3925 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 3926 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({}); 3927 } 3928 3929 // use default value when undefined. 3930 ParseOuterBorderColor(object->GetProperty("color")); 3931 3932 auto valueOuterRadius = object->GetProperty("radius"); 3933 if (!valueOuterRadius->IsUndefined()) { 3934 ParseOuterBorderRadius(valueOuterRadius); 3935 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 3936 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {}); 3937 } 3938 // use default value when undefined. 3939 ParseOuterBorderStyle(object->GetProperty("style")); 3940 info.ReturnSelf(); 3941 } 3942 JsOutlineWidth(const JSCallbackInfo & info)3943 void JSViewAbstract::JsOutlineWidth(const JSCallbackInfo& info) 3944 { 3945 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER, 3946 JSCallbackInfoType::OBJECT }; 3947 auto jsVal = info[0]; 3948 if (!CheckJSCallbackInfo("JsOutlineWidth", jsVal, checkList)) { 3949 ViewAbstractModel::GetInstance()->SetOuterBorderWidth({}); 3950 return; 3951 } 3952 ParseOuterBorderWidth(jsVal); 3953 } 3954 JsOutlineColor(const JSCallbackInfo & info)3955 void JSViewAbstract::JsOutlineColor(const JSCallbackInfo& info) 3956 { 3957 ParseOuterBorderColor(info[0]); 3958 } 3959 JsOutlineRadius(const JSCallbackInfo & info)3960 void JSViewAbstract::JsOutlineRadius(const JSCallbackInfo& info) 3961 { 3962 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER, 3963 JSCallbackInfoType::OBJECT }; 3964 auto jsVal = info[0]; 3965 if (!CheckJSCallbackInfo("JsOutlineRadius", jsVal, checkList)) { 3966 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(Dimension {}); 3967 return; 3968 } 3969 ParseOuterBorderRadius(jsVal); 3970 } 3971 JsOutlineStyle(const JSCallbackInfo & info)3972 void JSViewAbstract::JsOutlineStyle(const JSCallbackInfo& info) 3973 { 3974 ParseOuterBorderStyle(info[0]); 3975 } 3976 JsBorder(const JSCallbackInfo & info)3977 void JSViewAbstract::JsBorder(const JSCallbackInfo& info) 3978 { 3979 if (!info[0]->IsObject()) { 3980 CalcDimension borderWidth; 3981 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth); 3982 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK); 3983 ViewAbstractModel::GetInstance()->SetBorderRadius(borderWidth); 3984 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID); 3985 ViewAbstractModel::GetInstance()->SetDashGap(Dimension(-1)); 3986 ViewAbstractModel::GetInstance()->SetDashWidth(Dimension(-1)); 3987 return; 3988 } 3989 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]); 3990 3991 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)); 3992 if (!valueWidth->IsUndefined()) { 3993 ParseBorderWidth(valueWidth); 3994 } 3995 3996 // use default value when undefined. 3997 ParseBorderColor(object->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR))); 3998 3999 auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)); 4000 if (!valueRadius->IsUndefined()) { 4001 ParseBorderRadius(valueRadius); 4002 } 4003 // use default value when undefined. 4004 ParseBorderStyle(object->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE))); 4005 4006 auto dashGap = object->GetProperty("dashGap"); 4007 if (!dashGap->IsUndefined()) { 4008 ParseDashGap(dashGap); 4009 } 4010 auto dashWidth = object->GetProperty("dashWidth"); 4011 if (!dashWidth->IsUndefined()) { 4012 ParseDashWidth(dashWidth); 4013 } 4014 4015 info.ReturnSelf(); 4016 } 4017 IsBorderWidthObjUndefined(const JSRef<JSVal> & args)4018 bool IsBorderWidthObjUndefined(const JSRef<JSVal>& args) 4019 { 4020 if (!args->IsObject()) { 4021 return false; 4022 } 4023 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args); 4024 if (obj->IsUndefined()) { 4025 return true; 4026 } 4027 // filter dynamic $r raw input 4028 if (obj->HasProperty("id")) { 4029 return false; 4030 } 4031 if ((!obj->HasProperty(TOP_PROPERTY) || obj->GetProperty(TOP_PROPERTY)->IsUndefined()) && 4032 (!obj->HasProperty(RIGHT_PROPERTY) || obj->GetProperty(RIGHT_PROPERTY)->IsUndefined()) && 4033 (!obj->HasProperty(BOTTOM_PROPERTY) || obj->GetProperty(BOTTOM_PROPERTY)->IsUndefined()) && 4034 (!obj->HasProperty(LEFT_PROPERTY) || obj->GetProperty(LEFT_PROPERTY)->IsUndefined()) && 4035 (!obj->HasProperty(START_PROPERTY) || obj->GetProperty(START_PROPERTY)->IsUndefined()) && 4036 (!obj->HasProperty(END_PROPERTY) || obj->GetProperty(END_PROPERTY)->IsUndefined())) { 4037 return true; 4038 } 4039 4040 return false; 4041 } 4042 JsBorderWidth(const JSCallbackInfo & info)4043 void JSViewAbstract::JsBorderWidth(const JSCallbackInfo& info) 4044 { 4045 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER, 4046 JSCallbackInfoType::OBJECT }; 4047 auto jsVal = info[0]; 4048 if (!CheckJSCallbackInfo("JsBorderWidth", jsVal, checkList)) { 4049 ViewAbstractModel::GetInstance()->SetBorderWidth({}); 4050 return; 4051 } 4052 ParseBorderWidth(jsVal); 4053 } 4054 ParseBorderWidth(const JSRef<JSVal> & args)4055 void JSViewAbstract::ParseBorderWidth(const JSRef<JSVal>& args) 4056 { 4057 CalcDimension borderWidth; 4058 if (ParseJsDimensionVp(args, borderWidth)) { 4059 if (borderWidth.IsNegative()) { 4060 borderWidth.Reset(); 4061 } 4062 if (borderWidth.Unit() == DimensionUnit::PERCENT) { 4063 borderWidth.Reset(); 4064 } 4065 ViewAbstractModel::GetInstance()->SetBorderWidth(borderWidth); 4066 } else if (args->IsObject()) { 4067 if (IsBorderWidthObjUndefined(args)) { 4068 ViewAbstractModel::GetInstance()->SetBorderWidth({}); 4069 return; 4070 } 4071 CommonCalcDimension commonCalcDimension; 4072 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args); 4073 if (ParseCommonEdgeWidths(obj, commonCalcDimension, true)) { 4074 ViewAbstractModel::GetInstance()->SetBorderWidth(commonCalcDimension.left, commonCalcDimension.right, 4075 commonCalcDimension.top, commonCalcDimension.bottom, true); 4076 return; 4077 } 4078 ViewAbstractModel::GetInstance()->SetBorderWidth( 4079 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom); 4080 } else { 4081 return; 4082 } 4083 } 4084 ParseDashGap(const JSRef<JSVal> & args)4085 void JSViewAbstract::ParseDashGap(const JSRef<JSVal>& args) 4086 { 4087 CalcDimension dashGap; 4088 if (ParseLengthMetricsToDimension(args, dashGap)) { 4089 if (dashGap.Unit() == DimensionUnit::PERCENT) { 4090 dashGap.Reset(); 4091 } 4092 ViewAbstractModel::GetInstance()->SetDashGap(dashGap); 4093 } else if (args->IsObject()) { 4094 CommonCalcDimension commonCalcDimension; 4095 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args); 4096 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension); 4097 ViewAbstractModel::GetInstance()->SetDashGap( 4098 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom); 4099 } else { 4100 dashGap.Reset(); 4101 ViewAbstractModel::GetInstance()->SetDashGap(dashGap); 4102 } 4103 } 4104 ParseDashWidth(const JSRef<JSVal> & args)4105 void JSViewAbstract::ParseDashWidth(const JSRef<JSVal>& args) 4106 { 4107 CalcDimension dashWidth; 4108 if (ParseLengthMetricsToDimension(args, dashWidth)) { 4109 if (dashWidth.Unit() == DimensionUnit::PERCENT) { 4110 dashWidth.Reset(); 4111 } 4112 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth); 4113 } else if (args->IsObject()) { 4114 CommonCalcDimension commonCalcDimension; 4115 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args); 4116 ParseCommonEdgeWidthsForDashParams(obj, commonCalcDimension); 4117 ViewAbstractModel::GetInstance()->SetDashWidth( 4118 commonCalcDimension.left, commonCalcDimension.right, commonCalcDimension.top, commonCalcDimension.bottom); 4119 } else { 4120 dashWidth.Reset(); 4121 ViewAbstractModel::GetInstance()->SetDashWidth(dashWidth); 4122 } 4123 } 4124 ParseOuterBorderWidth(const JSRef<JSVal> & args)4125 void JSViewAbstract::ParseOuterBorderWidth(const JSRef<JSVal>& args) 4126 { 4127 CalcDimension borderWidth; 4128 if (ParseJsDimensionVp(args, borderWidth)) { 4129 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) { 4130 borderWidth.Reset(); 4131 } 4132 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(borderWidth); 4133 } else if (args->IsObject()) { 4134 std::optional<CalcDimension> leftDimen; 4135 std::optional<CalcDimension> rightDimen; 4136 std::optional<CalcDimension> topDimen; 4137 std::optional<CalcDimension> bottomDimen; 4138 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4139 CalcDimension left; 4140 if (ParseJsDimensionVp(object->GetProperty("left"), left) && left.IsNonNegative()) { 4141 if (left.Unit() == DimensionUnit::PERCENT) { 4142 left.Reset(); 4143 } 4144 leftDimen = left; 4145 } 4146 CalcDimension right; 4147 if (ParseJsDimensionVp(object->GetProperty("right"), right) && right.IsNonNegative()) { 4148 if (right.Unit() == DimensionUnit::PERCENT) { 4149 right.Reset(); 4150 } 4151 rightDimen = right; 4152 } 4153 CalcDimension top; 4154 if (ParseJsDimensionVp(object->GetProperty("top"), top) && top.IsNonNegative()) { 4155 if (top.Unit() == DimensionUnit::PERCENT) { 4156 top.Reset(); 4157 } 4158 topDimen = top; 4159 } 4160 CalcDimension bottom; 4161 if (ParseJsDimensionVp(object->GetProperty("bottom"), bottom) && bottom.IsNonNegative()) { 4162 if (bottom.Unit() == DimensionUnit::PERCENT) { 4163 bottom.Reset(); 4164 } 4165 bottomDimen = bottom; 4166 } 4167 ViewAbstractModel::GetInstance()->SetOuterBorderWidth(leftDimen, rightDimen, topDimen, bottomDimen); 4168 } else { 4169 return; 4170 } 4171 } 4172 JsBorderImage(const JSCallbackInfo & info)4173 void JSViewAbstract::JsBorderImage(const JSCallbackInfo& info) 4174 { 4175 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 4176 auto jsVal = info[0]; 4177 if (!CheckJSCallbackInfo("JsBorderImage", jsVal, checkList)) { 4178 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>(); 4179 uint8_t imageBorderBitsets = 0; 4180 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets); 4181 return; 4182 } 4183 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsVal); 4184 CHECK_NULL_VOID(!object->IsEmpty()); 4185 4186 RefPtr<BorderImage> borderImage = AceType::MakeRefPtr<BorderImage>(); 4187 uint8_t imageBorderBitsets = 0; 4188 4189 auto valueSource = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SOURCE)); 4190 CHECK_NULL_VOID((valueSource->IsString() || valueSource->IsObject())); 4191 std::string srcResult; 4192 std::string bundleName; 4193 std::string moduleName; 4194 GetJsMediaBundleInfo(valueSource, bundleName, moduleName); 4195 borderImage->SetBundleName(bundleName); 4196 borderImage->SetModuleName(moduleName); 4197 if (valueSource->IsString() && !valueSource->ToString().empty()) { 4198 borderImage->SetSrc(valueSource->ToString()); 4199 imageBorderBitsets |= BorderImage::SOURCE_BIT; 4200 } else if (valueSource->IsObject() && ParseJsMedia(valueSource, srcResult)) { 4201 borderImage->SetSrc(srcResult); 4202 imageBorderBitsets |= BorderImage::SOURCE_BIT; 4203 } else if (valueSource->IsObject()) { 4204 ParseBorderImageLinearGradient(valueSource, imageBorderBitsets); 4205 } 4206 auto valueOutset = object->GetProperty("outset"); 4207 if (valueOutset->IsNumber() || valueOutset->IsString() || valueOutset->IsObject()) { 4208 imageBorderBitsets |= BorderImage::OUTSET_BIT; 4209 ParseBorderImageOutset(valueOutset, borderImage); 4210 } 4211 auto valueRepeat = object->GetProperty(static_cast<int32_t>(ArkUIIndex::REPEAT)); 4212 if (!valueRepeat->IsNull()) { 4213 imageBorderBitsets |= BorderImage::REPEAT_BIT; 4214 ParseBorderImageRepeat(valueRepeat, borderImage); 4215 } 4216 auto valueSlice = object->GetProperty(static_cast<int32_t>(ArkUIIndex::SLICE)); 4217 if (valueSlice->IsNumber() || valueSlice->IsString() || valueSlice->IsObject()) { 4218 imageBorderBitsets |= BorderImage::SLICE_BIT; 4219 ParseBorderImageSlice(valueSlice, borderImage); 4220 } 4221 auto valueWidth = object->GetProperty(static_cast<int32_t>(ArkUIIndex::WIDTH)); 4222 if (valueWidth->IsNumber() || valueWidth->IsString() || valueWidth->IsObject()) { 4223 imageBorderBitsets |= BorderImage::WIDTH_BIT; 4224 ParseBorderImageWidth(valueWidth, borderImage); 4225 } 4226 auto needFill = object->GetProperty(static_cast<int32_t>(ArkUIIndex::FILL)); 4227 if (needFill->IsBoolean()) { 4228 borderImage->SetNeedFillCenter(needFill->ToBoolean()); 4229 } 4230 ViewAbstractModel::GetInstance()->SetBorderImage(borderImage, imageBorderBitsets); 4231 info.ReturnSelf(); 4232 } 4233 ParseBorderImageDimension(const JSRef<JSVal> & args,BorderImage::BorderImageOption & borderImageDimension)4234 bool JSViewAbstract::ParseBorderImageDimension( 4235 const JSRef<JSVal>& args, BorderImage::BorderImageOption& borderImageDimension) 4236 { 4237 if (!args->IsObject()) { 4238 return false; 4239 } 4240 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4241 if (CheckLengthMetrics(object)) { 4242 LocalizedCalcDimension localizedCalcDimension; 4243 ParseBorderImageLengthMetrics(object, localizedCalcDimension); 4244 borderImageDimension.topDimension = localizedCalcDimension.top; 4245 borderImageDimension.bottomDimension = localizedCalcDimension.bottom; 4246 borderImageDimension.startDimension = localizedCalcDimension.start; 4247 borderImageDimension.endDimension = localizedCalcDimension.end; 4248 return true; 4249 } 4250 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT), 4251 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP), 4252 static_cast<int32_t>(ArkUIIndex::BOTTOM) }; 4253 for (uint32_t i = 0; i < keys.size(); i++) { 4254 CalcDimension currentDimension; 4255 auto dimensionValue = object->GetProperty(keys.at(i)); 4256 if (ParseJsDimensionVp(dimensionValue, currentDimension)) { 4257 auto direction = static_cast<BorderImageDirection>(i); 4258 switch (direction) { 4259 case BorderImageDirection::LEFT: 4260 borderImageDimension.leftDimension = currentDimension; 4261 break; 4262 case BorderImageDirection::RIGHT: 4263 borderImageDimension.rightDimension = currentDimension; 4264 break; 4265 case BorderImageDirection::TOP: 4266 borderImageDimension.topDimension = currentDimension; 4267 break; 4268 case BorderImageDirection::BOTTOM: 4269 borderImageDimension.bottomDimension = currentDimension; 4270 break; 4271 default: 4272 break; 4273 } 4274 } 4275 } 4276 return false; 4277 } 4278 ParseBorderImageLengthMetrics(const JSRef<JSObject> & object,LocalizedCalcDimension & localizedCalcDimension)4279 void JSViewAbstract::ParseBorderImageLengthMetrics( 4280 const JSRef<JSObject>& object, LocalizedCalcDimension& localizedCalcDimension) 4281 { 4282 for (uint32_t i = 0; i < LENGTH_METRICS_KEYS.size(); i++) { 4283 auto jsVal = object->GetProperty(LENGTH_METRICS_KEYS.at(i)); 4284 if (!jsVal->IsObject()) { 4285 continue; 4286 } 4287 JSRef<JSObject> lengthMetricsObj = JSRef<JSObject>::Cast(jsVal); 4288 CalcDimension calcDimension; 4289 if (ParseJsLengthMetrics(lengthMetricsObj, calcDimension)) { 4290 auto direction = static_cast<BorderImageDirection>(i); 4291 switch (direction) { 4292 case BorderImageDirection::LEFT: 4293 localizedCalcDimension.start = calcDimension; 4294 break; 4295 case BorderImageDirection::RIGHT: 4296 localizedCalcDimension.end = calcDimension; 4297 break; 4298 case BorderImageDirection::TOP: 4299 localizedCalcDimension.top = calcDimension; 4300 break; 4301 case BorderImageDirection::BOTTOM: 4302 localizedCalcDimension.bottom = calcDimension; 4303 break; 4304 default: 4305 break; 4306 } 4307 } 4308 } 4309 } 4310 CheckJSCallbackInfo(const std::string & callerName,const JSRef<JSVal> & tmpInfo,std::vector<JSCallbackInfoType> & infoTypes)4311 bool JSViewAbstract::CheckJSCallbackInfo( 4312 const std::string& callerName, const JSRef<JSVal>& tmpInfo, std::vector<JSCallbackInfoType>& infoTypes) 4313 { 4314 bool typeVerified = false; 4315 std::string unrecognizedType; 4316 for (const auto& infoType : infoTypes) { 4317 switch (infoType) { 4318 case JSCallbackInfoType::STRING: 4319 if (tmpInfo->IsString()) { 4320 typeVerified = true; 4321 } else { 4322 unrecognizedType += "string|"; 4323 } 4324 break; 4325 case JSCallbackInfoType::NUMBER: 4326 if (tmpInfo->IsNumber()) { 4327 typeVerified = true; 4328 } else { 4329 unrecognizedType += "number|"; 4330 } 4331 break; 4332 case JSCallbackInfoType::OBJECT: 4333 if (tmpInfo->IsObject()) { 4334 typeVerified = true; 4335 } else { 4336 unrecognizedType += "object|"; 4337 } 4338 break; 4339 case JSCallbackInfoType::FUNCTION: 4340 if (tmpInfo->IsFunction()) { 4341 typeVerified = true; 4342 } else { 4343 unrecognizedType += "Function|"; 4344 } 4345 break; 4346 default: 4347 break; 4348 } 4349 } 4350 if (!typeVerified) { 4351 LOGD("%{public}s: info[0] is not a [%{public}s]", callerName.c_str(), 4352 unrecognizedType.substr(0, unrecognizedType.size() - 1).c_str()); 4353 } 4354 return typeVerified || infoTypes.size() == 0; 4355 } 4356 UpdateGradientWithDirection(NG::Gradient & lineGradient,NG::GradientDirection direction)4357 void JSViewAbstract::UpdateGradientWithDirection(NG::Gradient& lineGradient, NG::GradientDirection direction) 4358 { 4359 switch (direction) { 4360 case NG::GradientDirection::LEFT: 4361 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT; 4362 break; 4363 case NG::GradientDirection::RIGHT: 4364 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT; 4365 break; 4366 case NG::GradientDirection::TOP: 4367 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP; 4368 break; 4369 case NG::GradientDirection::BOTTOM: 4370 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM; 4371 break; 4372 case NG::GradientDirection::LEFT_TOP: 4373 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT; 4374 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP; 4375 break; 4376 case NG::GradientDirection::LEFT_BOTTOM: 4377 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT; 4378 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM; 4379 break; 4380 case NG::GradientDirection::RIGHT_TOP: 4381 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT; 4382 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP; 4383 break; 4384 case NG::GradientDirection::RIGHT_BOTTOM: 4385 lineGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT; 4386 lineGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM; 4387 break; 4388 case NG::GradientDirection::NONE: 4389 case NG::GradientDirection::START_TO_END: 4390 case NG::GradientDirection::END_TO_START: 4391 default: 4392 break; 4393 } 4394 } 4395 ParseBorderImageLinearGradient(const JSRef<JSVal> & args,uint8_t & bitset)4396 void JSViewAbstract::ParseBorderImageLinearGradient(const JSRef<JSVal>& args, uint8_t& bitset) 4397 { 4398 if (!args->IsObject()) { 4399 return; 4400 } 4401 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args); 4402 NG::Gradient lineGradient; 4403 lineGradient.CreateGradientWithType(NG::GradientType::LINEAR); 4404 // angle 4405 std::optional<float> degree; 4406 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 4407 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree); 4408 } else { 4409 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f); 4410 } 4411 if (degree) { 4412 lineGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX); 4413 degree.reset(); 4414 } 4415 // direction 4416 auto direction = static_cast<NG::GradientDirection>( 4417 jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::DIRECTION), 4418 static_cast<int32_t>(NG::GradientDirection::NONE))); 4419 UpdateGradientWithDirection(lineGradient, direction); 4420 auto repeating = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::REPEATING), false); 4421 lineGradient.SetRepeat(repeating); 4422 NewGetJsGradientColorStops(lineGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS))); 4423 ViewAbstractModel::GetInstance()->SetBorderImageGradient(lineGradient); 4424 bitset |= BorderImage::GRADIENT_BIT; 4425 } 4426 ParseBorderImageRepeat(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4427 void JSViewAbstract::ParseBorderImageRepeat(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage) 4428 { 4429 auto repeatString = args->ToString(); 4430 if (repeatString == "Repeat") { 4431 borderImage->SetRepeatMode(BorderImageRepeat::REPEAT); 4432 } else if (repeatString == "Round") { 4433 borderImage->SetRepeatMode(BorderImageRepeat::ROUND); 4434 } else if (repeatString == "Space") { 4435 borderImage->SetRepeatMode(BorderImageRepeat::SPACE); 4436 } else { 4437 borderImage->SetRepeatMode(BorderImageRepeat::STRETCH); 4438 } 4439 } 4440 ParseBorderImageOutset(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4441 void JSViewAbstract::ParseBorderImageOutset(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage) 4442 { 4443 CalcDimension outsetDimension; 4444 if (ParseJsDimensionVp(args, outsetDimension)) { 4445 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, outsetDimension); 4446 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, outsetDimension); 4447 borderImage->SetEdgeOutset(BorderImageDirection::TOP, outsetDimension); 4448 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, outsetDimension); 4449 return; 4450 } 4451 BorderImage::BorderImageOption option; 4452 ParseBorderImageDimension(args, option); 4453 if (option.startDimension.has_value()) { 4454 borderImage->SetEdgeOutset(BorderImageDirection::START, option.startDimension.value()); 4455 } 4456 if (option.endDimension.has_value()) { 4457 borderImage->SetEdgeOutset(BorderImageDirection::END, option.endDimension.value()); 4458 } 4459 if (option.leftDimension.has_value()) { 4460 borderImage->SetEdgeOutset(BorderImageDirection::LEFT, option.leftDimension.value()); 4461 } 4462 if (option.rightDimension.has_value()) { 4463 borderImage->SetEdgeOutset(BorderImageDirection::RIGHT, option.rightDimension.value()); 4464 } 4465 if (option.topDimension.has_value()) { 4466 borderImage->SetEdgeOutset(BorderImageDirection::TOP, option.topDimension.value()); 4467 } 4468 if (option.bottomDimension.has_value()) { 4469 borderImage->SetEdgeOutset(BorderImageDirection::BOTTOM, option.bottomDimension.value()); 4470 } 4471 } 4472 ParseBorderImageSlice(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4473 void JSViewAbstract::ParseBorderImageSlice(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage) 4474 { 4475 CalcDimension sliceDimension; 4476 if (ParseJsDimensionVp(args, sliceDimension)) { 4477 borderImage->SetEdgeSlice(BorderImageDirection::LEFT, sliceDimension); 4478 borderImage->SetEdgeSlice(BorderImageDirection::RIGHT, sliceDimension); 4479 borderImage->SetEdgeSlice(BorderImageDirection::TOP, sliceDimension); 4480 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, sliceDimension); 4481 return; 4482 } 4483 if (!args->IsObject()) { 4484 return; 4485 } 4486 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4487 if (CheckLengthMetrics(object)) { 4488 LocalizedCalcDimension localizedCalcDimension; 4489 ParseBorderImageLengthMetrics(object, localizedCalcDimension); 4490 if (localizedCalcDimension.top.has_value()) { 4491 borderImage->SetEdgeSlice(BorderImageDirection::TOP, localizedCalcDimension.top.value()); 4492 } 4493 if (localizedCalcDimension.bottom.has_value()) { 4494 borderImage->SetEdgeSlice(BorderImageDirection::BOTTOM, localizedCalcDimension.bottom.value()); 4495 } 4496 if (localizedCalcDimension.start.has_value()) { 4497 borderImage->SetEdgeSlice(BorderImageDirection::START, localizedCalcDimension.start.value()); 4498 } 4499 if (localizedCalcDimension.end.has_value()) { 4500 borderImage->SetEdgeSlice(BorderImageDirection::END, localizedCalcDimension.end.value()); 4501 } 4502 return; 4503 } 4504 static std::array<int32_t, DIRECTION_COUNT> keys = { static_cast<int32_t>(ArkUIIndex::LEFT), 4505 static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP), 4506 static_cast<int32_t>(ArkUIIndex::BOTTOM) }; 4507 for (uint32_t i = 0; i < keys.size(); i++) { 4508 auto dimensionValue = object->GetProperty(keys.at(i)); 4509 if (ParseJsDimensionVp(dimensionValue, sliceDimension)) { 4510 borderImage->SetEdgeSlice(static_cast<BorderImageDirection>(i), sliceDimension); 4511 } 4512 } 4513 } 4514 ParseBorderImageWidth(const JSRef<JSVal> & args,RefPtr<BorderImage> & borderImage)4515 void JSViewAbstract::ParseBorderImageWidth(const JSRef<JSVal>& args, RefPtr<BorderImage>& borderImage) 4516 { 4517 CalcDimension widthDimension; 4518 if (ParseJsDimensionVp(args, widthDimension)) { 4519 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, widthDimension); 4520 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, widthDimension); 4521 borderImage->SetEdgeWidth(BorderImageDirection::TOP, widthDimension); 4522 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, widthDimension); 4523 return; 4524 } 4525 4526 BorderImage::BorderImageOption option; 4527 ParseBorderImageDimension(args, option); 4528 if (option.startDimension.has_value()) { 4529 borderImage->SetEdgeWidth(BorderImageDirection::START, option.startDimension.value()); 4530 } 4531 if (option.endDimension.has_value()) { 4532 borderImage->SetEdgeWidth(BorderImageDirection::END, option.endDimension.value()); 4533 } 4534 if (option.leftDimension.has_value()) { 4535 borderImage->SetEdgeWidth(BorderImageDirection::LEFT, option.leftDimension.value()); 4536 } 4537 if (option.rightDimension.has_value()) { 4538 borderImage->SetEdgeWidth(BorderImageDirection::RIGHT, option.rightDimension.value()); 4539 } 4540 if (option.topDimension.has_value()) { 4541 borderImage->SetEdgeWidth(BorderImageDirection::TOP, option.topDimension.value()); 4542 } 4543 if (option.bottomDimension.has_value()) { 4544 borderImage->SetEdgeWidth(BorderImageDirection::BOTTOM, option.bottomDimension.value()); 4545 } 4546 } 4547 JsBorderColor(const JSCallbackInfo & info)4548 void JSViewAbstract::JsBorderColor(const JSCallbackInfo& info) 4549 { 4550 ParseBorderColor(info[0]); 4551 } 4552 GetLocalizedBorderColor(const std::optional<Color> & colorStart,const std::optional<Color> & colorEnd,const std::optional<Color> & colorTop,const std::optional<Color> & colorBottom)4553 NG::BorderColorProperty JSViewAbstract::GetLocalizedBorderColor(const std::optional<Color>& colorStart, 4554 const std::optional<Color>& colorEnd, const std::optional<Color>& colorTop, 4555 const std::optional<Color>& colorBottom) 4556 { 4557 NG::BorderColorProperty borderColors; 4558 borderColors.startColor = colorStart; 4559 borderColors.endColor = colorEnd; 4560 borderColors.topColor = colorTop; 4561 borderColors.bottomColor = colorBottom; 4562 borderColors.multiValued = true; 4563 return borderColors; 4564 } 4565 ParseBorderColor(const JSRef<JSVal> & args)4566 void JSViewAbstract::ParseBorderColor(const JSRef<JSVal>& args) 4567 { 4568 Color borderColor; 4569 if (ParseJsColor(args, borderColor)) { 4570 ViewAbstractModel::GetInstance()->SetBorderColor(borderColor); 4571 } else if (args->IsObject()) { 4572 CommonColor commonColor; 4573 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4574 if (ParseCommonEdgeColors(object, commonColor)) { 4575 ViewAbstractModel::GetInstance()->SetBorderColor( 4576 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom)); 4577 return; 4578 } 4579 ViewAbstractModel::GetInstance()->SetBorderColor( 4580 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom); 4581 } else { 4582 ViewAbstractModel::GetInstance()->SetBorderColor(Color::BLACK); 4583 } 4584 } 4585 ParseOuterBorderColor(const JSRef<JSVal> & args)4586 void JSViewAbstract::ParseOuterBorderColor(const JSRef<JSVal>& args) 4587 { 4588 Color borderColor; 4589 if (ParseJsColor(args, borderColor)) { 4590 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor); 4591 } else if (args->IsObject()) { 4592 CommonColor commonColor; 4593 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4594 if (ParseCommonEdgeColors(object, commonColor)) { 4595 ViewAbstractModel::GetInstance()->SetOuterBorderColor( 4596 GetLocalizedBorderColor(commonColor.left, commonColor.right, commonColor.top, commonColor.bottom)); 4597 return; 4598 } 4599 ViewAbstractModel::GetInstance()->SetOuterBorderColor( 4600 commonColor.left, commonColor.right, commonColor.top, commonColor.bottom); 4601 } else { 4602 ViewAbstractModel::GetInstance()->SetOuterBorderColor(Color::BLACK); 4603 } 4604 } 4605 JsBorderRadius(const JSCallbackInfo & info)4606 void JSViewAbstract::JsBorderRadius(const JSCallbackInfo& info) 4607 { 4608 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER, 4609 JSCallbackInfoType::OBJECT }; 4610 auto jsVal = info[0]; 4611 if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) { 4612 ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {}); 4613 return; 4614 } 4615 ParseBorderRadius(jsVal); 4616 } 4617 GetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)4618 NG::BorderRadiusProperty JSViewAbstract::GetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart, 4619 const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart, 4620 const std::optional<Dimension>& radiusBottomEnd) 4621 { 4622 NG::BorderRadiusProperty borderRadius; 4623 borderRadius.radiusTopStart = radiusTopStart; 4624 borderRadius.radiusTopEnd = radiusTopEnd; 4625 borderRadius.radiusBottomStart = radiusBottomStart; 4626 borderRadius.radiusBottomEnd = radiusBottomEnd; 4627 borderRadius.multiValued = true; 4628 return borderRadius; 4629 } 4630 ParseBorderRadius(const JSRef<JSVal> & args)4631 void JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args) 4632 { 4633 CalcDimension borderRadius; 4634 if (ParseJsDimensionVp(args, borderRadius)) { 4635 ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius); 4636 } else if (args->IsObject()) { 4637 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4638 CalcDimension topLeft; 4639 CalcDimension topRight; 4640 CalcDimension bottomLeft; 4641 CalcDimension bottomRight; 4642 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) { 4643 ViewAbstractModel::GetInstance()->SetBorderRadius( 4644 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight)); 4645 return; 4646 } 4647 ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight); 4648 } 4649 } 4650 ParseOuterBorderRadius(const JSRef<JSVal> & args)4651 void JSViewAbstract::ParseOuterBorderRadius(const JSRef<JSVal>& args) 4652 { 4653 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) { 4654 return; 4655 } 4656 CalcDimension borderRadius; 4657 if (ParseJsDimensionVp(args, borderRadius)) { 4658 if (borderRadius.Unit() == DimensionUnit::PERCENT) { 4659 borderRadius.Reset(); 4660 } 4661 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(borderRadius); 4662 } else if (args->IsObject()) { 4663 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4664 CalcDimension topLeft; 4665 CalcDimension topRight; 4666 CalcDimension bottomLeft; 4667 CalcDimension bottomRight; 4668 if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) { 4669 ViewAbstractModel::GetInstance()->SetOuterBorderRadius( 4670 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight)); 4671 } 4672 ViewAbstractModel::GetInstance()->SetOuterBorderRadius(topLeft, topRight, bottomLeft, bottomRight); 4673 } 4674 } 4675 GetBorderRadius(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4676 void JSViewAbstract::GetBorderRadius(const char* key, JSRef<JSObject>& object, CalcDimension& radius) 4677 { 4678 ParseJsDimensionVp(object->GetProperty(key), radius); 4679 } 4680 GetBorderRadiusByLengthMetrics(const char * key,JSRef<JSObject> & object,CalcDimension & radius)4681 void JSViewAbstract::GetBorderRadiusByLengthMetrics(const char* key, JSRef<JSObject>& object, CalcDimension& radius) 4682 { 4683 if (object->HasProperty(key) && object->GetProperty(key)->IsObject()) { 4684 JSRef<JSObject> startObj = JSRef<JSObject>::Cast(object->GetProperty(key)); 4685 ParseJsLengthMetrics(startObj, radius); 4686 } 4687 } 4688 ParseAllBorderRadiuses(JSRef<JSObject> & object,CalcDimension & topLeft,CalcDimension & topRight,CalcDimension & bottomLeft,CalcDimension & bottomRight)4689 bool JSViewAbstract::ParseAllBorderRadiuses(JSRef<JSObject>& object, CalcDimension& topLeft, CalcDimension& topRight, 4690 CalcDimension& bottomLeft, CalcDimension& bottomRight) 4691 { 4692 if (object->HasProperty(TOP_START_PROPERTY) || object->HasProperty(TOP_END_PROPERTY) || 4693 object->HasProperty(BOTTOM_START_PROPERTY) || object->HasProperty(BOTTOM_END_PROPERTY)) { 4694 CalcDimension topStart; 4695 CalcDimension topEnd; 4696 CalcDimension bottomStart; 4697 CalcDimension bottomEnd; 4698 GetBorderRadiusByLengthMetrics(TOP_START_PROPERTY, object, topStart); 4699 GetBorderRadiusByLengthMetrics(TOP_END_PROPERTY, object, topEnd); 4700 GetBorderRadiusByLengthMetrics(BOTTOM_START_PROPERTY, object, bottomStart); 4701 GetBorderRadiusByLengthMetrics(BOTTOM_END_PROPERTY, object, bottomEnd); 4702 topLeft = topStart; 4703 topRight = topEnd; 4704 bottomLeft = bottomStart; 4705 bottomRight = bottomEnd; 4706 return true; 4707 } 4708 GetBorderRadius("topLeft", object, topLeft); 4709 GetBorderRadius("topRight", object, topRight); 4710 GetBorderRadius("bottomLeft", object, bottomLeft); 4711 GetBorderRadius("bottomRight", object, bottomRight); 4712 return false; 4713 } 4714 JsBorderStyle(const JSCallbackInfo & info)4715 void JSViewAbstract::JsBorderStyle(const JSCallbackInfo& info) 4716 { 4717 ParseBorderStyle(info[0]); 4718 } 4719 namespace { ConvertBorderStyle(int32_t value)4720 BorderStyle ConvertBorderStyle(int32_t value) 4721 { 4722 auto style = static_cast<BorderStyle>(value); 4723 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) { 4724 style = BorderStyle::SOLID; 4725 } 4726 return style; 4727 } 4728 ConvertOptionBorderStyle(int32_t value,std::optional<BorderStyle> & style)4729 bool ConvertOptionBorderStyle(int32_t value, std::optional<BorderStyle>& style) 4730 { 4731 style = static_cast<BorderStyle>(value); 4732 if (style < BorderStyle::SOLID || style > BorderStyle::NONE) { 4733 return false; 4734 } 4735 return true; 4736 } 4737 } // namespace 4738 ParseBorderStyle(const JSRef<JSVal> & args)4739 void JSViewAbstract::ParseBorderStyle(const JSRef<JSVal>& args) 4740 { 4741 if (args->IsObject()) { 4742 std::optional<BorderStyle> styleLeft; 4743 std::optional<BorderStyle> styleRight; 4744 std::optional<BorderStyle> styleTop; 4745 std::optional<BorderStyle> styleBottom; 4746 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4747 auto leftValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)); 4748 if (leftValue->IsNumber()) { 4749 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>()); 4750 } 4751 auto rightValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)); 4752 if (rightValue->IsNumber()) { 4753 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>()); 4754 } 4755 auto topValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)); 4756 if (topValue->IsNumber()) { 4757 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>()); 4758 } 4759 auto bottomValue = object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)); 4760 if (bottomValue->IsNumber()) { 4761 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>()); 4762 } 4763 ViewAbstractModel::GetInstance()->SetBorderStyle(styleLeft, styleRight, styleTop, styleBottom); 4764 return; 4765 } 4766 if (args->IsNumber()) { 4767 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>()); 4768 ViewAbstractModel::GetInstance()->SetBorderStyle(borderStyle); 4769 return; 4770 } 4771 ViewAbstractModel::GetInstance()->SetBorderStyle(BorderStyle::SOLID); 4772 } 4773 ParseOuterBorderStyle(const JSRef<JSVal> & args)4774 void JSViewAbstract::ParseOuterBorderStyle(const JSRef<JSVal>& args) 4775 { 4776 if (!args->IsObject() && !args->IsNumber()) { 4777 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(BorderStyle::SOLID); 4778 return; 4779 } 4780 if (args->IsObject()) { 4781 std::optional<BorderStyle> styleLeft; 4782 std::optional<BorderStyle> styleRight; 4783 std::optional<BorderStyle> styleTop; 4784 std::optional<BorderStyle> styleBottom; 4785 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 4786 auto leftValue = object->GetProperty("left"); 4787 if (!leftValue->IsUndefined() && leftValue->IsNumber()) { 4788 styleLeft = ConvertBorderStyle(leftValue->ToNumber<int32_t>()); 4789 } 4790 auto rightValue = object->GetProperty("right"); 4791 if (!rightValue->IsUndefined() && rightValue->IsNumber()) { 4792 styleRight = ConvertBorderStyle(rightValue->ToNumber<int32_t>()); 4793 } 4794 auto topValue = object->GetProperty("top"); 4795 if (!topValue->IsUndefined() && topValue->IsNumber()) { 4796 styleTop = ConvertBorderStyle(topValue->ToNumber<int32_t>()); 4797 } 4798 auto bottomValue = object->GetProperty("bottom"); 4799 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) { 4800 styleBottom = ConvertBorderStyle(bottomValue->ToNumber<int32_t>()); 4801 } 4802 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(styleLeft, styleRight, styleTop, styleBottom); 4803 return; 4804 } 4805 auto borderStyle = ConvertBorderStyle(args->ToNumber<int32_t>()); 4806 ViewAbstractModel::GetInstance()->SetOuterBorderStyle(borderStyle); 4807 } 4808 JsBlur(const JSCallbackInfo & info)4809 void JSViewAbstract::JsBlur(const JSCallbackInfo& info) 4810 { 4811 if (info.Length() == 0) { 4812 return; 4813 } 4814 double blur = 0.0; 4815 if (!ParseJsDouble(info[0], blur)) { 4816 return; 4817 } 4818 4819 BlurOption blurOption; 4820 if (info.Length() > 1 && info[1]->IsObject()) { 4821 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]); 4822 ParseBlurOption(jsBlurOption, blurOption); 4823 } 4824 CalcDimension dimensionRadius(blur, DimensionUnit::PX); 4825 ViewAbstractModel::GetInstance()->SetFrontBlur(dimensionRadius, blurOption); 4826 info.SetReturnValue(info.This()); 4827 } 4828 JsMotionBlur(const JSCallbackInfo & info)4829 void JSViewAbstract::JsMotionBlur(const JSCallbackInfo& info) 4830 { 4831 if (!info[0]->IsObject()) { 4832 return; 4833 } 4834 MotionBlurOption option; 4835 double x = 0.0; 4836 double y = 0.0; 4837 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]); 4838 JSRef<JSVal> jsAnchor = jsObj->GetProperty("anchor"); 4839 if (!jsAnchor->IsNull() && !jsAnchor->IsUndefined() && jsAnchor->IsObject()) { 4840 JSRef<JSObject> jsAnchorObj = JSRef<JSObject>::Cast(jsAnchor); 4841 ParseJsDouble(jsAnchorObj->GetProperty("x"), x); 4842 ParseJsDouble(jsAnchorObj->GetProperty("y"), y); 4843 } 4844 double radius = 0.0; 4845 if (!ParseJsDouble(jsObj->GetProperty("radius"), radius) || LessNotEqual(radius, 0.0)) { 4846 radius = 0.0; 4847 } 4848 if (LessNotEqual(x, 0.0)) { 4849 x = 0.0; 4850 } 4851 if (LessNotEqual(y, 0.0)) { 4852 y = 0.0; 4853 } 4854 option.radius = radius; 4855 option.anchor.x = std::clamp(x, 0.0, 1.0); 4856 option.anchor.y = std::clamp(y, 0.0, 1.0); 4857 ViewAbstractModel::GetInstance()->SetMotionBlur(option); 4858 } 4859 JsColorBlend(const JSCallbackInfo & info)4860 void JSViewAbstract::JsColorBlend(const JSCallbackInfo& info) 4861 { 4862 Color colorBlend; 4863 if (info[0]->IsUndefined()) { 4864 colorBlend = Color::TRANSPARENT; 4865 SetColorBlend(colorBlend); 4866 return; 4867 } 4868 if (!ParseJsColor(info[0], colorBlend)) { 4869 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 4870 colorBlend = Color::TRANSPARENT; 4871 SetColorBlend(colorBlend); 4872 } 4873 return; 4874 } 4875 SetColorBlend(colorBlend); 4876 info.SetReturnValue(info.This()); 4877 } 4878 JsUseEffect(const JSCallbackInfo & info)4879 void JSViewAbstract::JsUseEffect(const JSCallbackInfo& info) 4880 { 4881 if (info[0]->IsBoolean()) { 4882 auto effectType = EffectType::DEFAULT; 4883 if (info.Length() == 2 && info[1]->IsNumber()) { 4884 effectType = static_cast<EffectType>(info[1]->ToNumber<int32_t>()); 4885 if (effectType < EffectType::DEFAULT || effectType > EffectType::WINDOW_EFFECT) { 4886 effectType = EffectType::DEFAULT; 4887 } 4888 } 4889 ViewAbstractModel::GetInstance()->SetUseEffect(info[0]->ToBoolean(), effectType); 4890 } 4891 } 4892 JsUseShadowBatching(const JSCallbackInfo & info)4893 void JSViewAbstract::JsUseShadowBatching(const JSCallbackInfo& info) 4894 { 4895 if (info[0]->IsBoolean()) { 4896 ViewAbstractModel::GetInstance()->SetUseShadowBatching(info[0]->ToBoolean()); 4897 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 4898 ViewAbstractModel::GetInstance()->SetUseShadowBatching(false); 4899 } 4900 } 4901 JsBackdropBlur(const JSCallbackInfo & info)4902 void JSViewAbstract::JsBackdropBlur(const JSCallbackInfo& info) 4903 { 4904 if (info.Length() == 0) { 4905 return; 4906 } 4907 double blur = 0.0; 4908 BlurOption blurOption; 4909 if (!ParseJsDouble(info[0], blur)) { 4910 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 4911 return; 4912 } 4913 } 4914 CalcDimension dimensionRadius(blur, DimensionUnit::PX); 4915 if (info.Length() > 1 && info[1]->IsObject()) { 4916 JSRef<JSObject> jsBlurOption = JSRef<JSObject>::Cast(info[1]); 4917 ParseBlurOption(jsBlurOption, blurOption); 4918 } 4919 ViewAbstractModel::GetInstance()->SetBackdropBlur(dimensionRadius, blurOption); 4920 info.SetReturnValue(info.This()); 4921 } 4922 GetFractionStops(std::vector<std::pair<float,float>> & fractionStops,const JSRef<JSVal> & array)4923 void JSViewAbstract::GetFractionStops( 4924 std::vector<std::pair<float, float>>& fractionStops, const JSRef<JSVal>& array) 4925 { 4926 if (!array->IsArray() || JSRef<JSArray>::Cast(array)->Length() <= 1) { 4927 return; 4928 } 4929 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array); 4930 float tmpPos = -1.0f; 4931 size_t length = jsArray->Length(); 4932 for (size_t i = 0; i < length; i++) { 4933 std::pair<float, float> fractionStop; 4934 JSRef<JSVal> item = jsArray->GetValueAt(i); 4935 if (!item->IsArray()) { 4936 continue; 4937 } 4938 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item); 4939 if (subArray->Length() < 2) { 4940 continue; 4941 } 4942 4943 double value = 0.0; 4944 if (ParseJsDouble(subArray->GetValueAt(0), value)) { 4945 value = std::clamp(value, 0.0, 1.0); 4946 fractionStop.first = static_cast<float>(value); 4947 } 4948 value = 0.0; 4949 if (ParseJsDouble(subArray->GetValueAt(1), value)) { 4950 value = std::clamp(value, 0.0, 1.0); 4951 fractionStop.second = static_cast<float>(value); 4952 } 4953 4954 if (fractionStop.second <= tmpPos) { 4955 fractionStops.clear(); 4956 return; 4957 } 4958 tmpPos = fractionStop.second; 4959 fractionStops.push_back(fractionStop); 4960 } 4961 } JsLinearGradientBlur(const JSCallbackInfo & info)4962 void JSViewAbstract::JsLinearGradientBlur(const JSCallbackInfo& info) 4963 { 4964 if (info.Length() < 2) { // 2 represents the least para num; 4965 return; 4966 } 4967 double blurRadius = 0.0; 4968 ParseJsDouble(info[0], blurRadius); 4969 4970 std::vector<std::pair<float, float>> fractionStops; 4971 auto direction = GradientDirection::BOTTOM; 4972 if (info[1]->IsObject()) { 4973 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[1]); 4974 GetFractionStops(fractionStops, jsObj->GetProperty("fractionStops")); 4975 auto directionValue = 4976 jsObj->GetPropertyValue<int8_t>("direction", static_cast<int8_t>(GradientDirection::BOTTOM)); 4977 if (directionValue < static_cast<int8_t>(GradientDirection::LEFT) || 4978 directionValue >= static_cast<int8_t>(GradientDirection::NONE)) { 4979 directionValue = static_cast<int8_t>(GradientDirection::BOTTOM); 4980 } 4981 direction = static_cast<GradientDirection>(directionValue); 4982 } 4983 if (static_cast<int32_t>(fractionStops.size()) <= 1) { 4984 fractionStops.clear(); 4985 fractionStops.push_back(std::pair<float, float>(0.0f, 0.0f)); 4986 fractionStops.push_back(std::pair<float, float>(0.0f, 1.0f)); 4987 } 4988 // Parse direction 4989 CalcDimension dimensionRadius(static_cast<float>(blurRadius), DimensionUnit::PX); 4990 NG::LinearGradientBlurPara blurPara(dimensionRadius, fractionStops, static_cast<NG::GradientDirection>(direction)); 4991 SetLinearGradientBlur(blurPara); 4992 } 4993 JsBackgroundBrightness(const JSCallbackInfo & info)4994 void JSViewAbstract::JsBackgroundBrightness(const JSCallbackInfo& info) 4995 { 4996 double rate = 0.0; 4997 double lightUpDegree = 0.0; 4998 if (info[0]->IsObject()) { 4999 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]); 5000 ParseJsDouble(jsObj->GetProperty("rate"), rate); 5001 ParseJsDouble(jsObj->GetProperty("lightUpDegree"), lightUpDegree); 5002 } 5003 SetDynamicLightUp(rate, lightUpDegree); 5004 } 5005 JsBackgroundBrightnessInternal(const JSCallbackInfo & info)5006 void JSViewAbstract::JsBackgroundBrightnessInternal(const JSCallbackInfo& info) 5007 { 5008 if (info.Length() == 0) { 5009 return; 5010 } 5011 BrightnessOption option; 5012 if (info[0]->IsObject()) { 5013 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]); 5014 ParseBrightnessOption(jsOption, option); 5015 } 5016 SetBgDynamicBrightness(option); 5017 } 5018 JsForegroundBrightness(const JSCallbackInfo & info)5019 void JSViewAbstract::JsForegroundBrightness(const JSCallbackInfo& info) 5020 { 5021 if (info.Length() == 0) { 5022 return; 5023 } 5024 BrightnessOption option; 5025 if (info[0]->IsObject()) { 5026 JSRef<JSObject> jsOption = JSRef<JSObject>::Cast(info[0]); 5027 ParseBrightnessOption(jsOption, option); 5028 } 5029 SetFgDynamicBrightness(option); 5030 } 5031 JsWindowBlur(const JSCallbackInfo & info)5032 void JSViewAbstract::JsWindowBlur(const JSCallbackInfo& info) 5033 { 5034 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 5035 auto jsVal = info[0]; 5036 if (!CheckJSCallbackInfo("JsWindowBlur", jsVal, checkList)) { 5037 return; 5038 } 5039 5040 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal); 5041 double progress = 0.0; 5042 ParseJsDouble(jsObj->GetProperty("percent"), progress); 5043 auto style = jsObj->GetPropertyValue<int32_t>("style", 5044 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT)); 5045 5046 progress = std::clamp(progress, 0.0, 1.0); 5047 style = std::clamp(style, static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT), 5048 static_cast<int32_t>(WindowBlurStyle::STYLE_BACKGROUND_XLARGE_DARK)); 5049 5050 SetWindowBlur(static_cast<float>(progress), static_cast<WindowBlurStyle>(style)); 5051 info.SetReturnValue(info.This()); 5052 } 5053 ParseDollarResource(const JSRef<JSVal> & jsValue,std::string & targetModule,ResourceType & resType,std::string & resName,bool isParseType)5054 bool JSViewAbstract::ParseDollarResource(const JSRef<JSVal>& jsValue, std::string& targetModule, ResourceType& resType, 5055 std::string& resName, bool isParseType) 5056 { 5057 if (!jsValue->IsString()) { 5058 return false; 5059 } 5060 std::string resPath = jsValue->ToString(); 5061 std::smatch results; 5062 std::regex tokenRegex(RESOURCE_TOKEN_PATTERN); 5063 if (!std::regex_match(resPath, results, tokenRegex)) { 5064 return false; 5065 } 5066 targetModule = results[1]; 5067 if (isParseType && !ConvertResourceType(results[2], resType)) { 5068 return false; 5069 } 5070 resName = resPath; 5071 return true; 5072 } 5073 ConvertResourceType(const std::string & typeName,ResourceType & resType)5074 bool JSViewAbstract::ConvertResourceType(const std::string& typeName, ResourceType& resType) 5075 { 5076 static const std::unordered_map<std::string, ResourceType> resTypeMap { 5077 { "color", ResourceType::COLOR }, 5078 { "media", ResourceType::MEDIA }, 5079 { "float", ResourceType::FLOAT }, 5080 { "string", ResourceType::STRING }, 5081 { "plural", ResourceType::PLURAL }, 5082 { "pattern", ResourceType::PATTERN }, 5083 { "boolean", ResourceType::BOOLEAN }, 5084 { "integer", ResourceType::INTEGER }, 5085 { "strarray", ResourceType::STRARRAY }, 5086 { "intarray", ResourceType::INTARRAY }, 5087 }; 5088 auto it = resTypeMap.find(typeName); 5089 if (it == resTypeMap.end()) { 5090 return false; 5091 } 5092 resType = it->second; 5093 return true; 5094 } 5095 CompleteResourceObject(JSRef<JSObject> & jsObj)5096 void JSViewAbstract::CompleteResourceObject(JSRef<JSObject>& jsObj) 5097 { 5098 std::string bundleName; 5099 std::string moduleName; 5100 int32_t resId = -1; 5101 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId); 5102 } 5103 CompleteResourceObjectWithBundleName(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resId)5104 void JSViewAbstract::CompleteResourceObjectWithBundleName( 5105 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resId) 5106 { 5107 CompleteResourceObjectInner(jsObj, bundleName, moduleName, resId); 5108 } 5109 CompleteResourceObjectInner(JSRef<JSObject> & jsObj,std::string & bundleName,std::string & moduleName,int32_t & resIdValue)5110 void JSViewAbstract::CompleteResourceObjectInner( 5111 JSRef<JSObject>& jsObj, std::string& bundleName, std::string& moduleName, int32_t& resIdValue) 5112 { 5113 // dynamic $r raw input format is 5114 // {"id":"app.xxx.xxx", "params":[], "bundleName":"xxx", "moduleName":"xxx"} 5115 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID)); 5116 ResourceType resType; 5117 5118 std::string targetModule; 5119 std::string resName; 5120 if (resId->IsString()) { 5121 JSRef<JSVal> type = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)); 5122 int32_t typeNum = -1; 5123 if (type->IsNumber()) { 5124 typeNum = type->ToNumber<int32_t>(); 5125 } 5126 if (!ParseDollarResource(resId, targetModule, resType, resName, typeNum == UNKNOWN_RESOURCE_TYPE)) { 5127 return; 5128 } 5129 CompleteResourceObjectFromId(type, jsObj, resType, resName); 5130 } else if (resId->IsNumber()) { 5131 resIdValue = resId->ToNumber<int32_t>(); 5132 if (resIdValue == -1) { 5133 CompleteResourceObjectFromParams(resIdValue, jsObj, targetModule, resType, resName); 5134 } 5135 } 5136 5137 JSViewAbstract::GetJsMediaBundleInfo(jsObj, bundleName, moduleName); 5138 if ((bundleName.empty() && !moduleName.empty()) || bundleName == DEFAULT_HAR_BUNDLE_NAME) { 5139 bundleName = GetBundleNameFromContainer(); 5140 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME), bundleName); 5141 } 5142 if (moduleName == DEFAULT_HAR_MODULE_NAME) { 5143 moduleName = GetModuleNameFromContainer(); 5144 jsObj->SetProperty<std::string>(static_cast<int32_t>(ArkUIIndex::MODULE_NAME), moduleName); 5145 } 5146 } 5147 ParseJsDimensionNG(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)5148 bool JSViewAbstract::ParseJsDimensionNG( 5149 const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent) 5150 { 5151 if (jsValue->IsNumber()) { 5152 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit); 5153 return true; 5154 } 5155 if (jsValue->IsString()) { 5156 auto value = jsValue->ToString(); 5157 if (!isSupportPercent && value.back() == '%') { 5158 return false; 5159 } 5160 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit); 5161 } 5162 if (jsValue->IsObject()) { 5163 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5164 CompleteResourceObject(jsObj); 5165 JSRef<JSVal> resId = jsObj->GetProperty("id"); 5166 if (!resId->IsNumber()) { 5167 return false; 5168 } 5169 auto resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE); 5170 if (resType == UNKNOWN_RESOURCE_TYPE) { 5171 return false; 5172 } 5173 5174 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 5175 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5176 if (!resourceWrapper) { 5177 return false; 5178 } 5179 5180 auto resIdNum = resId->ToNumber<int32_t>(); 5181 if (resIdNum == -1) { 5182 if (!IsGetResourceByName(jsObj)) { 5183 return false; 5184 } 5185 JSRef<JSVal> args = jsObj->GetProperty("params"); 5186 if (!args->IsArray()) { 5187 return false; 5188 } 5189 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5190 auto param = params->GetValueAt(0); 5191 if (resType == static_cast<int32_t>(ResourceType::STRING)) { 5192 auto value = resourceWrapper->GetStringByName(param->ToString()); 5193 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit); 5194 } 5195 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) { 5196 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString())); 5197 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit); 5198 return true; 5199 } 5200 result = resourceWrapper->GetDimensionByName(param->ToString()); 5201 return true; 5202 } 5203 5204 if (resType == static_cast<int32_t>(ResourceType::STRING)) { 5205 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>()); 5206 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit); 5207 } 5208 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) { 5209 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>())); 5210 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit); 5211 return true; 5212 } 5213 5214 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) { 5215 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); // float return true pixel value 5216 return true; 5217 } 5218 } 5219 5220 return false; 5221 } 5222 ParseJsLengthNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,DimensionUnit defaultUnit,bool isSupportPercent)5223 bool JSViewAbstract::ParseJsLengthNG( 5224 const JSRef<JSVal>& jsValue, NG::CalcLength& result, DimensionUnit defaultUnit, bool isSupportPercent) 5225 { 5226 if (jsValue->IsNumber()) { 5227 if (std::isnan(jsValue->ToNumber<double>())) { 5228 return false; 5229 } 5230 result = NG::CalcLength(jsValue->ToNumber<double>(), defaultUnit); 5231 return true; 5232 } else if (jsValue->IsObject()) { 5233 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5234 JSRef<JSVal> value = jsObj->GetProperty("value"); 5235 if (value->IsNull() || (value->IsNumber() && std::isnan(value->ToNumber<double>())) || value->IsUndefined()) { 5236 return false; 5237 } 5238 DimensionUnit unit = defaultUnit; 5239 JSRef<JSVal> jsUnit = jsObj->GetProperty("unit"); 5240 if (jsUnit->IsNumber()) { 5241 if (!isSupportPercent && jsUnit->ToNumber<int32_t>() == static_cast<int32_t>(DimensionUnit::PERCENT)) { 5242 return false; 5243 } 5244 unit = static_cast<DimensionUnit>(jsUnit->ToNumber<int32_t>()); 5245 } 5246 result = NG::CalcLength(value->ToNumber<double>(), unit); 5247 return true; 5248 } 5249 5250 return false; 5251 } 5252 ParseJsLengthVpNG(const JSRef<JSVal> & jsValue,NG::CalcLength & result,bool isSupportPercent)5253 bool JSViewAbstract::ParseJsLengthVpNG(const JSRef<JSVal>& jsValue, NG::CalcLength& result, bool isSupportPercent) 5254 { 5255 // 'vp' -> the value varies with pixel density of device. 5256 return ParseJsLengthNG(jsValue, result, DimensionUnit::VP, isSupportPercent); 5257 } 5258 ParseJsDimension(const JSRef<JSVal> & jsValue,CalcDimension & result,DimensionUnit defaultUnit)5259 bool JSViewAbstract::ParseJsDimension(const JSRef<JSVal>& jsValue, CalcDimension& result, DimensionUnit defaultUnit) 5260 { 5261 if (jsValue->IsNumber()) { 5262 result = CalcDimension(jsValue->ToNumber<double>(), defaultUnit); 5263 return true; 5264 } 5265 if (jsValue->IsString()) { 5266 result = StringUtils::StringToCalcDimension(jsValue->ToString(), false, defaultUnit); 5267 return true; 5268 } 5269 if (!jsValue->IsObject()) { 5270 return false; 5271 } 5272 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5273 CompleteResourceObject(jsObj); 5274 JSRef<JSVal> resId = jsObj->GetProperty("id"); 5275 if (!resId->IsNumber()) { 5276 return false; 5277 } 5278 5279 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 5280 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5281 if (!resourceWrapper) { 5282 return false; 5283 } 5284 5285 auto resIdNum = resId->ToNumber<int32_t>(); 5286 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE); 5287 if (resType == UNKNOWN_RESOURCE_TYPE) { 5288 return false; 5289 } 5290 5291 if (resIdNum == -1) { 5292 if (!IsGetResourceByName(jsObj)) { 5293 return false; 5294 } 5295 JSRef<JSVal> args = jsObj->GetProperty("params"); 5296 if (!args->IsArray()) { 5297 return false; 5298 } 5299 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5300 auto param = params->GetValueAt(0); 5301 if (resType == static_cast<int32_t>(ResourceType::STRING)) { 5302 auto value = resourceWrapper->GetStringByName(param->ToString()); 5303 result = StringUtils::StringToCalcDimension(value, false, defaultUnit); 5304 return true; 5305 } 5306 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) { 5307 auto value = std::to_string(resourceWrapper->GetIntByName(param->ToString())); 5308 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit); 5309 return true; 5310 } 5311 result = resourceWrapper->GetDimensionByName(param->ToString()); 5312 return true; 5313 } 5314 5315 if (resType == static_cast<int32_t>(ResourceType::STRING)) { 5316 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>()); 5317 result = StringUtils::StringToCalcDimension(value, false, defaultUnit); 5318 return true; 5319 } 5320 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) { 5321 auto value = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>())); 5322 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit); 5323 return true; 5324 } 5325 result = resourceWrapper->GetDimension(resId->ToNumber<uint32_t>()); 5326 return true; 5327 } 5328 ParseJsDimensionVpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5329 bool JSViewAbstract::ParseJsDimensionVpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent) 5330 { 5331 // 'vp' -> the value varies with pixel density of device. 5332 return ParseJsDimensionNG(jsValue, result, DimensionUnit::VP, isSupportPercent); 5333 } 5334 ParseJsDimensionVp(const JSRef<JSVal> & jsValue,CalcDimension & result)5335 bool JSViewAbstract::ParseJsDimensionVp(const JSRef<JSVal>& jsValue, CalcDimension& result) 5336 { 5337 // 'vp' -> the value varies with pixel density of device. 5338 return ParseJsDimension(jsValue, result, DimensionUnit::VP); 5339 } 5340 ParseJsDimensionFp(const JSRef<JSVal> & jsValue,CalcDimension & result)5341 bool JSViewAbstract::ParseJsDimensionFp(const JSRef<JSVal>& jsValue, CalcDimension& result) 5342 { 5343 // the 'fp' unit is used for text scenes. 5344 return ParseJsDimension(jsValue, result, DimensionUnit::FP); 5345 } 5346 ParseJsDimensionFpNG(const JSRef<JSVal> & jsValue,CalcDimension & result,bool isSupportPercent)5347 bool JSViewAbstract::ParseJsDimensionFpNG(const JSRef<JSVal>& jsValue, CalcDimension& result, bool isSupportPercent) 5348 { 5349 // the 'fp' unit is used for text scenes. 5350 return ParseJsDimensionNG(jsValue, result, DimensionUnit::FP, isSupportPercent); 5351 } 5352 ParseJsDimensionPx(const JSRef<JSVal> & jsValue,CalcDimension & result)5353 bool JSViewAbstract::ParseJsDimensionPx(const JSRef<JSVal>& jsValue, CalcDimension& result) 5354 { 5355 return ParseJsDimension(jsValue, result, DimensionUnit::PX); 5356 } 5357 ParseColorMetricsToColor(const JSRef<JSVal> & jsValue,Color & result)5358 bool JSViewAbstract::ParseColorMetricsToColor(const JSRef<JSVal>& jsValue, Color& result) 5359 { 5360 if (!jsValue->IsObject()) { 5361 return false; 5362 } 5363 auto colorObj = JSRef<JSObject>::Cast(jsValue); 5364 auto toNumericProp = colorObj->GetProperty("toNumeric"); 5365 if (toNumericProp->IsFunction()) { 5366 auto colorVal = JSRef<JSFunc>::Cast(toNumericProp)->Call(colorObj, 0, nullptr); 5367 result.SetValue(colorVal->ToNumber<uint32_t>()); 5368 return true; 5369 } 5370 return false; 5371 } 5372 ParseLengthMetricsToDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5373 bool JSViewAbstract::ParseLengthMetricsToDimension(const JSRef<JSVal>& jsValue, CalcDimension& result) 5374 { 5375 if (jsValue->IsNumber()) { 5376 result = CalcDimension(jsValue->ToNumber<double>(), DimensionUnit::FP); 5377 return true; 5378 } 5379 if (jsValue->IsString()) { 5380 auto value = jsValue->ToString(); 5381 return StringUtils::StringToCalcDimensionNG(value, result, false, DimensionUnit::FP); 5382 } 5383 if (jsValue->IsObject()) { 5384 auto jsObj = JSRef<JSObject>::Cast(jsValue); 5385 auto valObj = jsObj->GetProperty("value"); 5386 if (valObj->IsUndefined() || valObj->IsNull()) { 5387 return false; 5388 } 5389 double value = valObj->ToNumber<double>(); 5390 auto unit = static_cast<DimensionUnit>(jsObj->GetProperty("unit")->ToNumber<int32_t>()); 5391 result = CalcDimension(value, unit); 5392 return true; 5393 } 5394 return false; 5395 } 5396 ParseLengthMetricsToPositiveDimension(const JSRef<JSVal> & jsValue,CalcDimension & result)5397 bool JSViewAbstract::ParseLengthMetricsToPositiveDimension(const JSRef<JSVal>& jsValue, CalcDimension& result) 5398 { 5399 return ParseLengthMetricsToDimension(jsValue, result) ? GreatOrEqual(result.Value(), 0.0f) : false; 5400 } 5401 ParseResourceToDouble(const JSRef<JSVal> & jsValue,double & result)5402 bool JSViewAbstract::ParseResourceToDouble(const JSRef<JSVal>& jsValue, double& result) 5403 { 5404 if (!jsValue->IsObject()) { 5405 return false; 5406 } 5407 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5408 CompleteResourceObject(jsObj); 5409 if (jsObj->IsEmpty()) { 5410 return false; 5411 } 5412 JSRef<JSVal> id = jsObj->GetProperty("id"); 5413 if (!id->IsNumber()) { 5414 return false; 5415 } 5416 5417 auto resId = id->ToNumber<int32_t>(); 5418 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE); 5419 if (resType == UNKNOWN_RESOURCE_TYPE) { 5420 return false; 5421 } 5422 5423 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 5424 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5425 if (!resourceWrapper) { 5426 return false; 5427 } 5428 5429 if (resId == -1) { 5430 if (!IsGetResourceByName(jsObj)) { 5431 return false; 5432 } 5433 JSRef<JSVal> args = jsObj->GetProperty("params"); 5434 if (!args->IsArray()) { 5435 return false; 5436 } 5437 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5438 auto param = params->GetValueAt(0); 5439 if (resType == static_cast<int32_t>(ResourceType::STRING)) { 5440 auto numberString = resourceWrapper->GetStringByName(param->ToString()); 5441 return StringUtils::StringToDouble(numberString, result); 5442 } 5443 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) { 5444 result = resourceWrapper->GetIntByName(param->ToString()); 5445 return true; 5446 } 5447 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) { 5448 result = resourceWrapper->GetDoubleByName(param->ToString()); 5449 return true; 5450 } 5451 return false; 5452 } 5453 if (resType == static_cast<int32_t>(ResourceType::STRING)) { 5454 auto numberString = resourceWrapper->GetString(resId); 5455 return StringUtils::StringToDouble(numberString, result); 5456 } 5457 if (resType == static_cast<int32_t>(ResourceType::INTEGER)) { 5458 result = resourceWrapper->GetInt(resId); 5459 return true; 5460 } 5461 if (resType == static_cast<int32_t>(ResourceType::FLOAT)) { 5462 result = resourceWrapper->GetDouble(resId); 5463 return true; 5464 } 5465 return false; 5466 } 5467 ParseJsDouble(const JSRef<JSVal> & jsValue,double & result)5468 bool JSViewAbstract::ParseJsDouble(const JSRef<JSVal>& jsValue, double& result) 5469 { 5470 if (jsValue->IsNumber()) { 5471 result = jsValue->ToNumber<double>(); 5472 return true; 5473 } 5474 if (jsValue->IsString()) { 5475 return StringUtils::StringToDouble(jsValue->ToString(), result); 5476 } 5477 if (jsValue->IsObject()) { 5478 return ParseResourceToDouble(jsValue, result); 5479 } 5480 return false; 5481 } 5482 ParseJsInt32(const JSRef<JSVal> & jsValue,int32_t & result)5483 bool JSViewAbstract::ParseJsInt32(const JSRef<JSVal>& jsValue, int32_t& result) 5484 { 5485 if (jsValue->IsNumber()) { 5486 result = jsValue->ToNumber<int32_t>(); 5487 return true; 5488 } 5489 if (jsValue->IsString()) { 5490 result = StringUtils::StringToInt(jsValue->ToString()); 5491 return true; 5492 } 5493 if (!jsValue->IsObject()) { 5494 return false; 5495 } 5496 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5497 CompleteResourceObject(jsObj); 5498 JSRef<JSVal> resId = jsObj->GetProperty("id"); 5499 if (!resId->IsNumber()) { 5500 return false; 5501 } 5502 5503 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 5504 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5505 if (!resourceWrapper) { 5506 return false; 5507 } 5508 5509 auto resIdNum = resId->ToNumber<int32_t>(); 5510 if (resIdNum == -1) { 5511 if (!IsGetResourceByName(jsObj)) { 5512 return false; 5513 } 5514 JSRef<JSVal> args = jsObj->GetProperty("params"); 5515 if (!args->IsArray()) { 5516 return false; 5517 } 5518 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5519 auto param = params->GetValueAt(0); 5520 result = resourceWrapper->GetIntByName(param->ToString()); 5521 return true; 5522 } 5523 result = resourceWrapper->GetInt(resId->ToNumber<uint32_t>()); 5524 return true; 5525 } 5526 ParseJsColorFromResource(const JSRef<JSVal> & jsValue,Color & result)5527 bool JSViewAbstract::ParseJsColorFromResource(const JSRef<JSVal>& jsValue, Color& result) 5528 { 5529 if (!jsValue->IsObject()) { 5530 return false; 5531 } 5532 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5533 CompleteResourceObject(jsObj); 5534 5535 auto ok = JSViewAbstract::ParseJsObjColorFromResource(jsObj, result); 5536 if (ok) { 5537 JSRef<JSVal> jsOpacityRatio = jsObj->GetProperty("opacityRatio"); 5538 if (jsOpacityRatio->IsNumber()) { 5539 double opacityRatio = jsOpacityRatio->ToNumber<double>(); 5540 result = result.BlendOpacity(opacityRatio); 5541 } 5542 } 5543 return ok; 5544 } 5545 ParseJsObjColorFromResource(const JSRef<JSObject> & jsObj,Color & result)5546 bool JSViewAbstract::ParseJsObjColorFromResource(const JSRef<JSObject> &jsObj, Color& result) 5547 { 5548 JSRef<JSVal> resId = jsObj->GetProperty("id"); 5549 if (!resId->IsNumber()) { 5550 return false; 5551 } 5552 5553 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 5554 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5555 if (!resourceWrapper) { 5556 return false; 5557 } 5558 5559 auto resIdNum = resId->ToNumber<int32_t>(); 5560 if (resIdNum == -1) { 5561 if (!IsGetResourceByName(jsObj)) { 5562 return false; 5563 } 5564 JSRef<JSVal> args = jsObj->GetProperty("params"); 5565 if (!args->IsArray()) { 5566 return false; 5567 } 5568 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5569 auto param = params->GetValueAt(0); 5570 result = resourceWrapper->GetColorByName(param->ToString()); 5571 return true; 5572 } 5573 5574 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE); 5575 if (type == static_cast<int32_t>(ResourceType::STRING)) { 5576 auto value = resourceWrapper->GetString(resId->ToNumber<uint32_t>()); 5577 return Color::ParseColorString(value, result); 5578 } 5579 if (type == static_cast<int32_t>(ResourceType::INTEGER)) { 5580 auto value = resourceWrapper->GetInt(resId->ToNumber<uint32_t>()); 5581 result = Color(ColorAlphaAdapt(value)); 5582 return true; 5583 } 5584 if (type == static_cast<int32_t>(ResourceType::COLOR)) { 5585 result = resourceWrapper->GetColor(resId->ToNumber<uint32_t>()); 5586 result.SetResourceId(resId->ToNumber<uint32_t>()); 5587 return true; 5588 } 5589 return false; 5590 } 5591 ParseJsColor(const JSRef<JSVal> & jsValue,Color & result)5592 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result) 5593 { 5594 if (jsValue->IsNumber()) { 5595 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>())); 5596 return true; 5597 } 5598 if (jsValue->IsString()) { 5599 return Color::ParseColorString(jsValue->ToString(), result); 5600 } 5601 if (jsValue->IsObject()) { 5602 return ParseJsColorFromResource(jsValue, result); 5603 } 5604 return false; 5605 } 5606 ParseJsColor(const JSRef<JSVal> & jsValue,Color & result,const Color & defaultColor)5607 bool JSViewAbstract::ParseJsColor(const JSRef<JSVal>& jsValue, Color& result, const Color& defaultColor) 5608 { 5609 if (jsValue->IsNumber()) { 5610 result = Color(ColorAlphaAdapt(jsValue->ToNumber<uint32_t>())); 5611 return true; 5612 } 5613 if (jsValue->IsString()) { 5614 return Color::ParseColorString(jsValue->ToString(), result, defaultColor); 5615 } 5616 if (!jsValue->IsObject()) { 5617 return false; 5618 } 5619 return ParseJsColorFromResource(jsValue, result); 5620 } 5621 ParseJsColorStrategy(const JSRef<JSVal> & jsValue,ForegroundColorStrategy & strategy)5622 bool JSViewAbstract::ParseJsColorStrategy(const JSRef<JSVal>& jsValue, ForegroundColorStrategy& strategy) 5623 { 5624 if (jsValue->IsString()) { 5625 std::string colorStr = jsValue->ToString(); 5626 if (colorStr.compare("invert") == 0) { 5627 strategy = ForegroundColorStrategy::INVERT; 5628 return true; 5629 } 5630 } 5631 return false; 5632 } 5633 ParseJsShadowColorStrategy(const JSRef<JSVal> & jsValue,ShadowColorStrategy & strategy)5634 bool JSViewAbstract::ParseJsShadowColorStrategy(const JSRef<JSVal>& jsValue, ShadowColorStrategy& strategy) 5635 { 5636 if (jsValue->IsString()) { 5637 std::string colorStr = jsValue->ToString(); 5638 if (colorStr.compare("average") == 0) { 5639 strategy = ShadowColorStrategy::AVERAGE; 5640 return true; 5641 } else if (colorStr.compare("primary") == 0) { 5642 strategy = ShadowColorStrategy::PRIMARY; 5643 return true; 5644 } 5645 } 5646 return false; 5647 } 5648 ParseJsSymbolId(const JSRef<JSVal> & jsValue,std::uint32_t & symbolId,RefPtr<ResourceObject> & symbolResourceObject)5649 bool JSViewAbstract::ParseJsSymbolId( 5650 const JSRef<JSVal>& jsValue, std::uint32_t& symbolId, RefPtr<ResourceObject>& symbolResourceObject) 5651 { 5652 if (jsValue->IsNull() || jsValue->IsUndefined()) { 5653 symbolId = 0; 5654 return false; 5655 } 5656 if (!jsValue->IsObject()) { 5657 return false; 5658 } 5659 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5660 CompleteResourceObject(jsObj); 5661 JSRef<JSVal> resId = jsObj->GetProperty("id"); 5662 if (resId->IsNull() || !resId->IsNumber()) { 5663 return false; 5664 } 5665 auto resourceObject = GetResourceObject(jsObj); 5666 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5667 symbolResourceObject = resourceObject; 5668 if (!resourceWrapper) { 5669 return false; 5670 } 5671 if (!resourceObject) { 5672 return false; 5673 } 5674 5675 auto resIdNum = resId->ToNumber<int32_t>(); 5676 if (resIdNum == -1) { 5677 if (!IsGetResourceByName(jsObj)) { 5678 return false; 5679 } 5680 JSRef<JSVal> args = jsObj->GetProperty("params"); 5681 if (!args->IsArray()) { 5682 return false; 5683 } 5684 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5685 auto param = params->GetValueAt(0); 5686 auto symbol = resourceWrapper->GetSymbolByName(param->ToString().c_str()); 5687 if (!symbol) { 5688 return false; 5689 } 5690 symbolId = symbol; 5691 return true; 5692 } 5693 5694 auto symbol = resourceWrapper->GetSymbolById(resIdNum); 5695 if (!symbol) { 5696 return false; 5697 } 5698 symbolId = symbol; 5699 return true; 5700 } 5701 ParseJsSymbolColor(const JSRef<JSVal> & jsValue,std::vector<Color> & result)5702 bool JSViewAbstract::ParseJsSymbolColor(const JSRef<JSVal>& jsValue, std::vector<Color>& result) 5703 { 5704 if (!jsValue->IsArray()) { 5705 return false; 5706 } 5707 if (jsValue->IsArray()) { 5708 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue); 5709 for (size_t i = 0; i < array->Length(); i++) { 5710 JSRef<JSVal> value = array->GetValueAt(i); 5711 if (!value->IsNumber() && !value->IsString() && !value->IsObject()) { 5712 return false; 5713 } 5714 if (value->IsNumber()) { 5715 result.emplace_back(Color(ColorAlphaAdapt(value->ToNumber<uint32_t>()))); 5716 continue; 5717 } else if (value->IsString()) { 5718 Color color; 5719 Color::ParseColorString(value->ToString(), color); 5720 result.emplace_back(color); 5721 continue; 5722 } else { 5723 Color color; 5724 ParseJsColorFromResource(value, color); 5725 result.emplace_back(color); 5726 } 5727 } 5728 return true; 5729 } 5730 return false; 5731 } 5732 ParseJsFontFamilies(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)5733 bool JSViewAbstract::ParseJsFontFamilies(const JSRef<JSVal>& jsValue, std::vector<std::string>& result) 5734 { 5735 result.clear(); 5736 if (!jsValue->IsString() && !jsValue->IsObject()) { 5737 return false; 5738 } 5739 if (jsValue->IsString()) { 5740 result = ConvertStrToFontFamilies(jsValue->ToString()); 5741 return true; 5742 } 5743 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5744 CompleteResourceObject(jsObj); 5745 JSRef<JSVal> resId = jsObj->GetProperty("id"); 5746 if (!resId->IsNumber()) { 5747 return false; 5748 } 5749 5750 auto resourceObject = GetResourceObject(jsObj); 5751 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5752 if (!resourceWrapper) { 5753 return false; 5754 } 5755 5756 auto resIdNum = resId->ToNumber<int32_t>(); 5757 if (resIdNum == -1) { 5758 if (!IsGetResourceByName(jsObj)) { 5759 return false; 5760 } 5761 JSRef<JSVal> args = jsObj->GetProperty("params"); 5762 if (!args->IsArray()) { 5763 return false; 5764 } 5765 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5766 auto param = params->GetValueAt(0); 5767 result.emplace_back(resourceWrapper->GetStringByName(param->ToString())); 5768 return true; 5769 } 5770 result.emplace_back(resourceWrapper->GetString(resId->ToNumber<uint32_t>())); 5771 return true; 5772 } 5773 ParseJsString(const JSRef<JSVal> & jsValue,std::string & result)5774 bool JSViewAbstract::ParseJsString(const JSRef<JSVal>& jsValue, std::string& result) 5775 { 5776 if (jsValue->IsString()) { 5777 result = jsValue->ToString(); 5778 return true; 5779 } 5780 5781 if (!jsValue->IsObject()) { 5782 return false; 5783 } 5784 5785 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5786 CompleteResourceObject(jsObj); 5787 5788 JSRef<JSVal> resId = jsObj->GetProperty("id"); 5789 if (!resId->IsNumber()) { 5790 return false; 5791 } 5792 auto type = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE); 5793 if (type == UNKNOWN_RESOURCE_TYPE) { 5794 return false; 5795 } 5796 5797 JSRef<JSVal> args = jsObj->GetProperty("params"); 5798 if (!args->IsArray()) { 5799 return false; 5800 } 5801 5802 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 5803 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5804 if (!resourceWrapper) { 5805 return false; 5806 } 5807 5808 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5809 auto resIdNum = resId->ToNumber<int32_t>(); 5810 if (resIdNum == -1) { 5811 if (!IsGetResourceByName(jsObj)) { 5812 return false; 5813 } 5814 auto param = params->GetValueAt(0); 5815 if (type == static_cast<int32_t>(ResourceType::STRING)) { 5816 auto originStr = resourceWrapper->GetStringByName(param->ToString()); 5817 ReplaceHolder(originStr, params, 1); 5818 result = originStr; 5819 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) { 5820 auto countJsVal = params->GetValueAt(1); 5821 int count = 0; 5822 if (!countJsVal->IsNumber()) { 5823 return false; 5824 } 5825 count = countJsVal->ToNumber<int>(); 5826 auto pluralStr = resourceWrapper->GetPluralStringByName(param->ToString(), count); 5827 ReplaceHolder(pluralStr, params, 2); 5828 result = pluralStr; 5829 } else { 5830 return false; 5831 } 5832 return true; 5833 } 5834 if (type == static_cast<int32_t>(ResourceType::STRING)) { 5835 auto originStr = resourceWrapper->GetString(resId->ToNumber<uint32_t>()); 5836 ReplaceHolder(originStr, params, 0); 5837 result = originStr; 5838 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) { 5839 auto countJsVal = params->GetValueAt(0); 5840 int count = 0; 5841 if (!countJsVal->IsNumber()) { 5842 return false; 5843 } 5844 count = countJsVal->ToNumber<int>(); 5845 auto pluralStr = resourceWrapper->GetPluralString(resId->ToNumber<uint32_t>(), count); 5846 ReplaceHolder(pluralStr, params, 1); 5847 result = pluralStr; 5848 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) { 5849 result = std::to_string(resourceWrapper->GetDouble(resId->ToNumber<uint32_t>())); 5850 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) { 5851 result = std::to_string(resourceWrapper->GetInt(resId->ToNumber<uint32_t>())); 5852 } else { 5853 return false; 5854 } 5855 return true; 5856 } 5857 ParseJsMedia(const JSRef<JSVal> & jsValue,std::string & result)5858 bool JSViewAbstract::ParseJsMedia(const JSRef<JSVal>& jsValue, std::string& result) 5859 { 5860 if (!jsValue->IsObject() && !jsValue->IsString()) { 5861 return false; 5862 } 5863 if (jsValue->IsString()) { 5864 result = jsValue->ToString(); 5865 return true; 5866 } 5867 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5868 CompleteResourceObject(jsObj); 5869 return ParseJSMediaInternal(jsObj, result); 5870 } 5871 ParseJsMediaWithBundleName(const JSRef<JSVal> & jsValue,std::string & result,std::string & bundleName,std::string & moduleName,int32_t & resId)5872 bool JSViewAbstract::ParseJsMediaWithBundleName( 5873 const JSRef<JSVal>& jsValue, std::string& result, std::string& bundleName, std::string& moduleName, int32_t& resId) 5874 { 5875 if (!jsValue->IsObject() && !jsValue->IsString()) { 5876 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName); 5877 } 5878 if (jsValue->IsString()) { 5879 result = jsValue->ToString(); 5880 return JSViewAbstract::GetJsMediaBundleInfo(jsValue, bundleName, moduleName); 5881 } 5882 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5883 CompleteResourceObjectWithBundleName(jsObj, bundleName, moduleName, resId); 5884 return ParseJSMediaInternal(jsObj, result); 5885 } 5886 ParseJSMediaInternal(const JSRef<JSObject> & jsObj,std::string & result)5887 bool JSViewAbstract::ParseJSMediaInternal(const JSRef<JSObject>& jsObj, std::string& result) 5888 { 5889 int32_t type = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE); 5890 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID)); 5891 if (!resId->IsNull() && type != UNKNOWN_RESOURCE_TYPE && resId->IsNumber()) { 5892 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 5893 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 5894 CHECK_NULL_RETURN(resourceWrapper, false); 5895 if (type == static_cast<int32_t>(ResourceType::RAWFILE)) { 5896 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS)); 5897 if (!args->IsArray()) { 5898 return false; 5899 } 5900 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5901 auto fileName = params->GetValueAt(0); 5902 if (!fileName->IsString()) { 5903 return false; 5904 } 5905 result = resourceWrapper->GetRawfile(fileName->ToString()); 5906 return true; 5907 } 5908 auto resIdNum = resId->ToNumber<int32_t>(); 5909 if (resIdNum == -1) { 5910 if (!IsGetResourceByName(jsObj)) { 5911 return false; 5912 } 5913 JSRef<JSVal> args = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::PARAMS)); 5914 if (!args->IsArray()) { 5915 return false; 5916 } 5917 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 5918 auto param = params->GetValueAt(0); 5919 if (type == static_cast<int32_t>(ResourceType::MEDIA)) { 5920 result = resourceWrapper->GetMediaPathByName(param->ToString()); 5921 return true; 5922 } 5923 if (type == static_cast<int32_t>(ResourceType::STRING)) { 5924 result = resourceWrapper->GetStringByName(param->ToString()); 5925 return true; 5926 } 5927 return false; 5928 } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) { 5929 result = resourceWrapper->GetMediaPath(resId->ToNumber<uint32_t>()); 5930 return true; 5931 } else if (type == static_cast<int32_t>(ResourceType::STRING)) { 5932 result = resourceWrapper->GetString(resId->ToNumber<uint32_t>()); 5933 return true; 5934 } 5935 } 5936 return false; 5937 } 5938 SetTabBarSymbolOptionApply(const JSCallbackInfo & info,TabBarSymbol & symbolApply,const JSRef<JSVal> & modifierNormalObj,const JSRef<JSVal> & modifierSelectedObj)5939 void JSViewAbstract::SetTabBarSymbolOptionApply(const JSCallbackInfo& info, TabBarSymbol& symbolApply, 5940 const JSRef<JSVal>& modifierNormalObj, const JSRef<JSVal>& modifierSelectedObj) 5941 { 5942 auto vm = info.GetVm(); 5943 auto globalObj = JSNApi::GetGlobalObject(vm); 5944 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode")); 5945 JsiValue jsiValue(globalFunc); 5946 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue); 5947 if (!globalFuncRef->IsFunction()) { 5948 return; 5949 } 5950 if (modifierNormalObj->IsUndefined()) { 5951 symbolApply.onApply = nullptr; 5952 } else { 5953 RefPtr<JsFunction> jsFunc = 5954 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef)); 5955 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), 5956 modifierNormal = std::move(modifierNormalObj), 5957 modifierSelected = std::move(modifierSelectedObj)]( 5958 WeakPtr<NG::FrameNode> frameNode, std::string type) { 5959 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 5960 auto node = frameNode.Upgrade(); 5961 CHECK_NULL_VOID(node); 5962 JSRef<JSVal> params[SECOND_INDEX]; 5963 if (type == "normal") { 5964 params[0] = modifierNormal; 5965 } else if (!modifierSelected->IsUndefined()) { 5966 params[0] = modifierSelected; 5967 } 5968 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node))); 5969 PipelineContext::SetCallBackNode(node); 5970 func->ExecuteJS(SECOND_INDEX, params); 5971 }; 5972 symbolApply.onApply = onApply; 5973 } 5974 } 5975 ParseJsBool(const JSRef<JSVal> & jsValue,bool & result)5976 bool JSViewAbstract::ParseJsBool(const JSRef<JSVal>& jsValue, bool& result) 5977 { 5978 if (!jsValue->IsBoolean() && !jsValue->IsObject()) { 5979 return false; 5980 } 5981 5982 if (jsValue->IsBoolean()) { 5983 result = jsValue->ToBoolean(); 5984 return true; 5985 } 5986 5987 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 5988 CompleteResourceObject(jsObj); 5989 int32_t resType = jsObj->GetPropertyValue<int32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), UNKNOWN_RESOURCE_TYPE); 5990 if (resType == UNKNOWN_RESOURCE_TYPE) { 5991 return false; 5992 } 5993 5994 JSRef<JSVal> resId = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::ID)); 5995 if (!resId->IsNumber()) { 5996 return false; 5997 } 5998 5999 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 6000 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 6001 if (!resourceWrapper) { 6002 return false; 6003 } 6004 6005 auto resIdNum = resId->ToNumber<int32_t>(); 6006 if (resIdNum == -1) { 6007 if (!IsGetResourceByName(jsObj)) { 6008 return false; 6009 } 6010 JSRef<JSVal> args = jsObj->GetProperty("params"); 6011 if (!args->IsArray()) { 6012 return false; 6013 } 6014 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 6015 auto param = params->GetValueAt(0); 6016 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) { 6017 result = resourceWrapper->GetBooleanByName(param->ToString()); 6018 return true; 6019 } 6020 return false; 6021 } 6022 6023 if (resType == static_cast<int32_t>(ResourceType::BOOLEAN)) { 6024 result = resourceWrapper->GetBoolean(resId->ToNumber<uint32_t>()); 6025 return true; 6026 } 6027 return false; 6028 } 6029 ParseJsInteger(const JSRef<JSVal> & jsValue,uint32_t & result)6030 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, uint32_t& result) 6031 { 6032 return ParseJsInteger<uint32_t>(jsValue, result); 6033 } 6034 ParseJsInteger(const JSRef<JSVal> & jsValue,int32_t & result)6035 bool JSViewAbstract::ParseJsInteger(const JSRef<JSVal>& jsValue, int32_t& result) 6036 { 6037 return ParseJsInteger<int32_t>(jsValue, result); 6038 } 6039 ParseJsIntegerArray(const JSRef<JSVal> & jsValue,std::vector<uint32_t> & result)6040 bool JSViewAbstract::ParseJsIntegerArray(const JSRef<JSVal>& jsValue, std::vector<uint32_t>& result) 6041 { 6042 if (!jsValue->IsArray() && !jsValue->IsObject()) { 6043 return false; 6044 } 6045 6046 if (jsValue->IsArray()) { 6047 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue); 6048 for (size_t i = 0; i < array->Length(); i++) { 6049 JSRef<JSVal> value = array->GetValueAt(i); 6050 if (value->IsNumber()) { 6051 result.emplace_back(value->ToNumber<uint32_t>()); 6052 } else if (value->IsObject()) { 6053 uint32_t singleResInt; 6054 if (ParseJsInteger(value, singleResInt)) { 6055 result.emplace_back(singleResInt); 6056 } else { 6057 return false; 6058 } 6059 } else { 6060 return false; 6061 } 6062 } 6063 return true; 6064 } 6065 6066 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 6067 CompleteResourceObject(jsObj); 6068 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE); 6069 if (resType == UNKNOWN_RESOURCE_TYPE) { 6070 return false; 6071 } 6072 6073 JSRef<JSVal> resId = jsObj->GetProperty("id"); 6074 if (!resId->IsNumber()) { 6075 return false; 6076 } 6077 6078 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 6079 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 6080 if (!resourceWrapper) { 6081 return false; 6082 } 6083 6084 auto resIdNum = resId->ToNumber<int32_t>(); 6085 if (resIdNum == -1) { 6086 if (!IsGetResourceByName(jsObj)) { 6087 return false; 6088 } 6089 JSRef<JSVal> args = jsObj->GetProperty("params"); 6090 if (!args->IsArray()) { 6091 return false; 6092 } 6093 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 6094 auto param = params->GetValueAt(0); 6095 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) { 6096 result = resourceWrapper->GetIntArrayByName(param->ToString()); 6097 return true; 6098 } 6099 return false; 6100 } 6101 6102 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) { 6103 result = resourceWrapper->GetIntArray(resId->ToNumber<uint32_t>()); 6104 return true; 6105 } 6106 return false; 6107 } 6108 ParseJsStrArray(const JSRef<JSVal> & jsValue,std::vector<std::string> & result)6109 bool JSViewAbstract::ParseJsStrArray(const JSRef<JSVal>& jsValue, std::vector<std::string>& result) 6110 { 6111 if (!jsValue->IsArray() && !jsValue->IsObject()) { 6112 return false; 6113 } 6114 6115 if (jsValue->IsArray()) { 6116 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsValue); 6117 for (size_t i = 0; i < array->Length(); i++) { 6118 JSRef<JSVal> value = array->GetValueAt(i); 6119 if (value->IsString()) { 6120 result.emplace_back(value->ToString()); 6121 } else if (value->IsObject()) { 6122 std::string singleResStr; 6123 if (ParseJsString(value, singleResStr)) { 6124 result.emplace_back(singleResStr); 6125 } else { 6126 return false; 6127 } 6128 } else { 6129 return false; 6130 } 6131 } 6132 return true; 6133 } 6134 6135 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 6136 CompleteResourceObject(jsObj); 6137 int32_t resType = jsObj->GetPropertyValue<int32_t>("type", UNKNOWN_RESOURCE_TYPE); 6138 if (resType == UNKNOWN_RESOURCE_TYPE) { 6139 return false; 6140 } 6141 6142 JSRef<JSVal> resId = jsObj->GetProperty("id"); 6143 if (!resId->IsNumber()) { 6144 return false; 6145 } 6146 6147 auto resourceObject = GetResourceObjectByBundleAndModule(jsObj); 6148 auto resourceWrapper = CreateResourceWrapper(jsObj, resourceObject); 6149 if (!resourceWrapper) { 6150 return false; 6151 } 6152 6153 auto resIdNum = resId->ToNumber<int32_t>(); 6154 if (resIdNum == -1) { 6155 if (!IsGetResourceByName(jsObj)) { 6156 return false; 6157 } 6158 JSRef<JSVal> args = jsObj->GetProperty("params"); 6159 if (!args->IsArray()) { 6160 return false; 6161 } 6162 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 6163 auto param = params->GetValueAt(0); 6164 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) { 6165 result = resourceWrapper->GetStringArrayByName(param->ToString()); 6166 return true; 6167 } 6168 return false; 6169 } 6170 6171 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) { 6172 result = resourceWrapper->GetStringArray(resId->ToNumber<uint32_t>()); 6173 return true; 6174 } 6175 return false; 6176 } 6177 IsGetResourceByName(const JSRef<JSObject> & jsObj)6178 bool JSViewAbstract::IsGetResourceByName(const JSRef<JSObject>& jsObj) 6179 { 6180 JSRef<JSVal> resId = jsObj->GetProperty("id"); 6181 if (!resId->IsNumber() || resId->ToNumber<int32_t>() != -1) { 6182 return false; 6183 } 6184 JSRef<JSVal> args = jsObj->GetProperty("params"); 6185 if (!args->IsArray()) { 6186 return false; 6187 } 6188 JSRef<JSVal> bundleName = jsObj->GetProperty("bundleName"); 6189 JSRef<JSVal> moduleName = jsObj->GetProperty("moduleName"); 6190 if (!bundleName->IsString() || !moduleName->IsString()) { 6191 return false; 6192 } 6193 JSRef<JSArray> params = JSRef<JSArray>::Cast(args); 6194 if (params->IsEmpty()) { 6195 return false; 6196 } 6197 return true; 6198 } 6199 ParseSize(const JSCallbackInfo & info)6200 std::pair<CalcDimension, CalcDimension> JSViewAbstract::ParseSize(const JSCallbackInfo& info) 6201 { 6202 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 6203 auto jsVal = info[0]; 6204 if (!CheckJSCallbackInfo("ParseSize", jsVal, checkList)) { 6205 return std::pair<CalcDimension, CalcDimension>(); 6206 } 6207 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsVal); 6208 CalcDimension width; 6209 CalcDimension height; 6210 if (!ParseJsDimensionVp(jsObj->GetProperty("width"), width) || 6211 !ParseJsDimensionVp(jsObj->GetProperty("height"), height)) { 6212 return std::pair<CalcDimension, CalcDimension>(); 6213 } 6214 return std::pair<CalcDimension, CalcDimension>(width, height); 6215 } 6216 JsUseAlign(const JSCallbackInfo & info)6217 void JSViewAbstract::JsUseAlign(const JSCallbackInfo& info) 6218 { 6219 if (info.Length() < 2) { 6220 return; 6221 } 6222 6223 if (!info[0]->IsObject() && !info[1]->IsObject()) { 6224 return; 6225 } 6226 6227 AlignDeclaration* declaration = JSRef<JSObject>::Cast(info[0])->Unwrap<AlignDeclaration>(); 6228 if (declaration == nullptr) { 6229 return; 6230 } 6231 6232 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]); 6233 JSRef<JSVal> side = obj->GetProperty("side"); 6234 JSRef<JSVal> offset = obj->GetProperty("offset"); 6235 6236 if (!side->IsNumber()) { 6237 return; 6238 } 6239 6240 auto sideValue = side->ToNumber<int32_t>(); 6241 6242 if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::HORIZONTAL) { 6243 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::START) || 6244 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::END)) { 6245 return; 6246 } 6247 } else if (declaration->GetDeclarationType() == AlignDeclaration::DeclarationType::VERTICAL) { 6248 if (sideValue < static_cast<int32_t>(AlignDeclaration::Edge::TOP) || 6249 sideValue > static_cast<int32_t>(AlignDeclaration::Edge::BASELINE)) { 6250 return; 6251 } 6252 } 6253 6254 std::optional<CalcDimension> optOffset; 6255 CalcDimension offsetDimension; 6256 if (ParseJsDimensionVp(offset, offsetDimension)) { 6257 optOffset = offsetDimension; 6258 } 6259 ViewAbstractModel::GetInstance()->SetUseAlign( 6260 declaration, static_cast<AlignDeclaration::Edge>(sideValue), optOffset); 6261 } 6262 JsGridSpan(const JSCallbackInfo & info)6263 void JSViewAbstract::JsGridSpan(const JSCallbackInfo& info) 6264 { 6265 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER }; 6266 auto jsVal = info[0]; 6267 if (!CheckJSCallbackInfo("JsGridSpan", jsVal, checkList)) { 6268 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 6269 ViewAbstractModel::GetInstance()->SetGrid(NG::DEFAULT_GRID_SPAN, std::nullopt); 6270 } 6271 return; 6272 } 6273 auto span = jsVal->ToNumber<int32_t>(); 6274 ViewAbstractModel::GetInstance()->SetGrid(span, std::nullopt); 6275 } 6276 JsGridOffset(const JSCallbackInfo & info)6277 void JSViewAbstract::JsGridOffset(const JSCallbackInfo& info) 6278 { 6279 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER }; 6280 auto jsVal = info[0]; 6281 if (!CheckJSCallbackInfo("JsGridOffset", jsVal, checkList)) { 6282 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) { 6283 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, NG::DEFAULT_GRID_OFFSET); 6284 } 6285 return; 6286 } 6287 auto offset = jsVal->ToNumber<int32_t>(); 6288 ViewAbstractModel::GetInstance()->SetGrid(std::nullopt, offset); 6289 } 6290 ParseSpanAndOffset(const JSRef<JSVal> & val,uint32_t & span,int32_t & offset)6291 static bool ParseSpanAndOffset(const JSRef<JSVal>& val, uint32_t& span, int32_t& offset) 6292 { 6293 // {lg: 4} 6294 if (val->IsNumber()) { 6295 span = val->ToNumber<uint32_t>(); 6296 return true; 6297 } 6298 6299 if (!val->IsObject()) { 6300 return false; 6301 } 6302 6303 // {lg: {span: 1, offset: 2}} 6304 JSRef<JSObject> obj = JSRef<JSObject>::Cast(val); 6305 span = obj->GetProperty("span")->ToNumber<uint32_t>(); 6306 offset = obj->GetProperty("offset")->ToNumber<int32_t>(); 6307 return true; 6308 } 6309 JsUseSizeType(const JSCallbackInfo & info)6310 void JSViewAbstract::JsUseSizeType(const JSCallbackInfo& info) 6311 { 6312 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 6313 auto jsVal = info[0]; 6314 if (!CheckJSCallbackInfo("JsUseSizeType", jsVal, checkList)) { 6315 return; 6316 } 6317 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(jsVal); 6318 for (auto values : SCREEN_SIZE_VALUES) { 6319 JSRef<JSVal> val = sizeObj->GetProperty(values.second.c_str()); 6320 if (val->IsNull() || val->IsEmpty()) { 6321 continue; 6322 } 6323 uint32_t span = 0; 6324 int32_t offset = 0; 6325 if (ParseSpanAndOffset(val, span, offset)) { 6326 ViewAbstractModel::GetInstance()->SetGrid(span, offset, values.first); 6327 } 6328 } 6329 } 6330 JsZIndex(const JSCallbackInfo & info)6331 void JSViewAbstract::JsZIndex(const JSCallbackInfo& info) 6332 { 6333 int zIndex = 0; 6334 if (info[0]->IsNumber()) { 6335 zIndex = info[0]->ToNumber<int>(); 6336 } 6337 6338 ViewAbstractModel::GetInstance()->SetZIndex(zIndex); 6339 } 6340 Pop()6341 void JSViewAbstract::Pop() 6342 { 6343 ViewStackModel::GetInstance()->Pop(); 6344 } 6345 JsSetDraggable(bool draggable)6346 void JSViewAbstract::JsSetDraggable(bool draggable) 6347 { 6348 ViewAbstractModel::GetInstance()->SetDraggable(draggable); 6349 } 6350 ParseDragPreviewOptions(const JSCallbackInfo & info)6351 NG::DragPreviewOption JSViewAbstract::ParseDragPreviewOptions (const JSCallbackInfo& info) 6352 { 6353 NG::DragPreviewOption previewOption; 6354 if (!info[0]->IsObject()) { 6355 return previewOption; 6356 } 6357 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]); 6358 auto mode = obj->GetProperty("mode"); 6359 bool isAuto = true; 6360 if (mode->IsNumber()) { 6361 ParseDragPreviewMode(previewOption, mode->ToNumber<int>(), isAuto); 6362 } else if (mode->IsArray()) { 6363 JSRef<JSArray> array = JSRef<JSArray>::Cast(mode); 6364 for (size_t i = 0; i < array->Length(); i++) { 6365 JSRef<JSVal> value = array->GetValueAt(i); 6366 if (value->IsNumber()) { 6367 ParseDragPreviewMode(previewOption, value->ToNumber<int>(), isAuto); 6368 } 6369 if (isAuto) { 6370 break; 6371 } 6372 } 6373 } 6374 6375 JSViewAbstract::SetDragNumberBadge(info, previewOption); 6376 6377 if (info.Length() > 1 && info[1]->IsObject()) { 6378 JSRef<JSObject> interObj = JSRef<JSObject>::Cast(info[1]); 6379 auto multiSelection = interObj->GetProperty("isMultiSelectionEnabled"); 6380 if (multiSelection->IsBoolean()) { 6381 previewOption.isMultiSelectionEnabled = multiSelection->ToBoolean(); 6382 } 6383 auto defaultAnimation = interObj->GetProperty("defaultAnimationBeforeLifting"); 6384 if (defaultAnimation->IsBoolean()) { 6385 previewOption.defaultAnimationBeforeLifting = defaultAnimation->ToBoolean(); 6386 } 6387 auto dragPreview = interObj->GetProperty("isDragPreviewEnabled"); 6388 if (dragPreview->IsBoolean()) { 6389 previewOption.isDragPreviewEnabled = dragPreview->ToBoolean(); 6390 } 6391 } 6392 6393 JSViewAbstract::SetDragPreviewOptionApply(info, previewOption); 6394 6395 return previewOption; 6396 } 6397 JsSetDragPreviewOptions(const JSCallbackInfo & info)6398 void JSViewAbstract::JsSetDragPreviewOptions(const JSCallbackInfo& info) 6399 { 6400 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 6401 auto jsVal = info[0]; 6402 if (!CheckJSCallbackInfo("JsSetDragPreviewOptions", jsVal, checkList)) { 6403 return; 6404 } 6405 NG::DragPreviewOption previewOption = ParseDragPreviewOptions(info); 6406 ViewAbstractModel::GetInstance()->SetDragPreviewOptions(previewOption); 6407 } 6408 JsOnDragStart(const JSCallbackInfo & info)6409 void JSViewAbstract::JsOnDragStart(const JSCallbackInfo& info) 6410 { 6411 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6412 auto jsVal = info[0]; 6413 if (!CheckJSCallbackInfo("JsOnDragStart", jsVal, checkList)) { 6414 return; 6415 } 6416 6417 RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal)); 6418 6419 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6420 auto onDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode]( 6421 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo { 6422 NG::DragDropBaseInfo dragDropInfo; 6423 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, dragDropInfo); 6424 PipelineContext::SetCallBackNode(node); 6425 auto ret = func->Execute(info, extraParams); 6426 if (!ret->IsObject()) { 6427 return dragDropInfo; 6428 } 6429 6430 dragDropInfo.node = ParseDragNode(ret); 6431 auto builderObj = JSRef<JSObject>::Cast(ret); 6432 #if defined(PIXEL_MAP_SUPPORTED) 6433 auto pixmap = builderObj->GetProperty("pixelMap"); 6434 dragDropInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap); 6435 #endif 6436 auto extraInfo = builderObj->GetProperty("extraInfo"); 6437 ParseJsString(extraInfo, dragDropInfo.extraInfo); 6438 return dragDropInfo; 6439 }; 6440 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart)); 6441 } 6442 ParseAndUpdateDragItemInfo(const JSRef<JSVal> & info,NG::DragDropBaseInfo & dragInfo)6443 bool JSViewAbstract::ParseAndUpdateDragItemInfo(const JSRef<JSVal>& info, NG::DragDropBaseInfo& dragInfo) 6444 { 6445 auto node = ParseDragNode(info); 6446 if (!node) { 6447 return false; 6448 } 6449 dragInfo.node = node; 6450 return true; 6451 } 6452 ParseDragNode(const JSRef<JSVal> & info)6453 RefPtr<AceType> JSViewAbstract::ParseDragNode(const JSRef<JSVal>& info) 6454 { 6455 auto builderFunc = ParseDragStartBuilderFunc(info); 6456 if (!builderFunc) { 6457 return nullptr; 6458 } 6459 // use another VSP instance while executing the builder function 6460 ViewStackModel::GetInstance()->NewScope(); 6461 { 6462 ACE_SCORING_EVENT("onDragStart.builder"); 6463 builderFunc->Execute(); 6464 } 6465 6466 return ViewStackModel::GetInstance()->Finish(); 6467 } 6468 JsOnDragEnter(const JSCallbackInfo & info)6469 void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info) 6470 { 6471 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6472 auto jsVal = info[0]; 6473 if (!CheckJSCallbackInfo("JsOnDragEnter", jsVal, checkList)) { 6474 return; 6475 } 6476 RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal)); 6477 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6478 auto onDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc), node = frameNode]( 6479 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) { 6480 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6481 ACE_SCORING_EVENT("onDragEnter"); 6482 PipelineContext::SetCallBackNode(node); 6483 func->Execute(info, extraParams); 6484 }; 6485 6486 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter)); 6487 } 6488 JsOnDragEnd(const JSCallbackInfo & info)6489 void JSViewAbstract::JsOnDragEnd(const JSCallbackInfo& info) 6490 { 6491 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6492 auto jsVal = info[0]; 6493 if (!CheckJSCallbackInfo("JsOnDragEnd", jsVal, checkList)) { 6494 return; 6495 } 6496 RefPtr<JsDragFunction> jsOnDragEndFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal)); 6497 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6498 auto onDragEnd = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEndFunc), node = frameNode]( 6499 const RefPtr<OHOS::Ace::DragEvent>& info) { 6500 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6501 ACE_SCORING_EVENT("onDragEnd"); 6502 auto extraParams = JsonUtil::Create(true); 6503 PipelineContext::SetCallBackNode(node); 6504 func->Execute(info, extraParams->ToString()); 6505 }; 6506 6507 ViewAbstractModel::GetInstance()->SetOnDragEnd(std::move(onDragEnd)); 6508 } 6509 JsOnDragMove(const JSCallbackInfo & info)6510 void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info) 6511 { 6512 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6513 auto jsVal = info[0]; 6514 if (!CheckJSCallbackInfo("JsOnDragMove", jsVal, checkList)) { 6515 return; 6516 } 6517 RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal)); 6518 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6519 auto onDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc), node = frameNode]( 6520 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) { 6521 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6522 ACE_SCORING_EVENT("onDragMove"); 6523 PipelineContext::SetCallBackNode(node); 6524 func->Execute(info, extraParams); 6525 }; 6526 6527 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove)); 6528 } 6529 JsOnDragLeave(const JSCallbackInfo & info)6530 void JSViewAbstract::JsOnDragLeave(const JSCallbackInfo& info) 6531 { 6532 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6533 auto jsVal = info[0]; 6534 if (!CheckJSCallbackInfo("JsOnDragLeave", jsVal, checkList)) { 6535 return; 6536 } 6537 RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal)); 6538 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6539 auto onDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc), node = frameNode]( 6540 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) { 6541 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6542 ACE_SCORING_EVENT("onDragLeave"); 6543 PipelineContext::SetCallBackNode(node); 6544 func->Execute(info, extraParams); 6545 }; 6546 6547 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave)); 6548 } 6549 JsOnDrop(const JSCallbackInfo & info)6550 void JSViewAbstract::JsOnDrop(const JSCallbackInfo& info) 6551 { 6552 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6553 auto jsVal = info[0]; 6554 if (!CheckJSCallbackInfo("JsOnDrop", jsVal, checkList)) { 6555 return; 6556 } 6557 RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal)); 6558 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6559 auto onDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc), node = frameNode]( 6560 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) { 6561 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6562 ACE_SCORING_EVENT("onDrop"); 6563 PipelineContext::SetCallBackNode(node); 6564 func->Execute(info, extraParams); 6565 }; 6566 6567 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop)); 6568 } 6569 JsOnAreaChange(const JSCallbackInfo & info)6570 void JSViewAbstract::JsOnAreaChange(const JSCallbackInfo& info) 6571 { 6572 auto jsVal = info[0]; 6573 if (jsVal->IsUndefined() && IsDisableEventVersion()) { 6574 ViewAbstractModel::GetInstance()->DisableOnAreaChange(); 6575 return; 6576 } 6577 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6578 if (!CheckJSCallbackInfo("JsOnAreaChange", jsVal, checkList)) { 6579 return; 6580 } 6581 auto jsOnAreaChangeFunction = AceType::MakeRefPtr<JsOnAreaChangeFunction>(JSRef<JSFunc>::Cast(jsVal)); 6582 6583 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6584 auto onAreaChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAreaChangeFunction), 6585 node = frameNode]( 6586 const Rect& oldRect, const Offset& oldOrigin, const Rect& rect, const Offset& origin) { 6587 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6588 ACE_SCORING_EVENT("onAreaChange"); 6589 PipelineContext::SetCallBackNode(node); 6590 func->Execute(oldRect, oldOrigin, rect, origin); 6591 }; 6592 ViewAbstractModel::GetInstance()->SetOnAreaChanged(std::move(onAreaChanged)); 6593 } 6594 JsOnSizeChange(const JSCallbackInfo & info)6595 void JSViewAbstract::JsOnSizeChange(const JSCallbackInfo& info) 6596 { 6597 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 6598 auto jsVal = info[0]; 6599 if (!CheckJSCallbackInfo("JsOnSizeChange", jsVal, checkList)) { 6600 return; 6601 } 6602 auto jsOnSizeChangeFunction = AceType::MakeRefPtr<JsOnSizeChangeFunction>(JSRef<JSFunc>::Cast(jsVal)); 6603 6604 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6605 auto onSizeChanged = [execCtx = info.GetExecutionContext(), func = std::move(jsOnSizeChangeFunction), 6606 node = frameNode](const NG::RectF& oldRect, const NG::RectF& rect) { 6607 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6608 ACE_SCORING_EVENT("onSizeChange"); 6609 PipelineContext::SetCallBackNode(node); 6610 func->Execute(oldRect, rect); 6611 }; 6612 ViewAbstractModel::GetInstance()->SetOnSizeChanged(std::move(onSizeChanged)); 6613 } 6614 6615 #ifndef WEARABLE_PRODUCT JsBindPopup(const JSCallbackInfo & info)6616 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info) 6617 { 6618 if (info.Length() < 2) { 6619 return; 6620 } 6621 if ((!info[0]->IsBoolean() && !info[0]->IsObject()) || !info[1]->IsObject()) { 6622 return; 6623 } 6624 auto popupParam = AceType::MakeRefPtr<PopupParam>(); 6625 // Set IsShow to popupParam 6626 if (info[0]->IsBoolean()) { 6627 popupParam->SetIsShow(info[0]->ToBoolean()); 6628 } else { 6629 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[0]); 6630 auto callback = ParseDoubleBindCallback(info, showObj); 6631 popupParam->SetOnStateChange(std::move(callback)); 6632 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean()); 6633 } 6634 // Set popup to popupParam 6635 auto popupObj = JSRef<JSObject>::Cast(info[1]); 6636 SetPopupDismiss(info, popupObj, popupParam); 6637 if (popupObj->GetProperty("message")->IsString()) { 6638 ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param 6639 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr); 6640 } else if (!popupObj->GetProperty("builder").IsEmpty()) { 6641 ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param 6642 auto builderValue = popupObj->GetProperty("builder"); 6643 auto builder = builderValue; 6644 if (!builderValue->IsObject()) { 6645 return; 6646 } 6647 if (!builderValue->IsFunction()) { 6648 JSRef<JSObject> builderObj; 6649 builderObj = JSRef<JSObject>::Cast(builderValue); 6650 builder = builderObj->GetProperty("builder"); 6651 if (!builder->IsFunction()) { 6652 return; 6653 } 6654 } 6655 if (popupParam->IsShow() && !IsPopupCreated()) { 6656 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 6657 CHECK_NULL_VOID(builderFunc); 6658 ViewStackModel::GetInstance()->NewScope(); 6659 builderFunc->Execute(); 6660 auto customNode = ViewStackModel::GetInstance()->Finish(); 6661 ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode); 6662 } else { 6663 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr); 6664 } 6665 } else { 6666 return; 6667 } 6668 } 6669 SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)6670 void JSViewAbstract::SetPopupDismiss( 6671 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam) 6672 { 6673 auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss"); 6674 if (onWillDismissFunc->IsBoolean()) { 6675 bool onWillDismissBool = onWillDismissFunc->ToBoolean(); 6676 popupParam->SetInteractiveDismiss(onWillDismissBool); 6677 popupParam->SetOnWillDismiss(nullptr); 6678 if (onWillDismissBool) { 6679 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss"); 6680 } 6681 } else if (onWillDismissFunc->IsFunction()) { 6682 auto onWillDismissCallback = ParsePopupCallback(info, popupObj); 6683 popupParam->SetOnWillDismiss(std::move(onWillDismissCallback)); 6684 popupParam->SetInteractiveDismiss(true); 6685 if (onWillDismissCallback != nullptr) { 6686 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss"); 6687 } 6688 } 6689 } 6690 ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)6691 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj) 6692 { 6693 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss"); 6694 if (!onWillDismissFunc->IsFunction()) { 6695 return PopupOnWillDismiss(); 6696 } 6697 RefPtr<JsFunction> jsFunc = 6698 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc)); 6699 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 6700 auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), 6701 node = frameNode](int32_t reason) { 6702 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 6703 ACE_SCORING_EVENT("Bindpopup.dismiss"); 6704 PipelineContext::SetCallBackNode(node); 6705 6706 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New(); 6707 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT); 6708 JSRef<JSObject> dismissObj = objectTemplate->NewInstance(); 6709 dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup)); 6710 dismissObj->SetProperty<int32_t>("reason", reason); 6711 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj); 6712 6713 func->ExecuteJS(1, &newJSVal); 6714 }; 6715 return onWillDismiss; 6716 } 6717 JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)6718 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo) 6719 { 6720 ViewAbstractModel::GetInstance()->DismissPopup(); 6721 return JSValueRef::Undefined(runtimeCallInfo->GetVM()); 6722 } 6723 #endif 6724 ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info)> & onWillDismiss)6725 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj, 6726 std::function<void(const int32_t& info)>& onWillDismiss) 6727 { 6728 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss"); 6729 if (onWillDismissFunc->IsFunction()) { 6730 auto jsFunc = 6731 AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc)); 6732 onWillDismiss = [func = std::move(jsFunc)](const int32_t& info) { 6733 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New(); 6734 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT); 6735 JSRef<JSObject> dismissObj = objectTemplate->NewInstance(); 6736 dismissObj->SetPropertyObject( 6737 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog)); 6738 dismissObj->SetProperty<int32_t>("reason", info); 6739 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj); 6740 func->ExecuteJS(1, &newJSVal); 6741 }; 6742 } 6743 } 6744 JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)6745 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo) 6746 { 6747 ViewAbstractModel::GetInstance()->DismissDialog(); 6748 return JSValueRef::Undefined(runtimeCallInfo->GetVM()); 6749 } 6750 JsLinearGradient(const JSCallbackInfo & info)6751 void JSViewAbstract::JsLinearGradient(const JSCallbackInfo& info) 6752 { 6753 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 6754 auto jsVal = info[0]; 6755 if (!CheckJSCallbackInfo("LinearGradient", jsVal, checkList)) { 6756 NG::Gradient newGradient; 6757 newGradient.CreateGradientWithType(NG::GradientType::LINEAR); 6758 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient); 6759 return; 6760 } 6761 NG::Gradient newGradient; 6762 NewJsLinearGradient(info, newGradient); 6763 ViewAbstractModel::GetInstance()->SetLinearGradient(newGradient); 6764 } 6765 NewJsLinearGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6766 void JSViewAbstract::NewJsLinearGradient(const JSCallbackInfo& info, NG::Gradient& newGradient) 6767 { 6768 if (!info[0]->IsObject()) { 6769 return; 6770 } 6771 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]); 6772 newGradient.CreateGradientWithType(NG::GradientType::LINEAR); 6773 // angle 6774 std::optional<float> degree; 6775 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 6776 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree); 6777 } else { 6778 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ANGLE), jsObj, degree, 180.0f); 6779 } 6780 if (degree) { 6781 newGradient.GetLinearGradient()->angle = CalcDimension(degree.value(), DimensionUnit::PX); 6782 degree.reset(); 6783 } 6784 // direction 6785 auto direction = static_cast<GradientDirection>( 6786 jsObj->GetPropertyValue<int32_t>("direction", static_cast<int32_t>(GradientDirection::NONE))); 6787 switch (direction) { 6788 case GradientDirection::LEFT: 6789 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT; 6790 break; 6791 case GradientDirection::RIGHT: 6792 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT; 6793 break; 6794 case GradientDirection::TOP: 6795 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP; 6796 break; 6797 case GradientDirection::BOTTOM: 6798 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM; 6799 break; 6800 case GradientDirection::LEFT_TOP: 6801 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT; 6802 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP; 6803 break; 6804 case GradientDirection::LEFT_BOTTOM: 6805 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::LEFT; 6806 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM; 6807 break; 6808 case GradientDirection::RIGHT_TOP: 6809 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT; 6810 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::TOP; 6811 break; 6812 case GradientDirection::RIGHT_BOTTOM: 6813 newGradient.GetLinearGradient()->linearX = NG::GradientDirection::RIGHT; 6814 newGradient.GetLinearGradient()->linearY = NG::GradientDirection::BOTTOM; 6815 break; 6816 case GradientDirection::NONE: 6817 case GradientDirection::START_TO_END: 6818 case GradientDirection::END_TO_START: 6819 default: 6820 break; 6821 } 6822 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false); 6823 newGradient.SetRepeat(repeating); 6824 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS))); 6825 } 6826 JsRadialGradient(const JSCallbackInfo & info)6827 void JSViewAbstract::JsRadialGradient(const JSCallbackInfo& info) 6828 { 6829 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 6830 auto jsVal = info[0]; 6831 if (!CheckJSCallbackInfo("JsRadialGradient", jsVal, checkList)) { 6832 NG::Gradient newGradient; 6833 newGradient.CreateGradientWithType(NG::GradientType::RADIAL); 6834 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient); 6835 return; 6836 } 6837 NG::Gradient newGradient; 6838 NewJsRadialGradient(info, newGradient); 6839 ViewAbstractModel::GetInstance()->SetRadialGradient(newGradient); 6840 } 6841 NewJsRadialGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6842 void JSViewAbstract::NewJsRadialGradient(const JSCallbackInfo& info, NG::Gradient& newGradient) 6843 { 6844 JSRef<JSVal> arg = info[0]; 6845 if (!arg->IsObject()) { 6846 return; 6847 } 6848 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg); 6849 newGradient.CreateGradientWithType(NG::GradientType::RADIAL); 6850 // center 6851 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER)); 6852 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) { 6853 CalcDimension value; 6854 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center); 6855 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) { 6856 newGradient.GetRadialGradient()->radialCenterX = CalcDimension(value); 6857 if (value.Unit() == DimensionUnit::PERCENT) { 6858 // [0,1] -> [0, 100] 6859 newGradient.GetRadialGradient()->radialCenterX = 6860 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT); 6861 } 6862 } 6863 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) { 6864 newGradient.GetRadialGradient()->radialCenterY = CalcDimension(value); 6865 if (value.Unit() == DimensionUnit::PERCENT) { 6866 // [0,1] -> [0, 100] 6867 newGradient.GetRadialGradient()->radialCenterY = 6868 CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT); 6869 } 6870 } 6871 } 6872 // radius 6873 CalcDimension radius; 6874 if (ParseJsDimensionVp(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius)) { 6875 newGradient.GetRadialGradient()->radialVerticalSize = CalcDimension(radius); 6876 newGradient.GetRadialGradient()->radialHorizontalSize = CalcDimension(radius); 6877 } 6878 // repeating 6879 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false); 6880 newGradient.SetRepeat(repeating); 6881 // color stops 6882 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS))); 6883 } 6884 JsSweepGradient(const JSCallbackInfo & info)6885 void JSViewAbstract::JsSweepGradient(const JSCallbackInfo& info) 6886 { 6887 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 6888 auto jsVal = info[0]; 6889 if (!CheckJSCallbackInfo("JsSweepGradient", jsVal, checkList)) { 6890 NG::Gradient newGradient; 6891 newGradient.CreateGradientWithType(NG::GradientType::SWEEP); 6892 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient); 6893 return; 6894 } 6895 6896 NG::Gradient newGradient; 6897 NewJsSweepGradient(info, newGradient); 6898 ViewAbstractModel::GetInstance()->SetSweepGradient(newGradient); 6899 } 6900 NewJsSweepGradient(const JSCallbackInfo & info,NG::Gradient & newGradient)6901 void JSViewAbstract::NewJsSweepGradient(const JSCallbackInfo& info, NG::Gradient& newGradient) 6902 { 6903 JSRef<JSVal> arg = info[0]; 6904 if (!arg->IsObject()) { 6905 return; 6906 } 6907 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(arg); 6908 newGradient.CreateGradientWithType(NG::GradientType::SWEEP); 6909 // center 6910 JSRef<JSVal> center = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::CENTER)); 6911 if (center->IsArray() && JSRef<JSArray>::Cast(center)->Length() == 2) { 6912 CalcDimension value; 6913 JSRef<JSArray> centerArray = JSRef<JSArray>::Cast(center); 6914 if (ParseJsDimensionVp(centerArray->GetValueAt(0), value)) { 6915 newGradient.GetSweepGradient()->centerX = CalcDimension(value); 6916 if (value.Unit() == DimensionUnit::PERCENT) { 6917 // [0,1] -> [0, 100] 6918 newGradient.GetSweepGradient()->centerX = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT); 6919 } 6920 } 6921 if (ParseJsDimensionVp(centerArray->GetValueAt(1), value)) { 6922 newGradient.GetSweepGradient()->centerY = CalcDimension(value); 6923 if (value.Unit() == DimensionUnit::PERCENT) { 6924 // [0,1] -> [0, 100] 6925 newGradient.GetSweepGradient()->centerY = CalcDimension(value.Value() * 100.0, DimensionUnit::PERCENT); 6926 } 6927 } 6928 } 6929 // start, end and rotation 6930 ParseSweepGradientPartly(jsObj, newGradient); 6931 // repeating 6932 auto repeating = jsObj->GetPropertyValue<bool>("repeating", false); 6933 newGradient.SetRepeat(repeating); 6934 // color stops 6935 NewGetJsGradientColorStops(newGradient, jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLORS))); 6936 } 6937 ParseSweepGradientPartly(const JSRef<JSObject> & obj,NG::Gradient & newGradient)6938 void JSViewAbstract::ParseSweepGradientPartly(const JSRef<JSObject>& obj, NG::Gradient& newGradient) 6939 { 6940 std::optional<float> degreeStart; 6941 std::optional<float> degreeEnd; 6942 std::optional<float> degreeRotation; 6943 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 6944 GetJsAngle(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart); 6945 GetJsAngle(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd); 6946 GetJsAngle(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation); 6947 } else { 6948 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::START), obj, degreeStart, 0.0f); 6949 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::END), obj, degreeEnd, 0.0f); 6950 GetJsAngleWithDefault(static_cast<int32_t>(ArkUIIndex::ROTATION), obj, degreeRotation, 0.0f); 6951 } 6952 if (degreeStart) { 6953 CheckAngle(degreeStart); 6954 newGradient.GetSweepGradient()->startAngle = CalcDimension(degreeStart.value(), DimensionUnit::PX); 6955 } 6956 if (degreeEnd) { 6957 CheckAngle(degreeEnd); 6958 newGradient.GetSweepGradient()->endAngle = CalcDimension(degreeEnd.value(), DimensionUnit::PX); 6959 } 6960 if (degreeRotation) { 6961 CheckAngle(degreeRotation); 6962 newGradient.GetSweepGradient()->rotation = CalcDimension(degreeRotation.value(), DimensionUnit::PX); 6963 } 6964 } 6965 JsMotionPath(const JSCallbackInfo & info)6966 void JSViewAbstract::JsMotionPath(const JSCallbackInfo& info) 6967 { 6968 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT }; 6969 auto jsVal = info[0]; 6970 if (!CheckJSCallbackInfo("JsMotionPath", jsVal, checkList)) { 6971 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption()); 6972 return; 6973 } 6974 MotionPathOption motionPathOption; 6975 if (ParseMotionPath(jsVal, motionPathOption)) { 6976 ViewAbstractModel::GetInstance()->SetMotionPath(motionPathOption); 6977 } else { 6978 TAG_LOGI(AceLogTag::ACE_ANIMATION, "Parse animation motionPath failed. %{public}s", jsVal->ToString().c_str()); 6979 ViewAbstractModel::GetInstance()->SetMotionPath(MotionPathOption()); 6980 } 6981 } 6982 JsShadow(const JSCallbackInfo & info)6983 void JSViewAbstract::JsShadow(const JSCallbackInfo& info) 6984 { 6985 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER }; 6986 auto jsVal = info[0]; 6987 if (!CheckJSCallbackInfo("JsShadow", jsVal, checkList)) { 6988 Shadow shadow; 6989 std::vector<Shadow> shadows { shadow }; 6990 ViewAbstractModel::GetInstance()->SetBackShadow(shadows); 6991 return; 6992 } 6993 Shadow shadow; 6994 if (!ParseShadowProps(jsVal, shadow)) { 6995 info.ReturnSelf(); 6996 return; 6997 } 6998 std::vector<Shadow> shadows { shadow }; 6999 ViewAbstractModel::GetInstance()->SetBackShadow(shadows); 7000 } 7001 JsBlendMode(const JSCallbackInfo & info)7002 void JSViewAbstract::JsBlendMode(const JSCallbackInfo& info) 7003 { 7004 if (info.Length() == 0) { 7005 return; 7006 } 7007 BlendMode blendMode = BlendMode::NONE; 7008 BlendApplyType blendApplyType = BlendApplyType::FAST; 7009 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon 7010 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000; 7011 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000; 7012 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000; 7013 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000; 7014 if (info[0]->IsNumber()) { 7015 auto blendModeNum = info[0]->ToNumber<int32_t>(); 7016 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) { 7017 blendMode = static_cast<BlendMode>(blendModeNum); 7018 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) { 7019 // backward compatibility code, will remove soon 7020 blendMode = BlendMode::SRC_OVER; 7021 blendApplyType = BlendApplyType::OFFSCREEN; 7022 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) { 7023 // backward compatibility code, will remove soon 7024 blendMode = BlendMode::SRC_IN; 7025 blendApplyType = BlendApplyType::OFFSCREEN; 7026 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) { 7027 // backward compatibility code, will remove soon 7028 blendMode = BlendMode::DST_IN; 7029 blendApplyType = BlendApplyType::OFFSCREEN; 7030 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) { 7031 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN; 7032 } 7033 } 7034 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) { 7035 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>(); 7036 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) { 7037 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum); 7038 } 7039 } 7040 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode); 7041 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType); 7042 } 7043 JsAdvancedBlendMode(const JSCallbackInfo & info)7044 void JSViewAbstract::JsAdvancedBlendMode(const JSCallbackInfo& info) 7045 { 7046 if (info.Length() == 0) { 7047 return; 7048 } 7049 BlendMode blendMode = BlendMode::NONE; 7050 BlendApplyType blendApplyType = BlendApplyType::FAST; 7051 // for backward compatible, we temporary add a magic number to trigger offscreen, will remove soon 7052 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN = 1000; 7053 constexpr int BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN = 2000; 7054 constexpr int BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN = 3000; 7055 constexpr int BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN = 5000; 7056 if (info[0]->IsNumber()) { 7057 auto blendModeNum = info[0]->ToNumber<int32_t>(); 7058 if (blendModeNum >= 0 && blendModeNum < static_cast<int>(BlendMode::MAX)) { 7059 blendMode = static_cast<BlendMode>(blendModeNum); 7060 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_OFFSCREEN) { 7061 // backward compatibility code, will remove soon 7062 blendMode = BlendMode::SRC_OVER; 7063 blendApplyType = BlendApplyType::OFFSCREEN; 7064 } else if (blendModeNum == BACKWARD_COMPAT_SOURCE_IN_NUMBER_OFFSCREEN) { 7065 // backward compatibility code, will remove soon 7066 blendMode = BlendMode::SRC_IN; 7067 blendApplyType = BlendApplyType::OFFSCREEN; 7068 } else if (blendModeNum == BACKWARD_COMPAT_DESTINATION_IN_NUMBER_OFFSCREEN) { 7069 // backward compatibility code, will remove soon 7070 blendMode = BlendMode::DST_IN; 7071 blendApplyType = BlendApplyType::OFFSCREEN; 7072 } else if (blendModeNum == BACKWARD_COMPAT_MAGIC_NUMBER_SRC_IN) { 7073 blendMode = BlendMode::BACK_COMPAT_SOURCE_IN; 7074 } 7075 } else if (info[0]->IsObject()) { 7076 auto blender = CreateRSBrightnessBlenderFromNapiValue(info[0]); 7077 ViewAbstractModel::GetInstance()->SetBrightnessBlender(blender); 7078 } 7079 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) { 7080 auto blendApplyTypeNum = info[1]->ToNumber<int32_t>(); 7081 if (blendApplyTypeNum >= 0 && blendApplyTypeNum < static_cast<int>(BlendApplyType::MAX)) { 7082 blendApplyType = static_cast<BlendApplyType>(blendApplyTypeNum); 7083 } 7084 } 7085 if (!info[0]->IsObject()) { 7086 ViewAbstractModel::GetInstance()->SetBlendMode(blendMode); 7087 } 7088 ViewAbstractModel::GetInstance()->SetBlendApplyType(blendApplyType); 7089 } 7090 JsGrayScale(const JSCallbackInfo & info)7091 void JSViewAbstract::JsGrayScale(const JSCallbackInfo& info) 7092 { 7093 CalcDimension value; 7094 if (!ParseJsDimensionVp(info[0], value)) { 7095 value.SetValue(0.0); 7096 ViewAbstractModel::GetInstance()->SetGrayScale(value); 7097 return; 7098 } 7099 7100 if (LessNotEqual(value.Value(), 0.0)) { 7101 value.SetValue(0.0); 7102 } 7103 7104 if (GreatNotEqual(value.Value(), 1.0)) { 7105 value.SetValue(1.0); 7106 } 7107 7108 ViewAbstractModel::GetInstance()->SetGrayScale(value); 7109 } 7110 JsBrightness(const JSCallbackInfo & info)7111 void JSViewAbstract::JsBrightness(const JSCallbackInfo& info) 7112 { 7113 CalcDimension value; 7114 if (!ParseJsDimensionVp(info[0], value)) { 7115 value.SetValue(1.0); 7116 ViewAbstractModel::GetInstance()->SetBrightness(value); 7117 return; 7118 } 7119 7120 ViewAbstractModel::GetInstance()->SetBrightness(value); 7121 } 7122 JsContrast(const JSCallbackInfo & info)7123 void JSViewAbstract::JsContrast(const JSCallbackInfo& info) 7124 { 7125 CalcDimension value; 7126 if (!ParseJsDimensionVp(info[0], value)) { 7127 value.SetValue(1.0); 7128 ViewAbstractModel::GetInstance()->SetContrast(value); 7129 return; 7130 } 7131 7132 if (LessNotEqual(value.Value(), 0.0)) { 7133 value.SetValue(0.0); 7134 } 7135 7136 ViewAbstractModel::GetInstance()->SetContrast(value); 7137 } 7138 JsSaturate(const JSCallbackInfo & info)7139 void JSViewAbstract::JsSaturate(const JSCallbackInfo& info) 7140 { 7141 CalcDimension value; 7142 if (!ParseJsDimensionVp(info[0], value)) { 7143 value.SetValue(1.0); 7144 ViewAbstractModel::GetInstance()->SetSaturate(value); 7145 return; 7146 } 7147 7148 if (LessNotEqual(value.Value(), 0.0)) { 7149 value.SetValue(0.0); 7150 } 7151 7152 ViewAbstractModel::GetInstance()->SetSaturate(value); 7153 } 7154 JsSepia(const JSCallbackInfo & info)7155 void JSViewAbstract::JsSepia(const JSCallbackInfo& info) 7156 { 7157 CalcDimension value; 7158 if (!ParseJsDimensionVp(info[0], value)) { 7159 value.SetValue(0.0); 7160 ViewAbstractModel::GetInstance()->SetSepia(value); 7161 return; 7162 } 7163 7164 if (LessNotEqual(value.Value(), 0.0)) { 7165 value.SetValue(0.0); 7166 } 7167 7168 ViewAbstractModel::GetInstance()->SetSepia(value); 7169 } 7170 ParseInvertProps(const JSRef<JSVal> & jsValue,InvertVariant & invert)7171 bool JSViewAbstract::ParseInvertProps(const JSRef<JSVal>& jsValue, InvertVariant& invert) 7172 { 7173 double invertValue = 0.0; 7174 if (ParseJsDouble(jsValue, invertValue)) { 7175 invert = static_cast<float>(std::clamp(invertValue, 0.0, 1.0)); 7176 return true; 7177 } 7178 auto argsPtrItem = JsonUtil::ParseJsonString(jsValue->ToString()); 7179 if (!argsPtrItem || argsPtrItem->IsNull()) { 7180 return false; 7181 } 7182 InvertOption option; 7183 double low = 0.0; 7184 if (ParseJsonDouble(argsPtrItem->GetValue("low"), low)) { 7185 option.low_ = std::clamp(low, 0.0, 1.0); 7186 } 7187 double high = 0.0; 7188 if (ParseJsonDouble(argsPtrItem->GetValue("high"), high)) { 7189 option.high_ = std::clamp(high, 0.0, 1.0); 7190 } 7191 double threshold = 0.0; 7192 if (ParseJsonDouble(argsPtrItem->GetValue("threshold"), threshold)) { 7193 option.threshold_ = std::clamp(threshold, 0.0, 1.0); 7194 } 7195 double thresholdRange = 0.0; 7196 if (ParseJsonDouble(argsPtrItem->GetValue("thresholdRange"), thresholdRange)) { 7197 option.thresholdRange_ = std::clamp(thresholdRange, 0.0, 1.0); 7198 } 7199 invert = option; 7200 return true; 7201 } 7202 JsInvert(const JSCallbackInfo & info)7203 void JSViewAbstract::JsInvert(const JSCallbackInfo& info) 7204 { 7205 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::OBJECT, JSCallbackInfoType::NUMBER }; 7206 InvertVariant invert = 0.0f; 7207 auto jsVal = info[0]; 7208 if (!CheckJSCallbackInfo("JsInvert", jsVal, checkList)) { 7209 ViewAbstractModel::GetInstance()->SetInvert(invert); 7210 return; 7211 } 7212 if (ParseInvertProps(jsVal, invert)) { 7213 ViewAbstractModel::GetInstance()->SetInvert(invert); 7214 } 7215 ViewAbstractModel::GetInstance()->SetInvert(invert); 7216 } 7217 JsSystemBarEffect(const JSCallbackInfo & info)7218 void JSViewAbstract::JsSystemBarEffect(const JSCallbackInfo& info) 7219 { 7220 ViewAbstractModel::GetInstance()->SetSystemBarEffect(true); 7221 } 7222 JsHueRotate(const JSCallbackInfo & info)7223 void JSViewAbstract::JsHueRotate(const JSCallbackInfo& info) 7224 { 7225 std::optional<float> degree; 7226 JSRef<JSVal> arg = info[0]; 7227 if (arg->IsString()) { 7228 degree = static_cast<float>(StringUtils::StringToDegree(arg->ToString())); 7229 } else if (arg->IsNumber()) { 7230 degree = static_cast<float>(arg->ToNumber<int32_t>()); 7231 } else { 7232 ViewAbstractModel::GetInstance()->SetHueRotate(0.0); 7233 return; 7234 } 7235 float deg = 0.0f; 7236 if (degree) { 7237 deg = degree.value(); 7238 degree.reset(); 7239 } 7240 deg = std::fmod(deg, ROUND_UNIT); 7241 if (deg < 0.0f) { 7242 deg += ROUND_UNIT; 7243 } 7244 ViewAbstractModel::GetInstance()->SetHueRotate(deg); 7245 } 7246 JsClip(const JSCallbackInfo & info)7247 void JSViewAbstract::JsClip(const JSCallbackInfo& info) 7248 { 7249 JSRef<JSVal> arg = info[0]; 7250 if (arg->IsUndefined()) { 7251 ViewAbstractModel::GetInstance()->SetClipEdge(false); 7252 return; 7253 } 7254 if (arg->IsObject()) { 7255 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>(); 7256 if (clipShape == nullptr) { 7257 return; 7258 } 7259 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape()); 7260 } else if (arg->IsBoolean()) { 7261 ViewAbstractModel::GetInstance()->SetClipEdge(arg->ToBoolean()); 7262 } 7263 } 7264 JsClipShape(const JSCallbackInfo & info)7265 void JSViewAbstract::JsClipShape(const JSCallbackInfo& info) 7266 { 7267 if (info[0]->IsObject()) { 7268 JSShapeAbstract* clipShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>(); 7269 if (clipShape == nullptr) { 7270 return; 7271 } 7272 ViewAbstractModel::GetInstance()->SetClipShape(clipShape->GetBasicShape()); 7273 } 7274 } 7275 JsMask(const JSCallbackInfo & info)7276 void JSViewAbstract::JsMask(const JSCallbackInfo& info) 7277 { 7278 JSRef<JSVal> arg = info[0]; 7279 if (!arg->IsObject()) { 7280 ViewAbstractModel::GetInstance()->SetProgressMask(nullptr); 7281 return; 7282 } 7283 auto paramObject = JSRef<JSObject>::Cast(arg); 7284 JSRef<JSVal> typeParam = paramObject->GetProperty("type"); 7285 if (!typeParam->IsNull() && !typeParam->IsUndefined() && typeParam->IsString() && 7286 typeParam->ToString() == "ProgressMask") { 7287 auto progressMask = AceType::MakeRefPtr<NG::ProgressMaskProperty>(); 7288 JSRef<JSVal> jValue = paramObject->GetProperty("value"); 7289 auto value = jValue->IsNumber() ? jValue->ToNumber<float>() : 0.0f; 7290 if (value < 0.0f) { 7291 value = 0.0f; 7292 } 7293 progressMask->SetValue(value); 7294 JSRef<JSVal> jTotal = paramObject->GetProperty("total"); 7295 auto total = jTotal->IsNumber() ? jTotal->ToNumber<float>() : DEFAULT_PROGRESS_TOTAL; 7296 if (total < 0.0f) { 7297 total = DEFAULT_PROGRESS_TOTAL; 7298 } 7299 progressMask->SetMaxValue(total); 7300 JSRef<JSVal> jColor = paramObject->GetProperty("color"); 7301 Color colorVal; 7302 if (ParseJsColor(jColor, colorVal)) { 7303 progressMask->SetColor(colorVal); 7304 } else { 7305 RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>(); 7306 progressMask->SetColor(theme->GetMaskColor()); 7307 } 7308 JSRef<JSVal> jEnableBreathe = paramObject->GetProperty("breathe"); 7309 if (jEnableBreathe->IsBoolean()) { 7310 progressMask->SetEnableBreathe(jEnableBreathe->ToBoolean()); 7311 } 7312 ViewAbstractModel::GetInstance()->SetProgressMask(progressMask); 7313 } else { 7314 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(arg)->Unwrap<JSShapeAbstract>(); 7315 if (maskShape == nullptr) { 7316 return; 7317 }; 7318 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape()); 7319 } 7320 } 7321 JsMaskShape(const JSCallbackInfo & info)7322 void JSViewAbstract::JsMaskShape(const JSCallbackInfo& info) 7323 { 7324 if (!info[0]->IsObject()) { 7325 return; 7326 } 7327 7328 JSShapeAbstract* maskShape = JSRef<JSObject>::Cast(info[0])->Unwrap<JSShapeAbstract>(); 7329 if (maskShape == nullptr) { 7330 return; 7331 }; 7332 ViewAbstractModel::GetInstance()->SetMask(maskShape->GetBasicShape()); 7333 } 7334 JsFocusable(const JSCallbackInfo & info)7335 void JSViewAbstract::JsFocusable(const JSCallbackInfo& info) 7336 { 7337 if (!info[0]->IsBoolean()) { 7338 return; 7339 } 7340 ViewAbstractModel::GetInstance()->SetFocusable(info[0]->ToBoolean()); 7341 } 7342 JsTabStop(const JSCallbackInfo & info)7343 void JSViewAbstract::JsTabStop(const JSCallbackInfo& info) 7344 { 7345 if (!info[0]->IsBoolean()) { 7346 ViewAbstractModel::GetInstance()->SetTabStop(false); 7347 return; 7348 } 7349 ViewAbstractModel::GetInstance()->SetTabStop(info[0]->ToBoolean()); 7350 } 7351 JsFocusBox(const JSCallbackInfo & info)7352 void JSViewAbstract::JsFocusBox(const JSCallbackInfo& info) 7353 { 7354 if (!info[0]->IsObject() || info.Length() != 1) { 7355 return; 7356 } 7357 auto obj = JSRef<JSObject>::Cast(info[0]); 7358 NG::FocusBoxStyle style; 7359 7360 CalcDimension margin; 7361 if (ParseLengthMetricsToDimension(obj->GetProperty("margin"), margin)) { 7362 style.margin = margin; 7363 } 7364 CalcDimension strokeWidth; 7365 if (ParseLengthMetricsToPositiveDimension(obj->GetProperty("strokeWidth"), strokeWidth)) { 7366 style.strokeWidth = strokeWidth; 7367 } 7368 Color strokeColor; 7369 if (ParseColorMetricsToColor(obj->GetProperty("strokeColor"), strokeColor)) { 7370 style.strokeColor = strokeColor; 7371 } 7372 7373 ViewAbstractModel::GetInstance()->SetFocusBoxStyle(style); 7374 } 7375 JsOnFocusMove(const JSCallbackInfo & args)7376 void JSViewAbstract::JsOnFocusMove(const JSCallbackInfo& args) 7377 { 7378 JSRef<JSVal> arg = args[0]; 7379 if (arg->IsFunction()) { 7380 RefPtr<JsFocusFunction> jsOnFocusMove = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg)); 7381 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7382 auto onFocusMove = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocusMove), node = frameNode]( 7383 int info) { 7384 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7385 ACE_SCORING_EVENT("onFocusMove"); 7386 PipelineContext::SetCallBackNode(node); 7387 func->Execute(info); 7388 }; 7389 ViewAbstractModel::GetInstance()->SetOnFocusMove(std::move(onFocusMove)); 7390 } 7391 } 7392 JsOnKeyEvent(const JSCallbackInfo & args)7393 void JSViewAbstract::JsOnKeyEvent(const JSCallbackInfo& args) 7394 { 7395 JSRef<JSVal> arg = args[0]; 7396 if (arg->IsUndefined() && IsDisableEventVersion()) { 7397 ViewAbstractModel::GetInstance()->DisableOnKeyEvent(); 7398 return; 7399 } 7400 if (!arg->IsFunction()) { 7401 return; 7402 } 7403 RefPtr<JsKeyFunction> JsOnKeyEvent = AceType::MakeRefPtr<JsKeyFunction>(JSRef<JSFunc>::Cast(arg)); 7404 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7405 auto onKeyEvent = [execCtx = args.GetExecutionContext(), func = std::move(JsOnKeyEvent), node = frameNode]( 7406 KeyEventInfo& info) -> bool { 7407 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false); 7408 ACE_SCORING_EVENT("onKey"); 7409 PipelineContext::SetCallBackNode(node); 7410 auto ret = func->ExecuteWithValue(info); 7411 return ret->IsBoolean() ? ret->ToBoolean() : false; 7412 }; 7413 ViewAbstractModel::GetInstance()->SetOnKeyEvent(std::move(onKeyEvent)); 7414 } 7415 JsOnFocus(const JSCallbackInfo & args)7416 void JSViewAbstract::JsOnFocus(const JSCallbackInfo& args) 7417 { 7418 JSRef<JSVal> arg = args[0]; 7419 if (arg->IsUndefined() && IsDisableEventVersion()) { 7420 ViewAbstractModel::GetInstance()->DisableOnFocus(); 7421 return; 7422 } 7423 if (!arg->IsFunction()) { 7424 return; 7425 } 7426 RefPtr<JsFocusFunction> jsOnFocus = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg)); 7427 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7428 auto onFocus = [execCtx = args.GetExecutionContext(), func = std::move(jsOnFocus), node = frameNode]() { 7429 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7430 ACE_SCORING_EVENT("onFocus"); 7431 PipelineContext::SetCallBackNode(node); 7432 func->Execute(); 7433 }; 7434 7435 ViewAbstractModel::GetInstance()->SetOnFocus(std::move(onFocus)); 7436 } 7437 JsOnBlur(const JSCallbackInfo & args)7438 void JSViewAbstract::JsOnBlur(const JSCallbackInfo& args) 7439 { 7440 JSRef<JSVal> arg = args[0]; 7441 if (arg->IsUndefined() && IsDisableEventVersion()) { 7442 ViewAbstractModel::GetInstance()->DisableOnBlur(); 7443 return; 7444 } 7445 if (!arg->IsFunction()) { 7446 return; 7447 } 7448 RefPtr<JsFocusFunction> jsOnBlur = AceType::MakeRefPtr<JsFocusFunction>(JSRef<JSFunc>::Cast(arg)); 7449 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7450 auto onBlur = [execCtx = args.GetExecutionContext(), func = std::move(jsOnBlur), node = frameNode]() { 7451 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7452 ACE_SCORING_EVENT("onBlur"); 7453 PipelineContext::SetCallBackNode(node); 7454 func->Execute(); 7455 }; 7456 7457 ViewAbstractModel::GetInstance()->SetOnBlur(std::move(onBlur)); 7458 } 7459 JsTabIndex(const JSCallbackInfo & info)7460 void JSViewAbstract::JsTabIndex(const JSCallbackInfo& info) 7461 { 7462 JSRef<JSVal> arg = info[0]; 7463 if (!arg->IsNumber()) { 7464 return; 7465 } 7466 ViewAbstractModel::GetInstance()->SetTabIndex(arg->ToNumber<int32_t>()); 7467 } 7468 JsFocusOnTouch(const JSCallbackInfo & info)7469 void JSViewAbstract::JsFocusOnTouch(const JSCallbackInfo& info) 7470 { 7471 JSRef<JSVal> arg = info[0]; 7472 if (!arg->IsBoolean()) { 7473 return; 7474 } 7475 auto isFocusOnTouch = arg->ToBoolean(); 7476 ViewAbstractModel::GetInstance()->SetFocusOnTouch(isFocusOnTouch); 7477 } 7478 JsDefaultFocus(const JSCallbackInfo & info)7479 void JSViewAbstract::JsDefaultFocus(const JSCallbackInfo& info) 7480 { 7481 JSRef<JSVal> arg = info[0]; 7482 if (!arg->IsBoolean()) { 7483 return; 7484 } 7485 auto isDefaultFocus = arg->ToBoolean(); 7486 ViewAbstractModel::GetInstance()->SetDefaultFocus(isDefaultFocus); 7487 } 7488 JsGroupDefaultFocus(const JSCallbackInfo & info)7489 void JSViewAbstract::JsGroupDefaultFocus(const JSCallbackInfo& info) 7490 { 7491 JSRef<JSVal> arg = info[0]; 7492 if (!arg->IsBoolean()) { 7493 return; 7494 } 7495 auto isGroupDefaultFocus = arg->ToBoolean(); 7496 ViewAbstractModel::GetInstance()->SetGroupDefaultFocus(isGroupDefaultFocus); 7497 } 7498 JsKey(const std::string & key)7499 void JSViewAbstract::JsKey(const std::string& key) 7500 { 7501 ViewAbstractModel::GetInstance()->SetInspectorId(key); 7502 } 7503 JsId(const JSCallbackInfo & info)7504 void JSViewAbstract::JsId(const JSCallbackInfo& info) 7505 { 7506 JSRef<JSVal> arg = info[0]; 7507 if (!arg->IsString() || arg->IsNull() || arg->IsUndefined()) { 7508 return; 7509 } 7510 std::string id = arg->ToString(); 7511 if (id.empty()) { 7512 return; 7513 } 7514 JsKey(id); 7515 } 7516 JsRestoreId(int32_t restoreId)7517 void JSViewAbstract::JsRestoreId(int32_t restoreId) 7518 { 7519 ViewAbstractModel::GetInstance()->SetRestoreId(restoreId); 7520 } 7521 JsDebugLine(const JSCallbackInfo & info)7522 void JSViewAbstract::JsDebugLine(const JSCallbackInfo& info) 7523 { 7524 std::string debugLine; 7525 auto length = info.Length(); 7526 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING }; 7527 7528 if (length == 1) { // deprecated version of debug line 7529 auto jsVal = info[0]; 7530 if (!CheckJSCallbackInfo("JsDebugLine", jsVal, checkList)) { 7531 return; 7532 } 7533 debugLine = jsVal->ToString(); 7534 } else if (length == 2) { // debug line with extra package name 7535 auto line = info[0]; 7536 auto packageName = info[1]; 7537 if (!CheckJSCallbackInfo("JsDebugLine", line, checkList) || 7538 !CheckJSCallbackInfo("JsDebugLine", packageName, checkList)) { 7539 return; 7540 } 7541 auto json = JsonUtil::Create(true); 7542 json->Put(DEBUG_LINE_INFO_LINE, line->ToString().c_str()); 7543 json->Put(DEBUG_LINE_INFO_PACKAGE_NAME, packageName->ToString().c_str()); 7544 debugLine = json->ToString(); 7545 } 7546 7547 ViewAbstractModel::GetInstance()->SetDebugLine(debugLine); 7548 } 7549 JsOpacityPassThrough(const JSCallbackInfo & info)7550 void JSViewAbstract::JsOpacityPassThrough(const JSCallbackInfo& info) 7551 { 7552 double opacity = 1.0; 7553 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 7554 if (ParseJsDouble(info[0], opacity)) { 7555 opacity = std::clamp(opacity, 0.0, 1.0); 7556 } 7557 } else { 7558 if (!ParseJsDouble(info[0], opacity)) { 7559 return; 7560 } 7561 if ((LessNotEqual(opacity, 0.0)) || opacity > 1) { 7562 opacity = 1.0; 7563 } 7564 } 7565 7566 ViewAbstractModel::GetInstance()->SetOpacity(opacity, true); 7567 } 7568 JsTransitionPassThrough(const JSCallbackInfo & info)7569 void JSViewAbstract::JsTransitionPassThrough(const JSCallbackInfo& info) 7570 { 7571 if (info.Length() == 0) { 7572 ViewAbstractModel::GetInstance()->SetTransition( 7573 NG::TransitionOptions::GetDefaultTransition(TransitionType::ALL)); 7574 return; 7575 } 7576 if (!info[0]->IsObject()) { 7577 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 7578 ViewAbstractModel::GetInstance()->CleanTransition(); 7579 ViewAbstractModel::GetInstance()->SetChainedTransition(nullptr, nullptr); 7580 } 7581 return; 7582 } 7583 auto obj = JSRef<JSObject>::Cast(info[0]); 7584 if (!obj->GetProperty("successor_")->IsUndefined()) { 7585 auto chainedEffect = ParseChainedTransition(obj, info.GetExecutionContext()); 7586 std::function<void(bool)> finishCallback; 7587 if (info.Length() > 1 && info[1]->IsFunction()) { 7588 finishCallback = ParseTransitionCallback(JSRef<JSFunc>::Cast(info[1]), info.GetExecutionContext()); 7589 } 7590 ViewAbstractModel::GetInstance()->SetChainedTransition(chainedEffect, std::move(finishCallback)); 7591 return; 7592 } 7593 auto options = ParseJsTransition(obj); 7594 ViewAbstractModel::GetInstance()->SetTransition(options, true); 7595 } 7596 JsAccessibilityGroup(const JSCallbackInfo & info)7597 void JSViewAbstract::JsAccessibilityGroup(const JSCallbackInfo& info) 7598 { 7599 bool isGroup = false; 7600 if (info[0]->IsBoolean()) { 7601 isGroup = info[0]->ToBoolean(); 7602 } 7603 ViewAbstractModel::GetInstance()->SetAccessibilityGroup(isGroup); 7604 7605 if (info.Length() > 1 && info[1]->IsObject()) { 7606 auto obj = JSRef<JSObject>::Cast(info[1]); 7607 7608 auto preferAccessibilityTextObj = obj->GetProperty("accessibilityPreferred"); 7609 auto preferAccessibilityText = preferAccessibilityTextObj->IsBoolean() ? preferAccessibilityTextObj->ToBoolean() : false; 7610 ViewAbstractModel::GetInstance()->SetAccessibilityTextPreferred(preferAccessibilityText); 7611 } 7612 } 7613 JsAccessibilityText(const JSCallbackInfo & info)7614 void JSViewAbstract::JsAccessibilityText(const JSCallbackInfo& info) 7615 { 7616 const JSRef<JSVal>& jsValue = info[0]; 7617 std::string text; 7618 if (!ParseJsString(jsValue, text)) { 7619 return; 7620 } 7621 ViewAbstractModel::GetInstance()->SetAccessibilityText(text); 7622 } 7623 JsAccessibilityTextHint(const std::string & text)7624 void JSViewAbstract::JsAccessibilityTextHint(const std::string& text) 7625 { 7626 ViewAbstractModel::GetInstance()->SetAccessibilityTextHint(text); 7627 } 7628 JsAccessibilityDescription(const JSCallbackInfo & info)7629 void JSViewAbstract::JsAccessibilityDescription(const JSCallbackInfo& info) 7630 { 7631 const JSRef<JSVal>& jsValue = info[0]; 7632 std::string description; 7633 if (!ParseJsString(jsValue, description)) { 7634 return; 7635 } 7636 std::pair<bool, std::string> autoEventPair(false, ""); 7637 std::pair<bool, std::string> descriptionPair(false, ""); 7638 ParseAccessibilityDescriptionJson(description, autoEventPair, descriptionPair); 7639 if (descriptionPair.first) { 7640 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(descriptionPair.second); 7641 } else { 7642 ViewAbstractModel::GetInstance()->SetAccessibilityDescription(description); 7643 } 7644 if (autoEventPair.first) { 7645 ViewAbstractModel::GetInstance()->SetAutoEventParam(autoEventPair.second); 7646 } 7647 } 7648 ParseAccessibilityDescriptionJson(const std::string & description,std::pair<bool,std::string> & autoEventPair,std::pair<bool,std::string> & descriptionPair)7649 void JSViewAbstract::ParseAccessibilityDescriptionJson(const std::string& description, 7650 std::pair<bool, std::string>& autoEventPair, std::pair<bool, std::string>& descriptionPair) 7651 { 7652 if (description.empty()) { 7653 return; 7654 } 7655 if (!StartWith(description, "{") || !EndWith(description, "}")) { 7656 return; 7657 } 7658 auto jsonObj = JsonUtil::ParseJsonString(description); 7659 if (!jsonObj || !jsonObj->IsValid() || !jsonObj->IsObject()) { 7660 return; 7661 } 7662 if (jsonObj->Contains("$autoEventParam")) { 7663 auto param = jsonObj->GetValue("$autoEventParam"); 7664 if (param) { 7665 autoEventPair = std::make_pair(true, param->ToString()); 7666 } 7667 } 7668 if (jsonObj->Contains("$accessibilityDescription")) { 7669 descriptionPair = std::make_pair(true, jsonObj->GetString("$accessibilityDescription")); 7670 } else if (jsonObj->Contains("$autoEventParam")) { 7671 descriptionPair = std::make_pair(true, ""); 7672 } 7673 } 7674 JsAccessibilityImportance(const std::string & importance)7675 void JSViewAbstract::JsAccessibilityImportance(const std::string& importance) 7676 { 7677 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(importance); 7678 } 7679 JsAccessibilityLevel(const std::string & level)7680 void JSViewAbstract::JsAccessibilityLevel(const std::string& level) 7681 { 7682 ViewAbstractModel::GetInstance()->SetAccessibilityImportance(level); 7683 } 7684 JsAccessibilityVirtualNode(const JSCallbackInfo & info)7685 void JSViewAbstract::JsAccessibilityVirtualNode(const JSCallbackInfo& info) 7686 { 7687 // parse builder 7688 if (!info[0]->IsObject()) { 7689 return; 7690 } 7691 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]); 7692 auto builder = obj->GetProperty("builder"); 7693 if (builder->IsFunction()) { 7694 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 7695 CHECK_NULL_VOID(builderFunc); 7696 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc)]() { 7697 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7698 ACE_SCORING_EVENT("AccessibilityVirtualNode"); 7699 func->Execute(); 7700 }; 7701 NG::ViewAbstractModelNG::GetInstance()->SetAccessibilityVirtualNode(std::move(buildFunc)); 7702 } 7703 } 7704 JsAccessibilitySelected(const JSCallbackInfo & info)7705 void JSViewAbstract::JsAccessibilitySelected(const JSCallbackInfo& info) 7706 { 7707 bool selected = false; 7708 bool resetValue = false; 7709 JSRef<JSVal> arg = info[0]; 7710 if (arg->IsUndefined()) { 7711 resetValue = true; 7712 } else if (arg->IsBoolean()) { 7713 selected = arg->ToBoolean(); 7714 } else { 7715 return; 7716 } 7717 7718 ViewAbstractModel::GetInstance()->SetAccessibilitySelected(selected, resetValue); 7719 } 7720 JsAccessibilityChecked(const JSCallbackInfo & info)7721 void JSViewAbstract::JsAccessibilityChecked(const JSCallbackInfo& info) 7722 { 7723 bool checked = false; 7724 bool resetValue = false; 7725 JSRef<JSVal> arg = info[0]; 7726 if (arg->IsUndefined()) { 7727 resetValue = true; 7728 } else if (arg->IsBoolean()) { 7729 checked = arg->ToBoolean(); 7730 } else { 7731 return; 7732 } 7733 7734 ViewAbstractModel::GetInstance()->SetAccessibilityChecked(checked, resetValue); 7735 } 7736 JsBackground(const JSCallbackInfo & info)7737 void JSViewAbstract::JsBackground(const JSCallbackInfo& info) 7738 { 7739 // Check the parameters 7740 if (info.Length() <= 0 || !info[0]->IsObject()) { 7741 return; 7742 } 7743 JSRef<JSObject> backgroundObj = JSRef<JSObject>::Cast(info[0]); 7744 auto builder = backgroundObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER)); 7745 if (!builder->IsFunction()) { 7746 return; 7747 } 7748 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 7749 CHECK_NULL_VOID(builderFunc); 7750 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7751 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() { 7752 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7753 ACE_SCORING_EVENT("BindBackground"); 7754 PipelineContext::SetCallBackNode(node); 7755 func->Execute(); 7756 }; 7757 Alignment alignment = Alignment::CENTER; 7758 if (info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsObject()) { 7759 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[1]); 7760 auto align = object->GetProperty(static_cast<int32_t>(ArkUIIndex::ALIGN)); 7761 auto value = align->ToNumber<int32_t>(); 7762 alignment = ParseAlignment(value); 7763 } 7764 ViewAbstractModel::GetInstance()->BindBackground(std::move(buildFunc), alignment); 7765 } 7766 JsBindContextMenu(const JSCallbackInfo & info)7767 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info) 7768 { 7769 NG::MenuParam menuParam; 7770 // Check the parameters 7771 if (info.Length() <= 0) { 7772 return; 7773 } 7774 size_t builderIndex = ParseBindContextMenuShow(info, menuParam); 7775 if (!info[builderIndex]->IsObject()) { 7776 return; 7777 } 7778 7779 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]); 7780 auto builder = menuObj->GetProperty("builder"); 7781 if (!builder->IsFunction()) { 7782 return; 7783 } 7784 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 7785 CHECK_NULL_VOID(builderFunc); 7786 7787 ResponseType responseType = ResponseType::LONG_PRESS; 7788 if (!info[0]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[1]->IsNumber()) { 7789 auto response = info[1]->ToNumber<int32_t>(); 7790 responseType = static_cast<ResponseType>(response); 7791 } 7792 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7793 std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), 7794 node = frameNode]() { 7795 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7796 ACE_SCORING_EVENT("BuildContextMenu"); 7797 PipelineContext::SetCallBackNode(node); 7798 func->Execute(); 7799 }; 7800 7801 menuParam.previewMode = MenuPreviewMode::NONE; 7802 std::function<void()> previewBuildFunc = nullptr; 7803 if (info.Length() >= PARAMETER_LENGTH_THIRD && info[2]->IsObject()) { 7804 ParseBindContentOptionParam(info, info[2], menuParam, previewBuildFunc); 7805 } 7806 7807 if (responseType != ResponseType::LONG_PRESS) { 7808 menuParam.previewMode = MenuPreviewMode::NONE; 7809 menuParam.isShowHoverImage = false; 7810 menuParam.menuBindType = MenuBindingType::RIGHT_CLICK; 7811 } 7812 menuParam.type = NG::MenuType::CONTEXT_MENU; 7813 ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc); 7814 ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam); 7815 } 7816 ParseBindContentCoverIsShow(const JSCallbackInfo & info)7817 bool ParseBindContentCoverIsShow(const JSCallbackInfo& info) 7818 { 7819 bool isShow = false; 7820 if (info[0]->IsBoolean()) { 7821 isShow = info[0]->ToBoolean(); 7822 } else if (info[0]->IsObject()) { 7823 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]); 7824 auto isShowObj = callbackObj->GetProperty("value"); 7825 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false; 7826 } 7827 TAG_LOGD(AceLogTag::ACE_SHEET, "ContentCover get isShow is: %{public}d", isShow); 7828 return isShow; 7829 } 7830 JsBindContentCover(const JSCallbackInfo & info)7831 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info) 7832 { 7833 // parse isShow 7834 bool isShow = ParseBindContentCoverIsShow(info); 7835 DoubleBindCallback callback = nullptr; 7836 if (info[0]->IsObject()) { 7837 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]); 7838 callback = ParseDoubleBindCallback(info, callbackObj); 7839 } 7840 7841 // parse builder 7842 if (!info[1]->IsObject()) { 7843 return; 7844 } 7845 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]); 7846 auto builder = obj->GetProperty("builder"); 7847 if (!builder->IsFunction()) { 7848 return; 7849 } 7850 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 7851 CHECK_NULL_VOID(builderFunc); 7852 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7853 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() { 7854 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7855 ACE_SCORING_EVENT("BindContentCover"); 7856 PipelineContext::SetCallBackNode(node); 7857 func->Execute(); 7858 }; 7859 7860 // parse ModalTransition 7861 NG::ModalStyle modalStyle; 7862 modalStyle.modalTransition = NG::ModalTransition::DEFAULT; 7863 std::function<void()> onShowCallback; 7864 std::function<void()> onDismissCallback; 7865 std::function<void()> onWillShowCallback; 7866 std::function<void()> onWillDismissCallback; 7867 NG::ContentCoverParam contentCoverParam; 7868 std::function<void(const int32_t&)> onWillDismissFunc; 7869 if (info.Length() == 3) { 7870 if (info[2]->IsObject()) { 7871 ParseOverlayCallback(info[2], onShowCallback, onDismissCallback, onWillShowCallback, /* 2:args index */ 7872 onWillDismissCallback, onWillDismissFunc); 7873 ParseModalStyle(info[2], modalStyle); 7874 contentCoverParam.onWillDismiss = std::move(onWillDismissFunc); 7875 ParseModalTransitonEffect(info[2], contentCoverParam, info.GetExecutionContext()); /* 2:args index */ 7876 } else if (info[2]->IsNumber()) { 7877 auto transitionNumber = info[2]->ToNumber<int32_t>(); 7878 if (transitionNumber >= 0 && transitionNumber <= 2) { 7879 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber); 7880 } 7881 } 7882 } 7883 ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle, 7884 std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback), 7885 std::move(onWillDismissCallback), contentCoverParam); 7886 } 7887 ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)7888 void JSViewAbstract::ParseModalTransitonEffect( 7889 const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context) 7890 { 7891 auto transitionEffectValue = paramObj->GetProperty("transition"); 7892 if (transitionEffectValue->IsObject()) { 7893 JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue); 7894 contentCoverParam.transitionEffect = ParseChainedTransition(obj, context); 7895 } 7896 } 7897 ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)7898 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle) 7899 { 7900 auto modalTransition = paramObj->GetProperty("modalTransition"); 7901 auto backgroundColor = paramObj->GetProperty("backgroundColor"); 7902 if (modalTransition->IsNumber()) { 7903 auto transitionNumber = modalTransition->ToNumber<int32_t>(); 7904 if (transitionNumber >= 0 && transitionNumber <= 2) { 7905 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber); 7906 } 7907 } 7908 Color color; 7909 if (ParseJsColor(backgroundColor, color)) { 7910 modalStyle.backgroundColor = color; 7911 } 7912 } 7913 ParseSheetIsShow(const JSCallbackInfo & info,bool & isShow,std::function<void (const std::string &)> & callback)7914 void JSViewAbstract::ParseSheetIsShow( 7915 const JSCallbackInfo& info, bool& isShow, std::function<void(const std::string&)>& callback) 7916 { 7917 if (info[0]->IsBoolean()) { 7918 isShow = info[0]->ToBoolean(); 7919 } else if (info[0]->IsObject()) { 7920 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]); 7921 callback = ParseDoubleBindCallback(info, callbackObj); 7922 auto isShowObj = callbackObj->GetProperty("value"); 7923 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false; 7924 } 7925 TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet get isShow is: %{public}d", isShow); 7926 } 7927 JsBindSheet(const JSCallbackInfo & info)7928 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info) 7929 { 7930 // parse isShow and builder 7931 bool isShow = false; 7932 DoubleBindCallback callback = nullptr; 7933 ParseSheetIsShow(info, isShow, callback); 7934 if (!info[1]->IsObject()) 7935 return; 7936 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]); 7937 auto builder = obj->GetProperty("builder"); 7938 if (!builder->IsFunction()) 7939 return; 7940 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 7941 CHECK_NULL_VOID(builderFunc); 7942 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 7943 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() { 7944 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 7945 ACE_SCORING_EVENT("BindSheet"); 7946 PipelineContext::SetCallBackNode(node); 7947 func->Execute(); 7948 }; 7949 // parse SheetStyle and callbacks 7950 NG::SheetStyle sheetStyle; 7951 sheetStyle.sheetMode = NG::SheetMode::LARGE; 7952 sheetStyle.showDragBar = true; 7953 sheetStyle.showCloseIcon = true; 7954 sheetStyle.showInPage = false; 7955 std::function<void()> onAppearCallback; 7956 std::function<void()> onDisappearCallback; 7957 std::function<void()> onWillAppearCallback; 7958 std::function<void()> onWillDisappearCallback ; 7959 std::function<void()> shouldDismissFunc; 7960 std::function<void(const int32_t)> onWillDismissCallback; 7961 std::function<void(const float)> onHeightDidChangeCallback; 7962 std::function<void(const float)> onDetentsDidChangeCallback; 7963 std::function<void(const float)> onWidthDidChangeCallback; 7964 std::function<void(const float)> onTypeDidChangeCallback; 7965 std::function<void()> titleBuilderFunction; 7966 std::function<void()> sheetSpringBackFunc; 7967 if (info.Length() == PARAMETER_LENGTH_THIRD && info[SECOND_INDEX]->IsObject()) { 7968 ParseSheetCallback(info[SECOND_INDEX], onAppearCallback, onDisappearCallback, shouldDismissFunc, 7969 onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback, 7970 onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc); 7971 ParseSheetStyle(info[2], sheetStyle); 7972 ParseSheetTitle(info[2], sheetStyle, titleBuilderFunction); 7973 } 7974 ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc), 7975 std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback), 7976 std::move(shouldDismissFunc), std::move(onWillDismissCallback), std::move(onWillAppearCallback), 7977 std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback), 7978 std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc)); 7979 } 7980 ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)7981 void JSViewAbstract::ParseSheetStyle( 7982 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate) 7983 { 7984 auto height = paramObj->GetProperty("height"); 7985 auto showDragBar = paramObj->GetProperty("dragBar"); 7986 auto backgroundColor = paramObj->GetProperty("backgroundColor"); 7987 auto maskColor = paramObj->GetProperty("maskColor"); 7988 auto sheetDetents = paramObj->GetProperty("detents"); 7989 auto backgroundBlurStyle = paramObj->GetProperty("blurStyle"); 7990 auto showCloseIcon = paramObj->GetProperty("showClose"); 7991 auto type = paramObj->GetProperty("preferType"); 7992 auto interactive = paramObj->GetProperty("enableOutsideInteractive"); 7993 auto showMode = paramObj->GetProperty("mode"); 7994 auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode"); 7995 auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode"); 7996 auto uiContextObj = paramObj->GetProperty("uiContext"); 7997 if (uiContextObj->IsObject()) { 7998 JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj); 7999 auto prop = obj->GetProperty("instanceId_"); 8000 if (prop->IsNumber()) { 8001 sheetStyle.instanceId = prop->ToNumber<int32_t>(); 8002 } 8003 } 8004 NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY; 8005 if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) { 8006 sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED); 8007 } 8008 8009 std::vector<NG::SheetHeight> detents; 8010 if (ParseSheetDetents(sheetDetents, detents)) { 8011 sheetStyle.detents = detents; 8012 } 8013 BlurStyleOption styleOption; 8014 if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) { 8015 sheetStyle.backgroundBlurStyle = styleOption; 8016 } 8017 bool showClose = true; 8018 if (ParseJsBool(showCloseIcon, showClose)) { 8019 sheetStyle.showCloseIcon = showClose; 8020 } else if (!isPartialUpdate) { 8021 sheetStyle.showCloseIcon = true; 8022 } 8023 8024 bool isInteractive = false; 8025 if (ParseJsBool(interactive, isInteractive)) { 8026 sheetStyle.interactive = isInteractive; 8027 } 8028 8029 if (showDragBar->IsBoolean()) { 8030 sheetStyle.showDragBar = showDragBar->ToBoolean(); 8031 } else if (isPartialUpdate) { 8032 sheetStyle.showDragBar.reset(); 8033 } else { 8034 sheetStyle.showDragBar = true; 8035 } 8036 8037 if (type->IsNull() || type->IsUndefined()) { 8038 sheetStyle.sheetType.reset(); 8039 } else { 8040 if (type->IsNumber()) { 8041 auto sheetType = type->ToNumber<int32_t>(); 8042 if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) && 8043 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) { 8044 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType); 8045 } 8046 } 8047 } 8048 if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) { 8049 sheetStyle.scrollSizeMode.reset(); 8050 } else if (scrollSizeMode->IsNumber()) { 8051 auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>(); 8052 if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) && 8053 sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) { 8054 sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode); 8055 } 8056 } 8057 8058 if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) { 8059 sheetStyle.sheetKeyboardAvoidMode.reset(); 8060 } else if (keyboardAvoidMode->IsNumber()) { 8061 auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>(); 8062 if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) && 8063 sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) { 8064 sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode); 8065 } 8066 } 8067 8068 Color color; 8069 if (ParseJsColor(backgroundColor, color)) { 8070 sheetStyle.backgroundColor = color; 8071 } 8072 // parse maskColor 8073 Color parseMaskColor; 8074 if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) { 8075 sheetStyle.maskColor = std::move(parseMaskColor); 8076 } 8077 8078 // Parse border width 8079 auto borderWidthValue = paramObj->GetProperty("borderWidth"); 8080 NG::BorderWidthProperty borderWidth; 8081 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) { 8082 sheetStyle.borderWidth = borderWidth; 8083 // Parse border color 8084 auto colorValue = paramObj->GetProperty("borderColor"); 8085 NG::BorderColorProperty borderColor; 8086 if (ParseBorderColorProps(colorValue, borderColor)) { 8087 sheetStyle.borderColor = borderColor; 8088 } else { 8089 sheetStyle.borderColor = 8090 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK }); 8091 } 8092 // Parse border style 8093 auto styleValue = paramObj->GetProperty("borderStyle"); 8094 NG::BorderStyleProperty borderStyle; 8095 if (ParseBorderStyleProps(styleValue, borderStyle)) { 8096 sheetStyle.borderStyle = borderStyle; 8097 } else { 8098 sheetStyle.borderStyle = NG::BorderStyleProperty( 8099 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID }); 8100 } 8101 } 8102 if (isPartialUpdate) { 8103 auto colorValue = paramObj->GetProperty("borderColor"); 8104 NG::BorderColorProperty borderColor; 8105 if (ParseBorderColorProps(colorValue, borderColor)) { 8106 sheetStyle.borderColor = borderColor; 8107 } else { 8108 sheetStyle.borderColor.reset(); 8109 } 8110 auto styleValue = paramObj->GetProperty("borderStyle"); 8111 NG::BorderStyleProperty borderStyle; 8112 if (ParseBorderStyleProps(styleValue, borderStyle)) { 8113 sheetStyle.borderStyle = borderStyle; 8114 } else { 8115 sheetStyle.borderStyle.reset(); 8116 } 8117 } 8118 8119 // Parse shadow 8120 Shadow shadow; 8121 auto shadowValue = paramObj->GetProperty("shadow"); 8122 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) { 8123 sheetStyle.shadow = shadow; 8124 } 8125 8126 // Parse hoverMode 8127 auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode"); 8128 if (enableHoverModeValue->IsBoolean()) { 8129 sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean(); 8130 } 8131 auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea"); 8132 if (hoverModeAreaValue->IsNumber()) { 8133 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>(); 8134 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) { 8135 sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea]; 8136 } 8137 } 8138 8139 auto widthValue = paramObj->GetProperty("width"); 8140 CalcDimension width; 8141 if (ParseJsDimensionVpNG(widthValue, width, true)) { 8142 sheetStyle.width = width; 8143 } 8144 8145 CalcDimension sheetHeight; 8146 if (height->IsString()) { 8147 std::string heightStr = height->ToString(); 8148 // Remove all " ". 8149 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end()); 8150 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower); 8151 if (heightStr == SHEET_HEIGHT_MEDIUM) { 8152 sheetStyle.sheetMode = NG::SheetMode::MEDIUM; 8153 sheetStyle.height.reset(); 8154 return; 8155 } 8156 if (heightStr == SHEET_HEIGHT_LARGE) { 8157 sheetStyle.sheetMode = NG::SheetMode::LARGE; 8158 sheetStyle.height.reset(); 8159 return; 8160 } 8161 if (heightStr == SHEET_HEIGHT_FITCONTENT) { 8162 sheetStyle.sheetMode = NG::SheetMode::AUTO; 8163 sheetStyle.height.reset(); 8164 return; 8165 } 8166 if (heightStr.find("calc") != std::string::npos) { 8167 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC); 8168 } else { 8169 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0); 8170 } 8171 if (sheetHeight.Value() < 0) { 8172 sheetStyle.sheetMode = NG::SheetMode::LARGE; 8173 sheetStyle.height.reset(); 8174 return; 8175 } 8176 } 8177 if (!ParseJsDimensionVpNG(height, sheetHeight)) { 8178 if (isPartialUpdate) { 8179 sheetStyle.sheetMode.reset(); 8180 } else { 8181 sheetStyle.sheetMode = NG::SheetMode::LARGE; 8182 } 8183 sheetStyle.height.reset(); 8184 } else { 8185 sheetStyle.height = sheetHeight; 8186 sheetStyle.sheetMode.reset(); 8187 } 8188 } 8189 ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)8190 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents) 8191 { 8192 if (!args->IsArray()) { 8193 return false; 8194 } 8195 JSRef<JSArray> array = JSRef<JSArray>::Cast(args); 8196 NG::SheetHeight sheetDetent; 8197 for (size_t i = 0; i < array->Length(); i++) { 8198 ParseSheetDetentHeight(array->GetValueAt(i), sheetDetent); 8199 if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) { 8200 continue; 8201 } 8202 sheetDetents.emplace_back(sheetDetent); 8203 sheetDetent.height.reset(); 8204 sheetDetent.sheetMode.reset(); 8205 } 8206 return true; 8207 } 8208 ParseSheetDetentHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent)8209 void JSViewAbstract::ParseSheetDetentHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent) 8210 { 8211 CalcDimension sheetHeight; 8212 if (args->IsString()) { 8213 std::string heightStr = args->ToString(); 8214 // Remove all " ". 8215 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end()); 8216 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower); 8217 if (heightStr == SHEET_HEIGHT_MEDIUM) { 8218 detent.sheetMode = NG::SheetMode::MEDIUM; 8219 detent.height.reset(); 8220 return; 8221 } 8222 if (heightStr == SHEET_HEIGHT_LARGE) { 8223 detent.sheetMode = NG::SheetMode::LARGE; 8224 detent.height.reset(); 8225 return; 8226 } 8227 if (heightStr == SHEET_HEIGHT_FITCONTENT) { 8228 detent.sheetMode = NG::SheetMode::AUTO; 8229 detent.height.reset(); 8230 return; 8231 } 8232 if (heightStr.find("calc") != std::string::npos) { 8233 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC); 8234 } else { 8235 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0); 8236 } 8237 if (sheetHeight.Value() < 0) { 8238 detent.sheetMode = NG::SheetMode::LARGE; 8239 detent.height.reset(); 8240 return; 8241 } 8242 } 8243 if (!ParseJsDimensionVpNG(args, sheetHeight)) { 8244 detent.sheetMode = NG::SheetMode::LARGE; 8245 detent.height.reset(); 8246 } else { 8247 detent.height = sheetHeight; 8248 detent.sheetMode.reset(); 8249 } 8250 } 8251 ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)8252 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions) 8253 { 8254 if (args->IsNumber()) { 8255 auto sheetBlurStyle = args->ToNumber<int32_t>(); 8256 if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) && 8257 sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) { 8258 blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle); 8259 } else { 8260 return false; 8261 } 8262 } else { 8263 return false; 8264 } 8265 return true; 8266 } 8267 ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)8268 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel) 8269 { 8270 if (!args->IsNumber()) { 8271 return false; 8272 } 8273 auto sheetMode = args->ToNumber<int32_t>(); 8274 if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) && 8275 sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) { 8276 sheetLevel = static_cast<NG::SheetLevel>(sheetMode); 8277 return true; 8278 } 8279 return false; 8280 } 8281 ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)8282 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj, 8283 std::function<void(const float)>& callbackDidChange, const char* prop) 8284 { 8285 auto callBack = paramObj->GetProperty(prop); 8286 if (callBack->IsFunction()) { 8287 RefPtr<JsFunction> jsFunc = 8288 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack)); 8289 callbackDidChange = [func = std::move(jsFunc)](int32_t value) { 8290 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value)); 8291 func->ExecuteJS(1, ¶m); 8292 }; 8293 } 8294 } 8295 ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)8296 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj, 8297 std::function<void()>& lifeCycleCallBack, const char* prop) 8298 { 8299 auto callback = paramObj->GetProperty(prop); 8300 if (callback->IsFunction()) { 8301 RefPtr<JsFunction> jsFunc = 8302 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback)); 8303 lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); }; 8304 } 8305 } 8306 ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)8307 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj, 8308 std::function<void()>& sheetSpringBack, const char* prop) 8309 { 8310 auto sheetSpringBackCallback = paramObj->GetProperty(prop); 8311 if (sheetSpringBackCallback->IsFunction()) { 8312 RefPtr<JsFunction> jsFunc = 8313 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback)); 8314 sheetSpringBack = [func = std::move(jsFunc)]() { 8315 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New(); 8316 objectTemplate->SetInternalFieldCount(1); 8317 JSRef<JSObject> dismissObj = objectTemplate->NewInstance(); 8318 dismissObj->SetPropertyObject( 8319 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack)); 8320 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj); 8321 func->ExecuteJS(1, &newJSVal); 8322 }; 8323 } 8324 } 8325 ParseSheetCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & shouldDismiss,std::function<void (const int32_t info)> & onWillDismiss,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const float)> & onHeightDidChange,std::function<void (const float)> & onDetentsDidChange,std::function<void (const float)> & onWidthDidChange,std::function<void (const float)> & onTypeDidChange,std::function<void ()> & sheetSpringBack)8326 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear, 8327 std::function<void()>& onDisappear, std::function<void()>& shouldDismiss, 8328 std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear, 8329 std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange, 8330 std::function<void(const float)>& onDetentsDidChange, 8331 std::function<void(const float)>& onWidthDidChange, 8332 std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack) 8333 { 8334 auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss"); 8335 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss"); 8336 ParseLifeCycleCallback(paramObj, onAppear, "onAppear"); 8337 ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear"); 8338 ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear"); 8339 ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear"); 8340 if (shouldDismissFunc->IsFunction()) { 8341 RefPtr<JsFunction> jsFunc = 8342 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc)); 8343 shouldDismiss = [func = std::move(jsFunc)]() { 8344 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New(); 8345 objectTemplate->SetInternalFieldCount(1); 8346 JSRef<JSObject> dismissObj = objectTemplate->NewInstance(); 8347 dismissObj->SetPropertyObject( 8348 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet)); 8349 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj); 8350 func->ExecuteJS(1, &newJSVal); 8351 }; 8352 } 8353 if (onWillDismissFunc->IsFunction()) { 8354 RefPtr<JsFunction> jsFunc = 8355 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc)); 8356 onWillDismiss = [func = std::move(jsFunc)](const int32_t info) { 8357 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New(); 8358 objectTemplate->SetInternalFieldCount(1); 8359 JSRef<JSObject> dismissObj = objectTemplate->NewInstance(); 8360 dismissObj->SetPropertyObject( 8361 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet)); 8362 dismissObj->SetProperty<int32_t>("reason", info); 8363 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj); 8364 func->ExecuteJS(1, &newJSVal); 8365 }; 8366 } 8367 ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss"); 8368 ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange"); 8369 ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange"); 8370 ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange"); 8371 ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange"); 8372 } 8373 ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)8374 void JSViewAbstract::ParseSheetTitle( 8375 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction) 8376 { 8377 auto title = paramObj->GetProperty("title"); 8378 std::string mainTitle; 8379 std::string subtitle; 8380 if (title->IsFunction()) { 8381 sheetStyle.isTitleBuilder = true; 8382 auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title)); 8383 CHECK_NULL_VOID(titleBuilderFunc); 8384 titleBuilderFunction = [func = std::move(titleBuilderFunc)]() { 8385 ACE_SCORING_EVENT("BindSheet"); 8386 func->Execute(); 8387 }; 8388 } else if (title->IsObject()) { 8389 JSRef<JSObject> obj = JSRef<JSObject>::Cast(title); 8390 sheetStyle.isTitleBuilder = false; 8391 auto sheetTitle = obj->GetProperty("title"); 8392 auto sheetSubtitle = obj->GetProperty("subtitle"); 8393 if (ParseJsString(sheetTitle, mainTitle)) { 8394 sheetStyle.sheetTitle = mainTitle; 8395 } 8396 if (ParseJsString(sheetSubtitle, subtitle)) { 8397 sheetStyle.sheetSubtitle = subtitle; 8398 } 8399 } 8400 } 8401 JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)8402 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo) 8403 { 8404 ViewAbstractModel::GetInstance()->DismissSheet(); 8405 return JSValueRef::Undefined(runtimeCallInfo->GetVM()); 8406 } 8407 JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)8408 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo) 8409 { 8410 ViewAbstractModel::GetInstance()->DismissContentCover(); 8411 return JSValueRef::Undefined(runtimeCallInfo->GetVM()); 8412 } 8413 JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)8414 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo) 8415 { 8416 ViewAbstractModel::GetInstance()->SheetSpringBack(); 8417 return JSValueRef::Undefined(runtimeCallInfo->GetVM()); 8418 } 8419 ParseOverlayCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & onAppear,std::function<void ()> & onDisappear,std::function<void ()> & onWillAppear,std::function<void ()> & onWillDisappear,std::function<void (const int32_t & info)> & onWillDismiss)8420 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear, 8421 std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear, 8422 std::function<void(const int32_t& info)>& onWillDismiss) 8423 { 8424 auto showCallback = paramObj->GetProperty("onAppear"); 8425 auto dismissCallback = paramObj->GetProperty("onDisappear"); 8426 auto willShowCallback = paramObj->GetProperty("onWillAppear"); 8427 auto willDismissCallback = paramObj->GetProperty("onWillDisappear"); 8428 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss"); 8429 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 8430 if (showCallback->IsFunction()) { 8431 RefPtr<JsFunction> jsFunc = 8432 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback)); 8433 onAppear = [func = std::move(jsFunc), node = frameNode]() { 8434 PipelineContext::SetCallBackNode(node); 8435 func->Execute(); 8436 }; 8437 } 8438 if (dismissCallback->IsFunction()) { 8439 RefPtr<JsFunction> jsFunc = 8440 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback)); 8441 onDisappear = [func = std::move(jsFunc), node = frameNode]() { 8442 PipelineContext::SetCallBackNode(node); 8443 func->Execute(); 8444 }; 8445 } 8446 if (willShowCallback->IsFunction()) { 8447 RefPtr<JsFunction> jsFunc = 8448 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback)); 8449 onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); }; 8450 } 8451 if (willDismissCallback->IsFunction()) { 8452 RefPtr<JsFunction> jsFunc = 8453 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback)); 8454 onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); }; 8455 } 8456 if (onWillDismissFunc->IsFunction()) { 8457 RefPtr<JsFunction> jsFunc = 8458 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc)); 8459 onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) { 8460 ACE_SCORING_EVENT("contentCover.dismiss"); 8461 PipelineContext::SetCallBackNode(node); 8462 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New(); 8463 objectTemplate->SetInternalFieldCount(1); 8464 JSRef<JSObject> dismissObj = objectTemplate->NewInstance(); 8465 dismissObj->SetPropertyObject( 8466 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover)); 8467 dismissObj->SetProperty<int32_t>("reason", info); 8468 JSRef<JSVal> newJSVal = JSRef<JSObject>::Cast(dismissObj); 8469 func->ExecuteJS(1, &newJSVal); 8470 }; 8471 } 8472 } 8473 JSCreateAnimatableProperty(const JSCallbackInfo & info)8474 void JSViewAbstract::JSCreateAnimatableProperty(const JSCallbackInfo& info) 8475 { 8476 if (info.Length() < 3 || !info[0]->IsString()) { /* 3:args number */ 8477 return; 8478 } 8479 8480 JSRef<JSVal> callback = info[2]; /* 2:args index */ 8481 if (!callback->IsFunction()) { 8482 return; 8483 } 8484 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 8485 std::string propertyName = info[0]->ToString(); 8486 if (info[1]->IsNumber()) { 8487 float numValue = info[1]->ToNumber<float>(); 8488 std::function<void(float)> onCallbackEvent; 8489 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback)); 8490 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(), 8491 node = frameNode](const float val) { 8492 ContainerScope scope(id); 8493 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 8494 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(val)); 8495 PipelineContext::SetCallBackNode(node); 8496 func->ExecuteJS(1, &newJSVal); 8497 }; 8498 ViewAbstractModel::GetInstance()->CreateAnimatablePropertyFloat(propertyName, numValue, onCallbackEvent); 8499 } else if (info[1]->IsObject()) { 8500 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]); 8501 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl = 8502 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext()); 8503 RefPtr<CustomAnimatableArithmetic> animatableArithmetic = 8504 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl); 8505 std::function<void(const RefPtr<NG::CustomAnimatableArithmetic>&)> onCallbackEvent; 8506 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback)); 8507 onCallbackEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), id = Container::CurrentId(), 8508 node = frameNode](const RefPtr<NG::CustomAnimatableArithmetic>& value) { 8509 ContainerScope scope(id); 8510 RefPtr<JSAnimatableArithmetic> impl = AceType::DynamicCast<JSAnimatableArithmetic>(value); 8511 if (!impl) { 8512 return; 8513 } 8514 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 8515 auto newJSVal = JSRef<JSVal>(impl->GetObject()); 8516 PipelineContext::SetCallBackNode(node); 8517 func->ExecuteJS(1, &newJSVal); 8518 }; 8519 ViewAbstractModel::GetInstance()->CreateAnimatableArithmeticProperty( 8520 propertyName, animatableArithmetic, onCallbackEvent); 8521 } 8522 } 8523 JSUpdateAnimatableProperty(const JSCallbackInfo & info)8524 void JSViewAbstract::JSUpdateAnimatableProperty(const JSCallbackInfo& info) 8525 { 8526 if (info.Length() < 2 || !info[0]->IsString()) { /* 2:args number */ 8527 return; 8528 } 8529 8530 std::string propertyName = info[0]->ToString(); 8531 float numValue = 0.0; 8532 if (info[1]->IsNumber()) { 8533 numValue = info[1]->ToNumber<float>(); 8534 ViewAbstractModel::GetInstance()->UpdateAnimatablePropertyFloat(propertyName, numValue); 8535 } else if (info[1]->IsObject()) { 8536 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[1]); 8537 RefPtr<JSAnimatableArithmetic> animatableArithmeticImpl = 8538 AceType::MakeRefPtr<JSAnimatableArithmetic>(obj, info.GetExecutionContext()); 8539 RefPtr<CustomAnimatableArithmetic> animatableArithmetic = 8540 AceType::DynamicCast<CustomAnimatableArithmetic>(animatableArithmeticImpl); 8541 ViewAbstractModel::GetInstance()->UpdateAnimatableArithmeticProperty(propertyName, animatableArithmetic); 8542 } 8543 } 8544 JsExpandSafeArea(const JSCallbackInfo & info)8545 void JSViewAbstract::JsExpandSafeArea(const JSCallbackInfo& info) 8546 { 8547 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_ALL, .edges = NG::SAFE_AREA_EDGE_ALL }; 8548 if (info.Length() >= 1 && info[0]->IsArray()) { 8549 auto paramArray = JSRef<JSArray>::Cast(info[0]); 8550 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE; 8551 for (size_t i = 0; i < paramArray->Length(); ++i) { 8552 if (!paramArray->GetValueAt(i)->IsNumber() || 8553 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT) { 8554 safeAreaType = NG::SAFE_AREA_TYPE_ALL; 8555 break; 8556 } 8557 safeAreaType |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>()); 8558 } 8559 opts.type = safeAreaType; 8560 } 8561 if (info.Length() >= 2 && info[1]->IsArray()) { 8562 auto paramArray = JSRef<JSArray>::Cast(info[1]); 8563 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE; 8564 for (size_t i = 0; i < paramArray->Length(); ++i) { 8565 if (!paramArray->GetValueAt(i)->IsNumber() || 8566 paramArray->GetValueAt(i)->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) { 8567 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL; 8568 break; 8569 } 8570 safeAreaEdge |= (1 << paramArray->GetValueAt(i)->ToNumber<uint32_t>()); 8571 } 8572 opts.edges = safeAreaEdge; 8573 } 8574 8575 ViewAbstractModel::GetInstance()->UpdateSafeAreaExpandOpts(opts); 8576 } 8577 ParseJSLightSource(JSRef<JSObject> & lightSource)8578 void ParseJSLightSource(JSRef<JSObject>& lightSource) 8579 { 8580 if (lightSource->IsUndefined()) { 8581 return; 8582 } 8583 JSRef<JSVal> positionX = lightSource->GetProperty("positionX"); 8584 JSRef<JSVal> positionY = lightSource->GetProperty("positionY"); 8585 JSRef<JSVal> positionZ = lightSource->GetProperty("positionZ"); 8586 JSRef<JSVal> intensity = lightSource->GetProperty("intensity"); 8587 JSRef<JSVal> color = lightSource->GetProperty("color"); 8588 8589 CalcDimension dimPositionX; 8590 CalcDimension dimPositionY; 8591 CalcDimension dimPositionZ; 8592 if (JSViewAbstract::ParseJsDimensionVp(positionX, dimPositionX) && 8593 JSViewAbstract::ParseJsDimensionVp(positionY, dimPositionY) && 8594 JSViewAbstract::ParseJsDimensionVp(positionZ, dimPositionZ)) { 8595 ViewAbstractModel::GetInstance()->SetLightPosition(dimPositionX, dimPositionY, dimPositionZ); 8596 } 8597 8598 if (intensity->IsNumber()) { 8599 float intensityValue = intensity->ToNumber<float>(); 8600 ViewAbstractModel::GetInstance()->SetLightIntensity(intensityValue); 8601 } 8602 8603 Color lightColor; 8604 if (JSViewAbstract::ParseJsColor(color, lightColor)) { 8605 ViewAbstractModel::GetInstance()->SetLightColor(lightColor); 8606 } 8607 } 8608 JsPointLight(const JSCallbackInfo & info)8609 void JSViewAbstract::JsPointLight(const JSCallbackInfo& info) 8610 { 8611 #ifdef POINT_LIGHT_ENABLE 8612 if (!info[0]->IsObject()) { 8613 return; 8614 } 8615 8616 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]); 8617 JSRef<JSObject> lightSource = object->GetProperty("lightSource"); 8618 ParseJSLightSource(lightSource); 8619 8620 auto resourceWrapper = CreateResourceWrapper(); 8621 if (!resourceWrapper) { 8622 return; 8623 } 8624 double bloomRadius = resourceWrapper->GetDoubleByName(BLOOM_RADIUS_SYS_RES_NAME); 8625 Color bloomColor = resourceWrapper->GetColorByName(BLOOM_COLOR_SYS_RES_NAME); 8626 Dimension illuminatedBorderWidth = resourceWrapper->GetDimensionByName(ILLUMINATED_BORDER_WIDTH_SYS_RES_NAME); 8627 8628 JSRef<JSVal> illuminated = object->GetProperty("illuminated"); 8629 if (illuminated->IsNumber()) { 8630 uint32_t illuminatedValue = illuminated->ToNumber<uint32_t>(); 8631 ViewAbstractModel::GetInstance()->SetLightIlluminated(illuminatedValue); 8632 ViewAbstractModel::GetInstance()->SetIlluminatedBorderWidth(illuminatedBorderWidth); 8633 } 8634 8635 JSRef<JSVal> bloom = object->GetProperty("bloom"); 8636 if (bloom->IsNumber()) { 8637 float bloomValue = bloom->ToNumber<float>(); 8638 ViewAbstractModel::GetInstance()->SetBloom(bloomValue); 8639 8640 Shadow shadow; 8641 shadow.SetBlurRadius(bloomValue * bloomRadius); 8642 shadow.SetColor(bloomColor); 8643 std::vector<Shadow> shadows { shadow }; 8644 ViewAbstractModel::GetInstance()->SetBackShadow(shadows); 8645 } 8646 #endif 8647 } 8648 JsSetDragEventStrictReportingEnabled(const JSCallbackInfo & info)8649 void JSViewAbstract::JsSetDragEventStrictReportingEnabled(const JSCallbackInfo& info) 8650 { 8651 if (info[0]->IsBoolean()) { 8652 ViewAbstractModel::GetInstance()->SetDragEventStrictReportingEnabled(info[0]->ToBoolean()); 8653 } 8654 } 8655 JSBind(BindingTarget globalObj)8656 void JSViewAbstract::JSBind(BindingTarget globalObj) 8657 { 8658 JSClass<JSViewAbstract>::Declare("JSViewAbstract"); 8659 8660 // static methods 8661 MethodOptions opt = MethodOptions::NONE; 8662 JSClass<JSViewAbstract>::StaticMethod("pop", &JSViewAbstract::Pop, opt); 8663 8664 JSClass<JSViewAbstract>::StaticMethod("width", &JSViewAbstract::JsWidth); 8665 JSClass<JSViewAbstract>::StaticMethod("height", &JSViewAbstract::JsHeight); 8666 JSClass<JSViewAbstract>::StaticMethod("responseRegion", &JSViewAbstract::JsResponseRegion); 8667 JSClass<JSViewAbstract>::StaticMethod("mouseResponseRegion", &JSViewAbstract::JsMouseResponseRegion); 8668 JSClass<JSViewAbstract>::StaticMethod("size", &JSViewAbstract::JsSize); 8669 JSClass<JSViewAbstract>::StaticMethod("constraintSize", &JSViewAbstract::JsConstraintSize); 8670 JSClass<JSViewAbstract>::StaticMethod("layoutPriority", &JSViewAbstract::JsLayoutPriority); 8671 JSClass<JSViewAbstract>::StaticMethod("pixelRound", &JSViewAbstract::JsPixelRound); 8672 JSClass<JSViewAbstract>::StaticMethod("layoutWeight", &JSViewAbstract::JsLayoutWeight); 8673 JSClass<JSViewAbstract>::StaticMethod("chainWeight", &JSViewAbstract::JsChainWeight); 8674 8675 JSClass<JSViewAbstract>::StaticMethod("margin", &JSViewAbstract::JsMargin); 8676 JSClass<JSViewAbstract>::StaticMethod("marginTop", &JSViewAbstract::SetMarginTop, opt); 8677 JSClass<JSViewAbstract>::StaticMethod("marginBottom", &JSViewAbstract::SetMarginBottom, opt); 8678 JSClass<JSViewAbstract>::StaticMethod("marginLeft", &JSViewAbstract::SetMarginLeft, opt); 8679 JSClass<JSViewAbstract>::StaticMethod("marginRight", &JSViewAbstract::SetMarginRight, opt); 8680 8681 JSClass<JSViewAbstract>::StaticMethod("padding", &JSViewAbstract::JsPadding); 8682 JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSViewAbstract::SetPaddingTop, opt); 8683 JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSViewAbstract::SetPaddingBottom, opt); 8684 JSClass<JSViewAbstract>::StaticMethod("paddingLeft", &JSViewAbstract::SetPaddingLeft, opt); 8685 JSClass<JSViewAbstract>::StaticMethod("paddingRight", &JSViewAbstract::SetPaddingRight, opt); 8686 JSClass<JSViewAbstract>::StaticMethod("safeAreaPadding", &JSViewAbstract::SetSafeAreaPadding, opt); 8687 8688 JSClass<JSViewAbstract>::StaticMethod("foregroundColor", &JSViewAbstract::JsForegroundColor); 8689 JSClass<JSViewAbstract>::StaticMethod("foregroundEffect", &JSViewAbstract::JsForegroundEffect); 8690 JSClass<JSViewAbstract>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor); 8691 JSClass<JSViewAbstract>::StaticMethod("backgroundImage", &JSViewAbstract::JsBackgroundImage); 8692 JSClass<JSViewAbstract>::StaticMethod("backgroundImageResizable", &JSViewAbstract::JsBackgroundImageResizable); 8693 JSClass<JSViewAbstract>::StaticMethod("backgroundImageSize", &JSViewAbstract::JsBackgroundImageSize); 8694 JSClass<JSViewAbstract>::StaticMethod("backgroundImagePosition", &JSViewAbstract::JsBackgroundImagePosition); 8695 JSClass<JSViewAbstract>::StaticMethod("backgroundBlurStyle", &JSViewAbstract::JsBackgroundBlurStyle); 8696 JSClass<JSViewAbstract>::StaticMethod("backgroundEffect", &JSViewAbstract::JsBackgroundEffect); 8697 JSClass<JSViewAbstract>::StaticMethod("foregroundBlurStyle", &JSViewAbstract::JsForegroundBlurStyle); 8698 JSClass<JSViewAbstract>::StaticMethod("lightUpEffect", &JSViewAbstract::JsLightUpEffect); 8699 JSClass<JSViewAbstract>::StaticMethod("sphericalEffect", &JSViewAbstract::JsSphericalEffect); 8700 JSClass<JSViewAbstract>::StaticMethod("pixelStretchEffect", &JSViewAbstract::JsPixelStretchEffect); 8701 JSClass<JSViewAbstract>::StaticMethod("outline", &JSViewAbstract::JsOutline); 8702 JSClass<JSViewAbstract>::StaticMethod("outlineWidth", &JSViewAbstract::JsOutlineWidth); 8703 JSClass<JSViewAbstract>::StaticMethod("outlineStyle", &JSViewAbstract::JsOutlineStyle); 8704 JSClass<JSViewAbstract>::StaticMethod("outlineColor", &JSViewAbstract::JsOutlineColor); 8705 JSClass<JSViewAbstract>::StaticMethod("outlineRadius", &JSViewAbstract::JsOutlineRadius); 8706 JSClass<JSViewAbstract>::StaticMethod("border", &JSViewAbstract::JsBorder); 8707 JSClass<JSViewAbstract>::StaticMethod("borderWidth", &JSViewAbstract::JsBorderWidth); 8708 JSClass<JSViewAbstract>::StaticMethod("borderColor", &JSViewAbstract::JsBorderColor); 8709 JSClass<JSViewAbstract>::StaticMethod("borderRadius", &JSViewAbstract::JsBorderRadius); 8710 JSClass<JSViewAbstract>::StaticMethod("borderStyle", &JSViewAbstract::JsBorderStyle); 8711 JSClass<JSViewAbstract>::StaticMethod("borderImage", &JSViewAbstract::JsBorderImage); 8712 8713 JSClass<JSViewAbstract>::StaticMethod("scale", &JSViewAbstract::JsScale); 8714 JSClass<JSViewAbstract>::StaticMethod("scaleX", &JSViewAbstract::JsScaleX); 8715 JSClass<JSViewAbstract>::StaticMethod("scaleY", &JSViewAbstract::JsScaleY); 8716 JSClass<JSViewAbstract>::StaticMethod("opacity", &JSViewAbstract::JsOpacity); 8717 JSClass<JSViewAbstract>::StaticMethod("rotate", &JSViewAbstract::JsRotate); 8718 JSClass<JSViewAbstract>::StaticMethod("rotateX", &JSViewAbstract::JsRotateX); 8719 JSClass<JSViewAbstract>::StaticMethod("rotateY", &JSViewAbstract::JsRotateY); 8720 JSClass<JSViewAbstract>::StaticMethod("translate", &JSViewAbstract::JsTranslate); 8721 JSClass<JSViewAbstract>::StaticMethod("translateX", &JSViewAbstract::JsTranslateX); 8722 JSClass<JSViewAbstract>::StaticMethod("translateY", &JSViewAbstract::JsTranslateY); 8723 JSClass<JSViewAbstract>::StaticMethod("transform", &JSViewAbstract::JsTransform); 8724 JSClass<JSViewAbstract>::StaticMethod("transition", &JSViewAbstract::JsTransition); 8725 8726 JSClass<JSViewAbstract>::StaticMethod("align", &JSViewAbstract::JsAlign); 8727 JSClass<JSViewAbstract>::StaticMethod("position", &JSViewAbstract::JsPosition); 8728 JSClass<JSViewAbstract>::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor); 8729 JSClass<JSViewAbstract>::StaticMethod("offset", &JSViewAbstract::JsOffset); 8730 JSClass<JSViewAbstract>::StaticMethod("enabled", &JSViewAbstract::JsEnabled); 8731 JSClass<JSViewAbstract>::StaticMethod("aspectRatio", &JSViewAbstract::JsAspectRatio); 8732 JSClass<JSViewAbstract>::StaticMethod("overlay", &JSViewAbstract::JsOverlay); 8733 8734 JSClass<JSViewAbstract>::StaticMethod("blur", &JSViewAbstract::JsBlur); 8735 JSClass<JSViewAbstract>::StaticMethod("motionBlur", &JSViewAbstract::JsMotionBlur); 8736 JSClass<JSViewAbstract>::StaticMethod("useEffect", &JSViewAbstract::JsUseEffect); 8737 JSClass<JSViewAbstract>::StaticMethod("useShadowBatching", &JSViewAbstract::JsUseShadowBatching); 8738 JSClass<JSViewAbstract>::StaticMethod("colorBlend", &JSViewAbstract::JsColorBlend); 8739 JSClass<JSViewAbstract>::StaticMethod("backdropBlur", &JSViewAbstract::JsBackdropBlur); 8740 JSClass<JSViewAbstract>::StaticMethod("linearGradientBlur", &JSViewAbstract::JsLinearGradientBlur); 8741 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightness", &JSViewAbstract::JsBackgroundBrightness); 8742 JSClass<JSViewAbstract>::StaticMethod("backgroundBrightnessInternal", 8743 &JSViewAbstract::JsBackgroundBrightnessInternal); 8744 JSClass<JSViewAbstract>::StaticMethod("foregroundBrightness", &JSViewAbstract::JsForegroundBrightness); 8745 JSClass<JSViewAbstract>::StaticMethod("windowBlur", &JSViewAbstract::JsWindowBlur); 8746 JSClass<JSViewAbstract>::StaticMethod("visibility", &JSViewAbstract::SetVisibility); 8747 JSClass<JSViewAbstract>::StaticMethod("flexBasis", &JSViewAbstract::JsFlexBasis); 8748 JSClass<JSViewAbstract>::StaticMethod("flexGrow", &JSViewAbstract::JsFlexGrow); 8749 JSClass<JSViewAbstract>::StaticMethod("flexShrink", &JSViewAbstract::JsFlexShrink); 8750 JSClass<JSViewAbstract>::StaticMethod("alignSelf", &JSViewAbstract::JsAlignSelf); 8751 JSClass<JSViewAbstract>::StaticMethod("displayPriority", &JSViewAbstract::JsDisplayPriority); 8752 JSClass<JSViewAbstract>::StaticMethod("useAlign", &JSViewAbstract::JsUseAlign); 8753 JSClass<JSViewAbstract>::StaticMethod("zIndex", &JSViewAbstract::JsZIndex); 8754 JSClass<JSViewAbstract>::StaticMethod("sharedTransition", &JSViewAbstract::JsSharedTransition); 8755 JSClass<JSViewAbstract>::StaticMethod("direction", &JSViewAbstract::SetDirection, opt); 8756 #ifndef WEARABLE_PRODUCT 8757 JSClass<JSViewAbstract>::StaticMethod("bindPopup", &JSViewAbstract::JsBindPopup); 8758 #endif 8759 8760 JSClass<JSViewAbstract>::StaticMethod("background", &JSViewAbstract::JsBackground); 8761 JSClass<JSViewAbstract>::StaticMethod("bindMenu", &JSViewAbstract::JsBindMenu); 8762 JSClass<JSViewAbstract>::StaticMethod("bindContextMenu", &JSViewAbstract::JsBindContextMenu); 8763 JSClass<JSViewAbstract>::StaticMethod("bindContentCover", &JSViewAbstract::JsBindContentCover); 8764 JSClass<JSViewAbstract>::StaticMethod("bindSheet", &JSViewAbstract::JsBindSheet); 8765 JSClass<JSViewAbstract>::StaticMethod("draggable", &JSViewAbstract::JsSetDraggable); 8766 JSClass<JSViewAbstract>::StaticMethod("dragPreviewOptions", &JSViewAbstract::JsSetDragPreviewOptions); 8767 JSClass<JSViewAbstract>::StaticMethod("onPreDrag", &JSViewAbstract::JsOnPreDrag); 8768 JSClass<JSViewAbstract>::StaticMethod("onDragStart", &JSViewAbstract::JsOnDragStart); 8769 JSClass<JSViewAbstract>::StaticMethod("onDragEnter", &JSViewAbstract::JsOnDragEnter); 8770 JSClass<JSViewAbstract>::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove); 8771 JSClass<JSViewAbstract>::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave); 8772 JSClass<JSViewAbstract>::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop); 8773 JSClass<JSViewAbstract>::StaticMethod("onDragEnd", &JSViewAbstract::JsOnDragEnd); 8774 8775 JSClass<JSViewAbstract>::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient); 8776 JSClass<JSViewAbstract>::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient); 8777 JSClass<JSViewAbstract>::StaticMethod("radialGradient", &JSViewAbstract::JsRadialGradient); 8778 JSClass<JSViewAbstract>::StaticMethod("motionPath", &JSViewAbstract::JsMotionPath); 8779 JSClass<JSViewAbstract>::StaticMethod("gridSpan", &JSViewAbstract::JsGridSpan); 8780 JSClass<JSViewAbstract>::StaticMethod("gridOffset", &JSViewAbstract::JsGridOffset); 8781 JSClass<JSViewAbstract>::StaticMethod("useSizeType", &JSViewAbstract::JsUseSizeType); 8782 JSClass<JSViewAbstract>::StaticMethod("shadow", &JSViewAbstract::JsShadow); 8783 JSClass<JSViewAbstract>::StaticMethod("blendMode", &JSViewAbstract::JsBlendMode); 8784 JSClass<JSViewAbstract>::StaticMethod("advancedBlendMode", &JSViewAbstract::JsAdvancedBlendMode); 8785 JSClass<JSViewAbstract>::StaticMethod("grayscale", &JSViewAbstract::JsGrayScale); 8786 JSClass<JSViewAbstract>::StaticMethod("focusable", &JSViewAbstract::JsFocusable); 8787 JSClass<JSViewAbstract>::StaticMethod("tabStop", &JSViewAbstract::JsTabStop); 8788 JSClass<JSViewAbstract>::StaticMethod("focusBox", &JSViewAbstract::JsFocusBox); 8789 JSClass<JSViewAbstract>::StaticMethod("onKeyEvent", &JSViewAbstract::JsOnKeyEvent); 8790 JSClass<JSViewAbstract>::StaticMethod("onKeyPreIme", &JSInteractableView::JsOnKeyPreIme); 8791 JSClass<JSViewAbstract>::StaticMethod("onFocusMove", &JSViewAbstract::JsOnFocusMove); 8792 JSClass<JSViewAbstract>::StaticMethod("onFocus", &JSViewAbstract::JsOnFocus); 8793 JSClass<JSViewAbstract>::StaticMethod("onBlur", &JSViewAbstract::JsOnBlur); 8794 JSClass<JSViewAbstract>::StaticMethod("tabIndex", &JSViewAbstract::JsTabIndex); 8795 JSClass<JSViewAbstract>::StaticMethod("focusOnTouch", &JSViewAbstract::JsFocusOnTouch); 8796 JSClass<JSViewAbstract>::StaticMethod("defaultFocus", &JSViewAbstract::JsDefaultFocus); 8797 JSClass<JSViewAbstract>::StaticMethod("groupDefaultFocus", &JSViewAbstract::JsGroupDefaultFocus); 8798 JSClass<JSViewAbstract>::StaticMethod("brightness", &JSViewAbstract::JsBrightness); 8799 JSClass<JSViewAbstract>::StaticMethod("contrast", &JSViewAbstract::JsContrast); 8800 JSClass<JSViewAbstract>::StaticMethod("saturate", &JSViewAbstract::JsSaturate); 8801 JSClass<JSViewAbstract>::StaticMethod("sepia", &JSViewAbstract::JsSepia); 8802 JSClass<JSViewAbstract>::StaticMethod("invert", &JSViewAbstract::JsInvert); 8803 JSClass<JSViewAbstract>::StaticMethod("systemBarEffect", &JSViewAbstract::JsSystemBarEffect); 8804 JSClass<JSViewAbstract>::StaticMethod("hueRotate", &JSViewAbstract::JsHueRotate); 8805 JSClass<JSViewAbstract>::StaticMethod("clip", &JSViewAbstract::JsClip); 8806 JSClass<JSViewAbstract>::StaticMethod("clipShape", &JSViewAbstract::JsClip); 8807 JSClass<JSViewAbstract>::StaticMethod("mask", &JSViewAbstract::JsMask); 8808 JSClass<JSViewAbstract>::StaticMethod("maskShape", &JSViewAbstract::JsMask); 8809 JSClass<JSViewAbstract>::StaticMethod("key", &JSViewAbstract::JsKey); 8810 JSClass<JSViewAbstract>::StaticMethod("id", &JSViewAbstract::JsId); 8811 JSClass<JSViewAbstract>::StaticMethod("restoreId", &JSViewAbstract::JsRestoreId); 8812 JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect); 8813 JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse); 8814 JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover); 8815 JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover); 8816 JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick); 8817 JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin); 8818 JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept); 8819 JSClass<JSViewAbstract>::StaticMethod( 8820 "shouldBuiltInRecognizerParallelWith", &JSViewAbstract::JsShouldBuiltInRecognizerParallelWith); 8821 JSClass<JSViewAbstract>::StaticMethod( 8822 "onGestureRecognizerJudgeBegin", &JSViewAbstract::JsOnGestureRecognizerJudgeBegin); 8823 JSClass<JSViewAbstract>::StaticMethod("clickEffect", &JSViewAbstract::JsClickEffect); 8824 JSClass<JSViewAbstract>::StaticMethod("debugLine", &JSViewAbstract::JsDebugLine); 8825 JSClass<JSViewAbstract>::StaticMethod("geometryTransition", &JSViewAbstract::JsGeometryTransition); 8826 JSClass<JSViewAbstract>::StaticMethod("onAreaChange", &JSViewAbstract::JsOnAreaChange); 8827 JSClass<JSViewAbstract>::StaticMethod("onSizeChange", &JSViewAbstract::JsOnSizeChange); 8828 JSClass<JSViewAbstract>::StaticMethod("touchable", &JSInteractableView::JsTouchable); 8829 JSClass<JSViewAbstract>::StaticMethod("monopolizeEvents", &JSInteractableView::JsMonopolizeEvents); 8830 8831 JSClass<JSViewAbstract>::StaticMethod("accessibilityGroup", &JSViewAbstract::JsAccessibilityGroup); 8832 JSClass<JSViewAbstract>::StaticMethod("accessibilityText", &JSViewAbstract::JsAccessibilityText); 8833 JSClass<JSViewAbstract>::StaticMethod("accessibilityDescription", &JSViewAbstract::JsAccessibilityDescription); 8834 JSClass<JSViewAbstract>::StaticMethod("accessibilityImportance", &JSViewAbstract::JsAccessibilityImportance); 8835 JSClass<JSViewAbstract>::StaticMethod("accessibilityLevel", &JSViewAbstract::JsAccessibilityLevel); 8836 JSClass<JSViewAbstract>::StaticMethod("accessibilityVirtualNode", &JSViewAbstract::JsAccessibilityVirtualNode); 8837 JSClass<JSViewAbstract>::StaticMethod("onAccessibility", &JSInteractableView::JsOnAccessibility); 8838 JSClass<JSViewAbstract>::StaticMethod("accessibilitySelected", &JSViewAbstract::JsAccessibilitySelected); 8839 JSClass<JSViewAbstract>::StaticMethod("accessibilityChecked", &JSViewAbstract::JsAccessibilityChecked); 8840 8841 JSClass<JSViewAbstract>::StaticMethod("alignRules", &JSViewAbstract::JsAlignRules); 8842 JSClass<JSViewAbstract>::StaticMethod("chainMode", &JSViewAbstract::JsChainMode); 8843 JSClass<JSViewAbstract>::StaticMethod("onVisibleAreaChange", &JSViewAbstract::JsOnVisibleAreaChange); 8844 JSClass<JSViewAbstract>::StaticMethod("hitTestBehavior", &JSViewAbstract::JsHitTestBehavior); 8845 JSClass<JSViewAbstract>::StaticMethod("onChildTouchTest", &JSViewAbstract::JsOnChildTouchTest); 8846 JSClass<JSViewAbstract>::StaticMethod("keyboardShortcut", &JSViewAbstract::JsKeyboardShortcut); 8847 JSClass<JSViewAbstract>::StaticMethod("obscured", &JSViewAbstract::JsObscured); 8848 JSClass<JSViewAbstract>::StaticMethod("privacySensitive", &JSViewAbstract::JsPrivacySensitive); 8849 JSClass<JSViewAbstract>::StaticMethod("allowDrop", &JSViewAbstract::JsAllowDrop); 8850 JSClass<JSViewAbstract>::StaticMethod("dragPreview", &JSViewAbstract::JsDragPreview); 8851 JSClass<JSViewAbstract>::StaticMethod("accessibilityTextHint", &JSViewAbstract::JsAccessibilityTextHint); 8852 8853 JSClass<JSViewAbstract>::StaticMethod("createAnimatableProperty", &JSViewAbstract::JSCreateAnimatableProperty); 8854 JSClass<JSViewAbstract>::StaticMethod("updateAnimatableProperty", &JSViewAbstract::JSUpdateAnimatableProperty); 8855 JSClass<JSViewAbstract>::StaticMethod("renderGroup", &JSViewAbstract::JSRenderGroup); 8856 JSClass<JSViewAbstract>::StaticMethod("renderFit", &JSViewAbstract::JSRenderFit); 8857 8858 JSClass<JSViewAbstract>::StaticMethod("freeze", &JSViewAbstract::JsSetFreeze); 8859 8860 JSClass<JSViewAbstract>::StaticMethod("expandSafeArea", &JSViewAbstract::JsExpandSafeArea); 8861 8862 JSClass<JSViewAbstract>::StaticMethod("drawModifier", &JSViewAbstract::JsDrawModifier); 8863 JSClass<JSViewAbstract>::StaticMethod("customProperty", &JSViewAbstract::JsCustomProperty); 8864 JSClass<JSViewAbstract>::StaticMethod("gestureModifier", &JSViewAbstract::JsGestureModifier); 8865 8866 JSClass<JSViewAbstract>::StaticMethod( 8867 "setDragEventStrictReportingEnabled", &JSViewAbstract::JsSetDragEventStrictReportingEnabled); 8868 8869 JSClass<JSViewAbstract>::StaticMethod("focusScopeId", &JSViewAbstract::JsFocusScopeId); 8870 JSClass<JSViewAbstract>::StaticMethod("focusScopePriority", &JSViewAbstract::JsFocusScopePriority); 8871 8872 JSClass<JSViewAbstract>::StaticMethod("visualEffect", &JSViewAbstract::JsVisualEffect); 8873 JSClass<JSViewAbstract>::StaticMethod("backgroundFilter", &JSViewAbstract::JsBackgroundFilter); 8874 JSClass<JSViewAbstract>::StaticMethod("foregroundFilter", &JSViewAbstract::JsForegroundFilter); 8875 JSClass<JSViewAbstract>::StaticMethod("compositingFilter", &JSViewAbstract::JsCompositingFilter); 8876 8877 JSClass<JSViewAbstract>::Bind(globalObj); 8878 } 8879 AddInvalidateFunc(JSRef<JSObject> jsDrawModifier,NG::FrameNode * frameNode)8880 void AddInvalidateFunc(JSRef<JSObject> jsDrawModifier, NG::FrameNode* frameNode) 8881 { 8882 auto invalidate = [](panda::JsiRuntimeCallInfo* info) -> panda::Local<panda::JSValueRef> { 8883 auto vm = info->GetVM(); 8884 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); 8885 Local<JSValueRef> thisObj = info->GetFunctionRef(); 8886 auto thisObjRef = panda::Local<panda::ObjectRef>(thisObj); 8887 if (thisObjRef->GetNativePointerFieldCount(vm) < 1) { 8888 return panda::JSValueRef::Undefined(vm); 8889 } 8890 8891 auto* weak = reinterpret_cast<NG::NativeWeakRef*>(thisObjRef->GetNativePointerField(vm, 0)); 8892 if (weak->Invalid()) { 8893 return panda::JSValueRef::Undefined(vm); 8894 } 8895 8896 auto frameNode = AceType::DynamicCast<NG::FrameNode>(weak->weakRef.Upgrade()); 8897 if (frameNode) { 8898 const auto& extensionHandler = frameNode->GetExtensionHandler(); 8899 if (extensionHandler) { 8900 extensionHandler->InvalidateRender(); 8901 } else { 8902 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER); 8903 } 8904 } 8905 8906 return panda::JSValueRef::Undefined(vm); 8907 }; 8908 auto jsInvalidate = JSRef<JSFunc>::New<FunctionCallback>(invalidate); 8909 if (frameNode) { 8910 const auto& extensionHandler = frameNode->GetExtensionHandler(); 8911 if (extensionHandler) { 8912 extensionHandler->InvalidateRender(); 8913 } else { 8914 frameNode->MarkDirtyNode(NG::PROPERTY_UPDATE_RENDER); 8915 } 8916 } 8917 auto vm = jsInvalidate->GetEcmaVM(); 8918 auto* weak = new NG::NativeWeakRef(static_cast<AceType*>(frameNode)); 8919 jsInvalidate->GetHandle()->SetNativePointerFieldCount(vm, 1); 8920 jsInvalidate->GetHandle()->SetNativePointerField(vm, 0, weak, &NG::DestructorInterceptor<NG::NativeWeakRef>); 8921 jsDrawModifier->SetPropertyObject("invalidate", jsInvalidate); 8922 } 8923 JsDrawModifier(const JSCallbackInfo & info)8924 void JSViewAbstract::JsDrawModifier(const JSCallbackInfo& info) 8925 { 8926 if (!info[0]->IsObject()) { 8927 return; 8928 } 8929 8930 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode()); 8931 bool IsSupportDrawModifier = frameNode && frameNode->IsSupportDrawModifier(); 8932 if (!IsSupportDrawModifier) { 8933 return; 8934 } 8935 auto jsDrawModifier = JSRef<JSObject>::Cast(info[0]); 8936 RefPtr<NG::DrawModifier> drawModifier = AceType::MakeRefPtr<NG::DrawModifier>(); 8937 auto execCtx = info.GetExecutionContext(); 8938 auto getDrawModifierFunc = [execCtx, jsDrawModifier](const char* key) -> NG::DrawModifierFunc { 8939 JSRef<JSVal> drawMethod = jsDrawModifier->GetProperty(key); 8940 if (!drawMethod->IsFunction()) { 8941 return nullptr; 8942 } 8943 8944 auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>( 8945 JSRef<JSObject>(jsDrawModifier), JSRef<JSFunc>::Cast(drawMethod)); 8946 8947 return GetDrawCallback(jsDrawFunc, execCtx); 8948 }; 8949 8950 drawModifier->drawBehindFunc = getDrawModifierFunc("drawBehind"); 8951 drawModifier->drawContentFunc = getDrawModifierFunc("drawContent"); 8952 drawModifier->drawFrontFunc = getDrawModifierFunc("drawFront"); 8953 8954 ViewAbstractModel::GetInstance()->SetDrawModifier(drawModifier); 8955 AddInvalidateFunc(jsDrawModifier, frameNode); 8956 } 8957 JsAllowDrop(const JSCallbackInfo & info)8958 void JSViewAbstract::JsAllowDrop(const JSCallbackInfo& info) 8959 { 8960 std::set<std::string> allowDropSet; 8961 allowDropSet.clear(); 8962 if (!info[0]->IsUndefined() && info[0]->IsArray()) { 8963 auto allowDropArray = JSRef<JSArray>::Cast(info[0]); 8964 std::string allowDrop; 8965 for (size_t i = 0; i < allowDropArray->Length(); i++) { 8966 allowDrop = allowDropArray->GetValueAt(i)->ToString(); 8967 allowDropSet.insert(allowDrop); 8968 } 8969 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false); 8970 } else if (info[0]->IsNull()) { 8971 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(true); 8972 } else { 8973 ViewAbstractModel::GetInstance()->SetDisallowDropForcedly(false); 8974 } 8975 ViewAbstractModel::GetInstance()->SetAllowDrop(allowDropSet); 8976 } 8977 JsOnPreDrag(const JSCallbackInfo & info)8978 void JSViewAbstract::JsOnPreDrag(const JSCallbackInfo& info) 8979 { 8980 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 8981 auto jsVal = info[0]; 8982 if (!CheckJSCallbackInfo("JsOnPreDrag", jsVal, checkList)) { 8983 return; 8984 } 8985 RefPtr<JsDragFunction> jsDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(jsVal)); 8986 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 8987 auto onPreDrag = [execCtx = info.GetExecutionContext(), func = std::move(jsDragFunc), node = frameNode]( 8988 const PreDragStatus preDragStatus) { 8989 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 8990 ACE_SCORING_EVENT("onPreDrag"); 8991 PipelineContext::SetCallBackNode(node); 8992 func->PreDragExecute(preDragStatus); 8993 }; 8994 ViewAbstractModel::GetInstance()->SetOnPreDrag(onPreDrag); 8995 } 8996 JsDragPreview(const JSCallbackInfo & info)8997 void JSViewAbstract::JsDragPreview(const JSCallbackInfo& info) 8998 { 8999 auto jsVal = info[0]; 9000 if ((!jsVal->IsObject()) && (!jsVal->IsString())) { 9001 return; 9002 } 9003 NG::DragDropInfo dragPreviewInfo; 9004 JSRef<JSVal> builder; 9005 JSRef<JSVal> pixelMap; 9006 JSRef<JSVal> extraInfo; 9007 if (jsVal->IsFunction()) { 9008 builder = jsVal; 9009 } else if (jsVal->IsObject()) { 9010 auto dragItemInfo = JSRef<JSObject>::Cast(jsVal); 9011 builder = dragItemInfo->GetProperty("builder"); 9012 #if defined(PIXEL_MAP_SUPPORTED) 9013 pixelMap = dragItemInfo->GetProperty("pixelMap"); 9014 dragPreviewInfo.pixelMap = CreatePixelMapFromNapiValue(pixelMap); 9015 #endif 9016 extraInfo = dragItemInfo->GetProperty("extraInfo"); 9017 ParseJsString(extraInfo, dragPreviewInfo.extraInfo); 9018 } else if (jsVal->IsString()) { 9019 auto inspectorId = jsVal; 9020 ParseJsString(inspectorId, dragPreviewInfo.inspectorId); 9021 } else { 9022 return; 9023 } 9024 9025 if (builder->IsFunction()) { 9026 RefPtr<JsFunction> builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder)); 9027 if (builderFunc != nullptr) { 9028 ViewStackModel::GetInstance()->NewScope(); 9029 { 9030 ACE_SCORING_EVENT("dragPreview.builder"); 9031 builderFunc->Execute(); 9032 } 9033 RefPtr<AceType> node = ViewStackModel::GetInstance()->Finish(); 9034 dragPreviewInfo.customNode = AceType::DynamicCast<NG::UINode>(node); 9035 } 9036 } 9037 ViewAbstractModel::GetInstance()->SetDragPreview(dragPreviewInfo); 9038 } 9039 JsAlignRules(const JSCallbackInfo & info)9040 void JSViewAbstract::JsAlignRules(const JSCallbackInfo& info) 9041 { 9042 if (!info[0]->IsObject()) { 9043 return; 9044 } 9045 9046 JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(info[0]); 9047 if (valueObj->IsEmpty()) { 9048 return; 9049 } 9050 const char* keys[] = { "left", "middle", "right", "top", "center", "bottom", "bias", "start", "end" }; 9051 std::map<AlignDirection, AlignRule> alignRules; 9052 BiasPair biasPair(DEFAULT_BIAS, DEFAULT_BIAS); 9053 for (uint32_t i = 0; i < sizeof(keys) / sizeof(const char*); i++) { 9054 auto rule = valueObj->GetProperty(keys[i]); 9055 if (rule->IsObject()) { 9056 JSRef<JSObject> val = JSRef<JSObject>::Cast(rule); 9057 JSRef<JSVal> align = val->GetProperty("align"); 9058 AlignRule alignRule; 9059 alignRule.anchor = val->GetProperty("anchor")->ToString(); 9060 if (i < HORIZONTAL_DIRECTION_RANGE) { 9061 alignRule.horizontal = static_cast<HorizontalAlign>(val->GetProperty("align")->ToNumber<int32_t>()); 9062 } else { 9063 alignRule.vertical = static_cast<VerticalAlign>(val->GetProperty("align")->ToNumber<int32_t>()); 9064 } 9065 if (i < VERTICAL_DIRECTION_RANGE) { 9066 alignRules[static_cast<AlignDirection>(i)] = alignRule; 9067 } else if (i == HORIZONTAL_DIRECTION_START_INDEX) { 9068 alignRules[AlignDirection::LEFT] = alignRule; 9069 } else if (i == HORIZONTAL_DIRECTION_END_INDEX) { 9070 alignRules[AlignDirection::RIGHT] = alignRule; 9071 } 9072 auto biasX = val->GetProperty("horizontal"); 9073 if (biasX->IsNumber()) { 9074 biasPair.first = biasX->ToNumber<float>(); 9075 } 9076 auto biasY = val->GetProperty("vertical"); 9077 if (biasY->IsNumber()) { 9078 biasPair.second = biasY->ToNumber<float>(); 9079 } 9080 } 9081 } 9082 9083 ViewAbstractModel::GetInstance()->SetAlignRules(alignRules); 9084 ViewAbstractModel::GetInstance()->SetBias(biasPair); 9085 } 9086 JsChainMode(const JSCallbackInfo & info)9087 void JSViewAbstract::JsChainMode(const JSCallbackInfo& info) 9088 { 9089 ChainInfo chainInfo; 9090 if (info.Length() >= 1) { 9091 auto tmpDirection = info[0]; 9092 if (tmpDirection->IsUndefined()) { 9093 chainInfo.direction = std::nullopt; 9094 } else if (tmpDirection->IsNumber()) { 9095 auto direction = tmpDirection->ToNumber<int32_t>(); 9096 chainInfo.direction = static_cast<LineDirection>(direction); 9097 } 9098 } 9099 9100 if (info.Length() >= 2) { // 2 : two args 9101 auto tmpStyle = info[1]; 9102 if (tmpStyle->IsUndefined()) { 9103 chainInfo.style = std::nullopt; 9104 } else if (tmpStyle->IsNumber()) { 9105 auto style = tmpStyle->ToNumber<int32_t>(); 9106 chainInfo.style = static_cast<ChainStyle>(style); 9107 } 9108 } 9109 ViewAbstractModel::GetInstance()->SetChainStyle(chainInfo); 9110 } 9111 SetMarginTop(const JSCallbackInfo & info)9112 void JSViewAbstract::SetMarginTop(const JSCallbackInfo& info) 9113 { 9114 CalcDimension value; 9115 if (!ParseJsDimensionVp(info[0], value)) { 9116 return; 9117 } 9118 ViewAbstractModel::GetInstance()->SetMargins(value, std::nullopt, std::nullopt, std::nullopt); 9119 } 9120 SetMarginBottom(const JSCallbackInfo & info)9121 void JSViewAbstract::SetMarginBottom(const JSCallbackInfo& info) 9122 { 9123 CalcDimension value; 9124 if (!ParseJsDimensionVp(info[0], value)) { 9125 return; 9126 } 9127 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, value, std::nullopt, std::nullopt); 9128 } 9129 SetMarginLeft(const JSCallbackInfo & info)9130 void JSViewAbstract::SetMarginLeft(const JSCallbackInfo& info) 9131 { 9132 CalcDimension value; 9133 if (!ParseJsDimensionVp(info[0], value)) { 9134 return; 9135 } 9136 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, value, std::nullopt); 9137 } 9138 SetMarginRight(const JSCallbackInfo & info)9139 void JSViewAbstract::SetMarginRight(const JSCallbackInfo& info) 9140 { 9141 CalcDimension value; 9142 if (!ParseJsDimensionVp(info[0], value)) { 9143 return; 9144 } 9145 ViewAbstractModel::GetInstance()->SetMargins(std::nullopt, std::nullopt, std::nullopt, value); 9146 } 9147 SetPaddingTop(const JSCallbackInfo & info)9148 void JSViewAbstract::SetPaddingTop(const JSCallbackInfo& info) 9149 { 9150 CalcDimension value; 9151 if (!ParseJsDimensionVp(info[0], value)) { 9152 return; 9153 } 9154 ViewAbstractModel::GetInstance()->SetPaddings(value, std::nullopt, std::nullopt, std::nullopt); 9155 } 9156 SetPaddingBottom(const JSCallbackInfo & info)9157 void JSViewAbstract::SetPaddingBottom(const JSCallbackInfo& info) 9158 { 9159 CalcDimension value; 9160 if (!ParseJsDimensionVp(info[0], value)) { 9161 return; 9162 } 9163 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, value, std::nullopt, std::nullopt); 9164 } 9165 SetPaddingLeft(const JSCallbackInfo & info)9166 void JSViewAbstract::SetPaddingLeft(const JSCallbackInfo& info) 9167 { 9168 CalcDimension value; 9169 if (!ParseJsDimensionVp(info[0], value)) { 9170 return; 9171 } 9172 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt); 9173 } 9174 SetPaddingRight(const JSCallbackInfo & info)9175 void JSViewAbstract::SetPaddingRight(const JSCallbackInfo& info) 9176 { 9177 CalcDimension value; 9178 if (!ParseJsDimensionVp(info[0], value)) { 9179 return; 9180 } 9181 ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value); 9182 } 9183 SetSafeAreaPadding(const JSCallbackInfo & info)9184 void JSViewAbstract::SetSafeAreaPadding(const JSCallbackInfo& info) 9185 { 9186 ParseMarginOrPadding(info, EdgeType::SAFE_AREA_PADDING); 9187 } 9188 SetColorBlend(Color color)9189 void JSViewAbstract::SetColorBlend(Color color) 9190 { 9191 ViewAbstractModel::GetInstance()->SetColorBlend(color); 9192 } 9193 SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara)9194 void JSViewAbstract::SetLinearGradientBlur(NG::LinearGradientBlurPara blurPara) 9195 { 9196 ViewAbstractModel::GetInstance()->SetLinearGradientBlur(blurPara); 9197 } 9198 SetDynamicLightUp(float rate,float lightUpDegree)9199 void JSViewAbstract::SetDynamicLightUp(float rate, float lightUpDegree) 9200 { 9201 ViewAbstractModel::GetInstance()->SetDynamicLightUp(rate, lightUpDegree); 9202 } 9203 SetBgDynamicBrightness(BrightnessOption brightnessOption)9204 void JSViewAbstract::SetBgDynamicBrightness(BrightnessOption brightnessOption) 9205 { 9206 ViewAbstractModel::GetInstance()->SetBgDynamicBrightness(brightnessOption); 9207 } 9208 SetFgDynamicBrightness(BrightnessOption brightnessOption)9209 void JSViewAbstract::SetFgDynamicBrightness(BrightnessOption brightnessOption) 9210 { 9211 ViewAbstractModel::GetInstance()->SetFgDynamicBrightness(brightnessOption); 9212 } 9213 SetWindowBlur(float progress,WindowBlurStyle blurStyle)9214 void JSViewAbstract::SetWindowBlur(float progress, WindowBlurStyle blurStyle) 9215 { 9216 ViewAbstractModel::GetInstance()->SetWindowBlur(progress, blurStyle); 9217 } 9218 ParseJsonDimension(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,DimensionUnit defaultUnit,bool checkIllegal)9219 bool JSViewAbstract::ParseJsonDimension( 9220 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, DimensionUnit defaultUnit, bool checkIllegal) 9221 { 9222 if (!jsonValue || jsonValue->IsNull()) { 9223 return false; 9224 } 9225 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) { 9226 return false; 9227 } 9228 if (jsonValue->IsNumber()) { 9229 result = Dimension(jsonValue->GetDouble(), defaultUnit); 9230 return true; 9231 } 9232 if (jsonValue->IsString()) { 9233 if (checkIllegal) { 9234 return StringUtils::StringToDimensionWithUnitNG(jsonValue->GetString(), result, defaultUnit); 9235 } 9236 result = StringUtils::StringToCalcDimension(jsonValue->GetString(), false, defaultUnit); 9237 return true; 9238 } 9239 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString()); 9240 auto resId = resVal->GetValue("id"); 9241 if (!resId || !resId->IsNumber()) { 9242 return false; 9243 } 9244 9245 auto resourceWrapper = CreateResourceWrapper(); 9246 if (!resourceWrapper) { 9247 return false; 9248 } 9249 result = resourceWrapper->GetDimension(resId->GetUInt()); 9250 return true; 9251 } 9252 ParseJsonDimensionVp(const std::unique_ptr<JsonValue> & jsonValue,CalcDimension & result,bool checkIllegal)9253 bool JSViewAbstract::ParseJsonDimensionVp( 9254 const std::unique_ptr<JsonValue>& jsonValue, CalcDimension& result, bool checkIllegal) 9255 { 9256 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 9257 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, true); 9258 } 9259 return ParseJsonDimension(jsonValue, result, DimensionUnit::VP, checkIllegal); 9260 } 9261 ParseJsonDouble(const std::unique_ptr<JsonValue> & jsonValue,double & result)9262 bool JSViewAbstract::ParseJsonDouble(const std::unique_ptr<JsonValue>& jsonValue, double& result) 9263 { 9264 if (!jsonValue || jsonValue->IsNull()) { 9265 return false; 9266 } 9267 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) { 9268 return false; 9269 } 9270 if (jsonValue->IsNumber()) { 9271 result = jsonValue->GetDouble(); 9272 return true; 9273 } 9274 if (jsonValue->IsString()) { 9275 result = StringUtils::StringToDouble(jsonValue->GetString()); 9276 return true; 9277 } 9278 // parse json Resource 9279 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString()); 9280 auto resId = resVal->GetValue("id"); 9281 CHECK_NULL_RETURN(resId && resId->IsNumber(), false); 9282 auto id = resId->GetUInt(); 9283 auto resType = resVal->GetValue("type"); 9284 CHECK_NULL_RETURN(resType && resType->IsNumber(), false); 9285 auto type = resType->GetUInt(); 9286 9287 auto resourceWrapper = CreateResourceWrapper(); 9288 if (!resourceWrapper) { 9289 return false; 9290 } 9291 if (type == static_cast<uint32_t>(ResourceType::STRING)) { 9292 auto numberString = resourceWrapper->GetString(id); 9293 return StringUtils::StringToDouble(numberString, result); 9294 } 9295 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) { 9296 result = resourceWrapper->GetInt(id); 9297 return true; 9298 } 9299 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) { 9300 result = resourceWrapper->GetDouble(id); 9301 return true; 9302 } 9303 return false; 9304 } 9305 ParseJsonColor(const std::unique_ptr<JsonValue> & jsonValue,Color & result)9306 bool JSViewAbstract::ParseJsonColor(const std::unique_ptr<JsonValue>& jsonValue, Color& result) 9307 { 9308 if (!jsonValue || jsonValue->IsNull()) { 9309 return false; 9310 } 9311 if (!jsonValue->IsNumber() && !jsonValue->IsString() && !jsonValue->IsObject()) { 9312 return false; 9313 } 9314 if (jsonValue->IsNumber()) { 9315 result = Color(ColorAlphaAdapt(jsonValue->GetUInt())); 9316 return true; 9317 } 9318 9319 bool isSetColor = false; 9320 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { 9321 isSetColor = jsonValue->IsString(); 9322 } else { 9323 isSetColor = jsonValue->IsString() && jsonValue->GetString() != ""; 9324 } 9325 if (isSetColor) { 9326 result = Color::FromString(jsonValue->GetString()); 9327 return true; 9328 } 9329 auto resVal = JsonUtil::ParseJsonString(jsonValue->ToString()); 9330 auto resId = resVal->GetValue("id"); 9331 if (!resId || !resId->IsNumber()) { 9332 return false; 9333 } 9334 auto resourceWrapper = CreateResourceWrapper(); 9335 if (!resourceWrapper) { 9336 return false; 9337 } 9338 result = resourceWrapper->GetColor(resId->GetUInt()); 9339 return true; 9340 } 9341 ParseShadowOffsetX(const JSRef<JSObject> & jsObj,CalcDimension & offsetX,Shadow & shadow)9342 void JSViewAbstract::ParseShadowOffsetX(const JSRef<JSObject>& jsObj, CalcDimension& offsetX, Shadow& shadow) 9343 { 9344 auto jsOffsetX = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_X)); 9345 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft(); 9346 if (ParseJsResource(jsOffsetX, offsetX)) { 9347 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value(); 9348 shadow.SetOffsetX(xValue); 9349 } else { 9350 if (ParseJsDimensionVp(jsOffsetX, offsetX)) { 9351 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value(); 9352 shadow.SetOffsetX(xValue); 9353 } 9354 } 9355 } 9356 ParseShadowProps(const JSRef<JSVal> & jsValue,Shadow & shadow)9357 bool JSViewAbstract::ParseShadowProps(const JSRef<JSVal>& jsValue, Shadow& shadow) 9358 { 9359 int32_t shadowStyle = 0; 9360 if (ParseJsInteger<int32_t>(jsValue, shadowStyle)) { 9361 auto style = static_cast<ShadowStyle>(shadowStyle); 9362 return GetShadowFromTheme(style, shadow); 9363 } 9364 if (!jsValue->IsObject()) { 9365 return false; 9366 } 9367 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 9368 double radius = 0.0; 9369 ParseJsDouble(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS)), radius); 9370 if (LessNotEqual(radius, 0.0)) { 9371 radius = 0.0; 9372 } 9373 shadow.SetBlurRadius(radius); 9374 CalcDimension offsetX; 9375 ParseShadowOffsetX(jsObj, offsetX, shadow); 9376 CalcDimension offsetY; 9377 auto jsOffsetY = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::OFFSET_Y)); 9378 if (ParseJsResource(jsOffsetY, offsetY)) { 9379 shadow.SetOffsetY(offsetY.Value()); 9380 } else { 9381 if (ParseJsDimensionVp(jsOffsetY, offsetY)) { 9382 shadow.SetOffsetY(offsetY.Value()); 9383 } 9384 } 9385 Color color; 9386 ShadowColorStrategy shadowColorStrategy; 9387 auto jsColor = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::COLOR)); 9388 if (ParseJsShadowColorStrategy(jsColor, shadowColorStrategy)) { 9389 shadow.SetShadowColorStrategy(shadowColorStrategy); 9390 } else if (ParseJsColor(jsColor, color)) { 9391 shadow.SetColor(color); 9392 } 9393 int32_t type = static_cast<int32_t>(ShadowType::COLOR); 9394 JSViewAbstract::ParseJsInt32(jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::TYPE)), type); 9395 if (type != static_cast<int32_t>(ShadowType::BLUR)) { 9396 type = static_cast<int32_t>(ShadowType::COLOR); 9397 } 9398 shadow.SetShadowType(static_cast<ShadowType>(type)); 9399 bool isFilled = jsObj->GetPropertyValue<bool>(static_cast<int32_t>(ArkUIIndex::FILL), false); 9400 shadow.SetIsFilled(isFilled); 9401 return true; 9402 } 9403 GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)9404 bool JSViewAbstract::GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow) 9405 { 9406 auto colorMode = SystemProperties::GetColorMode(); 9407 if (shadowStyle == ShadowStyle::None) { 9408 return true; 9409 } 9410 9411 auto container = Container::Current(); 9412 CHECK_NULL_RETURN(container, false); 9413 auto pipelineContext = container->GetPipelineContext(); 9414 CHECK_NULL_RETURN(pipelineContext, false); 9415 9416 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>(); 9417 if (!shadowTheme) { 9418 return false; 9419 } 9420 9421 shadow = shadowTheme->GetShadow(shadowStyle, colorMode); 9422 return true; 9423 } 9424 ParseJsResource(const JSRef<JSVal> & jsValue,CalcDimension & result)9425 bool JSViewAbstract::ParseJsResource(const JSRef<JSVal>& jsValue, CalcDimension& result) 9426 { 9427 if (!jsValue->IsObject()) { 9428 return false; 9429 } 9430 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 9431 uint32_t type = jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::TYPE), 0); 9432 if (type == 0) { 9433 return false; 9434 } 9435 auto resourceWrapper = CreateResourceWrapper(); 9436 CHECK_NULL_RETURN(resourceWrapper, false); 9437 if (type == static_cast<uint32_t>(ResourceType::STRING)) { 9438 auto value = resourceWrapper->GetString( 9439 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)); 9440 return StringUtils::StringToCalcDimensionNG(value, result, false); 9441 } 9442 if (type == static_cast<uint32_t>(ResourceType::INTEGER)) { 9443 auto value = std::to_string( 9444 resourceWrapper->GetInt(jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0))); 9445 StringUtils::StringToDimensionWithUnitNG(value, result); 9446 return true; 9447 } 9448 9449 if (type == static_cast<uint32_t>(ResourceType::FLOAT)) { 9450 result = resourceWrapper->GetDimension( 9451 jsObj->GetPropertyValue<uint32_t>(static_cast<int32_t>(ArkUIIndex::ID), 0)); 9452 return true; 9453 } 9454 return false; 9455 } 9456 ParseDataDetectorConfig(const JSCallbackInfo & info,TextDetectConfig & textDetectConfig)9457 bool JSViewAbstract::ParseDataDetectorConfig(const JSCallbackInfo& info, TextDetectConfig& textDetectConfig) 9458 { 9459 JSRef<JSVal> arg = info[0]; 9460 if (!arg->IsObject()) { 9461 return false; 9462 } 9463 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg); 9464 JSRef<JSVal> typeValue = obj->GetProperty("types"); 9465 if (!typeValue->IsArray()) { 9466 return false; 9467 } 9468 JSRef<JSArray> array = JSRef<JSArray>::Cast(typeValue); 9469 for (size_t i = 0; i < array->Length(); i++) { 9470 JSRef<JSVal> value = array->GetValueAt(i); 9471 auto index = value->ToNumber<int32_t>(); 9472 if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) { 9473 return false; 9474 } 9475 if (i != 0) { 9476 textDetectConfig.types.append(","); 9477 } 9478 textDetectConfig.types.append(TEXT_DETECT_TYPES[index]); 9479 } 9480 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9481 JSRef<JSVal> resultCallback = obj->GetProperty("onDetectResultUpdate"); 9482 if (resultCallback->IsFunction()) { 9483 auto jsFunc = AceType::MakeRefPtr<JsClipboardFunction>(JSRef<JSFunc>::Cast(resultCallback)); 9484 textDetectConfig.onResult = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]( 9485 const std::string& result) { 9486 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 9487 PipelineContext::SetCallBackNode(node); 9488 func->Execute(result); 9489 }; 9490 } 9491 9492 return ParseAIEntityColor(obj, textDetectConfig); 9493 } 9494 ParseAIEntityColor(const JSRef<JSObject> & obj,TextDetectConfig & textDetectConfig)9495 bool JSViewAbstract::ParseAIEntityColor(const JSRef<JSObject>& obj, TextDetectConfig& textDetectConfig) 9496 { 9497 JSRef<JSVal> entityColorValue = obj->GetProperty("color"); 9498 ParseJsColor(entityColorValue, textDetectConfig.entityColor); 9499 9500 JSRef<JSVal> decorationValue = obj->GetProperty("decoration"); 9501 if (decorationValue->IsUndefined() || !decorationValue->IsObject()) { 9502 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor; 9503 return true; 9504 } 9505 JSRef<JSObject> decorationObj = JSRef<JSObject>::Cast(decorationValue); 9506 JSRef<JSVal> typeValue = decorationObj->GetProperty("type"); 9507 JSRef<JSVal> colorValue = decorationObj->GetProperty("color"); 9508 JSRef<JSVal> styleValue = decorationObj->GetProperty("style"); 9509 9510 if (typeValue->IsNumber()) { 9511 textDetectConfig.entityDecorationType = static_cast<TextDecoration>(typeValue->ToNumber<int32_t>()); 9512 } else { 9513 textDetectConfig.entityDecorationType = TextDecoration::UNDERLINE; 9514 } 9515 if (!ParseJsColor(colorValue, textDetectConfig.entityDecorationColor)) { 9516 textDetectConfig.entityDecorationColor = textDetectConfig.entityColor; 9517 } 9518 if (styleValue->IsNumber()) { 9519 textDetectConfig.entityDecorationStyle = static_cast<TextDecorationStyle>(styleValue->ToNumber<int32_t>()); 9520 } else { 9521 textDetectConfig.entityDecorationStyle = TextDecorationStyle::SOLID; 9522 } 9523 9524 return true; 9525 } 9526 GetAngle(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,std::optional<float> & angle)9527 void JSViewAbstract::GetAngle( 9528 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, std::optional<float>& angle) 9529 { 9530 auto value = jsonValue->GetValue(key); 9531 if (value && value->IsString()) { 9532 angle = static_cast<float>(StringUtils::StringToDegree(value->GetString())); 9533 } else if (value && value->IsNumber()) { 9534 angle = static_cast<float>(value->GetDouble()); 9535 } 9536 } 9537 GetJsAngle(int32_t key,const JSRef<JSVal> & jsValue,std::optional<float> & angle)9538 void JSViewAbstract::GetJsAngle( 9539 int32_t key, const JSRef<JSVal>& jsValue, std::optional<float>& angle) 9540 { 9541 if (!jsValue->IsObject()) { 9542 return; 9543 } 9544 JSRef<JSVal> value = JSRef<JSObject>::Cast(jsValue)->GetProperty(key); 9545 if (value->IsString()) { 9546 angle = static_cast<float>(StringUtils::StringToDegree(value->ToString())); 9547 } else if (value->IsNumber()) { 9548 angle = value->ToNumber<float>(); 9549 } 9550 } 9551 9552 // if angle is not string or number, return directly. If angle is invalid string, use defaultValue. GetJsAngleWithDefault(int32_t key,const JSRef<JSObject> & jsObj,std::optional<float> & angle,float defaultValue)9553 void JSViewAbstract::GetJsAngleWithDefault( 9554 int32_t key, const JSRef<JSObject>& jsObj, std::optional<float>& angle, float defaultValue) 9555 { 9556 JSRef<JSVal> value = jsObj->GetProperty(key); 9557 if (value->IsString()) { 9558 double temp = 0.0; 9559 if (StringUtils::StringToDegree(value->ToString(), temp)) { 9560 angle = static_cast<float>(temp); 9561 } else { 9562 angle = defaultValue; 9563 } 9564 } else if (value->IsNumber()) { 9565 angle = value->ToNumber<float>(); 9566 } 9567 } 9568 CheckAngle(std::optional<float> & angle)9569 inline void JSViewAbstract::CheckAngle(std::optional<float>& angle) 9570 { 9571 angle = std::clamp(angle.value(), 0.0f, MAX_ANGLE); 9572 } 9573 GetPerspective(const std::string & key,const std::unique_ptr<JsonValue> & jsonValue,float & perspective)9574 void JSViewAbstract::GetPerspective( 9575 const std::string& key, const std::unique_ptr<JsonValue>& jsonValue, float& perspective) 9576 { 9577 auto value = jsonValue->GetValue(key); 9578 if (value && value->IsNumber()) { 9579 perspective = static_cast<float>(value->GetDouble()); 9580 } 9581 } 9582 GetJsPerspective(int32_t key,const JSRef<JSObject> & jsValue,float & perspective)9583 void JSViewAbstract::GetJsPerspective(int32_t key, const JSRef<JSObject>& jsValue, float& perspective) 9584 { 9585 auto value = jsValue->GetProperty(key); 9586 if (value->IsNumber()) { 9587 perspective = value->ToNumber<float>(); 9588 } 9589 } 9590 GetGradientColorStops(Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9591 void JSViewAbstract::GetGradientColorStops(Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops) 9592 { 9593 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) { 9594 return; 9595 } 9596 9597 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) { 9598 GradientColor gradientColor; 9599 auto item = colorStops->GetArrayItem(i); 9600 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) { 9601 auto colorParams = item->GetArrayItem(0); 9602 // color 9603 Color color; 9604 if (!ParseJsonColor(colorParams, color)) { 9605 continue; 9606 } 9607 gradientColor.SetColor(color); 9608 gradientColor.SetHasValue(false); 9609 // stop value 9610 if (item->GetArraySize() <= 1) { 9611 continue; 9612 } 9613 auto stopValue = item->GetArrayItem(1); 9614 double value = 0.0; 9615 if (ParseJsonDouble(stopValue, value)) { 9616 value = std::clamp(value, 0.0, 1.0); 9617 gradientColor.SetHasValue(true); 9618 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT)); 9619 } 9620 gradient.AddColor(gradientColor); 9621 } 9622 } 9623 } 9624 NewGetGradientColorStops(NG::Gradient & gradient,const std::unique_ptr<JsonValue> & colorStops)9625 void JSViewAbstract::NewGetGradientColorStops(NG::Gradient& gradient, const std::unique_ptr<JsonValue>& colorStops) 9626 { 9627 if (!colorStops || colorStops->IsNull() || !colorStops->IsArray()) { 9628 return; 9629 } 9630 9631 for (int32_t i = 0; i < colorStops->GetArraySize(); i++) { 9632 NG::GradientColor gradientColor; 9633 auto item = colorStops->GetArrayItem(i); 9634 if (item && !item->IsNull() && item->IsArray() && item->GetArraySize() >= 1) { 9635 auto colorParams = item->GetArrayItem(0); 9636 // color 9637 Color color; 9638 if (!ParseJsonColor(colorParams, color)) { 9639 continue; 9640 } 9641 gradientColor.SetColor(color); 9642 gradientColor.SetHasValue(false); 9643 // stop value 9644 if (item->GetArraySize() <= 1) { 9645 continue; 9646 } 9647 auto stopValue = item->GetArrayItem(1); 9648 double value = 0.0; 9649 if (ParseJsonDouble(stopValue, value)) { 9650 value = std::clamp(value, 0.0, 1.0); 9651 gradientColor.SetHasValue(true); 9652 // [0, 1] -> [0, 100.0]; 9653 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT)); 9654 } 9655 gradient.AddColor(gradientColor); 9656 } 9657 } 9658 } 9659 NewGetJsGradientColorStops(NG::Gradient & gradient,const JSRef<JSVal> & colorStops)9660 void JSViewAbstract::NewGetJsGradientColorStops(NG::Gradient& gradient, const JSRef<JSVal>& colorStops) 9661 { 9662 if (!colorStops->IsArray()) { 9663 return; 9664 } 9665 9666 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(colorStops); 9667 size_t length = jsArray->Length(); 9668 for (size_t i = 0; i < length; i++) { 9669 NG::GradientColor gradientColor; 9670 JSRef<JSVal> item = jsArray->GetValueAt(i); 9671 if (!item->IsArray()) { 9672 continue; 9673 } 9674 JSRef<JSArray> subArray = JSRef<JSArray>::Cast(item); 9675 if (subArray->Length() < 2) { 9676 continue; 9677 } 9678 // color 9679 Color color; 9680 if (!ParseJsColor(subArray->GetValueAt(0), color)) { 9681 continue; 9682 } 9683 gradientColor.SetColor(color); 9684 gradientColor.SetHasValue(false); 9685 // stop value 9686 double value = 0.0; 9687 if (ParseJsDouble(subArray->GetValueAt(1), value)) { 9688 value = std::clamp(value, 0.0, 1.0); 9689 gradientColor.SetHasValue(true); 9690 } 9691 // [0, 1] -> [0, 100.0]; 9692 gradientColor.SetDimension(CalcDimension(value * 100.0, DimensionUnit::PERCENT)); 9693 gradient.AddColor(gradientColor); 9694 } 9695 } 9696 SetDirection(const std::string & dir)9697 void JSViewAbstract::SetDirection(const std::string& dir) 9698 { 9699 TextDirection direction = TextDirection::AUTO; 9700 if (dir == "Ltr") { 9701 direction = TextDirection::LTR; 9702 } else if (dir == "Rtl") { 9703 direction = TextDirection::RTL; 9704 } else if (dir == "Auto") { 9705 direction = TextDirection::AUTO; 9706 } else if (dir == "undefined" && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 9707 direction = TextDirection::AUTO; 9708 } 9709 ViewAbstractModel::GetInstance()->SetLayoutDirection(direction); 9710 } 9711 GetThemeConstants(const JSRef<JSObject> & jsObj)9712 RefPtr<ThemeConstants> JSViewAbstract::GetThemeConstants(const JSRef<JSObject>& jsObj) 9713 { 9714 std::string bundleName; 9715 std::string moduleName; 9716 if (!jsObj->IsUndefined()) { 9717 JSRef<JSVal> bundle = jsObj->GetProperty("bundleName"); 9718 JSRef<JSVal> module = jsObj->GetProperty("moduleName"); 9719 if (bundle->IsString() && module->IsString()) { 9720 bundleName = bundle->ToString(); 9721 moduleName = module->ToString(); 9722 } 9723 } 9724 9725 auto cardId = CardScope::CurrentId(); 9726 if (cardId != INVALID_CARD_ID) { 9727 auto container = Container::Current(); 9728 auto weak = container->GetCardPipeline(cardId); 9729 auto cardPipelineContext = weak.Upgrade(); 9730 CHECK_NULL_RETURN(cardPipelineContext, nullptr); 9731 auto cardThemeManager = cardPipelineContext->GetThemeManager(); 9732 CHECK_NULL_RETURN(cardThemeManager, nullptr); 9733 return cardThemeManager->GetThemeConstants(bundleName, moduleName); 9734 } 9735 9736 #ifdef PLUGIN_COMPONENT_SUPPORTED 9737 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) { 9738 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId()); 9739 if (!pluginContainer) { 9740 return nullptr; 9741 } 9742 auto pluginPipelineContext = pluginContainer->GetPipelineContext(); 9743 if (!pluginPipelineContext) { 9744 return nullptr; 9745 } 9746 auto pluginThemeManager = pluginPipelineContext->GetThemeManager(); 9747 if (!pluginThemeManager) { 9748 return nullptr; 9749 } 9750 return pluginThemeManager->GetThemeConstants(bundleName, moduleName); 9751 } 9752 #endif 9753 auto container = Container::Current(); 9754 CHECK_NULL_RETURN(container, nullptr); 9755 auto pipelineContext = container->GetPipelineContext(); 9756 CHECK_NULL_RETURN(pipelineContext, nullptr); 9757 auto themeManager = pipelineContext->GetThemeManager(); 9758 CHECK_NULL_RETURN(themeManager, nullptr); 9759 return themeManager->GetThemeConstants(bundleName, moduleName); 9760 } 9761 JsHoverEffect(const JSCallbackInfo & info)9762 void JSViewAbstract::JsHoverEffect(const JSCallbackInfo& info) 9763 { 9764 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::NUMBER }; 9765 auto jsVal = info[0]; 9766 if (!CheckJSCallbackInfo("HoverEffect", jsVal, checkList)) { 9767 ViewAbstractModel::GetInstance()->SetHoverEffect(HoverEffectType::AUTO); 9768 return; 9769 } 9770 if (!jsVal->IsNumber()) { 9771 return; 9772 } 9773 ViewAbstractModel::GetInstance()->SetHoverEffect(static_cast<HoverEffectType>(jsVal->ToNumber<int32_t>())); 9774 } 9775 JsOnMouse(const JSCallbackInfo & info)9776 void JSViewAbstract::JsOnMouse(const JSCallbackInfo& info) 9777 { 9778 if (info[0]->IsUndefined() && IsDisableEventVersion()) { 9779 ViewAbstractModel::GetInstance()->DisableOnMouse(); 9780 return; 9781 } 9782 if (!info[0]->IsFunction()) { 9783 return; 9784 } 9785 9786 RefPtr<JsClickFunction> jsOnMouseFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0])); 9787 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9788 auto onMouse = [execCtx = info.GetExecutionContext(), func = std::move(jsOnMouseFunc), node = targetNode]( 9789 MouseInfo& mouseInfo) { 9790 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 9791 ACE_SCORING_EVENT("onMouse"); 9792 PipelineContext::SetCallBackNode(node); 9793 func->Execute(mouseInfo); 9794 }; 9795 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse)); 9796 } 9797 JsOnHover(const JSCallbackInfo & info)9798 void JSViewAbstract::JsOnHover(const JSCallbackInfo& info) 9799 { 9800 if (info[0]->IsUndefined() && IsDisableEventVersion()) { 9801 ViewAbstractModel::GetInstance()->DisableOnHover(); 9802 return; 9803 } 9804 if (!info[0]->IsFunction()) { 9805 return; 9806 } 9807 9808 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0])); 9809 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9810 auto onHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), node = frameNode]( 9811 bool isHover, HoverInfo& hoverInfo) { 9812 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 9813 ACE_SCORING_EVENT("onHover"); 9814 PipelineContext::SetCallBackNode(node); 9815 func->HoverExecute(isHover, hoverInfo); 9816 }; 9817 ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover)); 9818 } 9819 JsOnAccessibilityHover(const JSCallbackInfo & info)9820 void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info) 9821 { 9822 if (info[0]->IsUndefined()) { 9823 ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover(); 9824 return; 9825 } 9826 if (!info[0]->IsFunction()) { 9827 return; 9828 } 9829 9830 RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0])); 9831 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9832 auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc), 9833 node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) { 9834 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 9835 ACE_SCORING_EVENT("onAccessibilityHover"); 9836 PipelineContext::SetCallBackNode(node); 9837 func->AccessibilityHoverExecute(isHover, hoverInfo); 9838 }; 9839 ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover)); 9840 } 9841 JsOnClick(const JSCallbackInfo & info)9842 void JSViewAbstract::JsOnClick(const JSCallbackInfo& info) 9843 { 9844 auto arg = info[0]; 9845 if (arg->IsUndefined() && IsDisableEventVersion()) { 9846 ViewAbstractModel::GetInstance()->DisableOnClick(); 9847 return; 9848 } 9849 if (!arg->IsFunction()) { 9850 return; 9851 } 9852 9853 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(arg)); 9854 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9855 auto onTap = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc), node = targetNode]( 9856 BaseEventInfo* info) { 9857 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 9858 auto* tapInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info); 9859 ACE_SCORING_EVENT("onClick"); 9860 PipelineContext::SetCallBackNode(node); 9861 func->Execute(*tapInfo); 9862 #if !defined(PREVIEW) && defined(OHOS_PLATFORM) 9863 JSInteractableView::ReportClickEvent(node); 9864 #endif 9865 }; 9866 auto tmpOnTap = [func = std::move(onTap)](GestureEvent& info) { func(&info); }; 9867 auto onClick = [execCtx = info.GetExecutionContext(), func = jsOnClickFunc, node = targetNode]( 9868 const ClickInfo* info) { 9869 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 9870 ACE_SCORING_EVENT("onClick"); 9871 PipelineContext::SetCallBackNode(node); 9872 func->Execute(*info); 9873 #if !defined(PREVIEW) && defined(OHOS_PLATFORM) 9874 JSInteractableView::ReportClickEvent(node); 9875 #endif 9876 }; 9877 9878 double distanceThreshold = std::numeric_limits<double>::infinity(); 9879 if (info.Length() > 1 && info[1]->IsNumber()) { 9880 distanceThreshold = info[1]->ToNumber<double>(); 9881 if (distanceThreshold < 0) { 9882 distanceThreshold = std::numeric_limits<double>::infinity(); 9883 } 9884 } 9885 distanceThreshold = Dimension(distanceThreshold, DimensionUnit::VP).ConvertToPx(); 9886 ViewAbstractModel::GetInstance()->SetOnClick(std::move(tmpOnTap), std::move(onClick), distanceThreshold); 9887 } 9888 JsOnGestureJudgeBegin(const JSCallbackInfo & info)9889 void JSViewAbstract::JsOnGestureJudgeBegin(const JSCallbackInfo& info) 9890 { 9891 if (info[0]->IsUndefined() || !info[0]->IsFunction()) { 9892 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(nullptr); 9893 return; 9894 } 9895 9896 auto jsOnGestureJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0])); 9897 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9898 auto onGestureJudgefunc = [execCtx = info.GetExecutionContext(), func = jsOnGestureJudgeFunc, node = frameNode]( 9899 const RefPtr<NG::GestureInfo>& gestureInfo, 9900 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult { 9901 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE); 9902 ACE_SCORING_EVENT("onGestureJudgeBegin"); 9903 return func->Execute(gestureInfo, info); 9904 }; 9905 ViewAbstractModel::GetInstance()->SetOnGestureJudgeBegin(std::move(onGestureJudgefunc)); 9906 } 9907 JsOnTouchIntercept(const JSCallbackInfo & info)9908 void JSViewAbstract::JsOnTouchIntercept(const JSCallbackInfo& info) 9909 { 9910 if (info[0]->IsUndefined() || !info[0]->IsFunction()) { 9911 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(nullptr); 9912 return; 9913 } 9914 9915 auto jsOnTouchInterceptFunc = AceType::MakeRefPtr<JsTouchInterceptFunction>(JSRef<JSFunc>::Cast(info[0])); 9916 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9917 auto onTouchInterceptfunc = [execCtx = info.GetExecutionContext(), func = jsOnTouchInterceptFunc, node = frameNode]( 9918 TouchEventInfo& info) -> NG::HitTestMode { 9919 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, NG::HitTestMode::HTMDEFAULT); 9920 ACE_SCORING_EVENT("onTouchIntercept"); 9921 PipelineContext::SetCallBackNode(node); 9922 return func->Execute(info); 9923 }; 9924 ViewAbstractModel::GetInstance()->SetOnTouchIntercept(std::move(onTouchInterceptfunc)); 9925 } 9926 JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo & info)9927 void JSViewAbstract::JsShouldBuiltInRecognizerParallelWith(const JSCallbackInfo& info) 9928 { 9929 if (info[0]->IsUndefined() || !info[0]->IsFunction()) { 9930 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith(nullptr); 9931 return; 9932 } 9933 9934 auto jsParallelInnerGestureToFunc = 9935 AceType::MakeRefPtr<JsShouldBuiltInRecognizerParallelWithFunction>(JSRef<JSFunc>::Cast(info[0])); 9936 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9937 auto shouldBuiltInRecognizerParallelWithFunc = 9938 [execCtx = info.GetExecutionContext(), func = jsParallelInnerGestureToFunc, node = frameNode]( 9939 const RefPtr<NG::NGGestureRecognizer>& current, 9940 const std::vector<RefPtr<NG::NGGestureRecognizer>>& others) -> RefPtr<NG::NGGestureRecognizer> { 9941 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr); 9942 ACE_SCORING_EVENT("shouldBuiltInRecognizerParallelWith"); 9943 PipelineContext::SetCallBackNode(node); 9944 return func->Execute(current, others); 9945 }; 9946 ViewAbstractModel::GetInstance()->SetShouldBuiltInRecognizerParallelWith( 9947 std::move(shouldBuiltInRecognizerParallelWithFunc)); 9948 } 9949 JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo & info)9950 void JSViewAbstract::JsOnGestureRecognizerJudgeBegin(const JSCallbackInfo& info) 9951 { 9952 if (info[0]->IsUndefined() || !info[0]->IsFunction()) { 9953 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin(nullptr, false); 9954 return; 9955 } 9956 9957 auto jsOnGestureRecognizerJudgeFunc = AceType::MakeRefPtr<JsGestureJudgeFunction>(JSRef<JSFunc>::Cast(info[0])); 9958 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 9959 auto onGestureRecognizerJudgefunc = 9960 [execCtx = info.GetExecutionContext(), func = jsOnGestureRecognizerJudgeFunc, node = frameNode]( 9961 const std::shared_ptr<BaseGestureEvent>& info, const RefPtr<NG::NGGestureRecognizer>& current, 9962 const std::list<RefPtr<NG::NGGestureRecognizer>>& others) -> GestureJudgeResult { 9963 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, GestureJudgeResult::CONTINUE); 9964 ACE_SCORING_EVENT("onGestureRecognizerJudgeBegin"); 9965 PipelineContext::SetCallBackNode(node); 9966 return func->Execute(info, current, others); 9967 }; 9968 9969 bool exposeInnerGestureFlag = false; 9970 if (info.Length() > 1 && info[1]->IsBoolean()) { 9971 exposeInnerGestureFlag = info[1]->ToBoolean(); 9972 } 9973 ViewAbstractModel::GetInstance()->SetOnGestureRecognizerJudgeBegin( 9974 std::move(onGestureRecognizerJudgefunc), exposeInnerGestureFlag); 9975 } 9976 JsClickEffect(const JSCallbackInfo & info)9977 void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info) 9978 { 9979 JSRef<JSVal> arg = info[0]; 9980 if (arg->IsUndefined() || arg->IsNull()) { 9981 ViewAbstractModel::GetInstance()->SetClickEffectLevel(ClickEffectLevel::UNDEFINED, DEFAULT_SCALE_LIGHT); 9982 return; 9983 } 9984 if (!arg->IsObject()) { 9985 return; 9986 } 9987 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]); 9988 JSRef<JSVal> clickEffectLevel = obj->GetProperty("level"); 9989 int32_t clickEffectLevelValue = 0; 9990 if (clickEffectLevel->IsNumber()) { 9991 clickEffectLevelValue = clickEffectLevel->ToNumber<int32_t>(); 9992 if (clickEffectLevelValue < static_cast<int32_t>(ClickEffectLevel::LIGHT) || 9993 clickEffectLevelValue > static_cast<int32_t>(ClickEffectLevel::HEAVY)) { 9994 clickEffectLevelValue = 0; 9995 } 9996 } 9997 9998 JSRef<JSVal> scaleNumber = obj->GetProperty("scale"); 9999 float scaleNumberValue = DEFAULT_SCALE_LIGHT; 10000 if (!scaleNumber->IsNumber()) { 10001 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE || 10002 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) { 10003 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY; 10004 } 10005 ViewAbstractModel::GetInstance()->SetClickEffectLevel( 10006 (ClickEffectLevel)clickEffectLevelValue, scaleNumberValue); 10007 return; 10008 } 10009 10010 scaleNumberValue = scaleNumber->ToNumber<float>(); 10011 if (LessNotEqual(scaleNumberValue, 0.0) || GreatNotEqual(scaleNumberValue, 1.0)) { 10012 if ((ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::MIDDLE || 10013 (ClickEffectLevel)clickEffectLevelValue == ClickEffectLevel::HEAVY) { 10014 scaleNumberValue = DEFAULT_SCALE_MIDDLE_OR_HEAVY; 10015 } else { 10016 scaleNumberValue = DEFAULT_SCALE_LIGHT; 10017 } 10018 } 10019 10020 ViewAbstractModel::GetInstance()->SetClickEffectLevel((ClickEffectLevel)clickEffectLevelValue, scaleNumberValue); 10021 } 10022 JsOnVisibleAreaChange(const JSCallbackInfo & info)10023 void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info) 10024 { 10025 if (info.Length() != 2) { 10026 return; 10027 } 10028 10029 if (!info[0]->IsArray() || !info[1]->IsFunction()) { 10030 return; 10031 } 10032 10033 auto ratioArray = JSRef<JSArray>::Cast(info[0]); 10034 size_t size = ratioArray->Length(); 10035 std::vector<double> ratioVec(size); 10036 ratioVec.clear(); 10037 for (size_t i = 0; i < size; i++) { 10038 double ratio = 0.0; 10039 ParseJsDouble(ratioArray->GetValueAt(i), ratio); 10040 if (LessOrEqual(ratio, VISIBLE_RATIO_MIN)) { 10041 ratio = VISIBLE_RATIO_MIN; 10042 } 10043 10044 if (GreatOrEqual(ratio, VISIBLE_RATIO_MAX)) { 10045 ratio = VISIBLE_RATIO_MAX; 10046 } 10047 ratioVec.push_back(ratio); 10048 } 10049 10050 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1])); 10051 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 10052 auto onVisibleChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]( 10053 bool visible, double ratio) { 10054 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 10055 ACE_SCORING_EVENT("onVisibleAreaChange"); 10056 10057 JSRef<JSVal> params[2]; 10058 params[0] = JSRef<JSVal>::Make(ToJSValue(visible)); 10059 params[1] = JSRef<JSVal>::Make(ToJSValue(ratio)); 10060 PipelineContext::SetCallBackNode(node); 10061 func->ExecuteJS(2, params); 10062 }; 10063 ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec); 10064 } 10065 JsHitTestBehavior(const JSCallbackInfo & info)10066 void JSViewAbstract::JsHitTestBehavior(const JSCallbackInfo& info) 10067 { 10068 if (info.Length() != 1 || !info[0]->IsNumber()) { 10069 return; 10070 } 10071 10072 NG::HitTestMode hitTestModeNG = NG::HitTestMode::HTMDEFAULT; 10073 hitTestModeNG = static_cast<NG::HitTestMode>(info[0]->ToNumber<int32_t>()); 10074 ViewAbstractModel::GetInstance()->SetHitTestMode(hitTestModeNG); 10075 } 10076 JsOnChildTouchTest(const JSCallbackInfo & info)10077 void JSViewAbstract::JsOnChildTouchTest(const JSCallbackInfo& info) 10078 { 10079 static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::FUNCTION }; 10080 auto jsVal = info[0]; 10081 if (!CheckJSCallbackInfo("onChildTouchTest", jsVal, checkList)) { 10082 return; 10083 } 10084 10085 RefPtr<JsOnChildTouchTestFunction> jsOnChildTouchTestFunc = 10086 AceType::MakeRefPtr<JsOnChildTouchTestFunction>(JSRef<JSFunc>::Cast(jsVal)); 10087 10088 auto onTouchTestFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsOnChildTouchTestFunc)]( 10089 const std::vector<NG::TouchTestInfo>& touchInfo) -> NG::TouchResult { 10090 NG::TouchResult touchRes; 10091 NG::TouchResult defaultRes; 10092 defaultRes.strategy = NG::TouchTestStrategy::DEFAULT; 10093 defaultRes.id = ""; 10094 auto ret = func->Execute(touchInfo); 10095 if (!ret->IsObject()) { 10096 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value is not object, parse failed."); 10097 return defaultRes; 10098 } 10099 10100 auto retObj = JSRef<JSObject>::Cast(ret); 10101 auto strategy = retObj->GetProperty("strategy"); 10102 if (!strategy->IsNumber()) { 10103 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value strategy is not number, parse failed."); 10104 return defaultRes; 10105 } 10106 touchRes.strategy = static_cast<NG::TouchTestStrategy>(strategy->ToNumber<int32_t>()); 10107 auto id = retObj->GetProperty("id"); 10108 if (!id->IsString()) { 10109 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest return value id is not string, parse failed."); 10110 return defaultRes; 10111 } 10112 touchRes.id = id->ToString(); 10113 return touchRes; 10114 }; 10115 ViewAbstractModel::GetInstance()->SetOnTouchTestFunc(std::move(onTouchTestFunc)); 10116 } 10117 JsForegroundColor(const JSCallbackInfo & info)10118 void JSViewAbstract::JsForegroundColor(const JSCallbackInfo& info) 10119 { 10120 Color foregroundColor = Color::TRANSPARENT; 10121 ForegroundColorStrategy strategy; 10122 if (ParseJsColorStrategy(info[0], strategy)) { 10123 ViewAbstractModel::GetInstance()->SetForegroundColorStrategy(strategy); 10124 return; 10125 } 10126 ParseJsColor(info[0], foregroundColor); 10127 ViewAbstractModel::GetInstance()->SetForegroundColor(foregroundColor); 10128 } 10129 JsKeyboardShortcut(const JSCallbackInfo & info)10130 void JSViewAbstract::JsKeyboardShortcut(const JSCallbackInfo& info) 10131 { 10132 // KeyboardShortcut only allows 2 or 3 params. 10133 if (info.Length() < 2 || info.Length() > 3) { 10134 return; 10135 } 10136 if ((!info[0]->IsString() && !info[0]->IsNumber()) || !info[1]->IsArray()) { 10137 // clear shortcut key 10138 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr); 10139 return; 10140 } 10141 10142 std::string value; 10143 if (info[0]->IsString()) { 10144 // common letter/number/symbol 10145 value = info[0]->ToString(); 10146 if (value.size() != 1) { 10147 // clear shortcut key 10148 ViewAbstractModel::GetInstance()->SetKeyboardShortcut({}, {}, nullptr); 10149 return; 10150 } 10151 } else { 10152 // function keys such as F1-F10/ESC 10153 FunctionKey functionkey = static_cast<FunctionKey>(info[0]->ToNumber<int32_t>()); 10154 value = GetFunctionKeyName(functionkey); 10155 } 10156 10157 auto keysArray = JSRef<JSArray>::Cast(info[1]); 10158 size_t size = keysArray->Length(); 10159 std::vector<ModifierKey> keys(size); 10160 keys.clear(); 10161 for (size_t i = 0; i < size; i++) { 10162 JSRef<JSVal> key = keysArray->GetValueAt(i); 10163 if (key->IsNumber()) { 10164 keys.emplace_back(static_cast<ModifierKey>(key->ToNumber<int32_t>())); 10165 } 10166 } 10167 10168 // KeyboardShortcut allows 3 params, the third param is function callback. 10169 if (info.Length() == 3 && info[2]->IsFunction()) { 10170 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[2])); 10171 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 10172 auto onKeyboardShortcutAction = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), 10173 node = frameNode]() { 10174 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 10175 ACE_SCORING_EVENT("onKeyboardShortcutAction"); 10176 PipelineContext::SetCallBackNode(node); 10177 func->ExecuteJS(); 10178 }; 10179 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, std::move(onKeyboardShortcutAction)); 10180 return; 10181 } 10182 ViewAbstractModel::GetInstance()->SetKeyboardShortcut(value, keys, nullptr); 10183 } 10184 CheckColor(const JSRef<JSVal> & jsValue,Color & result,const char * componentName,const char * propName)10185 bool JSViewAbstract::CheckColor( 10186 const JSRef<JSVal>& jsValue, Color& result, const char* componentName, const char* propName) 10187 { 10188 // Color is undefined or null 10189 if (jsValue->IsUndefined() || jsValue->IsNull()) { 10190 return false; 10191 } 10192 // input type is not in [number, string, Resource] 10193 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) { 10194 return false; 10195 } 10196 // Correct type, incorrect value parsing 10197 if (!ParseJsColor(jsValue, result)) { 10198 return false; 10199 } 10200 return true; 10201 } 10202 CheckLength(const JSRef<JSVal> & jsValue,CalcDimension & result,const char * componentName,const char * propName)10203 bool JSViewAbstract::CheckLength( 10204 const JSRef<JSVal>& jsValue, CalcDimension& result, const char* componentName, const char* propName) 10205 { 10206 // Length is undefined or null 10207 if (jsValue->IsUndefined() || jsValue->IsNull()) { 10208 return false; 10209 } 10210 // input type is not in [number, string, Resource] 10211 if (!jsValue->IsNumber() && !jsValue->IsString() && !jsValue->IsObject()) { 10212 return false; 10213 } 10214 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) { 10215 return ParseJsDimensionVpNG(jsValue, result); 10216 } 10217 // Correct type, incorrect value parsing 10218 if (!ParseJsDimensionVp(jsValue, result)) { 10219 return false; 10220 } 10221 return true; 10222 } 10223 10224 // obscured means that the developer calls the component to be private style. JsObscured(const JSCallbackInfo & info)10225 void JSViewAbstract::JsObscured(const JSCallbackInfo& info) 10226 { 10227 JSRef<JSVal> arg = info[0]; 10228 if (arg->IsUndefined() || arg->IsNull()) { 10229 std::vector<ObscuredReasons> reasons(0); 10230 ViewAbstractModel::GetInstance()->SetObscured(reasons); 10231 return; 10232 } 10233 if (!arg->IsArray()) { 10234 return; 10235 } 10236 10237 auto obscuredArray = JSRef<JSArray>::Cast(arg); 10238 size_t size = obscuredArray->Length(); 10239 std::vector<ObscuredReasons> reasons(size); 10240 reasons.clear(); 10241 for (size_t i = 0; i < size; i++) { 10242 JSRef<JSVal> reason = obscuredArray->GetValueAt(i); 10243 if (reason->IsNumber()) { 10244 reasons.emplace_back(static_cast<ObscuredReasons>(reason->ToNumber<int32_t>())); 10245 } 10246 } 10247 10248 ViewAbstractModel::GetInstance()->SetObscured(reasons); 10249 } 10250 10251 // PrivacySensitive means that the component will change style when system calls the app to be privated. JsPrivacySensitive(const JSCallbackInfo & info)10252 void JSViewAbstract::JsPrivacySensitive(const JSCallbackInfo& info) 10253 { 10254 auto sensitiveInfo = info[0]; 10255 if (sensitiveInfo->IsUndefined()) { 10256 ViewAbstractModel::GetInstance()->SetPrivacySensitive(false); 10257 return; 10258 } 10259 bool sensitive = false; 10260 if (sensitiveInfo->IsBoolean()) { 10261 sensitive = sensitiveInfo->ToBoolean(); 10262 } 10263 ViewAbstractModel::GetInstance()->SetPrivacySensitive(sensitive); 10264 } 10265 JSRenderGroup(const JSCallbackInfo & info)10266 void JSViewAbstract::JSRenderGroup(const JSCallbackInfo& info) 10267 { 10268 if (info.Length() != 1) { 10269 return; 10270 } 10271 bool isRenderGroup = false; 10272 if (info[0]->IsBoolean()) { 10273 isRenderGroup = info[0]->ToBoolean(); 10274 } 10275 ViewAbstractModel::GetInstance()->SetRenderGroup(isRenderGroup); 10276 } 10277 JSRenderFit(const JSCallbackInfo & info)10278 void JSViewAbstract::JSRenderFit(const JSCallbackInfo& info) 10279 { 10280 if (info.Length() != 1) { 10281 return; 10282 } 10283 RenderFit renderFit = RenderFit::TOP_LEFT; 10284 if (info[0]->IsNumber()) { 10285 int32_t fitNumber = info[0]->ToNumber<int32_t>(); 10286 if (fitNumber >= static_cast<int32_t>(RenderFit::CENTER) && 10287 fitNumber <= static_cast<int32_t>(RenderFit::RESIZE_COVER_BOTTOM_RIGHT)) { 10288 renderFit = static_cast<RenderFit>(fitNumber); 10289 } 10290 } 10291 // how content fills the node duration implicit animation 10292 ViewAbstractModel::GetInstance()->SetRenderFit(renderFit); 10293 } 10294 GetJsMediaBundleInfo(const JSRef<JSVal> & jsValue,std::string & bundleName,std::string & moduleName)10295 bool JSViewAbstract::GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName) 10296 { 10297 if (!jsValue->IsObject() || jsValue->IsString()) { 10298 return false; 10299 } 10300 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 10301 if (!jsObj->IsUndefined()) { 10302 JSRef<JSVal> bundle = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUNDLE_NAME)); 10303 JSRef<JSVal> module = jsObj->GetProperty(static_cast<int32_t>(ArkUIIndex::MODULE_NAME)); 10304 if (bundle->IsString() && module->IsString()) { 10305 bundleName = bundle->ToString(); 10306 moduleName = module->ToString(); 10307 return true; 10308 } 10309 } 10310 return false; 10311 } 10312 GetDrawCallback(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)10313 std::function<void(NG::DrawingContext& context)> JSViewAbstract::GetDrawCallback( 10314 const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx) 10315 { 10316 std::function<void(NG::DrawingContext & context)> drawCallback = [func = std::move(jsDraw), execCtx]( 10317 NG::DrawingContext& context) -> void { 10318 JAVASCRIPT_EXECUTION_SCOPE(execCtx); 10319 10320 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New(); 10321 objectTemplate->SetInternalFieldCount(1); 10322 JSRef<JSObject> contextObj = objectTemplate->NewInstance(); 10323 JSRef<JSObject> sizeObj = objectTemplate->NewInstance(); 10324 sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height)); 10325 sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width)); 10326 contextObj->SetPropertyObject("size", sizeObj); 10327 10328 JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance(); 10329 sizeInPxObj->SetProperty<float>("height", context.height); 10330 sizeInPxObj->SetProperty<float>("width", context.width); 10331 contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj); 10332 10333 auto engine = EngineHelper::GetCurrentEngine(); 10334 CHECK_NULL_VOID(engine); 10335 NativeEngine* nativeEngine = engine->GetNativeEngine(); 10336 napi_env env = reinterpret_cast<napi_env>(nativeEngine); 10337 ScopeRAII scope(env); 10338 10339 auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas); 10340 OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr; 10341 napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas)); 10342 if (unwrapCanvas) { 10343 unwrapCanvas->SaveCanvas(); 10344 unwrapCanvas->ClipCanvas(context.width, context.height); 10345 } 10346 JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas); 10347 contextObj->SetPropertyObject("canvas", jsCanvasVal); 10348 10349 auto jsVal = JSRef<JSVal>::Cast(contextObj); 10350 panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle(); 10351 JSValueWrapper valueWrapper = value; 10352 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper); 10353 10354 napi_wrap( 10355 env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr); 10356 10357 JSRef<JSVal> result = func->ExecuteJS(1, &jsVal); 10358 if (unwrapCanvas) { 10359 unwrapCanvas->RestoreCanvas(); 10360 unwrapCanvas->ResetCanvas(); 10361 } 10362 }; 10363 return drawCallback; 10364 } 10365 ParseBorderColorProps(const JSRef<JSVal> & args,NG::BorderColorProperty & colorProperty)10366 bool JSViewAbstract::ParseBorderColorProps(const JSRef<JSVal>& args, NG::BorderColorProperty& colorProperty) 10367 { 10368 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) { 10369 return false; 10370 } 10371 Color borderColor; 10372 if (ParseJsColor(args, borderColor)) { 10373 colorProperty.SetColor(borderColor); 10374 return true; 10375 } else if (args->IsObject()) { 10376 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args); 10377 CommonColor commonColor; 10378 ParseCommonEdgeColors(obj, commonColor); 10379 colorProperty.topColor = commonColor.top; 10380 colorProperty.bottomColor = commonColor.bottom; 10381 colorProperty.leftColor = commonColor.left; 10382 colorProperty.rightColor = commonColor.right; 10383 colorProperty.multiValued = true; 10384 return true; 10385 } 10386 return false; 10387 } 10388 ParseBorderWidthProps(const JSRef<JSVal> & args,NG::BorderWidthProperty & borderWidthProperty)10389 bool JSViewAbstract::ParseBorderWidthProps(const JSRef<JSVal>& args, NG::BorderWidthProperty& borderWidthProperty) 10390 { 10391 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) { 10392 return false; 10393 } 10394 CalcDimension borderWidth; 10395 if (ParseJsDimensionVpNG(args, borderWidth, true)) { 10396 if (borderWidth.IsNegative()) { 10397 borderWidth.Reset(); 10398 } 10399 borderWidthProperty = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth }); 10400 return true; 10401 } else if (args->IsObject()) { 10402 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args); 10403 CommonCalcDimension commonCalcDimension; 10404 ParseCommonEdgeWidthsProps(obj, commonCalcDimension); 10405 borderWidthProperty.topDimen = commonCalcDimension.top; 10406 borderWidthProperty.bottomDimen = commonCalcDimension.bottom; 10407 borderWidthProperty.leftDimen = commonCalcDimension.left; 10408 borderWidthProperty.rightDimen = commonCalcDimension.right; 10409 borderWidthProperty.multiValued = true; 10410 return true; 10411 } 10412 return false; 10413 } 10414 ParseBorderStyleProps(const JSRef<JSVal> & args,NG::BorderStyleProperty & borderStyleProperty)10415 bool JSViewAbstract::ParseBorderStyleProps(const JSRef<JSVal>& args, NG::BorderStyleProperty& borderStyleProperty) 10416 { 10417 if (!args->IsObject() && !args->IsNumber()) { 10418 return false; 10419 } 10420 if (args->IsObject()) { 10421 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args); 10422 auto leftValue = obj->GetProperty("left"); 10423 if (!leftValue->IsUndefined() && leftValue->IsNumber()) { 10424 ConvertOptionBorderStyle(leftValue->ToNumber<int32_t>(), borderStyleProperty.styleLeft); 10425 } 10426 auto rightValue = obj->GetProperty("right"); 10427 if (!rightValue->IsUndefined() && rightValue->IsNumber()) { 10428 ConvertOptionBorderStyle(rightValue->ToNumber<int32_t>(), borderStyleProperty.styleRight); 10429 } 10430 auto topValue = obj->GetProperty("top"); 10431 if (!topValue->IsUndefined() && topValue->IsNumber()) { 10432 ConvertOptionBorderStyle(topValue->ToNumber<int32_t>(), borderStyleProperty.styleTop); 10433 } 10434 auto bottomValue = obj->GetProperty("bottom"); 10435 if (!bottomValue->IsUndefined() && bottomValue->IsNumber()) { 10436 ConvertOptionBorderStyle(bottomValue->ToNumber<int32_t>(), borderStyleProperty.styleBottom); 10437 } 10438 borderStyleProperty.multiValued = true; 10439 return true; 10440 } 10441 std::optional<BorderStyle> borderStyle; 10442 if (ConvertOptionBorderStyle(args->ToNumber<int32_t>(), borderStyle)) { 10443 borderStyleProperty = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle }); 10444 return true; 10445 } 10446 return false; 10447 } 10448 ParseBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10449 void JSViewAbstract::ParseBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius) 10450 { 10451 std::optional<CalcDimension> radiusTopLeft; 10452 std::optional<CalcDimension> radiusTopRight; 10453 std::optional<CalcDimension> radiusBottomLeft; 10454 std::optional<CalcDimension> radiusBottomRight; 10455 CalcDimension topLeft; 10456 if (ParseJsDimensionVpNG(object->GetProperty("topLeft"), topLeft, true)) { 10457 radiusTopLeft = topLeft; 10458 } 10459 CalcDimension topRight; 10460 if (ParseJsDimensionVpNG(object->GetProperty("topRight"), topRight, true)) { 10461 radiusTopRight = topRight; 10462 } 10463 CalcDimension bottomLeft; 10464 if (ParseJsDimensionVpNG(object->GetProperty("bottomLeft"), bottomLeft, true)) { 10465 radiusBottomLeft = bottomLeft; 10466 } 10467 CalcDimension bottomRight; 10468 if (ParseJsDimensionVpNG(object->GetProperty("bottomRight"), bottomRight, true)) { 10469 radiusBottomRight = bottomRight; 10470 } 10471 CheckLengthMetrics(object); 10472 radius.radiusTopLeft = radiusTopLeft; 10473 radius.radiusTopRight = radiusTopRight; 10474 radius.radiusBottomLeft = radiusBottomLeft; 10475 radius.radiusBottomRight = radiusBottomRight; 10476 radius.multiValued = true; 10477 return; 10478 } 10479 ParseCommonBorderRadiusProps(const JSRef<JSObject> & object,NG::BorderRadiusProperty & radius)10480 void JSViewAbstract::ParseCommonBorderRadiusProps(const JSRef<JSObject>& object, NG::BorderRadiusProperty& radius) 10481 { 10482 if (CheckLengthMetrics(object)) { 10483 std::optional<CalcDimension> radiusTopStart; 10484 std::optional<CalcDimension> radiusTopEnd; 10485 std::optional<CalcDimension> radiusBottomStart; 10486 std::optional<CalcDimension> radiusBottomEnd; 10487 if (object->HasProperty(TOP_START_PROPERTY) && object->GetProperty(TOP_START_PROPERTY)->IsObject()) { 10488 JSRef<JSObject> topStartObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_START_PROPERTY)); 10489 CalcDimension calcDimension; 10490 if (ParseJsLengthMetrics(topStartObj, calcDimension)) { 10491 CheckDimensionUnit(calcDimension, false, true); 10492 radiusTopStart = calcDimension; 10493 } 10494 } 10495 if (object->HasProperty(TOP_END_PROPERTY) && object->GetProperty(TOP_END_PROPERTY)->IsObject()) { 10496 JSRef<JSObject> topEndObj = JSRef<JSObject>::Cast(object->GetProperty(TOP_END_PROPERTY)); 10497 CalcDimension calcDimension; 10498 if (ParseJsLengthMetrics(topEndObj, calcDimension)) { 10499 CheckDimensionUnit(calcDimension, false, true); 10500 radiusTopEnd = calcDimension; 10501 } 10502 } 10503 if (object->HasProperty(BOTTOM_START_PROPERTY) && object->GetProperty(BOTTOM_START_PROPERTY)->IsObject()) { 10504 JSRef<JSObject> bottomStartObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_START_PROPERTY)); 10505 CalcDimension calcDimension; 10506 if (ParseJsLengthMetrics(bottomStartObj, calcDimension)) { 10507 CheckDimensionUnit(calcDimension, false, true); 10508 radiusBottomStart = calcDimension; 10509 } 10510 } 10511 if (object->HasProperty(BOTTOM_END_PROPERTY) && object->GetProperty(BOTTOM_END_PROPERTY)->IsObject()) { 10512 JSRef<JSObject> bottomEndObj = JSRef<JSObject>::Cast(object->GetProperty(BOTTOM_END_PROPERTY)); 10513 CalcDimension calcDimension; 10514 if (ParseJsLengthMetrics(bottomEndObj, calcDimension)) { 10515 CheckDimensionUnit(calcDimension, false, true); 10516 radiusBottomEnd = calcDimension; 10517 } 10518 } 10519 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft(); 10520 radius.radiusTopLeft = isRightToLeft ? radiusTopEnd : radiusTopStart; 10521 radius.radiusTopRight = isRightToLeft ? radiusTopStart : radiusTopEnd; 10522 radius.radiusBottomLeft = isRightToLeft ? radiusBottomEnd : radiusBottomStart; 10523 radius.radiusBottomRight = isRightToLeft ? radiusBottomStart : radiusBottomEnd; 10524 radius.multiValued = true; 10525 return; 10526 } 10527 ParseBorderRadiusProps(object, radius); 10528 } 10529 ParseBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)10530 bool JSViewAbstract::ParseBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius) 10531 { 10532 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) { 10533 return false; 10534 } 10535 CalcDimension borderRadius; 10536 if (ParseJsDimensionVpNG(args, borderRadius, true)) { 10537 radius = NG::BorderRadiusProperty(borderRadius); 10538 radius.multiValued = false; 10539 } else if (args->IsObject()) { 10540 JSRef<JSObject> object = JSRef<JSObject>::Cast(args); 10541 ParseCommonBorderRadiusProps(object, radius); 10542 } else { 10543 return false; 10544 } 10545 return true; 10546 } 10547 SetDragPreviewOptionApply(const JSCallbackInfo & info,NG::DragPreviewOption & option)10548 void JSViewAbstract::SetDragPreviewOptionApply(const JSCallbackInfo& info, NG::DragPreviewOption& option) 10549 { 10550 JSRef<JSVal> arg = info[0]; 10551 if (!arg->IsObject()) { 10552 return; 10553 } 10554 JSRef<JSObject> obj = JSRef<JSObject>::Cast(arg); 10555 auto vm = info.GetVm(); 10556 auto globalObj = JSNApi::GetGlobalObject(vm); 10557 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyImageModifierToNode")); 10558 JsiValue jsiValue(globalFunc); 10559 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue); 10560 if (globalFuncRef->IsFunction()) { 10561 auto modifierObj = obj->GetProperty("modifier"); 10562 if (modifierObj->IsUndefined()) { 10563 option.onApply = nullptr; 10564 } else { 10565 RefPtr<JsFunction> jsFunc = 10566 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef)); 10567 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), 10568 modifier = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) { 10569 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 10570 auto node = frameNode.Upgrade(); 10571 JSRef<JSVal> params[PARAMETER_LENGTH_SECOND]; 10572 params[0] = modifier; 10573 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node))); 10574 PipelineContext::SetCallBackNode(node); 10575 func->ExecuteJS(PARAMETER_LENGTH_SECOND, params); 10576 }; 10577 option.onApply = onApply; 10578 } 10579 } 10580 } 10581 SetDragNumberBadge(const JSCallbackInfo & info,NG::DragPreviewOption & option)10582 void JSViewAbstract::SetDragNumberBadge(const JSCallbackInfo& info, NG::DragPreviewOption& option) 10583 { 10584 if (!info[0]->IsObject()) { 10585 return; 10586 } 10587 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]); 10588 auto numberBadge = obj->GetProperty("numberBadge"); 10589 if (!numberBadge->IsEmpty()) { 10590 if (numberBadge->IsNumber()) { 10591 int64_t number = numberBadge->ToNumber<int64_t>(); 10592 if (number < 0 || number > INT_MAX) { 10593 option.isNumber = false; 10594 option.isShowBadge = true; 10595 } else { 10596 option.isNumber = true; 10597 option.badgeNumber = numberBadge->ToNumber<int>(); 10598 } 10599 } else if (numberBadge->IsBoolean()) { 10600 option.isNumber = false; 10601 option.isShowBadge = numberBadge->ToBoolean(); 10602 } 10603 } else { 10604 option.isNumber = false; 10605 option.isShowBadge = true; 10606 } 10607 } 10608 SetDialogProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10609 void JSViewAbstract::SetDialogProperties(const JSRef<JSObject>& obj, DialogProperties& properties) 10610 { 10611 // Parse cornerRadius. 10612 auto cornerRadiusValue = obj->GetProperty("cornerRadius"); 10613 NG::BorderRadiusProperty radius; 10614 if (ParseBorderRadius(cornerRadiusValue, radius)) { 10615 properties.borderRadius = radius; 10616 } 10617 // Parse border width 10618 auto borderWidthValue = obj->GetProperty("borderWidth"); 10619 NG::BorderWidthProperty borderWidth; 10620 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) { 10621 properties.borderWidth = borderWidth; 10622 auto colorValue = obj->GetProperty("borderColor"); 10623 NG::BorderColorProperty borderColor; 10624 if (ParseBorderColorProps(colorValue, borderColor)) { 10625 properties.borderColor = borderColor; 10626 } else { 10627 borderColor.SetColor(Color::BLACK); 10628 properties.borderColor = borderColor; 10629 } 10630 // Parse border style 10631 auto styleValue = obj->GetProperty("borderStyle"); 10632 NG::BorderStyleProperty borderStyle; 10633 if (ParseBorderStyleProps(styleValue, borderStyle)) { 10634 properties.borderStyle = borderStyle; 10635 } else { 10636 properties.borderStyle = NG::BorderStyleProperty( 10637 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID }); 10638 } 10639 } 10640 auto shadowValue = obj->GetProperty("shadow"); 10641 Shadow shadow; 10642 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) { 10643 properties.shadow = shadow; 10644 } 10645 auto widthValue = obj->GetProperty("width"); 10646 CalcDimension width; 10647 if (ParseJsDimensionVpNG(widthValue, width, true)) { 10648 properties.width = width; 10649 } 10650 auto heightValue = obj->GetProperty("height"); 10651 CalcDimension height; 10652 if (ParseJsDimensionVpNG(heightValue, height, true)) { 10653 properties.height = height; 10654 } 10655 } 10656 SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)10657 void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties) 10658 { 10659 auto enableHoverModeValue = obj->GetProperty("enableHoverMode"); 10660 if (enableHoverModeValue->IsBoolean()) { 10661 properties.enableHoverMode = enableHoverModeValue->ToBoolean(); 10662 } 10663 10664 // Parse hoverModeArea 10665 auto hoverModeAreaValue = obj->GetProperty("hoverModeArea"); 10666 if (hoverModeAreaValue->IsNumber()) { 10667 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>(); 10668 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) { 10669 properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea]; 10670 } 10671 } 10672 } 10673 ParseJsGetFunc(const JSCallbackInfo & info,int32_t nodeId)10674 std::function<std::string(const std::string&)> ParseJsGetFunc(const JSCallbackInfo& info, int32_t nodeId) 10675 { 10676 auto* vm = info.GetVm(); 10677 return [vm, nodeId](const std::string& key) -> std::string { 10678 std::string resultString = std::string(); 10679 CHECK_NULL_RETURN(vm, resultString); 10680 panda::LocalScope scope(vm); 10681 auto global = JSNApi::GetGlobalObject(vm); 10682 auto getCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__getCustomPropertyString__")); 10683 if (getCustomProperty->IsUndefined() || !getCustomProperty->IsFunction(vm)) { 10684 return resultString; 10685 } 10686 auto obj = getCustomProperty->ToObject(vm); 10687 panda::Local<panda::FunctionRef> func = obj; 10688 panda::Local<panda::JSValueRef> params2[2] = { panda::NumberRef::New(vm, nodeId), 10689 panda::StringRef::NewFromUtf8(vm, key.c_str()) }; 10690 auto function = panda::CopyableGlobal(vm, func); 10691 auto callValue = function->Call(vm, function.ToLocal(), params2, 2); 10692 if (callValue.IsNull() || callValue->IsUndefined() || !callValue->IsString(vm)) { 10693 return resultString; 10694 } 10695 auto value = callValue->ToString(vm)->ToString(vm); 10696 return value; 10697 }; 10698 } 10699 ParseJsFunc(const JSCallbackInfo & info,int32_t nodeId)10700 std::function<bool()> ParseJsFunc(const JSCallbackInfo& info, int32_t nodeId) 10701 { 10702 auto* vm = info.GetVm(); 10703 panda::Local<panda::JSValueRef> params3[3] = { panda::NumberRef::New(vm, nodeId), info[0]->GetLocalHandle(), 10704 info[1]->GetLocalHandle() }; 10705 return [vm, params3]() -> bool { 10706 CHECK_NULL_RETURN(vm, false); 10707 panda::LocalScope scope(vm); 10708 auto global = JSNApi::GetGlobalObject(vm); 10709 auto setCustomProperty = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__setCustomProperty__")); 10710 if (setCustomProperty->IsUndefined() || !setCustomProperty->IsFunction(vm)) { 10711 return false; 10712 } 10713 auto obj = setCustomProperty->ToObject(vm); 10714 panda::Local<panda::FunctionRef> func = obj; 10715 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode()); 10716 auto nodeId = frameNode->GetId(); 10717 auto function = panda::CopyableGlobal(vm, func); 10718 auto customPropertyExisted = function->Call(vm, function.ToLocal(), params3, 3)->ToBoolean(vm)->Value(); 10719 if (customPropertyExisted) { 10720 frameNode->SetRemoveCustomProperties([vm, nodeId]() -> void { 10721 CHECK_NULL_VOID(vm); 10722 panda::LocalScope scope(vm); 10723 auto global = JSNApi::GetGlobalObject(vm); 10724 auto removeCustomProperty = 10725 global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__removeCustomProperties__")); 10726 if (removeCustomProperty->IsUndefined() || !removeCustomProperty->IsFunction(vm)) { 10727 return; 10728 } 10729 auto obj = removeCustomProperty->ToObject(vm); 10730 panda::Local<panda::FunctionRef> func = obj; 10731 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, nodeId) }; 10732 auto function = panda::CopyableGlobal(vm, func); 10733 function->Call(vm, function.ToLocal(), params, 1); 10734 }); 10735 } 10736 return true; 10737 }; 10738 } 10739 JsCustomProperty(const JSCallbackInfo & info)10740 void JSViewAbstract::JsCustomProperty(const JSCallbackInfo& info) 10741 { 10742 if (info[0]->GetLocalHandle()->IsUndefined()) { 10743 return; 10744 } 10745 auto* vm = info.GetVm(); 10746 CHECK_NULL_VOID(vm); 10747 auto frameNode = static_cast<NG::FrameNode*>(ViewAbstractModel::GetInstance()->GetFrameNode()); 10748 auto nodeId = frameNode->GetId(); 10749 auto getFunc = ParseJsGetFunc(info, nodeId); 10750 auto func = ParseJsFunc(info, nodeId); 10751 frameNode->SetJSCustomProperty(func, getFunc); 10752 } 10753 JsGestureModifier(const JSCallbackInfo & info)10754 void JSViewAbstract::JsGestureModifier(const JSCallbackInfo& info) 10755 { 10756 auto* vm = info.GetExecutionContext().vm_; 10757 CHECK_NULL_VOID(vm); 10758 auto global = JSNApi::GetGlobalObject(vm); 10759 auto gestureModifier = global->Get(vm, panda::StringRef::NewFromUtf8(vm, "__gestureModifier__")); 10760 if (gestureModifier->IsUndefined() || !gestureModifier->IsFunction(vm)) { 10761 return; 10762 } 10763 auto obj = gestureModifier->ToObject(vm); 10764 panda::Local<panda::FunctionRef> func = obj; 10765 auto thisObj = info.This()->GetLocalHandle(); 10766 panda::Local<panda::JSValueRef> params[1] = { info[0]->GetLocalHandle() }; 10767 func->Call(vm, thisObj, params, 1); 10768 } 10769 JsBackgroundImageResizable(const JSCallbackInfo & info)10770 void JSViewAbstract::JsBackgroundImageResizable(const JSCallbackInfo& info) 10771 { 10772 auto infoObj = info[0]; 10773 ImageResizableSlice sliceResult; 10774 if (!infoObj->IsObject()) { 10775 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult); 10776 return; 10777 } 10778 JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj); 10779 if (resizableObject->IsEmpty()) { 10780 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult); 10781 return; 10782 } 10783 auto sliceValue = resizableObject->GetProperty("slice"); 10784 if (!sliceValue->IsObject()) { 10785 return; 10786 } 10787 JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue); 10788 if (sliceObj->IsEmpty()) { 10789 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult); 10790 return; 10791 } 10792 for (uint32_t i = 0; i < SLICE_KEYS.size(); i++) { 10793 auto sliceSize = sliceObj->GetProperty(SLICE_KEYS.at(i).c_str()); 10794 CalcDimension sliceDimension; 10795 if (!ParseJsDimensionVp(sliceSize, sliceDimension)) { 10796 continue; 10797 } 10798 if (!sliceDimension.IsValid()) { 10799 continue; 10800 } 10801 switch (static_cast<BorderImageDirection>(i)) { 10802 case BorderImageDirection::LEFT: 10803 sliceResult.left = sliceDimension; 10804 break; 10805 case BorderImageDirection::RIGHT: 10806 sliceResult.right = sliceDimension; 10807 break; 10808 case BorderImageDirection::TOP: 10809 sliceResult.top = sliceDimension; 10810 break; 10811 case BorderImageDirection::BOTTOM: 10812 sliceResult.bottom = sliceDimension; 10813 break; 10814 default: 10815 break; 10816 } 10817 } 10818 ViewAbstractModel::GetInstance()->SetBackgroundImageResizableSlice(sliceResult); 10819 } 10820 JsFocusScopeId(const JSCallbackInfo & info)10821 void JSViewAbstract::JsFocusScopeId(const JSCallbackInfo& info) 10822 { 10823 if (info.Length() == 0) { 10824 return; 10825 } 10826 10827 std::string focusScopeId; 10828 if (info[0]->IsString()) { 10829 focusScopeId = info[0]->ToString(); 10830 } 10831 10832 bool isGroup = false; 10833 if (info.Length() >= PARAMETER_LENGTH_SECOND && !info[1]->IsNull() && !info[1]->IsUndefined() && 10834 info[1]->IsBoolean()) { 10835 isGroup = info[1]->ToBoolean(); 10836 } 10837 bool arrowKeyStepOut = true; 10838 if (info.Length() >= PARAMETER_LENGTH_THIRD && !info[2]->IsNull() && !info[2]->IsUndefined() && 10839 info[2]->IsBoolean()) { 10840 arrowKeyStepOut = info[2]->ToBoolean(); 10841 } 10842 ViewAbstractModel::GetInstance()->SetFocusScopeId(focusScopeId, isGroup, arrowKeyStepOut); 10843 } 10844 JsFocusScopePriority(const JSCallbackInfo & info)10845 void JSViewAbstract::JsFocusScopePriority(const JSCallbackInfo& info) 10846 { 10847 if (info.Length() == 0) { 10848 return; 10849 } 10850 10851 if (!info[0]->IsString() || info[0]->IsNull() || info[0]->IsUndefined()) { 10852 return; 10853 } 10854 std::string focusScopeId = info[0]->ToString(); 10855 10856 int32_t focusPriority = 0; 10857 if (info.Length() == PARAMETER_LENGTH_SECOND && !info[0]->IsNull() && !info[0]->IsUndefined() && 10858 info[1]->IsNumber()) { 10859 focusPriority = info[1]->ToNumber<int32_t>(); 10860 } 10861 ViewAbstractModel::GetInstance()->SetFocusScopePriority(focusScopeId, focusPriority); 10862 } 10863 ParseJsPropertyId(const JSRef<JSVal> & jsValue)10864 int32_t JSViewAbstract::ParseJsPropertyId(const JSRef<JSVal>& jsValue) 10865 { 10866 int32_t resId = 0; 10867 if (jsValue->IsObject()) { 10868 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue); 10869 JSRef<JSVal> tmp = jsObj->GetProperty("id"); 10870 if (!tmp->IsNull() && tmp->IsNumber()) { 10871 resId = tmp->ToNumber<int32_t>(); 10872 } 10873 } 10874 return resId; 10875 } 10876 JsVisualEffect(const JSCallbackInfo & info)10877 void JSViewAbstract::JsVisualEffect(const JSCallbackInfo& info) 10878 { 10879 if (!info[0]->IsObject()) { 10880 return; 10881 } 10882 auto visualEffect = CreateRSEffectFromNapiValue(info[0]); 10883 ViewAbstractModel::GetInstance()->SetVisualEffect(visualEffect); 10884 } 10885 JsBackgroundFilter(const JSCallbackInfo & info)10886 void JSViewAbstract::JsBackgroundFilter(const JSCallbackInfo& info) 10887 { 10888 if (!info[0]->IsObject()) { 10889 return; 10890 } 10891 auto backgroundFilter = CreateRSFilterFromNapiValue(info[0]); 10892 ViewAbstractModel::GetInstance()->SetBackgroundFilter(backgroundFilter); 10893 } 10894 JsForegroundFilter(const JSCallbackInfo & info)10895 void JSViewAbstract::JsForegroundFilter(const JSCallbackInfo& info) 10896 { 10897 if (!info[0]->IsObject()) { 10898 return; 10899 } 10900 auto foregroundFilter = CreateRSFilterFromNapiValue(info[0]); 10901 ViewAbstractModel::GetInstance()->SetForegroundFilter(foregroundFilter); 10902 } 10903 JsCompositingFilter(const JSCallbackInfo & info)10904 void JSViewAbstract::JsCompositingFilter(const JSCallbackInfo& info) 10905 { 10906 if (!info[0]->IsObject()) { 10907 return; 10908 } 10909 auto compositingFilter = CreateRSFilterFromNapiValue(info[0]); 10910 ViewAbstractModel::GetInstance()->SetCompositingFilter(compositingFilter); 10911 } 10912 ParseOnCreateMenu(const JSCallbackInfo & info,const JSRef<JSVal> & jsFunc,NG::OnCreateMenuCallback & onCreateMenuCallback)10913 void JSViewAbstract::ParseOnCreateMenu( 10914 const JSCallbackInfo& info, const JSRef<JSVal>& jsFunc, NG::OnCreateMenuCallback& onCreateMenuCallback) 10915 { 10916 if (jsFunc.IsEmpty() || !jsFunc->IsFunction()) { 10917 return; 10918 } 10919 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 10920 auto jsOnCreateMenu = AceType::MakeRefPtr<JsEventFunction<std::vector<NG::MenuItemParam>, 1>>( 10921 JSRef<JSFunc>::Cast(jsFunc), CreateJsSystemMenuItems); 10922 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnCreateMenu), 10923 instanceId = Container::CurrentId(), node = frameNode]( 10924 const std::vector<NG::MenuItemParam>& systemMenuItems) -> std::vector<NG::MenuOptionsParam> { 10925 ContainerScope scope(instanceId); 10926 std::vector<NG::MenuOptionsParam> menuParams; 10927 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, menuParams); 10928 auto pipelineContext = PipelineContext::GetCurrentContext(); 10929 CHECK_NULL_RETURN(pipelineContext, menuParams); 10930 10931 pipelineContext->UpdateCurrentActiveNode(node); 10932 auto menuItem = func->ExecuteWithValue(systemMenuItems); 10933 if (!menuItem->IsArray()) { 10934 return menuParams; 10935 } 10936 auto menuItemsArray = JSRef<JSArray>::Cast(menuItem); 10937 for (size_t i = 0; i <= menuItemsArray->Length(); i++) { 10938 auto menuItem = menuItemsArray->GetValueAt(i); 10939 if (!menuItem->IsObject()) { 10940 continue; 10941 } 10942 auto menuItemObject = JSRef<JSObject>::Cast(menuItem); 10943 NG::MenuOptionsParam menuOptionsParam; 10944 auto jsContent = menuItemObject->GetProperty("content"); 10945 std::string content; 10946 ParseJsString(jsContent, content); 10947 menuOptionsParam.content = content; 10948 auto jsStartIcon = menuItemObject->GetProperty("icon"); 10949 std::string icon; 10950 ParseJsMedia(jsStartIcon, icon); 10951 menuOptionsParam.icon = icon; 10952 auto jsTextMenuId = menuItemObject->GetProperty("id"); 10953 std::string id; 10954 if (jsTextMenuId->IsObject()) { 10955 auto textMenuIdObject = JSRef<JSObject>::Cast(jsTextMenuId); 10956 auto jsId = textMenuIdObject->GetProperty("id_"); 10957 ParseJsString(jsId, id); 10958 } 10959 menuOptionsParam.id = id; 10960 menuParams.emplace_back(menuOptionsParam); 10961 } 10962 return menuParams; 10963 }; 10964 onCreateMenuCallback = jsCallback; 10965 } 10966 CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam> & systemMenuItems)10967 JSRef<JSVal> JSViewAbstract::CreateJsSystemMenuItems(const std::vector<NG::MenuItemParam>& systemMenuItems) 10968 { 10969 JSRef<JSArray> systemMenuItemsArray = JSRef<JSArray>::New(); 10970 uint32_t idx = 0; 10971 for (const auto& item : systemMenuItems) { 10972 systemMenuItemsArray->SetValueAt(idx++, CreateJsTextMenuItem(item)); 10973 } 10974 return systemMenuItemsArray; 10975 } 10976 ParseEditMenuOptions(const JSCallbackInfo & info,NG::OnCreateMenuCallback & onCreateMenuCallback,NG::OnMenuItemClickCallback & onMenuItemClick)10977 bool JSViewAbstract::ParseEditMenuOptions(const JSCallbackInfo& info, NG::OnCreateMenuCallback& onCreateMenuCallback, 10978 NG::OnMenuItemClickCallback& onMenuItemClick) 10979 { 10980 auto tmpInfo = info[0]; 10981 if (info.Length() != 1 || !tmpInfo->IsObject()) { 10982 return false; 10983 } 10984 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); 10985 auto menuOptionsObject = JSRef<JSObject>::Cast(tmpInfo); 10986 auto jsValueOnCreateMenu = menuOptionsObject->GetProperty("onCreateMenu"); 10987 ParseOnCreateMenu(info, jsValueOnCreateMenu, onCreateMenuCallback); 10988 10989 auto jsValue = menuOptionsObject->GetProperty("onMenuItemClick"); 10990 if (jsValue.IsEmpty() || !jsValue->IsFunction()) { 10991 return false; 10992 } 10993 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(jsValue)); 10994 auto jsCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), 10995 onMenuItemCallback = std::move(CreateJsOnMenuItemClick), instanceId = Container::CurrentId(), 10996 node = frameNode](NG::MenuItemParam menuOptionsParam) -> bool { 10997 ContainerScope scope(instanceId); 10998 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false); 10999 auto pipelineContext = PipelineContext::GetCurrentContext(); 11000 CHECK_NULL_RETURN(pipelineContext, false); 11001 pipelineContext->UpdateCurrentActiveNode(node); 11002 auto paramArray = onMenuItemCallback(menuOptionsParam); 11003 if (paramArray->Length() != 2) { 11004 return false; 11005 } 11006 JSRef<JSVal> params[2]; 11007 params[0] = JSRef<JSVal>::Cast(paramArray->GetValueAt(0)); 11008 params[1] = JSRef<JSVal>::Cast(paramArray->GetValueAt(1)); 11009 auto ret = func->ExecuteJS(2, params); 11010 if (ret->IsBoolean()) { 11011 return ret->ToBoolean(); 11012 } 11013 return false; 11014 }; 11015 onMenuItemClick = jsCallback; 11016 return true; 11017 } 11018 CreateJsTextMenuId(const std::string & id)11019 JSRef<JSObject> JSViewAbstract::CreateJsTextMenuId(const std::string& id) 11020 { 11021 JSRef<JSObject> empty; 11022 auto engine = EngineHelper::GetCurrentEngine(); 11023 CHECK_NULL_RETURN(engine, empty); 11024 NativeEngine* nativeEngine = engine->GetNativeEngine(); 11025 CHECK_NULL_RETURN(nativeEngine, empty); 11026 auto env = reinterpret_cast<napi_env>(nativeEngine); 11027 11028 napi_value global; 11029 napi_status ret = napi_get_global(env, &global); 11030 if (ret != napi_ok) { 11031 return empty; 11032 } 11033 napi_value constructor; 11034 ret = napi_get_named_property(env, global, JS_TEXT_MENU_ID_CLASS_NAME, &constructor); 11035 if (ret != napi_ok) { 11036 return empty; 11037 } 11038 11039 napi_value obj; 11040 napi_value menuId = nullptr; 11041 11042 ret = napi_create_string_utf8(env, id.c_str(), id.length(), &menuId); 11043 if (ret != napi_ok) { 11044 return empty; 11045 } 11046 ret = napi_new_instance(env, constructor, NUM1, &menuId, &obj); 11047 if (ret != napi_ok) { 11048 return empty; 11049 } 11050 11051 JSRef<JSVal> value = JsConverter::ConvertNapiValueToJsVal(obj); 11052 if (!value->IsObject()) { 11053 return empty; 11054 } 11055 11056 return JSRef<JSObject>::Cast(value); 11057 } 11058 CreateJsOnMenuItemClick(const NG::MenuItemParam & menuItemParam)11059 JSRef<JSArray> JSViewAbstract::CreateJsOnMenuItemClick(const NG::MenuItemParam& menuItemParam) 11060 { 11061 JSRef<JSArray> params = JSRef<JSArray>::New(); 11062 params->SetValueAt(0, CreateJsTextMenuItem(menuItemParam)); 11063 params->SetValueAt(1, CreateJsTextRange(menuItemParam)); 11064 return params; 11065 } 11066 CreateJsTextMenuItem(const NG::MenuItemParam & menuItemParam)11067 JSRef<JSVal> JSViewAbstract::CreateJsTextMenuItem(const NG::MenuItemParam& menuItemParam) 11068 { 11069 JSRef<JSObject> TextMenuItem = JSRef<JSObject>::New(); 11070 TextMenuItem->SetProperty<std::string>("content", menuItemParam.menuOptionsParam.content.value_or("")); 11071 JSRef<JSObject> obj = CreateJsTextMenuId(menuItemParam.menuOptionsParam.id); 11072 TextMenuItem->SetPropertyObject("id", obj); 11073 return JSRef<JSVal>::Cast(TextMenuItem); 11074 } 11075 CreateJsTextRange(const NG::MenuItemParam & menuItemParam)11076 JSRef<JSVal> JSViewAbstract::CreateJsTextRange(const NG::MenuItemParam& menuItemParam) 11077 { 11078 JSRef<JSObject> textRange = JSRef<JSObject>::New(); 11079 textRange->SetProperty<int32_t>("start", menuItemParam.start); 11080 textRange->SetProperty<int32_t>("end", menuItemParam.end); 11081 return JSRef<JSVal>::Cast(textRange); 11082 } 11083 OHOS_ACE_ParseJsMedia(void * value,void * resource)11084 extern "C" ACE_FORCE_EXPORT void OHOS_ACE_ParseJsMedia(void* value, void* resource) 11085 { 11086 napi_value napiValue = reinterpret_cast<napi_value>(value); 11087 ArkUI_Resource* res = reinterpret_cast<ArkUI_Resource*>(resource); 11088 if (!napiValue || !res) { 11089 return; 11090 } 11091 JSRef<JSVal> jsVal = JsConverter::ConvertNapiValueToJsVal(napiValue); 11092 std::string src; 11093 std::string bundleName; 11094 std::string moduleName; 11095 JSViewAbstract::ParseJsMedia(jsVal, src); 11096 JSViewAbstract::GetJsMediaBundleInfo(jsVal, bundleName, moduleName); 11097 res->resId = JSViewAbstract::ParseJsPropertyId(jsVal); 11098 res->src = src; 11099 res->bundleName = bundleName; 11100 res->moduleName = moduleName; 11101 } 11102 SetTextStyleApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & textStyleApply,const JSRef<JSVal> & modifierObj)11103 void JSViewAbstract::SetTextStyleApply(const JSCallbackInfo& info, 11104 std::function<void(WeakPtr<NG::FrameNode>)>& textStyleApply, const JSRef<JSVal>& modifierObj) 11105 { 11106 if (!modifierObj->IsObject()) { 11107 textStyleApply = nullptr; 11108 return; 11109 } 11110 auto vm = info.GetVm(); 11111 auto globalObj = JSNApi::GetGlobalObject(vm); 11112 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applyTextModifierToNode")); 11113 JsiValue jsiValue(globalFunc); 11114 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue); 11115 if (!globalFuncRef->IsFunction()) { 11116 textStyleApply = nullptr; 11117 return; 11118 } 11119 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef)); 11120 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), 11121 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) { 11122 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 11123 auto node = frameNode.Upgrade(); 11124 CHECK_NULL_VOID(node); 11125 JSRef<JSVal> params[2]; 11126 params[0] = modifierParam; 11127 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node))); 11128 PipelineContext::SetCallBackNode(node); 11129 func->ExecuteJS(2, params); 11130 }; 11131 textStyleApply = onApply; 11132 } 11133 SetSymbolOptionApply(const JSCallbackInfo & info,std::function<void (WeakPtr<NG::FrameNode>)> & symbolApply,const JSRef<JSVal> modifierObj)11134 void JSViewAbstract::SetSymbolOptionApply(const JSCallbackInfo& info, 11135 std::function<void(WeakPtr<NG::FrameNode>)>& symbolApply, const JSRef<JSVal> modifierObj) 11136 { 11137 auto vm = info.GetVm(); 11138 auto globalObj = JSNApi::GetGlobalObject(vm); 11139 auto globalFunc = globalObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "applySymbolGlyphModifierToNode")); 11140 JsiValue jsiValue(globalFunc); 11141 JsiRef<JsiValue> globalFuncRef = JsiRef<JsiValue>::Make(jsiValue); 11142 if (globalFuncRef->IsFunction()) { 11143 RefPtr<JsFunction> jsFunc = 11144 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(globalFuncRef)); 11145 if (!modifierObj->IsObject()) { 11146 symbolApply = nullptr; 11147 } else { 11148 auto onApply = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), 11149 modifierParam = std::move(modifierObj)](WeakPtr<NG::FrameNode> frameNode) { 11150 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); 11151 auto node = frameNode.Upgrade(); 11152 CHECK_NULL_VOID(node); 11153 JSRef<JSVal> params[2]; 11154 params[0] = modifierParam; 11155 params[1] = JSRef<JSVal>::Make(panda::NativePointerRef::New(execCtx.vm_, AceType::RawPtr(node))); 11156 PipelineContext::SetCallBackNode(node); 11157 func->ExecuteJS(2, params); 11158 }; 11159 symbolApply = onApply; 11160 } 11161 } 11162 } 11163 } // namespace OHOS::Ace::Framework 11164