• 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 
29 #include "bridge/declarative_frontend/jsview/js_popups.h"
30 
31 namespace OHOS::Ace::Framework {
32 namespace {
33 constexpr int32_t PARAMETER_LENGTH_ZERO = 0;
34 constexpr int32_t PARAMETER_LENGTH_FIRST = 1;
35 constexpr int32_t PARAMETER_LENGTH_SECOND = 2;
36 constexpr int32_t PARAMETER_LENGTH_THIRD = 3;
37 constexpr int NUM_ZERO = 0;
38 constexpr int NUM_FIRST = 1;
39 constexpr int NUM_SECOND = 2;
40 constexpr int32_t TRANSITION_NUM_ZERO = 0;
41 constexpr int32_t TRANSITION_NUM_TWO = 2;
42 constexpr uint32_t ON_WILL_DISMISS_FIELD_COUNT = 2;
43 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
44 constexpr Dimension ARROW_ZERO_PERCENT_VALUE = 0.0_pct;
45 constexpr Dimension ARROW_HALF_PERCENT_VALUE = 0.5_pct;
46 constexpr Dimension ARROW_ONE_HUNDRED_PERCENT_VALUE = 1.0_pct;
47 const std::string SHEET_HEIGHT_MEDIUM = "medium";
48 const std::string SHEET_HEIGHT_LARGE = "large";
49 const std::string SHEET_HEIGHT_AUTO = "auto";
50 const std::string SHEET_HEIGHT_FITCONTENT = "fit_content";
51 constexpr int HAPTIC_FEEDBACK_MODE_ENABLED = 1;
52 constexpr int HAPTIC_FEEDBACK_MODE_AUTO = 2;
53 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
54     HoverModeAreaType::BOTTOM_SCREEN };
55 }
56 
57 using DoubleBindCallback = std::function<void(const std::string&)>;
58 
59 #ifndef WEARABLE_PRODUCT
ParseDoubleBindCallback(const JSCallbackInfo & info,const JSRef<JSObject> & callbackObj,const char * arrowFuncName)60 DoubleBindCallback JSViewPopups::ParseDoubleBindCallback(const JSCallbackInfo& info, const JSRef<JSObject>& callbackObj,
61     const char* arrowFuncName)
62 {
63     JSRef<JSVal> arrowFunc = callbackObj->GetProperty(arrowFuncName);
64     if (!arrowFunc->IsFunction()) {
65         return {};
66     }
67     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(arrowFunc));
68     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
69     auto callback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
70                         const std::string& param) {
71         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
72         if (param != "true" && param != "false") {
73             return;
74         }
75         PipelineContext::SetCallBackNode(node);
76         bool newValue = StringToBool(param);
77         JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(newValue));
78         func->ExecuteJS(1, &newJSVal);
79     };
80     return callback;
81 }
82 
SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj,const RefPtr<PopupParam> & popupParam)83 void SetPopupMessageOptions(const JSRef<JSObject> messageOptionsObj, const RefPtr<PopupParam>& popupParam)
84 {
85     auto colorValue = messageOptionsObj->GetProperty("textColor");
86     Color textColor;
87     if (JSViewAbstract::ParseJsColor(colorValue, textColor)) {
88         if (popupParam) {
89             popupParam->SetTextColor(textColor);
90         }
91     }
92 
93     auto font = messageOptionsObj->GetProperty("font");
94     if (!font->IsNull() && font->IsObject()) {
95         JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(font);
96         auto fontSizeValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::SIZE));
97         CalcDimension fontSize;
98         if (JSViewAbstract::ParseJsDimensionFp(fontSizeValue, fontSize)) {
99             if (popupParam && fontSize.IsValid()) {
100                 popupParam->SetFontSize(fontSize);
101             }
102         }
103         auto fontWeightValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::WEIGHT));
104         if (fontWeightValue->IsString()) {
105             if (popupParam) {
106                 popupParam->SetFontWeight(ConvertStrToFontWeight(fontWeightValue->ToString()));
107             }
108         }
109         auto fontStyleValue = fontObj->GetProperty(static_cast<int32_t>(ArkUIIndex::STYLE));
110         if (fontStyleValue->IsNumber()) {
111             int32_t value = fontStyleValue->ToNumber<int32_t>();
112             if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
113                 return;
114             }
115             if (popupParam) {
116                 popupParam->SetFontStyle(FONT_STYLES[value]);
117             }
118         }
119     }
120 }
121 
SetPlacementOnTopVal(const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)122 void SetPlacementOnTopVal(const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
123 {
124     JSRef<JSVal> placementOnTopVal = popupObj->GetProperty("placementOnTop");
125     if (placementOnTopVal->IsBoolean() && popupParam) {
126         popupParam->SetPlacement(placementOnTopVal->ToBoolean() ? Placement::TOP : Placement::BOTTOM);
127     }
128 }
129 
IsPopupCreated()130 bool IsPopupCreated()
131 {
132     auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
133     CHECK_NULL_RETURN(targetNode, false);
134     auto targetId = targetNode->GetId();
135     auto container = Container::Current();
136     CHECK_NULL_RETURN(container, false);
137     auto pipelineContext = container->GetPipelineContext();
138     CHECK_NULL_RETURN(pipelineContext, false);
139     auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
140     CHECK_NULL_RETURN(context, false);
141     auto overlayManager = context->GetOverlayManager();
142     CHECK_NULL_RETURN(overlayManager, false);
143     auto popupInfo = overlayManager->GetPopupInfo(targetId);
144     if (popupInfo.popupId == -1 || !popupInfo.popupNode) {
145         return false;
146     }
147     return true;
148 }
149 
GetPopupDefaultShadowStyle()150 ShadowStyle GetPopupDefaultShadowStyle()
151 {
152     auto shadowStyle = ShadowStyle::OuterDefaultMD;
153     auto container = Container::Current();
154     CHECK_NULL_RETURN(container, shadowStyle);
155     auto pipelineContext = container->GetPipelineContext();
156     CHECK_NULL_RETURN(pipelineContext, shadowStyle);
157     auto popupTheme = pipelineContext->GetTheme<PopupTheme>();
158     CHECK_NULL_RETURN(popupTheme, shadowStyle);
159     return popupTheme->GetPopupShadowStyle();
160 }
161 
GetBlurStyleFromTheme(const RefPtr<PopupParam> & popupParam)162 static void GetBlurStyleFromTheme(const RefPtr<PopupParam>& popupParam)
163 {
164     CHECK_NULL_VOID(popupParam);
165     auto pipelineContext = PipelineContext::GetCurrentContext();
166     CHECK_NULL_VOID(pipelineContext);
167     auto theme = pipelineContext->GetTheme<PopupTheme>();
168     CHECK_NULL_VOID(theme);
169     auto blurStyle = static_cast<BlurStyle>(theme->GetPopupBackgroundBlurStyle());
170     popupParam->SetBlurStyle(blurStyle);
171 }
172 
ParsePopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam,const RefPtr<NG::FrameNode> popupTargetNode=nullptr)173 void ParsePopupCommonParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj,
174     const RefPtr<PopupParam>& popupParam, const RefPtr<NG::FrameNode> popupTargetNode = nullptr)
175 {
176     auto arrowOffset = popupObj->GetProperty("arrowOffset");
177     CalcDimension offset;
178     if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
179         if (popupParam) {
180             popupParam->SetArrowOffset(offset);
181         }
182     }
183 
184     auto arrowPointPosition = popupObj->GetProperty("arrowPointPosition");
185     if (arrowPointPosition->IsString()) {
186         char* pEnd = nullptr;
187         auto arrowString = arrowPointPosition->ToString();
188         std::strtod(arrowString.c_str(), &pEnd);
189         if (pEnd != nullptr) {
190             if (std::strcmp(pEnd, "Start") == 0) {
191                 offset = ARROW_ZERO_PERCENT_VALUE;
192             }
193             if (std::strcmp(pEnd, "Center") == 0) {
194                 offset = ARROW_HALF_PERCENT_VALUE;
195             }
196             if (std::strcmp(pEnd, "End") == 0) {
197                 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
198             }
199             if (popupParam) {
200                 popupParam->SetArrowOffset(offset);
201             }
202         }
203     }
204 
205     auto targetSpace = popupObj->GetProperty("targetSpace");
206     if (!targetSpace->IsNull()) {
207         CalcDimension space;
208         if (JSViewAbstract::ParseJsDimensionVp(targetSpace, space)) {
209             if (popupParam) {
210                 popupParam->SetTargetSpace(space);
211             }
212         }
213     }
214 
215     JSRef<JSVal> showInSubWindowValue = popupObj->GetProperty("showInSubWindow");
216     if (showInSubWindowValue->IsBoolean()) {
217         bool showInSubBoolean = showInSubWindowValue->ToBoolean();
218 #if defined(PREVIEW)
219         if (showInSubBoolean) {
220             LOGI("[Engine Log] Unable to use the SubWindow in the Previewer. Use normal type instead.");
221             showInSubBoolean = false;
222         }
223 #endif
224         if (popupParam) {
225             popupParam->SetShowInSubWindow(showInSubBoolean);
226         }
227     }
228 
229     auto placementValue = popupObj->GetProperty("placement");
230     if (placementValue->IsNumber()) {
231         auto placement = placementValue->ToNumber<int32_t>();
232         if (placement >= 0 && placement < static_cast<int32_t>(Placement::NONE)) {
233             popupParam->SetPlacement(static_cast<Placement>(placement));
234         }
235     } else {
236         SetPlacementOnTopVal(popupObj, popupParam);
237     }
238 
239     auto enableArrowValue = popupObj->GetProperty("enableArrow");
240     if (enableArrowValue->IsBoolean()) {
241         popupParam->SetEnableArrow(enableArrowValue->ToBoolean());
242     }
243 
244     auto enableHoverModeValue = popupObj->GetProperty("enableHoverMode");
245     if (enableHoverModeValue->IsBoolean()) {
246         popupParam->SetEnableHoverMode(enableHoverModeValue->ToBoolean());
247     }
248 
249     auto followTransformOfTargetValue = popupObj->GetProperty("followTransformOfTarget");
250     if (followTransformOfTargetValue->IsBoolean()) {
251         popupParam->SetFollowTransformOfTarget(followTransformOfTargetValue->ToBoolean());
252     }
253 
254     JSRef<JSVal> maskValue = popupObj->GetProperty("mask");
255     if (maskValue->IsBoolean()) {
256         if (popupParam) {
257             popupParam->SetBlockEvent(maskValue->ToBoolean());
258         }
259     }
260     if (maskValue->IsObject()) {
261         auto maskObj = JSRef<JSObject>::Cast(maskValue);
262         auto colorValue = maskObj->GetProperty("color");
263         Color maskColor;
264         if (JSViewAbstract::ParseJsColor(colorValue, maskColor)) {
265             popupParam->SetMaskColor(maskColor);
266         }
267     }
268 
269     JSRef<JSVal> onStateChangeVal = popupObj->GetProperty("onStateChange");
270     if (onStateChangeVal->IsFunction()) {
271         std::vector<std::string> keys = { "isVisible" };
272         RefPtr<JsFunction> jsFunc =
273             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onStateChangeVal));
274         WeakPtr<NG::FrameNode> targetNode = nullptr;
275         if (popupTargetNode) {
276             targetNode = AceType::WeakClaim(AceType::RawPtr(popupTargetNode));
277         } else {
278             targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
279         }
280         if (popupParam) {
281             auto onStateChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), keys,
282                                              node = targetNode](const std::string& param) {
283                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
284                 ACE_SCORING_EVENT("Popup.onStateChange");
285                 PipelineContext::SetCallBackNode(node);
286                 func->Execute(keys, param);
287             };
288             popupParam->SetOnStateChange(onStateChangeCallback);
289         }
290     }
291 
292     auto offsetVal = popupObj->GetProperty("offset");
293     if (offsetVal->IsObject()) {
294         auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
295         auto xVal = offsetObj->GetProperty("x");
296         auto yVal = offsetObj->GetProperty("y");
297         Offset popupOffset;
298         CalcDimension dx;
299         CalcDimension dy;
300         if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
301             popupOffset.SetX(dx.ConvertToPx());
302         }
303         if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
304             popupOffset.SetY(dy.ConvertToPx());
305         }
306         if (popupParam) {
307             popupParam->SetTargetOffset(popupOffset);
308         }
309     }
310 
311     Color backgroundColor;
312     auto popupColorVal = popupObj->GetProperty("popupColor");
313     if (JSViewAbstract::ParseJsColor(popupColorVal, backgroundColor)) {
314         popupParam->SetBackgroundColor(backgroundColor);
315     }
316 
317     auto autoCancelVal = popupObj->GetProperty("autoCancel");
318     if (autoCancelVal->IsBoolean()) {
319         popupParam->SetHasAction(!autoCancelVal->ToBoolean());
320     }
321 
322     auto childWidthVal = popupObj->GetProperty("width");
323     if (!childWidthVal->IsNull()) {
324         CalcDimension width;
325         if (JSViewAbstract::ParseJsDimensionVp(childWidthVal, width)) {
326             if (width.Value() > 0) {
327                 popupParam->SetChildWidth(width);
328             }
329         }
330     }
331 
332     auto arrowWidthVal = popupObj->GetProperty("arrowWidth");
333     if (!arrowWidthVal->IsNull()) {
334         bool setError = true;
335         CalcDimension arrowWidth;
336         if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
337             if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
338                 popupParam->SetArrowWidth(arrowWidth);
339                 setError = false;
340             }
341         }
342         popupParam->SetErrorArrowWidth(setError);
343     }
344 
345     auto arrowHeightVal = popupObj->GetProperty("arrowHeight");
346     if (!arrowHeightVal->IsNull()) {
347         bool setError = true;
348         CalcDimension arrowHeight;
349         if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
350             if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
351                 popupParam->SetArrowHeight(arrowHeight);
352                 setError = false;
353             }
354         }
355         popupParam->SetErrorArrowHeight(setError);
356     }
357 
358     auto radiusVal = popupObj->GetProperty("radius");
359     if (!radiusVal->IsNull()) {
360         bool setError = true;
361         CalcDimension radius;
362         if (JSViewAbstract::ParseJsDimensionVp(radiusVal, radius)) {
363             if (radius.Value() >= 0) {
364                 popupParam->SetRadius(radius);
365                 setError = false;
366             }
367         }
368         popupParam->SetErrorRadius(setError);
369     }
370 
371     auto defaultShadowStyle = GetPopupDefaultShadowStyle();
372     Shadow shadow;
373     auto shadowVal = popupObj->GetProperty("shadow");
374     if (shadowVal->IsObject() || shadowVal->IsNumber()) {
375         auto ret = JSViewAbstract::ParseShadowProps(shadowVal, shadow);
376         if (!ret) {
377             if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
378                 JSViewAbstract::GetShadowFromTheme(defaultShadowStyle, shadow);
379                 popupParam->SetShadow(shadow);
380             }
381         } else {
382             popupParam->SetShadow(shadow);
383         }
384     } else {
385         if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
386             JSViewAbstract::GetShadowFromTheme(defaultShadowStyle, shadow);
387             popupParam->SetShadow(shadow);
388         }
389     }
390 
391     auto blurStyleValue = popupObj->GetProperty("backgroundBlurStyle");
392     if (blurStyleValue->IsNumber()) {
393         auto blurStyle = blurStyleValue->ToNumber<int32_t>();
394         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
395             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
396             popupParam->SetBlurStyle(static_cast<BlurStyle>(blurStyle));
397         } else {
398             if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
399                 GetBlurStyleFromTheme(popupParam);
400             }
401         }
402     } else {
403         if (!(popupParam->GetIsPartialUpdate().has_value() && popupParam->GetIsPartialUpdate().value())) {
404             GetBlurStyleFromTheme(popupParam);
405         }
406     }
407 
408     auto popupTransition = popupObj->GetProperty("transition");
409     if (popupTransition->IsObject()) {
410         popupParam->SetHasTransition(true);
411         auto obj = JSRef<JSObject>::Cast(popupTransition);
412         if (popupTargetNode) {
413             auto effects = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext(), popupTargetNode);
414             popupParam->SetTransitionEffects(effects);
415         } else {
416             auto effects = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
417             popupParam->SetTransitionEffects(effects);
418         }
419     }
420     auto keyboardAvoidMode = popupObj->GetProperty("keyboardAvoidMode");
421     if (keyboardAvoidMode->IsNumber()) {
422         auto popupKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
423         if (popupKeyboardAvoidMode >= static_cast<int>(PopupKeyboardAvoidMode::DEFAULT) &&
424             popupKeyboardAvoidMode <= static_cast<int>(PopupKeyboardAvoidMode::NONE)) {
425             popupParam->SetKeyBoardAvoidMode(static_cast<PopupKeyboardAvoidMode>(popupKeyboardAvoidMode));
426         }
427     }
428 }
429 
ParsePopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)430 void ParsePopupParam(const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
431 {
432     ParsePopupCommonParam(info, popupObj, popupParam);
433     JSRef<JSVal> messageVal = popupObj->GetProperty("message");
434     if (popupParam) {
435         popupParam->SetMessage(messageVal->ToString());
436     }
437 
438     auto messageOptions = popupObj->GetProperty("messageOptions");
439     JSRef<JSObject> messageOptionsObj;
440     if (!messageOptions->IsNull() && messageOptions->IsObject()) {
441         messageOptionsObj = JSRef<JSObject>::Cast(messageOptions);
442         SetPopupMessageOptions(messageOptionsObj, popupParam);
443     }
444 
445     JSRef<JSVal> primaryButtonVal = popupObj->GetProperty("primaryButton");
446     if (primaryButtonVal->IsObject()) {
447         ButtonProperties properties;
448         JSRef<JSObject> obj = JSRef<JSObject>::Cast(primaryButtonVal);
449         JSRef<JSVal> value = obj->GetProperty("value");
450         if (value->IsString()) {
451             properties.value = value->ToString();
452         }
453 
454         JSRef<JSVal> actionValue = obj->GetProperty("action");
455         if (actionValue->IsFunction()) {
456             auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
457             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
458             if (popupParam) {
459                 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
460                                          node = targetNode](GestureEvent& info) {
461                     JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
462                     ACE_SCORING_EVENT("primaryButton.action");
463                     PipelineContext::SetCallBackNode(node);
464                     func->Execute(info);
465                 };
466                 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
467             }
468         }
469         properties.showButton = true;
470         if (popupParam) {
471             popupParam->SetPrimaryButtonProperties(properties);
472         }
473     }
474 
475     JSRef<JSVal> secondaryButtonVal = popupObj->GetProperty("secondaryButton");
476     if (secondaryButtonVal->IsObject()) {
477         ButtonProperties properties;
478         JSRef<JSObject> obj = JSRef<JSObject>::Cast(secondaryButtonVal);
479         JSRef<JSVal> value = obj->GetProperty("value");
480         if (value->IsString()) {
481             properties.value = value->ToString();
482         }
483 
484         JSRef<JSVal> actionValue = obj->GetProperty("action");
485         if (actionValue->IsFunction()) {
486             auto jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionValue));
487             auto targetNode =
488                 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
489             if (popupParam) {
490                 auto clickCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc),
491                                          node = targetNode](GestureEvent& info) {
492                     JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
493                     ACE_SCORING_EVENT("secondaryButton.action");
494                     PipelineContext::SetCallBackNode(node);
495                     func->Execute(info);
496                 };
497                 properties.action = AceType::MakeRefPtr<NG::ClickEvent>(clickCallback);
498             }
499         }
500         properties.showButton = true;
501         if (popupParam) {
502             popupParam->SetSecondaryButtonProperties(properties);
503         }
504     }
505 }
506 
ParseCustomPopupParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)507 void ParseCustomPopupParam(
508     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
509 {
510     auto builderValue = popupObj->GetProperty("builder");
511     if (!builderValue->IsObject()) {
512         return;
513     }
514     if (!builderValue->IsFunction()) {
515         JSRef<JSObject> builderObj;
516         builderObj = JSRef<JSObject>::Cast(builderValue);
517         auto builder = builderObj->GetProperty("builder");
518         if (!builder->IsFunction()) {
519             return;
520         }
521         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
522         if (!builderFunc) {
523             return;
524         }
525     }
526     if (popupParam) {
527         popupParam->SetUseCustomComponent(true);
528     }
529 
530     auto focusableValue = popupObj->GetProperty("focusable");
531     if (focusableValue->IsBoolean()) {
532         popupParam->SetFocusable(focusableValue->ToBoolean());
533     }
534 
535     ParsePopupCommonParam(info, popupObj, popupParam);
536 }
537 
ParseTipsParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)538 void ParseTipsParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
539 {
540     CHECK_NULL_VOID(tipsParam);
541     auto appearingTimeVal = tipsObj->GetProperty("appearingTime");
542     if (appearingTimeVal->IsNumber()) {
543         auto appearingTime = appearingTimeVal->ToNumber<int32_t>();
544         if (appearingTime >= 0) {
545             tipsParam->SetAppearingTime(appearingTime);
546         }
547     }
548 
549     auto disappearingTimeVal = tipsObj->GetProperty("disappearingTime");
550     if (disappearingTimeVal->IsNumber()) {
551         auto disappearingTime = disappearingTimeVal->ToNumber<int32_t>();
552         if (disappearingTime >= 0) {
553             tipsParam->SetDisappearingTime(disappearingTime);
554         }
555     }
556 
557     auto appearingTimeWithContinuousOperationVal = tipsObj->GetProperty("appearingTimeWithContinuousOperation");
558     if (appearingTimeWithContinuousOperationVal->IsNumber()) {
559         auto appearingTimeWithContinuousOperation = appearingTimeWithContinuousOperationVal->ToNumber<int32_t>();
560         if (appearingTimeWithContinuousOperation >= 0) {
561             tipsParam->SetAppearingTimeWithContinuousOperation(appearingTimeWithContinuousOperation);
562         }
563     }
564 
565     auto disappearingTimeWithContinuousOperationVal = tipsObj->GetProperty("disappearingTimeWithContinuousOperation");
566     if (disappearingTimeWithContinuousOperationVal->IsNumber()) {
567         auto disappearingTimeWithContinuousOperation = disappearingTimeWithContinuousOperationVal->ToNumber<int32_t>();
568         if (disappearingTimeWithContinuousOperation >= 0) {
569             tipsParam->SetDisappearingTimeWithContinuousOperation(disappearingTimeWithContinuousOperation);
570         }
571     }
572 
573     auto enableArrowValue = tipsObj->GetProperty("enableArrow");
574     if (enableArrowValue->IsBoolean()) {
575         tipsParam->SetEnableArrow(enableArrowValue->ToBoolean());
576     }
577     tipsParam->SetBlockEvent(false);
578     tipsParam->SetTipsFlag(true);
579 }
580 
ParseTipsArrowPositionParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)581 void ParseTipsArrowPositionParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
582 {
583     CalcDimension offset;
584     auto arrowPointPosition = tipsObj->GetProperty("arrowPointPosition");
585     if (arrowPointPosition->IsString()) {
586         char* pEnd = nullptr;
587         auto arrowString = arrowPointPosition->ToString();
588         std::strtod(arrowString.c_str(), &pEnd);
589         if (pEnd != nullptr) {
590             if (std::strcmp(pEnd, "Start") == 0) {
591                 offset = ARROW_ZERO_PERCENT_VALUE;
592             }
593             if (std::strcmp(pEnd, "Center") == 0) {
594                 offset = ARROW_HALF_PERCENT_VALUE;
595             }
596             if (std::strcmp(pEnd, "End") == 0) {
597                 offset = ARROW_ONE_HUNDRED_PERCENT_VALUE;
598             }
599             if (tipsParam) {
600                 tipsParam->SetArrowOffset(offset);
601             }
602         }
603     }
604 }
605 
ParseTipsArrowSizeParam(const JSRef<JSObject> & tipsObj,const RefPtr<PopupParam> & tipsParam)606 void ParseTipsArrowSizeParam(const JSRef<JSObject>& tipsObj, const RefPtr<PopupParam>& tipsParam)
607 {
608     auto arrowWidthVal = tipsObj->GetProperty("arrowWidth");
609     if (!arrowWidthVal->IsNull()) {
610         bool setError = true;
611         CalcDimension arrowWidth;
612         if (JSViewAbstract::ParseJsDimensionVp(arrowWidthVal, arrowWidth)) {
613             if (arrowWidth.Value() > 0 && arrowWidth.Unit() != DimensionUnit::PERCENT) {
614                 tipsParam->SetArrowWidth(arrowWidth);
615                 setError = false;
616             }
617         }
618         tipsParam->SetErrorArrowWidth(setError);
619     }
620 
621     auto arrowHeightVal = tipsObj->GetProperty("arrowHeight");
622     if (!arrowHeightVal->IsNull()) {
623         bool setError = true;
624         CalcDimension arrowHeight;
625         if (JSViewAbstract::ParseJsDimensionVp(arrowHeightVal, arrowHeight)) {
626             if (arrowHeight.Value() > 0 && arrowHeight.Unit() != DimensionUnit::PERCENT) {
627                 tipsParam->SetArrowHeight(arrowHeight);
628                 setError = false;
629             }
630         }
631         tipsParam->SetErrorArrowHeight(setError);
632     }
633 }
634 #endif
635 
ParseBindContextMenuShow(const JSCallbackInfo & info,NG::MenuParam & menuParam)636 uint32_t ParseBindContextMenuShow(const JSCallbackInfo& info, NG::MenuParam& menuParam)
637 {
638     size_t builderIndex = 0;
639     if (info[0]->IsBoolean()) {
640         menuParam.isShow = info[0]->ToBoolean();
641         menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
642         menuParam.placement = Placement::BOTTOM_LEFT;
643         builderIndex = 1;
644     } else if (info[0]->IsObject()) {
645         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
646         menuParam.onStateChange = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
647         auto isShowObj = callbackObj->GetProperty("value");
648         if (isShowObj->IsBoolean()) {
649             menuParam.isShow = isShowObj->ToBoolean();
650             menuParam.contextMenuRegisterType = NG::ContextMenuRegisterType::CUSTOM_TYPE;
651             menuParam.placement = Placement::BOTTOM_LEFT;
652             builderIndex = 1;
653         }
654     }
655     return builderIndex;
656 }
657 
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)658 void JSViewAbstract::ParseOverlayCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
659     std::function<void()>& onDisappear, std::function<void()>& onWillAppear, std::function<void()>& onWillDisappear,
660     std::function<void(const int32_t& info)>& onWillDismiss)
661 {
662     auto showCallback = paramObj->GetProperty("onAppear");
663     auto dismissCallback = paramObj->GetProperty("onDisappear");
664     auto willShowCallback = paramObj->GetProperty("onWillAppear");
665     auto willDismissCallback = paramObj->GetProperty("onWillDisappear");
666     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
667     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
668     if (showCallback->IsFunction()) {
669         RefPtr<JsFunction> jsFunc =
670             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(showCallback));
671         onAppear = [func = std::move(jsFunc), node = frameNode]() {
672             PipelineContext::SetCallBackNode(node);
673             func->Execute();
674         };
675     }
676     if (dismissCallback->IsFunction()) {
677         RefPtr<JsFunction> jsFunc =
678             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(dismissCallback));
679         onDisappear = [func = std::move(jsFunc), node = frameNode]() {
680             PipelineContext::SetCallBackNode(node);
681             func->Execute();
682         };
683     }
684     if (willShowCallback->IsFunction()) {
685         RefPtr<JsFunction> jsFunc =
686             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willShowCallback));
687         onWillAppear = [func = std::move(jsFunc)]() { func->Execute(); };
688     }
689     if (willDismissCallback->IsFunction()) {
690         RefPtr<JsFunction> jsFunc =
691             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(willDismissCallback));
692         onWillDisappear = [func = std::move(jsFunc)]() { func->Execute(); };
693     }
694     if (onWillDismissFunc->IsFunction()) {
695         RefPtr<JsFunction> jsFunc =
696             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
697         onWillDismiss = [func = std::move(jsFunc), node = frameNode](const int32_t& info) {
698             ACE_SCORING_EVENT("contentCover.dismiss");
699             PipelineContext::SetCallBackNode(node);
700             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
701             objectTemplate->SetInternalFieldCount(1);
702             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
703             dismissObj->SetPropertyObject(
704                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissContentCover));
705             dismissObj->SetProperty<int32_t>("reason", info);
706             JSRef<JSVal> newJSVal = dismissObj;
707             func->ExecuteJS(1, &newJSVal);
708         };
709     }
710 }
711 
ParseBindOptionParam(const JSCallbackInfo & info,size_t optionIndex)712 std::vector<NG::OptionParam> JSViewPopups::ParseBindOptionParam(const JSCallbackInfo& info, size_t optionIndex)
713 {
714     JSRef<JSVal> arg = info[optionIndex];
715     if (!arg->IsArray()) {
716         return std::vector<NG::OptionParam>();
717     }
718     auto paramArray = JSRef<JSArray>::Cast(arg);
719     auto paramArrayLength = paramArray->Length();
720     std::vector<NG::OptionParam> params(paramArrayLength);
721     // parse paramArray
722     for (size_t i = 0; i < paramArrayLength; ++i) {
723         if (!paramArray->GetValueAt(i)->IsObject()) {
724             return std::vector<NG::OptionParam>();
725         }
726         auto indexObject = JSRef<JSObject>::Cast(paramArray->GetValueAt(i));
727         JSViewAbstract::ParseJsString(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE)),
728             params[i].value);
729         auto actionFunc = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ACTION));
730         if (!actionFunc->IsFunction()) {
731             return params;
732         }
733         auto action = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(actionFunc));
734         auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
735         // set onClick function
736         params[i].action = [func = std::move(action), context = info.GetExecutionContext(), node = targetNode]() {
737             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(context);
738             ACE_SCORING_EVENT("menu.action");
739             PipelineContext::SetCallBackNode(node);
740             if (func) {
741                 func->Execute();
742             }
743         };
744         std::string iconPath;
745         if (JSViewAbstract::ParseJsMedia(indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ICON)), iconPath)) {
746             params[i].icon = iconPath;
747         }
748         if (indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON))->IsObject()) {
749             std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
750             JSViewAbstract::SetSymbolOptionApply(info, symbolApply,
751                 indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::SYMBOL_ICON)));
752             params[i].symbol = symbolApply;
753         }
754         auto enabled = indexObject->GetProperty(static_cast<int32_t>(ArkUIIndex::ENABLED));
755         if (enabled->IsBoolean()) {
756             params[i].enabled = enabled->ToBoolean();
757         }
758     }
759     return params;
760 }
761 
ParseMenuBorderRadius(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)762 void JSViewPopups::ParseMenuBorderRadius(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
763 {
764     auto borderRadiusValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BORDER_RADIUS));
765     NG::BorderRadiusProperty menuBorderRadius;
766     CalcDimension borderRadius;
767     if (JSViewAbstract::ParseJsDimensionVp(borderRadiusValue, borderRadius)) {
768         if (GreatOrEqual(borderRadius.Value(), 0.0f)) {
769             menuBorderRadius.SetRadius(borderRadius);
770             menuBorderRadius.multiValued = false;
771             menuParam.borderRadius = menuBorderRadius;
772         };
773     } else if (borderRadiusValue->IsObject()) {
774         JSRef<JSObject> object = JSRef<JSObject>::Cast(borderRadiusValue);
775         CalcDimension topLeft;
776         CalcDimension topRight;
777         CalcDimension bottomLeft;
778         CalcDimension bottomRight;
779         bool hasSetBorderRadius =
780             JSViewAbstract::ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight);
781         if (LessNotEqual(topLeft.Value(), 0.0f)) {
782             topLeft.Reset();
783         }
784         if (LessNotEqual(topRight.Value(), 0.0f)) {
785             topRight.Reset();
786         }
787         if (LessNotEqual(bottomLeft.Value(), 0.0f)) {
788             bottomLeft.Reset();
789         }
790         if (LessNotEqual(bottomRight.Value(), 0.0f)) {
791             bottomRight.Reset();
792         }
793         auto isRtl = hasSetBorderRadius && AceApplicationInfo::GetInstance().IsRightToLeft();
794         menuBorderRadius.radiusTopLeft = isRtl ? topRight : topLeft;
795         menuBorderRadius.radiusTopRight = isRtl ? topLeft : topRight;
796         menuBorderRadius.radiusBottomLeft = isRtl ? bottomRight : bottomLeft;
797         menuBorderRadius.radiusBottomRight = isRtl ? bottomLeft : bottomRight;
798         menuBorderRadius.multiValued = true;
799         menuParam.borderRadius = menuBorderRadius;
800     }
801 }
802 
ParseMenuArrowParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)803 void JSViewPopups::ParseMenuArrowParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
804 {
805     auto enableArrowValue = menuOptions->GetProperty("enableArrow");
806     if (enableArrowValue->IsBoolean()) {
807         menuParam.enableArrow = enableArrowValue->ToBoolean();
808     }
809 
810     auto arrowOffset = menuOptions->GetProperty("arrowOffset");
811     CalcDimension offset;
812     if (JSViewAbstract::ParseJsDimensionVp(arrowOffset, offset)) {
813         menuParam.arrowOffset = offset;
814     }
815 
816     // if enableArrow is true and placement not set, set placement default value to top.
817     if (menuParam.enableArrow.has_value() && !menuParam.placement.has_value() && menuParam.enableArrow.value()) {
818         menuParam.placement = Placement::TOP;
819     }
820 }
821 
ParseLayoutRegionMargin(const JSRef<JSVal> & jsValue,std::optional<CalcDimension> & calcDimension)822 void JSViewPopups::ParseLayoutRegionMargin(const JSRef<JSVal>& jsValue, std::optional<CalcDimension>& calcDimension)
823 {
824     CalcDimension dimension;
825     if (!JSViewAbstract::ParseJsDimensionVpNG(jsValue, dimension, true)) {
826         return;
827     }
828 
829     if (dimension.IsNonNegative() && dimension.CalcValue().find("calc") == std::string::npos) {
830         calcDimension = dimension;
831     }
832 }
833 
ParseMenuLayoutRegionMarginParam(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)834 void JSViewPopups::ParseMenuLayoutRegionMarginParam(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
835 {
836     auto marginVal = menuOptions->GetProperty("layoutRegionMargin");
837     if (!marginVal->IsObject()) {
838         return;
839     }
840 
841     CommonCalcDimension commonCalcDimension;
842     auto object = JSRef<JSObject>::Cast(marginVal);
843     JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("top"), commonCalcDimension.top);
844     JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("bottom"), commonCalcDimension.bottom);
845     JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("left"), commonCalcDimension.left);
846     JSViewPopups::ParseLayoutRegionMargin(object->GetProperty("right"), commonCalcDimension.right);
847 
848     if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
849         commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
850         menuParam.layoutRegionMargin = JSViewAbstract::GetLocalizedPadding(
851             commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left, commonCalcDimension.right);
852     }
853 }
854 
ParseMenuBlurStyleOption(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)855 void JSViewPopups::ParseMenuBlurStyleOption(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
856 {
857     auto blurStyle = menuOptions->GetProperty("backgroundBlurStyleOptions");
858     if (blurStyle->IsObject()) {
859         if (!menuParam.blurStyleOption.has_value()) {
860             menuParam.blurStyleOption.emplace();
861         }
862         JSViewAbstract::ParseBlurStyleOption(blurStyle, menuParam.blurStyleOption.value());
863     }
864 }
865 
ParseMenuEffectOption(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)866 void JSViewPopups::ParseMenuEffectOption(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
867 {
868     auto effectOption = menuOptions->GetProperty("backgroundEffect");
869     if (effectOption->IsObject()) {
870         if (!menuParam.effectOption.has_value()) {
871             menuParam.effectOption.emplace();
872         }
873         JSViewAbstract::ParseEffectOption(effectOption, menuParam.effectOption.value());
874     }
875 }
876 
ParseMenuHapticFeedbackMode(const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)877 void JSViewPopups::ParseMenuHapticFeedbackMode(const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
878 {
879     auto hapticFeedbackMode = menuOptions->GetProperty("hapticFeedbackMode");
880     if (!hapticFeedbackMode->IsNumber()) {
881         return;
882     }
883     if (hapticFeedbackMode->ToNumber<int32_t>() == HAPTIC_FEEDBACK_MODE_ENABLED) {
884         menuParam.hapticFeedbackMode = HapticFeedbackMode::ENABLED;
885     } else if (hapticFeedbackMode->ToNumber<int32_t>() == HAPTIC_FEEDBACK_MODE_AUTO) {
886         menuParam.hapticFeedbackMode = HapticFeedbackMode::AUTO;
887     }
888 }
889 
GetMenuShowInSubwindow(NG::MenuParam & menuParam)890 void JSViewPopups::GetMenuShowInSubwindow(NG::MenuParam& menuParam)
891 {
892     menuParam.isShowInSubWindow = false;
893     auto pipeline = PipelineBase::GetCurrentContext();
894     CHECK_NULL_VOID(pipeline);
895     auto theme = pipeline->GetTheme<SelectTheme>();
896     CHECK_NULL_VOID(theme);
897     menuParam.isShowInSubWindow = theme->GetExpandDisplay();
898 }
899 
ParseMenuParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuOptions,NG::MenuParam & menuParam)900 void JSViewPopups::ParseMenuParam(
901     const JSCallbackInfo& info, const JSRef<JSObject>& menuOptions, NG::MenuParam& menuParam)
902 {
903     auto offsetVal = menuOptions->GetProperty("offset");
904     if (offsetVal->IsObject()) {
905         auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
906         JSRef<JSVal> xVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::X));
907         JSRef<JSVal> yVal = offsetObj->GetProperty(static_cast<int32_t>(ArkUIIndex::Y));
908         CalcDimension dx;
909         CalcDimension dy;
910         if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
911             menuParam.positionOffset.SetX(dx.ConvertToPx());
912         }
913         if (JSViewAbstract::ParseJsDimensionVp(yVal, dy)) {
914             menuParam.positionOffset.SetY(dy.ConvertToPx());
915         }
916     }
917 
918     auto placementValue = menuOptions->GetProperty("placement");
919     if (placementValue->IsNumber()) {
920         auto placement = placementValue->ToNumber<int32_t>();
921         if (placement >= 0 && placement < static_cast<int32_t>(Placement::NONE)) {
922             menuParam.placement = static_cast<Placement>(placement);
923         }
924     }
925 
926     auto enableHoverModeValue = menuOptions->GetProperty("enableHoverMode");
927     if (enableHoverModeValue->IsBoolean()) {
928         menuParam.enableHoverMode = enableHoverModeValue->ToBoolean();
929     }
930 
931     auto backgroundColorValue = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_COLOR));
932     Color backgroundColor;
933     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
934         menuParam.backgroundColor = backgroundColor;
935     }
936 
937     auto backgroundBlurStyle = menuOptions->GetProperty(static_cast<int32_t>(ArkUIIndex::BACKGROUND_BLUR_STYLE));
938     if (backgroundBlurStyle->IsNumber()) {
939         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
940         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
941             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
942             menuParam.backgroundBlurStyle = blurStyle;
943         }
944     }
945     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
946     auto onAppearValue = menuOptions->GetProperty("onAppear");
947     if (onAppearValue->IsFunction()) {
948         RefPtr<JsFunction> jsOnAppearFunc =
949             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAppearValue));
950         auto onAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnAppearFunc), node = frameNode]() {
951             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
952             ACE_SCORING_EVENT("onAppear");
953             PipelineContext::SetCallBackNode(node);
954             func->Execute();
955         };
956         menuParam.onAppear = std::move(onAppear);
957     }
958 
959     auto onDisappearValue = menuOptions->GetProperty("onDisappear");
960     if (onDisappearValue->IsFunction()) {
961         RefPtr<JsFunction> jsOnDisAppearFunc =
962             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDisappearValue));
963         auto onDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDisAppearFunc),
964                                node = frameNode]() {
965             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
966             ACE_SCORING_EVENT("onDisappear");
967             PipelineContext::SetCallBackNode(node);
968             func->Execute();
969         };
970         menuParam.onDisappear = std::move(onDisappear);
971     }
972     auto aboutToAppearValue = menuOptions->GetProperty("aboutToAppear");
973     if (aboutToAppearValue->IsFunction()) {
974         RefPtr<JsFunction> jsAboutToAppearFunc =
975             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToAppearValue));
976         auto aboutToAppear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToAppearFunc),
977                                  node = frameNode]() {
978             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
979             ACE_SCORING_EVENT("aboutToAppear");
980             PipelineContext::SetCallBackNode(node);
981             func->Execute();
982         };
983         menuParam.aboutToAppear = std::move(aboutToAppear);
984     }
985 
986     auto aboutToDisAppearValue = menuOptions->GetProperty("aboutToDisappear");
987     if (aboutToDisAppearValue->IsFunction()) {
988         RefPtr<JsFunction> jsAboutToDisAppearFunc =
989             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(aboutToDisAppearValue));
990         auto aboutToDisappear = [execCtx = info.GetExecutionContext(), func = std::move(jsAboutToDisAppearFunc),
991                                     node = frameNode]() {
992             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
993             ACE_SCORING_EVENT("aboutToDisappear");
994             PipelineContext::SetCallBackNode(node);
995             func->Execute();
996         };
997         menuParam.aboutToDisappear = std::move(aboutToDisappear);
998     }
999 
1000     auto menuTransition = menuOptions->GetProperty("transition");
1001     menuParam.hasTransitionEffect = false;
1002     if (menuTransition->IsObject()) {
1003         auto obj = JSRef<JSObject>::Cast(menuTransition);
1004         menuParam.hasTransitionEffect = true;
1005         menuParam.transition = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
1006     }
1007 
1008     JSRef<JSVal> showInSubWindowValue = menuOptions->GetProperty("showInSubWindow");
1009     JSViewPopups::GetMenuShowInSubwindow(menuParam);
1010     if (menuParam.isShowInSubWindow) {
1011         if (showInSubWindowValue->IsBoolean()) {
1012             menuParam.isShowInSubWindow = showInSubWindowValue->ToBoolean();
1013         }
1014     }
1015     JSViewPopups::ParseMenuArrowParam(menuOptions, menuParam);
1016     JSViewPopups::ParseMenuBorderRadius(menuOptions, menuParam);
1017     JSViewPopups::ParseMenuLayoutRegionMarginParam(menuOptions, menuParam);
1018     JSViewPopups::ParseMenuBlurStyleOption(menuOptions, menuParam);
1019     JSViewPopups::ParseMenuEffectOption(menuOptions, menuParam);
1020     JSViewPopups::ParseMenuHapticFeedbackMode(menuOptions, menuParam);
1021 }
1022 
ParseBindOptionParam(const JSCallbackInfo & info,NG::MenuParam & menuParam,size_t optionIndex)1023 void JSViewPopups::ParseBindOptionParam(const JSCallbackInfo& info, NG::MenuParam& menuParam, size_t optionIndex)
1024 {
1025     if (!info[optionIndex]->IsObject()) {
1026         return;
1027     }
1028     auto menuOptions = JSRef<JSObject>::Cast(info[optionIndex]);
1029     JSViewAbstract::ParseJsString(menuOptions->GetProperty("title"), menuParam.title);
1030     JSViewPopups::ParseMenuParam(info, menuOptions, menuParam);
1031 }
1032 
ParseAnimationScaleArray(const JSRef<JSArray> & scaleArray,MenuPreviewAnimationOptions & options)1033 void ParseAnimationScaleArray(const JSRef<JSArray>& scaleArray, MenuPreviewAnimationOptions& options)
1034 {
1035     constexpr int scaleArraySize = 2;
1036     if (scaleArray->Length() == scaleArraySize) {
1037         auto scalePropertyFrom = scaleArray->GetValueAt(0);
1038         if (scalePropertyFrom->IsNumber()) {
1039             auto scaleFrom = scalePropertyFrom->ToNumber<float>();
1040             options.scaleFrom = LessOrEqual(scaleFrom, 0.0) ? -1.0f : scaleFrom;
1041         }
1042         auto scalePropertyTo = scaleArray->GetValueAt(1);
1043         if (scalePropertyTo->IsNumber()) {
1044             auto scaleTo = scalePropertyTo->ToNumber<float>();
1045             options.scaleTo = LessOrEqual(scaleTo, 0.0) ? -1.0f : scaleTo;
1046         }
1047     }
1048 }
1049 
ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)1050 void ParseContentPreviewAnimationOptionsParam(const JSCallbackInfo& info, const JSRef<JSObject>& menuContentOptions,
1051     NG::MenuParam& menuParam)
1052 {
1053     menuParam.previewAnimationOptions.scaleFrom = -1.0f;
1054     menuParam.previewAnimationOptions.scaleTo = -1.0f;
1055 
1056     auto animationOptions = menuContentOptions->GetProperty("previewAnimationOptions");
1057     if (!animationOptions->IsEmpty() && animationOptions->IsObject()) {
1058         auto animationOptionsObj = JSRef<JSObject>::Cast(animationOptions);
1059         auto scaleProperty = animationOptionsObj->GetProperty("scale");
1060         if (!scaleProperty->IsEmpty() && scaleProperty->IsArray()) {
1061             JSRef<JSArray> scaleArray = JSRef<JSArray>::Cast(scaleProperty);
1062             ParseAnimationScaleArray(scaleArray, menuParam.previewAnimationOptions);
1063         }
1064         auto previewTransition = animationOptionsObj->GetProperty("transition");
1065         menuParam.hasPreviewTransitionEffect = false;
1066         if (previewTransition->IsObject()) {
1067             auto obj = JSRef<JSObject>::Cast(previewTransition);
1068             menuParam.hasPreviewTransitionEffect = true;
1069             menuParam.previewTransition = JSViewAbstract::ParseChainedTransition(obj, info.GetExecutionContext());
1070         }
1071         if (menuParam.previewMode != MenuPreviewMode::CUSTOM ||
1072             menuParam.hasPreviewTransitionEffect || menuParam.hasTransitionEffect ||
1073             menuParam.contextMenuRegisterType == NG::ContextMenuRegisterType::CUSTOM_TYPE) {
1074             return;
1075         }
1076         auto hoverScaleProperty = animationOptionsObj->GetProperty("hoverScale");
1077         menuParam.isShowHoverImage = false;
1078         menuParam.hoverImageAnimationOptions.scaleFrom = -1.0f;
1079         menuParam.hoverImageAnimationOptions.scaleTo = -1.0f;
1080         if (!hoverScaleProperty->IsEmpty() && hoverScaleProperty->IsArray()) {
1081             JSRef<JSArray> hoverScaleArray = JSRef<JSArray>::Cast(hoverScaleProperty);
1082             ParseAnimationScaleArray(hoverScaleArray, menuParam.hoverImageAnimationOptions);
1083             menuParam.isShowHoverImage = true;
1084         }
1085     }
1086 }
1087 
ParsePreviewBorderRadiusParam(const JSRef<JSObject> & menuContentOptions,NG::MenuParam & menuParam)1088 void ParsePreviewBorderRadiusParam(const JSRef<JSObject>& menuContentOptions, NG::MenuParam& menuParam)
1089 {
1090     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_SIXTEEN)) {
1091         return;
1092     }
1093     auto previewBorderRadiusValue = menuContentOptions->GetProperty("previewBorderRadius");
1094     NG::BorderRadiusProperty previewBorderRadius;
1095     JSViewAbstract::ParseBorderRadius(previewBorderRadiusValue, previewBorderRadius);
1096     menuParam.previewBorderRadius = previewBorderRadius;
1097 }
1098 
ParseBindContentOptionParam(const JSCallbackInfo & info,const JSRef<JSVal> & args,NG::MenuParam & menuParam,std::function<void ()> & previewBuildFunc)1099 void ParseBindContentOptionParam(const JSCallbackInfo& info, const JSRef<JSVal>& args, NG::MenuParam& menuParam,
1100     std::function<void()>& previewBuildFunc)
1101 {
1102     if (!args->IsObject()) {
1103         return;
1104     }
1105     auto menuContentOptions = JSRef<JSObject>::Cast(args);
1106     JSViewPopups::ParseMenuParam(info, menuContentOptions, menuParam);
1107     RefPtr<JsFunction> previewBuilderFunc;
1108     auto preview = menuContentOptions->GetProperty("preview");
1109     if (!preview->IsFunction() && !preview->IsNumber()) {
1110         return;
1111     }
1112 
1113     if (preview->IsNumber()) {
1114         if (preview->ToNumber<int32_t>() == 1) {
1115             menuParam.previewMode = MenuPreviewMode::IMAGE;
1116             ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
1117             ParsePreviewBorderRadiusParam(menuContentOptions, menuParam);
1118         }
1119     } else {
1120         previewBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(preview));
1121         CHECK_NULL_VOID(previewBuilderFunc);
1122         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1123         previewBuildFunc = [execCtx = info.GetExecutionContext(), func = std::move(previewBuilderFunc),
1124                                node = frameNode]() {
1125             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1126             ACE_SCORING_EVENT("BuildContextMenuPreviwer");
1127             PipelineContext::SetCallBackNode(node);
1128             func->Execute();
1129         };
1130         menuParam.previewMode = MenuPreviewMode::CUSTOM;
1131         ParseContentPreviewAnimationOptionsParam(info, menuContentOptions, menuParam);
1132         ParsePreviewBorderRadiusParam(menuContentOptions, menuParam);
1133     }
1134 }
1135 
1136 #ifndef WEARABLE_PRODUCT
JsBindPopup(const JSCallbackInfo & info)1137 void JSViewAbstract::JsBindPopup(const JSCallbackInfo& info)
1138 {
1139     if (info.Length() < PARAMETER_LENGTH_SECOND) {
1140         return;
1141     }
1142     if ((!info[NUM_ZERO]->IsBoolean() && !info[NUM_ZERO]->IsObject()) || !info[NUM_FIRST]->IsObject()) {
1143         return;
1144     }
1145     auto popupParam = AceType::MakeRefPtr<PopupParam>();
1146     // Set IsShow to popupParam
1147     if (info[NUM_ZERO]->IsBoolean()) {
1148         popupParam->SetIsShow(info[NUM_ZERO]->ToBoolean());
1149     } else {
1150         JSRef<JSObject> showObj = JSRef<JSObject>::Cast(info[NUM_ZERO]);
1151         auto callback = JSViewPopups::ParseDoubleBindCallback(info, showObj, "$value");
1152         popupParam->SetDoubleBindCallback(std::move(callback));
1153         popupParam->SetIsShow(showObj->GetProperty("value")->ToBoolean());
1154     }
1155     // Set popup to popupParam
1156     auto popupObj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1157     SetPopupDismiss(info, popupObj, popupParam);
1158     if (popupObj->GetProperty("message")->IsString()) {
1159         ParsePopupParam(info, popupObj, popupParam); // Parse PopupOptions param
1160         ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
1161     } else if (!popupObj->GetProperty("builder").IsEmpty()) {
1162         ParseCustomPopupParam(info, popupObj, popupParam); // Parse CustomPopupOptions param
1163         auto builderValue = popupObj->GetProperty("builder");
1164         auto builder = builderValue;
1165         if (!builderValue->IsObject()) {
1166             return;
1167         }
1168         if (!builderValue->IsFunction()) {
1169             JSRef<JSObject> builderObj;
1170             builderObj = JSRef<JSObject>::Cast(builderValue);
1171             builder = builderObj->GetProperty("builder");
1172             if (!builder->IsFunction()) {
1173                 return;
1174             }
1175         }
1176         if (popupParam->IsShow() && !IsPopupCreated()) {
1177             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1178             CHECK_NULL_VOID(builderFunc);
1179             ViewStackModel::GetInstance()->NewScope();
1180             builderFunc->Execute();
1181             auto customNode = ViewStackModel::GetInstance()->Finish();
1182             ViewAbstractModel::GetInstance()->BindPopup(popupParam, customNode);
1183         } else {
1184             ViewAbstractModel::GetInstance()->BindPopup(popupParam, nullptr);
1185         }
1186     } else {
1187         return;
1188     }
1189 }
1190 
JsBindTips(const JSCallbackInfo & info)1191 void JSViewAbstract::JsBindTips(const JSCallbackInfo& info)
1192 {
1193     if (info.Length() < PARAMETER_LENGTH_SECOND || (!info[NUM_ZERO]->IsString() && !info[NUM_ZERO]->IsObject()) ||
1194         !info[NUM_FIRST]->IsObject()) {
1195         return;
1196     }
1197     auto tipsParam = AceType::MakeRefPtr<PopupParam>();
1198     CHECK_NULL_VOID(tipsParam);
1199     // Set message to tipsParam
1200     tipsParam->SetMessage(info[0]->ToString());
1201     // Set bindTipsOptions to tipsParam
1202     auto tipsObj = JSRef<JSObject>::Cast(info[1]);
1203     // Parse bindTipsOptions param
1204     ParseTipsParam(tipsObj, tipsParam);
1205     ParseTipsArrowPositionParam(tipsObj, tipsParam);
1206     ParseTipsArrowSizeParam(tipsObj, tipsParam);
1207     ViewAbstractModel::GetInstance()->BindTips(tipsParam);
1208 }
1209 
SetPopupDismiss(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1210 void JSViewAbstract::SetPopupDismiss(
1211     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1212 {
1213     auto onWillDismissFunc = popupObj->GetProperty("onWillDismiss");
1214     if (onWillDismissFunc->IsBoolean()) {
1215         bool onWillDismissBool = onWillDismissFunc->ToBoolean();
1216         popupParam->SetInteractiveDismiss(onWillDismissBool);
1217         popupParam->SetOnWillDismiss(nullptr);
1218         if (onWillDismissBool) {
1219             TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
1220         }
1221     } else if (onWillDismissFunc->IsFunction()) {
1222         auto onWillDismissCallback = ParsePopupCallback(info, popupObj);
1223         popupParam->SetOnWillDismiss(std::move(onWillDismissCallback));
1224         popupParam->SetInteractiveDismiss(true);
1225         if (onWillDismissCallback != nullptr) {
1226             TAG_LOGI(AceLogTag::ACE_FORM, "popup register onWillDismiss");
1227         }
1228     }
1229 }
1230 
ParsePopupCallback(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)1231 PopupOnWillDismiss JSViewAbstract::ParsePopupCallback(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
1232 {
1233     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
1234     if (!onWillDismissFunc->IsFunction()) {
1235         return PopupOnWillDismiss();
1236     }
1237     RefPtr<JsFunction> jsFunc =
1238         AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
1239     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1240     auto onWillDismiss = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
1241                           node = frameNode](int32_t reason) {
1242         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1243         ACE_SCORING_EVENT("Bindpopup.dismiss");
1244         PipelineContext::SetCallBackNode(node);
1245 
1246         JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1247         objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
1248         JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1249         dismissObj->SetPropertyObject("dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissPopup));
1250         dismissObj->SetProperty<int32_t>("reason", reason);
1251         JSRef<JSVal> newJSVal = dismissObj;
1252         func->ExecuteJS(1, &newJSVal);
1253     };
1254     return onWillDismiss;
1255 }
1256 
JsDismissPopup(panda::JsiRuntimeCallInfo * runtimeCallInfo)1257 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissPopup(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1258 {
1259     ViewAbstractModel::GetInstance()->DismissPopup();
1260     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1261 }
1262 
ParseContentPopupCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & popupObj,const RefPtr<PopupParam> & popupParam)1263 void JSViewAbstract::ParseContentPopupCommonParam(
1264     const JSCallbackInfo& info, const JSRef<JSObject>& popupObj, const RefPtr<PopupParam>& popupParam)
1265 {
1266     CHECK_EQUAL_VOID(popupObj->IsEmpty(), true);
1267     CHECK_NULL_VOID(popupParam);
1268     int32_t targetId = StringUtils::StringToInt(popupParam->GetTargetId(), -1);
1269     if (targetId < 0) {
1270         TAG_LOGE(AceLogTag::ACE_DIALOG, "The targetId is error.");
1271         return;
1272     }
1273     auto targetNode = ElementRegister::GetInstance()->GetSpecificItemById<NG::FrameNode>(targetId);
1274     if (!targetNode) {
1275         TAG_LOGE(AceLogTag::ACE_DIALOG, "The targetNode does not exist.");
1276         return;
1277     }
1278     SetPopupDismiss(info, popupObj, popupParam);
1279     ParsePopupCommonParam(info, popupObj, popupParam, targetNode);
1280     auto focusableValue = popupObj->GetProperty("focusable");
1281     if (focusableValue->IsBoolean()) {
1282         popupParam->SetFocusable(focusableValue->ToBoolean());
1283     }
1284 }
1285 
OpenPopup(const RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1286 int32_t JSViewAbstract::OpenPopup(const RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1287 {
1288     return ViewAbstractModel::GetInstance()->OpenPopup(param, customNode);
1289 }
1290 
UpdatePopup(const RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1291 int32_t JSViewAbstract::UpdatePopup(const RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1292 {
1293     return ViewAbstractModel::GetInstance()->UpdatePopup(param, customNode);
1294 }
1295 
ClosePopup(const RefPtr<NG::UINode> & customNode)1296 int32_t JSViewAbstract::ClosePopup(const RefPtr<NG::UINode>& customNode)
1297 {
1298     return ViewAbstractModel::GetInstance()->ClosePopup(customNode);
1299 }
1300 
GetPopupParam(RefPtr<PopupParam> & param,const RefPtr<NG::UINode> & customNode)1301 int32_t JSViewAbstract::GetPopupParam(RefPtr<PopupParam>& param, const RefPtr<NG::UINode>& customNode)
1302 {
1303     return ViewAbstractModel::GetInstance()->GetPopupParam(param, customNode);
1304 }
1305 
JsBindContextMenu(const JSCallbackInfo & info)1306 void JSViewAbstract::JsBindContextMenu(const JSCallbackInfo& info)
1307 {
1308     NG::MenuParam menuParam;
1309     // Check the parameters
1310     if (info.Length() <= PARAMETER_LENGTH_ZERO) {
1311         return;
1312     }
1313     size_t builderIndex = ParseBindContextMenuShow(info, menuParam);
1314     if (!info[builderIndex]->IsObject()) {
1315         return;
1316     }
1317 
1318     JSRef<JSObject> menuObj = JSRef<JSObject>::Cast(info[builderIndex]);
1319     auto builder = menuObj->GetProperty("builder");
1320     if (!builder->IsFunction()) {
1321         return;
1322     }
1323     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1324     CHECK_NULL_VOID(builderFunc);
1325 
1326     ResponseType responseType = ResponseType::LONG_PRESS;
1327     if (!info[NUM_ZERO]->IsBoolean() && info.Length() >= PARAMETER_LENGTH_SECOND && info[NUM_FIRST]->IsNumber()) {
1328         auto response = info[NUM_FIRST]->ToNumber<int32_t>();
1329         responseType = static_cast<ResponseType>(response);
1330     }
1331     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1332     std::function<void()> buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc),
1333                                           node = frameNode]() {
1334         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1335         ACE_SCORING_EVENT("BuildContextMenu");
1336         PipelineContext::SetCallBackNode(node);
1337         func->Execute();
1338     };
1339 
1340     menuParam.previewMode = MenuPreviewMode::NONE;
1341     std::function<void()> previewBuildFunc = nullptr;
1342     if (info.Length() >= PARAMETER_LENGTH_THIRD && info[NUM_SECOND]->IsObject()) {
1343         ParseBindContentOptionParam(info, info[NUM_SECOND], menuParam, previewBuildFunc);
1344     }
1345     if (responseType != ResponseType::LONG_PRESS) {
1346         menuParam.previewMode = MenuPreviewMode::NONE;
1347         menuParam.isShowHoverImage = false;
1348         menuParam.menuBindType = MenuBindingType::RIGHT_CLICK;
1349     }
1350     // arrow is disabled for contextMenu with preview
1351     if (menuParam.previewMode != MenuPreviewMode::NONE) {
1352         menuParam.enableArrow = false;
1353     }
1354     menuParam.type = NG::MenuType::CONTEXT_MENU;
1355     ViewAbstractModel::GetInstance()->BindContextMenu(responseType, buildFunc, menuParam, previewBuildFunc);
1356     ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(menuParam);
1357 }
1358 #endif
1359 
JsBindContentCover(const JSCallbackInfo & info)1360 void JSViewAbstract::JsBindContentCover(const JSCallbackInfo& info)
1361 {
1362     // parse isShow
1363     DoubleBindCallback callback = nullptr;
1364     bool isShow = ParseSheetIsShow(info, "ContentCover", callback);
1365 
1366     // parse builder
1367     if (!info[NUM_FIRST]->IsObject()) {
1368         return;
1369     }
1370     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1371     auto builder = obj->GetProperty("builder");
1372     if (!builder->IsFunction()) {
1373         return;
1374     }
1375     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1376     CHECK_NULL_VOID(builderFunc);
1377     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1378     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
1379         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1380         ACE_SCORING_EVENT("BindContentCover");
1381         PipelineContext::SetCallBackNode(node);
1382         func->Execute();
1383     };
1384 
1385     // parse ModalTransition
1386     NG::ModalStyle modalStyle;
1387     modalStyle.modalTransition = NG::ModalTransition::DEFAULT;
1388     std::function<void()> onShowCallback;
1389     std::function<void()> onDismissCallback;
1390     std::function<void()> onWillShowCallback;
1391     std::function<void()> onWillDismissCallback;
1392     NG::ContentCoverParam contentCoverParam;
1393     std::function<void(const int32_t&)> onWillDismissFunc;
1394     if (info.Length() == PARAMETER_LENGTH_THIRD) {
1395         if (info[NUM_SECOND]->IsObject()) {
1396             ParseOverlayCallback(info[NUM_SECOND], onShowCallback, onDismissCallback, /* 2:args index */
1397                 onWillShowCallback, onWillDismissCallback, onWillDismissFunc);
1398             ParseModalStyle(info[NUM_SECOND], modalStyle);
1399             contentCoverParam.onWillDismiss = std::move(onWillDismissFunc);
1400             ParseModalTransitonEffect(info[NUM_SECOND], contentCoverParam, /* 2:args index */
1401                 info.GetExecutionContext());
1402         } else if (info[NUM_SECOND]->IsNumber()) {
1403             auto transitionNumber = info[NUM_SECOND]->ToNumber<int32_t>();
1404             if (transitionNumber >= TRANSITION_NUM_ZERO && transitionNumber <= TRANSITION_NUM_TWO) {
1405                 modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
1406             }
1407         }
1408     }
1409     ViewAbstractModel::GetInstance()->BindContentCover(isShow, std::move(callback), std::move(buildFunc), modalStyle,
1410         std::move(onShowCallback), std::move(onDismissCallback), std::move(onWillShowCallback),
1411         std::move(onWillDismissCallback), contentCoverParam);
1412 }
1413 
ParseModalTransitonEffect(const JSRef<JSObject> & paramObj,NG::ContentCoverParam & contentCoverParam,const JSExecutionContext & context)1414 void JSViewAbstract::ParseModalTransitonEffect(
1415     const JSRef<JSObject>& paramObj, NG::ContentCoverParam& contentCoverParam, const JSExecutionContext& context)
1416 {
1417     auto transitionEffectValue = paramObj->GetProperty("transition");
1418     if (transitionEffectValue->IsObject()) {
1419         JSRef<JSObject> obj = JSRef<JSObject>::Cast(transitionEffectValue);
1420         contentCoverParam.transitionEffect = ParseChainedTransition(obj, context);
1421     }
1422 }
1423 
ParseModalStyle(const JSRef<JSObject> & paramObj,NG::ModalStyle & modalStyle)1424 void JSViewAbstract::ParseModalStyle(const JSRef<JSObject>& paramObj, NG::ModalStyle& modalStyle)
1425 {
1426     auto modalTransition = paramObj->GetProperty("modalTransition");
1427     auto backgroundColor = paramObj->GetProperty("backgroundColor");
1428     if (modalTransition->IsNumber()) {
1429         auto transitionNumber = modalTransition->ToNumber<int32_t>();
1430         if (transitionNumber >= TRANSITION_NUM_ZERO && transitionNumber <= TRANSITION_NUM_TWO) {
1431             modalStyle.modalTransition = static_cast<NG::ModalTransition>(transitionNumber);
1432         }
1433     }
1434     Color color;
1435     if (ParseJsColor(backgroundColor, color)) {
1436         modalStyle.backgroundColor = color;
1437     }
1438 }
1439 
ParseSheetIsShow(const JSCallbackInfo & info,const std::string & name,std::function<void (const std::string &)> & callback)1440 bool JSViewAbstract::ParseSheetIsShow(const JSCallbackInfo& info, const std::string& name,
1441     std::function<void(const std::string&)>& callback)
1442 {
1443     bool isShow = false;
1444     if (info[0]->IsBoolean()) {
1445         isShow = info[0]->ToBoolean();
1446     } else if (info[0]->IsObject()) {
1447         JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
1448         auto isShowObj = callbackObj->GetProperty("value");
1449         isShow = isShowObj->IsBoolean() ? isShowObj->ToBoolean() : false;
1450         callback = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "changeEvent");
1451         if (!callback && Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
1452             TAG_LOGD(AceLogTag::ACE_SHEET, "Try %{public}s another parsing", name.c_str());
1453             callback = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
1454         }
1455     }
1456     TAG_LOGD(AceLogTag::ACE_SHEET, "%{public}s get isShow is: %{public}d", name.c_str(), isShow);
1457     return isShow;
1458 }
1459 
JsBindSheet(const JSCallbackInfo & info)1460 void JSViewAbstract::JsBindSheet(const JSCallbackInfo& info)
1461 {
1462     // parse isShow and builder
1463     DoubleBindCallback callback = nullptr;
1464     bool isShow = ParseSheetIsShow(info, "Sheet", callback);
1465     if (!info[NUM_FIRST]->IsObject())
1466         return;
1467     JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[NUM_FIRST]);
1468     auto builder = obj->GetProperty("builder");
1469     if (!builder->IsFunction())
1470         return;
1471     auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
1472     CHECK_NULL_VOID(builderFunc);
1473     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1474     auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
1475         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1476         ACE_SCORING_EVENT("BindSheet");
1477         PipelineContext::SetCallBackNode(node);
1478         func->Execute();
1479     };
1480     // parse SheetStyle and callbacks
1481     NG::SheetStyle sheetStyle;
1482     sheetStyle.sheetHeight.sheetMode = NG::SheetMode::LARGE;
1483     sheetStyle.showDragBar = true;
1484     sheetStyle.showCloseIcon = true;
1485     sheetStyle.showInPage = false;
1486     std::function<void()> onAppearCallback;
1487     std::function<void()> onDisappearCallback;
1488     std::function<void()> onWillAppearCallback;
1489     std::function<void()> onWillDisappearCallback  ;
1490     std::function<void()> shouldDismissFunc;
1491     std::function<void(const int32_t)> onWillDismissCallback;
1492     std::function<void(const float)> onHeightDidChangeCallback;
1493     std::function<void(const float)> onDetentsDidChangeCallback;
1494     std::function<void(const float)> onWidthDidChangeCallback;
1495     std::function<void(const float)> onTypeDidChangeCallback;
1496     std::function<void()> titleBuilderFunction;
1497     std::function<void()> sheetSpringBackFunc;
1498     if (info.Length() == PARAMETER_LENGTH_THIRD && info[NUM_SECOND]->IsObject()) {
1499         ParseSheetCallback(info[NUM_SECOND], onAppearCallback, onDisappearCallback, shouldDismissFunc,
1500             onWillDismissCallback, onWillAppearCallback, onWillDisappearCallback, onHeightDidChangeCallback,
1501             onDetentsDidChangeCallback, onWidthDidChangeCallback, onTypeDidChangeCallback, sheetSpringBackFunc);
1502         ParseSheetStyle(info[NUM_SECOND], sheetStyle);
1503         ParseSheetTitle(info[NUM_SECOND], sheetStyle, titleBuilderFunction);
1504     }
1505     ViewAbstractModel::GetInstance()->BindSheet(isShow, std::move(callback), std::move(buildFunc),
1506         std::move(titleBuilderFunction), sheetStyle, std::move(onAppearCallback), std::move(onDisappearCallback),
1507         std::move(shouldDismissFunc), std::move(onWillDismissCallback),  std::move(onWillAppearCallback),
1508         std::move(onWillDisappearCallback), std::move(onHeightDidChangeCallback), std::move(onDetentsDidChangeCallback),
1509         std::move(onWidthDidChangeCallback), std::move(onTypeDidChangeCallback), std::move(sheetSpringBackFunc));
1510 }
1511 
ParseSheetEffectEdge(const JSRef<JSObject> & paramObj)1512 NG::SheetEffectEdge JSViewAbstract::ParseSheetEffectEdge(const JSRef<JSObject>& paramObj)
1513 {
1514     auto sheetEffectEdge = static_cast<int32_t>(NG::SheetEffectEdge::ALL);
1515     JSRef<JSVal> effectEdgedParam = paramObj->GetProperty("effectEdge");
1516     if (effectEdgedParam->IsNull() || effectEdgedParam->IsUndefined() ||
1517         !JSViewAbstract::ParseJsInt32(effectEdgedParam, sheetEffectEdge) ||
1518         sheetEffectEdge < static_cast<int32_t>(NG::SheetEffectEdge::NONE) ||
1519         sheetEffectEdge > static_cast<int32_t>(NG::SheetEffectEdge::END)) {
1520         sheetEffectEdge = static_cast<int32_t>(NG::SheetEffectEdge::ALL);
1521     }
1522     return static_cast<NG::SheetEffectEdge>(sheetEffectEdge);
1523 }
1524 
ParseSheetStyle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,bool isPartialUpdate)1525 void JSViewAbstract::ParseSheetStyle(
1526     const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, bool isPartialUpdate)
1527 {
1528     auto height = paramObj->GetProperty("height");
1529     auto showDragBar = paramObj->GetProperty("dragBar");
1530     auto backgroundColor = paramObj->GetProperty("backgroundColor");
1531     auto maskColor = paramObj->GetProperty("maskColor");
1532     auto sheetDetents = paramObj->GetProperty("detents");
1533     auto backgroundBlurStyle = paramObj->GetProperty("blurStyle");
1534     auto showCloseIcon = paramObj->GetProperty("showClose");
1535     auto type = paramObj->GetProperty("preferType");
1536     auto interactive = paramObj->GetProperty("enableOutsideInteractive");
1537     auto showMode = paramObj->GetProperty("mode");
1538     auto offsetVal = paramObj->GetProperty("offset");
1539     auto scrollSizeMode = paramObj->GetProperty("scrollSizeMode");
1540     auto keyboardAvoidMode = paramObj->GetProperty("keyboardAvoidMode");
1541     auto uiContextObj = paramObj->GetProperty("uiContext");
1542     if (uiContextObj->IsObject()) {
1543         JSRef<JSObject> obj = JSRef<JSObject>::Cast(uiContextObj);
1544         auto prop = obj->GetProperty("instanceId_");
1545         if (prop->IsNumber()) {
1546             sheetStyle.instanceId = prop->ToNumber<int32_t>();
1547         }
1548     }
1549 
1550     if (offsetVal->IsObject()) {
1551         auto offsetObj = JSRef<JSObject>::Cast(offsetVal);
1552         auto xVal = offsetObj->GetProperty("x");
1553         auto yVal = offsetObj->GetProperty("y");
1554         NG::OffsetF bottomOffset;
1555         CalcDimension dx;
1556         CalcDimension dy;
1557         if (JSViewAbstract::ParseJsDimensionVp(xVal, dx)) {
1558             bottomOffset.SetX(dx.ConvertToPx());
1559         }
1560         if (JSViewAbstract::ParseJsDimensionVp(yVal, dy) && dy.IsNegative()) {
1561             bottomOffset.SetY(dy.ConvertToPx());
1562         }
1563         sheetStyle.bottomOffset = bottomOffset;
1564     }
1565 
1566     NG::SheetLevel sheetLevel = NG::SheetLevel::OVERLAY;
1567     if (ParseSheetLevel(showMode, sheetLevel) || !isPartialUpdate) {
1568         sheetStyle.showInPage = (sheetLevel == NG::SheetLevel::EMBEDDED);
1569     }
1570 
1571     std::vector<NG::SheetHeight> detents;
1572     if (ParseSheetDetents(sheetDetents, detents)) {
1573         sheetStyle.detents = detents;
1574     }
1575     BlurStyleOption styleOption;
1576     if (ParseSheetBackgroundBlurStyle(backgroundBlurStyle, styleOption)) {
1577         sheetStyle.backgroundBlurStyle = styleOption;
1578     }
1579     bool showClose = true;
1580     if (ParseJsBool(showCloseIcon, showClose)) {
1581         sheetStyle.showCloseIcon = showClose;
1582     } else if (!isPartialUpdate) {
1583         sheetStyle.showCloseIcon = true;
1584     }
1585 
1586     bool isInteractive = false;
1587     if (ParseJsBool(interactive, isInteractive)) {
1588         sheetStyle.interactive = isInteractive;
1589     }
1590 
1591     if (showDragBar->IsBoolean()) {
1592         sheetStyle.showDragBar = showDragBar->ToBoolean();
1593     } else if (isPartialUpdate) {
1594         sheetStyle.showDragBar.reset();
1595     } else {
1596         sheetStyle.showDragBar = true;
1597     }
1598 
1599     if (type->IsNull() || type->IsUndefined()) {
1600         sheetStyle.sheetType.reset();
1601     } else {
1602         if (type->IsNumber()) {
1603             auto sheetType = type->ToNumber<int32_t>();
1604             if (sheetType >= static_cast<int>(NG::SheetType::SHEET_BOTTOM) &&
1605                 sheetType <= static_cast<int>(NG::SheetType::SHEET_POPUP)) {
1606                 sheetStyle.sheetType = static_cast<NG::SheetType>(sheetType);
1607             }
1608         }
1609     }
1610     if (scrollSizeMode->IsNull() || scrollSizeMode->IsUndefined()) {
1611         sheetStyle.scrollSizeMode.reset();
1612     } else if (scrollSizeMode->IsNumber()) {
1613         auto sheetScrollSizeMode = scrollSizeMode->ToNumber<int32_t>();
1614         if (sheetScrollSizeMode >= static_cast<int>(NG::ScrollSizeMode::FOLLOW_DETENT) &&
1615             sheetScrollSizeMode <= static_cast<int>(NG::ScrollSizeMode::CONTINUOUS)) {
1616             sheetStyle.scrollSizeMode = static_cast<NG::ScrollSizeMode>(sheetScrollSizeMode);
1617         }
1618     }
1619 
1620     if (keyboardAvoidMode->IsNull() || keyboardAvoidMode->IsUndefined()) {
1621         sheetStyle.sheetKeyboardAvoidMode.reset();
1622     } else if (keyboardAvoidMode->IsNumber()) {
1623         auto sheetKeyboardAvoidMode = keyboardAvoidMode->ToNumber<int32_t>();
1624         if (sheetKeyboardAvoidMode >= static_cast<int>(NG::SheetKeyboardAvoidMode::NONE) &&
1625             sheetKeyboardAvoidMode <= static_cast<int>(NG::SheetKeyboardAvoidMode::TRANSLATE_AND_SCROLL)) {
1626             sheetStyle.sheetKeyboardAvoidMode = static_cast<NG::SheetKeyboardAvoidMode>(sheetKeyboardAvoidMode);
1627         }
1628     }
1629 
1630     auto placement = paramObj->GetProperty("placement");
1631     sheetStyle.placement.reset();
1632     if (placement->IsNumber()) {
1633         auto placementValue = placement->ToNumber<int32_t>();
1634         if (placementValue >= static_cast<int>(Placement::LEFT) &&
1635             placementValue <= static_cast<int>(Placement::RIGHT_BOTTOM)) {
1636             sheetStyle.placement = static_cast<Placement>(placementValue);
1637         }
1638     }
1639 
1640     auto placementOnTarget = paramObj->GetProperty("placementOnTarget");
1641     sheetStyle.placementOnTarget.reset();
1642     if (placementOnTarget->IsBoolean()) {
1643         sheetStyle.placementOnTarget = placementOnTarget->ToBoolean();
1644     }
1645 
1646     Color color;
1647     if (ParseJsColor(backgroundColor, color)) {
1648         sheetStyle.backgroundColor = color;
1649     }
1650     // parse maskColor
1651     Color parseMaskColor;
1652     if (!maskColor->IsNull() && !maskColor->IsUndefined() && JSViewAbstract::ParseJsColor(maskColor, parseMaskColor)) {
1653         sheetStyle.maskColor = std::move(parseMaskColor);
1654     }
1655 
1656     // Parse border width
1657     auto borderWidthValue = paramObj->GetProperty("borderWidth");
1658     NG::BorderWidthProperty borderWidth;
1659     if (ParseBorderWidthProps(borderWidthValue, borderWidth)) {
1660         sheetStyle.borderWidth = borderWidth;
1661         // Parse border color
1662         auto colorValue = paramObj->GetProperty("borderColor");
1663         NG::BorderColorProperty borderColor;
1664         if (ParseBorderColorProps(colorValue, borderColor)) {
1665             sheetStyle.borderColor = borderColor;
1666         } else {
1667             sheetStyle.borderColor =
1668                 NG::BorderColorProperty({ Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK });
1669         }
1670         // Parse border style
1671         auto styleValue = paramObj->GetProperty("borderStyle");
1672         NG::BorderStyleProperty borderStyle;
1673         if (ParseBorderStyleProps(styleValue, borderStyle)) {
1674             sheetStyle.borderStyle = borderStyle;
1675         } else {
1676             sheetStyle.borderStyle = NG::BorderStyleProperty(
1677                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
1678         }
1679     }
1680     if (isPartialUpdate) {
1681         auto colorValue = paramObj->GetProperty("borderColor");
1682         NG::BorderColorProperty borderColor;
1683         if (ParseBorderColorProps(colorValue, borderColor)) {
1684             sheetStyle.borderColor = borderColor;
1685         } else {
1686             sheetStyle.borderColor.reset();
1687         }
1688         auto styleValue = paramObj->GetProperty("borderStyle");
1689         NG::BorderStyleProperty borderStyle;
1690         if (ParseBorderStyleProps(styleValue, borderStyle)) {
1691             sheetStyle.borderStyle = borderStyle;
1692         } else {
1693             sheetStyle.borderStyle.reset();
1694         }
1695     }
1696 
1697     // Parse shadow
1698     Shadow shadow;
1699     auto shadowValue = paramObj->GetProperty("shadow");
1700     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && ParseShadowProps(shadowValue, shadow)) {
1701         sheetStyle.shadow = shadow;
1702     }
1703 
1704     //parse effectEdge
1705     sheetStyle.sheetEffectEdge = ParseSheetEffectEdge(paramObj);
1706 
1707     // Parse hoverMode
1708     auto enableHoverModeValue = paramObj->GetProperty("enableHoverMode");
1709     if (enableHoverModeValue->IsBoolean()) {
1710         sheetStyle.enableHoverMode = enableHoverModeValue->ToBoolean();
1711     }
1712     auto hoverModeAreaValue = paramObj->GetProperty("hoverModeArea");
1713     if (hoverModeAreaValue->IsNumber()) {
1714         auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
1715         if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
1716             sheetStyle.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
1717         }
1718     }
1719 
1720     auto widthValue = paramObj->GetProperty("width");
1721     CalcDimension width;
1722     if (ParseJsDimensionVpNG(widthValue, width, true)) {
1723         sheetStyle.width = width;
1724     }
1725 
1726     auto radiusValue = paramObj->GetProperty("radius");
1727     JSViewAbstract::ParseBindSheetBorderRadius(radiusValue, sheetStyle);
1728 
1729     ParseDetentSelection(paramObj, sheetStyle);
1730 
1731     NG::SheetHeight sheetStruct;
1732     bool parseResult = ParseSheetHeight(height, sheetStruct, isPartialUpdate);
1733     if (!parseResult) {
1734         TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet height in unnormal condition");
1735     }
1736     sheetStyle.sheetHeight = sheetStruct;
1737 
1738     ParseSheetSubWindowValue(paramObj, sheetStyle);
1739 }
1740 
ParseSheetSubWindowValue(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)1741 void JSViewAbstract::ParseSheetSubWindowValue(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
1742 {
1743     // parse sheet showInSubWindow
1744     sheetStyle.showInSubWindow = false;
1745     if (sheetStyle.showInPage == NG::SheetLevel::EMBEDDED) {
1746         return;
1747     }
1748     auto showInSubWindowValue = paramObj->GetProperty("showInSubWindow");
1749     if (showInSubWindowValue->IsBoolean()) {
1750 #if defined(PREVIEW)
1751         LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Perform this operation on the "
1752                 "emulator or a real device instead.");
1753 #else
1754         sheetStyle.showInSubWindow = showInSubWindowValue->ToBoolean();
1755 #endif
1756     }
1757 }
1758 
ParseDetentSelection(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle)1759 void JSViewAbstract::ParseDetentSelection(const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle)
1760 {
1761     auto detentSelection = paramObj->GetProperty("detentSelection");
1762     NG::SheetHeight sheetStruct;
1763     bool parseResult = ParseSheetHeight(detentSelection, sheetStruct, true);
1764     if (!parseResult) {
1765         sheetStruct.height.reset();
1766         sheetStruct.sheetMode.reset();
1767         TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent selection in unnormal condition");
1768     }
1769     sheetStyle.detentSelection = sheetStruct;
1770 }
1771 
ParseSheetDetents(const JSRef<JSVal> & args,std::vector<NG::SheetHeight> & sheetDetents)1772 bool JSViewAbstract::ParseSheetDetents(const JSRef<JSVal>& args, std::vector<NG::SheetHeight>& sheetDetents)
1773 {
1774     if (!args->IsArray()) {
1775         return false;
1776     }
1777     JSRef<JSArray> array = JSRef<JSArray>::Cast(args);
1778     NG::SheetHeight sheetDetent;
1779     for (size_t i = 0; i < array->Length(); i++) {
1780         bool parseResult = ParseSheetHeight(array->GetValueAt(i), sheetDetent, false);
1781         if (!parseResult) {
1782             TAG_LOGD(AceLogTag::ACE_SHEET, "parse sheet detent in unnormal condition");
1783         }
1784         if ((!sheetDetent.height.has_value()) && (!sheetDetent.sheetMode.has_value())) {
1785             continue;
1786         }
1787         sheetDetents.emplace_back(sheetDetent);
1788         sheetDetent.height.reset();
1789         sheetDetent.sheetMode.reset();
1790     }
1791     return true;
1792 }
1793 
ParseSheetBackgroundBlurStyle(const JSRef<JSVal> & args,BlurStyleOption & blurStyleOptions)1794 bool JSViewAbstract::ParseSheetBackgroundBlurStyle(const JSRef<JSVal>& args, BlurStyleOption& blurStyleOptions)
1795 {
1796     if (args->IsNumber()) {
1797         auto sheetBlurStyle = args->ToNumber<int32_t>();
1798         if (sheetBlurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1799             sheetBlurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1800             blurStyleOptions.blurStyle = static_cast<BlurStyle>(sheetBlurStyle);
1801         } else {
1802             return false;
1803         }
1804     } else {
1805         return false;
1806     }
1807     return true;
1808 }
1809 
ParseSheetLevel(const JSRef<JSVal> & args,NG::SheetLevel & sheetLevel)1810 bool JSViewAbstract::ParseSheetLevel(const JSRef<JSVal>& args, NG::SheetLevel& sheetLevel)
1811 {
1812     if (!args->IsNumber()) {
1813         return false;
1814     }
1815     auto sheetMode = args->ToNumber<int32_t>();
1816     if (sheetMode >= static_cast<int>(NG::SheetLevel::OVERLAY) &&
1817         sheetMode <= static_cast<int>(NG::SheetLevel::EMBEDDED)) {
1818         sheetLevel = static_cast<NG::SheetLevel>(sheetMode);
1819         return true;
1820     }
1821     return false;
1822 }
1823 
ParseCallback(const JSRef<JSObject> & paramObj,std::function<void (const float)> & callbackDidChange,const char * prop)1824 void JSViewAbstract::ParseCallback(const JSRef<JSObject>& paramObj,
1825     std::function<void(const float)>& callbackDidChange, const char* prop)
1826 {
1827     auto callBack = paramObj->GetProperty(prop);
1828     if (callBack->IsFunction()) {
1829         RefPtr<JsFunction> jsFunc =
1830             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callBack));
1831         callbackDidChange = [func = std::move(jsFunc)](int32_t value) {
1832             JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(value));
1833             func->ExecuteJS(1, &param);
1834         };
1835     }
1836 }
1837 
ParseLifeCycleCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & lifeCycleCallBack,const char * prop)1838 void JSViewAbstract::ParseLifeCycleCallback(const JSRef<JSObject>& paramObj,
1839     std::function<void()>& lifeCycleCallBack, const char* prop)
1840 {
1841     auto callback = paramObj->GetProperty(prop);
1842     if (callback->IsFunction()) {
1843         RefPtr<JsFunction> jsFunc =
1844             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(callback));
1845         lifeCycleCallBack = [func = std::move(jsFunc)]() { func->Execute(); };
1846     }
1847 }
1848 
ParseSpringBackCallback(const JSRef<JSObject> & paramObj,std::function<void ()> & sheetSpringBack,const char * prop)1849 void JSViewAbstract::ParseSpringBackCallback(const JSRef<JSObject>& paramObj,
1850     std::function<void()>& sheetSpringBack, const char* prop)
1851 {
1852     auto sheetSpringBackCallback = paramObj->GetProperty(prop);
1853     if (sheetSpringBackCallback->IsFunction()) {
1854         RefPtr<JsFunction> jsFunc =
1855             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(sheetSpringBackCallback));
1856         sheetSpringBack = [func = std::move(jsFunc)]() {
1857             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1858             objectTemplate->SetInternalFieldCount(1);
1859             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1860             dismissObj->SetPropertyObject(
1861                 "springBack", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsSheetSpringBack));
1862             JSRef<JSVal> newJSVal = dismissObj;
1863             func->ExecuteJS(1, &newJSVal);
1864         };
1865     }
1866 }
1867 
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)1868 void JSViewAbstract::ParseSheetCallback(const JSRef<JSObject>& paramObj, std::function<void()>& onAppear,
1869     std::function<void()>& onDisappear, std::function<void()>& shouldDismiss,
1870     std::function<void(const int32_t info)>& onWillDismiss, std::function<void()>& onWillAppear,
1871     std::function<void()>& onWillDisappear, std::function<void(const float)>& onHeightDidChange,
1872     std::function<void(const float)>& onDetentsDidChange,
1873     std::function<void(const float)>& onWidthDidChange,
1874     std::function<void(const float)>& onTypeDidChange, std::function<void()>& sheetSpringBack)
1875 {
1876     auto shouldDismissFunc = paramObj->GetProperty("shouldDismiss");
1877     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
1878     ParseLifeCycleCallback(paramObj, onAppear, "onAppear");
1879     ParseLifeCycleCallback(paramObj, onDisappear, "onDisappear");
1880     ParseLifeCycleCallback(paramObj, onWillAppear, "onWillAppear");
1881     ParseLifeCycleCallback(paramObj, onWillDisappear, "onWillDisappear");
1882     if (shouldDismissFunc->IsFunction()) {
1883         RefPtr<JsFunction> jsFunc =
1884             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(shouldDismissFunc));
1885         shouldDismiss = [func = std::move(jsFunc)]() {
1886             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1887             objectTemplate->SetInternalFieldCount(1);
1888             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1889             dismissObj->SetPropertyObject(
1890                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
1891             JSRef<JSVal> newJSVal = dismissObj;
1892             func->ExecuteJS(1, &newJSVal);
1893         };
1894     }
1895     if (onWillDismissFunc->IsFunction()) {
1896         RefPtr<JsFunction> jsFunc =
1897             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
1898         onWillDismiss = [func = std::move(jsFunc)](const int32_t info) {
1899             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1900             objectTemplate->SetInternalFieldCount(1);
1901             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
1902             dismissObj->SetPropertyObject(
1903                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissSheet));
1904             dismissObj->SetProperty<int32_t>("reason", info);
1905             JSRef<JSVal> newJSVal = dismissObj;
1906             func->ExecuteJS(1, &newJSVal);
1907         };
1908     }
1909     ParseSpringBackCallback(paramObj, sheetSpringBack, "onWillSpringBackWhenDismiss");
1910     ParseCallback(paramObj, onHeightDidChange, "onHeightDidChange");
1911     ParseCallback(paramObj, onDetentsDidChange, "onDetentsDidChange");
1912     ParseCallback(paramObj, onWidthDidChange, "onWidthDidChange");
1913     ParseCallback(paramObj, onTypeDidChange, "onTypeDidChange");
1914 }
1915 
ParseSheetTitle(const JSRef<JSObject> & paramObj,NG::SheetStyle & sheetStyle,std::function<void ()> & titleBuilderFunction)1916 void JSViewAbstract::ParseSheetTitle(
1917     const JSRef<JSObject>& paramObj, NG::SheetStyle& sheetStyle, std::function<void()>& titleBuilderFunction)
1918 {
1919     auto title = paramObj->GetProperty("title");
1920     std::string mainTitle;
1921     std::string subtitle;
1922     if (title->IsFunction()) {
1923         sheetStyle.isTitleBuilder = true;
1924         auto titleBuilderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(title));
1925         CHECK_NULL_VOID(titleBuilderFunc);
1926         titleBuilderFunction = [func = std::move(titleBuilderFunc)]() {
1927             ACE_SCORING_EVENT("BindSheet");
1928             func->Execute();
1929         };
1930     } else if (title->IsObject()) {
1931         JSRef<JSObject> obj = JSRef<JSObject>::Cast(title);
1932         sheetStyle.isTitleBuilder = false;
1933         auto sheetTitle = obj->GetProperty("title");
1934         auto sheetSubtitle = obj->GetProperty("subtitle");
1935         if (ParseJsString(sheetTitle, mainTitle)) {
1936             sheetStyle.sheetTitle = mainTitle;
1937         }
1938         if (ParseJsString(sheetSubtitle, subtitle)) {
1939             sheetStyle.sheetSubtitle = subtitle;
1940         }
1941     }
1942 }
1943 
JsDismissSheet(panda::JsiRuntimeCallInfo * runtimeCallInfo)1944 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissSheet(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1945 {
1946     ViewAbstractModel::GetInstance()->DismissSheet();
1947     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1948 }
1949 
JsDismissContentCover(panda::JsiRuntimeCallInfo * runtimeCallInfo)1950 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissContentCover(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1951 {
1952     ViewAbstractModel::GetInstance()->DismissContentCover();
1953     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1954 }
1955 
JsSheetSpringBack(panda::JsiRuntimeCallInfo * runtimeCallInfo)1956 panda::Local<panda::JSValueRef> JSViewAbstract::JsSheetSpringBack(panda::JsiRuntimeCallInfo* runtimeCallInfo)
1957 {
1958     ViewAbstractModel::GetInstance()->SheetSpringBack();
1959     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
1960 }
1961 
ParseSheetMode(const std::string heightStr,NG::SheetHeight & detent)1962 bool JSViewAbstract::ParseSheetMode(const std::string heightStr, NG::SheetHeight& detent)
1963 {
1964     if (heightStr == SHEET_HEIGHT_MEDIUM) {
1965         detent.sheetMode = NG::SheetMode::MEDIUM;
1966         return true;
1967     }
1968 
1969     if (heightStr == SHEET_HEIGHT_LARGE) {
1970         detent.sheetMode = NG::SheetMode::LARGE;
1971         return true;
1972     }
1973     if (heightStr == SHEET_HEIGHT_FITCONTENT) {
1974         detent.sheetMode = NG::SheetMode::AUTO;
1975         return true;
1976     }
1977     return false;
1978 }
1979 
ParseSheetHeight(const JSRef<JSVal> & args,NG::SheetHeight & detent,bool isReset)1980 bool JSViewAbstract::ParseSheetHeight(const JSRef<JSVal>& args, NG::SheetHeight& detent,
1981     bool isReset)
1982 {
1983     detent.height.reset();
1984     detent.sheetMode.reset();
1985     CalcDimension sheetHeight;
1986     if (args->IsString()) {
1987         std::string heightStr = args->ToString();
1988 
1989         // Remove all " ".
1990         heightStr.erase(std::remove(heightStr.begin(), heightStr.end(), ' '), heightStr.end());
1991         std::transform(heightStr.begin(), heightStr.end(), heightStr.begin(), ::tolower);
1992         if (ParseSheetMode(heightStr, detent)) {
1993             return true;
1994         }
1995         if (heightStr.find("calc") != std::string::npos) {
1996             sheetHeight = CalcDimension(heightStr, DimensionUnit::CALC);
1997         } else {
1998             sheetHeight = StringUtils::StringToDimensionWithUnit(heightStr, DimensionUnit::VP, -1.0);
1999         }
2000         if (sheetHeight.Value() < 0) {
2001             detent.sheetMode = NG::SheetMode::LARGE;
2002             return false;
2003         }
2004     }
2005     if (!ParseJsDimensionVpNG(args, sheetHeight)) {
2006         if (!isReset) {
2007             detent.sheetMode = NG::SheetMode::LARGE;
2008         }
2009         return false;
2010     }
2011     detent.height = sheetHeight;
2012     return true;
2013 }
2014 
JsBindMenu(const JSCallbackInfo & info)2015 void JSViewAbstract::JsBindMenu(const JSCallbackInfo& info)
2016 {
2017     NG::MenuParam menuParam;
2018     MenuDefaultParam(menuParam);
2019     size_t builderIndex = 0;
2020     JSViewPopups::GetMenuShowInSubwindow(menuParam);
2021     if (info.Length() > PARAMETER_LENGTH_FIRST) {
2022         auto jsVal = info[0];
2023         if (jsVal->IsBoolean()) {
2024             menuParam.isShow = jsVal->ToBoolean();
2025             menuParam.setShow = true;
2026             builderIndex = 1;
2027             if (info.Length() > PARAMETER_LENGTH_SECOND) {
2028                 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2029             }
2030         } else if (jsVal->IsUndefined()) {
2031             menuParam.setShow = true;
2032             menuParam.isShow = false;
2033             builderIndex = 1;
2034             if (info.Length() > PARAMETER_LENGTH_SECOND) {
2035                 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2036             }
2037         } else if (jsVal->IsObject()) {
2038             JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(jsVal);
2039             menuParam.onStateChange = JSViewPopups::ParseDoubleBindCallback(info, callbackObj, "$value");
2040             auto isShowObj = callbackObj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
2041             if (isShowObj->IsBoolean()) {
2042                 menuParam.isShow = isShowObj->ToBoolean();
2043                 menuParam.setShow = true;
2044                 builderIndex = 1;
2045                 if (info.Length() > PARAMETER_LENGTH_SECOND) {
2046                     JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2047                 }
2048             } else {
2049                 builderIndex = 0;
2050                 JSViewPopups::ParseBindOptionParam(info, menuParam, builderIndex + 1);
2051             }
2052         }
2053     }
2054 
2055     if (info[builderIndex]->IsArray()) {
2056         std::vector<NG::OptionParam> optionsParam = JSViewPopups::ParseBindOptionParam(info, builderIndex);
2057         ViewAbstractModel::GetInstance()->BindMenu(std::move(optionsParam), nullptr, menuParam);
2058     } else if (info[builderIndex]->IsObject()) {
2059         // CustomBuilder
2060         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[builderIndex]);
2061         auto builder = obj->GetProperty(static_cast<int32_t>(ArkUIIndex::BUILDER));
2062         if (!builder->IsFunction()) {
2063             return;
2064         }
2065         auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(builder));
2066 
2067         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2068         CHECK_NULL_VOID(builderFunc);
2069         auto buildFunc = [execCtx = info.GetExecutionContext(), func = std::move(builderFunc), node = frameNode]() {
2070             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2071             ACE_SCORING_EVENT("BuildMenu");
2072             auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2073             func->Execute();
2074         };
2075         ViewAbstractModel::GetInstance()->BindMenu({}, std::move(buildFunc), menuParam);
2076     }
2077 }
2078 
MenuDefaultParam(NG::MenuParam & menuParam)2079 void JSViewAbstract::MenuDefaultParam(NG::MenuParam& menuParam)
2080 {
2081     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
2082         menuParam.placement = Placement::BOTTOM_LEFT;
2083     }
2084 }
2085 
ParseContentMenuCommonParam(const JSCallbackInfo & info,const JSRef<JSObject> & menuObj,NG::MenuParam & menuParam)2086 void JSViewAbstract::ParseContentMenuCommonParam(
2087     const JSCallbackInfo& info, const JSRef<JSObject>& menuObj, NG::MenuParam& menuParam)
2088 {
2089     if (!menuParam.placement.has_value()) {
2090         MenuDefaultParam(menuParam);
2091     }
2092     CHECK_EQUAL_VOID(menuObj->IsEmpty(), true);
2093     JSViewPopups::ParseMenuParam(info, menuObj, menuParam);
2094     auto preview = menuObj->GetProperty("preview");
2095     if (preview->IsNumber()) {
2096         auto previewMode = preview->ToNumber<int32_t>();
2097         if (previewMode == static_cast<int32_t>(MenuPreviewMode::IMAGE)) {
2098             menuParam.previewMode = static_cast<MenuPreviewMode>(previewMode);
2099             ParseContentPreviewAnimationOptionsParam(info, menuObj, menuParam);
2100         }
2101     }
2102 }
2103 
OpenMenu(NG::MenuParam & menuParam,const RefPtr<NG::UINode> & customNode,const int32_t & targetId)2104 int32_t JSViewAbstract::OpenMenu(
2105     NG::MenuParam& menuParam, const RefPtr<NG::UINode>& customNode, const int32_t& targetId)
2106 {
2107     return ViewAbstractModel::GetInstance()->OpenMenu(menuParam, customNode, targetId);
2108 }
2109 
UpdateMenu(const NG::MenuParam & menuParam,const RefPtr<NG::UINode> & customNode)2110 int32_t JSViewAbstract::UpdateMenu(const NG::MenuParam& menuParam, const RefPtr<NG::UINode>& customNode)
2111 {
2112     return ViewAbstractModel::GetInstance()->UpdateMenu(menuParam, customNode);
2113 }
2114 
CloseMenu(const RefPtr<NG::UINode> & customNode)2115 int32_t JSViewAbstract::CloseMenu(const RefPtr<NG::UINode>& customNode)
2116 {
2117     return ViewAbstractModel::GetInstance()->CloseMenu(customNode);
2118 }
2119 
ParseDialogCallback(const JSRef<JSObject> & paramObj,std::function<void (const int32_t & info,const int32_t & instanceId)> & onWillDismiss)2120 void JSViewAbstract::ParseDialogCallback(const JSRef<JSObject>& paramObj,
2121     std::function<void(const int32_t& info, const int32_t& instanceId)>& onWillDismiss)
2122 {
2123     auto onWillDismissFunc = paramObj->GetProperty("onWillDismiss");
2124     if (onWillDismissFunc->IsFunction()) {
2125         auto jsFunc =
2126             AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDismissFunc));
2127         onWillDismiss = [func = std::move(jsFunc)](const int32_t& info, const int32_t& instanceId) {
2128             JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
2129             objectTemplate->SetInternalFieldCount(ON_WILL_DISMISS_FIELD_COUNT);
2130             JSRef<JSObject> dismissObj = objectTemplate->NewInstance();
2131             dismissObj->SetPropertyObject(
2132                 "dismiss", JSRef<JSFunc>::New<FunctionCallback>(JSViewAbstract::JsDismissDialog));
2133             dismissObj->SetProperty<int32_t>("reason", info);
2134             JSRef<JSVal> newJSVal = dismissObj;
2135             func->ExecuteJS(1, &newJSVal);
2136         };
2137     }
2138 }
2139 
JsDismissDialog(panda::JsiRuntimeCallInfo * runtimeCallInfo)2140 panda::Local<panda::JSValueRef> JSViewAbstract::JsDismissDialog(panda::JsiRuntimeCallInfo* runtimeCallInfo)
2141 {
2142     ViewAbstractModel::GetInstance()->DismissDialog();
2143     return JSValueRef::Undefined(runtimeCallInfo->GetVM());
2144 }
2145 
AppearDialogEvent(const JSCallbackInfo & info,DialogProperties & dialogProperties)2146 void AppearDialogEvent(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2147 {
2148     if (!info[0]->IsObject()) {
2149         return;
2150     }
2151     auto paramObject = JSRef<JSObject>::Cast(info[0]);
2152     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2153     auto onDidAppear = paramObject->GetProperty("onDidAppear");
2154     if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
2155         auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
2156         auto didAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2157             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2158             ACE_SCORING_EVENT("Popups.onDidAppear");
2159             PipelineContext::SetCallBackNode(node);
2160             func->Execute();
2161         };
2162         dialogProperties.onDidAppear = std::move(didAppearId);
2163     }
2164     auto onWillAppear = paramObject->GetProperty("onWillAppear");
2165     if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
2166         auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
2167         auto willAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2168             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2169             ACE_SCORING_EVENT("Popups.onWillAppear");
2170             PipelineContext::SetCallBackNode(node);
2171             func->Execute();
2172         };
2173         dialogProperties.onWillAppear = std::move(willAppearId);
2174     }
2175 }
2176 
DisappearDialogEvent(const JSCallbackInfo & info,DialogProperties & dialogProperties)2177 void DisappearDialogEvent(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2178 {
2179     if (!info[0]->IsObject()) {
2180         return;
2181     }
2182     auto paramObject = JSRef<JSObject>::Cast(info[0]);
2183     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
2184     auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
2185     if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
2186         auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
2187         auto didDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2188             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2189             ACE_SCORING_EVENT("Popups.onDidDisappear");
2190             PipelineContext::SetCallBackNode(node);
2191             func->Execute();
2192         };
2193         dialogProperties.onDidDisappear = std::move(didDisappearId);
2194     }
2195     auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
2196     if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
2197         auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
2198         auto willDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
2199             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
2200             ACE_SCORING_EVENT("Popups.onWillDisappear");
2201             PipelineContext::SetCallBackNode(node);
2202             func->Execute();
2203         };
2204         dialogProperties.onWillDisappear = std::move(willDisappearId);
2205     }
2206 }
2207 
ParseAppearDialogCallback(const JSCallbackInfo & info,DialogProperties & dialogProperties)2208 void JSViewAbstract::ParseAppearDialogCallback(const JSCallbackInfo& info, DialogProperties& dialogProperties)
2209 {
2210     if (!info[0]->IsObject()) {
2211         return ;
2212     }
2213     AppearDialogEvent(info, dialogProperties);
2214     DisappearDialogEvent(info, dialogProperties);
2215 }
2216 
SetDialogHoverModeProperties(const JSRef<JSObject> & obj,DialogProperties & properties)2217 void JSViewAbstract::SetDialogHoverModeProperties(const JSRef<JSObject>& obj, DialogProperties& properties)
2218 {
2219     auto enableHoverModeValue = obj->GetProperty("enableHoverMode");
2220     if (enableHoverModeValue->IsBoolean()) {
2221         properties.enableHoverMode = enableHoverModeValue->ToBoolean();
2222     }
2223 
2224     // Parse hoverModeArea
2225     auto hoverModeAreaValue = obj->GetProperty("hoverModeArea");
2226     if (hoverModeAreaValue->IsNumber()) {
2227         auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
2228         if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
2229             properties.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
2230         }
2231     }
2232 }
2233 
SetDialogBlurStyleOption(const JSRef<JSObject> & obj,DialogProperties & properties)2234 void JSViewAbstract::SetDialogBlurStyleOption(const JSRef<JSObject>& obj, DialogProperties& properties)
2235 {
2236     auto blurStyleValue = obj->GetProperty("backgroundBlurStyleOptions");
2237     if (blurStyleValue->IsObject()) {
2238         if (!properties.blurStyleOption.has_value()) {
2239             properties.blurStyleOption.emplace();
2240         }
2241         JSViewAbstract::ParseBlurStyleOption(blurStyleValue, properties.blurStyleOption.value());
2242     }
2243 }
2244 
SetDialogEffectOption(const JSRef<JSObject> & obj,DialogProperties & properties)2245 void JSViewAbstract::SetDialogEffectOption(const JSRef<JSObject>& obj, DialogProperties& properties)
2246 {
2247     auto effectOptionValue = obj->GetProperty("backgroundEffect");
2248     if (effectOptionValue->IsObject()) {
2249         if (!properties.effectOption.has_value()) {
2250             properties.effectOption.emplace();
2251         }
2252         JSViewAbstract::ParseEffectOption(effectOptionValue, properties.effectOption.value());
2253     }
2254 }
2255 }