• 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     properties.levelOrder = std::make_optional(NG::LevelOrder::ORDER_DEFAULT);
403     auto levelOrderValue = obj->GetProperty("levelOrder");
404     if (!levelOrderValue->IsObject()) {
405         return;
406     }
407     napi_value levelOrderApi = JsConverter::ConvertJsValToNapiValue(levelOrderValue);
408     CHECK_NULL_VOID(levelOrderApi);
409 
410     auto engine = EngineHelper::GetCurrentEngine();
411     CHECK_NULL_VOID(engine);
412     NativeEngine* nativeEngine = engine->GetNativeEngine();
413     CHECK_NULL_VOID(nativeEngine);
414     auto env = reinterpret_cast<napi_env>(nativeEngine);
415     NG::LevelOrder* levelOrder = nullptr;
416     napi_status status = napi_unwrap(env, levelOrderApi, reinterpret_cast<void**>(&levelOrder));
417     if (status != napi_ok || !levelOrder) {
418         LOGE("Failed to unwrap LevelOrder.");
419         return;
420     }
421 
422     double order = levelOrder->GetOrder();
423     properties.levelOrder = std::make_optional(order);
424 }
425 
Show(const JSCallbackInfo & args)426 void JSAlertDialog::Show(const JSCallbackInfo& args)
427 {
428     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
429     if (!scopedDelegate) {
430         // this case usually means there is no foreground container, need to figure out the reason.
431         LOGE("scopedDelegate is null, please check");
432         return;
433     }
434 
435     DialogProperties properties { .type = DialogType::ALERT_DIALOG };
436     if (args[0]->IsObject()) {
437         auto obj = JSRef<JSObject>::Cast(args[0]);
438         auto dialogNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
439         auto execContext = args.GetExecutionContext();
440 
441         ParseDialogTitleAndMessage(properties, obj);
442         ParseButtons(execContext, properties, obj);
443         ParseAlertShadow(properties, obj);
444         ParseAlertBorderWidthAndColor(properties, obj);
445         ParseAlertRadius(properties, obj);
446         ParseAlertAlignment(properties, obj);
447         ParseAlertOffset(properties, obj);
448         ParseTextStyle(properties, obj);
449         ParseAlertMaskRect(properties, obj);
450         ParseAlertDialogLevelMode(properties, obj);
451 
452         auto onLanguageChange = [execContext, obj, parseContent = ParseDialogTitleAndMessage,
453                                     parseButton = ParseButtons, parseShadow = ParseAlertShadow,
454                                     parseBorderProps = ParseAlertBorderWidthAndColor,
455                                     parseRadius = ParseAlertRadius, parseAlignment = ParseAlertAlignment,
456                                     parseOffset = ParseAlertOffset, parseMaskRect = ParseAlertMaskRect,
457                                     parseDialogLevelMode = ParseAlertDialogLevelMode,
458                                     node = dialogNode](DialogProperties& dialogProps) {
459             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execContext);
460             ACE_SCORING_EVENT("AlertDialog.property.onLanguageChange");
461             auto pipelineContext = PipelineContext::GetCurrentContextSafely();
462             CHECK_NULL_VOID(pipelineContext);
463             pipelineContext->UpdateCurrentActiveNode(node);
464             parseContent(dialogProps, obj);
465             parseButton(execContext, dialogProps, obj);
466             parseShadow(dialogProps, obj);
467             parseBorderProps(dialogProps, obj);
468             parseRadius(dialogProps, obj);
469             parseAlignment(dialogProps, obj);
470             parseOffset(dialogProps, obj);
471             parseMaskRect(dialogProps, obj);
472             parseDialogLevelMode(dialogProps, obj);
473         };
474         properties.onLanguageChange = std::move(onLanguageChange);
475 
476         // Parses gridCount.
477         auto gridCountValue = obj->GetProperty("gridCount");
478         if (gridCountValue->IsNumber()) {
479             properties.gridCount = gridCountValue->ToNumber<int32_t>();
480         }
481 
482         // Parse auto autoCancel.
483         auto autoCancelValue = obj->GetProperty("autoCancel");
484         if (autoCancelValue->IsBoolean()) {
485             properties.autoCancel = autoCancelValue->ToBoolean();
486         }
487 
488         // Parse cancel.
489         auto cancelValue = obj->GetProperty("cancel");
490         if (cancelValue->IsFunction()) {
491             auto cancelFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(cancelValue));
492             auto eventFunc = [execContext, func = std::move(cancelFunc), node = dialogNode]() {
493                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execContext);
494                 ACE_SCORING_EVENT("AlertDialog.property.cancel");
495                 auto pipelineContext = PipelineContext::GetCurrentContextSafely();
496                 CHECK_NULL_VOID(pipelineContext);
497                 pipelineContext->UpdateCurrentActiveNode(node);
498                 func->Execute();
499             };
500             AlertDialogModel::GetInstance()->SetOnCancel(eventFunc, properties);
501         }
502 
503         std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismissFunc = nullptr;
504         ParseDialogCallback(obj, onWillDismissFunc);
505         AlertDialogModel::GetInstance()->SetOnWillDismiss(std::move(onWillDismissFunc), properties);
506 
507         JSViewAbstract::ParseAppearDialogCallback(args, properties);
508 
509         // Parse showInSubWindowValue.
510         auto showInSubWindowValue = obj->GetProperty("showInSubWindow");
511         if (showInSubWindowValue->IsBoolean()) {
512 #if defined(PREVIEW)
513             LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Perform this operation on the "
514                  "emulator or a real device instead.");
515 #else
516             properties.isShowInSubWindow = showInSubWindowValue->ToBoolean();
517 #endif
518         }
519 
520         // Parse isModal.
521         auto isModalValue = obj->GetProperty("isModal");
522         if (isModalValue->IsBoolean()) {
523             LOGI("Parse isModalValue");
524             properties.isModal = isModalValue->ToBoolean();
525         }
526 
527         auto backgroundColorValue = obj->GetProperty("backgroundColor");
528         Color backgroundColor;
529         if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
530             properties.backgroundColor = backgroundColor;
531         }
532 
533         auto backgroundBlurStyle = obj->GetProperty("backgroundBlurStyle");
534         if (backgroundBlurStyle->IsNumber()) {
535             auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
536             if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
537                 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
538                 properties.backgroundBlurStyle = blurStyle;
539             }
540         }
541         // Parse transition.
542         properties.transitionEffect = ParseJsTransitionEffect(args);
543         ParseAlertLevelOrder(properties, obj);
544         JSViewAbstract::SetDialogProperties(obj, properties);
545         JSViewAbstract::SetDialogHoverModeProperties(obj, properties);
546         JSViewAbstract::SetDialogBlurStyleOption(obj, properties);
547         JSViewAbstract::SetDialogEffectOption(obj, properties);
548         AlertDialogModel::GetInstance()->SetShowDialog(properties);
549     }
550 }
551 
JSBind(BindingTarget globalObj)552 void JSAlertDialog::JSBind(BindingTarget globalObj)
553 {
554     JSClass<JSAlertDialog>::Declare("AlertDialog");
555     JSClass<JSAlertDialog>::StaticMethod("show", &JSAlertDialog::Show);
556 
557     JSClass<JSAlertDialog>::InheritAndBind<JSViewAbstract>(globalObj);
558 }
559 } // namespace OHOS::Ace::Framework
560