• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param);
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