• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #include "frameworks/bridge/declarative_frontend/jsview/dialog/js_alert_dialog.h"
16 
17 #include <sstream>
18 #include <string>
19 #include <vector>
20 
21 #include "base/log/ace_scoring_log.h"
22 #include "bridge/declarative_frontend/engine/js_converter.h"
23 #include "bridge/declarative_frontend/jsview/models/alert_dialog_model_impl.h"
24 #include "core/common/container.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/pattern/dialog/alert_dialog_model_ng.h"
27 #include "core/components_ng/pattern/overlay/level_order.h"
28 #include "frameworks/bridge/common/utils/engine_helper.h"
29 #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
30 
31 namespace OHOS::Ace {
32 std::unique_ptr<AlertDialogModel> AlertDialogModel::instance_ = nullptr;
33 std::mutex AlertDialogModel::mutex_;
GetInstance()34 AlertDialogModel* AlertDialogModel::GetInstance()
35 {
36     if (!instance_) {
37         std::lock_guard<std::mutex> lock(mutex_);
38         if (!instance_) {
39 #ifdef NG_BUILD
40             instance_.reset(new NG::AlertDialogModelNG());
41 #else
42             if (Container::IsCurrentUseNewPipeline()) {
43                 instance_.reset(new NG::AlertDialogModelNG());
44             } else {
45                 instance_.reset(new Framework::AlertDialogModelImpl());
46             }
47 #endif
48         }
49     }
50     return instance_.get();
51 }
52 
53 } // namespace OHOS::Ace
54 namespace OHOS::Ace::Framework {
55 namespace {
56 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
57     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
58     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
59     DialogAlignment::BOTTOM_END };
60 const std::vector<DialogButtonDirection> DIALOG_BUTTONS_DIRECTION = { DialogButtonDirection::AUTO,
61     DialogButtonDirection::HORIZONTAL, DialogButtonDirection::VERTICAL };
62 constexpr int32_t ALERT_DIALOG_VALID_PRIMARY_BUTTON_NUM = 1;
63 const std::vector<LevelMode> DIALOG_LEVEL_MODE = { LevelMode::OVERLAY, LevelMode::EMBEDDED };
64 const std::vector<ImmersiveMode> DIALOG_IMMERSIVE_MODE = { ImmersiveMode::DEFAULT, ImmersiveMode::EXTEND};
65 } // namespace
66 
SetParseStyle(ButtonInfo & buttonInfo,const int32_t styleValue)67 void SetParseStyle(ButtonInfo& buttonInfo, const int32_t styleValue)
68 {
69     if (styleValue >= static_cast<int32_t>(DialogButtonStyle::DEFAULT) &&
70         styleValue <= static_cast<int32_t>(DialogButtonStyle::HIGHTLIGHT)) {
71         buttonInfo.dlgButtonStyle = static_cast<DialogButtonStyle>(styleValue);
72     }
73 }
74 
ParseButtonObj(const JsiExecutionContext & execContext,DialogProperties & properties,JSRef<JSVal> jsVal,const std::string & property,bool isPrimaryButtonValid)75 void ParseButtonObj(const JsiExecutionContext& execContext, DialogProperties& properties, JSRef<JSVal> jsVal,
76     const std::string& property, bool isPrimaryButtonValid)
77 {
78     if (!jsVal->IsObject()) {
79         return;
80     }
81     auto objInner = JSRef<JSObject>::Cast(jsVal);
82     std::string buttonValue;
83     ButtonInfo buttonInfo;
84     if (JSAlertDialog::ParseJsString(objInner->GetProperty("value"), buttonValue)) {
85         buttonInfo.text = buttonValue;
86     }
87 
88     // Parse enabled
89     auto enabledValue = objInner->GetProperty("enabled");
90     if (enabledValue->IsBoolean()) {
91         buttonInfo.enabled = enabledValue->ToBoolean();
92     }
93 
94     // Parse defaultFocus
95     auto defaultFocusValue = objInner->GetProperty("defaultFocus");
96     if (defaultFocusValue->IsBoolean()) {
97         buttonInfo.defaultFocus = defaultFocusValue->ToBoolean();
98     }
99 
100     // Parse style
101     auto style = objInner->GetProperty("style");
102     if (style->IsNumber()) {
103         SetParseStyle(buttonInfo, style->ToNumber<int32_t>());
104     }
105 
106     Color textColor;
107     if (JSAlertDialog::ParseJsColor(objInner->GetProperty("fontColor"), textColor)) {
108         buttonInfo.textColor = textColor.ColorToString();
109     }
110 
111     Color backgroundColor;
112     if (JSAlertDialog::ParseJsColor(objInner->GetProperty("backgroundColor"), backgroundColor)) {
113         buttonInfo.isBgColorSetted = true;
114         buttonInfo.bgColor = backgroundColor;
115     }
116 
117     auto actionValue = objInner->GetProperty("action");
118     if (actionValue->IsFunction()) {
119         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
120         auto actionFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(actionValue));
121         auto eventFunc = [execCtx = execContext, func = std::move(actionFunc), property, node = frameNode]() {
122             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
123             ACE_SCORING_EVENT("AlertDialog.[" + property + "].onAction");
124             auto pipelineContext = PipelineContext::GetCurrentContextSafely();
125             CHECK_NULL_VOID(pipelineContext);
126             pipelineContext->UpdateCurrentActiveNode(node);
127             func->Execute();
128         };
129         AlertDialogModel::GetInstance()->SetParseButtonObj(eventFunc, buttonInfo, properties, property);
130     }
131 
132     if (!buttonInfo.defaultFocus && isPrimaryButtonValid) {
133         if (strcmp(property.c_str(), "confirm") == 0 ||
134         strcmp(property.c_str(), "primaryButton") == 0) {
135             buttonInfo.isPrimary = true;
136         } else {
137             auto primaryButton = objInner->GetProperty("primary");
138             if (primaryButton->IsBoolean()) {
139                 buttonInfo.isPrimary = primaryButton->ToBoolean();
140             }
141         }
142     }
143 
144     if (buttonInfo.IsValid()) {
145         properties.buttons.emplace_back(buttonInfo);
146     }
147 }
148 
ParseButtonArray(const JsiExecutionContext & execContext,DialogProperties & properties,JSRef<JSObject> obj,const std::string & property)149 void ParseButtonArray(const JsiExecutionContext& execContext, DialogProperties& properties, JSRef<JSObject> obj,
150     const std::string& property)
151 {
152     auto jsVal = obj->GetProperty(property.c_str());
153     if (!jsVal->IsArray()) {
154         return;
155     }
156     JSRef<JSArray> array = JSRef<JSArray>::Cast(jsVal);
157     size_t length = array->Length();
158     if (length <= 0) {
159         return;
160     }
161     int32_t primaryButtonNum = 0;
162     bool isPrimaryButtonValid = true;
163     for (size_t i = 0; i < length; i++) {
164         JSRef<JSVal> buttonItem = array->GetValueAt(i);
165         if (!buttonItem->IsObject()) {
166             break;
167         }
168         auto objInner = JSRef<JSObject>::Cast(buttonItem);
169         auto primaryButton = objInner->GetProperty("primary");
170         if (primaryButton->IsBoolean()) {
171             primaryButtonNum += (primaryButton->ToBoolean() ? ALERT_DIALOG_VALID_PRIMARY_BUTTON_NUM : 0);
172         }
173         if (primaryButtonNum > ALERT_DIALOG_VALID_PRIMARY_BUTTON_NUM) {
174             isPrimaryButtonValid = false;
175             break;
176         }
177     }
178     for (size_t i = 0; i < length; i++) {
179         JSRef<JSVal> buttonItem = array->GetValueAt(i);
180         if (!buttonItem->IsObject()) {
181             break;
182         }
183         ParseButtonObj(execContext, properties, buttonItem, property + std::to_string(i), isPrimaryButtonValid);
184     }
185 }
186 
ParseButtons(const JsiExecutionContext & execContext,DialogProperties & properties,JSRef<JSObject> obj)187 void ParseButtons(const JsiExecutionContext& execContext, DialogProperties& properties, JSRef<JSObject> obj)
188 {
189     properties.buttons.clear();
190     if (obj->GetProperty("confirm")->IsObject()) {
191         // Parse confirm.
192         auto objInner = obj->GetProperty("confirm");
193         ParseButtonObj(execContext, properties, objInner, "confirm", true);
194     } else if (obj->GetProperty("buttons")->IsArray()) {
195         // Parse buttons array.
196         ParseButtonArray(execContext, properties, obj, "buttons");
197     } else {
198         // Parse primaryButton and secondaryButton.
199         auto objInner = obj->GetProperty("primaryButton");
200         ParseButtonObj(execContext, properties, objInner, "primaryButton", true);
201         objInner = obj->GetProperty("secondaryButton");
202         ParseButtonObj(execContext, properties, objInner, "secondaryButton", true);
203     }
204 
205     // Parse buttons direction.
206     auto directionValue = obj->GetProperty("buttonDirection");
207     if (directionValue->IsNumber()) {
208         auto buttonDirection = directionValue->ToNumber<int32_t>();
209         if (buttonDirection >= 0 && buttonDirection < static_cast<int32_t>(DIALOG_BUTTONS_DIRECTION.size())) {
210             properties.buttonDirection = DIALOG_BUTTONS_DIRECTION[buttonDirection];
211         }
212     }
213 }
214 
ParseDialogTitleAndMessage(DialogProperties & properties,JSRef<JSObject> obj)215 void ParseDialogTitleAndMessage(DialogProperties& properties, JSRef<JSObject> obj)
216 {
217     // Parse title.
218     auto titleValue = obj->GetProperty("title");
219     std::string title;
220     if (JSAlertDialog::ParseJsString(titleValue, title)) {
221         properties.title = title;
222     }
223 
224     // Parse subtitle.
225     auto subtitleValue = obj->GetProperty("subtitle");
226     std::string subtitle;
227     if (JSAlertDialog::ParseJsString(subtitleValue, subtitle)) {
228         properties.subtitle = subtitle;
229     }
230 
231     // Parses message.
232     auto messageValue = obj->GetProperty("message");
233     std::string message;
234     if (JSAlertDialog::ParseJsString(messageValue, message)) {
235         properties.content = message;
236     }
237 }
238 
ParseAlertShadow(DialogProperties & properties,JSRef<JSObject> obj)239 void ParseAlertShadow(DialogProperties& properties, JSRef<JSObject> obj)
240 {
241     // Parse shadow.
242     auto shadowValue = obj->GetProperty("shadow");
243     Shadow shadow;
244     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSAlertDialog::ParseShadowProps(shadowValue, shadow)) {
245         properties.shadow = shadow;
246     }
247 }
248 
ParseAlertBorderWidthAndColor(DialogProperties & properties,JSRef<JSObject> obj)249 void ParseAlertBorderWidthAndColor(DialogProperties& properties, JSRef<JSObject> obj)
250 {
251     auto borderWidthValue = obj->GetProperty("borderWidth");
252     NG::BorderWidthProperty borderWidth;
253     if (JSAlertDialog::ParseBorderWidthProps(borderWidthValue, borderWidth)) {
254         properties.borderWidth = borderWidth;
255         auto colorValue = obj->GetProperty("borderColor");
256         NG::BorderColorProperty borderColor;
257         if (JSAlertDialog::ParseBorderColorProps(colorValue, borderColor)) {
258             properties.borderColor = borderColor;
259         } else {
260             borderColor.SetColor(Color::BLACK);
261             properties.borderColor = borderColor;
262         }
263     }
264 }
265 
ParseAlertRadius(DialogProperties & properties,JSRef<JSObject> obj)266 void ParseAlertRadius(DialogProperties& properties, JSRef<JSObject> obj)
267 {
268     auto cornerRadiusValue = obj->GetProperty("cornerRadius");
269     NG::BorderRadiusProperty radius;
270     if (JSAlertDialog::ParseBorderRadius(cornerRadiusValue, radius)) {
271         properties.borderRadius = radius;
272     }
273 }
274 
UpdateAlertAlignment(DialogAlignment & alignment)275 void UpdateAlertAlignment(DialogAlignment& alignment)
276 {
277     bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
278     if (alignment == DialogAlignment::TOP_START) {
279         if (isRtl) {
280             alignment = DialogAlignment::TOP_END;
281         }
282     } else if (alignment == DialogAlignment::TOP_END) {
283         if (isRtl) {
284             alignment = DialogAlignment::TOP_START;
285         }
286     } else if (alignment == DialogAlignment::CENTER_START) {
287         if (isRtl) {
288             alignment = DialogAlignment::CENTER_END;
289         }
290     } else if (alignment == DialogAlignment::CENTER_END) {
291         if (isRtl) {
292             alignment = DialogAlignment::CENTER_START;
293         }
294     } else if (alignment == DialogAlignment::BOTTOM_START) {
295         if (isRtl) {
296             alignment = DialogAlignment::BOTTOM_END;
297         }
298     } else if (alignment == DialogAlignment::BOTTOM_END) {
299         if (isRtl) {
300             alignment = DialogAlignment::BOTTOM_START;
301         }
302     }
303 }
304 
ParseAlertAlignment(DialogProperties & properties,JSRef<JSObject> obj)305 void ParseAlertAlignment(DialogProperties& properties, JSRef<JSObject> obj)
306 {
307     // Parse alignment
308     auto alignmentValue = obj->GetProperty("alignment");
309     if (alignmentValue->IsNumber()) {
310         auto alignment = alignmentValue->ToNumber<int32_t>();
311         if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
312             properties.alignment = DIALOG_ALIGNMENT[alignment];
313             UpdateAlertAlignment(properties.alignment);
314         }
315     }
316 }
317 
ParseAlertOffset(DialogProperties & properties,JSRef<JSObject> obj)318 void ParseAlertOffset(DialogProperties& properties, JSRef<JSObject> obj)
319 {
320     // Parse offset
321     auto offsetValue = obj->GetProperty("offset");
322     if (offsetValue->IsObject()) {
323         auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
324         CalcDimension dx;
325         auto dxValue = offsetObj->GetProperty("dx");
326         JSAlertDialog::ParseJsDimensionVp(dxValue, dx);
327         CalcDimension dy;
328         auto dyValue = offsetObj->GetProperty("dy");
329         JSAlertDialog::ParseJsDimensionVp(dyValue, dy);
330         properties.offset = DimensionOffset(dx, dy);
331         bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
332         Dimension offsetX = isRtl ? properties.offset.GetX() * (-1) : properties.offset.GetX();
333         properties.offset.SetX(offsetX);
334     }
335 }
336 
ParseTextStyle(DialogProperties & properties,JSRef<JSObject> obj)337 void ParseTextStyle(DialogProperties& properties, JSRef<JSObject> obj)
338 {
339     auto textStyleObj = obj->GetProperty("textStyle");
340     if (textStyleObj->IsNull() || !textStyleObj->IsObject()) {
341         return;
342     }
343     auto textStyle = JSRef<JSObject>::Cast(textStyleObj);
344     auto args = textStyle->GetProperty("wordBreak");
345     int32_t index = 1;
346     if (args->IsNumber()) {
347         index = args->ToNumber<int32_t>();
348     }
349     if (index < 0 || index >= static_cast<int32_t>(WORD_BREAK_TYPES.size())) {
350         index = 1;
351     }
352     properties.wordBreak = WORD_BREAK_TYPES[index];
353 }
354 
ParseAlertMaskRect(DialogProperties & properties,JSRef<JSObject> obj)355 void ParseAlertMaskRect(DialogProperties& properties, JSRef<JSObject> obj)
356 {
357     // Parse maskRect.
358     auto maskRectValue = obj->GetProperty("maskRect");
359     DimensionRect maskRect;
360     if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
361         properties.maskRect = maskRect;
362         bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
363         auto offset = maskRect.GetOffset();
364         Dimension offsetX = isRtl ? offset.GetX() * (-1) : offset.GetX();
365         offset.SetX(offsetX);
366         properties.maskRect->SetOffset(offset);
367     }
368 }
369 
ParseAlertDialogLevelMode(DialogProperties & properties,JSRef<JSObject> obj)370 void ParseAlertDialogLevelMode(DialogProperties& properties, JSRef<JSObject> obj)
371 {
372     auto levelMode = obj->GetProperty("levelMode");
373     auto levelUniqueId = obj->GetProperty("levelUniqueId");
374     auto immersiveMode = obj->GetProperty("immersiveMode");
375     bool showInMainWindow = true;
376     if (obj->GetProperty("showInSubWindow")->IsBoolean() && obj->GetProperty("showInSubWindow")->ToBoolean()) {
377         showInMainWindow = false;
378     }
379     if (levelMode->IsNumber() && showInMainWindow) {
380         auto mode = levelMode->ToNumber<int32_t>();
381         if (mode >= 0 && mode < static_cast<int32_t>(DIALOG_LEVEL_MODE.size())) {
382             properties.dialogLevelMode = DIALOG_LEVEL_MODE[mode];
383         }
384     }
385     if (levelUniqueId->IsNumber()) {
386         properties.dialogLevelUniqueId = levelUniqueId->ToNumber<int32_t>();
387     }
388     if (immersiveMode->IsNumber()) {
389         auto immersiveVal = immersiveMode->ToNumber<int32_t>();
390         if (immersiveVal >= 0 && immersiveVal < static_cast<int32_t>(DIALOG_IMMERSIVE_MODE.size())) {
391             properties.dialogImmersiveMode = DIALOG_IMMERSIVE_MODE[immersiveVal];
392         }
393     }
394 }
395 
ParseAlertLevelOrder(DialogProperties & properties,JSRef<JSObject> obj)396 void ParseAlertLevelOrder(DialogProperties& properties, JSRef<JSObject> obj)
397 {
398     if (properties.isShowInSubWindow) {
399         return;
400     }
401 
402     auto levelOrderValue = obj->GetProperty("levelOrder");
403     if (!levelOrderValue->IsObject()) {
404         return;
405     }
406     napi_value levelOrderApi = JsConverter::ConvertJsValToNapiValue(levelOrderValue);
407     CHECK_NULL_VOID(levelOrderApi);
408 
409     auto engine = EngineHelper::GetCurrentEngine();
410     CHECK_NULL_VOID(engine);
411     NativeEngine* nativeEngine = engine->GetNativeEngine();
412     CHECK_NULL_VOID(nativeEngine);
413     auto env = reinterpret_cast<napi_env>(nativeEngine);
414     NG::LevelOrder* levelOrder = nullptr;
415     napi_status status = napi_unwrap(env, levelOrderApi, reinterpret_cast<void**>(&levelOrder));
416     if (status != napi_ok || !levelOrder) {
417         LOGE("Failed to unwrap LevelOrder.");
418         return;
419     }
420 
421     double order = levelOrder->GetOrder();
422     properties.levelOrder = std::make_optional(order);
423 }
424 
Show(const JSCallbackInfo & args)425 void JSAlertDialog::Show(const JSCallbackInfo& args)
426 {
427     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
428     if (!scopedDelegate) {
429         // this case usually means there is no foreground container, need to figure out the reason.
430         LOGE("scopedDelegate is null, please check");
431         return;
432     }
433 
434     DialogProperties properties { .type = DialogType::ALERT_DIALOG, .isAlertDialog = true };
435     if (args[0]->IsObject()) {
436         auto obj = JSRef<JSObject>::Cast(args[0]);
437         auto dialogNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
438         auto execContext = args.GetExecutionContext();
439 
440         ParseDialogTitleAndMessage(properties, obj);
441         ParseButtons(execContext, properties, obj);
442         ParseAlertShadow(properties, obj);
443         ParseAlertBorderWidthAndColor(properties, obj);
444         ParseAlertRadius(properties, obj);
445         ParseAlertAlignment(properties, obj);
446         ParseAlertOffset(properties, obj);
447         ParseTextStyle(properties, obj);
448         ParseAlertMaskRect(properties, obj);
449         ParseAlertDialogLevelMode(properties, obj);
450 
451         auto onLanguageChange = [execContext, obj, parseContent = ParseDialogTitleAndMessage,
452                                     parseButton = ParseButtons, parseShadow = ParseAlertShadow,
453                                     parseBorderProps = ParseAlertBorderWidthAndColor,
454                                     parseRadius = ParseAlertRadius, parseAlignment = ParseAlertAlignment,
455                                     parseOffset = ParseAlertOffset, parseMaskRect = ParseAlertMaskRect,
456                                     parseDialogLevelMode = ParseAlertDialogLevelMode,
457                                     node = dialogNode](DialogProperties& dialogProps) {
458             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execContext);
459             ACE_SCORING_EVENT("AlertDialog.property.onLanguageChange");
460             auto pipelineContext = PipelineContext::GetCurrentContextSafely();
461             CHECK_NULL_VOID(pipelineContext);
462             pipelineContext->UpdateCurrentActiveNode(node);
463             parseContent(dialogProps, obj);
464             parseButton(execContext, dialogProps, obj);
465             parseShadow(dialogProps, obj);
466             parseBorderProps(dialogProps, obj);
467             parseRadius(dialogProps, obj);
468             parseAlignment(dialogProps, obj);
469             parseOffset(dialogProps, obj);
470             parseMaskRect(dialogProps, obj);
471             parseDialogLevelMode(dialogProps, obj);
472         };
473         properties.onLanguageChange = std::move(onLanguageChange);
474 
475         // Parses gridCount.
476         auto gridCountValue = obj->GetProperty("gridCount");
477         if (gridCountValue->IsNumber()) {
478             properties.gridCount = gridCountValue->ToNumber<int32_t>();
479         }
480 
481         // Parse auto autoCancel.
482         auto autoCancelValue = obj->GetProperty("autoCancel");
483         if (autoCancelValue->IsBoolean()) {
484             properties.autoCancel = autoCancelValue->ToBoolean();
485         }
486 
487         // Parse cancel.
488         auto cancelValue = obj->GetProperty("cancel");
489         if (cancelValue->IsFunction()) {
490             auto cancelFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(cancelValue));
491             auto eventFunc = [execContext, func = std::move(cancelFunc), node = dialogNode]() {
492                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execContext);
493                 ACE_SCORING_EVENT("AlertDialog.property.cancel");
494                 auto pipelineContext = PipelineContext::GetCurrentContextSafely();
495                 CHECK_NULL_VOID(pipelineContext);
496                 pipelineContext->UpdateCurrentActiveNode(node);
497                 func->Execute();
498             };
499             AlertDialogModel::GetInstance()->SetOnCancel(eventFunc, properties);
500         }
501 
502         std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismissFunc = nullptr;
503         ParseDialogCallback(obj, onWillDismissFunc);
504         AlertDialogModel::GetInstance()->SetOnWillDismiss(std::move(onWillDismissFunc), properties);
505 
506         JSViewAbstract::ParseAppearDialogCallback(args, properties);
507 
508         // Parse showInSubWindowValue.
509         auto showInSubWindowValue = obj->GetProperty("showInSubWindow");
510         if (showInSubWindowValue->IsBoolean()) {
511 #if defined(PREVIEW)
512             LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Perform this operation on the "
513                  "emulator or a real device instead.");
514 #else
515             properties.isShowInSubWindow = showInSubWindowValue->ToBoolean();
516 #endif
517         }
518 
519         // Parse isModal.
520         auto isModalValue = obj->GetProperty("isModal");
521         if (isModalValue->IsBoolean()) {
522             LOGI("Parse isModalValue");
523             properties.isModal = isModalValue->ToBoolean();
524         }
525 
526         auto backgroundColorValue = obj->GetProperty("backgroundColor");
527         Color backgroundColor;
528         if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
529             properties.backgroundColor = backgroundColor;
530         }
531         auto backgroundBlurStyle = obj->GetProperty("backgroundBlurStyle");
532         if (backgroundBlurStyle->IsNumber()) {
533             auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
534             if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
535                 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
536                 properties.backgroundBlurStyle = blurStyle;
537             }
538         }
539         // Parse transition.
540         properties.transitionEffect = ParseJsTransitionEffect(args);
541         ParseAlertLevelOrder(properties, obj);
542         JSViewAbstract::SetDialogProperties(obj, properties);
543         JSViewAbstract::SetDialogHoverModeProperties(obj, properties);
544         JSViewAbstract::SetDialogBlurStyleOption(obj, properties);
545         JSViewAbstract::SetDialogEffectOption(obj, properties);
546         AlertDialogModel::GetInstance()->SetShowDialog(properties);
547     }
548 }
549 
JSBind(BindingTarget globalObj)550 void JSAlertDialog::JSBind(BindingTarget globalObj)
551 {
552     JSClass<JSAlertDialog>::Declare("AlertDialog");
553     JSClass<JSAlertDialog>::StaticMethod("show", &JSAlertDialog::Show);
554 
555     JSClass<JSAlertDialog>::InheritAndBind<JSViewAbstract>(globalObj);
556 }
557 } // namespace OHOS::Ace::Framework
558