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