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