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