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