• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "prompt_action.h"
17 #include "prompt_controller.h"
18 
19 #include "interfaces/napi/kits/utils/napi_utils.h"
20 #include "base/i18n/localization.h"
21 #include "base/subwindow/subwindow_manager.h"
22 #include "bridge/common/utils/engine_helper.h"
23 #include "core/common/ace_engine.h"
24 #include "core/components/theme/shadow_theme.h"
25 #include "core/components/toast/toast_theme.h"
26 #include "core/components_ng/pattern/overlay/level_order.h"
27 #include "core/pipeline/pipeline_base.h"
28 
29 namespace OHOS::Ace::Napi {
30 namespace {
31 const int32_t SHOW_DIALOG_BUTTON_NUM_MAX = -1;
32 const int32_t SHOW_ACTION_MENU_BUTTON_NUM_MAX = 6;
33 const int32_t CUSTOM_DIALOG_PARAM_NUM = 2;
34 const int32_t BG_BLUR_STYLE_MAX_INDEX = 13;
35 const int32_t PROMPTACTION_VALID_PRIMARY_BUTTON_NUM = 1;
36 const int32_t OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_TOTAL = 3;
37 const int32_t OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_MAND_COUNT = 2;
38 const int32_t OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_INDEX_CONTROLLER = 1;
39 const int32_t OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_INDEX_OPTIONS = 2;
40 const int32_t PRESENT_CUSTOM_DIALOG_PARAM_TOTAL = 3;
41 const int32_t PRESENT_CUSTOM_DIALOG_PARAM_MAND_COUNT = 1;
42 const int32_t PRESENT_CUSTOM_DIALOG_PARAM_INDEX_CONTROLLER = 1;
43 const int32_t PRESENT_CUSTOM_DIALOG_PARAM_INDEX_OPTIONS = 2;
44 constexpr char DEFAULT_FONT_COLOR_STRING_VALUE[] = "#ff007dff";
45 constexpr float DEFAULT_AVOID_DISTANCE = 16.0f;
46 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
47     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
48     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
49     DialogAlignment::BOTTOM_END };
50 const std::vector<KeyboardAvoidMode> KEYBOARD_AVOID_MODE = { KeyboardAvoidMode::DEFAULT, KeyboardAvoidMode::NONE };
51 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
52     HoverModeAreaType::BOTTOM_SCREEN };
53 const std::vector<LevelMode> DIALOG_LEVEL_MODE = { LevelMode::OVERLAY, LevelMode::EMBEDDED };
54 const std::vector<ImmersiveMode> DIALOG_IMMERSIVE_MODE = { ImmersiveMode::DEFAULT, ImmersiveMode::EXTEND};
55 
56 #ifdef OHOS_STANDARD_SYSTEM
ContainerIsService()57 bool ContainerIsService()
58 {
59     auto containerId = Container::CurrentIdSafely();
60     // Get active container when current instanceid is less than 0
61     if (containerId < 0) {
62         auto container = Container::GetActive();
63         if (container) {
64             containerId = container->GetInstanceId();
65         }
66     }
67     // for pa service
68     return containerId >= MIN_PA_SERVICE_ID || containerId < 0;
69 }
70 
ContainerIsScenceBoard()71 bool ContainerIsScenceBoard()
72 {
73     auto container = Container::CurrentSafely();
74     if (!container) {
75         container = Container::GetActive();
76     }
77 
78     return container && container->IsScenceBoardWindow();
79 }
80 #endif
81 } // namespace
82 
GetToastMessage(napi_env env,napi_value messageNApi,std::string & messageString)83 bool GetToastMessage(napi_env env, napi_value messageNApi, std::string& messageString)
84 {
85     size_t ret = 0;
86     ResourceInfo recv;
87     napi_valuetype valueType = napi_undefined;
88     napi_typeof(env, messageNApi, &valueType);
89     if (valueType == napi_string) {
90         size_t messageLen = GetParamLen(env, messageNApi) + 1;
91         std::unique_ptr<char[]> message = std::make_unique<char[]>(messageLen);
92         napi_get_value_string_utf8(env, messageNApi, message.get(), messageLen, &ret);
93         messageString = message.get();
94     } else if (valueType == napi_object) {
95         if (!ParseResourceParam(env, messageNApi, recv)) {
96             NapiThrow(env, "Can not parse resource info from input params.", ERROR_CODE_INTERNAL_ERROR);
97             return false;
98         }
99         if (!ParseString(recv, messageString)) {
100             NapiThrow(env, "Can not get message from resource manager.", ERROR_CODE_INTERNAL_ERROR);
101             return false;
102         }
103         if (messageString.size() == 0) {
104             TAG_LOGE(AceLogTag::ACE_DIALOG, "Toast message is empty");
105         }
106     } else {
107         NapiThrow(env, "The type of message is incorrect.", ERROR_CODE_PARAM_INVALID);
108         return false;
109     }
110     return true;
111 }
112 
GetToastDuration(napi_env env,napi_value durationNApi,int32_t & duration)113 bool GetToastDuration(napi_env env, napi_value durationNApi, int32_t& duration)
114 {
115     napi_valuetype valueType = napi_undefined;
116     napi_typeof(env, durationNApi, &valueType);
117     ResourceInfo recv;
118     std::string durationStr;
119     if (valueType == napi_number) {
120         napi_get_value_int32(env, durationNApi, &duration);
121     } else if (valueType == napi_object) {
122         recv = {};
123         if (!ParseResourceParam(env, durationNApi, recv)) {
124             NapiThrow(env, "Can not parse resource info from input params.", ERROR_CODE_INTERNAL_ERROR);
125             return false;
126         }
127         if (!ParseString(recv, durationStr)) {
128             NapiThrow(env, "Can not get message from resource manager.", ERROR_CODE_INTERNAL_ERROR);
129             return false;
130         }
131         duration = StringUtils::StringToInt(durationStr);
132     }
133     return true;
134 }
135 
GetToastBottom(napi_env env,napi_value bottomNApi,std::string & bottomString)136 bool GetToastBottom(napi_env env, napi_value bottomNApi, std::string& bottomString)
137 {
138     size_t ret = 0;
139     ResourceInfo recv;
140     napi_valuetype valueType = napi_undefined;
141     napi_typeof(env, bottomNApi, &valueType);
142     if (valueType == napi_string) {
143         size_t bottomLen = GetParamLen(env, bottomNApi) + 1;
144         std::unique_ptr<char[]> bottom = std::make_unique<char[]>(bottomLen);
145         napi_get_value_string_utf8(env, bottomNApi, bottom.get(), bottomLen, &ret);
146         bottomString = bottom.get();
147     } else if (valueType == napi_number) {
148         double bottom = 0.0;
149         napi_get_value_double(env, bottomNApi, &bottom);
150         bottomString = std::to_string(bottom);
151     } else if (valueType == napi_object) {
152         recv = {};
153         if (!ParseResourceParam(env, bottomNApi, recv)) {
154             NapiThrow(env, "Can not parse resource info from input params.", ERROR_CODE_INTERNAL_ERROR);
155             return false;
156         }
157         if (!ParseString(recv, bottomString)) {
158             NapiThrow(env, "Can not get message from resource manager.", ERROR_CODE_INTERNAL_ERROR);
159             return false;
160         }
161     }
162     return true;
163 }
164 
GetToastShowMode(napi_env env,napi_value showModeNApi,NG::ToastShowMode & showMode)165 bool GetToastShowMode(napi_env env, napi_value showModeNApi, NG::ToastShowMode& showMode)
166 {
167     napi_valuetype valueType = napi_undefined;
168     napi_typeof(env, showModeNApi, &valueType);
169     if (valueType == napi_number) {
170         int32_t num = -1;
171         napi_get_value_int32(env, showModeNApi, &num);
172         if (num >= 0 && num <= static_cast<int32_t>(NG::ToastShowMode::SYSTEM_TOP_MOST)) {
173             showMode = static_cast<NG::ToastShowMode>(num);
174         }
175     }
176     return true;
177 }
178 
GetToastAlignment(napi_env env,napi_value alignmentApi,int32_t & alignment)179 bool GetToastAlignment(napi_env env, napi_value alignmentApi, int32_t& alignment)
180 {
181     napi_valuetype valueType = napi_undefined;
182     napi_typeof(env, alignmentApi, &valueType);
183     if (valueType == napi_number) {
184         napi_get_value_int32(env, alignmentApi, &alignment);
185     }
186     return true;
187 }
188 
GetToastOffset(napi_env env,napi_value offsetApi,std::optional<DimensionOffset> & offset)189 bool GetToastOffset(napi_env env, napi_value offsetApi, std::optional<DimensionOffset>& offset)
190 {
191     napi_valuetype valueType = napi_undefined;
192     napi_typeof(env, offsetApi, &valueType);
193     if (valueType == napi_object) {
194         napi_value dxApi = nullptr;
195         napi_value dyApi = nullptr;
196         napi_get_named_property(env, offsetApi, "dx", &dxApi);
197         napi_get_named_property(env, offsetApi, "dy", &dyApi);
198         CalcDimension dx;
199         CalcDimension dy;
200         ParseNapiDimension(env, dx, dxApi, DimensionUnit::VP);
201         ParseNapiDimension(env, dy, dyApi, DimensionUnit::VP);
202         offset = DimensionOffset { dx, dy };
203     }
204     return true;
205 }
206 
GetToastBackgroundColor(napi_env env,napi_value backgroundColorNApi,std::optional<Color> & backgroundColor)207 void GetToastBackgroundColor(napi_env env, napi_value backgroundColorNApi, std::optional<Color>& backgroundColor)
208 {
209     napi_valuetype valueType = napi_undefined;
210     napi_typeof(env, backgroundColorNApi, &valueType);
211     Color color;
212     backgroundColor = std::nullopt;
213     if (ParseNapiColor(env, backgroundColorNApi, color)) {
214         backgroundColor = color;
215     }
216 }
217 
GetToastTextColor(napi_env env,napi_value textColorNApi,std::optional<Color> & textColor)218 void GetToastTextColor(napi_env env, napi_value textColorNApi, std::optional<Color>& textColor)
219 {
220     napi_valuetype valueType = napi_undefined;
221     napi_typeof(env, textColorNApi, &valueType);
222     Color color;
223     textColor = std::nullopt;
224     if (ParseNapiColor(env, textColorNApi, color)) {
225         textColor = color;
226     }
227 }
228 
GetToastBackgroundBlurStyle(napi_env env,napi_value backgroundBlurStyleNApi,std::optional<int32_t> & backgroundBlurStyle)229 void GetToastBackgroundBlurStyle(napi_env env,
230     napi_value backgroundBlurStyleNApi, std::optional<int32_t>& backgroundBlurStyle)
231 {
232     napi_valuetype valueType = napi_undefined;
233     napi_typeof(env, backgroundBlurStyleNApi, &valueType);
234     if (valueType == napi_number) {
235         int32_t num;
236         napi_get_value_int32(env, backgroundBlurStyleNApi, &num);
237         if (num >= 0 && num < BG_BLUR_STYLE_MAX_INDEX) {
238             backgroundBlurStyle = num;
239         }
240     }
241 }
242 
GetShadowFromTheme(ShadowStyle shadowStyle,Shadow & shadow)243 bool GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow)
244 {
245     if (shadowStyle == ShadowStyle::None) {
246         return true;
247     }
248     auto container = Container::CurrentSafelyWithCheck();
249     CHECK_NULL_RETURN(container, false);
250     auto colorMode = container->GetColorMode();
251     auto pipelineContext = container->GetPipelineContext();
252     CHECK_NULL_RETURN(pipelineContext, false);
253     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
254     if (!shadowTheme) {
255         return false;
256     }
257     shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
258     return true;
259 }
260 
ParseResource(const ResourceInfo resource,CalcDimension & result)261 bool ParseResource(const ResourceInfo resource, CalcDimension& result)
262 {
263     auto resourceWrapper = CreateResourceWrapper(resource);
264     CHECK_NULL_RETURN(resourceWrapper, false);
265     if (resource.type == static_cast<uint32_t>(ResourceType::STRING)) {
266         auto value = resourceWrapper->GetString(resource.resId);
267         return StringUtils::StringToCalcDimensionNG(value, result, false);
268     }
269     if (resource.type == static_cast<uint32_t>(ResourceType::INTEGER)) {
270         auto value = std::to_string(resourceWrapper->GetInt(resource.resId));
271         StringUtils::StringToDimensionWithUnitNG(value, result);
272         return true;
273     }
274     if (resource.type == static_cast<uint32_t>(ResourceType::FLOAT)) {
275         result = resourceWrapper->GetDimension(resource.resId);
276         return true;
277     }
278     return false;
279 }
280 
GetToastObjectShadow(napi_env env,napi_value shadowNApi,Shadow & shadowProps)281 void GetToastObjectShadow(napi_env env, napi_value shadowNApi, Shadow& shadowProps)
282 {
283     napi_value radiusApi = nullptr;
284     napi_value colorApi = nullptr;
285     napi_value typeApi = nullptr;
286     napi_value fillApi = nullptr;
287     napi_get_named_property(env, shadowNApi, "radius", &radiusApi);
288     napi_get_named_property(env, shadowNApi, "color", &colorApi);
289     napi_get_named_property(env, shadowNApi, "type", &typeApi);
290     napi_get_named_property(env, shadowNApi, "fill", &fillApi);
291     ResourceInfo recv;
292     double radiusValue = 0.0;
293     if (ParseResourceParam(env, radiusApi, recv)) {
294         CalcDimension radius;
295         if (ParseResource(recv, radius)) {
296             radiusValue = LessNotEqual(radius.Value(), 0.0) ? 0.0 : radius.Value();
297         }
298     } else {
299         napi_get_value_double(env, radiusApi, &radiusValue);
300         if (LessNotEqual(radiusValue, 0.0)) {
301             radiusValue = 0.0;
302         }
303     }
304     shadowProps.SetBlurRadius(radiusValue);
305     Color color;
306     ShadowColorStrategy shadowColorStrategy;
307     if (ParseShadowColorStrategy(env, colorApi, shadowColorStrategy)) {
308         shadowProps.SetShadowColorStrategy(shadowColorStrategy);
309     } else if (ParseNapiColor(env, colorApi, color)) {
310         shadowProps.SetColor(color);
311     }
312     napi_valuetype valueType = GetValueType(env, typeApi);
313     int32_t shadowType = static_cast<int32_t>(ShadowType::COLOR);
314     if (valueType == napi_number) {
315         napi_get_value_int32(env, typeApi, &shadowType);
316     }
317     if (shadowType != static_cast<int32_t>(ShadowType::BLUR)) {
318         shadowType = static_cast<int32_t>(ShadowType::COLOR);
319     }
320     shadowType =
321         std::clamp(shadowType, static_cast<int32_t>(ShadowType::COLOR), static_cast<int32_t>(ShadowType::BLUR));
322     shadowProps.SetShadowType(static_cast<ShadowType>(shadowType));
323     valueType = GetValueType(env, fillApi);
324     bool isFilled = false;
325     if (valueType == napi_boolean) {
326         napi_get_value_bool(env, fillApi, &isFilled);
327     }
328     shadowProps.SetIsFilled(isFilled);
329 }
330 
GetToastDefaultShadowStyle()331 ShadowStyle GetToastDefaultShadowStyle()
332 {
333     auto shadowStyle = ShadowStyle::OuterDefaultMD;
334     auto container = Container::Current();
335     CHECK_NULL_RETURN(container, shadowStyle);
336     auto pipelineContext = container->GetPipelineContext();
337     CHECK_NULL_RETURN(pipelineContext, shadowStyle);
338     auto toastTheme = pipelineContext->GetTheme<ToastTheme>();
339     CHECK_NULL_RETURN(toastTheme, shadowStyle);
340     return toastTheme->GetToastShadowStyle();
341 }
342 
GetToastShadow(napi_env env,napi_value shadowNApi,std::optional<Shadow> & shadow,bool & isTypeStyleShadow)343 void GetToastShadow(napi_env env, napi_value shadowNApi, std::optional<Shadow>& shadow, bool& isTypeStyleShadow)
344 {
345     Shadow shadowProps;
346     napi_valuetype valueType = napi_undefined;
347     napi_typeof(env, shadowNApi, &valueType);
348     if (valueType == napi_number) {
349         int32_t num = 0;
350         napi_get_value_int32(env, shadowNApi, &num);
351         auto style = static_cast<ShadowStyle>(num);
352         GetShadowFromTheme(style, shadowProps);
353     } else if (valueType == napi_object) {
354         napi_value offsetXApi = nullptr;
355         napi_value offsetYApi = nullptr;
356         napi_get_named_property(env, shadowNApi, "offsetX", &offsetXApi);
357         napi_get_named_property(env, shadowNApi, "offsetY", &offsetYApi);
358         ResourceInfo recv;
359         bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
360         if (ParseResourceParam(env, offsetXApi, recv)) {
361             CalcDimension offsetX;
362             if (ParseResource(recv, offsetX)) {
363                 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
364                 shadowProps.SetOffsetX(xValue);
365             }
366         } else {
367             CalcDimension offsetX;
368             if (ParseNapiDimension(env, offsetX, offsetXApi, DimensionUnit::VP)) {
369                 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
370                 shadowProps.SetOffsetX(xValue);
371             }
372         }
373         if (ParseResourceParam(env, offsetYApi, recv)) {
374             CalcDimension offsetY;
375             if (ParseResource(recv, offsetY)) {
376                 shadowProps.SetOffsetY(offsetY.Value());
377             }
378         } else {
379             CalcDimension offsetY;
380             if (ParseNapiDimension(env, offsetY, offsetYApi, DimensionUnit::VP)) {
381                 shadowProps.SetOffsetY(offsetY.Value());
382             }
383         }
384         GetToastObjectShadow(env, shadowNApi, shadowProps);
385         isTypeStyleShadow = false;
386     } else {
387         auto shadowStyle = GetToastDefaultShadowStyle();
388         GetShadowFromTheme(shadowStyle, shadowProps);
389     }
390     shadow = shadowProps;
391 }
392 
GetToastEnableHoverMode(napi_env env,napi_value enableHoverModeNApi,bool & enableHoverMode)393 void GetToastEnableHoverMode(napi_env env, napi_value enableHoverModeNApi, bool& enableHoverMode)
394 {
395     napi_valuetype valueType = napi_undefined;
396     napi_typeof(env, enableHoverModeNApi, &valueType);
397     if (valueType == napi_boolean) {
398         napi_get_value_bool(env, enableHoverModeNApi, &enableHoverMode);
399     }
400 }
401 
GetToastHoverModeArea(napi_env env,napi_value hoverModeAreaNApi,HoverModeAreaType & hoverModeArea)402 void GetToastHoverModeArea(napi_env env, napi_value hoverModeAreaNApi, HoverModeAreaType& hoverModeArea)
403 {
404     napi_valuetype valueType = napi_undefined;
405     napi_typeof(env, hoverModeAreaNApi, &valueType);
406     if (valueType == napi_number) {
407         int32_t num = -1;
408         napi_get_value_int32(env, hoverModeAreaNApi, &num);
409         if (num >= 0 && num <= static_cast<int32_t>(HoverModeAreaType::BOTTOM_SCREEN)) {
410             hoverModeArea = static_cast<HoverModeAreaType>(num);
411         }
412     }
413 }
414 
GetToastHoverModeParams(napi_env env,napi_value argv,NG::ToastInfo & toastInfo)415 void GetToastHoverModeParams(napi_env env, napi_value argv, NG::ToastInfo& toastInfo)
416 {
417     napi_value enableHoverModeNApi = nullptr;
418     napi_value hoverModeAreaNApi = nullptr;
419 
420     napi_get_named_property(env, argv, "enableHoverMode", &enableHoverModeNApi);
421     napi_get_named_property(env, argv, "hoverModeArea", &hoverModeAreaNApi);
422 
423     GetToastEnableHoverMode(env, enableHoverModeNApi, toastInfo.enableHoverMode);
424     GetToastHoverModeArea(env, hoverModeAreaNApi, toastInfo.hoverModeArea);
425 }
426 
GetToastParams(napi_env env,napi_value argv,NG::ToastInfo & toastInfo)427 bool GetToastParams(napi_env env, napi_value argv, NG::ToastInfo& toastInfo)
428 {
429     napi_value messageNApi = nullptr;
430     napi_value durationNApi = nullptr;
431     napi_value bottomNApi = nullptr;
432     napi_value showModeNApi = nullptr;
433     napi_value alignmentApi = nullptr;
434     napi_value offsetApi = nullptr;
435     napi_value backgroundColorNApi = nullptr;
436     napi_value textColorNApi = nullptr;
437     napi_value backgroundBlurStyleNApi = nullptr;
438     napi_value shadowNApi = nullptr;
439 
440     napi_valuetype valueType = napi_undefined;
441     napi_typeof(env, argv, &valueType);
442     if (valueType == napi_object) {
443         // message can not be null
444         if (!HasProperty(env, argv, "message")) {
445             NapiThrow(env, "Required input parameters are missing.", ERROR_CODE_PARAM_INVALID);
446             return false;
447         }
448         napi_get_named_property(env, argv, "message", &messageNApi);
449         napi_get_named_property(env, argv, "duration", &durationNApi);
450         napi_get_named_property(env, argv, "bottom", &bottomNApi);
451         napi_get_named_property(env, argv, "showMode", &showModeNApi);
452         napi_get_named_property(env, argv, "alignment", &alignmentApi);
453         napi_get_named_property(env, argv, "offset", &offsetApi);
454         napi_get_named_property(env, argv, "backgroundColor", &backgroundColorNApi);
455         napi_get_named_property(env, argv, "textColor", &textColorNApi);
456         napi_get_named_property(env, argv, "backgroundBlurStyle", &backgroundBlurStyleNApi);
457         napi_get_named_property(env, argv, "shadow", &shadowNApi);
458     } else {
459         NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
460         return false;
461     }
462     if (!GetToastMessage(env, messageNApi, toastInfo.message) ||
463         !GetToastDuration(env, durationNApi, toastInfo.duration) ||
464         !GetToastBottom(env, bottomNApi, toastInfo.bottom) ||
465         !GetToastShowMode(env, showModeNApi, toastInfo.showMode) ||
466         !GetToastAlignment(env, alignmentApi, toastInfo.alignment) ||
467         !GetToastOffset(env, offsetApi, toastInfo.offset)) {
468         return false;
469     }
470     GetToastHoverModeParams(env, argv, toastInfo);
471     GetToastBackgroundColor(env, backgroundColorNApi, toastInfo.backgroundColor);
472     GetToastTextColor(env, textColorNApi, toastInfo.textColor);
473     GetToastBackgroundBlurStyle(env, backgroundBlurStyleNApi, toastInfo.backgroundBlurStyle);
474     GetToastShadow(env, shadowNApi, toastInfo.shadow, toastInfo.isTypeStyleShadow);
475     return true;
476 }
477 
ShowToast(napi_env env,NG::ToastInfo & toastInfo,std::function<void (int32_t)> & toastCallback)478 bool ShowToast(napi_env env, NG::ToastInfo& toastInfo, std::function<void(int32_t)>& toastCallback)
479 {
480 #ifdef OHOS_STANDARD_SYSTEM
481     if ((SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) && !ContainerIsScenceBoard() &&
482         toastInfo.showMode == NG::ToastShowMode::DEFAULT) {
483         auto delegate = EngineHelper::GetCurrentDelegateSafely();
484         if (!delegate) {
485             NapiThrow(env, "Can not get delegate.", ERROR_CODE_INTERNAL_ERROR);
486             return false;
487         }
488         TAG_LOGD(AceLogTag::ACE_DIALOG, "before delegate show toast");
489         delegate->ShowToast(toastInfo, std::move(toastCallback));
490     } else if (SubwindowManager::GetInstance() != nullptr) {
491         TAG_LOGD(AceLogTag::ACE_DIALOG, "before subwindow manager show toast");
492         SubwindowManager::GetInstance()->ShowToast(toastInfo, std::move(toastCallback));
493     }
494 #else
495     auto delegate = EngineHelper::GetCurrentDelegateSafely();
496     if (!delegate) {
497         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
498         return false;
499     }
500     if (toastInfo.showMode == NG::ToastShowMode::DEFAULT) {
501         TAG_LOGD(AceLogTag::ACE_DIALOG, "before delegate show toast");
502         delegate->ShowToast(toastInfo, std::move(toastCallback));
503     } else if (SubwindowManager::GetInstance() != nullptr) {
504         TAG_LOGD(AceLogTag::ACE_DIALOG, "before subwindow manager show toast");
505         SubwindowManager::GetInstance()->ShowToast(toastInfo, std::move(toastCallback));
506     }
507 #endif
508     return true;
509 }
510 
JSPromptShowToast(napi_env env,napi_callback_info info)511 napi_value JSPromptShowToast(napi_env env, napi_callback_info info)
512 {
513     TAG_LOGD(AceLogTag::ACE_DIALOG, "show toast enter");
514     size_t requireArgc = 1;
515     size_t argc = 1;
516     napi_value argv = nullptr;
517     napi_value thisVar = nullptr;
518     void* data = nullptr;
519     napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
520     if (argc != requireArgc) {
521         NapiThrow(env, "The number of parameters must be equal to 1.", ERROR_CODE_PARAM_INVALID);
522         return nullptr;
523     }
524     int32_t alignment = -1;
525     auto pipelineContext = PipelineBase::GetCurrentContext();
526     if (pipelineContext) {
527         auto toastTheme = pipelineContext->GetTheme<ToastTheme>();
528         if (toastTheme) {
529             alignment = toastTheme->GetAlign();
530         }
531     }
532     auto toastInfo = NG::ToastInfo { .duration = -1, .showMode = NG::ToastShowMode::DEFAULT, .alignment = alignment };
533     if (!GetToastParams(env, argv, toastInfo)) {
534         return nullptr;
535     }
536     std::function<void(int32_t)> toastCallback = nullptr;
537     ShowToast(env, toastInfo, toastCallback);
538     return nullptr;
539 }
540 
JSPromptOpenToast(napi_env env,napi_callback_info info)541 napi_value JSPromptOpenToast(napi_env env, napi_callback_info info)
542 {
543     TAG_LOGD(AceLogTag::ACE_DIALOG, "open toast enter");
544     size_t requireArgc = 1;
545     size_t argc = 1;
546     napi_value argv = nullptr;
547     napi_value thisVar = nullptr;
548     void* data = nullptr;
549     napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
550     if (argc != requireArgc) {
551         NapiThrow(env, "The number of parameters must be equal to 1.", ERROR_CODE_PARAM_INVALID);
552         return nullptr;
553     }
554     auto toastInfo = NG::ToastInfo { .duration = -1, .showMode = NG::ToastShowMode::DEFAULT, .alignment = -1 };
555     if (!GetToastParams(env, argv, toastInfo)) {
556         return nullptr;
557     }
558     napi_deferred deferred;
559     napi_value result;
560     napi_create_promise(env, &deferred, &result);
561     std::function<void(int32_t)> toastCallback = nullptr;
562     toastCallback = [env, deferred](int32_t toastId) mutable {
563         napi_value napiToastId = nullptr;
564         napi_create_int32(env, toastId, &napiToastId);
565         napi_resolve_deferred(env, deferred, napiToastId);
566     };
567     if (ShowToast(env, toastInfo, toastCallback)) {
568         return result;
569     }
570     return nullptr;
571 }
572 
CloseToast(napi_env env,int32_t toastId,NG::ToastShowMode showMode)573 void CloseToast(napi_env env, int32_t toastId, NG::ToastShowMode showMode)
574 {
575     std::function<void(int32_t)> toastCloseCallback = nullptr;
576     toastCloseCallback = [env](int32_t errorCode) mutable {
577         if (errorCode != ERROR_CODE_NO_ERROR) {
578             NapiThrow(env, "", errorCode);
579         }
580     };
581 #ifdef OHOS_STANDARD_SYSTEM
582     if ((SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) && !ContainerIsScenceBoard() &&
583         showMode == NG::ToastShowMode::DEFAULT) {
584         auto delegate = EngineHelper::GetCurrentDelegateSafely();
585         if (delegate) {
586             delegate->CloseToast(toastId, std::move(toastCloseCallback));
587         } else {
588             NapiThrow(env, "Can not get delegate.", ERROR_CODE_INTERNAL_ERROR);
589         }
590     } else if (SubwindowManager::GetInstance() != nullptr) {
591         SubwindowManager::GetInstance()->CloseToast(toastId, showMode, std::move(toastCloseCallback));
592     }
593 #else
594     auto delegate = EngineHelper::GetCurrentDelegateSafely();
595     if (!delegate) {
596         NapiThrow(env, "UI execution context not found.", ERROR_CODE_INTERNAL_ERROR);
597     }
598     if (showMode == NG::ToastShowMode::DEFAULT) {
599         delegate->CloseToast(toastId, std::move(toastCloseCallback));
600     } else if (SubwindowManager::GetInstance() != nullptr) {
601         SubwindowManager::GetInstance()->CloseToast(toastId, showMode, std::move(toastCloseCallback));
602     }
603 #endif
604 }
605 
JSPromptCloseToast(napi_env env,napi_callback_info info)606 napi_value JSPromptCloseToast(napi_env env, napi_callback_info info)
607 {
608     size_t argc = 1;
609     napi_value args[1];
610     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
611     if (argc != 1) {
612         NapiThrow(env, "The number of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
613         return nullptr;
614     }
615     int32_t id = -1;
616     napi_get_value_int32(env, args[0], &id);
617     if (id < 0 || id > INT32_MAX) {
618         NapiThrow(env, "The toastId is invalid.", ERROR_CODE_PARAM_INVALID);
619         return nullptr;
620     }
621     int32_t showModeVal = static_cast<int32_t>(static_cast<uint32_t>(id) & 0b111);
622     int32_t toastId =
623         static_cast<int32_t>(static_cast<uint32_t>(id) >>
624                              3); // 3 : Move 3 bits to the right to get toastId, and the last 3 bits are the showMode
625     if (toastId < 0 || showModeVal < 0 || showModeVal > static_cast<int32_t>(NG::ToastShowMode::SYSTEM_TOP_MOST)) {
626         NapiThrow(env, "", ERROR_CODE_TOAST_NOT_FOUND);
627         return nullptr;
628     }
629     auto showMode = static_cast<NG::ToastShowMode>(showModeVal);
630     CloseToast(env, toastId, showMode);
631     return nullptr;
632 }
633 
634 struct PromptAsyncContext {
635     napi_env env = nullptr;
636     napi_value titleNApi = nullptr;
637     napi_value messageNApi = nullptr;
638     napi_value buttonsNApi = nullptr;
639     napi_value autoCancel = nullptr;
640     napi_value showInSubWindow = nullptr;
641     napi_value isModal = nullptr;
642     napi_value alignmentApi = nullptr;
643     napi_value offsetApi = nullptr;
644     napi_value maskRectApi = nullptr;
645     napi_value builder = nullptr;
646     napi_value onWillDismiss = nullptr;
647     napi_value backgroundColorApi = nullptr;
648     napi_value backgroundBlurStyleApi = nullptr;
649     napi_value blurStyleOptionApi = nullptr;
650     napi_value effectOptionApi = nullptr;
651     napi_value enableHoverMode = nullptr;
652     napi_value hoverModeAreaApi = nullptr;
653     napi_value borderWidthApi = nullptr;
654     napi_value borderColorApi = nullptr;
655     napi_value borderStyleApi = nullptr;
656     napi_value borderRadiusApi = nullptr;
657     napi_value shadowApi = nullptr;
658     napi_value widthApi = nullptr;
659     napi_value heightApi = nullptr;
660     napi_value frameNodePtr = nullptr;
661     napi_value maskColorApi = nullptr;
662     napi_value onDidAppear = nullptr;
663     napi_value onDidDisappear = nullptr;
664     napi_value onWillAppear = nullptr;
665     napi_value onWillDisappear = nullptr;
666     napi_value transitionApi = nullptr;
667     napi_value dialogTransitionApi = nullptr;
668     napi_value maskTransitionApi = nullptr;
669     napi_ref callbackSuccess = nullptr;
670     napi_ref callbackCancel = nullptr;
671     napi_ref callbackComplete = nullptr;
672     std::string titleString;
673     std::string messageString;
674     std::vector<ButtonInfo> buttons;
675     bool autoCancelBool = true;
676     bool enableHoverModeBool = false;
677     bool showInSubWindowBool = false;
678     bool isModalBool = true;
679     std::set<std::string> callbacks;
680     std::string callbackSuccessString;
681     std::string callbackCancelString;
682     std::string callbackCompleteString;
683     napi_deferred deferred = nullptr;
684     napi_ref callbackRef = nullptr;
685     napi_ref builderRef = nullptr;
686     napi_ref onWillDismissRef = nullptr;
687     int32_t callbackType = -1;
688     int32_t successType = -1;
689     bool valid = true;
690     int32_t instanceId = -1;
691     void* nativePtr = nullptr;
692     napi_ref onDidAppearRef = nullptr;
693     napi_ref onDidDisappearRef = nullptr;
694     napi_ref onWillAppearRef = nullptr;
695     napi_ref onWillDisappearRef = nullptr;
696     napi_value keyboardAvoidModeApi = nullptr;
697     napi_value keyboardAvoidDistanceApi = nullptr;
698     napi_value levelOrderApi = nullptr;
699     napi_value dialogLevelModeApi = nullptr;
700     napi_value dialogLevelUniqueId = nullptr;
701     napi_value dialogImmersiveModeApi = nullptr;
702     napi_value focusableApi = nullptr;
703 };
704 
DeleteContextAndThrowError(napi_env env,std::shared_ptr<PromptAsyncContext> & context,const std::string & errorMessage)705 void DeleteContextAndThrowError(
706     napi_env env, std::shared_ptr<PromptAsyncContext>& context, const std::string& errorMessage)
707 {
708     if (!context) {
709         // context is null, no need to delete
710         return;
711     }
712     NapiThrow(env, errorMessage, ERROR_CODE_PARAM_INVALID);
713 }
714 
GetButtonArraryLen(napi_env env,std::shared_ptr<PromptAsyncContext> & context,int32_t maxButtonNum)715 int32_t GetButtonArraryLen(napi_env env, std::shared_ptr<PromptAsyncContext>& context,
716     int32_t maxButtonNum)
717 {
718     uint32_t buttonsLen = 0;
719     napi_get_array_length(env, context->buttonsNApi, &buttonsLen);
720     int32_t buttonsLenInt = static_cast<int32_t>(buttonsLen);
721     if (buttonsLenInt > maxButtonNum && maxButtonNum != -1) {
722         buttonsLenInt = maxButtonNum;
723     }
724     return buttonsLenInt;
725 }
726 
GetPrimaryButtonNum(napi_env env,std::shared_ptr<PromptAsyncContext> & context,int32_t buttonsLenInt,int32_t & primaryButtonNum)727 void GetPrimaryButtonNum(napi_env env, std::shared_ptr<PromptAsyncContext>& context,
728     int32_t buttonsLenInt, int32_t& primaryButtonNum)
729 {
730     napi_value buttonArray = nullptr;
731     napi_value primaryButtonNApi = nullptr;
732     napi_valuetype valueType = napi_undefined;
733     for (int32_t index = 0; index < buttonsLenInt; index++) {
734         napi_get_element(env, context->buttonsNApi, index, &buttonArray);
735         bool isPrimaryButtonSet = false;
736         napi_get_named_property(env, buttonArray, "primary", &primaryButtonNApi);
737         napi_typeof(env, primaryButtonNApi, &valueType);
738         if (valueType == napi_boolean) {
739             napi_get_value_bool(env, primaryButtonNApi, &isPrimaryButtonSet);
740         }
741         if (isPrimaryButtonSet) {
742             primaryButtonNum++;
743         }
744     }
745 }
746 
ParseButtons(napi_env env,std::shared_ptr<PromptAsyncContext> & context,int32_t maxButtonNum,int32_t & primaryButtonNum)747 bool ParseButtons(napi_env env, std::shared_ptr<PromptAsyncContext>& context,
748     int32_t maxButtonNum, int32_t& primaryButtonNum)
749 {
750     napi_value buttonArray = nullptr;
751     napi_value textNApi = nullptr;
752     napi_value colorNApi = nullptr;
753     napi_value primaryButtonNApi = nullptr;
754     napi_valuetype valueType = napi_undefined;
755     int32_t buttonsLenInt = GetButtonArraryLen(env, context, maxButtonNum);
756     GetPrimaryButtonNum(env, context, buttonsLenInt, primaryButtonNum);
757     for (int32_t index = 0; index < buttonsLenInt; index++) {
758         napi_get_element(env, context->buttonsNApi, index, &buttonArray);
759         if (!HasProperty(env, buttonArray, "text")) {
760             DeleteContextAndThrowError(env, context, "Required input parameters are missing.");
761             return false;
762         }
763         std::string textString;
764         napi_get_named_property(env, buttonArray, "text", &textNApi);
765         if (!GetNapiString(env, textNApi, textString, valueType)) {
766             DeleteContextAndThrowError(env, context, "The type of parameters is incorrect.");
767             return false;
768         }
769         if (!HasProperty(env, buttonArray, "color")) {
770             DeleteContextAndThrowError(env, context, "Required input parameters are missing.");
771             return false;
772         }
773         std::string colorString;
774         napi_get_named_property(env, buttonArray, "color", &colorNApi);
775         if (!GetNapiString(env, colorNApi, colorString, valueType)) {
776             if (valueType == napi_undefined) {
777                 colorString = DEFAULT_FONT_COLOR_STRING_VALUE;
778             } else {
779                 DeleteContextAndThrowError(env, context, "The type of parameters is incorrect.");
780                 return false;
781             }
782         }
783         ButtonInfo buttonInfo = { .text = textString, .textColor = colorString };
784         if (primaryButtonNum <= PROMPTACTION_VALID_PRIMARY_BUTTON_NUM) {
785             napi_get_named_property(env, buttonArray, "primary", &primaryButtonNApi);
786             napi_typeof(env, primaryButtonNApi, &valueType);
787             if (valueType == napi_boolean) {
788                 napi_get_value_bool(env, primaryButtonNApi, &buttonInfo.isPrimary);
789             }
790         }
791         context->buttons.emplace_back(buttonInfo);
792     }
793     return true;
794 }
795 
ParseButtonsPara(napi_env env,std::shared_ptr<PromptAsyncContext> & context,int32_t maxButtonNum,bool isShowActionMenu)796 bool ParseButtonsPara(napi_env env, std::shared_ptr<PromptAsyncContext>& context,
797     int32_t maxButtonNum, bool isShowActionMenu)
798 {
799     bool isBool = false;
800     napi_valuetype valueType = napi_undefined;
801     int32_t primaryButtonNum = 0;
802     napi_is_array(env, context->buttonsNApi, &isBool);
803     napi_typeof(env, context->buttonsNApi, &valueType);
804     if (valueType == napi_object && isBool) {
805         if (!ParseButtons(env, context, SHOW_DIALOG_BUTTON_NUM_MAX, primaryButtonNum)) {
806             return false;
807         }
808     } else if (isShowActionMenu) {
809         DeleteContextAndThrowError(env, context, "The type of the button parameters is incorrect.");
810         return false;
811     }
812     if (isShowActionMenu) {
813         ButtonInfo buttonInfo = { .text = Localization::GetInstance()->GetEntryLetters("common.cancel"),
814             .textColor = "", .isPrimary = primaryButtonNum == 0 ? true : false};
815         context->buttons.emplace_back(buttonInfo);
816     }
817     return true;
818 }
819 
GetNapiDialogProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,std::optional<DialogAlignment> & alignment,std::optional<DimensionOffset> & offset,std::optional<DimensionRect> & maskRect)820 void GetNapiDialogProps(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext,
821     std::optional<DialogAlignment>& alignment, std::optional<DimensionOffset>& offset,
822     std::optional<DimensionRect>& maskRect)
823 {
824     TAG_LOGD(AceLogTag::ACE_DIALOG, "get napi dialog props enter");
825     napi_valuetype valueType = napi_undefined;
826     // parse alignment
827     napi_typeof(env, asyncContext->alignmentApi, &valueType);
828     if (valueType == napi_number) {
829         int32_t num;
830         napi_get_value_int32(env, asyncContext->alignmentApi, &num);
831         if (num >= 0 && num < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
832             alignment = DIALOG_ALIGNMENT[num];
833         }
834     }
835 
836     // parse offset
837     napi_typeof(env, asyncContext->offsetApi, &valueType);
838     if (valueType == napi_object) {
839         napi_value dxApi = nullptr;
840         napi_value dyApi = nullptr;
841         napi_get_named_property(env, asyncContext->offsetApi, "dx", &dxApi);
842         napi_get_named_property(env, asyncContext->offsetApi, "dy", &dyApi);
843         CalcDimension dx;
844         CalcDimension dy;
845         ParseNapiDimension(env, dx, dxApi, DimensionUnit::VP);
846         ParseNapiDimension(env, dy, dyApi, DimensionUnit::VP);
847         offset = DimensionOffset { dx, dy };
848     }
849 
850     // parse maskRect
851     DimensionRect rect;
852     rect.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
853     rect.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
854     maskRect = rect;
855     napi_typeof(env, asyncContext->maskRectApi, &valueType);
856     if (valueType == napi_object) {
857         napi_value xApi = nullptr;
858         napi_value yApi = nullptr;
859         napi_value widthApi = nullptr;
860         napi_value heightApi = nullptr;
861         napi_get_named_property(env, asyncContext->maskRectApi, "x", &xApi);
862         napi_get_named_property(env, asyncContext->maskRectApi, "y", &yApi);
863         napi_get_named_property(env, asyncContext->maskRectApi, "width", &widthApi);
864         napi_get_named_property(env, asyncContext->maskRectApi, "height", &heightApi);
865         CalcDimension x;
866         CalcDimension y;
867         CalcDimension width;
868         CalcDimension height;
869         ParseNapiDimension(env, x, xApi, DimensionUnit::VP);
870         ParseNapiDimension(env, y, yApi, DimensionUnit::VP);
871         ParseNapiDimension(env, width, widthApi, DimensionUnit::VP);
872         ParseNapiDimension(env, height, heightApi, DimensionUnit::VP);
873         DimensionOffset dimensionOffset = { x, y };
874         maskRect = DimensionRect { width, height, dimensionOffset };
875     }
876 }
877 
GetNapiBlurStyleAndHoverModeProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,std::optional<int32_t> & backgroundBlurStyle,std::optional<HoverModeAreaType> & hoverModeArea)878 void GetNapiBlurStyleAndHoverModeProps(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext,
879     std::optional<int32_t>& backgroundBlurStyle, std::optional<HoverModeAreaType>& hoverModeArea)
880 {
881     TAG_LOGD(AceLogTag::ACE_DIALOG, "get napi dialog backgroundBlurStyle and hoverModeArea props enter");
882     napi_valuetype blurStyleValueType = napi_undefined;
883 
884     napi_typeof(env, asyncContext->backgroundBlurStyleApi, &blurStyleValueType);
885     if (blurStyleValueType == napi_number) {
886         int32_t num = 0;
887         napi_get_value_int32(env, asyncContext->backgroundBlurStyleApi, &num);
888         if (num >= 0 && num < BG_BLUR_STYLE_MAX_INDEX) {
889             backgroundBlurStyle = num;
890         }
891     }
892 
893     napi_valuetype hoverModeValueType = napi_undefined;
894     napi_typeof(env, asyncContext->hoverModeAreaApi, &hoverModeValueType);
895     if (hoverModeValueType == napi_number) {
896         int32_t num = 0;
897         napi_get_value_int32(env, asyncContext->hoverModeAreaApi, &num);
898         if (num >= 0 && num < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
899             hoverModeArea = HOVER_MODE_AREA_TYPE[num];
900         }
901     }
902 }
903 
GetBackgroundBlurStyleOption(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,std::optional<BlurStyleOption> & blurStyleOption)904 void GetBackgroundBlurStyleOption(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext,
905     std::optional<BlurStyleOption>& blurStyleOption)
906 {
907     napi_valuetype valueType = napi_undefined;
908     napi_typeof(env, asyncContext->blurStyleOptionApi, &valueType);
909     if (valueType == napi_object) {
910         BlurStyleOption styleOption;
911         auto delegate = EngineHelper::GetCurrentDelegateSafely();
912         if (delegate) {
913             delegate->GetBackgroundBlurStyleOption(asyncContext->blurStyleOptionApi, styleOption);
914         }
915         if (!blurStyleOption.has_value()) {
916             blurStyleOption.emplace();
917         }
918         blurStyleOption.value() = styleOption;
919     }
920 }
921 
GetBackgroundEffect(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,std::optional<EffectOption> & effectOption)922 void GetBackgroundEffect(
923     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext, std::optional<EffectOption>& effectOption)
924 {
925     napi_valuetype valueType = napi_undefined;
926     napi_typeof(env, asyncContext->effectOptionApi, &valueType);
927     if (valueType == napi_object) {
928         EffectOption styleOption;
929         auto delegate = EngineHelper::GetCurrentDelegateSafely();
930         if (delegate) {
931             delegate->GetBackgroundEffect(asyncContext->effectOptionApi, styleOption);
932         }
933         if (!effectOption.has_value()) {
934             effectOption.emplace();
935         }
936         effectOption.value() = styleOption;
937     }
938 }
939 
CheckNapiDimension(CalcDimension value)940 void CheckNapiDimension(CalcDimension value)
941 {
942     if (value.IsNegative()) {
943         value.Reset();
944     }
945 }
946 
GetBorderColorProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)947 std::optional<NG::BorderColorProperty> GetBorderColorProps(
948     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
949 {
950     napi_valuetype valueType = napi_undefined;
951     NG::BorderColorProperty colorProperty;
952     napi_typeof(env, asyncContext->borderColorApi, &valueType);
953     if (valueType != napi_number && valueType != napi_string && valueType != napi_object) {
954         return std::nullopt;
955     }
956     Color borderColor;
957     if (ParseNapiColor(env, asyncContext->borderColorApi, borderColor)) {
958         colorProperty.SetColor(borderColor);
959         return colorProperty;
960     } else if (valueType == napi_object) {
961         napi_value leftApi = nullptr;
962         napi_value rightApi = nullptr;
963         napi_value topApi = nullptr;
964         napi_value bottomApi = nullptr;
965         napi_get_named_property(env, asyncContext->borderColorApi, "left", &leftApi);
966         napi_get_named_property(env, asyncContext->borderColorApi, "right", &rightApi);
967         napi_get_named_property(env, asyncContext->borderColorApi, "top", &topApi);
968         napi_get_named_property(env, asyncContext->borderColorApi, "bottom", &bottomApi);
969         Color leftColor;
970         Color rightColor;
971         Color topColor;
972         Color bottomColor;
973         if (ParseNapiColor(env, leftApi, leftColor)) {
974             colorProperty.leftColor = leftColor;
975         }
976         if (ParseNapiColor(env, rightApi, rightColor)) {
977             colorProperty.rightColor = rightColor;
978         }
979         if (ParseNapiColor(env, topApi, topColor)) {
980             colorProperty.topColor = topColor;
981         }
982         if (ParseNapiColor(env, bottomApi, bottomColor)) {
983             colorProperty.bottomColor = bottomColor;
984         }
985         colorProperty.multiValued = true;
986         return colorProperty;
987     }
988     return std::nullopt;
989 }
990 
GetBorderWidthProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)991 std::optional<NG::BorderWidthProperty> GetBorderWidthProps(
992     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
993 {
994     napi_valuetype valueType = napi_undefined;
995     napi_typeof(env, asyncContext->borderWidthApi, &valueType);
996     if (valueType != napi_number && valueType != napi_string && valueType != napi_object) {
997         return std::nullopt;
998     }
999     NG::BorderWidthProperty borderWidthProps;
1000     CalcDimension borderWidth;
1001     if (ParseNapiDimensionNG(env, borderWidth, asyncContext->borderWidthApi, DimensionUnit::VP, true)) {
1002         CheckNapiDimension(borderWidth);
1003         borderWidthProps = NG::BorderWidthProperty({ borderWidth, borderWidth, borderWidth, borderWidth });
1004         return borderWidthProps;
1005     } else if (valueType == napi_object) {
1006         napi_value leftApi = nullptr;
1007         napi_value rightApi = nullptr;
1008         napi_value topApi = nullptr;
1009         napi_value bottomApi = nullptr;
1010         napi_get_named_property(env, asyncContext->borderWidthApi, "left", &leftApi);
1011         napi_get_named_property(env, asyncContext->borderWidthApi, "right", &rightApi);
1012         napi_get_named_property(env, asyncContext->borderWidthApi, "top", &topApi);
1013         napi_get_named_property(env, asyncContext->borderWidthApi, "bottom", &bottomApi);
1014         CalcDimension leftDimen;
1015         CalcDimension rightDimen;
1016         CalcDimension topDimen;
1017         CalcDimension bottomDimen;
1018         if (ParseNapiDimensionNG(env, leftDimen, leftApi, DimensionUnit::VP, true)) {
1019             CheckNapiDimension(leftDimen);
1020             borderWidthProps.leftDimen = leftDimen;
1021         }
1022         if (ParseNapiDimensionNG(env, rightDimen, rightApi, DimensionUnit::VP, true)) {
1023             CheckNapiDimension(rightDimen);
1024             borderWidthProps.rightDimen = rightDimen;
1025         }
1026         if (ParseNapiDimensionNG(env, topDimen, topApi, DimensionUnit::VP, true)) {
1027             CheckNapiDimension(topDimen);
1028             borderWidthProps.topDimen = topDimen;
1029         }
1030         if (ParseNapiDimensionNG(env, bottomDimen, bottomApi, DimensionUnit::VP, true)) {
1031             CheckNapiDimension(bottomDimen);
1032             borderWidthProps.bottomDimen = bottomDimen;
1033         }
1034         borderWidthProps.multiValued = true;
1035         return borderWidthProps;
1036     }
1037     return std::nullopt;
1038 }
1039 
GetBorderRadiusProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)1040 std::optional<NG::BorderRadiusProperty> GetBorderRadiusProps(
1041     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
1042 {
1043     napi_valuetype valueType = napi_undefined;
1044     napi_typeof(env, asyncContext->borderRadiusApi, &valueType);
1045     if (valueType != napi_number && valueType != napi_object && valueType != napi_string) {
1046         return std::nullopt;
1047     }
1048     CalcDimension borderRadius;
1049     if (ParseNapiDimensionNG(env, borderRadius, asyncContext->borderRadiusApi, DimensionUnit::VP, true)) {
1050         CheckNapiDimension(borderRadius);
1051         return NG::BorderRadiusProperty(borderRadius);
1052     } else if (valueType == napi_object) {
1053         NG::BorderRadiusProperty radiusProps;
1054         napi_value topLeft = nullptr;
1055         napi_value topRight = nullptr;
1056         napi_value bottomLeft = nullptr;
1057         napi_value bottomRight = nullptr;
1058         napi_get_named_property(env, asyncContext->borderRadiusApi, "topLeft", &topLeft);
1059         napi_get_named_property(env, asyncContext->borderRadiusApi, "topRight", &topRight);
1060         napi_get_named_property(env, asyncContext->borderRadiusApi, "bottomLeft", &bottomLeft);
1061         napi_get_named_property(env, asyncContext->borderRadiusApi, "bottomRight", &bottomRight);
1062         CalcDimension radiusTopLeft;
1063         CalcDimension radiusTopRight;
1064         CalcDimension radiusBottomLeft;
1065         CalcDimension radiusBottomRight;
1066         if (ParseNapiDimensionNG(env, radiusTopLeft, topLeft, DimensionUnit::VP, true)) {
1067             CheckNapiDimension(radiusTopLeft);
1068             radiusProps.radiusTopLeft = radiusTopLeft;
1069         }
1070         if (ParseNapiDimensionNG(env, radiusTopRight, topRight, DimensionUnit::VP, true)) {
1071             CheckNapiDimension(radiusTopRight);
1072             radiusProps.radiusTopRight = radiusTopRight;
1073         }
1074         if (ParseNapiDimensionNG(env, radiusBottomLeft, bottomLeft, DimensionUnit::VP, true)) {
1075             CheckNapiDimension(radiusBottomLeft);
1076             radiusProps.radiusBottomLeft = radiusBottomLeft;
1077         }
1078         if (ParseNapiDimensionNG(env, radiusBottomRight, bottomRight, DimensionUnit::VP, true)) {
1079             CheckNapiDimension(radiusBottomRight);
1080             radiusProps.radiusBottomRight = radiusBottomRight;
1081         }
1082         radiusProps.multiValued = true;
1083         return radiusProps;
1084     }
1085     return std::nullopt;
1086 }
1087 
GetColorProps(napi_env env,napi_value value)1088 std::optional<Color> GetColorProps(napi_env env, napi_value value)
1089 {
1090     Color color;
1091     if (ParseNapiColor(env, value, color)) {
1092         return color;
1093     }
1094     return std::nullopt;
1095 }
1096 
GetBorderStyleProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)1097 std::optional<NG::BorderStyleProperty> GetBorderStyleProps(
1098     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
1099 {
1100     NG::BorderStyleProperty styleProps;
1101     napi_valuetype valueType = napi_undefined;
1102     napi_typeof(env, asyncContext->borderStyleApi, &valueType);
1103     if (valueType != napi_number && valueType != napi_object) {
1104         return std::nullopt;
1105     } else if (valueType == napi_object) {
1106         napi_value leftApi = nullptr;
1107         napi_value rightApi = nullptr;
1108         napi_value topApi = nullptr;
1109         napi_value bottomApi = nullptr;
1110         napi_get_named_property(env, asyncContext->borderStyleApi, "left", &leftApi);
1111         napi_get_named_property(env, asyncContext->borderStyleApi, "right", &rightApi);
1112         napi_get_named_property(env, asyncContext->borderStyleApi, "top", &topApi);
1113         napi_get_named_property(env, asyncContext->borderStyleApi, "bottom", &bottomApi);
1114         std::optional<BorderStyle> styleLeft;
1115         std::optional<BorderStyle> styleRight;
1116         std::optional<BorderStyle> styleTop;
1117         std::optional<BorderStyle> styleBottom;
1118         if (ParseStyle(env, leftApi, styleLeft)) {
1119             styleProps.styleLeft = styleLeft;
1120         }
1121         if (ParseStyle(env, rightApi, styleRight)) {
1122             styleProps.styleRight = styleRight;
1123         }
1124         if (ParseStyle(env, topApi, styleTop)) {
1125             styleProps.styleTop = styleTop;
1126         }
1127         if (ParseStyle(env, bottomApi, styleBottom)) {
1128             styleProps.styleBottom = styleBottom;
1129         }
1130         styleProps.multiValued = true;
1131         return styleProps;
1132     }
1133     std::optional<BorderStyle> borderStyle;
1134     if (ParseStyle(env, asyncContext->borderStyleApi, borderStyle)) {
1135         styleProps = NG::BorderStyleProperty({ borderStyle, borderStyle, borderStyle, borderStyle });
1136         return styleProps;
1137     }
1138     return std::nullopt;
1139 }
1140 
GetNapiObjectShadow(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,Shadow & shadow)1141 void GetNapiObjectShadow(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext, Shadow& shadow)
1142 {
1143     napi_value radiusApi = nullptr;
1144     napi_value colorApi = nullptr;
1145     napi_value typeApi = nullptr;
1146     napi_value fillApi = nullptr;
1147     napi_get_named_property(env, asyncContext->shadowApi, "radius", &radiusApi);
1148     napi_get_named_property(env, asyncContext->shadowApi, "color", &colorApi);
1149     napi_get_named_property(env, asyncContext->shadowApi, "type", &typeApi);
1150     napi_get_named_property(env, asyncContext->shadowApi, "fill", &fillApi);
1151     double radius = 0.0;
1152     napi_get_value_double(env, radiusApi, &radius);
1153     if (LessNotEqual(radius, 0.0)) {
1154         radius = 0.0;
1155     }
1156     shadow.SetBlurRadius(radius);
1157     Color color;
1158     ShadowColorStrategy shadowColorStrategy;
1159     if (ParseShadowColorStrategy(env, colorApi, shadowColorStrategy)) {
1160         shadow.SetShadowColorStrategy(shadowColorStrategy);
1161     } else if (ParseNapiColor(env, colorApi, color)) {
1162         shadow.SetColor(color);
1163     }
1164     napi_valuetype valueType = GetValueType(env, typeApi);
1165     int32_t shadowType = static_cast<int32_t>(ShadowType::COLOR);
1166     if (valueType == napi_number) {
1167         napi_get_value_int32(env, typeApi, &shadowType);
1168     }
1169     if (shadowType != static_cast<int32_t>(ShadowType::BLUR)) {
1170         shadowType = static_cast<int32_t>(ShadowType::COLOR);
1171     }
1172     shadowType =
1173         std::clamp(shadowType, static_cast<int32_t>(ShadowType::COLOR), static_cast<int32_t>(ShadowType::BLUR));
1174     shadow.SetShadowType(static_cast<ShadowType>(shadowType));
1175     valueType = GetValueType(env, fillApi);
1176     bool isFilled = false;
1177     if (valueType == napi_boolean) {
1178         napi_get_value_bool(env, fillApi, &isFilled);
1179     }
1180     shadow.SetIsFilled(isFilled);
1181 }
1182 
GetShadowProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)1183 std::optional<Shadow> GetShadowProps(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
1184 {
1185     Shadow shadow;
1186     napi_valuetype valueType = napi_undefined;
1187     napi_typeof(env, asyncContext->shadowApi, &valueType);
1188     if (valueType != napi_object && valueType != napi_number) {
1189         return std::nullopt;
1190     }
1191     if (valueType == napi_number) {
1192         int32_t num = 0;
1193         if (napi_get_value_int32(env, asyncContext->shadowApi, &num) == napi_ok) {
1194             auto style = static_cast<ShadowStyle>(num);
1195             GetShadowFromTheme(style, shadow);
1196             return shadow;
1197         }
1198     } else if (valueType == napi_object) {
1199         napi_value offsetXApi = nullptr;
1200         napi_value offsetYApi = nullptr;
1201         napi_get_named_property(env, asyncContext->shadowApi, "offsetX", &offsetXApi);
1202         napi_get_named_property(env, asyncContext->shadowApi, "offsetY", &offsetYApi);
1203         ResourceInfo recv;
1204         bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
1205         if (ParseResourceParam(env, offsetXApi, recv)) {
1206             auto resourceWrapper = CreateResourceWrapper(recv);
1207             auto offsetX = resourceWrapper->GetDimension(recv.resId);
1208             double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
1209             shadow.SetOffsetX(xValue);
1210         } else {
1211             CalcDimension offsetX;
1212             if (ParseNapiDimension(env, offsetX, offsetXApi, DimensionUnit::VP)) {
1213                 double xValue = isRtl ? offsetX.Value() * (-1) : offsetX.Value();
1214                 shadow.SetOffsetX(xValue);
1215             }
1216         }
1217         if (ParseResourceParam(env, offsetYApi, recv)) {
1218             auto resourceWrapper = CreateResourceWrapper(recv);
1219             auto offsetY = resourceWrapper->GetDimension(recv.resId);
1220             shadow.SetOffsetY(offsetY.Value());
1221         } else {
1222             CalcDimension offsetY;
1223             if (ParseNapiDimension(env, offsetY, offsetYApi, DimensionUnit::VP)) {
1224                 shadow.SetOffsetY(offsetY.Value());
1225             }
1226         }
1227         GetNapiObjectShadow(env, asyncContext, shadow);
1228         return shadow;
1229     }
1230     return std::nullopt;
1231 }
1232 
GetNapiDialogWidthProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)1233 std::optional<CalcDimension> GetNapiDialogWidthProps(
1234     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
1235 {
1236     std::optional<CalcDimension> widthProperty;
1237     CalcDimension width;
1238     if (ParseNapiDimensionNG(env, width, asyncContext->widthApi, DimensionUnit::VP, true)) {
1239         widthProperty = width;
1240     }
1241     return widthProperty;
1242 }
1243 
GetKeyboardAvoidDistanceProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)1244 std::optional<CalcDimension> GetKeyboardAvoidDistanceProps(
1245     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
1246 {
1247     std::optional<CalcDimension> keyboardAvoidDistanceProperty;
1248     napi_valuetype valueType = napi_undefined;
1249     napi_typeof(env, asyncContext->keyboardAvoidDistanceApi, &valueType);
1250     if (valueType != napi_object) {
1251         return keyboardAvoidDistanceProperty;
1252     }
1253     if (valueType == napi_object) {
1254         napi_value avoidDistance = nullptr;
1255         napi_value avoidDistanceUnit = nullptr;
1256         napi_get_named_property(env, asyncContext->keyboardAvoidDistanceApi, "value", &avoidDistance);
1257         napi_get_named_property(env, asyncContext->keyboardAvoidDistanceApi, "unit", &avoidDistanceUnit);
1258         napi_valuetype distanceType = napi_undefined;
1259         napi_valuetype distanceUnitType = napi_undefined;
1260         napi_typeof(env, avoidDistance, &distanceType);
1261         napi_typeof(env, avoidDistanceUnit, &distanceUnitType);
1262         double avoidDistanceValue = 0.0;
1263         int32_t avoidDistanceUnitValue = 0;
1264         if (distanceType == napi_number && distanceUnitType == napi_number) {
1265             napi_get_value_double(env, avoidDistance, &avoidDistanceValue);
1266             napi_get_value_int32(env, avoidDistanceUnit, &avoidDistanceUnitValue);
1267             auto avoidDistanceUnitValueType = static_cast<DimensionUnit>(avoidDistanceUnitValue);
1268             if (avoidDistanceValue >= 0.0 && avoidDistanceUnitValueType >= DimensionUnit::PX &&
1269                 avoidDistanceUnitValueType <= DimensionUnit::CALC &&
1270                 avoidDistanceUnitValueType != DimensionUnit::PERCENT) {
1271                 Dimension dimension(avoidDistanceValue, avoidDistanceUnitValueType);
1272                 keyboardAvoidDistanceProperty = dimension;
1273             } else {
1274                 Dimension dimension(DEFAULT_AVOID_DISTANCE, DimensionUnit::VP);
1275                 keyboardAvoidDistanceProperty = dimension;
1276             }
1277         }
1278     }
1279     return keyboardAvoidDistanceProperty;
1280 }
1281 
GetNapiDialogHeightProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)1282 std::optional<CalcDimension> GetNapiDialogHeightProps(
1283     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
1284 {
1285     std::optional<CalcDimension> heightProperty;
1286     CalcDimension height;
1287     if (ParseNapiDimensionNG(env, height, asyncContext->heightApi, DimensionUnit::VP, true)) {
1288         heightProperty = height;
1289     }
1290     return heightProperty;
1291 }
1292 
GetDialogKeyboardAvoidMode(napi_env env,napi_value keyboardAvoidModeApi)1293 int32_t GetDialogKeyboardAvoidMode(napi_env env, napi_value keyboardAvoidModeApi)
1294 {
1295     int32_t mode = 0;
1296     napi_valuetype valueType = napi_undefined;
1297     napi_typeof(env, keyboardAvoidModeApi, &valueType);
1298     if (valueType == napi_number) {
1299         napi_get_value_int32(env, keyboardAvoidModeApi, &mode);
1300     }
1301     if (mode >= 0 && mode < static_cast<int32_t>(KEYBOARD_AVOID_MODE.size())) {
1302         return mode;
1303     }
1304     return 0;
1305 }
1306 
GetDialogLevelModeAndUniqueId(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,LevelMode & dialogLevelMode,int32_t & dialogLevelUniqueId,ImmersiveMode & dialogImmersiveMode)1307 void GetDialogLevelModeAndUniqueId(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext,
1308     LevelMode& dialogLevelMode, int32_t& dialogLevelUniqueId, ImmersiveMode& dialogImmersiveMode)
1309 {
1310     int32_t mode = 0;
1311     int32_t immersiveMode = 0;
1312     napi_valuetype levelModeValueType = napi_undefined;
1313     napi_typeof(env, asyncContext->dialogLevelModeApi, &levelModeValueType);
1314     if (levelModeValueType == napi_number) {
1315         napi_get_value_int32(env, asyncContext->dialogLevelModeApi, &mode);
1316     }
1317     if (!asyncContext->showInSubWindowBool && mode >= 0 && mode < static_cast<int32_t>(DIALOG_LEVEL_MODE.size())) {
1318         dialogLevelMode = DIALOG_LEVEL_MODE[mode];
1319     }
1320     napi_valuetype levelUniquedIdValueType = napi_undefined;
1321     napi_typeof(env, asyncContext->dialogLevelUniqueId, &levelUniquedIdValueType);
1322     if (levelUniquedIdValueType == napi_number) {
1323         napi_get_value_int32(env, asyncContext->dialogLevelUniqueId, &dialogLevelUniqueId);
1324     }
1325     napi_valuetype immersiveModeValueType = napi_undefined;
1326     napi_typeof(env, asyncContext->dialogImmersiveModeApi, &immersiveModeValueType);
1327     if (immersiveModeValueType == napi_number) {
1328         napi_get_value_int32(env, asyncContext->dialogImmersiveModeApi, &immersiveMode);
1329     }
1330     if (immersiveMode >= 0 && immersiveMode < static_cast<int32_t>(DIALOG_IMMERSIVE_MODE.size())) {
1331         dialogImmersiveMode = DIALOG_IMMERSIVE_MODE[immersiveMode];
1332     }
1333 }
1334 
GetNapiNamedBoolProperties(napi_env env,std::shared_ptr<PromptAsyncContext> & asyncContext)1335 void GetNapiNamedBoolProperties(napi_env env, std::shared_ptr<PromptAsyncContext>& asyncContext)
1336 {
1337     napi_valuetype valueType = napi_undefined;
1338     napi_typeof(env, asyncContext->autoCancel, &valueType);
1339     if (valueType == napi_boolean) {
1340         napi_get_value_bool(env, asyncContext->autoCancel, &asyncContext->autoCancelBool);
1341     }
1342     napi_typeof(env, asyncContext->enableHoverMode, &valueType);
1343     if (valueType == napi_boolean) {
1344         napi_get_value_bool(env, asyncContext->enableHoverMode, &asyncContext->enableHoverModeBool);
1345     }
1346     napi_typeof(env, asyncContext->showInSubWindow, &valueType);
1347     if (valueType == napi_boolean) {
1348         napi_get_value_bool(env, asyncContext->showInSubWindow, &asyncContext->showInSubWindowBool);
1349     }
1350     napi_typeof(env, asyncContext->isModal, &valueType);
1351     if (valueType == napi_boolean) {
1352         napi_get_value_bool(env, asyncContext->isModal, &asyncContext->isModalBool);
1353     }
1354 }
1355 
GetNapiNamedProperties(napi_env env,napi_value * argv,size_t index,std::shared_ptr<PromptAsyncContext> & asyncContext)1356 void GetNapiNamedProperties(napi_env env, napi_value* argv, size_t index,
1357     std::shared_ptr<PromptAsyncContext>& asyncContext)
1358 {
1359     napi_valuetype valueType = napi_undefined;
1360 
1361     if (index == 0) {
1362         napi_get_named_property(env, argv[index], "builder", &asyncContext->builder);
1363         napi_get_named_property(env, argv[index], "backgroundColor", &asyncContext->backgroundColorApi);
1364         napi_get_named_property(env, argv[index], "backgroundBlurStyle", &asyncContext->backgroundBlurStyleApi);
1365         napi_get_named_property(env, argv[index], "backgroundBlurStyleOptions", &asyncContext->blurStyleOptionApi);
1366         napi_get_named_property(env, argv[index], "backgroundEffect", &asyncContext->effectOptionApi);
1367         napi_get_named_property(env, argv[index], "hoverModeArea", &asyncContext->hoverModeAreaApi);
1368         napi_get_named_property(env, argv[index], "cornerRadius", &asyncContext->borderRadiusApi);
1369         napi_get_named_property(env, argv[index], "borderWidth", &asyncContext->borderWidthApi);
1370         napi_get_named_property(env, argv[index], "borderColor", &asyncContext->borderColorApi);
1371         napi_get_named_property(env, argv[index], "borderStyle", &asyncContext->borderStyleApi);
1372         napi_get_named_property(env, argv[index], "shadow", &asyncContext->shadowApi);
1373         napi_get_named_property(env, argv[index], "width", &asyncContext->widthApi);
1374         napi_get_named_property(env, argv[index], "height", &asyncContext->heightApi);
1375 
1376         napi_typeof(env, asyncContext->builder, &valueType);
1377         if (valueType == napi_function) {
1378             napi_create_reference(env, asyncContext->builder, 1, &asyncContext->builderRef);
1379         }
1380     }
1381     napi_get_named_property(env, argv[index], "enableHoverMode", &asyncContext->enableHoverMode);
1382     napi_get_named_property(env, argv[index], "showInSubWindow", &asyncContext->showInSubWindow);
1383     napi_get_named_property(env, argv[index], "isModal", &asyncContext->isModal);
1384     napi_get_named_property(env, argv[index], "alignment", &asyncContext->alignmentApi);
1385     napi_get_named_property(env, argv[index], "offset", &asyncContext->offsetApi);
1386     napi_get_named_property(env, argv[index], "maskRect", &asyncContext->maskRectApi);
1387     napi_get_named_property(env, argv[index], "autoCancel", &asyncContext->autoCancel);
1388     napi_get_named_property(env, argv[index], "maskColor", &asyncContext->maskColorApi);
1389     napi_get_named_property(env, argv[index], "transition", &asyncContext->transitionApi);
1390     napi_get_named_property(env, argv[index], "dialogTransition", &asyncContext->dialogTransitionApi);
1391     napi_get_named_property(env, argv[index], "maskTransition", &asyncContext->maskTransitionApi);
1392     napi_get_named_property(env, argv[index], "onWillDismiss", &asyncContext->onWillDismiss);
1393     napi_get_named_property(env, argv[index], "onDidAppear", &asyncContext->onDidAppear);
1394     napi_get_named_property(env, argv[index], "onDidDisappear", &asyncContext->onDidDisappear);
1395     napi_get_named_property(env, argv[index], "onWillAppear", &asyncContext->onWillAppear);
1396     napi_get_named_property(env, argv[index], "onWillDisappear", &asyncContext->onWillDisappear);
1397     napi_get_named_property(env, argv[index], "keyboardAvoidMode", &asyncContext->keyboardAvoidModeApi);
1398     napi_get_named_property(env, argv[index], "keyboardAvoidDistance", &asyncContext->keyboardAvoidDistanceApi);
1399     napi_get_named_property(env, argv[index], "levelOrder", &asyncContext->levelOrderApi);
1400     napi_get_named_property(env, argv[index], "levelMode", &asyncContext->dialogLevelModeApi);
1401     napi_get_named_property(env, argv[index], "levelUniqueId", &asyncContext->dialogLevelUniqueId);
1402     napi_get_named_property(env, argv[index], "immersiveMode", &asyncContext->dialogImmersiveModeApi);
1403     napi_get_named_property(env, argv[index], "focusable", &asyncContext->focusableApi);
1404 
1405     GetNapiNamedBoolProperties(env, asyncContext);
1406 }
1407 
JSPromptParseParam(napi_env env,size_t argc,napi_value * argv,std::shared_ptr<PromptAsyncContext> & asyncContext)1408 bool JSPromptParseParam(napi_env env, size_t argc, napi_value* argv, std::shared_ptr<PromptAsyncContext>& asyncContext)
1409 {
1410     for (size_t i = 0; i < argc; i++) {
1411         napi_valuetype valueType = napi_undefined;
1412         napi_typeof(env, argv[i], &valueType);
1413         if (i == 0 || i == 1) {
1414             if (valueType != napi_object) {
1415                 DeleteContextAndThrowError(env, asyncContext, "The type of parameters is incorrect.");
1416                 return false;
1417             }
1418             GetNapiNamedProperties(env, argv, i, asyncContext);
1419             auto result = napi_get_named_property(env, argv[0], "nodePtr_", &asyncContext->frameNodePtr);
1420             if (result == napi_ok) {
1421                 napi_get_value_external(env, asyncContext->frameNodePtr, &asyncContext->nativePtr);
1422             }
1423 
1424             napi_typeof(env, asyncContext->onWillDismiss, &valueType);
1425             if (valueType == napi_function) {
1426                 napi_create_reference(env, asyncContext->onWillDismiss, 1, &asyncContext->onWillDismissRef);
1427             }
1428             napi_typeof(env, asyncContext->onDidAppear, &valueType);
1429             if (valueType == napi_function) {
1430                 napi_create_reference(env, asyncContext->onDidAppear, 1, &asyncContext->onDidAppearRef);
1431             }
1432             napi_typeof(env, asyncContext->onDidDisappear, &valueType);
1433             if (valueType == napi_function) {
1434                 napi_create_reference(env, asyncContext->onDidDisappear, 1, &asyncContext->onDidDisappearRef);
1435             }
1436             napi_typeof(env, asyncContext->onWillAppear, &valueType);
1437             if (valueType == napi_function) {
1438                 napi_create_reference(env, asyncContext->onWillAppear, 1, &asyncContext->onWillAppearRef);
1439             }
1440             napi_typeof(env, asyncContext->onWillDisappear, &valueType);
1441             if (valueType == napi_function) {
1442                 napi_create_reference(env, asyncContext->onWillDisappear, 1, &asyncContext->onWillDisappearRef);
1443             }
1444         } else {
1445             DeleteContextAndThrowError(env, asyncContext, "The type of parameters is incorrect.");
1446             return false;
1447         }
1448     }
1449     return true;
1450 }
1451 
JSPromptThrowInterError(napi_env env,std::shared_ptr<PromptAsyncContext> & asyncContext,std::string & strMsg)1452 void JSPromptThrowInterError(napi_env env, std::shared_ptr<PromptAsyncContext>& asyncContext, std::string& strMsg)
1453 {
1454     napi_value code = nullptr;
1455     std::string strCode = std::to_string(ERROR_CODE_INTERNAL_ERROR);
1456     napi_create_string_utf8(env, strCode.c_str(), strCode.length(), &code);
1457     napi_value msg = nullptr;
1458     napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg);
1459     napi_value error = nullptr;
1460     napi_create_error(env, code, msg, &error);
1461 
1462     if (asyncContext->deferred) {
1463         napi_reject_deferred(env, asyncContext->deferred, error);
1464     }
1465 }
1466 
UpdatePromptAlignment(DialogAlignment & alignment)1467 void UpdatePromptAlignment(DialogAlignment& alignment)
1468 {
1469     bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
1470     if (alignment == DialogAlignment::TOP_START) {
1471         if (isRtl) {
1472             alignment = DialogAlignment::TOP_END;
1473         }
1474     } else if (alignment == DialogAlignment::TOP_END) {
1475         if (isRtl) {
1476             alignment = DialogAlignment::TOP_START;
1477         }
1478     } else if (alignment == DialogAlignment::CENTER_START) {
1479         if (isRtl) {
1480             alignment = DialogAlignment::CENTER_END;
1481         }
1482     } else if (alignment == DialogAlignment::CENTER_END) {
1483         if (isRtl) {
1484             alignment = DialogAlignment::CENTER_START;
1485         }
1486     } else if (alignment == DialogAlignment::BOTTOM_START) {
1487         if (isRtl) {
1488             alignment = DialogAlignment::BOTTOM_END;
1489         }
1490     } else if (alignment == DialogAlignment::BOTTOM_END) {
1491         if (isRtl) {
1492             alignment = DialogAlignment::BOTTOM_START;
1493         }
1494     }
1495 }
1496 
GetLevelOrderParam(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)1497 std::optional<double> GetLevelOrderParam(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
1498 {
1499     if (asyncContext->showInSubWindowBool) {
1500         return std::nullopt;
1501     }
1502 
1503     napi_value levelOrderApi = asyncContext->levelOrderApi;
1504     NG::LevelOrder* levelOrder = nullptr;
1505     if (levelOrderApi) {
1506         napi_unwrap(env, levelOrderApi, reinterpret_cast<void**>(&levelOrder));
1507     }
1508 
1509     double order = NG::LevelOrder::ORDER_DEFAULT;
1510     if (levelOrder) {
1511         order = levelOrder->GetOrder();
1512     }
1513     return std::make_optional(order);
1514 }
1515 
JSPromptShowDialog(napi_env env,napi_callback_info info)1516 napi_value JSPromptShowDialog(napi_env env, napi_callback_info info)
1517 {
1518     TAG_LOGD(AceLogTag::ACE_DIALOG, "js prompt show dialog enter");
1519     size_t requireArgc = 1;
1520     size_t argc = 2;
1521     napi_value argv[3] = { 0 };
1522     napi_value thisVar = nullptr;
1523     void* data = nullptr;
1524     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1525     if (argc < requireArgc) {
1526         NapiThrow(
1527             env, "The number of parameters must be greater than or equal to 1.", ERROR_CODE_PARAM_INVALID);
1528         return nullptr;
1529     }
1530     if (thisVar == nullptr) {
1531         return nullptr;
1532     }
1533     napi_valuetype valueTypeOfThis = napi_undefined;
1534     napi_typeof(env, thisVar, &valueTypeOfThis);
1535     if (valueTypeOfThis == napi_undefined) {
1536         return nullptr;
1537     }
1538 
1539     auto asyncContext = std::make_shared<PromptAsyncContext>();
1540     asyncContext->env = env;
1541     asyncContext->instanceId = Container::CurrentIdSafely();
1542 
1543     std::optional<DialogAlignment> alignment;
1544     std::optional<DimensionOffset> offset;
1545     std::optional<DimensionRect> maskRect;
1546     std::optional<Shadow> shadowProps;
1547     std::optional<Color> backgroundColor;
1548     std::optional<int32_t> backgroundBlurStyle;
1549     std::optional<BlurStyleOption> blurStyleOption;
1550     std::optional<EffectOption> effectOption;
1551     std::optional<HoverModeAreaType> hoverModeArea;
1552     LevelMode dialogLevelMode = LevelMode::OVERLAY;
1553     int32_t dialogLevelUniqueId = -1;
1554     ImmersiveMode dialogImmersiveMode = ImmersiveMode::DEFAULT;
1555     for (size_t i = 0; i < argc; i++) {
1556         napi_valuetype valueType = napi_undefined;
1557         napi_typeof(env, argv[i], &valueType);
1558         if (i == 0) {
1559             if (valueType != napi_object) {
1560                 DeleteContextAndThrowError(env, asyncContext, "The type of parameters is incorrect.");
1561                 return nullptr;
1562             }
1563             napi_get_named_property(env, argv[0], "title", &asyncContext->titleNApi);
1564             napi_get_named_property(env, argv[0], "message", &asyncContext->messageNApi);
1565             napi_get_named_property(env, argv[0], "buttons", &asyncContext->buttonsNApi);
1566             napi_get_named_property(env, argv[0], "autoCancel", &asyncContext->autoCancel);
1567             napi_get_named_property(env, argv[0], "showInSubWindow", &asyncContext->showInSubWindow);
1568             napi_get_named_property(env, argv[0], "isModal", &asyncContext->isModal);
1569             napi_get_named_property(env, argv[0], "alignment", &asyncContext->alignmentApi);
1570             napi_get_named_property(env, argv[0], "offset", &asyncContext->offsetApi);
1571             napi_get_named_property(env, argv[0], "maskRect", &asyncContext->maskRectApi);
1572             napi_get_named_property(env, argv[0], "shadow", &asyncContext->shadowApi);
1573             napi_get_named_property(env, argv[0], "backgroundColor", &asyncContext->backgroundColorApi);
1574             napi_get_named_property(env, argv[0], "backgroundBlurStyle", &asyncContext->backgroundBlurStyleApi);
1575             napi_get_named_property(env, argv[0], "backgroundBlurStyleOptions", &asyncContext->blurStyleOptionApi);
1576             napi_get_named_property(env, argv[0], "backgroundEffect", &asyncContext->effectOptionApi);
1577             napi_get_named_property(env, argv[0], "enableHoverMode", &asyncContext->enableHoverMode);
1578             napi_get_named_property(env, argv[0], "hoverModeArea", &asyncContext->hoverModeAreaApi);
1579             napi_get_named_property(env, argv[0], "levelOrder", &asyncContext->levelOrderApi);
1580             napi_get_named_property(env, argv[0], "levelMode", &asyncContext->dialogLevelModeApi);
1581             napi_get_named_property(env, argv[0], "levelUniqueId", &asyncContext->dialogLevelUniqueId);
1582             napi_get_named_property(env, argv[0], "immersiveMode", &asyncContext->dialogImmersiveModeApi);
1583             GetNapiString(env, asyncContext->titleNApi, asyncContext->titleString, valueType);
1584             GetNapiString(env, asyncContext->messageNApi, asyncContext->messageString, valueType);
1585             GetNapiDialogProps(env, asyncContext, alignment, offset, maskRect);
1586             backgroundColor = GetColorProps(env, asyncContext->backgroundColorApi);
1587             shadowProps = GetShadowProps(env, asyncContext);
1588             GetNapiBlurStyleAndHoverModeProps(env, asyncContext, backgroundBlurStyle, hoverModeArea);
1589             GetBackgroundBlurStyleOption(env, asyncContext, blurStyleOption);
1590             GetBackgroundEffect(env, asyncContext, effectOption);
1591             if (!ParseButtonsPara(env, asyncContext, SHOW_DIALOG_BUTTON_NUM_MAX, false)) {
1592                 return nullptr;
1593             }
1594             napi_typeof(env, asyncContext->enableHoverMode, &valueType);
1595             if (valueType == napi_boolean) {
1596                 napi_get_value_bool(env, asyncContext->enableHoverMode, &asyncContext->enableHoverModeBool);
1597             }
1598             napi_typeof(env, asyncContext->autoCancel, &valueType);
1599             if (valueType == napi_boolean) {
1600                 napi_get_value_bool(env, asyncContext->autoCancel, &asyncContext->autoCancelBool);
1601             }
1602             napi_typeof(env, asyncContext->showInSubWindow, &valueType);
1603             if (valueType == napi_boolean) {
1604                 napi_get_value_bool(env, asyncContext->showInSubWindow, &asyncContext->showInSubWindowBool);
1605             }
1606             napi_typeof(env, asyncContext->isModal, &valueType);
1607             if (valueType == napi_boolean) {
1608                 napi_get_value_bool(env, asyncContext->isModal, &asyncContext->isModalBool);
1609             }
1610             GetDialogLevelModeAndUniqueId(env, asyncContext, dialogLevelMode, dialogLevelUniqueId, dialogImmersiveMode);
1611         } else if (valueType == napi_function) {
1612             napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
1613         } else {
1614             DeleteContextAndThrowError(env, asyncContext, "The type of parameters is incorrect.");
1615             return nullptr;
1616         }
1617     }
1618     auto onLanguageChange = [shadowProps, alignment, offset, maskRect,
1619         updateAlignment = UpdatePromptAlignment](DialogProperties& dialogProps) {
1620         bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
1621         if (shadowProps.has_value()) {
1622             std::optional<Shadow> shadow = shadowProps.value();
1623             double offsetX = isRtl ? shadow->GetOffset().GetX() * (-1) : shadow->GetOffset().GetX();
1624             shadow->SetOffsetX(offsetX);
1625             dialogProps.shadow = shadow.value();
1626         }
1627         if (alignment.has_value()) {
1628             std::optional<DialogAlignment> pmAlign = alignment.value();
1629             updateAlignment(pmAlign.value());
1630             dialogProps.alignment = pmAlign.value();
1631         }
1632         if (offset.has_value()) {
1633             std::optional<DimensionOffset> pmOffset = offset.value();
1634             Dimension offsetX = isRtl ? pmOffset->GetX() * (-1) : pmOffset->GetX();
1635             pmOffset->SetX(offsetX);
1636             dialogProps.offset = pmOffset.value();
1637         }
1638         if (maskRect.has_value()) {
1639             std::optional<DimensionRect> pmMaskRect = maskRect.value();
1640             auto offset = pmMaskRect->GetOffset();
1641             Dimension offsetX = isRtl ? offset.GetX() * (-1) : offset.GetX();
1642             offset.SetX(offsetX);
1643             pmMaskRect->SetOffset(offset);
1644             dialogProps.maskRect = pmMaskRect.value();
1645         }
1646     };
1647     napi_value result = nullptr;
1648     if (asyncContext->callbackRef == nullptr) {
1649         napi_create_promise(env, &asyncContext->deferred, &result);
1650     } else {
1651         napi_get_undefined(env, &result);
1652     }
1653     asyncContext->callbacks.emplace("success");
1654     asyncContext->callbacks.emplace("cancel");
1655 
1656     auto callBack = [asyncContext](int32_t callbackType, int32_t successType) mutable {
1657         if (asyncContext == nullptr) {
1658             return;
1659         }
1660 
1661         asyncContext->callbackType = callbackType;
1662         asyncContext->successType = successType;
1663         auto container = AceEngine::Get().GetContainer(asyncContext->instanceId);
1664         if (!container) {
1665             return;
1666         }
1667 
1668         auto taskExecutor = container->GetTaskExecutor();
1669         if (!taskExecutor) {
1670             return;
1671         }
1672         taskExecutor->PostTask(
1673             [asyncContext]() {
1674                 if (asyncContext == nullptr) {
1675                     return;
1676                 }
1677 
1678                 if (!asyncContext->valid) {
1679                     return;
1680                 }
1681 
1682                 napi_handle_scope scope = nullptr;
1683                 napi_open_handle_scope(asyncContext->env, &scope);
1684                 if (scope == nullptr) {
1685                     return;
1686                 }
1687 
1688                 napi_value ret;
1689                 napi_value successIndex = nullptr;
1690                 napi_create_int32(asyncContext->env, asyncContext->successType, &successIndex);
1691                 napi_value indexObj = nullptr;
1692                 napi_create_object(asyncContext->env, &indexObj);
1693                 napi_set_named_property(asyncContext->env, indexObj, "index", successIndex);
1694                 napi_value result[2] = { 0 };
1695                 napi_create_object(asyncContext->env, &result[1]);
1696                 napi_set_named_property(asyncContext->env, result[1], "index", successIndex);
1697                 bool dialogResult = true;
1698                 switch (asyncContext->callbackType) {
1699                     case 0:
1700                         napi_get_undefined(asyncContext->env, &result[0]);
1701                         dialogResult = true;
1702                         break;
1703                     case 1:
1704                         napi_value message = nullptr;
1705                         napi_create_string_utf8(asyncContext->env, "cancel", strlen("cancel"), &message);
1706                         napi_create_error(asyncContext->env, nullptr, message, &result[0]);
1707                         dialogResult = false;
1708                         break;
1709                 }
1710                 if (asyncContext->deferred) {
1711                     if (dialogResult) {
1712                         napi_resolve_deferred(asyncContext->env, asyncContext->deferred, result[1]);
1713                     } else {
1714                         napi_reject_deferred(asyncContext->env, asyncContext->deferred, result[0]);
1715                     }
1716                 } else {
1717                     napi_value callback = nullptr;
1718                     napi_get_reference_value(asyncContext->env, asyncContext->callbackRef, &callback);
1719                     napi_call_function(
1720                         asyncContext->env, nullptr, callback, sizeof(result) / sizeof(result[0]), result, &ret);
1721                     napi_delete_reference(asyncContext->env, asyncContext->callbackRef);
1722                 }
1723                 napi_close_handle_scope(asyncContext->env, scope);
1724             },
1725             TaskExecutor::TaskType::JS, "ArkUIDialogParseDialogCallback");
1726         asyncContext = nullptr;
1727     };
1728 
1729     PromptDialogAttr promptDialogAttr = {
1730         .title = asyncContext->titleString,
1731         .message = asyncContext->messageString,
1732         .autoCancel = asyncContext->autoCancelBool,
1733         .showInSubWindow = asyncContext->showInSubWindowBool,
1734         .isModal = asyncContext->isModalBool,
1735         .enableHoverMode = asyncContext->enableHoverModeBool,
1736         .alignment = alignment,
1737         .offset = offset,
1738         .maskRect = maskRect,
1739         .backgroundColor = backgroundColor,
1740         .backgroundBlurStyle = backgroundBlurStyle,
1741         .blurStyleOption = blurStyleOption,
1742         .effectOption = effectOption,
1743         .shadow = shadowProps,
1744         .hoverModeArea = hoverModeArea,
1745         .onLanguageChange = onLanguageChange,
1746         .levelOrder = GetLevelOrderParam(asyncContext->env, asyncContext),
1747         .dialogLevelMode = dialogLevelMode,
1748         .dialogLevelUniqueId = dialogLevelUniqueId,
1749         .dialogImmersiveMode = dialogImmersiveMode,
1750     };
1751 
1752 #ifdef OHOS_STANDARD_SYSTEM
1753     // NG
1754     if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) {
1755         auto delegate = EngineHelper::GetCurrentDelegateSafely();
1756         if (delegate) {
1757             delegate->ShowDialog(promptDialogAttr, asyncContext->buttons, std::move(callBack), asyncContext->callbacks);
1758         } else {
1759             // throw internal error
1760             napi_value code = nullptr;
1761             std::string strCode = std::to_string(ERROR_CODE_INTERNAL_ERROR);
1762             napi_create_string_utf8(env, strCode.c_str(), strCode.length(), &code);
1763             napi_value msg = nullptr;
1764             std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "Can not get delegate.";
1765             napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg);
1766             napi_value error = nullptr;
1767             napi_create_error(env, code, msg, &error);
1768 
1769             if (asyncContext->deferred) {
1770                 napi_reject_deferred(env, asyncContext->deferred, error);
1771             } else {
1772                 napi_value ret1;
1773                 napi_value callback = nullptr;
1774                 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
1775                 napi_call_function(env, nullptr, callback, 1, &error, &ret1);
1776                 napi_delete_reference(env, asyncContext->callbackRef);
1777             }
1778         }
1779     } else if (SubwindowManager::GetInstance() != nullptr) {
1780         SubwindowManager::GetInstance()->ShowDialog(
1781             promptDialogAttr, asyncContext->buttons, std::move(callBack), asyncContext->callbacks);
1782     }
1783 #else
1784     auto delegate = EngineHelper::GetCurrentDelegateSafely();
1785     if (delegate) {
1786         delegate->ShowDialog(promptDialogAttr, asyncContext->buttons, std::move(callBack), asyncContext->callbacks);
1787     } else {
1788         // throw internal error
1789         napi_value code = nullptr;
1790         std::string strCode = std::to_string(ERROR_CODE_INTERNAL_ERROR);
1791         napi_create_string_utf8(env, strCode.c_str(), strCode.length(), &code);
1792         napi_value msg = nullptr;
1793         std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "UI execution context not found.";
1794         napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg);
1795         napi_value error = nullptr;
1796         napi_create_error(env, code, msg, &error);
1797 
1798         if (asyncContext->deferred) {
1799             napi_reject_deferred(env, asyncContext->deferred, error);
1800         } else {
1801             napi_value ret1;
1802             napi_value callback = nullptr;
1803             napi_get_reference_value(env, asyncContext->callbackRef, &callback);
1804             napi_call_function(env, nullptr, callback, 1, &error, &ret1);
1805             napi_delete_reference(env, asyncContext->callbackRef);
1806         }
1807     }
1808 #endif
1809     return result;
1810 }
1811 
JSPromptShowActionMenu(napi_env env,napi_callback_info info)1812 napi_value JSPromptShowActionMenu(napi_env env, napi_callback_info info)
1813 {
1814     TAG_LOGD(AceLogTag::ACE_DIALOG, "js prompt show action menu enter");
1815     size_t requireArgc = 1;
1816     size_t argc = 2;
1817     napi_value argv[3] = { 0 };
1818     napi_value thisVar = nullptr;
1819     void* data = nullptr;
1820     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1821     if (argc < requireArgc) {
1822         NapiThrow(
1823             env, "The number of parameters must be greater than or equal to 1.", ERROR_CODE_PARAM_INVALID);
1824         return nullptr;
1825     }
1826     if (thisVar == nullptr) {
1827         return nullptr;
1828     }
1829     napi_valuetype valueTypeOfThis = napi_undefined;
1830     napi_typeof(env, thisVar, &valueTypeOfThis);
1831     if (valueTypeOfThis == napi_undefined) {
1832         return nullptr;
1833     }
1834 
1835     auto asyncContext = std::make_shared<PromptAsyncContext>();
1836     asyncContext->env = env;
1837     asyncContext->instanceId = Container::CurrentIdSafely();
1838     LevelMode dialogLevelMode = LevelMode::OVERLAY;
1839     int32_t dialogLevelUniqueId = -1;
1840     ImmersiveMode dialogImmersiveMode = ImmersiveMode::DEFAULT;
1841     for (size_t i = 0; i < argc; i++) {
1842         napi_valuetype valueType = napi_undefined;
1843         napi_typeof(env, argv[i], &valueType);
1844         if (i == 0) {
1845             if (valueType != napi_object) {
1846                 DeleteContextAndThrowError(env, asyncContext, "The type of parameters is incorrect.");
1847                 return nullptr;
1848             }
1849             napi_get_named_property(env, argv[0], "title", &asyncContext->titleNApi);
1850             napi_get_named_property(env, argv[0], "showInSubWindow", &asyncContext->showInSubWindow);
1851             napi_get_named_property(env, argv[0], "isModal", &asyncContext->isModal);
1852             napi_get_named_property(env, argv[0], "levelMode", &asyncContext->dialogLevelModeApi);
1853             napi_get_named_property(env, argv[0], "levelUniqueId", &asyncContext->dialogLevelUniqueId);
1854             napi_get_named_property(env, argv[0], "immersiveMode", &asyncContext->dialogImmersiveModeApi);
1855             GetNapiString(env, asyncContext->titleNApi, asyncContext->titleString, valueType);
1856             if (!HasProperty(env, argv[0], "buttons")) {
1857                 DeleteContextAndThrowError(env, asyncContext, "Required input parameters are missing.");
1858                 return nullptr;
1859             }
1860             napi_get_named_property(env, argv[0], "buttons", &asyncContext->buttonsNApi);
1861             if (!ParseButtonsPara(env, asyncContext, SHOW_ACTION_MENU_BUTTON_NUM_MAX, true)) {
1862                 return nullptr;
1863             }
1864             napi_typeof(env, asyncContext->showInSubWindow, &valueType);
1865             if (valueType == napi_boolean) {
1866                 napi_get_value_bool(env, asyncContext->showInSubWindow, &asyncContext->showInSubWindowBool);
1867             }
1868             napi_typeof(env, asyncContext->isModal, &valueType);
1869             if (valueType == napi_boolean) {
1870                 napi_get_value_bool(env, asyncContext->isModal, &asyncContext->isModalBool);
1871             }
1872             GetDialogLevelModeAndUniqueId(env, asyncContext, dialogLevelMode, dialogLevelUniqueId, dialogImmersiveMode);
1873         } else if (valueType == napi_function) {
1874             napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
1875         } else {
1876             DeleteContextAndThrowError(env, asyncContext, "The type of parameters is incorrect.");
1877             return nullptr;
1878         }
1879     }
1880     napi_value result = nullptr;
1881     if (asyncContext->callbackRef == nullptr) {
1882         napi_create_promise(env, &asyncContext->deferred, &result);
1883     } else {
1884         napi_get_undefined(env, &result);
1885     }
1886 
1887     auto callBack = [asyncContext](int32_t callbackType, int32_t successType) mutable {
1888         if (asyncContext == nullptr) {
1889             return;
1890         }
1891 
1892         asyncContext->callbackType = callbackType;
1893         asyncContext->successType = successType;
1894         auto container = AceEngine::Get().GetContainer(asyncContext->instanceId);
1895         if (!container) {
1896             return;
1897         }
1898 
1899         auto taskExecutor = container->GetTaskExecutor();
1900         if (!taskExecutor) {
1901             return;
1902         }
1903         taskExecutor->PostTask(
1904             [asyncContext]() {
1905                 if (asyncContext == nullptr) {
1906                     return;
1907                 }
1908 
1909                 if (!asyncContext->valid) {
1910                     return;
1911                 }
1912 
1913                 napi_handle_scope scope = nullptr;
1914                 napi_open_handle_scope(asyncContext->env, &scope);
1915                 if (scope == nullptr) {
1916                     return;
1917                 }
1918 
1919                 napi_value ret;
1920                 napi_value successIndex = nullptr;
1921                 napi_create_int32(asyncContext->env, asyncContext->successType, &successIndex);
1922                 asyncContext->callbackSuccessString = "showActionMenu:ok";
1923                 napi_value indexObj = GetReturnObject(asyncContext->env, asyncContext->callbackSuccessString);
1924                 napi_set_named_property(asyncContext->env, indexObj, "index", successIndex);
1925                 napi_value result[2] = { 0 };
1926                 napi_create_object(asyncContext->env, &result[1]);
1927                 napi_set_named_property(asyncContext->env, result[1], "index", successIndex);
1928                 bool dialogResult = true;
1929                 switch (asyncContext->callbackType) {
1930                     case 0:
1931                         napi_get_undefined(asyncContext->env, &result[0]);
1932                         dialogResult = true;
1933                         break;
1934                     case 1:
1935                         napi_value message = nullptr;
1936                         napi_create_string_utf8(asyncContext->env, "cancel", strlen("cancel"), &message);
1937                         napi_create_error(asyncContext->env, nullptr, message, &result[0]);
1938                         dialogResult = false;
1939                         break;
1940                 }
1941                 if (asyncContext->deferred) {
1942                     if (dialogResult) {
1943                         napi_resolve_deferred(asyncContext->env, asyncContext->deferred, result[1]);
1944                     } else {
1945                         napi_reject_deferred(asyncContext->env, asyncContext->deferred, result[0]);
1946                     }
1947                 } else {
1948                     napi_value callback = nullptr;
1949                     napi_get_reference_value(asyncContext->env, asyncContext->callbackRef, &callback);
1950                     napi_call_function(
1951                         asyncContext->env, nullptr, callback, sizeof(result) / sizeof(result[0]), result, &ret);
1952                     napi_delete_reference(asyncContext->env, asyncContext->callbackRef);
1953                 }
1954                 napi_close_handle_scope(asyncContext->env, scope);
1955             },
1956             TaskExecutor::TaskType::JS, "ArkUIDialogParseActionMenuCallback");
1957         asyncContext = nullptr;
1958     };
1959 
1960     DimensionRect rect;
1961     rect.SetOffset(DimensionOffset(CalcDimension(0, DimensionUnit::VP), CalcDimension(0, DimensionUnit::VP)));
1962     rect.SetSize(DimensionSize(CalcDimension(1, DimensionUnit::PERCENT), CalcDimension(1, DimensionUnit::PERCENT)));
1963 
1964     PromptDialogAttr promptDialogAttr = {
1965         .title = asyncContext->titleString,
1966         .showInSubWindow = asyncContext->showInSubWindowBool,
1967         .isModal = asyncContext->isModalBool,
1968         .maskRect = rect,
1969         .dialogLevelMode = dialogLevelMode,
1970         .dialogLevelUniqueId = dialogLevelUniqueId,
1971         .dialogImmersiveMode = dialogImmersiveMode,
1972     };
1973 #ifdef OHOS_STANDARD_SYSTEM
1974     if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) {
1975         auto delegate = EngineHelper::GetCurrentDelegateSafely();
1976         if (delegate) {
1977             delegate->ShowActionMenu(promptDialogAttr, asyncContext->buttons, std::move(callBack));
1978         } else {
1979             napi_value code = nullptr;
1980             std::string strCode = std::to_string(ERROR_CODE_INTERNAL_ERROR);
1981             napi_create_string_utf8(env, strCode.c_str(), strCode.length(), &code);
1982             napi_value msg = nullptr;
1983             std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "Can not get delegate.";
1984             napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg);
1985             napi_value error = nullptr;
1986             napi_create_error(env, code, msg, &error);
1987 
1988             if (asyncContext->deferred) {
1989                 napi_reject_deferred(env, asyncContext->deferred, error);
1990             } else {
1991                 napi_value ret1;
1992                 napi_value callback = nullptr;
1993                 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
1994                 napi_call_function(env, nullptr, callback, 1, &error, &ret1);
1995                 napi_delete_reference(env, asyncContext->callbackRef);
1996             }
1997         }
1998     } else if (SubwindowManager::GetInstance() != nullptr) {
1999         SubwindowManager::GetInstance()->ShowActionMenu(
2000             asyncContext->titleString, asyncContext->buttons, std::move(callBack));
2001     }
2002 #else
2003     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2004     if (delegate) {
2005         delegate->ShowActionMenu(promptDialogAttr, asyncContext->buttons, std::move(callBack));
2006     } else {
2007         napi_value code = nullptr;
2008         std::string strCode = std::to_string(ERROR_CODE_INTERNAL_ERROR);
2009         napi_create_string_utf8(env, strCode.c_str(), strCode.length(), &code);
2010         napi_value msg = nullptr;
2011         std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "UI execution context not found.";
2012         napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg);
2013         napi_value error = nullptr;
2014         napi_create_error(env, code, msg, &error);
2015 
2016         if (asyncContext->deferred) {
2017             napi_reject_deferred(env, asyncContext->deferred, error);
2018         } else {
2019             napi_value ret1;
2020             napi_value callback = nullptr;
2021             napi_get_reference_value(env, asyncContext->callbackRef, &callback);
2022             napi_call_function(env, nullptr, callback, 1, &error, &ret1);
2023             napi_delete_reference(env, asyncContext->callbackRef);
2024         }
2025     }
2026 #endif
2027     return result;
2028 }
2029 
JSRemoveCustomDialog(napi_env env,napi_callback_info info)2030 napi_value JSRemoveCustomDialog(napi_env env, napi_callback_info info)
2031 {
2032     size_t argc = 1;
2033     napi_value argv = nullptr;
2034     napi_value thisVar = nullptr;
2035     void* data = nullptr;
2036     napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
2037     int32_t instanceId = Container::CurrentIdSafely();
2038     if (data) {
2039         int32_t* instanceIdPtr = reinterpret_cast<int32_t*>(data);
2040         instanceId = *instanceIdPtr;
2041     }
2042     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2043     if (delegate) {
2044         delegate->RemoveCustomDialog(instanceId);
2045     }
2046     return nullptr;
2047 }
2048 
ParseDialogCallback(std::shared_ptr<PromptAsyncContext> & asyncContext,std::function<void (const int32_t & info,const int32_t & instanceId)> & onWillDismiss)2049 void ParseDialogCallback(std::shared_ptr<PromptAsyncContext>& asyncContext,
2050     std::function<void(const int32_t& info, const int32_t& instanceId)>& onWillDismiss)
2051 {
2052     onWillDismiss = [env = asyncContext->env, onWillDismissRef = asyncContext->onWillDismissRef]
2053         (const int32_t& info, const int32_t& instanceId) {
2054         if (onWillDismissRef) {
2055             napi_handle_scope scope = nullptr;
2056             napi_open_handle_scope(env, &scope);
2057             napi_value onWillDismissFunc = nullptr;
2058             napi_value value = nullptr;
2059             napi_value funcValue = nullptr;
2060             napi_value paramObj = nullptr;
2061             napi_create_object(env, &paramObj);
2062 
2063             napi_value id = nullptr;
2064             napi_create_int32(env, instanceId, &id);
2065             napi_create_function(env, "dismiss", strlen("dismiss"), JSRemoveCustomDialog, id, &funcValue);
2066             napi_set_named_property(env, paramObj, "dismiss", funcValue);
2067 
2068             napi_create_int32(env, info, &value);
2069             napi_set_named_property(env, paramObj, "reason", value);
2070             napi_get_reference_value(env, onWillDismissRef, &onWillDismissFunc);
2071             napi_call_function(env, nullptr, onWillDismissFunc, 1, &paramObj, nullptr);
2072             napi_close_handle_scope(env, scope);
2073         }
2074     };
2075 }
2076 
GetDialogLifeCycleCallback(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)2077 PromptDialogAttr GetDialogLifeCycleCallback(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
2078 {
2079     auto onDidAppear = [env = asyncContext->env, onDidAppearRef = asyncContext->onDidAppearRef]() {
2080         if (onDidAppearRef) {
2081             napi_handle_scope scope = nullptr;
2082             napi_open_handle_scope(env, &scope);
2083             napi_value onDidAppearFunc = nullptr;
2084             napi_get_reference_value(env, onDidAppearRef, &onDidAppearFunc);
2085             napi_call_function(env, nullptr, onDidAppearFunc, 0, nullptr, nullptr);
2086             napi_delete_reference(env, onDidAppearRef);
2087             napi_close_handle_scope(env, scope);
2088         }
2089     };
2090     auto onDidDisappear = [env = asyncContext->env, onDidDisappearRef = asyncContext->onDidDisappearRef]() {
2091         if (onDidDisappearRef) {
2092             napi_handle_scope scope = nullptr;
2093             napi_open_handle_scope(env, &scope);
2094             napi_value onDidDisappearFunc = nullptr;
2095             napi_get_reference_value(env, onDidDisappearRef, &onDidDisappearFunc);
2096             napi_call_function(env, nullptr, onDidDisappearFunc, 0, nullptr, nullptr);
2097             napi_delete_reference(env, onDidDisappearRef);
2098             napi_close_handle_scope(env, scope);
2099         }
2100     };
2101     auto onWillAppear = [env = asyncContext->env, onWillAppearRef = asyncContext->onWillAppearRef]() {
2102         if (onWillAppearRef) {
2103             napi_handle_scope scope = nullptr;
2104             napi_open_handle_scope(env, &scope);
2105             napi_value onWillAppearFunc = nullptr;
2106             napi_get_reference_value(env, onWillAppearRef, &onWillAppearFunc);
2107             napi_call_function(env, nullptr, onWillAppearFunc, 0, nullptr, nullptr);
2108             napi_delete_reference(env, onWillAppearRef);
2109             napi_close_handle_scope(env, scope);
2110         }
2111     };
2112     auto onWillDisappear = [env = asyncContext->env, onWillDisappearRef = asyncContext->onWillDisappearRef]() {
2113         if (onWillDisappearRef) {
2114             napi_handle_scope scope = nullptr;
2115             napi_open_handle_scope(env, &scope);
2116             napi_value onWillDisappearFunc = nullptr;
2117             napi_get_reference_value(env, onWillDisappearRef, &onWillDisappearFunc);
2118             napi_call_function(env, nullptr, onWillDisappearFunc, 0, nullptr, nullptr);
2119             napi_delete_reference(env, onWillDisappearRef);
2120             napi_close_handle_scope(env, scope);
2121         }
2122     };
2123     PromptDialogAttr promptDialogAttr = {
2124         .onDidAppear =  std::move(onDidAppear),
2125         .onDidDisappear = std::move(onDidDisappear),
2126         .onWillAppear = std::move(onWillAppear),
2127         .onWillDisappear = std::move(onWillDisappear) };
2128     return promptDialogAttr;
2129 }
2130 
ParseBorderColorAndStyle(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,std::optional<NG::BorderWidthProperty> & borderWidthProps,std::optional<NG::BorderColorProperty> & borderColorProps,std::optional<NG::BorderStyleProperty> & borderStyleProps)2131 void ParseBorderColorAndStyle(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext,
2132     std::optional<NG::BorderWidthProperty>& borderWidthProps, std::optional<NG::BorderColorProperty>& borderColorProps,
2133     std::optional<NG::BorderStyleProperty>& borderStyleProps)
2134 {
2135     if (borderWidthProps.has_value()) {
2136         borderColorProps = GetBorderColorProps(env, asyncContext);
2137         if (!borderColorProps.has_value()) {
2138             NG::BorderColorProperty borderColor;
2139             borderColor.SetColor(Color::BLACK);
2140             borderColorProps = borderColor;
2141         }
2142         borderStyleProps = GetBorderStyleProps(env, asyncContext);
2143         if (!borderStyleProps.has_value()) {
2144             borderStyleProps = NG::BorderStyleProperty(
2145                 { BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID, BorderStyle::SOLID });
2146         }
2147     }
2148 }
2149 
GetTransitionProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)2150 RefPtr<NG::ChainedTransitionEffect> GetTransitionProps(
2151     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
2152 {
2153     RefPtr<NG::ChainedTransitionEffect> transitionEffect = nullptr;
2154     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2155     if (delegate) {
2156         napi_valuetype valueType = napi_undefined;
2157         napi_typeof(env, asyncContext->transitionApi, &valueType);
2158         if (valueType == napi_object) {
2159             transitionEffect = delegate->GetTransitionEffect(asyncContext->transitionApi);
2160         }
2161     }
2162     return transitionEffect;
2163 }
2164 
GetDialogTransitionProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)2165 RefPtr<NG::ChainedTransitionEffect> GetDialogTransitionProps(
2166     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
2167 {
2168     RefPtr<NG::ChainedTransitionEffect> dialogTransitionEffect = nullptr;
2169     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2170     if (delegate) {
2171         napi_valuetype valueType = napi_undefined;
2172         napi_typeof(env, asyncContext->dialogTransitionApi, &valueType);
2173         if (valueType == napi_object) {
2174             dialogTransitionEffect = delegate->GetTransitionEffect(asyncContext->dialogTransitionApi);
2175         }
2176     }
2177     return dialogTransitionEffect;
2178 }
2179 
GetMaskTransitionProps(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)2180 RefPtr<NG::ChainedTransitionEffect> GetMaskTransitionProps(
2181     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
2182 {
2183     RefPtr<NG::ChainedTransitionEffect> maskTransitionEffect = nullptr;
2184     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2185     if (delegate) {
2186         napi_valuetype valueType = napi_undefined;
2187         napi_typeof(env, asyncContext->maskTransitionApi, &valueType);
2188         if (valueType == napi_object) {
2189             maskTransitionEffect = delegate->GetTransitionEffect(asyncContext->maskTransitionApi);
2190         }
2191     }
2192     return maskTransitionEffect;
2193 }
2194 
GetCustomBuilder(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)2195 std::function<void()> GetCustomBuilder(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
2196 {
2197     auto builder = [env = asyncContext->env, builderRef = asyncContext->builderRef]() {
2198         if (builderRef) {
2199             napi_value builderFunc = nullptr;
2200             napi_get_reference_value(env, builderRef, &builderFunc);
2201             napi_call_function(env, nullptr, builderFunc, 0, nullptr, nullptr);
2202             napi_delete_reference(env, builderRef);
2203         }
2204     };
2205     return builder;
2206 }
2207 
GetCustomBuilderWithId(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)2208 std::function<void(const int32_t& dialogId)> GetCustomBuilderWithId(
2209     napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
2210 {
2211     auto builder = [env = asyncContext->env, builderRef = asyncContext->builderRef](const int32_t dialogId) {
2212         if (builderRef) {
2213             napi_value builderFunc = nullptr;
2214             napi_get_reference_value(env, builderRef, &builderFunc);
2215             napi_value dialogIdArg = nullptr;
2216             napi_create_int32(env, dialogId, &dialogIdArg);
2217             napi_call_function(env, nullptr, builderFunc, 1, &dialogIdArg, nullptr);
2218             napi_delete_reference(env, builderRef);
2219         }
2220     };
2221     return builder;
2222 }
2223 
GetFocusableParam(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext)2224 bool GetFocusableParam(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext)
2225 {
2226     bool focusable = true;
2227     napi_valuetype valueType = napi_undefined;
2228     napi_typeof(env, asyncContext->focusableApi, &valueType);
2229     if (valueType != napi_boolean) {
2230         return focusable;
2231     }
2232 
2233     napi_get_value_bool(env, asyncContext->focusableApi, &focusable);
2234     return focusable;
2235 }
2236 
GetPromptActionDialog(napi_env env,const std::shared_ptr<PromptAsyncContext> & asyncContext,std::function<void (const int32_t & info,const int32_t & instanceId)> onWillDismiss)2237 PromptDialogAttr GetPromptActionDialog(napi_env env, const std::shared_ptr<PromptAsyncContext>& asyncContext,
2238     std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismiss)
2239 {
2240     std::optional<DialogAlignment> alignment;
2241     std::optional<DimensionOffset> offset;
2242     std::optional<DimensionRect> maskRect;
2243     std::optional<int32_t> backgroundBlurStyle;
2244     std::optional<HoverModeAreaType> hoverModeArea;
2245     std::optional<BlurStyleOption> blurStyleOption;
2246     std::optional<EffectOption> effectOption;
2247     GetNapiDialogProps(env, asyncContext, alignment, offset, maskRect);
2248     GetNapiBlurStyleAndHoverModeProps(env, asyncContext, backgroundBlurStyle, hoverModeArea);
2249     GetBackgroundBlurStyleOption(env, asyncContext, blurStyleOption);
2250     GetBackgroundEffect(env, asyncContext, effectOption);
2251     auto borderWidthProps = GetBorderWidthProps(env, asyncContext);
2252     std::optional<NG::BorderColorProperty> borderColorProps;
2253     std::optional<NG::BorderStyleProperty> borderStyleProps;
2254     ParseBorderColorAndStyle(env, asyncContext, borderWidthProps, borderColorProps, borderStyleProps);
2255     auto backgroundColorProps = GetColorProps(env, asyncContext->backgroundColorApi);
2256     auto builder = GetCustomBuilder(env, asyncContext);
2257     auto* nodePtr = reinterpret_cast<OHOS::Ace::NG::UINode*>(asyncContext->nativePtr);
2258     auto maskColorProps = GetColorProps(env, asyncContext->maskColorApi);
2259     auto transitionEffectProps = GetTransitionProps(env, asyncContext);
2260     auto dialogTransitionEffectProps = GetDialogTransitionProps(env, asyncContext);
2261     auto maskTransitionEffectProps = GetMaskTransitionProps(env, asyncContext);
2262     PromptDialogAttr lifeCycleAttr = GetDialogLifeCycleCallback(env, asyncContext);
2263     int32_t mode = GetDialogKeyboardAvoidMode(env, asyncContext->keyboardAvoidModeApi);
2264     LevelMode dialogLevelMode = LevelMode::OVERLAY;
2265     int32_t dialogLevelUniqueId = -1;
2266     ImmersiveMode dialogImmersiveMode = ImmersiveMode::DEFAULT;
2267     GetDialogLevelModeAndUniqueId(env, asyncContext, dialogLevelMode, dialogLevelUniqueId, dialogImmersiveMode);
2268     PromptDialogAttr promptDialogAttr = { .autoCancel = asyncContext->autoCancelBool,
2269         .showInSubWindow = asyncContext->showInSubWindowBool,
2270         .isModal = asyncContext->isModalBool,
2271         .enableHoverMode = asyncContext->enableHoverModeBool,
2272         .customBuilder = std::move(builder),
2273         .customOnWillDismiss = std::move(onWillDismiss),
2274         .alignment = alignment,
2275         .offset = offset,
2276         .maskRect = maskRect,
2277         .backgroundColor = backgroundColorProps,
2278         .backgroundBlurStyle = backgroundBlurStyle,
2279         .blurStyleOption = blurStyleOption,
2280         .effectOption = effectOption,
2281         .borderWidth = borderWidthProps,
2282         .borderColor = borderColorProps,
2283         .borderStyle = borderStyleProps,
2284         .borderRadius = GetBorderRadiusProps(env, asyncContext),
2285         .shadow = GetShadowProps(env, asyncContext),
2286         .width = GetNapiDialogWidthProps(env, asyncContext),
2287         .height = GetNapiDialogHeightProps(env, asyncContext),
2288         .hoverModeArea = hoverModeArea,
2289         .contentNode = AceType::WeakClaim(nodePtr),
2290         .maskColor = maskColorProps,
2291         .transitionEffect = transitionEffectProps,
2292         .dialogTransitionEffect = dialogTransitionEffectProps,
2293         .maskTransitionEffect = maskTransitionEffectProps,
2294         .onDidAppear = lifeCycleAttr.onDidAppear,
2295         .onDidDisappear = lifeCycleAttr.onDidDisappear,
2296         .onWillAppear = lifeCycleAttr.onWillAppear,
2297         .onWillDisappear = lifeCycleAttr.onWillDisappear,
2298         .keyboardAvoidMode = KEYBOARD_AVOID_MODE[mode],
2299         .keyboardAvoidDistance = GetKeyboardAvoidDistanceProps(env, asyncContext),
2300         .levelOrder = GetLevelOrderParam(env, asyncContext),
2301         .dialogLevelMode = dialogLevelMode,
2302         .dialogLevelUniqueId = dialogLevelUniqueId,
2303         .dialogImmersiveMode = dialogImmersiveMode,
2304         .focusable = GetFocusableParam(env, asyncContext),
2305     };
2306     return promptDialogAttr;
2307 }
2308 
GetErrorMsg(int32_t errorCode)2309 std::string GetErrorMsg(int32_t errorCode)
2310 {
2311     std::string strMsg;
2312     if (errorCode == ERROR_CODE_DIALOG_CONTENT_ERROR) {
2313         strMsg = ErrorToMessage(ERROR_CODE_DIALOG_CONTENT_ERROR) + "The ComponentContent is incorrect.";
2314     } else if (errorCode == ERROR_CODE_DIALOG_CONTENT_ALREADY_EXIST) {
2315         strMsg = ErrorToMessage(ERROR_CODE_DIALOG_CONTENT_ALREADY_EXIST) +
2316             "The ComponentContent has already been opened.";
2317     } else if (errorCode == ERROR_CODE_DIALOG_CONTENT_NOT_FOUND) {
2318         strMsg = ErrorToMessage(ERROR_CODE_DIALOG_CONTENT_NOT_FOUND) + "The ComponentContent cannot be found.";
2319     } else {
2320         strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "Build custom dialog failed.";
2321     }
2322     return strMsg;
2323 }
2324 
GetErrorCode(int32_t errorCode)2325 std::string GetErrorCode(int32_t errorCode)
2326 {
2327     std::string strCode;
2328     if (errorCode == ERROR_CODE_DIALOG_CONTENT_ERROR) {
2329         strCode = std::to_string(ERROR_CODE_DIALOG_CONTENT_ERROR);
2330     } else if (errorCode == ERROR_CODE_DIALOG_CONTENT_ALREADY_EXIST) {
2331         strCode = std::to_string(ERROR_CODE_DIALOG_CONTENT_ALREADY_EXIST);
2332     } else if (errorCode == ERROR_CODE_DIALOG_CONTENT_NOT_FOUND) {
2333         strCode = std::to_string(ERROR_CODE_DIALOG_CONTENT_NOT_FOUND);
2334     } else {
2335         strCode = std::to_string(ERROR_CODE_INTERNAL_ERROR);
2336     }
2337     return strCode;
2338 }
2339 
ParseCustomDialogContentCallback(std::shared_ptr<PromptAsyncContext> & asyncContext,std::function<void (int32_t)> & callBack)2340 void ParseCustomDialogContentCallback(std::shared_ptr<PromptAsyncContext>& asyncContext,
2341     std::function<void(int32_t)>& callBack)
2342 {
2343     callBack = [asyncContext](int32_t errorCode) mutable {
2344         if (!asyncContext) {
2345             return;
2346         }
2347         auto container = AceEngine::Get().GetContainer(asyncContext->instanceId);
2348         if (!container) {
2349             return;
2350         }
2351         auto taskExecutor = container->GetTaskExecutor();
2352         if (!taskExecutor) {
2353             return;
2354         }
2355         taskExecutor->PostTask(
2356             [asyncContext, errorCode]() {
2357                 if (asyncContext == nullptr || !asyncContext->valid) {
2358                     return;
2359                 }
2360                 napi_handle_scope scope = nullptr;
2361                 napi_open_handle_scope(asyncContext->env, &scope);
2362                 if (scope == nullptr) {
2363                     return;
2364                 }
2365                 if (!asyncContext->deferred) {
2366                     return;
2367                 }
2368                 if (errorCode == ERROR_CODE_NO_ERROR) {
2369                     napi_value result = nullptr;
2370                     napi_get_undefined(asyncContext->env, &result);
2371                     napi_resolve_deferred(asyncContext->env, asyncContext->deferred, result);
2372                 } else {
2373                     std::string strMsg = GetErrorMsg(errorCode);
2374                     std::string strCode = GetErrorCode(errorCode);
2375                     napi_value code = nullptr;
2376                     napi_create_string_utf8(asyncContext->env, strCode.c_str(), strCode.length(), &code);
2377                     napi_value msg = nullptr;
2378                     napi_create_string_utf8(asyncContext->env, strMsg.c_str(), strMsg.length(), &msg);
2379                     napi_value error = nullptr;
2380                     napi_create_error(asyncContext->env, code, msg, &error);
2381                     napi_reject_deferred(asyncContext->env, asyncContext->deferred, error);
2382                 }
2383                 napi_close_handle_scope(asyncContext->env, scope);
2384             },
2385             TaskExecutor::TaskType::JS, "ArkUIDialogParseCustomDialogContentCallback");
2386         asyncContext = nullptr;
2387     };
2388 }
2389 
ParseCustomDialogIdCallback(std::shared_ptr<PromptAsyncContext> & asyncContext,std::function<void (int32_t)> & callBack)2390 void ParseCustomDialogIdCallback(std::shared_ptr<PromptAsyncContext>& asyncContext,
2391     std::function<void(int32_t)>& callBack)
2392 {
2393     callBack = [asyncContext](int32_t dialogId) mutable {
2394         if (!asyncContext) {
2395             return;
2396         }
2397         auto container = AceEngine::Get().GetContainer(asyncContext->instanceId);
2398         if (!container) {
2399             return;
2400         }
2401         auto taskExecutor = container->GetTaskExecutor();
2402         if (!taskExecutor) {
2403             return;
2404         }
2405         taskExecutor->PostTask(
2406             [asyncContext, dialogId]() {
2407                 if (asyncContext == nullptr || !asyncContext->valid) {
2408                     return;
2409                 }
2410 
2411                 napi_handle_scope scope = nullptr;
2412                 napi_open_handle_scope(asyncContext->env, &scope);
2413                 if (scope == nullptr) {
2414                     return;
2415                 }
2416 
2417                 napi_value ret = nullptr;
2418                 if (!asyncContext->deferred) {
2419                     return;
2420                 }
2421                 if (dialogId > 0) {
2422                     napi_create_int32(asyncContext->env, dialogId, &ret);
2423                     napi_resolve_deferred(asyncContext->env, asyncContext->deferred, ret);
2424                 } else {
2425                     std::string strMsg = GetErrorMsg(dialogId);
2426                     std::string strCode = GetErrorCode(dialogId);
2427                     napi_value code = nullptr;
2428                     napi_create_string_utf8(asyncContext->env, strCode.c_str(), strCode.length(), &code);
2429                     napi_value msg = nullptr;
2430                     napi_create_string_utf8(asyncContext->env, strMsg.c_str(), strMsg.length(), &msg);
2431                     napi_value error = nullptr;
2432                     napi_create_error(asyncContext->env, code, msg, &error);
2433                     napi_reject_deferred(asyncContext->env, asyncContext->deferred, error);
2434                 }
2435                 napi_close_handle_scope(asyncContext->env, scope);
2436             },
2437             TaskExecutor::TaskType::JS, "ArkUIDialogParseCustomDialogIdCallback");
2438         asyncContext = nullptr;
2439     };
2440 }
2441 
OpenCustomDialog(napi_env env,std::shared_ptr<PromptAsyncContext> & asyncContext,PromptDialogAttr & promptDialogAttr,std::function<void (int32_t)> & openCallback)2442 void OpenCustomDialog(napi_env env, std::shared_ptr<PromptAsyncContext>& asyncContext,
2443     PromptDialogAttr& promptDialogAttr, std::function<void(int32_t)>& openCallback)
2444 {
2445     promptDialogAttr.isUserCreatedDialog = true;
2446 #ifdef OHOS_STANDARD_SYSTEM
2447     // NG
2448     if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) {
2449         auto delegate = EngineHelper::GetCurrentDelegateSafely();
2450         if (delegate) {
2451             delegate->OpenCustomDialog(promptDialogAttr, std::move(openCallback));
2452         } else {
2453             // throw internal error
2454             std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "Can not get delegate.";
2455             JSPromptThrowInterError(env, asyncContext, strMsg);
2456         }
2457     } else if (SubwindowManager::GetInstance() != nullptr) {
2458         SubwindowManager::GetInstance()->OpenCustomDialog(promptDialogAttr, std::move(openCallback));
2459     }
2460 #else
2461     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2462     if (delegate) {
2463         delegate->OpenCustomDialog(promptDialogAttr, std::move(openCallback));
2464     } else {
2465         // throw internal error
2466         std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "UI execution context not found.";
2467         JSPromptThrowInterError(env, asyncContext, strMsg);
2468     }
2469 #endif
2470 }
2471 
JSPromptOpenCustomDialog(napi_env env,napi_callback_info info)2472 napi_value JSPromptOpenCustomDialog(napi_env env, napi_callback_info info)
2473 {
2474     size_t argc = 2;
2475     napi_value argv[2] = { nullptr };
2476     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
2477     if (argc < 1) {
2478         NapiThrow(
2479             env, "The number of parameters must be greater than or equal to 1.", ERROR_CODE_PARAM_INVALID);
2480         return nullptr;
2481     }
2482 
2483     auto asyncContext = std::make_shared<PromptAsyncContext>();
2484     asyncContext->env = env;
2485     asyncContext->instanceId = Container::CurrentIdSafely();
2486     bool parseOK = JSPromptParseParam(env, argc, argv, asyncContext);
2487     if (!parseOK) {
2488         return nullptr;
2489     }
2490     napi_value result = nullptr;
2491     napi_create_promise(env, &asyncContext->deferred, &result);
2492 
2493     std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismiss = nullptr;
2494     if (asyncContext->onWillDismissRef) {
2495         ParseDialogCallback(asyncContext, onWillDismiss);
2496     }
2497     std::function<void(int32_t)> openCallback = nullptr;
2498     PromptDialogAttr promptDialogAttr = GetPromptActionDialog(env, asyncContext, onWillDismiss);
2499     if (!asyncContext->builderRef) {
2500         ParseCustomDialogContentCallback(asyncContext, openCallback);
2501         promptDialogAttr.customStyle = true;
2502         promptDialogAttr.customBuilder = nullptr;
2503     } else {
2504         ParseCustomDialogIdCallback(asyncContext, openCallback);
2505     }
2506 
2507     OpenCustomDialog(env, asyncContext, promptDialogAttr, openCallback);
2508 
2509     return result;
2510 }
2511 
ParseBaseDialogOptionsEvent(napi_env env,napi_value arg,std::shared_ptr<PromptAsyncContext> & asyncContext)2512 void ParseBaseDialogOptionsEvent(napi_env env, napi_value arg, std::shared_ptr<PromptAsyncContext>& asyncContext)
2513 {
2514     napi_get_named_property(env, arg, "onWillDismiss", &asyncContext->onWillDismiss);
2515     napi_valuetype valueType = napi_undefined;
2516     napi_typeof(env, asyncContext->onWillDismiss, &valueType);
2517     if (valueType == napi_function) {
2518         napi_create_reference(env, asyncContext->onWillDismiss, 1, &asyncContext->onWillDismissRef);
2519     }
2520     napi_get_named_property(env, arg, "onDidAppear", &asyncContext->onDidAppear);
2521     napi_typeof(env, asyncContext->onDidAppear, &valueType);
2522     if (valueType == napi_function) {
2523         napi_create_reference(env, asyncContext->onDidAppear, 1, &asyncContext->onDidAppearRef);
2524     }
2525     napi_get_named_property(env, arg, "onDidDisappear", &asyncContext->onDidDisappear);
2526     napi_typeof(env, asyncContext->onDidDisappear, &valueType);
2527     if (valueType == napi_function) {
2528         napi_create_reference(env, asyncContext->onDidDisappear, 1, &asyncContext->onDidDisappearRef);
2529     }
2530     napi_get_named_property(env, arg, "onWillAppear", &asyncContext->onWillAppear);
2531     napi_typeof(env, asyncContext->onWillAppear, &valueType);
2532     if (valueType == napi_function) {
2533         napi_create_reference(env, asyncContext->onWillAppear, 1, &asyncContext->onWillAppearRef);
2534     }
2535     napi_get_named_property(env, arg, "onWillDisappear", &asyncContext->onWillDisappear);
2536     napi_typeof(env, asyncContext->onWillDisappear, &valueType);
2537     if (valueType == napi_function) {
2538         napi_create_reference(env, asyncContext->onWillDisappear, 1, &asyncContext->onWillDisappearRef);
2539     }
2540 }
2541 
ParseBaseDialogOptions(napi_env env,napi_value arg,std::shared_ptr<PromptAsyncContext> & asyncContext)2542 void ParseBaseDialogOptions(napi_env env, napi_value arg, std::shared_ptr<PromptAsyncContext>& asyncContext)
2543 {
2544     napi_get_named_property(env, arg, "maskRect", &asyncContext->maskRectApi);
2545     napi_get_named_property(env, arg, "alignment", &asyncContext->alignmentApi);
2546     napi_get_named_property(env, arg, "offset", &asyncContext->offsetApi);
2547     napi_get_named_property(env, arg, "showInSubWindow", &asyncContext->showInSubWindow);
2548     napi_valuetype valueType = napi_undefined;
2549     napi_typeof(env, asyncContext->showInSubWindow, &valueType);
2550     if (valueType == napi_boolean) {
2551         napi_get_value_bool(env, asyncContext->showInSubWindow, &asyncContext->showInSubWindowBool);
2552     }
2553     napi_get_named_property(env, arg, "isModal", &asyncContext->isModal);
2554     napi_typeof(env, asyncContext->isModal, &valueType);
2555     if (valueType == napi_boolean) {
2556         napi_get_value_bool(env, asyncContext->isModal, &asyncContext->isModalBool);
2557     }
2558     napi_get_named_property(env, arg, "autoCancel", &asyncContext->autoCancel);
2559     napi_typeof(env, asyncContext->autoCancel, &valueType);
2560     if (valueType == napi_boolean) {
2561         napi_get_value_bool(env, asyncContext->autoCancel, &asyncContext->autoCancelBool);
2562     }
2563     napi_get_named_property(env, arg, "transition", &asyncContext->transitionApi);
2564     napi_get_named_property(env, arg, "dialogTransition", &asyncContext->dialogTransitionApi);
2565     napi_get_named_property(env, arg, "maskTransition", &asyncContext->maskTransitionApi);
2566     napi_get_named_property(env, arg, "maskColor", &asyncContext->maskColorApi);
2567     napi_get_named_property(env, arg, "keyboardAvoidMode", &asyncContext->keyboardAvoidModeApi);
2568     napi_get_named_property(env, arg, "keyboardAvoidDistance", &asyncContext->keyboardAvoidDistanceApi);
2569     napi_get_named_property(env, arg, "enableHoverMode", &asyncContext->enableHoverMode);
2570     napi_typeof(env, asyncContext->enableHoverMode, &valueType);
2571     if (valueType == napi_boolean) {
2572         napi_get_value_bool(env, asyncContext->enableHoverMode, &asyncContext->enableHoverModeBool);
2573     }
2574     napi_get_named_property(env, arg, "hoverModeArea", &asyncContext->hoverModeAreaApi);
2575     napi_get_named_property(env, arg, "levelOrder", &asyncContext->levelOrderApi);
2576     napi_get_named_property(env, arg, "backgroundBlurStyleOptions", &asyncContext->blurStyleOptionApi);
2577     napi_get_named_property(env, arg, "backgroundEffect", &asyncContext->effectOptionApi);
2578     napi_get_named_property(env, arg, "levelMode", &asyncContext->dialogLevelModeApi);
2579     napi_get_named_property(env, arg, "levelUniqueId", &asyncContext->dialogLevelUniqueId);
2580     napi_get_named_property(env, arg, "immersiveMode", &asyncContext->dialogImmersiveModeApi);
2581     napi_get_named_property(env, arg, "focusable", &asyncContext->focusableApi);
2582 
2583     ParseBaseDialogOptionsEvent(env, arg, asyncContext);
2584 }
2585 
GetDialogCallback(PromptDialogController * controller)2586 std::function<void(RefPtr<NG::FrameNode> dialogNode)> GetDialogCallback(PromptDialogController* controller)
2587 {
2588     auto builder = [controller](RefPtr<NG::FrameNode> dialogNode) {
2589         if (controller) {
2590             controller->SetNode(dialogNode);
2591         }
2592     };
2593     return builder;
2594 }
2595 
JSPromptOpenCustomDialogWithController(napi_env env,napi_callback_info info)2596 napi_value JSPromptOpenCustomDialogWithController(napi_env env, napi_callback_info info)
2597 {
2598     size_t argc = OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_TOTAL;
2599     napi_value argv[OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_TOTAL] = { nullptr };
2600     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
2601     if (argc < OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_MAND_COUNT
2602         || argc > OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_TOTAL) {
2603         NapiThrow(env, "The number of parameters must be between 2 and 3.", ERROR_CODE_PARAM_INVALID);
2604         return nullptr;
2605     }
2606 
2607     for (size_t i = 0; i < argc; i++) {
2608         napi_valuetype valueType = napi_undefined;
2609         napi_typeof(env, argv[i], &valueType);
2610         if (valueType != napi_object) {
2611             NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2612             return nullptr;
2613         }
2614     }
2615 
2616     auto asyncContext = std::make_shared<PromptAsyncContext>();
2617     asyncContext->env = env;
2618     asyncContext->instanceId = Container::CurrentIdSafely();
2619     auto nodeResult = napi_get_named_property(env, argv[0], "nodePtr_", &asyncContext->frameNodePtr);
2620     if (nodeResult != napi_ok) {
2621         NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2622         return nullptr;
2623     }
2624     napi_get_value_external(env, asyncContext->frameNodePtr, &asyncContext->nativePtr);
2625 
2626     PromptDialogController* controller = nullptr;
2627     napi_unwrap(env, argv[OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_INDEX_CONTROLLER], (void**)&controller);
2628     if (!controller) {
2629         NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2630         return nullptr;
2631     }
2632 
2633     if (argc > OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_INDEX_OPTIONS) {
2634         ParseBaseDialogOptions(env, argv[OPEN_CUSTOM_DIALOG_WITH_CONTROLLER_PARAM_INDEX_OPTIONS], asyncContext);
2635     }
2636 
2637     napi_value result = nullptr;
2638     napi_create_promise(env, &asyncContext->deferred, &result);
2639 
2640     std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismiss = nullptr;
2641     if (asyncContext->onWillDismissRef) {
2642         ParseDialogCallback(asyncContext, onWillDismiss);
2643     }
2644 
2645     PromptDialogAttr promptDialogAttr = GetPromptActionDialog(env, asyncContext, onWillDismiss);
2646     promptDialogAttr.customStyle = true;
2647     promptDialogAttr.customBuilder = nullptr;
2648     promptDialogAttr.dialogCallback = GetDialogCallback(controller);
2649 
2650     std::function<void(int32_t)> openCallback = nullptr;
2651     ParseCustomDialogContentCallback(asyncContext, openCallback);
2652     OpenCustomDialog(env, asyncContext, promptDialogAttr, openCallback);
2653     return result;
2654 }
2655 
ParseDialogOptions(napi_env env,napi_value arg,std::shared_ptr<PromptAsyncContext> & asyncContext)2656 void ParseDialogOptions(napi_env env, napi_value arg, std::shared_ptr<PromptAsyncContext>& asyncContext)
2657 {
2658     ParseBaseDialogOptions(env, arg, asyncContext);
2659     napi_get_named_property(env, arg, "backgroundColor", &asyncContext->backgroundColorApi);
2660     napi_get_named_property(env, arg, "cornerRadius", &asyncContext->borderRadiusApi);
2661     napi_get_named_property(env, arg, "width", &asyncContext->widthApi);
2662     napi_get_named_property(env, arg, "height", &asyncContext->heightApi);
2663     napi_get_named_property(env, arg, "borderWidth", &asyncContext->borderWidthApi);
2664     napi_get_named_property(env, arg, "borderColor", &asyncContext->borderColorApi);
2665     napi_get_named_property(env, arg, "borderStyle", &asyncContext->borderStyleApi);
2666     napi_get_named_property(env, arg, "shadow", &asyncContext->shadowApi);
2667     napi_get_named_property(env, arg, "backgroundBlurStyle", &asyncContext->backgroundBlurStyleApi);
2668 }
2669 
JSPromptPresentCustomDialog(napi_env env,napi_callback_info info)2670 napi_value JSPromptPresentCustomDialog(napi_env env, napi_callback_info info)
2671 {
2672     size_t argc = PRESENT_CUSTOM_DIALOG_PARAM_TOTAL;
2673     napi_value argv[PRESENT_CUSTOM_DIALOG_PARAM_TOTAL] = { nullptr };
2674     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
2675     if (argc < PRESENT_CUSTOM_DIALOG_PARAM_MAND_COUNT || argc > PRESENT_CUSTOM_DIALOG_PARAM_TOTAL) {
2676         NapiThrow(env, "The number of parameters must be between 1 and 3.", ERROR_CODE_PARAM_INVALID);
2677         return nullptr;
2678     }
2679 
2680     napi_valuetype paramTypes[PRESENT_CUSTOM_DIALOG_PARAM_TOTAL] = { napi_function, napi_object, napi_object };
2681     for (size_t i = 0; i < argc; i++) {
2682         napi_valuetype valueType = napi_undefined;
2683         napi_typeof(env, argv[i], &valueType);
2684         if (valueType != paramTypes[i]) {
2685             NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2686             return nullptr;
2687         }
2688     }
2689 
2690     auto asyncContext = std::make_shared<PromptAsyncContext>();
2691     asyncContext->env = env;
2692     asyncContext->instanceId = Container::CurrentIdSafely();
2693     napi_create_reference(env, argv[0], 1, &asyncContext->builderRef);
2694 
2695     PromptDialogController* controller = nullptr;
2696     if (argc > PRESENT_CUSTOM_DIALOG_PARAM_INDEX_CONTROLLER) {
2697         napi_unwrap(env, argv[PRESENT_CUSTOM_DIALOG_PARAM_INDEX_CONTROLLER], (void**)&controller);
2698     }
2699 
2700     if (argc > PRESENT_CUSTOM_DIALOG_PARAM_INDEX_OPTIONS) {
2701         ParseDialogOptions(env, argv[PRESENT_CUSTOM_DIALOG_PARAM_INDEX_OPTIONS], asyncContext);
2702     }
2703 
2704     napi_value result = nullptr;
2705     napi_create_promise(env, &asyncContext->deferred, &result);
2706 
2707     std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismiss = nullptr;
2708     if (asyncContext->onWillDismissRef) {
2709         ParseDialogCallback(asyncContext, onWillDismiss);
2710     }
2711 
2712     PromptDialogAttr promptDialogAttr = GetPromptActionDialog(env, asyncContext, onWillDismiss);
2713     auto builder = GetCustomBuilderWithId(env, asyncContext);
2714     promptDialogAttr.customBuilderWithId = std::move(builder);
2715     if (controller) {
2716         promptDialogAttr.dialogCallback = GetDialogCallback(controller);
2717     }
2718 
2719     std::function<void(int32_t)> openCallback = nullptr;
2720     ParseCustomDialogIdCallback(asyncContext, openCallback);
2721     OpenCustomDialog(env, asyncContext, promptDialogAttr, openCallback);
2722     return result;
2723 }
2724 
CloseCustomDialog(napi_env env,std::shared_ptr<PromptAsyncContext> & asyncContext,bool useDialogId,int32_t dialogId,const WeakPtr<NG::UINode> & nodeWk,std::function<void (int32_t)> & contentCallback)2725 void CloseCustomDialog(napi_env env, std::shared_ptr<PromptAsyncContext>& asyncContext, bool useDialogId,
2726     int32_t dialogId, const WeakPtr<NG::UINode>& nodeWk, std::function<void(int32_t)>& contentCallback)
2727 {
2728 #ifdef OHOS_STANDARD_SYSTEM
2729     // NG
2730     if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) {
2731         auto delegate = EngineHelper::GetCurrentDelegateSafely();
2732         if (delegate) {
2733             if (useDialogId) {
2734                 delegate->CloseCustomDialog(dialogId);
2735             } else {
2736                 delegate->CloseCustomDialog(nodeWk, std::move(contentCallback));
2737             }
2738         } else {
2739             // throw internal error
2740             napi_create_promise(env, &asyncContext->deferred, nullptr);
2741             std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "Can not get delegate.";
2742             JSPromptThrowInterError(env, asyncContext, strMsg);
2743         }
2744     } else if (SubwindowManager::GetInstance() != nullptr) {
2745         if (useDialogId) {
2746             SubwindowManager::GetInstance()->CloseCustomDialogNG(dialogId);
2747         } else {
2748             SubwindowManager::GetInstance()->CloseCustomDialogNG(nodeWk, std::move(contentCallback));
2749         }
2750     }
2751 #else
2752     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2753     if (delegate) {
2754         if (useDialogId) {
2755             delegate->CloseCustomDialog(dialogId);
2756         } else {
2757             delegate->CloseCustomDialog(nodeWk, std::move(contentCallback));
2758         }
2759     } else {
2760         // throw internal error
2761         napi_create_promise(env, &asyncContext->deferred, nullptr);
2762         std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "UI execution context not found.";
2763         JSPromptThrowInterError(env, asyncContext, strMsg);
2764     }
2765 #endif
2766 }
2767 
JSPromptCloseCustomDialog(napi_env env,napi_callback_info info)2768 napi_value JSPromptCloseCustomDialog(napi_env env, napi_callback_info info)
2769 {
2770     size_t argc = 1;
2771     napi_value argv[1] = { 0 };
2772     int32_t dialogId = -1;
2773     WeakPtr<NG::UINode> nodeWk;
2774     bool useDialogId = true;
2775     std::function<void(int32_t)> contentCallback = nullptr;
2776     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
2777     auto asyncContext = std::make_shared<PromptAsyncContext>();
2778     asyncContext->env = env;
2779     asyncContext->instanceId = Container::CurrentIdSafely();
2780     napi_value ret = nullptr;
2781     if (argc > 1) {
2782         NapiThrow(env, "The number of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2783         return nullptr;
2784     } else if (argc == 0) {
2785         dialogId = -1;
2786     } else {
2787         napi_valuetype valueType = napi_undefined;
2788         napi_typeof(env, argv[0], &valueType);
2789         if (valueType == napi_number) {
2790             napi_get_value_int32(env, argv[0], &dialogId);
2791         } else if (valueType == napi_object) {
2792             napi_value frameNodePtr = nullptr;
2793             auto result = napi_get_named_property(env, argv[0], "nodePtr_", &frameNodePtr);
2794             if (result != napi_ok) {
2795                 NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2796                 return nullptr;
2797             }
2798             void* nativePtr = nullptr;
2799             result = napi_get_value_external(env, frameNodePtr, &nativePtr);
2800             if (result != napi_ok) {
2801                 NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2802                 return nullptr;
2803             }
2804             auto* uiNodePtr = reinterpret_cast<OHOS::Ace::NG::UINode*>(nativePtr);
2805             nodeWk = AceType::WeakClaim(uiNodePtr);
2806             useDialogId = false;
2807             napi_create_promise(env, &asyncContext->deferred, &ret);
2808             ParseCustomDialogContentCallback(asyncContext, contentCallback);
2809         } else {
2810             NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2811             return nullptr;
2812         }
2813     }
2814 
2815     CloseCustomDialog(env, asyncContext, useDialogId, dialogId, nodeWk, contentCallback);
2816 
2817     return ret;
2818 }
2819 
UpdateCustomDialog(napi_env env,std::shared_ptr<PromptAsyncContext> & asyncContext,PromptDialogAttr & promptDialogAttr,const WeakPtr<NG::UINode> & nodeWk,std::function<void (int32_t)> & contentCallback)2820 void UpdateCustomDialog(napi_env env, std::shared_ptr<PromptAsyncContext>& asyncContext,
2821     PromptDialogAttr& promptDialogAttr, const WeakPtr<NG::UINode>& nodeWk,
2822     std::function<void(int32_t)>& contentCallback)
2823 {
2824 #ifdef OHOS_STANDARD_SYSTEM
2825     // NG
2826     if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) {
2827         auto delegate = EngineHelper::GetCurrentDelegateSafely();
2828         if (delegate) {
2829             delegate->UpdateCustomDialog(nodeWk, promptDialogAttr, std::move(contentCallback));
2830         } else {
2831             // throw internal error
2832             napi_create_promise(env, &asyncContext->deferred, nullptr);
2833             std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "Can not get delegate.";
2834             JSPromptThrowInterError(env, asyncContext, strMsg);
2835         }
2836     } else if (SubwindowManager::GetInstance() != nullptr) {
2837         SubwindowManager::GetInstance()->UpdateCustomDialogNG(nodeWk, promptDialogAttr, std::move(contentCallback));
2838     }
2839 #else
2840     auto delegate = EngineHelper::GetCurrentDelegateSafely();
2841     if (delegate) {
2842         delegate->UpdateCustomDialog(nodeWk, promptDialogAttr, std::move(contentCallback));
2843     } else {
2844         // throw internal error
2845         napi_create_promise(env, &asyncContext->deferred, nullptr);
2846         std::string strMsg = ErrorToMessage(ERROR_CODE_INTERNAL_ERROR) + "UI execution context not found.";
2847         JSPromptThrowInterError(env, asyncContext, strMsg);
2848     }
2849 #endif
2850 }
2851 
JSPromptUpdateCustomDialog(napi_env env,napi_callback_info info)2852 napi_value JSPromptUpdateCustomDialog(napi_env env, napi_callback_info info)
2853 {
2854     size_t argc = CUSTOM_DIALOG_PARAM_NUM;
2855     napi_value argv[CUSTOM_DIALOG_PARAM_NUM] = { nullptr };
2856     WeakPtr<NG::UINode> nodeWk;
2857     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
2858     if (argc != CUSTOM_DIALOG_PARAM_NUM) {
2859         NapiThrow(env, "The number of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2860         return nullptr;
2861     }
2862     auto asyncContext = std::make_shared<PromptAsyncContext>();
2863     asyncContext->env = env;
2864     asyncContext->instanceId = Container::CurrentIdSafely();
2865     napi_value ret = nullptr;
2866 
2867     napi_valuetype valueType = napi_undefined;
2868     napi_typeof(env, argv[0], &valueType);
2869     if (valueType == napi_object) {
2870         napi_value frameNodePtr = nullptr;
2871         auto result = napi_get_named_property(env, argv[0], "nodePtr_", &frameNodePtr);
2872         if (result != napi_ok) {
2873             NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2874             return nullptr;
2875         }
2876         void* nativePtr = nullptr;
2877         result = napi_get_value_external(env, frameNodePtr, &nativePtr);
2878         if (result != napi_ok) {
2879             NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2880             return nullptr;
2881         }
2882         auto* uiNodePtr = reinterpret_cast<OHOS::Ace::NG::UINode*>(nativePtr);
2883         nodeWk = AceType::WeakClaim(uiNodePtr);
2884     } else {
2885         NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2886         return nullptr;
2887     }
2888 
2889     napi_typeof(env, argv[1], &valueType);
2890     if (valueType != napi_object) {
2891         NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID);
2892         return nullptr;
2893     }
2894     GetNapiNamedProperties(env, argv, 1, asyncContext);
2895 
2896     napi_create_promise(env, &asyncContext->deferred, &ret);
2897     std::function<void(int32_t)> contentCallback = nullptr;
2898     ParseCustomDialogContentCallback(asyncContext, contentCallback);
2899     PromptDialogAttr promptDialogAttr = GetPromptActionDialog(env, asyncContext, nullptr);
2900 
2901     UpdateCustomDialog(env, asyncContext, promptDialogAttr, nodeWk, contentCallback);
2902 
2903     return ret;
2904 }
2905 
2906 } // namespace OHOS::Ace::Napi
2907