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