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