1 /*
2 * Copyright (c) 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 "base/utils/utils.h"
17 #include "base/utils/string_utils.h"
18 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
19
20 #include "base/log/ace_scoring_log.h"
21 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
22 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
23 #include "bridge/declarative_frontend/jsview/js_view_context.h"
24 #include "bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h"
25 #include "core/components/popup/popup_theme.h"
26 #include "core/components_ng/base/view_abstract_model_ng.h"
27 #include "core/components_ng/base/view_stack_model.h"
28 #include "core/components_ng/pattern/text/span/span_string.h"
29
30 #include "bridge/declarative_frontend/jsview/js_popups.h"
31 #include "bridge/declarative_frontend/style_string/js_span_string.h"
32 #include "core/common/resource/resource_parse_utils.h"
33
34 namespace OHOS::Ace::Framework {
35 namespace {
36 constexpr int32_t PARAMETER_LENGTH_ZERO = 0;
37 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
38 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
39 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
40 constexpr int NUM_ZERO = 0;
41 constexpr int NUM_FIRST = 1;
42 constexpr int NUM_SECOND = 2;
43 constexpr int32_t TRANSITION_NUM_ZERO = 0;
44 constexpr int32_t TRANSITION_NUM_TWO = 2;
45 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
46 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
47 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
48 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
49 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
50 const std::string SHEET_HEIGHT_MEDIUM = "medium";
51 const std::string SHEET_HEIGHT_LARGE = "large";
52 const std::string SHEET_HEIGHT_AUTO = "auto";
53 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
54 constexpr int HAPTIC_FEEDBACK_MODE_ENABLED = 1;
55 constexpr int HAPTIC_FEEDBACK_MODE_AUTO = 2;
56 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
57 HoverModeAreaType::BOTTOM_SCREEN };
58 }
59 constexpr int32_t OUTER_BORDER_WIDTH = 0;
60 constexpr int32_t INNER_BORDER_WIDTH = 1;
61 constexpr int32_t OUTER_BORDER_LINEAR_GRADIENT = 0;
62 constexpr int32_t INNER_BORDER_LINEAR_GRADIENT = 1;
63 const std::vector<std::string> BORDER_WIDTH_TYPE = {"outlineWidth", "borderWidth"};
64 const std::vector<std::string> BORDER_LINEAR_GRADIENT_TYPE = {"outlineLinearGradient", "borderLinearGradient"};
65
66 const char* START_PROPERTY = "start";
67 const char* END_PROPERTY = "end";
68 const char* TOP_PROPERTY = "top";
69 const char* BOTTOM_PROPERTY = "bottom";
70 const char* LEFT_PROPERTY = "left";
71 const char* RIGHT_PROPERTY = "right";
72 const char* TOP_START_PROPERTY = "topStart";
73 const char* TOP_END_PROPERTY = "topEnd";
74 const char* TOP_LEFT_PROPERTY = "topLeft";
75 const char* TOP_RIGHT_PROPERTY = "topRight";
76 const char* BOTTOM_START_PROPERTY = "bottomStart";
77 const char* BOTTOM_END_PROPERTY = "bottomEnd";
78 const char* BOTTOM_LEFT_PROPERTY = "bottomLeft";
79 const char* BOTTOM_RIGHT_PROPERTY = "bottomRight";
80
81 using DoubleBindCallback = std::function<void(const std::string&)>;
82
83 #ifndef WEARABLE_PRODUCT
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj,const char * arrowFuncName)84 DoubleBindCallback JSViewPopups::ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj,
85 const char* arrowFuncName)
86 {
87 JSRef<JSVal> arrowFunc = callbackObj->GetProperty(arrowFuncName);
88 if (!arrowFunc->IsFunction()) {
89 return {};
90 }
91 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(arrowFunc));
92 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
93 auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
94 const std::string& param) {
95 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
96 if (param != "true" && param != "false") {
97 return;
98 }
99 PipelineContext::SetCallBackNode(node);
100 bool newValue = StringToBool(param);
101 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
102 func->ExecuteJS(1, &newJSVal);
103 };
104 return callback;
105 }
106
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)107 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
108 {
109 auto colorValue = messageOptionsObj->GetProperty("textColor");
110 Color textColor;
111 if (SystemProperties::ConfigChangePerform()) {
112 RefPtr<ResourceObject> resObj;
113 if (JSViewAbstract::ParseJsColor(colorValue, textColor, resObj)) {
114 if (popupParam) {
115 popupParam->SetTextColorResourceObject(resObj);
116 popupParam->SetTextColor(textColor);
117 }
118 }
119 } else {
120 if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
121 if (popupParam) {
122 popupParam->SetTextColor(textColor);
123 }
124 }
125 }
126
127 auto font = messageOptionsObj->GetProperty("font");
128 if (!font->IsNull() && font->IsObject()) {
129 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
130 auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
131 CalcDimension fontSize;
132 if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
133 if (popupParam && fontSize.IsValid()) {
134 popupParam->SetFontSize(fontSize);
135 }
136 }
137 auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
138 if (fontWeightValue->IsString()) {
139 if (popupParam) {
140 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
141 }
142 }
143 auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
144 if (fontStyleValue->IsNumber()) {
145 int32_t value = fontStyleValue->ToNumber<int32_t>();
146 if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
147 return;
148 }
149 if (popupParam) {
150 popupParam->SetFontStyle(FONT_STYLES[value]);
151 }
152 }
153 }
154 }
155
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)156 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
157 {
158 JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
159 if (placementOnTopVal->IsBoolean() && popupParam) {
160 popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
161 }
162 }
163
IsPopupCreated()164 bool IsPopupCreated()
165 {
166 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
167 CHECK_NULL_RETURN(targetNode, false);
168 auto targetId = targetNode->GetId();
169 auto container = Container::Current();
170 CHECK_NULL_RETURN(container, false);
171 auto pipelineContext = container->GetPipelineContext();
172 CHECK_NULL_RETURN(pipelineContext, false);
173 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
174 CHECK_NULL_RETURN(context, false);
175 auto overlayManager = context->GetOverlayManager();
176 CHECK_NULL_RETURN(overlayManager, false);
177 auto popupInfo = overlayManager->GetPopupInfo(targetId);
178 if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
179 return false;
180 }
181 return true;
182 }
183
GetPopupDefaultShadowStyle()184 ShadowStyle GetPopupDefaultShadowStyle()
185 {
186 auto shadowStyle = ShadowStyle::OuterDefaultMD;
187 auto container = Container::Current();
188 CHECK_NULL_RETURN(container, shadowStyle);
189 auto pipelineContext = container->GetPipelineContext();
190 CHECK_NULL_RETURN(pipelineContext, shadowStyle);
191 auto popupTheme = pipelineContext->GetTheme<PopupTheme>();
192 CHECK_NULL_RETURN(popupTheme, shadowStyle);
193 return popupTheme->GetPopupShadowStyle();
194 }
195
GetBlurStyleFromTheme(const RefPtr<PopupParam> & popupParam)196 static void GetBlurStyleFromTheme(const RefPtr<PopupParam>& popupParam)
197 {
198 CHECK_NULL_VOID(popupParam);
199 auto pipelineContext = PipelineContext::GetCurrentContext();
200 CHECK_NULL_VOID(pipelineContext);
201 auto theme = pipelineContext->GetTheme<PopupTheme>();
202 CHECK_NULL_VOID(theme);
203 auto blurStyle = static_cast<BlurStyle>(theme->GetPopupBackgroundBlurStyle());
204 popupParam->SetBlurStyle(blurStyle);
205 }
206
SetBorderLinearGradientDirection(const JSRef<JSObject> & obj,PopupLinearGradientProperties & popupBorderLinearGradient)207 void SetBorderLinearGradientDirection(const JSRef<JSObject>& obj,
208 PopupLinearGradientProperties& popupBorderLinearGradient)
209 {
210 popupBorderLinearGradient.popupDirection = GradientDirection::BOTTOM;
211 auto directionValue = obj->GetProperty("direction");
212 if (directionValue->IsNumber()) {
213 auto gradientDirection = directionValue->ToNumber<int32_t>();
214 if (gradientDirection >= static_cast<int32_t>(GradientDirection::LEFT) &&
215 gradientDirection <= static_cast<int32_t>(GradientDirection::END_TO_START)) {
216 popupBorderLinearGradient.popupDirection = static_cast<GradientDirection>(gradientDirection);
217 }
218 }
219 }
220
ParseGradientColor(const JSRef<JSArray> & colorArray,PopupGradientColor & gradientColor)221 void ParseGradientColor(const JSRef<JSArray>& colorArray, PopupGradientColor& gradientColor)
222 {
223 Color gradientColorItem;
224 auto colorVal = colorArray->GetValueAt(0);
225 if (JSViewAbstract::ParseJsColor(colorVal, gradientColorItem)) {
226 gradientColor.gradientColor = gradientColorItem;
227 }
228 if (colorArray->GetValueAt(1)->IsNumber()) {
229 gradientColor.gradientNumber = colorArray->GetValueAt(1)->ToNumber<double>();
230 }
231 }
232
SetBorderLinearGradientColors(const JSRef<JSObject> & obj,PopupLinearGradientProperties & popupBorderLinearGradient)233 void SetBorderLinearGradientColors(const JSRef<JSObject>& obj,
234 PopupLinearGradientProperties& popupBorderLinearGradient)
235 {
236 auto colorsValues = obj->GetProperty("colors");
237 if (!colorsValues->IsArray()) {
238 return;
239 }
240 auto colorsArray = JSRef<JSArray>::Cast(colorsValues);
241 for (size_t i = 0; i < colorsArray->Length(); i++) {
242 auto colorInfo = colorsArray->GetValueAt(i);
243 if (!colorInfo->IsArray()) {
244 continue;
245 }
246 auto colorArray = JSRef<JSArray>::Cast(colorInfo);
247 PopupGradientColor gradientColor;
248 ParseGradientColor(colorArray, gradientColor);
249 popupBorderLinearGradient.gradientColors.push_back(gradientColor);
250 }
251 }
252
SetPopupBorderWidthInfo(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam,const int32_t & borderWidthParamFlag)253 void SetPopupBorderWidthInfo(
254 const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam, const int32_t& borderWidthParamFlag)
255 {
256 auto popupBorderWidthVal = popupObj->GetProperty(BORDER_WIDTH_TYPE[borderWidthParamFlag].c_str());
257 if (popupBorderWidthVal->IsNull()) {
258 return;
259 }
260 CalcDimension popupBorderWidth;
261 RefPtr<ResourceObject> widthResObj = nullptr;
262 if (SystemProperties::ConfigChangePerform()) {
263 if (!JSViewAbstract::ParseJsDimensionVp(popupBorderWidthVal, popupBorderWidth, widthResObj)) {
264 return;
265 }
266 } else {
267 if (!JSViewAbstract::ParseJsDimensionVp(popupBorderWidthVal, popupBorderWidth)) {
268 return;
269 }
270 }
271
272 if (popupBorderWidth.Value() < 0) {
273 return;
274 }
275 if (OUTER_BORDER_WIDTH == borderWidthParamFlag) {
276 popupParam->SetOutlineWidthObject(widthResObj);
277 popupParam->SetOutlineWidth(popupBorderWidth);
278 } else {
279 popupParam->SetBorderWidthObject(widthResObj);
280 popupParam->SetInnerBorderWidth(popupBorderWidth);
281 }
282 }
283
SetPopupBorderLinearGradientInfo(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam,const int32_t & borderColorParamFlag)284 void SetPopupBorderLinearGradientInfo(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam,
285 const int32_t& borderColorParamFlag)
286 {
287 PopupLinearGradientProperties popupBorderLinearGradient;
288 auto borderLinearGradientVal = popupObj->GetProperty(BORDER_LINEAR_GRADIENT_TYPE[borderColorParamFlag].c_str());
289 if (borderLinearGradientVal->IsObject()) {
290 auto obj = JSRef<JSObject>::Cast(borderLinearGradientVal);
291 SetBorderLinearGradientDirection(obj, popupBorderLinearGradient);
292 SetBorderLinearGradientColors(obj, popupBorderLinearGradient);
293 if (OUTER_BORDER_LINEAR_GRADIENT == borderColorParamFlag) {
294 popupParam->SetOutlineLinearGradient(popupBorderLinearGradient);
295 } else {
296 popupParam->SetInnerBorderLinearGradient(popupBorderLinearGradient);
297 }
298 }
299 }
300
ParsePopupMask(const RefPtr<PopupParam> & popupParam,bool maskValueBool,JSRef<JSVal> & maskValue)301 void ParsePopupMask(const RefPtr<PopupParam>& popupParam, bool maskValueBool, JSRef<JSVal>& maskValue)
302 {
303 if (!popupParam) {
304 return;
305 }
306 if (SystemProperties::ConfigChangePerform()) {
307 RefPtr<ResourceObject> resObj;
308 if (JSViewAbstract::ParseJsBool(maskValue, maskValueBool, resObj)) {
309 popupParam->SetMaskResourceObject(resObj);
310 popupParam->SetBlockEvent(maskValueBool);
311 }
312 } else {
313 if (maskValue->IsBoolean()) {
314 popupParam->SetBlockEvent(maskValue->ToBoolean());
315 }
316 }
317 }
318
ParsePopupChildWidth(const RefPtr<PopupParam> & popupParam,JSRef<JSVal> & childWidthVal)319 void ParsePopupChildWidth(const RefPtr<PopupParam>& popupParam, JSRef<JSVal>& childWidthVal)
320 {
321 if (!popupParam) {
322 return;
323 }
324
325 CalcDimension width;
326 if (SystemProperties::ConfigChangePerform()) {
327 RefPtr<ResourceObject> widthResObj = nullptr;
328 if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width, widthResObj)) {
329 popupParam->SetWidthResourceObject(widthResObj);
330 if (width.Value() > 0) {
331 popupParam->SetChildWidth(width);
332 }
333 }
334 } else {
335 if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
336 if (width.Value() > 0) {
337 popupParam->SetChildWidth(width);
338 }
339 }
340 }
341 }
342
ParseArrowWidth(const RefPtr<PopupParam> & popupParam,JSRef<JSVal> & arrowWidthVal)343 void ParseArrowWidth(const RefPtr<PopupParam>& popupParam, JSRef<JSVal>& arrowWidthVal)
344 {
345 bool setError = true;
346 CalcDimension arrowWidth;
347 if (SystemProperties::ConfigChangePerform()) {
348 RefPtr<ResourceObject> arrowWidthhResObj = nullptr;
349 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth, arrowWidthhResObj)) {
350 popupParam->SetArrowWidthResourceObject(arrowWidthhResObj);
351 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
352 popupParam->SetArrowWidth(arrowWidth);
353 setError = false;
354 }
355 }
356 } else {
357 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
358 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
359 popupParam->SetArrowWidth(arrowWidth);
360 setError = false;
361 }
362 }
363 }
364
365 popupParam->SetErrorArrowWidth(setError);
366 }
367
ParseArrowHeight(const RefPtr<PopupParam> & popupParam,JSRef<JSVal> & arrowHeightVal)368 void ParseArrowHeight(const RefPtr<PopupParam>& popupParam, JSRef<JSVal>& arrowHeightVal)
369 {
370 bool setError = true;
371 CalcDimension arrowHeight;
372 if (SystemProperties::ConfigChangePerform()) {
373 RefPtr<ResourceObject> arrowHeighthResObj = nullptr;
374 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight, arrowHeighthResObj)) {
375 popupParam->SetArrowHeightResourceObject(arrowHeighthResObj);
376 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
377 popupParam->SetArrowHeight(arrowHeight);
378 setError = false;
379 }
380 }
381 } else {
382 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
383 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
384 popupParam->SetArrowHeight(arrowHeight);
385 setError = false;
386 }
387 }
388 }
389
390 popupParam->SetErrorArrowHeight(setError);
391 }
392
ParseRadius(const RefPtr<PopupParam> & popupParam,JSRef<JSVal> & radiusVal)393 void ParseRadius(const RefPtr<PopupParam>& popupParam, JSRef<JSVal>& radiusVal)
394 {
395 bool setError = true;
396 CalcDimension radius;
397 if (SystemProperties::ConfigChangePerform()) {
398 RefPtr<ResourceObject> radiusResObj = nullptr;
399 if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius, radiusResObj)) {
400 popupParam->SetRadiusResourceObject(radiusResObj);
401 if (radius.Value() >= 0) {
402 popupParam->SetRadius(radius);
403 setError = false;
404 }
405 }
406 } else {
407 if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
408 if (radius.Value() >= 0) {
409 popupParam->SetRadius(radius);
410 setError = false;
411 }
412 }
413 }
414
415 popupParam->SetErrorRadius(setError);
416 }
417
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam,const RefPtr<NG::FrameNode> popupTargetNode=nullptr)418 void ParsePopupCommonParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj,
419 const RefPtr<PopupParam>& popupParam, const RefPtr<NG::FrameNode> popupTargetNode = nullptr)
420 {
421 auto arrowOffset = popupObj->GetProperty("arrowOffset");
422 CalcDimension offset;
423 if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
424 if (popupParam) {
425 popupParam->SetArrowOffset(offset);
426 }
427 }
428
429 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
430 if (targetNode) {
431 bool isWithTheme = targetNode->GetLocalColorMode() != ColorMode::COLOR_MODE_UNDEFINED;
432 popupParam->SetIsWithTheme(isWithTheme);
433 }
434
435 auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
436 if (arrowPointPosition->IsString()) {
437 char* pEnd = nullptr;
438 auto arrowString = arrowPointPosition->ToString();
439 std::strtod(arrowString.c_str(), &pEnd);
440 if (pEnd != nullptr) {
441 if (std::strcmp(pEnd, "Start") == 0) {
442 offset = ARROW_ZERO_PERCENT_VALUE;
443 }
444 if (std::strcmp(pEnd, "Center") == 0) {
445 offset = ARROW_HALF_PERCENT_VALUE;
446 }
447 if (std::strcmp(pEnd, "End") == 0) {
448 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
449 }
450 if (popupParam) {
451 popupParam->SetArrowOffset(offset);
452 }
453 }
454 }
455
456 auto targetSpace = popupObj->GetProperty("targetSpace");
457 if (!targetSpace->IsNull()) {
458 CalcDimension space;
459 if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
460 if (popupParam) {
461 popupParam->SetTargetSpace(space);
462 }
463 }
464 }
465
466 JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
467 if (showInSubWindowValue->IsBoolean()) {
468 bool showInSubBoolean = showInSubWindowValue->ToBoolean();
469 #if defined(PREVIEW)
470 if (showInSubBoolean) {
471 LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
472 showInSubBoolean = false;
473 }
474 #endif
475 if (popupParam) {
476 popupParam->SetShowInSubWindow(showInSubBoolean);
477 }
478 }
479
480 auto placementValue = popupObj->GetProperty("placement");
481 if (placementValue->IsNumber()) {
482 auto placement = placementValue->ToNumber<int32_t>();
483 if (placement >= 0 && placement < static_cast<int32_t>(Placement::NONE)) {
484 popupParam->SetPlacement(static_cast<Placement>(placement));
485 popupParam->SetHasPlacement(true);
486 }
487 } else {
488 SetPlacementOnTopVal(popupObj, popupParam);
489 }
490
491 auto enableArrowValue = popupObj->GetProperty("enableArrow");
492 if (enableArrowValue->IsBoolean()) {
493 popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
494 }
495
496 auto enableHoverModeValue = popupObj->GetProperty("enableHoverMode");
497 if (enableHoverModeValue->IsBoolean()) {
498 popupParam->SetEnableHoverMode(enableHoverModeValue->ToBoolean());
499 }
500
501 auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
502 if (followTransformOfTargetValue->IsBoolean()) {
503 popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
504 }
505
506 JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
507 bool maskValueBool = false;
508 ParsePopupMask(popupParam, maskValueBool, maskValue);
509
510 if (maskValue->IsObject()) {
511 auto maskObj = JSRef<JSObject>::Cast(maskValue);
512 auto colorValue = maskObj->GetProperty("color");
513 Color maskColor;
514 if (SystemProperties::ConfigChangePerform()) {
515 RefPtr<ResourceObject> resObj;
516 if (JSViewAbstract::ParseJsColor(colorValue, maskColor, resObj)) {
517 popupParam->SetMaskColorResourceObject(resObj);
518 popupParam->SetMaskColor(maskColor);
519 }
520 } else {
521 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
522 popupParam->SetMaskColor(maskColor);
523 }
524 }
525 }
526
527 JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
528 if (onStateChangeVal->IsFunction()) {
529 std::vector<std::string> keys = { "isVisible" };
530 RefPtr<JsFunction> jsFunc =
531 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
532 WeakPtr<NG::FrameNode> targetNode = nullptr;
533 if (popupTargetNode) {
534 targetNode = AceType::WeakClaim(AceType::RawPtr(popupTargetNode));
535 } else {
536 targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
537 }
538 if (popupParam) {
539 auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
540 node = targetNode](const std::string& param) {
541 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
542 ACE_SCORING_EVENT("Popup.onStateChange");
543 PipelineContext::SetCallBackNode(node);
544 func->Execute(keys, param);
545 };
546 popupParam->SetOnStateChange(onStateChangeCallback);
547 }
548 }
549
550 auto offsetVal = popupObj->GetProperty("offset");
551 if (offsetVal->IsObject()) {
552 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
553 auto xVal = offsetObj->GetProperty("x");
554 auto yVal = offsetObj->GetProperty("y");
555 Offset popupOffset;
556 CalcDimension dx;
557 CalcDimension dy;
558 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
559 popupOffset.SetX(dx.ConvertToPx());
560 }
561 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
562 popupOffset.SetY(dy.ConvertToPx());
563 }
564 if (popupParam) {
565 popupParam->SetTargetOffset(popupOffset);
566 }
567 }
568
569 Color backgroundColor;
570 auto popupColorVal = popupObj->GetProperty("popupColor");
571 if (SystemProperties::ConfigChangePerform()) {
572 RefPtr<ResourceObject> resObj;
573 if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor, resObj)) {
574 popupParam->SetPopupColorResourceObject(resObj);
575 popupParam->SetBackgroundColor(backgroundColor);
576 }
577 } else {
578 if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
579 popupParam->SetBackgroundColor(backgroundColor);
580 }
581 }
582
583 auto autoCancelVal = popupObj->GetProperty("autoCancel");
584 if (autoCancelVal->IsBoolean()) {
585 popupParam->SetHasAction(!autoCancelVal->ToBoolean());
586 }
587
588 auto childWidthVal = popupObj->GetProperty("width");
589 if (!childWidthVal->IsNull()) {
590 ParsePopupChildWidth(popupParam, childWidthVal);
591 }
592
593 auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
594 if (!arrowWidthVal->IsNull()) {
595 ParseArrowWidth(popupParam, arrowWidthVal);
596 }
597
598 auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
599 if (!arrowHeightVal->IsNull()) {
600 ParseArrowHeight(popupParam, arrowHeightVal);
601 }
602
603 auto radiusVal = popupObj->GetProperty("radius");
604 if (!radiusVal->IsNull()) {
605 ParseRadius(popupParam, radiusVal);
606 }
607
608 auto defaultShadowStyle = GetPopupDefaultShadowStyle();
609 Shadow shadow;
610 auto shadowVal = popupObj->GetProperty("shadow");
611 if (shadowVal->IsObject() || shadowVal->IsNumber()) {
612 auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
613 if (!ret) {
614 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
615 JSViewAbstract::GetShadowFromTheme(defaultShadowStyle, shadow);
616 popupParam->SetShadow(shadow);
617 }
618 } else {
619 popupParam->SetShadow(shadow);
620 }
621 } else {
622 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
623 JSViewAbstract::GetShadowFromTheme(defaultShadowStyle, shadow);
624 popupParam->SetShadow(shadow);
625 }
626 }
627
628 auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
629 if (blurStyleValue->IsNumber()) {
630 auto blurStyle = blurStyleValue->ToNumber<int32_t>();
631 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
632 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
633 popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
634 } else {
635 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
636 GetBlurStyleFromTheme(popupParam);
637 }
638 }
639 } else {
640 if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
641 GetBlurStyleFromTheme(popupParam);
642 }
643 }
644
645 auto popupTransition = popupObj->GetProperty("transition");
646 if (popupTransition->IsObject()) {
647 popupParam->SetHasTransition(true);
648 auto obj = JSRef<JSObject>::Cast(popupTransition);
649 if (popupTargetNode) {
650 auto effects = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext(), popupTargetNode);
651 popupParam->SetTransitionEffects(effects);
652 } else {
653 auto effects = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
654 popupParam->SetTransitionEffects(effects);
655 }
656 }
657 auto keyboardAvoidMode = popupObj->GetProperty("keyboardAvoidMode");
658 if (keyboardAvoidMode->IsNumber()) {
659 auto popupKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
660 if (popupKeyboardAvoidMode >= static_cast<int>(PopupKeyboardAvoidMode::DEFAULT) &&
661 popupKeyboardAvoidMode <= static_cast<int>(PopupKeyboardAvoidMode::NONE)) {
662 popupParam->SetKeyBoardAvoidMode(static_cast<PopupKeyboardAvoidMode>(popupKeyboardAvoidMode));
663 }
664 }
665 auto avoidTargetValue = popupObj->GetProperty("avoidTarget");
666 if (avoidTargetValue->IsNumber()) {
667 auto avoidTargetNumValue = avoidTargetValue->ToNumber<int32_t>();
668 if (avoidTargetNumValue >= static_cast<int>(AvoidanceMode::COVER_TARGET) &&
669 avoidTargetNumValue <= static_cast<int>(AvoidanceMode::AVOID_AROUND_TARGET)) {
670 popupParam->SetAvoidTarget(static_cast<AvoidanceMode>(avoidTargetNumValue));
671 }
672 }
673 SetPopupBorderWidthInfo(popupObj, popupParam, OUTER_BORDER_WIDTH);
674 SetPopupBorderWidthInfo(popupObj, popupParam, INNER_BORDER_WIDTH);
675 SetPopupBorderLinearGradientInfo(popupObj, popupParam, OUTER_BORDER_LINEAR_GRADIENT);
676 SetPopupBorderLinearGradientInfo(popupObj, popupParam, INNER_BORDER_LINEAR_GRADIENT);
677 }
678
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)679 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
680 {
681 ParsePopupCommonParam(info, popupObj, popupParam);
682 JSRef<JSVal> messageVal = popupObj->GetProperty("message");
683 if (popupParam) {
684 popupParam->SetMessage(messageVal->ToString());
685 }
686
687 auto messageOptions = popupObj->GetProperty("messageOptions");
688 JSRef<JSObject> messageOptionsObj;
689 if (!messageOptions->IsNull() && messageOptions->IsObject()) {
690 messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
691 SetPopupMessageOptions(messageOptionsObj, popupParam);
692 }
693
694 JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
695 if (primaryButtonVal->IsObject()) {
696 ButtonProperties properties;
697 JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
698 JSRef<JSVal> value = obj->GetProperty("value");
699 if (value->IsString()) {
700 properties.value = value->ToString();
701 }
702
703 JSRef<JSVal> actionValue = obj->GetProperty("action");
704 if (actionValue->IsFunction()) {
705 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
706 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
707 if (popupParam) {
708 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
709 node = targetNode](GestureEvent& info) {
710 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
711 ACE_SCORING_EVENT("primaryButton.action");
712 PipelineContext::SetCallBackNode(node);
713 func->Execute(info);
714 };
715 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
716 }
717 }
718 properties.showButton = true;
719 if (popupParam) {
720 popupParam->SetPrimaryButtonProperties(properties);
721 }
722 }
723
724 JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
725 if (secondaryButtonVal->IsObject()) {
726 ButtonProperties properties;
727 JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
728 JSRef<JSVal> value = obj->GetProperty("value");
729 if (value->IsString()) {
730 properties.value = value->ToString();
731 }
732
733 JSRef<JSVal> actionValue = obj->GetProperty("action");
734 if (actionValue->IsFunction()) {
735 auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
736 auto targetNode =
737 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
738 if (popupParam) {
739 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
740 node = targetNode](GestureEvent& info) {
741 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
742 ACE_SCORING_EVENT("secondaryButton.action");
743 PipelineContext::SetCallBackNode(node);
744 func->Execute(info);
745 };
746 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
747 }
748 }
749 properties.showButton = true;
750 if (popupParam) {
751 popupParam->SetSecondaryButtonProperties(properties);
752 }
753 }
754 }
755
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)756 void ParseCustomPopupParam(
757 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
758 {
759 auto builderValue = popupObj->GetProperty("builder");
760 if (!builderValue->IsObject()) {
761 return;
762 }
763 if (!builderValue->IsFunction()) {
764 JSRef<JSObject> builderObj;
765 builderObj = JSRef<JSObject>::Cast(builderValue);
766 auto builder = builderObj->GetProperty("builder");
767 if (!builder->IsFunction()) {
768 return;
769 }
770 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
771 if (!builderFunc) {
772 return;
773 }
774 }
775 if (popupParam) {
776 popupParam->SetUseCustomComponent(true);
777 }
778
779 auto focusableValue = popupObj->GetProperty("focusable");
780 if (focusableValue->IsBoolean()) {
781 popupParam->SetFocusable(focusableValue->ToBoolean());
782 }
783
784 ParsePopupCommonParam(info, popupObj, popupParam);
785 }
786
ParseTipsParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)787 void ParseTipsParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
788 {
789 CHECK_NULL_VOID(tipsParam);
790 auto appearingTimeVal = tipsObj->GetProperty("appearingTime");
791 if (appearingTimeVal->IsNumber()) {
792 auto appearingTime = appearingTimeVal->ToNumber<int32_t>();
793 if (appearingTime >= 0) {
794 tipsParam->SetAppearingTime(appearingTime);
795 }
796 }
797
798 auto disappearingTimeVal = tipsObj->GetProperty("disappearingTime");
799 if (disappearingTimeVal->IsNumber()) {
800 auto disappearingTime = disappearingTimeVal->ToNumber<int32_t>();
801 if (disappearingTime >= 0) {
802 tipsParam->SetDisappearingTime(disappearingTime);
803 }
804 }
805
806 auto appearingTimeWithContinuousOperationVal = tipsObj->GetProperty("appearingTimeWithContinuousOperation");
807 if (appearingTimeWithContinuousOperationVal->IsNumber()) {
808 auto appearingTimeWithContinuousOperation = appearingTimeWithContinuousOperationVal->ToNumber<int32_t>();
809 if (appearingTimeWithContinuousOperation >= 0) {
810 tipsParam->SetAppearingTimeWithContinuousOperation(appearingTimeWithContinuousOperation);
811 }
812 }
813
814 auto disappearingTimeWithContinuousOperationVal = tipsObj->GetProperty("disappearingTimeWithContinuousOperation");
815 if (disappearingTimeWithContinuousOperationVal->IsNumber()) {
816 auto disappearingTimeWithContinuousOperation = disappearingTimeWithContinuousOperationVal->ToNumber<int32_t>();
817 if (disappearingTimeWithContinuousOperation >= 0) {
818 tipsParam->SetDisappearingTimeWithContinuousOperation(disappearingTimeWithContinuousOperation);
819 }
820 }
821
822 auto enableArrowValue = tipsObj->GetProperty("enableArrow");
823 if (enableArrowValue->IsBoolean()) {
824 tipsParam->SetEnableArrow(enableArrowValue->ToBoolean());
825 }
826 auto showAtAnchor = tipsObj->GetProperty("showAtAnchor");
827 if (showAtAnchor->IsNumber()) {
828 auto type = static_cast<TipsAnchorType>(showAtAnchor->ToNumber<int32_t>());
829 if (type == TipsAnchorType::TARGET || type == TipsAnchorType::CURSOR) {
830 tipsParam->SetAnchorType(type);
831 }
832 }
833 tipsParam->SetBlockEvent(false);
834 tipsParam->SetTipsFlag(true);
835 tipsParam->SetShowInSubWindow(true);
836 tipsParam->SetKeyBoardAvoidMode(PopupKeyboardAvoidMode::DEFAULT);
837 }
838
ParseTipsArrowPositionParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)839 void ParseTipsArrowPositionParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
840 {
841 CalcDimension offset;
842 auto arrowPointPosition = tipsObj->GetProperty("arrowPointPosition");
843 if (arrowPointPosition->IsString()) {
844 char* pEnd = nullptr;
845 auto arrowString = arrowPointPosition->ToString();
846 std::strtod(arrowString.c_str(), &pEnd);
847 if (pEnd != nullptr) {
848 if (std::strcmp(pEnd, "Start") == 0) {
849 offset = ARROW_ZERO_PERCENT_VALUE;
850 }
851 if (std::strcmp(pEnd, "Center") == 0) {
852 offset = ARROW_HALF_PERCENT_VALUE;
853 }
854 if (std::strcmp(pEnd, "End") == 0) {
855 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
856 }
857 if (tipsParam) {
858 tipsParam->SetArrowOffset(offset);
859 }
860 }
861 }
862 }
863
ParseTipsArrowSizeParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)864 void ParseTipsArrowSizeParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
865 {
866 auto arrowWidthVal = tipsObj->GetProperty("arrowWidth");
867 if (!arrowWidthVal->IsNull()) {
868 bool setError = true;
869 CalcDimension arrowWidth;
870 if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
871 if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
872 tipsParam->SetArrowWidth(arrowWidth);
873 setError = false;
874 }
875 }
876 tipsParam->SetErrorArrowWidth(setError);
877 }
878
879 auto arrowHeightVal = tipsObj->GetProperty("arrowHeight");
880 if (!arrowHeightVal->IsNull()) {
881 bool setError = true;
882 CalcDimension arrowHeight;
883 if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
884 if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
885 tipsParam->SetArrowHeight(arrowHeight);
886 setError = false;
887 }
888 }
889 tipsParam->SetErrorArrowHeight(setError);
890 }
891 }
892 #endif
893
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)894 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
895 {
896 size_t builderIndex = 0;
897 if (info[0]->IsBoolean()) {
898 menuParam.isShow = info[0]->ToBoolean();
899 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
900 menuParam.placement = Placement::BOTTOM_LEFT;
901 builderIndex = 1;
902 } else if (info[0]->IsObject()) {
903 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
904 menuParam.onStateChange = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
905 auto isShowObj = callbackObj->GetProperty("value");
906 if (isShowObj->IsBoolean()) {
907 menuParam.isShow = isShowObj->ToBoolean();
908 menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
909 menuParam.placement = Placement::BOTTOM_LEFT;
910 builderIndex = 1;
911 }
912 }
913 return builderIndex;
914 }
915
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)916 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
917 std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
918 std::function<void(const int32_t& info)>& onWillDismiss)
919 {
920 auto showCallback = paramObj->GetProperty("onAppear");
921 auto dismissCallback = paramObj->GetProperty("onDisappear");
922 auto willShowCallback = paramObj->GetProperty("onWillAppear");
923 auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
924 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
925 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
926 if (showCallback->IsFunction()) {
927 RefPtr<JsFunction> jsFunc =
928 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
929 onAppear = [func = std::move(jsFunc), node = frameNode]() {
930 PipelineContext::SetCallBackNode(node);
931 func->Execute();
932 };
933 }
934 if (dismissCallback->IsFunction()) {
935 RefPtr<JsFunction> jsFunc =
936 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
937 onDisappear = [func = std::move(jsFunc), node = frameNode]() {
938 PipelineContext::SetCallBackNode(node);
939 func->Execute();
940 };
941 }
942 if (willShowCallback->IsFunction()) {
943 RefPtr<JsFunction> jsFunc =
944 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
945 onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
946 }
947 if (willDismissCallback->IsFunction()) {
948 RefPtr<JsFunction> jsFunc =
949 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
950 onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
951 }
952 if (onWillDismissFunc->IsFunction()) {
953 RefPtr<JsFunction> jsFunc =
954 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
955 onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
956 ACE_SCORING_EVENT("contentCover.dismiss");
957 PipelineContext::SetCallBackNode(node);
958 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
959 objectTemplate->SetInternalFieldCount(1);
960 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
961 dismissObj->SetPropertyObject(
962 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
963 dismissObj->SetProperty<int32_t>("reason", info);
964 JSRef<JSVal> newJSVal = dismissObj;
965 func->ExecuteJS(1, &newJSVal);
966 };
967 }
968 }
969
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)970 std::vector<NG::OptionParam> JSViewPopups::ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
971 {
972 JSRef<JSVal> arg = info[optionIndex];
973 if (!arg->IsArray()) {
974 return std::vector<NG::OptionParam>();
975 }
976 auto paramArray = JSRef<JSArray>::Cast(arg);
977 auto paramArrayLength = paramArray->Length();
978 std::vector<NG::OptionParam> params(paramArrayLength);
979 // parse paramArray
980 for (size_t i = 0; i < paramArrayLength; ++i) {
981 if (!paramArray->GetValueAt(i)->IsObject()) {
982 return std::vector<NG::OptionParam>();
983 }
984 auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
985 JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
986 params[i].value);
987 auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
988 if (!actionFunc->IsFunction()) {
989 return params;
990 }
991 auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
992 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
993 // set onClick function
994 params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
995 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
996 ACE_SCORING_EVENT("menu.action");
997 PipelineContext::SetCallBackNode(node);
998 if (func) {
999 func->Execute();
1000 }
1001 };
1002 std::string iconPath;
1003 if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
1004 params[i].icon = iconPath;
1005 }
1006 if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
1007 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
1008 JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
1009 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
1010 params[i].symbol = symbolApply;
1011 }
1012 auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
1013 if (enabled->IsBoolean()) {
1014 params[i].enabled = enabled->ToBoolean();
1015 }
1016 }
1017 return params;
1018 }
1019
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1020 void JSViewPopups::ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1021 {
1022 auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
1023 NG::BorderRadiusProperty menuBorderRadius;
1024 CalcDimension borderRadius;
1025 RefPtr<ResourceObject> borderRadiusResObj;
1026 if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius, borderRadiusResObj)) {
1027 if (GreatOrEqual(borderRadius.Value(), 0.0f)) {
1028 menuBorderRadius.SetRadius(borderRadius);
1029 menuBorderRadius.multiValued = false;
1030 ParseMenuBorderRadiusWithResourceObj(borderRadiusResObj, menuBorderRadius);
1031 menuParam.borderRadius = menuBorderRadius;
1032 };
1033 } else if (borderRadiusValue->IsObject()) {
1034 JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
1035 JSViewAbstract::ParseAllBorderRadiuses(object, menuBorderRadius);
1036 menuParam.borderRadius = menuBorderRadius;
1037 }
1038 }
1039
ParseMenuBorderRadiusWithResourceObj(const RefPtr<ResourceObject> & borderRadiusResObj,NG::BorderRadiusProperty & menuBorderRadius)1040 void JSViewPopups::ParseMenuBorderRadiusWithResourceObj(const RefPtr<ResourceObject>& borderRadiusResObj,
1041 NG::BorderRadiusProperty& menuBorderRadius)
1042 {
1043 if (borderRadiusResObj) {
1044 auto&& updateFunc =
1045 [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& borderRadiusProp) {
1046 CalcDimension radius;
1047 auto state = ResourceParseUtils::ParseResDimensionVp(resObj, radius);
1048 if (state && GreatOrEqual(radius.Value(), 0.0f)) {
1049 borderRadiusProp.SetRadius(radius);
1050 } else {
1051 borderRadiusProp.radiusTopLeft = std::nullopt;
1052 borderRadiusProp.radiusTopRight = std::nullopt;
1053 borderRadiusProp.radiusBottomLeft = std::nullopt;
1054 borderRadiusProp.radiusBottomRight = std::nullopt;
1055 }
1056 borderRadiusProp.multiValued = false;
1057 };
1058 menuBorderRadius.AddResource("borderRadius.radius", borderRadiusResObj, std::move(updateFunc));
1059 }
1060 }
1061
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1062 void JSViewPopups::ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1063 {
1064 auto enableArrowValue = menuOptions->GetProperty("enableArrow");
1065 if (enableArrowValue->IsBoolean()) {
1066 menuParam.enableArrow = enableArrowValue->ToBoolean();
1067 }
1068 auto enableArrow = menuParam.enableArrow.has_value() && menuParam.enableArrow.value();
1069 RefPtr<ResourceObject> arrowOffsetResObj;
1070 auto arrowOffset = menuOptions->GetProperty("arrowOffset");
1071 CalcDimension offset;
1072 if (enableArrow && JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset, arrowOffsetResObj)) {
1073 menuParam.arrowOffset = offset;
1074 }
1075 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MenuParam& menuParam) {
1076 CalcDimension offset;
1077 if (ResourceParseUtils::ParseResDimensionVp(resObj, offset)) {
1078 menuParam.arrowOffset = offset;
1079 }
1080 };
1081 if (enableArrow && arrowOffsetResObj) {
1082 menuParam.AddResource("arrowOffset", arrowOffsetResObj, std::move(updateFunc));
1083 }
1084 // if enableArrow is true and placement not set, set placement default value to top.
1085 if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
1086 menuParam.placement = Placement::TOP;
1087 }
1088 }
1089
ParseMenuShowInSubWindowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam,bool isCheckThemeValue)1090 void JSViewPopups::ParseMenuShowInSubWindowParam(
1091 const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam, bool isCheckThemeValue)
1092 {
1093 auto showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
1094 if (isCheckThemeValue) {
1095 JSViewPopups::GetMenuShowInSubwindow(menuParam);
1096 if (!menuParam.isShowInSubWindow) {
1097 return;
1098 }
1099 }
1100 if (showInSubWindowValue->IsBoolean()) {
1101 bool showInSubBoolean = showInSubWindowValue->ToBoolean();
1102 #if defined(PREVIEW)
1103 if (showInSubBoolean) {
1104 LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
1105 showInSubBoolean = false;
1106 }
1107 #endif
1108 menuParam.isShowInSubWindow = showInSubBoolean;
1109 }
1110 }
1111
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)1112 void JSViewPopups::ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
1113 {
1114 CalcDimension dimension;
1115 if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
1116 return;
1117 }
1118
1119 if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
1120 calcDimension = dimension;
1121 }
1122 }
1123
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension,RefPtr<ResourceObject> & resObj)1124 void JSViewPopups::ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension,
1125 RefPtr<ResourceObject>& resObj)
1126 {
1127 CalcDimension dimension;
1128 if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, resObj, true)) {
1129 return;
1130 }
1131
1132 if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
1133 calcDimension = dimension;
1134 }
1135 }
1136
ParseResLayoutRegionMargin(const RefPtr<ResourceObject> & resObj,std::optional<CalcDimension> & calcDimension)1137 void JSViewPopups::ParseResLayoutRegionMargin(const RefPtr<ResourceObject>& resObj,
1138 std::optional<CalcDimension>& calcDimension)
1139 {
1140 CHECK_NULL_VOID(resObj);
1141 CalcDimension dimension;
1142 if (!ResourceParseUtils::ParseResDimensionVpNG(resObj, dimension, true)) {
1143 return;
1144 }
1145 if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
1146 calcDimension = dimension;
1147 }
1148 }
1149
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1150 void JSViewPopups::ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1151 {
1152 auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
1153 if (!marginVal->IsObject()) {
1154 return;
1155 }
1156 CommonCalcDimension calcDimension;
1157 auto object = JSRef<JSObject>::Cast(marginVal);
1158 RefPtr<ResourceObject> dimensionTopResObj;
1159 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("top"), calcDimension.top, dimensionTopResObj);
1160 RefPtr<ResourceObject> dimensionBottomResObj;
1161 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("bottom"), calcDimension.bottom, dimensionBottomResObj);
1162 RefPtr<ResourceObject> dimensionLeftResObj;
1163 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("left"), calcDimension.left, dimensionLeftResObj);
1164 RefPtr<ResourceObject> dimensionRightResObj;
1165 JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("right"), calcDimension.right, dimensionRightResObj);
1166 if (calcDimension.left.has_value() || calcDimension.right.has_value() ||
1167 calcDimension.top.has_value() || calcDimension.bottom.has_value()) {
1168 menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
1169 calcDimension.top, calcDimension.bottom, calcDimension.left, calcDimension.right);
1170 }
1171 auto&& nullFunc = [](const RefPtr<ResourceObject>& resObj, NG::MenuParam& menuParam) {
1172 };
1173 menuParam.AddResource("layoutRegionMargin.top", dimensionTopResObj, std::move(nullFunc));
1174 menuParam.AddResource("layoutRegionMargin.bottom", dimensionBottomResObj, std::move(nullFunc));
1175 menuParam.AddResource("layoutRegionMargin.left", dimensionLeftResObj, std::move(nullFunc));
1176 menuParam.AddResource("layoutRegionMargin.right", dimensionRightResObj, std::move(nullFunc));
1177 RefPtr<ResourceObject> commonCalcDimensionResObj;
1178 for (const auto& obj : {dimensionTopResObj, dimensionBottomResObj, dimensionLeftResObj, dimensionRightResObj}) {
1179 if (obj) {
1180 commonCalcDimensionResObj = obj;
1181 break;
1182 }
1183 }
1184 if (commonCalcDimensionResObj) {
1185 auto&& updateFunc = [](const RefPtr<ResourceObject>& commonCalcDimensionResObj, NG::MenuParam& menuParam) {
1186 CommonCalcDimension calcDimension;
1187 ParseResLayoutRegionMargin(menuParam.GetResource("layoutRegionMargin.top"), calcDimension.top);
1188 ParseResLayoutRegionMargin(menuParam.GetResource("layoutRegionMargin.bottom"), calcDimension.bottom);
1189 ParseResLayoutRegionMargin(menuParam.GetResource("layoutRegionMargin.left"), calcDimension.left);
1190 ParseResLayoutRegionMargin(menuParam.GetResource("layoutRegionMargin.right"), calcDimension.right);
1191 if (calcDimension.left.has_value() || calcDimension.right.has_value() ||
1192 calcDimension.top.has_value() || calcDimension.bottom.has_value()) {
1193 menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
1194 calcDimension.top, calcDimension.bottom, calcDimension.left, calcDimension.right);
1195 }
1196 };
1197 menuParam.AddResource("layoutRegionMargin", commonCalcDimensionResObj, std::move(updateFunc));
1198 }
1199 }
1200
ParseMenuBlurStyleOption(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1201 void JSViewPopups::ParseMenuBlurStyleOption(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1202 {
1203 auto blurStyle = menuOptions->GetProperty("backgroundBlurStyleOptions");
1204 if (blurStyle->IsObject()) {
1205 if (!menuParam.blurStyleOption.has_value()) {
1206 menuParam.blurStyleOption.emplace();
1207 }
1208 JSViewAbstract::ParseBlurStyleOption(blurStyle, menuParam.blurStyleOption.value());
1209 }
1210 }
1211
ParseMenuEffectOption(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1212 void JSViewPopups::ParseMenuEffectOption(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1213 {
1214 auto effectOption = menuOptions->GetProperty("backgroundEffect");
1215 if (effectOption->IsObject()) {
1216 if (!menuParam.effectOption.has_value()) {
1217 menuParam.effectOption.emplace();
1218 }
1219 JSViewAbstract::ParseEffectOption(effectOption, menuParam.effectOption.value());
1220 }
1221 }
1222
ParseMenuHapticFeedbackMode(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1223 void JSViewPopups::ParseMenuHapticFeedbackMode(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1224 {
1225 auto hapticFeedbackMode = menuOptions->GetProperty("hapticFeedbackMode");
1226 if (!hapticFeedbackMode->IsNumber()) {
1227 return;
1228 }
1229 if (hapticFeedbackMode->ToNumber<int32_t>() == HAPTIC_FEEDBACK_MODE_ENABLED) {
1230 menuParam.hapticFeedbackMode = HapticFeedbackMode::ENABLED;
1231 } else if (hapticFeedbackMode->ToNumber<int32_t>() == HAPTIC_FEEDBACK_MODE_AUTO) {
1232 menuParam.hapticFeedbackMode = HapticFeedbackMode::AUTO;
1233 }
1234 }
1235
ParseMenuModalMode(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1236 void JSViewPopups::ParseMenuModalMode(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1237 {
1238 auto modalModeProperty = menuOptions->GetProperty("modalMode");
1239 if (!modalModeProperty->IsNumber()) {
1240 return;
1241 }
1242 auto modalMode = modalModeProperty->ToNumber<int32_t>();
1243 if (modalMode == static_cast<int32_t>(ModalMode::TARGET_WINDOW)) {
1244 menuParam.modalMode = ModalMode::TARGET_WINDOW;
1245 } else if (modalMode == static_cast<int32_t>(ModalMode::NONE)) {
1246 menuParam.modalMode = ModalMode::NONE;
1247 } else if (modalMode == static_cast<int32_t>(ModalMode::AUTO)) {
1248 menuParam.modalMode = ModalMode::AUTO;
1249 }
1250 }
1251
ParseMenuPreviewScaleMode(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1252 void JSViewPopups::ParseMenuPreviewScaleMode(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1253 {
1254 auto previewScaleModeProperty = menuOptions->GetProperty("previewScaleMode");
1255 if (!previewScaleModeProperty->IsNumber()) {
1256 return;
1257 }
1258 auto previewScaleMode = previewScaleModeProperty->ToNumber<int32_t>();
1259 if (previewScaleMode == static_cast<int32_t>(NG::PreviewScaleMode::AUTO)) {
1260 menuParam.previewScaleMode = NG::PreviewScaleMode::AUTO;
1261 } else if (previewScaleMode == static_cast<int32_t>(NG::PreviewScaleMode::CONSTANT)) {
1262 menuParam.previewScaleMode = NG::PreviewScaleMode::CONSTANT;
1263 } else if (previewScaleMode == static_cast<int32_t>(NG::PreviewScaleMode::MAINTAIN)) {
1264 menuParam.previewScaleMode = NG::PreviewScaleMode::MAINTAIN;
1265 }
1266 }
1267
ParseMenuAvailableLayoutArea(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1268 void JSViewPopups::ParseMenuAvailableLayoutArea(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1269 {
1270 auto availableLayoutAreaModeProperty = menuOptions->GetProperty("availableLayoutArea");
1271 if (!availableLayoutAreaModeProperty->IsNumber()) {
1272 return;
1273 }
1274 auto availableLayoutAreaMode = availableLayoutAreaModeProperty->ToNumber<int32_t>();
1275 if (availableLayoutAreaMode == static_cast<int32_t>(NG::AvailableLayoutAreaMode::SAFE_AREA)) {
1276 menuParam.availableLayoutAreaMode = NG::AvailableLayoutAreaMode::SAFE_AREA;
1277 }
1278 }
1279
GetMenuShowInSubwindow(NG::MenuParam & menuParam)1280 void JSViewPopups::GetMenuShowInSubwindow(NG::MenuParam& menuParam)
1281 {
1282 menuParam.isShowInSubWindow = false;
1283 auto pipeline = PipelineBase::GetCurrentContext();
1284 CHECK_NULL_VOID(pipeline);
1285 auto theme = pipeline->GetTheme<SelectTheme>();
1286 CHECK_NULL_VOID(theme);
1287 menuParam.isShowInSubWindow = theme->GetExpandDisplay();
1288 }
1289
ParseMenuMaskType(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1290 void JSViewPopups::ParseMenuMaskType(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1291 {
1292 auto maskValue = menuOptions->GetProperty("mask");
1293 if (maskValue->IsBoolean()) {
1294 menuParam.maskEnable = maskValue->ToBoolean();
1295 } else if (maskValue->IsObject()) {
1296 menuParam.maskEnable = true;
1297 if (!menuParam.maskType.has_value()) {
1298 menuParam.maskType.emplace();
1299 }
1300 auto maskObj = JSRef<JSObject>::Cast(maskValue);
1301 auto colorValue = maskObj->GetProperty("color");
1302 Color maskColor;
1303 if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
1304 menuParam.maskType->maskColor = maskColor;
1305 }
1306 auto backgroundBlurStyleValue = maskObj->GetProperty("backgroundBlurStyle");
1307 if (backgroundBlurStyleValue->IsNumber()) {
1308 auto blurStyle = backgroundBlurStyleValue->ToNumber<int32_t>();
1309 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1310 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1311 menuParam.maskType->maskBackGroundBlurStyle = static_cast<BlurStyle>(blurStyle);
1312 }
1313 }
1314 }
1315 }
1316
ParseMenuAppearLifeCycleParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1317 void JSViewPopups::ParseMenuAppearLifeCycleParam(
1318 const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1319 {
1320 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1321 auto onWillAppearValue = menuOptions->GetProperty("onWillAppear");
1322 if (onWillAppearValue->IsFunction()) {
1323 RefPtr<JsFunction> jsOnWillAppearValue =
1324 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppearValue));
1325 auto onWillAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnWillAppearValue),
1326 node = frameNode]() {
1327 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1328 ACE_SCORING_EVENT("onWillAppear");
1329 PipelineContext::SetCallBackNode(node);
1330 func->Execute();
1331 };
1332 menuParam.onWillAppear = std::move(onWillAppear);
1333 }
1334
1335 auto onDidAppearValue = menuOptions->GetProperty("onDidAppear");
1336 if (onDidAppearValue->IsFunction()) {
1337 RefPtr<JsFunction> jsOnDidAppearFunc =
1338 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppearValue));
1339 auto onDidAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDidAppearFunc),
1340 node = frameNode]() {
1341 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1342 ACE_SCORING_EVENT("onDidAppear");
1343 PipelineContext::SetCallBackNode(node);
1344 func->Execute();
1345 };
1346 menuParam.onDidAppear = std::move(onDidAppear);
1347 }
1348 }
1349
ParseMenuDisappearLifeCycleParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1350 void JSViewPopups::ParseMenuDisappearLifeCycleParam(
1351 const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1352 {
1353 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1354 auto onWillDisappearValue = menuOptions->GetProperty("onWillDisappear");
1355 if (onWillDisappearValue->IsFunction()) {
1356 RefPtr<JsFunction> jsOnWillDisappearValueFunc =
1357 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappearValue));
1358 auto onWillDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnWillDisappearValueFunc),
1359 node = frameNode]() {
1360 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1361 ACE_SCORING_EVENT("onWillDisappear");
1362 PipelineContext::SetCallBackNode(node);
1363 func->Execute();
1364 };
1365 menuParam.onWillDisappear = std::move(onWillDisappear);
1366 }
1367
1368 auto onDidDisappearValue = menuOptions->GetProperty("onDidDisappear");
1369 if (onDidDisappearValue->IsFunction()) {
1370 RefPtr<JsFunction> jsOnDidDisappearFunc =
1371 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappearValue));
1372 auto onDidDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDidDisappearFunc),
1373 node = frameNode]() {
1374 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1375 ACE_SCORING_EVENT("onDidDisappear");
1376 PipelineContext::SetCallBackNode(node);
1377 func->Execute();
1378 };
1379 menuParam.onDidDisappear = std::move(onDidDisappear);
1380 }
1381 }
1382
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)1383 void JSViewPopups::ParseMenuParam(
1384 const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
1385 {
1386 auto offsetVal = menuOptions->GetProperty("offset");
1387 if (offsetVal->IsObject()) {
1388 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
1389 JSViewPopups::ParseMenuOffsetParam(offsetObj, menuParam);
1390 }
1391
1392 auto placementValue = menuOptions->GetProperty("placement");
1393 if (placementValue->IsNumber()) {
1394 auto placement = placementValue->ToNumber<int32_t>();
1395 if (placement >= 0 && placement < static_cast<int32_t>(Placement::NONE)) {
1396 menuParam.placement = static_cast<Placement>(placement);
1397 }
1398 }
1399
1400 auto enableHoverModeValue = menuOptions->GetProperty("enableHoverMode");
1401 if (enableHoverModeValue->IsBoolean()) {
1402 menuParam.enableHoverMode = enableHoverModeValue->ToBoolean();
1403 }
1404
1405 auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
1406 Color backgroundColor;
1407 RefPtr<ResourceObject> backgroundColorResObj;
1408 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor, backgroundColorResObj)) {
1409 menuParam.backgroundColor = backgroundColor;
1410 }
1411 if (backgroundColorResObj) {
1412 auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, NG::MenuParam& menuParam) {
1413 Color backgroundColor;
1414 if (ResourceParseUtils::ParseResColor(colorResObj, backgroundColor)) {
1415 menuParam.backgroundColor = backgroundColor;
1416 }
1417 };
1418 menuParam.AddResource("backgroundColor", backgroundColorResObj, std::move(updateFunc));
1419 }
1420
1421 auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
1422 if (backgroundBlurStyle->IsNumber()) {
1423 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1424 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1425 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1426 menuParam.backgroundBlurStyle = blurStyle;
1427 }
1428 }
1429 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1430 auto onAppearValue = menuOptions->GetProperty("onAppear");
1431 if (onAppearValue->IsFunction()) {
1432 RefPtr<JsFunction> jsOnAppearFunc =
1433 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
1434 auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
1435 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1436 ACE_SCORING_EVENT("onAppear");
1437 PipelineContext::SetCallBackNode(node);
1438 func->Execute();
1439 };
1440 menuParam.onAppear = std::move(onAppear);
1441 }
1442
1443 auto onDisappearValue = menuOptions->GetProperty("onDisappear");
1444 if (onDisappearValue->IsFunction()) {
1445 RefPtr<JsFunction> jsOnDisAppearFunc =
1446 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
1447 auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
1448 node = frameNode]() {
1449 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1450 ACE_SCORING_EVENT("onDisappear");
1451 PipelineContext::SetCallBackNode(node);
1452 func->Execute();
1453 };
1454 menuParam.onDisappear = std::move(onDisappear);
1455 }
1456 auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
1457 if (aboutToAppearValue->IsFunction()) {
1458 RefPtr<JsFunction> jsAboutToAppearFunc =
1459 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
1460 auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
1461 node = frameNode]() {
1462 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1463 ACE_SCORING_EVENT("aboutToAppear");
1464 PipelineContext::SetCallBackNode(node);
1465 func->Execute();
1466 };
1467 menuParam.aboutToAppear = std::move(aboutToAppear);
1468 }
1469
1470 auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
1471 if (aboutToDisAppearValue->IsFunction()) {
1472 RefPtr<JsFunction> jsAboutToDisAppearFunc =
1473 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
1474 auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
1475 node = frameNode]() {
1476 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1477 ACE_SCORING_EVENT("aboutToDisappear");
1478 PipelineContext::SetCallBackNode(node);
1479 func->Execute();
1480 };
1481 menuParam.aboutToDisappear = std::move(aboutToDisappear);
1482 }
1483 JSViewPopups::ParseMenuAppearLifeCycleParam(info, menuOptions, menuParam);
1484 JSViewPopups::ParseMenuDisappearLifeCycleParam(info, menuOptions, menuParam);
1485
1486 auto menuTransition = menuOptions->GetProperty("transition");
1487 menuParam.hasTransitionEffect = false;
1488 if (menuTransition->IsObject()) {
1489 auto obj = JSRef<JSObject>::Cast(menuTransition);
1490 menuParam.hasTransitionEffect = true;
1491 menuParam.transition = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
1492 }
1493 JSViewPopups::ParseMenuShowInSubWindowParam(menuOptions, menuParam);
1494 JSViewPopups::ParseMenuArrowParam(menuOptions, menuParam);
1495 JSViewPopups::ParseMenuBorderRadius(menuOptions, menuParam);
1496 JSViewPopups::ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
1497 JSViewPopups::ParseMenuBlurStyleOption(menuOptions, menuParam);
1498 JSViewPopups::ParseMenuEffectOption(menuOptions, menuParam);
1499 JSViewPopups::ParseMenuHapticFeedbackMode(menuOptions, menuParam);
1500 JSViewPopups::ParseMenuModalMode(menuOptions, menuParam);
1501 JSViewPopups::ParseMenuPreviewScaleMode(menuOptions, menuParam);
1502 JSViewPopups::ParseMenuAvailableLayoutArea(menuOptions, menuParam);
1503 auto outlineWidthValue = menuOptions->GetProperty("outlineWidth");
1504 JSViewPopups::ParseMenuOutlineWidth(outlineWidthValue, menuParam);
1505 auto outlineColorValue = menuOptions->GetProperty("outlineColor");
1506 JSViewPopups::ParseMenuOutlineColor(outlineColorValue, menuParam);
1507 JSViewPopups::ParseMenuMaskType(menuOptions, menuParam);
1508
1509 auto anchorPositionVal = menuOptions->GetProperty("anchorPosition");
1510 if (anchorPositionVal->IsObject()) {
1511 auto anchorPositionObj = JSRef<JSObject>::Cast(anchorPositionVal);
1512 JSRef<JSVal> xVal = anchorPositionObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
1513 JSRef<JSVal> yVal = anchorPositionObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
1514 CalcDimension dx;
1515 CalcDimension dy;
1516 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx) && JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
1517 menuParam.anchorPosition = { dx.ConvertToPx(), dy.ConvertToPx() };
1518 }
1519
1520 if (menuParam.anchorPosition.has_value()) {
1521 if (LessNotEqual(menuParam.anchorPosition->GetX(), 0.0f) &&
1522 LessNotEqual(menuParam.anchorPosition->GetY(), 0.0f)) {
1523 menuParam.placement = Placement::BOTTOM_LEFT;
1524 menuParam.anchorPosition.reset();
1525 }
1526 }
1527 }
1528 }
1529
InitMenuParamColorMode(NG::MenuParam & menuParam)1530 void JSViewPopups::InitMenuParamColorMode(NG::MenuParam& menuParam)
1531 {
1532 auto node = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
1533 CHECK_NULL_VOID(node);
1534 auto localColorMode = node->GetLocalColorMode();
1535 menuParam.isWithTheme = (localColorMode != ColorMode::COLOR_MODE_UNDEFINED);
1536 auto colorMode = Container::CurrentColorMode();
1537 menuParam.isDarkMode = (colorMode == ColorMode::DARK);
1538 }
1539
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)1540 void JSViewPopups::ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
1541 {
1542 if (!info[optionIndex]->IsObject()) {
1543 return;
1544 }
1545 auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
1546 RefPtr<ResourceObject> titleResObj;
1547 JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title, titleResObj);
1548 if (titleResObj) {
1549 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MenuParam& menuParam) {
1550 ResourceParseUtils::ParseResString(resObj, menuParam.title);
1551 };
1552 menuParam.AddResource("title", titleResObj, std::move(updateFunc));
1553 }
1554 JSViewPopups::InitMenuParamColorMode(menuParam);
1555 JSViewPopups::ParseMenuParam(info, menuOptions, menuParam);
1556 }
1557
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)1558 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
1559 {
1560 constexpr int scaleArraySize = 2;
1561 if (scaleArray->Length() == scaleArraySize) {
1562 auto scalePropertyFrom = scaleArray->GetValueAt(0);
1563 if (scalePropertyFrom->IsNumber()) {
1564 auto scaleFrom = scalePropertyFrom->ToNumber<float>();
1565 options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
1566 }
1567 auto scalePropertyTo = scaleArray->GetValueAt(1);
1568 if (scalePropertyTo->IsNumber()) {
1569 auto scaleTo = scalePropertyTo->ToNumber<float>();
1570 options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
1571 }
1572 }
1573 }
1574
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)1575 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
1576 NG::MenuParam& menuParam)
1577 {
1578 menuParam.previewAnimationOptions.scaleFrom = -1.0f;
1579 menuParam.previewAnimationOptions.scaleTo = -1.0f;
1580
1581 auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
1582 if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
1583 auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
1584 auto scaleProperty = animationOptionsObj->GetProperty("scale");
1585 if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
1586 JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
1587 ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
1588 }
1589 auto previewTransition = animationOptionsObj->GetProperty("transition");
1590 menuParam.hasPreviewTransitionEffect = false;
1591 if (previewTransition->IsObject()) {
1592 auto obj = JSRef<JSObject>::Cast(previewTransition);
1593 menuParam.hasPreviewTransitionEffect = true;
1594 menuParam.previewTransition = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
1595 }
1596 if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
1597 menuParam.hasPreviewTransitionEffect ||menuParam.hasTransitionEffect ||
1598 menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
1599 return;
1600 }
1601 auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
1602 menuParam.isShowHoverImage = false;
1603 menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
1604 menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
1605 if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
1606 JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
1607 ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
1608 menuParam.isShowHoverImage = true;
1609 }
1610 auto hoverInterruptValue = animationOptionsObj->GetProperty("hoverScaleInterruption");
1611 if (hoverInterruptValue->IsBoolean()) {
1612 menuParam.hoverScaleInterruption = hoverInterruptValue->ToBoolean();
1613 }
1614 }
1615 }
1616
ParsePreviewBorderRadiusParam(const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)1617 void ParsePreviewBorderRadiusParam(const JSRef<JSObject>& menuContentOptions, NG::MenuParam& menuParam)
1618 {
1619 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
1620 return;
1621 }
1622 auto previewBorderRadiusValue = menuContentOptions->GetProperty("previewBorderRadius");
1623 NG::BorderRadiusProperty previewBorderRadius;
1624 JSViewPopups::ParseMenuPreviewBorderRadius(previewBorderRadiusValue, previewBorderRadius);
1625 menuParam.previewBorderRadius = previewBorderRadius;
1626 }
1627
ParseMenuOffsetParam(const JSRef<JSObject> & offsetObj,NG::MenuParam & menuParam)1628 void JSViewPopups::ParseMenuOffsetParam(const JSRef<JSObject>& offsetObj, NG::MenuParam& menuParam)
1629 {
1630 JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
1631 JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
1632 CalcDimension dx;
1633 CalcDimension dy;
1634 RefPtr<ResourceObject> offsetDxResObj;
1635 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx, offsetDxResObj)) {
1636 menuParam.positionOffset.SetX(dx.ConvertToPx());
1637 }
1638 RefPtr<ResourceObject> offsetDyResObj;
1639 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy, offsetDyResObj)) {
1640 menuParam.positionOffset.SetY(dy.ConvertToPx());
1641 }
1642 if (offsetDxResObj) {
1643 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MenuParam& menuParam) {
1644 CalcDimension dx;
1645 ResourceParseUtils::ParseResDimensionVp(resObj, dx);
1646 menuParam.positionOffset.SetX(dx.ConvertToPx());
1647 };
1648 menuParam.AddResource("offset.dx", offsetDxResObj, std::move(updateFunc));
1649 }
1650 if (offsetDyResObj) {
1651 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::MenuParam& menuParam) {
1652 CalcDimension dy;
1653 ResourceParseUtils::ParseResDimensionVp(resObj, dy);
1654 menuParam.positionOffset.SetY(dy.ConvertToPx());
1655 };
1656 menuParam.AddResource("offset.dy", offsetDyResObj, std::move(updateFunc));
1657 }
1658 }
1659
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)1660 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
1661 std::function<void()>& previewBuildFunc)
1662 {
1663 if (!args->IsObject()) {
1664 return;
1665 }
1666 auto menuContentOptions = JSRef<JSObject>::Cast(args);
1667 JSViewPopups::InitMenuParamColorMode(menuParam);
1668 JSViewPopups::ParseMenuParam(info, menuContentOptions, menuParam);
1669 RefPtr<JsFunction> previewBuilderFunc;
1670 auto preview = menuContentOptions->GetProperty("preview");
1671 if (!preview->IsFunction() && !preview->IsNumber()) {
1672 return;
1673 }
1674
1675 if (preview->IsNumber()) {
1676 if (preview->ToNumber<int32_t>() == 1) {
1677 menuParam.previewMode = MenuPreviewMode::IMAGE;
1678 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
1679 ParsePreviewBorderRadiusParam(menuContentOptions, menuParam);
1680 }
1681 } else {
1682 previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
1683 CHECK_NULL_VOID(previewBuilderFunc);
1684 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1685 previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
1686 node = frameNode]() {
1687 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1688 ACE_SCORING_EVENT("BuildContextMenuPreviwer");
1689 PipelineContext::SetCallBackNode(node);
1690 func->Execute();
1691 };
1692 menuParam.previewMode = MenuPreviewMode::CUSTOM;
1693 ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
1694 ParsePreviewBorderRadiusParam(menuContentOptions, menuParam);
1695 }
1696 }
1697
1698 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)1699 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
1700 {
1701 if (info.Length() < PARAMETER_LENGTH_SECOND) {
1702 return;
1703 }
1704 if ((!info[NUM_ZERO]->IsBoolean() && !info[NUM_ZERO]->IsObject()) || !info[NUM_FIRST]->IsObject()) {
1705 return;
1706 }
1707 auto popupParam = AceType::MakeRefPtr<PopupParam>();
1708 // Set IsShow to popupParam
1709 if (info[NUM_ZERO]->IsBoolean()) {
1710 popupParam->SetIsShow(info[NUM_ZERO]->ToBoolean());
1711 } else {
1712 JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[NUM_ZERO]);
1713 auto callback = JSViewPopups::ParseDoubleBindCallback(info, showObj, "$value");
1714 popupParam->SetDoubleBindCallback(std::move(callback));
1715 popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
1716 }
1717 // Set popup to popupParam
1718 auto popupObj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1719 SetPopupDismiss(info, popupObj, popupParam);
1720 if (popupObj->GetProperty("message")->IsString()) {
1721 ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
1722 ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
1723 } else if (!popupObj->GetProperty("builder").IsEmpty()) {
1724 ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
1725 auto builderValue = popupObj->GetProperty("builder");
1726 auto builder = builderValue;
1727 if (!builderValue->IsObject()) {
1728 return;
1729 }
1730 if (!builderValue->IsFunction()) {
1731 JSRef<JSObject> builderObj;
1732 builderObj = JSRef<JSObject>::Cast(builderValue);
1733 builder = builderObj->GetProperty("builder");
1734 if (!builder->IsFunction()) {
1735 return;
1736 }
1737 }
1738 RefPtr<NG::UINode> customNode;
1739 if (popupParam->IsShow() && !IsPopupCreated()) {
1740 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1741 CHECK_NULL_VOID(builderFunc);
1742 NG::ScopedViewStackProcessor builderViewStackProcessor;
1743 builderFunc->Execute();
1744 customNode = NG::ViewStackProcessor::GetInstance()->Finish();
1745 }
1746 ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
1747 } else {
1748 return;
1749 }
1750 }
1751
JsBindTips(const JSCallbackInfo & info)1752 void JSViewAbstract::JsBindTips(const JSCallbackInfo& info)
1753 {
1754 if (info.Length() < PARAMETER_LENGTH_FIRST || (!info[NUM_ZERO]->IsString() && !info[NUM_ZERO]->IsObject())) {
1755 return;
1756 }
1757 auto tipsParam = AceType::MakeRefPtr<PopupParam>();
1758 CHECK_NULL_VOID(tipsParam);
1759 // Set message to tipsParam
1760 std::string value;
1761 RefPtr<SpanString> styledString;
1762 if (info[0]->IsString()) {
1763 value = info[0]->ToString();
1764 } else {
1765 auto infoParam = info[0];
1766 if (!infoParam->IsObject()) {
1767 return;
1768 }
1769 auto* spanString = JSRef<JSObject>::Cast(infoParam)->Unwrap<JSSpanString>();
1770 if (!spanString) {
1771 JSViewAbstract::ParseJsString(infoParam, value);
1772 } else {
1773 styledString = spanString->GetController();
1774 }
1775 }
1776 tipsParam->SetMessage(value);
1777 // Set bindTipsOptions to tipsParam
1778 JSRef<JSObject> tipsObj;
1779 if (info.Length() > PARAMETER_LENGTH_FIRST && info[1]->IsObject()) {
1780 tipsObj = JSRef<JSObject>::Cast(info[1]);
1781 } else {
1782 tipsObj = JSRef<JSObject>::New();
1783 }
1784 // Parse bindTipsOptions param
1785 ParseTipsParam(tipsObj, tipsParam);
1786 if (tipsParam->EnableArrow()) {
1787 ParseTipsArrowPositionParam(tipsObj, tipsParam);
1788 ParseTipsArrowSizeParam(tipsObj, tipsParam);
1789 }
1790 ViewAbstractModel::GetInstance()->BindTips(tipsParam, styledString);
1791 }
1792
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1793 void JSViewAbstract::SetPopupDismiss(
1794 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1795 {
1796 auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
1797 if (onWillDismissFunc->IsBoolean()) {
1798 bool onWillDismissBool = onWillDismissFunc->ToBoolean();
1799 popupParam->SetInteractiveDismiss(onWillDismissBool);
1800 popupParam->SetOnWillDismiss(nullptr);
1801 if (onWillDismissBool) {
1802 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
1803 }
1804 } else if (onWillDismissFunc->IsFunction()) {
1805 auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
1806 popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
1807 popupParam->SetInteractiveDismiss(true);
1808 if (onWillDismissCallback != nullptr) {
1809 TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
1810 }
1811 }
1812 }
1813
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)1814 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
1815 {
1816 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
1817 if (!onWillDismissFunc->IsFunction()) {
1818 return PopupOnWillDismiss();
1819 }
1820 RefPtr<JsFunction> jsFunc =
1821 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
1822 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1823 auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
1824 node = frameNode](int32_t reason) {
1825 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1826 ACE_SCORING_EVENT("Bindpopup.dismiss");
1827 PipelineContext::SetCallBackNode(node);
1828
1829 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1830 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
1831 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1832 dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
1833 dismissObj->SetProperty<int32_t>("reason", reason);
1834 JSRef<JSVal> newJSVal = dismissObj;
1835 func->ExecuteJS(1, &newJSVal);
1836 };
1837 return onWillDismiss;
1838 }
1839
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)1840 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1841 {
1842 ViewAbstractModel::GetInstance()->DismissPopup();
1843 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1844 }
1845
ParseContentPopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1846 void JSViewAbstract::ParseContentPopupCommonParam(
1847 const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1848 {
1849 CHECK_EQUAL_VOID(popupObj->IsEmpty(), true);
1850 CHECK_NULL_VOID(popupParam);
1851 int32_t targetId = StringUtils::StringToInt(popupParam->GetTargetId(), -1);
1852 if (targetId < 0) {
1853 TAG_LOGE(AceLogTag::ACE_DIALOG, "The targetId is error.");
1854 return;
1855 }
1856 auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<NG::FrameNode>(targetId);
1857 if (!targetNode) {
1858 TAG_LOGE(AceLogTag::ACE_DIALOG, "The targetNode does not exist.");
1859 return;
1860 }
1861 SetPopupDismiss(info, popupObj, popupParam);
1862 ParsePopupCommonParam(info, popupObj, popupParam, targetNode);
1863 auto focusableValue = popupObj->GetProperty("focusable");
1864 if (focusableValue->IsBoolean()) {
1865 popupParam->SetFocusable(focusableValue->ToBoolean());
1866 }
1867 }
1868
OpenPopup(const RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1869 int32_t JSViewAbstract::OpenPopup(const RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1870 {
1871 return ViewAbstractModel::GetInstance()->OpenPopup(param, customNode);
1872 }
1873
UpdatePopup(const RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1874 int32_t JSViewAbstract::UpdatePopup(const RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1875 {
1876 return ViewAbstractModel::GetInstance()->UpdatePopup(param, customNode);
1877 }
1878
ClosePopup(const RefPtr<NG::UINode> & customNode)1879 int32_t JSViewAbstract::ClosePopup(const RefPtr<NG::UINode>& customNode)
1880 {
1881 return ViewAbstractModel::GetInstance()->ClosePopup(customNode);
1882 }
1883
GetPopupParam(RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1884 int32_t JSViewAbstract::GetPopupParam(RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1885 {
1886 return ViewAbstractModel::GetInstance()->GetPopupParam(param, customNode);
1887 }
1888
JsBindContextMenu(const JSCallbackInfo & info)1889 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
1890 {
1891 NG::MenuParam menuParam;
1892 // Check the parameters
1893 if (info.Length() <= PARAMETER_LENGTH_ZERO) {
1894 return;
1895 }
1896 size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
1897 if (!info[builderIndex]->IsObject()) {
1898 return;
1899 }
1900
1901 JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
1902 auto builder = menuObj->GetProperty("builder");
1903 if (!builder->IsFunction()) {
1904 return;
1905 }
1906 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1907 CHECK_NULL_VOID(builderFunc);
1908
1909 ResponseType responseType = ResponseType::LONG_PRESS;
1910 if (!info[NUM_ZERO]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[NUM_FIRST]->IsNumber()) {
1911 auto response = info[NUM_FIRST]->ToNumber<int32_t>();
1912 responseType = static_cast<ResponseType>(response);
1913 }
1914 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1915 std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
1916 node = frameNode]() {
1917 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1918 ACE_SCORING_EVENT("BuildContextMenu");
1919 PipelineContext::SetCallBackNode(node);
1920 func->Execute();
1921 };
1922
1923 menuParam.previewMode = MenuPreviewMode::NONE;
1924 std::function<void()> previewBuildFunc = nullptr;
1925 if (info.Length() >= PARAMETER_LENGTH_THIRD && info[NUM_SECOND]->IsObject()) {
1926 ParseBindContentOptionParam(info, info[NUM_SECOND], menuParam, previewBuildFunc);
1927 }
1928 if (responseType != ResponseType::LONG_PRESS) {
1929 menuParam.previewMode = MenuPreviewMode::NONE;
1930 menuParam.isShowHoverImage = false;
1931 menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
1932 }
1933 // arrow is disabled for contextMenu with preview
1934 if (menuParam.previewMode != MenuPreviewMode::NONE) {
1935 menuParam.enableArrow = false;
1936 }
1937 menuParam.type = NG::MenuType::CONTEXT_MENU;
1938 ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
1939 ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
1940 }
1941 #endif
1942
JsBindContentCover(const JSCallbackInfo & info)1943 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
1944 {
1945 // parse isShow
1946 DoubleBindCallback callback = nullptr;
1947 bool isShow = ParseSheetIsShow(info, "ContentCover", callback);
1948
1949 // parse builder
1950 if (!info[NUM_FIRST]->IsObject()) {
1951 return;
1952 }
1953 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1954 auto builder = obj->GetProperty("builder");
1955 if (!builder->IsFunction()) {
1956 return;
1957 }
1958 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1959 CHECK_NULL_VOID(builderFunc);
1960 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1961 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
1962 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1963 ACE_SCORING_EVENT("BindContentCover");
1964 PipelineContext::SetCallBackNode(node);
1965 func->Execute();
1966 };
1967
1968 // parse ModalTransition
1969 NG::ModalStyle modalStyle;
1970 modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
1971 std::function<void()> onShowCallback;
1972 std::function<void()> onDismissCallback;
1973 std::function<void()> onWillShowCallback;
1974 std::function<void()> onWillDismissCallback;
1975 NG::ContentCoverParam contentCoverParam;
1976 std::function<void(const int32_t&)> onWillDismissFunc;
1977 if (info.Length() == PARAMETER_LENGTH_THIRD) {
1978 if (info[NUM_SECOND]->IsObject()) {
1979 ParseOverlayCallback(info[NUM_SECOND], onShowCallback, onDismissCallback, /* 2:args index */
1980 onWillShowCallback, onWillDismissCallback, onWillDismissFunc);
1981 ParseModalStyle(info[NUM_SECOND], modalStyle);
1982 contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
1983 ParseModalTransitonEffect(info[NUM_SECOND], contentCoverParam, /* 2:args index */
1984 info.GetExecutionContext());
1985 ParseEnableSafeArea(info[NUM_SECOND], contentCoverParam);
1986 } else if (info[NUM_SECOND]->IsNumber()) {
1987 auto transitionNumber = info[NUM_SECOND]->ToNumber<int32_t>();
1988 if (transitionNumber >= TRANSITION_NUM_ZERO && transitionNumber <= TRANSITION_NUM_TWO) {
1989 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
1990 }
1991 }
1992 }
1993 ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
1994 std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
1995 std::move(onWillDismissCallback), contentCoverParam);
1996 }
1997
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)1998 void JSViewAbstract::ParseModalTransitonEffect(
1999 const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
2000 {
2001 auto transitionEffectValue = paramObj->GetProperty("transition");
2002 if (transitionEffectValue->IsObject()) {
2003 JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
2004 contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
2005 }
2006 }
2007
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)2008 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
2009 {
2010 auto modalTransitionValue = paramObj->GetProperty("modalTransition");
2011 ParseModalTransition(modalTransitionValue, modalStyle.modalTransition, NG::ModalTransition::DEFAULT);
2012 auto backgroundColor = paramObj->GetProperty("backgroundColor");
2013 Color color;
2014 if (SystemProperties::ConfigChangePerform()) {
2015 // When the switch is turned on, the modal background color and its resource are parsed together.
2016 RefPtr<ResourceObject> resObj;
2017 if (ParseJsColor(backgroundColor, color, resObj)) {
2018 modalStyle.SetBackgroundColorResObj(resObj);
2019 modalStyle.backgroundColor = color;
2020 }
2021 } else {
2022 if (ParseJsColor(backgroundColor, color)) {
2023 modalStyle.backgroundColor = color;
2024 }
2025 }
2026 }
2027
ParseModalTransition(const JSRef<JSVal> & jsValue,std::optional<NG::ModalTransition> & modalTransition,NG::ModalTransition defaultTransition)2028 void JSViewAbstract::ParseModalTransition(const JSRef<JSVal>& jsValue,
2029 std::optional<NG::ModalTransition>& modalTransition, NG::ModalTransition defaultTransition)
2030 {
2031 if (jsValue->IsNull() || jsValue->IsUndefined()) {
2032 modalTransition = defaultTransition;
2033 } else if (jsValue->IsNumber()) {
2034 auto transitionNumber = jsValue->ToNumber<int32_t>();
2035 if (transitionNumber >= TRANSITION_NUM_ZERO && transitionNumber <= TRANSITION_NUM_TWO) {
2036 modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
2037 } else {
2038 modalTransition = defaultTransition;
2039 }
2040 }
2041 }
2042
ParseEnableSafeArea(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam)2043 void JSViewAbstract::ParseEnableSafeArea(const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam)
2044 {
2045 auto enableSafeArea = paramObj->GetProperty("enableSafeArea");
2046 if (enableSafeArea->IsBoolean()) {
2047 bool enable = enableSafeArea->ToBoolean();
2048 contentCoverParam.enableSafeArea = enable;
2049 }
2050 }
2051
ParseSheetIsShow(const JSCallbackInfo & info,const std::string & name,std::function<void (const std::string &)> & callback)2052 bool JSViewAbstract::ParseSheetIsShow(const JSCallbackInfo& info, const std::string& name,
2053 std::function<void(const std::string&)>& callback)
2054 {
2055 bool isShow = false;
2056 auto tmpInfo = info[0];
2057 if (tmpInfo->IsBoolean()) {
2058 isShow = tmpInfo->ToBoolean();
2059 } else if (tmpInfo->IsObject()) {
2060 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(tmpInfo);
2061 auto isShowObj = callbackObj->GetProperty("value");
2062 isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
2063 callback = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "changeEvent");
2064 if (!callback && Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
2065 TAG_LOGD(AceLogTag::ACE_SHEET, "Try %{public}s another parsing", name.c_str());
2066 callback = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
2067 }
2068 }
2069 TAG_LOGD(AceLogTag::ACE_SHEET, "%{public}s get isShow is: %{public}d", name.c_str(), isShow);
2070 return isShow;
2071 }
2072
JsBindSheet(const JSCallbackInfo & info)2073 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
2074 {
2075 // parse isShow and builder
2076 DoubleBindCallback callback = nullptr;
2077 bool isShow = ParseSheetIsShow(info, "Sheet", callback);
2078 if (!info[NUM_FIRST]->IsObject())
2079 return;
2080 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
2081 auto builder = obj->GetProperty("builder");
2082 if (!builder->IsFunction())
2083 return;
2084 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2085 CHECK_NULL_VOID(builderFunc);
2086 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2087 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
2088 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2089 ACE_SCORING_EVENT("BindSheet");
2090 PipelineContext::SetCallBackNode(node);
2091 func->Execute();
2092 };
2093 // parse SheetStyle and callbacks
2094 NG::SheetStyle sheetStyle;
2095 sheetStyle.sheetHeight.sheetMode = NG::SheetMode::LARGE;
2096 sheetStyle.enableFloatingDragBar = false;
2097 sheetStyle.showDragBar = true;
2098 sheetStyle.showCloseIcon = true;
2099 sheetStyle.showInPage = false;
2100 std::function<void()> onAppearCallback;
2101 std::function<void()> onDisappearCallback;
2102 std::function<void()> onWillAppearCallback;
2103 std::function<void()> onWillDisappearCallback;
2104 std::function<void()> shouldDismissFunc;
2105 std::function<void(const int32_t)> onWillDismissCallback;
2106 std::function<void(const float)> onHeightDidChangeCallback;
2107 std::function<void(const float)> onDetentsDidChangeCallback;
2108 std::function<void(const float)> onWidthDidChangeCallback;
2109 std::function<void(const float)> onTypeDidChangeCallback;
2110 std::function<void()> titleBuilderFunction;
2111 std::function<void()> sheetSpringBackFunc;
2112 if (info.Length() == PARAMETER_LENGTH_THIRD && info[NUM_SECOND]->IsObject()) {
2113 ParseSheetCallback(info[NUM_SECOND], onAppearCallback, onDisappearCallback, shouldDismissFunc,
2114 onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
2115 onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
2116 ParseSheetStyle(info[NUM_SECOND], sheetStyle);
2117 ParseSheetTitle(info[NUM_SECOND], sheetStyle, titleBuilderFunction);
2118 }
2119 ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
2120 std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
2121 std::move(shouldDismissFunc), std::move(onWillDismissCallback), std::move(onWillAppearCallback),
2122 std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
2123 std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
2124 }
2125
ParseSheetEffectEdge(const JSRef<JSObject> & paramObj)2126 NG::SheetEffectEdge JSViewAbstract::ParseSheetEffectEdge(const JSRef<JSObject>& paramObj)
2127 {
2128 auto sheetEffectEdge = static_cast<int32_t>(NG::SheetEffectEdge::ALL);
2129 JSRef<JSVal> effectEdgedParam = paramObj->GetProperty("effectEdge");
2130 if (effectEdgedParam->IsNull() || effectEdgedParam->IsUndefined() ||
2131 !JSViewAbstract::ParseJsInt32(effectEdgedParam, sheetEffectEdge) ||
2132 sheetEffectEdge < static_cast<int32_t>(NG::SheetEffectEdge::NONE) ||
2133 sheetEffectEdge > static_cast<int32_t>(NG::SheetEffectEdge::END)) {
2134 sheetEffectEdge = static_cast<int32_t>(NG::SheetEffectEdge::ALL);
2135 }
2136 return static_cast<NG::SheetEffectEdge>(sheetEffectEdge);
2137 }
2138
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)2139 void JSViewAbstract::ParseSheetStyle(
2140 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
2141 {
2142 auto height = paramObj->GetProperty("height");
2143 auto showDragBar = paramObj->GetProperty("dragBar");
2144 auto floatingDragBar = paramObj->GetProperty("enableFloatingDragBar");
2145 auto backgroundColor = paramObj->GetProperty("backgroundColor");
2146 auto maskColor = paramObj->GetProperty("maskColor");
2147 auto sheetDetents = paramObj->GetProperty("detents");
2148 auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
2149 auto showCloseIcon = paramObj->GetProperty("showClose");
2150 auto type = paramObj->GetProperty("preferType");
2151 auto interactive = paramObj->GetProperty("enableOutsideInteractive");
2152 auto showMode = paramObj->GetProperty("mode");
2153 auto offsetVal = paramObj->GetProperty("offset");
2154 auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
2155 auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
2156 auto uiContextObj = paramObj->GetProperty("uiContext");
2157 if (uiContextObj->IsObject()) {
2158 JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
2159 auto prop = obj->GetProperty("instanceId_");
2160 if (prop->IsNumber()) {
2161 sheetStyle.instanceId = prop->ToNumber<int32_t>();
2162 }
2163 }
2164
2165 if (offsetVal->IsObject()) {
2166 auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
2167 auto xVal = offsetObj->GetProperty("x");
2168 auto yVal = offsetObj->GetProperty("y");
2169 NG::OffsetF bottomOffset;
2170 CalcDimension dx;
2171 CalcDimension dy;
2172 if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
2173 bottomOffset.SetX(dx.ConvertToPx());
2174 }
2175 if (JSViewAbstract::ParseJsDimensionVp(yVal, dy) && dy.IsNegative()) {
2176 bottomOffset.SetY(dy.ConvertToPx());
2177 }
2178 sheetStyle.bottomOffset = bottomOffset;
2179 }
2180
2181 NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
2182 if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
2183 sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
2184 }
2185
2186 std::vector<NG::SheetHeight> detents;
2187 if (ParseSheetDetents(sheetDetents, detents, sheetStyle)) {
2188 sheetStyle.detents = detents;
2189 }
2190 BlurStyleOption styleOption;
2191 if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
2192 sheetStyle.backgroundBlurStyle = styleOption;
2193 }
2194
2195 if (showDragBar->IsBoolean()) {
2196 sheetStyle.showDragBar = showDragBar->ToBoolean();
2197 } else if (isPartialUpdate) {
2198 sheetStyle.showDragBar.reset();
2199 } else {
2200 sheetStyle.showDragBar = true;
2201 }
2202
2203 if (floatingDragBar->IsBoolean()) {
2204 sheetStyle.enableFloatingDragBar = floatingDragBar->ToBoolean();
2205 } else if (isPartialUpdate) {
2206 sheetStyle.enableFloatingDragBar.reset();
2207 } else {
2208 sheetStyle.enableFloatingDragBar = false;
2209 }
2210
2211 if (type->IsNull() || type->IsUndefined()) {
2212 sheetStyle.sheetType.reset();
2213 } else {
2214 if (type->IsNumber()) {
2215 auto sheetType = type->ToNumber<int32_t>();
2216 if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
2217 sheetType <= static_cast<int>(NG::SheetType::SHEET_CONTENT_COVER)) {
2218 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
2219 }
2220 }
2221 }
2222
2223 bool isInteractive = false;
2224 if (NG::SheetType::SHEET_CONTENT_COVER == sheetStyle.sheetType) {
2225 sheetStyle.interactive = true;
2226 } else if (ParseJsBool(interactive, isInteractive)) {
2227 sheetStyle.interactive = isInteractive;
2228 }
2229
2230 bool showClose = true;
2231 if (NG::SheetType::SHEET_CONTENT_COVER == sheetStyle.sheetType) {
2232 sheetStyle.showCloseIcon = false;
2233 } else if (SystemProperties::ConfigChangePerform()) {
2234 // When the switch is turned on, the sheet closeIcon and its resource are parsed together.
2235 RefPtr<ResourceObject> resObj;
2236 if (ParseJsBool(showCloseIcon, showClose, resObj)) {
2237 sheetStyle.showCloseIcon = showClose;
2238 sheetStyle.SetShowCloseResObj(resObj);
2239 } else if (!isPartialUpdate) {
2240 sheetStyle.showCloseIcon = true;
2241 }
2242 } else {
2243 if (ParseJsBool(showCloseIcon, showClose)) {
2244 sheetStyle.showCloseIcon = showClose;
2245 } else if (!isPartialUpdate) {
2246 sheetStyle.showCloseIcon = true;
2247 }
2248 }
2249
2250 if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
2251 sheetStyle.scrollSizeMode.reset();
2252 } else if (scrollSizeMode->IsNumber()) {
2253 auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
2254 if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
2255 sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
2256 sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
2257 }
2258 }
2259
2260 if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
2261 sheetStyle.sheetKeyboardAvoidMode.reset();
2262 } else if (keyboardAvoidMode->IsNumber()) {
2263 auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
2264 if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
2265 sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::POPUP_SHEET)) {
2266 sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
2267 }
2268 }
2269
2270 auto placement = paramObj->GetProperty("placement");
2271 sheetStyle.placement.reset();
2272 if (placement->IsNumber()) {
2273 auto placementValue = placement->ToNumber<int32_t>();
2274 if (placementValue >= static_cast<int>(Placement::LEFT) &&
2275 placementValue <= static_cast<int>(Placement::RIGHT_BOTTOM)) {
2276 sheetStyle.placement = static_cast<Placement>(placementValue);
2277 }
2278 }
2279
2280 auto placementOnTarget = paramObj->GetProperty("placementOnTarget");
2281 sheetStyle.placementOnTarget.reset();
2282 if (placementOnTarget->IsBoolean()) {
2283 sheetStyle.placementOnTarget = placementOnTarget->ToBoolean();
2284 }
2285
2286 Color color;
2287 if (SystemProperties::ConfigChangePerform()) {
2288 // When the switch is turned on, the sheet background color and its resource are parsed together.
2289 RefPtr<ResourceObject> resObj;
2290 if (ParseJsColor(backgroundColor, color, resObj)) {
2291 sheetStyle.backgroundColor = color;
2292 sheetStyle.SetBackgroundColorResObj(resObj);
2293 }
2294 } else {
2295 if (ParseJsColor(backgroundColor, color)) {
2296 sheetStyle.backgroundColor = color;
2297 }
2298 }
2299 // parse maskColor
2300 Color parseMaskColor;
2301 if (SystemProperties::ConfigChangePerform()) {
2302 // When the switch is turned on, the sheet maskColor and its resource are parsed together.
2303 RefPtr<ResourceObject> resObj;
2304 if (!maskColor->IsNull() && !maskColor->IsUndefined() &&
2305 JSViewAbstract::ParseJsColor(maskColor, parseMaskColor, resObj)) {
2306 sheetStyle.maskColor = std::move(parseMaskColor);
2307 sheetStyle.SetMaskColorResObj(resObj);
2308 }
2309 } else {
2310 if (!maskColor->IsNull() && !maskColor->IsUndefined() &&
2311 JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
2312 sheetStyle.maskColor = std::move(parseMaskColor);
2313 }
2314 }
2315
2316 // Parse border width
2317 auto borderWidthValue = paramObj->GetProperty("borderWidth");
2318 NG::BorderWidthProperty borderWidth;
2319 if (SystemProperties::ConfigChangePerform()) {
2320 // When the switch is turned on, the sheet borderWidth and its resource are parsed together.
2321 RefPtr<ResourceObject> borderWidthResObj;
2322 if (ParseBorderWidthProps(borderWidthValue, borderWidth, borderWidthResObj)) {
2323 sheetStyle.borderWidth = borderWidth;
2324 sheetStyle.SetBorderWidthResObj(borderWidthResObj);
2325
2326 // When the switch is turned on, the sheet borderColor and its resource are parsed together,
2327 // when borderWidth and borderColor are set at the same time.
2328 auto colorValue = paramObj->GetProperty("borderColor");
2329 NG::BorderColorProperty borderColor;
2330 RefPtr<ResourceObject> borderColorResObj;
2331 if (ParseBorderColorProps(colorValue, borderColor, borderColorResObj)) {
2332 sheetStyle.borderColor = borderColor;
2333 } else {
2334 sheetStyle.borderColor =
2335 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
2336 }
2337 sheetStyle.SetBorderColorResObj(borderColorResObj);
2338 // Parse border style
2339 auto styleValue = paramObj->GetProperty("borderStyle");
2340 NG::BorderStyleProperty borderStyle;
2341 if (ParseBorderStyleProps(styleValue, borderStyle)) {
2342 sheetStyle.borderStyle = borderStyle;
2343 } else {
2344 sheetStyle.borderStyle = NG::BorderStyleProperty(
2345 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
2346 }
2347 }
2348 } else {
2349 if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
2350 sheetStyle.borderWidth = borderWidth;
2351 // Parse border color
2352 auto colorValue = paramObj->GetProperty("borderColor");
2353 NG::BorderColorProperty borderColor;
2354 if (ParseBorderColorProps(colorValue, borderColor)) {
2355 sheetStyle.borderColor = borderColor;
2356 } else {
2357 sheetStyle.borderColor =
2358 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
2359 }
2360 // Parse border style
2361 auto styleValue = paramObj->GetProperty("borderStyle");
2362 NG::BorderStyleProperty borderStyle;
2363 if (ParseBorderStyleProps(styleValue, borderStyle)) {
2364 sheetStyle.borderStyle = borderStyle;
2365 } else {
2366 sheetStyle.borderStyle = NG::BorderStyleProperty(
2367 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
2368 }
2369 }
2370 }
2371 if (isPartialUpdate) {
2372 auto colorValue = paramObj->GetProperty("borderColor");
2373 NG::BorderColorProperty borderColor;
2374 if (ParseBorderColorProps(colorValue, borderColor)) {
2375 sheetStyle.borderColor = borderColor;
2376 } else {
2377 sheetStyle.borderColor.reset();
2378 }
2379 auto styleValue = paramObj->GetProperty("borderStyle");
2380 NG::BorderStyleProperty borderStyle;
2381 if (ParseBorderStyleProps(styleValue, borderStyle)) {
2382 sheetStyle.borderStyle = borderStyle;
2383 } else {
2384 sheetStyle.borderStyle.reset();
2385 }
2386 }
2387
2388 // Parse shadow
2389 Shadow shadow;
2390 auto shadowValue = paramObj->GetProperty("shadow");
2391 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
2392 sheetStyle.shadow = shadow;
2393 }
2394
2395 //parse effectEdge
2396 sheetStyle.sheetEffectEdge = ParseSheetEffectEdge(paramObj);
2397
2398 // Parse hoverMode
2399 auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode");
2400 if (enableHoverModeValue->IsBoolean()) {
2401 sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean();
2402 }
2403 auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea");
2404 if (hoverModeAreaValue->IsNumber()) {
2405 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
2406 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
2407 sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
2408 }
2409 }
2410
2411 auto widthValue = paramObj->GetProperty("width");
2412 CalcDimension width;
2413 if (SystemProperties::ConfigChangePerform()) {
2414 // When the switch is turned on, the sheet width and its resource are parsed together.
2415 RefPtr<ResourceObject> resObj;
2416 if (ParseJsDimensionVpNG(widthValue, width, resObj, true)) {
2417 sheetStyle.SetSheetWidthResObj(resObj);
2418 sheetStyle.width = width;
2419 }
2420 } else {
2421 if (ParseJsDimensionVpNG(widthValue, width, true)) {
2422 sheetStyle.width = width;
2423 }
2424 }
2425
2426 auto radiusValue = paramObj->GetProperty("radius");
2427 if (SystemProperties::ConfigChangePerform()) {
2428 // When the switch is turned on, the sheet radius and its resource are parsed together.
2429 RefPtr<ResourceObject> resObj;
2430 JSViewAbstract::ParseBindSheetBorderRadius(radiusValue, sheetStyle, resObj);
2431 sheetStyle.SetRadiusResObj(resObj);
2432 } else {
2433 JSViewAbstract::ParseBindSheetBorderRadius(radiusValue, sheetStyle);
2434 }
2435
2436 ParseDetentSelection(paramObj, sheetStyle);
2437
2438 NG::SheetHeight sheetStruct;
2439 bool parseResult = false;
2440 if (SystemProperties::ConfigChangePerform()) {
2441 // When the switch is turned on, the sheet height and its resource are parsed together.
2442 RefPtr<ResourceObject> heightResObj;
2443 parseResult = ParseSheetHeight(height, sheetStruct, isPartialUpdate, heightResObj);
2444 sheetStyle.SetSheetHeightResObj(heightResObj);
2445 } else {
2446 parseResult = ParseSheetHeight(height, sheetStruct, isPartialUpdate);
2447 }
2448 if (!parseResult) {
2449 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet height in unnormal condition");
2450 }
2451 sheetStyle.sheetHeight = sheetStruct;
2452
2453 ParseSheetSubWindowValue(paramObj, sheetStyle);
2454
2455 // parse ModalTransition
2456 auto modalTransitionValue = paramObj->GetProperty("modalTransition");
2457 ParseModalTransition(modalTransitionValue, sheetStyle.modalTransition, NG::ModalTransition::DEFAULT);
2458 }
2459
ParseSheetSubWindowValue(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)2460 void JSViewAbstract::ParseSheetSubWindowValue(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
2461 {
2462 // parse sheet showInSubWindow
2463 sheetStyle.showInSubWindow = false;
2464 // content cover is not shown in sub window
2465 if (sheetStyle.sheetType.has_value() && sheetStyle.sheetType.value() == NG::SheetType::SHEET_CONTENT_COVER) {
2466 sheetStyle.showInSubWindow = false;
2467 return;
2468 }
2469 if (sheetStyle.showInPage == NG::SheetLevel::EMBEDDED) {
2470 return;
2471 }
2472 auto showInSubWindowValue = paramObj->GetProperty("showInSubWindow");
2473 if (showInSubWindowValue->IsBoolean()) {
2474 #if defined(PREVIEW)
2475 LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Perform this operation on the "
2476 "emulator or a real device instead.");
2477 #else
2478 sheetStyle.showInSubWindow = showInSubWindowValue->ToBoolean();
2479 #endif
2480 }
2481 }
2482
ParseDetentSelection(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)2483 void JSViewAbstract::ParseDetentSelection(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
2484 {
2485 auto detentSelection = paramObj->GetProperty("detentSelection");
2486 NG::SheetHeight sheetStruct;
2487 bool parseResult = false;
2488 if (SystemProperties::ConfigChangePerform()) {
2489 // When the switch is turned on, the sheet detentSelection and its resource are parsed together.
2490 RefPtr<ResourceObject> resObj;
2491 parseResult = ParseSheetHeight(detentSelection, sheetStruct, true, resObj);
2492 sheetStyle.SetDetentSelectionResObj(resObj);
2493 } else {
2494 parseResult = ParseSheetHeight(detentSelection, sheetStruct, true);
2495 }
2496 if (!parseResult) {
2497 sheetStruct.height.reset();
2498 sheetStruct.sheetMode.reset();
2499 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent selection in unnormal condition");
2500 }
2501 sheetStyle.detentSelection = sheetStruct;
2502 }
2503
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents,NG::SheetStyle & sheetStyle)2504 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args,
2505 std::vector<NG::SheetHeight>& sheetDetents, NG::SheetStyle& sheetStyle)
2506 {
2507 if (!args->IsArray()) {
2508 return false;
2509 }
2510 JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
2511 NG::SheetHeight sheetDetent;
2512 std::vector<RefPtr<ResourceObject>> detentsResObj;
2513 for (size_t i = 0; i < array->Length(); i++) {
2514 bool parseResult = false;
2515 if (SystemProperties::ConfigChangePerform()) {
2516 // When the switch is turned on, the sheet detents and its resource are parsed together.
2517 RefPtr<ResourceObject> resObj;
2518 parseResult = ParseSheetHeight(array->GetValueAt(i), sheetDetent, false, resObj);
2519 detentsResObj.push_back(resObj);
2520 } else {
2521 parseResult = ParseSheetHeight(array->GetValueAt(i), sheetDetent, false);
2522 }
2523 if (!parseResult) {
2524 TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent in unnormal condition");
2525 }
2526 if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
2527 continue;
2528 }
2529 sheetDetents.emplace_back(sheetDetent);
2530 sheetDetent.height.reset();
2531 sheetDetent.sheetMode.reset();
2532 }
2533 if (SystemProperties::ConfigChangePerform()) {
2534 sheetStyle.SetDetentsResObjs(std::move(detentsResObj));
2535 }
2536 return true;
2537 }
2538
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)2539 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
2540 {
2541 if (args->IsNumber()) {
2542 auto sheetBlurStyle = args->ToNumber<int32_t>();
2543 if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
2544 sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
2545 blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
2546 } else {
2547 return false;
2548 }
2549 } else {
2550 return false;
2551 }
2552 return true;
2553 }
2554
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)2555 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
2556 {
2557 if (!args->IsNumber()) {
2558 return false;
2559 }
2560 auto sheetMode = args->ToNumber<int32_t>();
2561 if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
2562 sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
2563 sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
2564 return true;
2565 }
2566 return false;
2567 }
2568
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)2569 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
2570 std::function<void(const float)>& callbackDidChange, const char* prop)
2571 {
2572 auto callBack = paramObj->GetProperty(prop);
2573 if (callBack->IsFunction()) {
2574 RefPtr<JsFunction> jsFunc =
2575 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
2576 callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
2577 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
2578 func->ExecuteJS(1, ¶m);
2579 };
2580 }
2581 }
2582
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)2583 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
2584 std::function<void()>& lifeCycleCallBack, const char* prop)
2585 {
2586 auto callback = paramObj->GetProperty(prop);
2587 if (callback->IsFunction()) {
2588 RefPtr<JsFunction> jsFunc =
2589 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
2590 lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
2591 }
2592 }
2593
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)2594 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
2595 std::function<void()>& sheetSpringBack, const char* prop)
2596 {
2597 auto sheetSpringBackCallback = paramObj->GetProperty(prop);
2598 if (sheetSpringBackCallback->IsFunction()) {
2599 RefPtr<JsFunction> jsFunc =
2600 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
2601 sheetSpringBack = [func = std::move(jsFunc)]() {
2602 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
2603 objectTemplate->SetInternalFieldCount(1);
2604 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
2605 dismissObj->SetPropertyObject(
2606 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
2607 JSRef<JSVal> newJSVal = dismissObj;
2608 func->ExecuteJS(1, &newJSVal);
2609 };
2610 }
2611 }
2612
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)2613 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
2614 std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
2615 std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
2616 std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
2617 std::function<void(const float)>& onDetentsDidChange,
2618 std::function<void(const float)>& onWidthDidChange,
2619 std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
2620 {
2621 auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
2622 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
2623 ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
2624 ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
2625 ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
2626 ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
2627 if (shouldDismissFunc->IsFunction()) {
2628 RefPtr<JsFunction> jsFunc =
2629 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
2630 shouldDismiss = [func = std::move(jsFunc)]() {
2631 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
2632 objectTemplate->SetInternalFieldCount(1);
2633 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
2634 dismissObj->SetPropertyObject(
2635 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
2636 JSRef<JSVal> newJSVal = dismissObj;
2637 func->ExecuteJS(1, &newJSVal);
2638 };
2639 }
2640 if (onWillDismissFunc->IsFunction()) {
2641 RefPtr<JsFunction> jsFunc =
2642 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
2643 onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
2644 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
2645 objectTemplate->SetInternalFieldCount(1);
2646 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
2647 dismissObj->SetPropertyObject(
2648 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
2649 dismissObj->SetProperty<int32_t>("reason", info);
2650 JSRef<JSVal> newJSVal = dismissObj;
2651 func->ExecuteJS(1, &newJSVal);
2652 };
2653 }
2654 ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
2655 ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
2656 ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
2657 ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
2658 ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
2659 }
2660
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)2661 void JSViewAbstract::ParseSheetTitle(
2662 const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
2663 {
2664 auto title = paramObj->GetProperty("title");
2665 std::string mainTitle;
2666 std::string subtitle;
2667 if (title->IsFunction()) {
2668 sheetStyle.isTitleBuilder = true;
2669 auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
2670 CHECK_NULL_VOID(titleBuilderFunc);
2671 titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
2672 ACE_SCORING_EVENT("BindSheet");
2673 func->Execute();
2674 };
2675 } else if (title->IsObject()) {
2676 JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
2677 sheetStyle.isTitleBuilder = false;
2678 auto sheetTitle = obj->GetProperty("title");
2679 auto sheetSubtitle = obj->GetProperty("subtitle");
2680 if (SystemProperties::ConfigChangePerform()) {
2681 // When the switch is turned on, the sheet title and its resource are parsed together.
2682 RefPtr<ResourceObject> mainTitleResObj;
2683 if (ParseJsString(sheetTitle, mainTitle, mainTitleResObj)) {
2684 sheetStyle.sheetTitle = mainTitle;
2685 sheetStyle.SetMainTitleResObj(mainTitleResObj);
2686 }
2687
2688 // When the switch is turned on, the sheet subtitle and its resource are parsed together,
2689 // when title and subtitle are set at the same time.
2690 RefPtr<ResourceObject> subTitleResObj;
2691 if (ParseJsString(sheetSubtitle, subtitle, subTitleResObj)) {
2692 sheetStyle.sheetSubtitle = subtitle;
2693 sheetStyle.SetSubTitleResObj(subTitleResObj);
2694 }
2695 } else {
2696 if (ParseJsString(sheetTitle, mainTitle)) {
2697 sheetStyle.sheetTitle = mainTitle;
2698 }
2699 if (ParseJsString(sheetSubtitle, subtitle)) {
2700 sheetStyle.sheetSubtitle = subtitle;
2701 }
2702 }
2703 }
2704 }
2705
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)2706 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
2707 {
2708 ViewAbstractModel::GetInstance()->DismissSheet();
2709 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
2710 }
2711
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)2712 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
2713 {
2714 ViewAbstractModel::GetInstance()->DismissContentCover();
2715 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
2716 }
2717
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)2718 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
2719 {
2720 ViewAbstractModel::GetInstance()->SheetSpringBack();
2721 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
2722 }
2723
ParseSheetMode(const std::string heightStr,NG::SheetHeight & detent)2724 bool JSViewAbstract::ParseSheetMode(const std::string heightStr, NG::SheetHeight& detent)
2725 {
2726 if (heightStr == SHEET_HEIGHT_MEDIUM) {
2727 detent.sheetMode = NG::SheetMode::MEDIUM;
2728 return true;
2729 }
2730
2731 if (heightStr == SHEET_HEIGHT_LARGE) {
2732 detent.sheetMode = NG::SheetMode::LARGE;
2733 return true;
2734 }
2735 if (heightStr == SHEET_HEIGHT_FITCONTENT) {
2736 detent.sheetMode = NG::SheetMode::AUTO;
2737 return true;
2738 }
2739 return false;
2740 }
2741
ParseSheetHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent,bool isReset)2742 bool JSViewAbstract::ParseSheetHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent,
2743 bool isReset)
2744 {
2745 RefPtr<ResourceObject> resObj;
2746 return ParseSheetHeight(args, detent, isReset, resObj);
2747 }
2748
ParseSheetHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent,bool isReset,RefPtr<ResourceObject> & resObj)2749 bool JSViewAbstract::ParseSheetHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent,
2750 bool isReset, RefPtr<ResourceObject>& resObj)
2751 {
2752 detent.height.reset();
2753 detent.sheetMode.reset();
2754 CalcDimension sheetHeight;
2755 if (args->IsString()) {
2756 std::string heightStr = args->ToString();
2757
2758 // Remove all " ".
2759 heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
2760 std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
2761 if (ParseSheetMode(heightStr, detent)) {
2762 return true;
2763 }
2764 if (heightStr.find("calc") != std::string::npos) {
2765 sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
2766 } else {
2767 sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
2768 }
2769 if (sheetHeight.Value() < 0) {
2770 detent.sheetMode = NG::SheetMode::LARGE;
2771 return false;
2772 }
2773 }
2774 if (!ParseJsDimensionVpNG(args, sheetHeight, resObj)) {
2775 if (!isReset) {
2776 auto sheetTheme = GetTheme<OHOS::Ace::NG::SheetTheme>();
2777 detent.sheetMode = sheetTheme != nullptr
2778 ? static_cast<NG::SheetMode>(sheetTheme->GetSheetHeightDefaultMode())
2779 : NG::SheetMode::LARGE;
2780 }
2781 return false;
2782 }
2783 detent.height = sheetHeight;
2784 return true;
2785 }
2786
JsBindMenu(const JSCallbackInfo & info)2787 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
2788 {
2789 NG::MenuParam menuParam;
2790 MenuDefaultParam(menuParam);
2791 size_t builderIndex = 0;
2792 JSViewPopups::GetMenuShowInSubwindow(menuParam);
2793 if (info.Length() > PARAMETER_LENGTH_FIRST) {
2794 auto jsVal = info[0];
2795 if (jsVal->IsBoolean()) {
2796 menuParam.isShow = jsVal->ToBoolean();
2797 menuParam.setShow = true;
2798 builderIndex = 1;
2799 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2800 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2801 }
2802 } else if (jsVal->IsUndefined()) {
2803 menuParam.setShow = true;
2804 menuParam.isShow = false;
2805 builderIndex = 1;
2806 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2807 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2808 }
2809 } else if (jsVal->IsObject()) {
2810 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
2811 menuParam.onStateChange = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
2812 auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
2813 if (isShowObj->IsBoolean()) {
2814 menuParam.isShow = isShowObj->ToBoolean();
2815 menuParam.setShow = true;
2816 builderIndex = 1;
2817 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2818 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2819 }
2820 } else {
2821 builderIndex = 0;
2822 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2823 }
2824 }
2825 }
2826
2827 if (info[builderIndex]->IsArray()) {
2828 std::vector<NG::OptionParam> optionsParam = JSViewPopups::ParseBindOptionParam(info, builderIndex);
2829 ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
2830 } else if (info[builderIndex]->IsObject()) {
2831 // CustomBuilder
2832 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
2833 auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
2834 if (!builder->IsFunction()) {
2835 return;
2836 }
2837 auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2838
2839 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2840 CHECK_NULL_VOID(builderFunc);
2841 auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
2842 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2843 ACE_SCORING_EVENT("BuildMenu");
2844 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2845 func->Execute();
2846 };
2847 ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
2848 }
2849 }
2850
MenuDefaultParam(NG::MenuParam & menuParam)2851 void JSViewAbstract::MenuDefaultParam(NG::MenuParam& menuParam)
2852 {
2853 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2854 menuParam.placement = Placement::BOTTOM_LEFT;
2855 }
2856 }
2857
ParseContentMenuCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuObj,NG::MenuParam & menuParam)2858 void JSViewAbstract::ParseContentMenuCommonParam(
2859 const JSCallbackInfo& info, const JSRef<JSObject>& menuObj, NG::MenuParam& menuParam)
2860 {
2861 if (!menuParam.placement.has_value()) {
2862 MenuDefaultParam(menuParam);
2863 }
2864 JSViewPopups::GetMenuShowInSubwindow(menuParam);
2865 CHECK_EQUAL_VOID(menuObj->IsEmpty(), true);
2866 JSViewPopups::InitMenuParamColorMode(menuParam);
2867 JSViewPopups::ParseMenuParam(info, menuObj, menuParam);
2868 JSViewPopups::ParseMenuShowInSubWindowParam(menuObj, menuParam, false);
2869 auto preview = menuObj->GetProperty("preview");
2870 if (preview->IsNumber()) {
2871 auto previewMode = preview->ToNumber<int32_t>();
2872 if (previewMode == static_cast<int32_t>(MenuPreviewMode::IMAGE)) {
2873 menuParam.previewMode = static_cast<MenuPreviewMode>(previewMode);
2874 ParseContentPreviewAnimationOptionsParam(info, menuObj, menuParam);
2875 menuParam.enableArrow = false;
2876 }
2877 }
2878 }
2879
OpenMenu(NG::MenuParam & menuParam,const RefPtr<NG::UINode> & customNode,const int32_t & targetId)2880 int32_t JSViewAbstract::OpenMenu(
2881 NG::MenuParam& menuParam, const RefPtr<NG::UINode>& customNode, const int32_t& targetId)
2882 {
2883 return ViewAbstractModel::GetInstance()->OpenMenu(menuParam, customNode, targetId);
2884 }
2885
UpdateMenu(const NG::MenuParam & menuParam,const RefPtr<NG::UINode> & customNode)2886 int32_t JSViewAbstract::UpdateMenu(const NG::MenuParam& menuParam, const RefPtr<NG::UINode>& customNode)
2887 {
2888 return ViewAbstractModel::GetInstance()->UpdateMenu(menuParam, customNode);
2889 }
2890
CloseMenu(const RefPtr<NG::UINode> & customNode)2891 int32_t JSViewAbstract::CloseMenu(const RefPtr<NG::UINode>& customNode)
2892 {
2893 return ViewAbstractModel::GetInstance()->CloseMenu(customNode);
2894 }
2895
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info,const int32_t & instanceId)> & onWillDismiss)2896 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
2897 std::function<void(const int32_t& info, const int32_t& instanceId)>& onWillDismiss)
2898 {
2899 auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
2900 if (onWillDismissFunc->IsFunction()) {
2901 auto jsFunc =
2902 AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
2903 onWillDismiss = [func = std::move(jsFunc)](const int32_t& info, const int32_t& instanceId) {
2904 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
2905 objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
2906 JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
2907 dismissObj->SetPropertyObject(
2908 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
2909 dismissObj->SetProperty<int32_t>("reason", info);
2910 JSRef<JSVal> newJSVal = dismissObj;
2911 func->ExecuteJS(1, &newJSVal);
2912 };
2913 }
2914 }
2915
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)2916 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
2917 {
2918 ViewAbstractModel::GetInstance()->DismissDialog();
2919 return JSValueRef::Undefined(runtimeCallInfo->GetVM());
2920 }
2921
AppearDialogEvent(const JSCallbackInfo & info,DialogProperties & dialogProperties)2922 void AppearDialogEvent(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2923 {
2924 if (!info[0]->IsObject()) {
2925 return;
2926 }
2927 auto paramObject = JSRef<JSObject>::Cast(info[0]);
2928 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2929 auto onDidAppear = paramObject->GetProperty("onDidAppear");
2930 if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
2931 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
2932 auto didAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2933 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2934 ACE_SCORING_EVENT("Popups.onDidAppear");
2935 PipelineContext::SetCallBackNode(node);
2936 func->Execute();
2937 };
2938 dialogProperties.onDidAppear = std::move(didAppearId);
2939 }
2940 auto onWillAppear = paramObject->GetProperty("onWillAppear");
2941 if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
2942 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
2943 auto willAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2944 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2945 ACE_SCORING_EVENT("Popups.onWillAppear");
2946 PipelineContext::SetCallBackNode(node);
2947 func->Execute();
2948 };
2949 dialogProperties.onWillAppear = std::move(willAppearId);
2950 }
2951 }
2952
DisappearDialogEvent(const JSCallbackInfo & info,DialogProperties & dialogProperties)2953 void DisappearDialogEvent(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2954 {
2955 if (!info[0]->IsObject()) {
2956 return;
2957 }
2958 auto paramObject = JSRef<JSObject>::Cast(info[0]);
2959 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2960 auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
2961 if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
2962 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
2963 auto didDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2964 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2965 ACE_SCORING_EVENT("Popups.onDidDisappear");
2966 PipelineContext::SetCallBackNode(node);
2967 func->Execute();
2968 };
2969 dialogProperties.onDidDisappear = std::move(didDisappearId);
2970 }
2971 auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
2972 if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
2973 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
2974 auto willDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2975 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2976 ACE_SCORING_EVENT("Popups.onWillDisappear");
2977 PipelineContext::SetCallBackNode(node);
2978 func->Execute();
2979 };
2980 dialogProperties.onWillDisappear = std::move(willDisappearId);
2981 }
2982 }
2983
ParseAppearDialogCallback(const JSCallbackInfo & info,DialogProperties & dialogProperties)2984 void JSViewAbstract::ParseAppearDialogCallback(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2985 {
2986 if (!info[0]->IsObject()) {
2987 return ;
2988 }
2989 AppearDialogEvent(info, dialogProperties);
2990 DisappearDialogEvent(info, dialogProperties);
2991 }
2992
SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)2993 void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
2994 {
2995 auto enableHoverModeValue = obj->GetProperty("enableHoverMode");
2996 if (enableHoverModeValue->IsBoolean()) {
2997 properties.enableHoverMode = enableHoverModeValue->ToBoolean();
2998 }
2999
3000 // Parse hoverModeArea
3001 auto hoverModeAreaValue = obj->GetProperty("hoverModeArea");
3002 if (hoverModeAreaValue->IsNumber()) {
3003 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
3004 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
3005 properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
3006 }
3007 }
3008 }
3009
SetDialogBlurStyleOption(const JSRef<JSObject> & obj,DialogProperties & properties)3010 void JSViewAbstract::SetDialogBlurStyleOption(const JSRef<JSObject>& obj, DialogProperties& properties)
3011 {
3012 auto blurStyleValue = obj->GetProperty("backgroundBlurStyleOptions");
3013 if (blurStyleValue->IsObject()) {
3014 if (!properties.blurStyleOption.has_value()) {
3015 properties.blurStyleOption.emplace();
3016 }
3017 JSViewAbstract::ParseBlurStyleOption(blurStyleValue, properties.blurStyleOption.value());
3018 }
3019 }
3020
SetDialogEffectOption(const JSRef<JSObject> & obj,DialogProperties & properties)3021 void JSViewAbstract::SetDialogEffectOption(const JSRef<JSObject>& obj, DialogProperties& properties)
3022 {
3023 auto effectOptionValue = obj->GetProperty("backgroundEffect");
3024 if (effectOptionValue->IsObject()) {
3025 if (!properties.effectOption.has_value()) {
3026 properties.effectOption.emplace();
3027 }
3028 JSViewAbstract::ParseEffectOption(effectOptionValue, properties.effectOption.value());
3029 }
3030 }
3031
ParseMenuOutlineWidth(const JSRef<JSVal> & outlineWidthValue,NG::MenuParam & menuParam)3032 void JSViewPopups::ParseMenuOutlineWidth(const JSRef<JSVal>& outlineWidthValue, NG::MenuParam& menuParam)
3033 {
3034 NG::BorderWidthProperty outlineWidth;
3035 CalcDimension borderWidth;
3036 RefPtr<ResourceObject> borderWidthResObj;
3037 if (JSViewAbstract::ParseJsDimensionVp(outlineWidthValue, borderWidth, borderWidthResObj)) {
3038 if (borderWidth.IsNegative() || borderWidth.Unit() == DimensionUnit::PERCENT) {
3039 outlineWidth.SetBorderWidth(Dimension { -1 });
3040 } else {
3041 outlineWidth.SetBorderWidth(borderWidth);
3042 }
3043 ParseMenuOutlineWidthWithResourceObj(borderWidthResObj, outlineWidth);
3044 menuParam.outlineWidth = outlineWidth;
3045 return;
3046 }
3047 if (!outlineWidthValue->IsObject()) {
3048 outlineWidth.SetBorderWidth(Dimension { -1 });
3049 menuParam.outlineWidth = outlineWidth;
3050 return;
3051 }
3052 ParseMenuOutlineWidthObject(outlineWidthValue, menuParam, outlineWidth);
3053 }
3054
ParseMenuOutlineWidthObject(const JSRef<JSVal> & outlineWidthValue,NG::MenuParam & menuParam,NG::BorderWidthProperty & outlineWidth)3055 void JSViewPopups::ParseMenuOutlineWidthObject(const JSRef<JSVal>& outlineWidthValue, NG::MenuParam& menuParam,
3056 NG::BorderWidthProperty& outlineWidth)
3057 {
3058 if (!outlineWidthValue->IsObject()) {
3059 return;
3060 }
3061 JSRef<JSObject> object = JSRef<JSObject>::Cast(outlineWidthValue);
3062 CalcDimension left;
3063 RefPtr<ResourceObject> leftResObj;
3064 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty("left"), left, leftResObj) && left.IsNonNegative()) {
3065 if (left.Unit() == DimensionUnit::PERCENT) {
3066 left.Reset();
3067 }
3068 outlineWidth.leftDimen = left;
3069 }
3070 CalcDimension right;
3071 RefPtr<ResourceObject> rightResObj;
3072 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty("right"), right, rightResObj) &&
3073 right.IsNonNegative()) {
3074 if (right.Unit() == DimensionUnit::PERCENT) {
3075 right.Reset();
3076 }
3077 outlineWidth.rightDimen = right;
3078 }
3079 CalcDimension top;
3080 RefPtr<ResourceObject> topResObj;
3081 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty("top"), top, topResObj) && top.IsNonNegative()) {
3082 if (top.Unit() == DimensionUnit::PERCENT) {
3083 top.Reset();
3084 }
3085 outlineWidth.topDimen = top;
3086 }
3087 CalcDimension bottom;
3088 RefPtr<ResourceObject> bottomResObj;
3089 if (JSViewAbstract::ParseJsDimensionVp(object->GetProperty("bottom"), bottom, bottomResObj) &&
3090 bottom.IsNonNegative()) {
3091 if (bottom.Unit() == DimensionUnit::PERCENT) {
3092 bottom.Reset();
3093 }
3094 outlineWidth.bottomDimen = bottom;
3095 }
3096 ParseMenuOutlineWidthWithResourceObj(leftResObj, rightResObj, topResObj, bottomResObj, outlineWidth);
3097 menuParam.outlineWidth = outlineWidth;
3098 }
3099
ParseMenuOutlineWidthWithResourceObj(const RefPtr<ResourceObject> & borderWidthResObj,NG::BorderWidthProperty & outlineWidth)3100 void JSViewPopups::ParseMenuOutlineWidthWithResourceObj(
3101 const RefPtr<ResourceObject>& borderWidthResObj, NG::BorderWidthProperty& outlineWidth)
3102 {
3103 if (borderWidthResObj) {
3104 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& outlineWidthProp) {
3105 CalcDimension width;
3106 ResourceParseUtils::ParseResDimensionVp(resObj, width);
3107 outlineWidthProp.SetBorderWidth(width);
3108 };
3109 outlineWidth.AddResource("outlineWidth.width", borderWidthResObj, std::move(updateFunc));
3110 }
3111 }
3112
ParseMenuOutlineWidthWithResourceObj(const RefPtr<ResourceObject> & leftResObj,const RefPtr<ResourceObject> & rightResObj,const RefPtr<ResourceObject> & topResObj,const RefPtr<ResourceObject> & bottomResObj,NG::BorderWidthProperty & outlineWidth)3113 void JSViewPopups::ParseMenuOutlineWidthWithResourceObj(const RefPtr<ResourceObject>& leftResObj,
3114 const RefPtr<ResourceObject>& rightResObj, const RefPtr<ResourceObject>& topResObj,
3115 const RefPtr<ResourceObject>& bottomResObj, NG::BorderWidthProperty& outlineWidth)
3116 {
3117 if (leftResObj) {
3118 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& outlineWidth) {
3119 CalcDimension left;
3120 if (!ResourceParseUtils::ParseResDimensionVp(resObj, left) ||
3121 left.Unit() == DimensionUnit::PERCENT || left.IsNegative()) {
3122 left.Reset();
3123 }
3124 outlineWidth.leftDimen = left;
3125 };
3126 outlineWidth.AddResource("outlineWidth.left", leftResObj, std::move(updateFunc));
3127 }
3128 if (rightResObj) {
3129 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& outlineWidth) {
3130 CalcDimension right;
3131 if (!ResourceParseUtils::ParseResDimensionVp(resObj, right) ||
3132 right.Unit() == DimensionUnit::PERCENT || right.IsNegative()) {
3133 right.Reset();
3134 }
3135 outlineWidth.rightDimen = right;
3136 };
3137 outlineWidth.AddResource("outlineWidth.right", rightResObj, std::move(updateFunc));
3138 }
3139 if (topResObj) {
3140 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& outlineWidth) {
3141 CalcDimension top;
3142 if (!ResourceParseUtils::ParseResDimensionVp(resObj, top) ||
3143 top.Unit() == DimensionUnit::PERCENT || top.IsNegative()) {
3144 top.Reset();
3145 }
3146 outlineWidth.topDimen = top;
3147 };
3148 outlineWidth.AddResource("outlineWidth.top", topResObj, std::move(updateFunc));
3149 }
3150 if (bottomResObj) {
3151 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderWidthProperty& outlineWidth) {
3152 CalcDimension bottom;
3153 if (!ResourceParseUtils::ParseResDimensionVp(resObj, bottom) ||
3154 bottom.Unit() == DimensionUnit::PERCENT || bottom.IsNegative()) {
3155 bottom.Reset();
3156 }
3157 outlineWidth.bottomDimen = bottom;
3158 };
3159 outlineWidth.AddResource("outlineWidth.bottom", bottomResObj, std::move(updateFunc));
3160 }
3161 }
3162
ParseMenuOutlineColor(const JSRef<JSVal> & outlineColorValue,NG::MenuParam & menuParam)3163 void JSViewPopups::ParseMenuOutlineColor(const JSRef<JSVal>& outlineColorValue, NG::MenuParam& menuParam)
3164 {
3165 NG::BorderColorProperty outlineColor;
3166 Color borderColor;
3167 RefPtr<ResourceObject> borderColorResObj;
3168 if (JSViewAbstract::ParseJsColor(outlineColorValue, borderColor, borderColorResObj)) {
3169 outlineColor.SetColor(borderColor);
3170 ViewAbstractModel::GetInstance()->SetOuterBorderColor(borderColor);
3171 ParseMenuOutlineColorWithResourceObj(borderColorResObj, outlineColor);
3172 menuParam.outlineColor = outlineColor;
3173 } else if (outlineColorValue->IsObject()) {
3174 ParseMenuOutlineColorObject(outlineColorValue, menuParam, outlineColor);
3175 } else {
3176 auto defaultColor = Color(0x19FFFFFF);
3177 outlineColor.SetColor(defaultColor);
3178 menuParam.outlineColor = outlineColor;
3179 }
3180 }
3181
ParseMenuOutlineColorObject(const JSRef<JSVal> & outlineColorValue,NG::MenuParam & menuParam,NG::BorderColorProperty & outlineColor)3182 void JSViewPopups::ParseMenuOutlineColorObject(const JSRef<JSVal>& outlineColorValue, NG::MenuParam& menuParam,
3183 NG::BorderColorProperty& outlineColor)
3184 {
3185 if (!outlineColorValue->IsObject()) {
3186 return;
3187 }
3188 JSRef<JSObject> object = JSRef<JSObject>::Cast(outlineColorValue);
3189 Color left;
3190 RefPtr<ResourceObject> leftColorResObj;
3191 outlineColor.SetColor(Color::TRANSPARENT);
3192 bool isSettingOutlineColor = false;
3193 if (JSViewAbstract::ParseJsColor(
3194 object->GetProperty(static_cast<int32_t>(ArkUIIndex::LEFT)), left, leftColorResObj)) {
3195 isSettingOutlineColor = true;
3196 outlineColor.leftColor = left;
3197 }
3198 Color right;
3199 RefPtr<ResourceObject> rightColorResObj;
3200 if (JSViewAbstract::ParseJsColor(
3201 object->GetProperty(static_cast<int32_t>(ArkUIIndex::RIGHT)), right, rightColorResObj)) {
3202 isSettingOutlineColor = true;
3203 outlineColor.rightColor = right;
3204 }
3205 Color top;
3206 RefPtr<ResourceObject> topColorResObj;
3207 if (JSViewAbstract::ParseJsColor(
3208 object->GetProperty(static_cast<int32_t>(ArkUIIndex::TOP)), top, topColorResObj)) {
3209 isSettingOutlineColor = true;
3210 outlineColor.topColor = top;
3211 }
3212 Color bottom;
3213 RefPtr<ResourceObject> bottomColorResObj;
3214 if (JSViewAbstract::ParseJsColor(
3215 object->GetProperty(static_cast<int32_t>(ArkUIIndex::BOTTOM)), bottom, bottomColorResObj)) {
3216 isSettingOutlineColor = true;
3217 outlineColor.bottomColor = bottom;
3218 }
3219 if (!isSettingOutlineColor) {
3220 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
3221 CHECK_NULL_VOID(frameNode);
3222 auto pipeline = frameNode->GetContextRefPtr();
3223 CHECK_NULL_VOID(pipeline);
3224 auto theme = pipeline->GetTheme<NG::MenuTheme>();
3225 CHECK_NULL_VOID(theme);
3226 outlineColor.SetColor(theme->GetMenuOutlineColor());
3227 }
3228 ParseMenuOutlineColorWithResourceObj(
3229 leftColorResObj, rightColorResObj, topColorResObj, bottomColorResObj, outlineColor);
3230 menuParam.outlineColor = outlineColor;
3231 }
3232
ParseMenuOutlineColorWithResourceObj(const RefPtr<ResourceObject> & borderColorResObj,NG::BorderColorProperty & outlineColor)3233 void JSViewPopups::ParseMenuOutlineColorWithResourceObj(const RefPtr<ResourceObject>& borderColorResObj,
3234 NG::BorderColorProperty& outlineColor)
3235 {
3236 if (borderColorResObj) {
3237 auto&& updateFunc =
3238 [](const RefPtr<ResourceObject>& colorResObj, NG::BorderColorProperty& borderColorProp) {
3239 Color color;
3240 ResourceParseUtils::ParseResColor(colorResObj, color);
3241 borderColorProp.SetColor(color);
3242 ViewAbstractModel::GetInstance()->SetOuterBorderColor(color);
3243 };
3244 outlineColor.AddResource("outlineColor.border", borderColorResObj, std::move(updateFunc));
3245 }
3246 }
3247
ParseMenuOutlineColorWithResourceObj(const RefPtr<ResourceObject> & leftColorResObj,const RefPtr<ResourceObject> & rightColorResObj,const RefPtr<ResourceObject> & topColorResObj,const RefPtr<ResourceObject> & bottomColorResObj,NG::BorderColorProperty & outlineColor)3248 void JSViewPopups::ParseMenuOutlineColorWithResourceObj(const RefPtr<ResourceObject>& leftColorResObj,
3249 const RefPtr<ResourceObject>& rightColorResObj, const RefPtr<ResourceObject>& topColorResObj,
3250 const RefPtr<ResourceObject>& bottomColorResObj, NG::BorderColorProperty& outlineColor)
3251 {
3252 if (leftColorResObj) {
3253 auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, NG::BorderColorProperty& outlineColor) {
3254 Color left;
3255 ResourceParseUtils::ParseResColor(colorResObj, left);
3256 outlineColor.leftColor = left;
3257 };
3258 outlineColor.AddResource("outlineColor.left", leftColorResObj, std::move(updateFunc));
3259 }
3260 if (rightColorResObj) {
3261 auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, NG::BorderColorProperty& outlineColor) {
3262 Color right;
3263 ResourceParseUtils::ParseResColor(colorResObj, right);
3264 outlineColor.rightColor = right;
3265 };
3266 outlineColor.AddResource("outlineColor.right", rightColorResObj, std::move(updateFunc));
3267 }
3268 if (topColorResObj) {
3269 auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, NG::BorderColorProperty& outlineColor) {
3270 Color top;
3271 ResourceParseUtils::ParseResColor(colorResObj, top);
3272 outlineColor.topColor = top;
3273 };
3274 outlineColor.AddResource("outlineColor.top", topColorResObj, std::move(updateFunc));
3275 }
3276 if (bottomColorResObj) {
3277 auto&& updateFunc = [](const RefPtr<ResourceObject>& colorResObj, NG::BorderColorProperty& outlineColor) {
3278 Color bottom;
3279 ResourceParseUtils::ParseResColor(colorResObj, bottom);
3280 outlineColor.bottomColor = bottom;
3281 };
3282 outlineColor.AddResource("outlineColor.bottom", bottomColorResObj, std::move(updateFunc));
3283 }
3284 }
3285
ParseMenuPreviewBorderRadiusObject(const JSRef<JSVal> & args,NG::BorderRadiusProperty & props)3286 bool JSViewPopups::ParseMenuPreviewBorderRadiusObject(const JSRef<JSVal>& args, NG::BorderRadiusProperty& props)
3287 {
3288 CalcDimension borderRadius;
3289 RefPtr<ResourceObject> resObj;
3290 if (!JSViewAbstract::ParseJsDimensionVpNG(args, borderRadius, resObj)) {
3291 return false;
3292 }
3293 props.SetRadius(borderRadius);
3294 props.multiValued = false;
3295 auto&& updateFunc = [](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& props) {
3296 CalcDimension radiusValue;
3297 ResourceParseUtils::ParseResDimensionVpNG(resObj, radiusValue);
3298 props.SetRadius(radiusValue);
3299 props.multiValued = false;
3300 };
3301 props.AddResource("menu.borderRadius", resObj, std::move(updateFunc));
3302 return true;
3303 }
3304
SetBorderRadiusProps(const CalcDimension & dim,NG::BorderRadiusProperty & props,const char * propName)3305 void JSViewPopups::SetBorderRadiusProps(
3306 const CalcDimension& dim, NG::BorderRadiusProperty& props, const char* propName)
3307 {
3308 if (dim.IsNegative() || propName == nullptr) {
3309 return;
3310 }
3311 auto isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
3312 if (propName == BOTTOM_LEFT_PROPERTY) {
3313 props.radiusBottomLeft = dim;
3314 } else if (propName == BOTTOM_RIGHT_PROPERTY) {
3315 props.radiusBottomRight = dim;
3316 } else if (propName == TOP_LEFT_PROPERTY) {
3317 props.radiusTopLeft = dim;
3318 } else if (propName == TOP_RIGHT_PROPERTY) {
3319 props.radiusTopRight = dim;
3320 } else if (propName == TOP_START_PROPERTY || propName == TOP_END_PROPERTY) {
3321 if (isRightToLeft) {
3322 props.radiusTopRight = dim;
3323 return;
3324 }
3325 props.radiusTopLeft = dim;
3326 } else if (propName == BOTTOM_START_PROPERTY || propName == BOTTOM_END_PROPERTY) {
3327 if (isRightToLeft) {
3328 props.radiusBottomRight = dim;
3329 return;
3330 }
3331 props.radiusBottomLeft = dim;
3332 }
3333 }
3334
ParseBorderRadiusProps(const char * key,const JSRef<JSObject> & object,NG::BorderRadiusProperty & props)3335 void JSViewPopups::ParseBorderRadiusProps(
3336 const char* key, const JSRef<JSObject>& object, NG::BorderRadiusProperty& props)
3337 {
3338 CHECK_NULL_VOID(key);
3339 if (!object->HasProperty(key)) {
3340 return;
3341 }
3342 CalcDimension radius;
3343 RefPtr<ResourceObject> resObj;
3344 if (JSViewAbstract::ParseJsDimensionVpNG(object->GetProperty(key), radius, resObj)) {
3345 SetBorderRadiusProps(radius, props, key);
3346 }
3347 if (!resObj) {
3348 return;
3349 }
3350 auto&& updateFunc = [key](const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& props) {
3351 CalcDimension value;
3352 if (ResourceParseUtils::ParseResDimensionVpNG(resObj, value)) {
3353 SetBorderRadiusProps(value, props, key);
3354 }
3355 };
3356 props.AddResource("menu.borderRadius." + std::string(key), resObj, std::move(updateFunc));
3357 }
3358
CheckDimensionUnit(CalcDimension & checkDimension,bool notPercent)3359 void CheckDimensionUnit(CalcDimension& checkDimension, bool notPercent)
3360 {
3361 if (notPercent && checkDimension.Unit() == DimensionUnit::PERCENT) {
3362 checkDimension.Reset();
3363 return;
3364 }
3365 }
3366
ParseBorderRadiusPropsByLengthMetrics(const char * key,const JSRef<JSObject> & object,NG::BorderRadiusProperty & props)3367 void JSViewPopups::ParseBorderRadiusPropsByLengthMetrics(
3368 const char* key, const JSRef<JSObject>& object, NG::BorderRadiusProperty& props)
3369 {
3370 CHECK_NULL_VOID(key);
3371 if (!object->HasProperty(key) || !object->GetProperty(key)->IsObject()) {
3372 return;
3373 }
3374 JSRef<JSObject> radiusObj = JSRef<JSObject>::Cast(object->GetProperty(key));
3375 CalcDimension radius;
3376 RefPtr<ResourceObject> resObj = nullptr;
3377 if (JSViewAbstract::ParseJsLengthMetricsVpWithResObj(radiusObj, radius, resObj)) {
3378 CheckDimensionUnit(radius, false);
3379 SetBorderRadiusProps(radius, props, key);
3380 }
3381 if (!resObj) {
3382 return;
3383 }
3384 auto unit = radius.Unit();
3385 auto&& updateFunc = [unit, key](
3386 const RefPtr<ResourceObject>& resObj, NG::BorderRadiusProperty& props) {
3387 CalcDimension value;
3388 if (ResourceParseUtils::ParseResDimension(resObj, value, unit)) {
3389 CheckDimensionUnit(value, false);
3390 SetBorderRadiusProps(value, props, key);
3391 }
3392 };
3393 props.AddResource("menu.borderRadius." + std::string(key), resObj, std::move(updateFunc));
3394 }
3395
ParseMenuPreviewBorderRadiusMultiObject(const JSRef<JSObject> & object,NG::BorderRadiusProperty & props)3396 void JSViewPopups::ParseMenuPreviewBorderRadiusMultiObject(
3397 const JSRef<JSObject>& object, NG::BorderRadiusProperty& props)
3398 {
3399 if (JSViewAbstract::CheckLengthMetrics(object)) {
3400 ParseBorderRadiusPropsByLengthMetrics(BOTTOM_START_PROPERTY, object, props);
3401 ParseBorderRadiusPropsByLengthMetrics(BOTTOM_END_PROPERTY, object, props);
3402 ParseBorderRadiusPropsByLengthMetrics(TOP_START_PROPERTY, object, props);
3403 ParseBorderRadiusPropsByLengthMetrics(TOP_END_PROPERTY, object, props);
3404 return;
3405 }
3406 ParseBorderRadiusProps(TOP_LEFT_PROPERTY, object, props);
3407 ParseBorderRadiusProps(TOP_RIGHT_PROPERTY, object, props);
3408 ParseBorderRadiusProps(BOTTOM_LEFT_PROPERTY, object, props);
3409 ParseBorderRadiusProps(BOTTOM_RIGHT_PROPERTY, object, props);
3410 }
3411
ParseMenuPreviewBorderRadius(const JSRef<JSVal> & args,NG::BorderRadiusProperty & radius)3412 void JSViewPopups::ParseMenuPreviewBorderRadius(const JSRef<JSVal>& args, NG::BorderRadiusProperty& radius)
3413 {
3414 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
3415 return;
3416 }
3417 if (SystemProperties::ConfigChangePerform()) {
3418 if (ParseMenuPreviewBorderRadiusObject(args, radius)) {
3419 return;
3420 }
3421 if (args->IsObject()) {
3422 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3423 ParseMenuPreviewBorderRadiusMultiObject(object, radius);
3424 radius.multiValued = true;
3425 return;
3426 }
3427 }
3428 CalcDimension borderRadius;
3429 if (JSViewAbstract::ParseJsDimensionVpNG(args, borderRadius, true)) {
3430 radius = NG::BorderRadiusProperty(borderRadius);
3431 radius.multiValued = false;
3432 } else if (args->IsObject()) {
3433 JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
3434 JSViewAbstract::ParseCommonBorderRadiusProps(object, radius, false);
3435 }
3436 return;
3437 }
3438 }
3439