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