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 "bridge/declarative_frontend/jsview/dialog/js_custom_dialog_controller.h"
17
18 #include "bridge/declarative_frontend/engine/js_converter.h"
19
20 #include "base/subwindow/subwindow_manager.h"
21 #include "base/utils/system_properties.h"
22 #include "base/utils/utils.h"
23 #include "bridge/declarative_frontend/engine/jsi/jsi_types.h"
24 #include "bridge/declarative_frontend/jsview/js_view.h"
25 #include "bridge/declarative_frontend/jsview/models/custom_dialog_controller_model_impl.h"
26 #include "core/common/ace_engine.h"
27 #include "core/common/container.h"
28 #include "core/components_ng/base/view_stack_processor.h"
29 #include "core/components_ng/pattern/dialog/custom_dialog_controller_model_ng.h"
30 #include "core/components_ng/pattern/overlay/level_order.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 #include "frameworks/bridge/common/utils/engine_helper.h"
33 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
34 #include "frameworks/bridge/declarative_frontend/engine/jsi/js_ui_index.h"
35
36 namespace OHOS::Ace {
37 std::unique_ptr<CustomDialogControllerModel> CustomDialogControllerModel::instance_ = nullptr;
38 std::mutex CustomDialogControllerModel::mutex_;
GetInstance()39 CustomDialogControllerModel* CustomDialogControllerModel::GetInstance()
40 {
41 if (!instance_) {
42 std::lock_guard<std::mutex> lock(mutex_);
43 if (!instance_) {
44 #ifdef NG_BUILD
45 instance_.reset(new NG::CustomDialogControllerModelNG());
46 #else
47 if (Container::IsCurrentUseNewPipeline()) {
48 instance_.reset(new NG::CustomDialogControllerModelNG());
49 } else {
50 instance_.reset(new Framework::CustomDialogControllerModelImpl());
51 }
52 #endif
53 }
54 }
55 return instance_.get();
56 }
57 } // namespace OHOS::Ace
58
59 namespace OHOS::Ace::Framework {
60 namespace {
61 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
62 DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
63 DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
64 DialogAlignment::BOTTOM_END };
65 const std::vector<KeyboardAvoidMode> KEYBOARD_AVOID_MODE = { KeyboardAvoidMode::DEFAULT, KeyboardAvoidMode::NONE };
66 const std::vector<LevelMode> DIALOG_LEVEL_MODE = { LevelMode::OVERLAY, LevelMode::EMBEDDED };
67 const std::vector<ImmersiveMode> DIALOG_IMMERSIVE_MODE = { ImmersiveMode::DEFAULT, ImmersiveMode::EXTEND};
68 constexpr int32_t DEFAULT_ANIMATION_DURATION = 200;
69 constexpr float DEFAULT_AVOID_DISTANCE = 16.0f;
70
71 } // namespace
72
ParseCustomDialogLevelOrder(DialogProperties & properties,JSRef<JSObject> obj)73 void ParseCustomDialogLevelOrder(DialogProperties& properties, JSRef<JSObject> obj)
74 {
75 if (properties.isShowInSubWindow) {
76 return;
77 }
78
79 properties.levelOrder = std::make_optional(NG::LevelOrder::ORDER_DEFAULT);
80 auto levelOrderValue = obj->GetProperty("levelOrder");
81 if (!levelOrderValue->IsObject()) {
82 return;
83 }
84 napi_value levelOrderApi = JsConverter::ConvertJsValToNapiValue(levelOrderValue);
85 CHECK_NULL_VOID(levelOrderApi);
86
87 auto engine = EngineHelper::GetCurrentEngine();
88 CHECK_NULL_VOID(engine);
89 NativeEngine* nativeEngine = engine->GetNativeEngine();
90 CHECK_NULL_VOID(nativeEngine);
91 auto env = reinterpret_cast<napi_env>(nativeEngine);
92 NG::LevelOrder* levelOrder = nullptr;
93 napi_status status = napi_unwrap(env, levelOrderApi, reinterpret_cast<void**>(&levelOrder));
94 if (status != napi_ok || !levelOrder) {
95 LOGE("Failed to unwrap LevelOrder.");
96 return;
97 }
98
99 double order = levelOrder->GetOrder();
100 properties.levelOrder = std::make_optional(order);
101 }
102
ParseCustomDialogFocusable(DialogProperties & properties,JSRef<JSObject> obj)103 void ParseCustomDialogFocusable(DialogProperties& properties, JSRef<JSObject> obj)
104 {
105 auto focusableValue = obj->GetProperty("focusable");
106 if (!focusableValue->IsBoolean()) {
107 return;
108 }
109 properties.focusable = focusableValue->ToBoolean();
110 }
111
112 static std::atomic<int32_t> controllerId = 0;
ConstructorCallback(const JSCallbackInfo & info)113 void JSCustomDialogController::ConstructorCallback(const JSCallbackInfo& info)
114 {
115 uint32_t argc = info.Length();
116 if (argc > 1 && !info[0]->IsUndefined() && info[0]->IsObject() && !info[1]->IsUndefined() && info[1]->IsObject()) {
117 JSRef<JSObject> constructorArg = JSRef<JSObject>::Cast(info[0]);
118 JSRef<JSObject> ownerObj = JSRef<JSObject>::Cast(info[1]);
119
120 // check if owner object is set
121 auto* ownerView = JSView::GetNativeView(ownerObj);
122 auto instance = AceType::MakeRefPtr<JSCustomDialogController>(ownerView);
123 if (ownerView == nullptr) {
124 instance->IncRefCount();
125 info.SetReturnValue(AceType::RawPtr(instance));
126 instance = nullptr;
127 return;
128 }
129
130 // Process builder function.
131 JSRef<JSVal> builderCallback = constructorArg->GetProperty("builder");
132 if (!builderCallback->IsUndefined() && builderCallback->IsFunction()) {
133 instance->jsBuilderFunction_ =
134 AceType::MakeRefPtr<JsWeakFunction>(ownerObj, JSRef<JSFunc>::Cast(builderCallback));
135 } else {
136 instance->jsBuilderFunction_ = nullptr;
137 instance->IncRefCount();
138 info.SetReturnValue(AceType::RawPtr(instance));
139 instance = nullptr;
140 return;
141 }
142
143 // Process cancel function.
144 JSRef<JSVal> cancelCallback = constructorArg->GetProperty("cancel");
145 if (!cancelCallback->IsUndefined() && cancelCallback->IsFunction()) {
146 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
147 auto jsCancelFunction = AceType::MakeRefPtr<JsWeakFunction>(ownerObj, JSRef<JSFunc>::Cast(cancelCallback));
148 instance->jsCancelFunction_ = jsCancelFunction;
149
150 auto onCancel = [execCtx = info.GetExecutionContext(), func = std::move(jsCancelFunction),
151 node = frameNode]() {
152 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
153 ACE_SCORING_EVENT("onCancel");
154 auto pipelineContext = PipelineContext::GetCurrentContext();
155 CHECK_NULL_VOID(pipelineContext);
156 pipelineContext->UpdateCurrentActiveNode(node);
157 func->Execute();
158 };
159 instance->dialogProperties_.onCancel = onCancel;
160 }
161
162 std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismissFunc = nullptr;
163 JSViewAbstract::ParseDialogCallback(constructorArg, onWillDismissFunc);
164 instance->dialogProperties_.onWillDismiss = onWillDismissFunc;
165
166 JSViewAbstract::ParseAppearDialogCallback(info, instance->dialogProperties_);
167
168 // Parses autoCancel.
169 JSRef<JSVal> autoCancelValue = constructorArg->GetProperty("autoCancel");
170 if (autoCancelValue->IsBoolean()) {
171 instance->dialogProperties_.autoCancel = autoCancelValue->ToBoolean();
172 }
173
174 // Parses customStyle.
175 JSRef<JSVal> customStyleValue = constructorArg->GetProperty("customStyle");
176 if (customStyleValue->IsBoolean()) {
177 instance->dialogProperties_.customStyle = customStyleValue->ToBoolean();
178 }
179
180 // Parse alignment
181 auto alignmentValue = constructorArg->GetProperty("alignment");
182 if (alignmentValue->IsNumber()) {
183 auto alignment = alignmentValue->ToNumber<int32_t>();
184 if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
185 instance->dialogProperties_.alignment = DIALOG_ALIGNMENT[alignment];
186 }
187 }
188
189 // Parse keyboardAvoidMode
190 auto avoidModeValue = constructorArg->GetProperty("keyboardAvoidMode");
191 if (avoidModeValue->IsNumber()) {
192 auto avoidMode = avoidModeValue->ToNumber<int32_t>();
193 if (avoidMode >= 0 && avoidMode < static_cast<int32_t>(KEYBOARD_AVOID_MODE.size())) {
194 instance->dialogProperties_.keyboardAvoidMode = KEYBOARD_AVOID_MODE[avoidMode];
195 }
196 }
197
198 // Parse keyboardAvoidDistance
199 auto avoidDistance = constructorArg->GetProperty("keyboardAvoidDistance");
200 if (avoidDistance->IsObject()) {
201 JSRef<JSObject> avoidDistanceobj = JSRef<JSObject>::Cast(avoidDistance);
202 auto avoidDisValue = avoidDistanceobj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
203 auto jsAvoidDisUnit = avoidDistanceobj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
204 DimensionUnit avoidDisUnit = OHOS::Ace::DimensionUnit::VP;
205 if (jsAvoidDisUnit->IsNumber()) {
206 avoidDisUnit = static_cast<DimensionUnit>(jsAvoidDisUnit->ToNumber<int32_t>());
207 }
208 if (avoidDisValue->IsNumber() && avoidDisValue->ToNumber<double>() >= 0 &&
209 avoidDisUnit >= OHOS::Ace::DimensionUnit::PX && avoidDisUnit <= OHOS::Ace::DimensionUnit::CALC &&
210 avoidDisUnit != OHOS::Ace::DimensionUnit::PERCENT) {
211 Dimension avoidDistanceDimension(avoidDisValue->ToNumber<double>(), avoidDisUnit);
212 instance->dialogProperties_.keyboardAvoidDistance = avoidDistanceDimension;
213 } else {
214 Dimension avoidDistanceDimension(DEFAULT_AVOID_DISTANCE, OHOS::Ace::DimensionUnit::VP);
215 instance->dialogProperties_.keyboardAvoidDistance = avoidDistanceDimension;
216 }
217 }
218
219 // Parse offset
220 auto offsetValue = constructorArg->GetProperty("offset");
221 if (offsetValue->IsObject()) {
222 auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
223 CalcDimension dx;
224 auto dxValue = offsetObj->GetProperty("dx");
225 JSViewAbstract::ParseJsDimensionVp(dxValue, dx);
226 CalcDimension dy;
227 auto dyValue = offsetObj->GetProperty("dy");
228 JSViewAbstract::ParseJsDimensionVp(dyValue, dy);
229 dx.ResetInvalidValue();
230 dy.ResetInvalidValue();
231 instance->dialogProperties_.offset = DimensionOffset(dx, dy);
232 }
233
234 // Parses gridCount.
235 auto gridCountValue = constructorArg->GetProperty("gridCount");
236 if (gridCountValue->IsNumber()) {
237 instance->dialogProperties_.gridCount = gridCountValue->ToNumber<int32_t>();
238 }
239
240 // Parse maskColor.
241 auto maskColorValue = constructorArg->GetProperty("maskColor");
242 Color maskColor;
243 if (JSViewAbstract::ParseJsColor(maskColorValue, maskColor)) {
244 instance->dialogProperties_.maskColor = maskColor;
245 }
246
247 // Parse maskRect.
248 auto maskRectValue = constructorArg->GetProperty("maskRect");
249 DimensionRect maskRect;
250 if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
251 instance->dialogProperties_.maskRect = maskRect;
252 }
253
254 // Parse backgroundColor.
255 auto backgroundColorValue = constructorArg->GetProperty("backgroundColor");
256 Color backgroundColor;
257 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
258 instance->dialogProperties_.backgroundColor = backgroundColor;
259 }
260
261 // Parse backgroundBlurStyle.
262 auto backgroundBlurStyle = constructorArg->GetProperty("backgroundBlurStyle");
263 if (backgroundBlurStyle->IsNumber()) {
264 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
265 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
266 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
267 instance->dialogProperties_.backgroundBlurStyle = blurStyle;
268 }
269 }
270
271 auto execContext = info.GetExecutionContext();
272 // Parse openAnimation.
273 auto openAnimationValue = constructorArg->GetProperty("openAnimation");
274 AnimationOption openAnimation;
275 if (ParseAnimation(execContext, openAnimationValue, openAnimation)) {
276 instance->dialogProperties_.openAnimation = openAnimation;
277 }
278
279 // Parse closeAnimation.
280 auto closeAnimationValue = constructorArg->GetProperty("closeAnimation");
281 AnimationOption closeAnimation;
282 if (ParseAnimation(execContext, closeAnimationValue, closeAnimation)) {
283 instance->dialogProperties_.closeAnimation = closeAnimation;
284 }
285
286 // Parse showInSubWindowValue.
287 auto showInSubWindowValue = constructorArg->GetProperty("showInSubWindow");
288 if (showInSubWindowValue->IsBoolean()) {
289 #if defined(PREVIEW)
290 LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Perform this operation on the "
291 "emulator or a real device instead.");
292 #else
293 instance->dialogProperties_.isShowInSubWindow = showInSubWindowValue->ToBoolean();
294 #endif
295 }
296
297 auto dialogLevelMode = constructorArg->GetProperty("levelMode");
298 if (dialogLevelMode->IsNumber() && !instance->dialogProperties_.isShowInSubWindow) {
299 auto levelMode = dialogLevelMode->ToNumber<int32_t>();
300 if (levelMode >= 0 && levelMode < static_cast<int32_t>(DIALOG_LEVEL_MODE.size())) {
301 instance->dialogProperties_.dialogLevelMode = DIALOG_LEVEL_MODE[levelMode];
302 }
303 }
304
305 auto dialogLevelUniqueId = constructorArg->GetProperty("levelUniqueId");
306 if (dialogLevelUniqueId->IsNumber()) {
307 instance->dialogProperties_.dialogLevelUniqueId = dialogLevelUniqueId->ToNumber<int32_t>();
308 }
309
310 auto immersiveMode = constructorArg->GetProperty("immersiveMode");
311 if (immersiveMode->IsNumber()) {
312 auto immersiveVal = immersiveMode->ToNumber<int32_t>();
313 if (immersiveVal >= 0 && immersiveVal < static_cast<int32_t>(DIALOG_IMMERSIVE_MODE.size())) {
314 instance->dialogProperties_.dialogImmersiveMode = DIALOG_IMMERSIVE_MODE[immersiveVal];
315 }
316 }
317
318 // Parse isModal.
319 auto isModalValue = constructorArg->GetProperty("isModal");
320 if (isModalValue->IsBoolean()) {
321 instance->dialogProperties_.isModal = isModalValue->ToBoolean();
322 }
323
324 // Parse levelOrder.
325 ParseCustomDialogLevelOrder(instance->dialogProperties_, constructorArg);
326 ParseCustomDialogFocusable(instance->dialogProperties_, constructorArg);
327
328 instance->dialogProperties_.controllerId = controllerId.fetch_add(1, std::memory_order_relaxed);
329 JSViewAbstract::SetDialogProperties(constructorArg, instance->dialogProperties_);
330 JSViewAbstract::SetDialogHoverModeProperties(constructorArg, instance->dialogProperties_);
331 JSViewAbstract::SetDialogBlurStyleOption(constructorArg, instance->dialogProperties_);
332 JSViewAbstract::SetDialogEffectOption(constructorArg, instance->dialogProperties_);
333 instance->IncRefCount();
334 info.SetReturnValue(AceType::RawPtr(instance));
335 }
336 }
337
DestructorCallback(JSCustomDialogController * controller)338 void JSCustomDialogController::DestructorCallback(JSCustomDialogController* controller)
339 {
340 if (controller != nullptr) {
341 controller->ownerView_ = nullptr;
342 controller->DecRefCount();
343 }
344 }
345
JsOpenDialog(const JSCallbackInfo & info)346 void JSCustomDialogController::JsOpenDialog(const JSCallbackInfo& info)
347 {
348 if (!jsBuilderFunction_) {
349 return;
350 }
351
352 if (this->ownerView_ == nullptr) {
353 return;
354 }
355 auto containerId = this->ownerView_->GetInstanceId();
356 ContainerScope containerScope(containerId);
357 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
358 auto pipelineContext = PipelineContext::GetCurrentContext();
359 CHECK_NULL_VOID(pipelineContext);
360
361 auto scopedDelegate = EngineHelper::GetCurrentDelegate();
362 if (!scopedDelegate) {
363 // this case usually means there is no foreground container, need to figure out the reason.
364 return;
365 }
366
367 auto buildFunc = [buildfunc = jsBuilderFunction_, node = frameNode, context = pipelineContext]() {
368 {
369 ACE_SCORING_EVENT("CustomDialog.builder");
370 context->UpdateCurrentActiveNode(node);
371 buildfunc->Execute();
372 }
373 };
374
375 auto cancelTask = ([cancelCallback = jsCancelFunction_, node = frameNode, context = pipelineContext]() {
376 if (cancelCallback) {
377 ACE_SCORING_EVENT("CustomDialog.cancel");
378 context->UpdateCurrentActiveNode(node);
379 cancelCallback->Execute();
380 }
381 });
382
383 auto container = Container::Current();
384 if (container && container->IsScenceBoardWindow() && !dialogProperties_.windowScene.Upgrade()) {
385 dialogProperties_.isScenceBoardDialog = true;
386 auto viewNode = this->ownerView_->GetViewNode();
387 CHECK_NULL_VOID(viewNode);
388 auto parentCustom = AceType::DynamicCast<NG::CustomNode>(viewNode);
389 CHECK_NULL_VOID(parentCustom);
390 auto parent = parentCustom->GetParent();
391 while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
392 parent = parent->GetParent();
393 }
394 if (parent) {
395 dialogProperties_.windowScene = parent;
396 }
397 }
398 dialogProperties_.isSysBlurStyle =
399 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TWELVE) ? true : false;
400 CustomDialogControllerModel::GetInstance()->SetOpenDialog(dialogProperties_, WeakClaim(this), dialogs_, pending_,
401 isShown_, std::move(cancelTask), std::move(buildFunc), dialogComponent_, customDialog_, dialogOperation_);
402 }
403
JsCloseDialog(const JSCallbackInfo & info)404 void JSCustomDialogController::JsCloseDialog(const JSCallbackInfo& info)
405 {
406
407 if (this->ownerView_ == nullptr) {
408 return;
409 }
410 auto containerId = this->ownerView_->GetInstanceId();
411 ContainerScope containerScope(containerId);
412
413 auto scopedDelegate = EngineHelper::GetCurrentDelegate();
414 if (!scopedDelegate) {
415 // this case usually means there is no foreground container, need to figure out the reason.
416 return;
417 }
418
419 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
420 auto cancelTask = ([cancelCallback = jsCancelFunction_, node = frameNode]() {
421 if (cancelCallback) {
422 ACE_SCORING_EVENT("CustomDialog.cancel");
423 auto pipelineContext = PipelineContext::GetCurrentContext();
424 CHECK_NULL_VOID(pipelineContext);
425 pipelineContext->UpdateCurrentActiveNode(node);
426 cancelCallback->Execute();
427 }
428 });
429
430 CustomDialogControllerModel::GetInstance()->SetCloseDialog(dialogProperties_, WeakClaim(this), dialogs_, pending_,
431 isShown_, std::move(cancelTask), dialogComponent_, customDialog_, dialogOperation_);
432 }
433
ParseAnimation(const JsiExecutionContext & execContext,const JsiRef<JsiValue> & animationValue,AnimationOption & result)434 bool JSCustomDialogController::ParseAnimation(
435 const JsiExecutionContext& execContext, const JsiRef<JsiValue>& animationValue, AnimationOption& result)
436 {
437 if (animationValue->IsNull() || !animationValue->IsObject()) {
438 return false;
439 }
440
441 JSRef<JSObject> obj = JSRef<JSObject>::Cast(animationValue);
442 // If the attribute does not exist, the default value is used.
443 int32_t duration = obj->GetPropertyValue<int32_t>("duration", DEFAULT_ANIMATION_DURATION);
444 int32_t delay = obj->GetPropertyValue<int32_t>("delay", 0);
445 int32_t iterations = obj->GetPropertyValue<int32_t>("iterations", 1);
446 float tempo = obj->GetPropertyValue<float>("tempo", 1.0);
447 auto finishCallbackType = static_cast<FinishCallbackType>(obj->GetPropertyValue<int32_t>("finishCallbackType", 0));
448 if (tempo < 0) {
449 tempo = 1.0f;
450 } else if (tempo == 0) {
451 tempo = 1000.0f;
452 }
453 auto direction = StringToAnimationDirection(obj->GetPropertyValue<std::string>("playMode", "normal"));
454 RefPtr<Curve> curve;
455 JSRef<JSVal> curveArgs = obj->GetProperty("curve");
456 if (curveArgs->IsString()) {
457 curve = CreateCurve(obj->GetPropertyValue<std::string>("curve", "linear"));
458 } else if (curveArgs->IsObject()) {
459 JSRef<JSObject> curveObj = JSRef<JSObject>::Cast(curveArgs);
460 JSRef<JSVal> curveString = curveObj->GetProperty("__curveString");
461 if (!curveString->IsString()) {
462 // Default AnimationOption which is invalid.
463 return false;
464 }
465 curve = CreateCurve(curveString->ToString());
466 } else {
467 curve = Curves::EASE_IN_OUT;
468 }
469 result.SetDuration(duration);
470 result.SetDelay(delay);
471 result.SetIteration(iterations);
472 result.SetTempo(tempo);
473 result.SetAnimationDirection(direction);
474 result.SetCurve(curve);
475 result.SetFinishCallbackType(finishCallbackType);
476
477 JSRef<JSVal> onFinish = obj->GetProperty("onFinish");
478 std::function<void()> onFinishEvent;
479 if (onFinish->IsFunction()) {
480 auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
481 auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
482 onFinishEvent = [execCtx = execContext, func = std::move(jsFunc), node = frameNode]() {
483 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
484 ACE_SCORING_EVENT("CustomDialog.onFinish");
485 auto pipelineContext = PipelineContext::GetCurrentContext();
486 CHECK_NULL_VOID(pipelineContext);
487 pipelineContext->UpdateCurrentActiveNode(node);
488 func->Execute();
489 };
490 result.SetOnFinishEvent(onFinishEvent);
491 }
492 return true;
493 }
494
JSBind(BindingTarget object)495 void JSCustomDialogController::JSBind(BindingTarget object)
496 {
497 JSClass<JSCustomDialogController>::Declare("NativeCustomDialogController");
498 JSClass<JSCustomDialogController>::CustomMethod("open", &JSCustomDialogController::JsOpenDialog);
499 JSClass<JSCustomDialogController>::CustomMethod("close", &JSCustomDialogController::JsCloseDialog);
500 JSClass<JSCustomDialogController>::Bind(
501 object, &JSCustomDialogController::ConstructorCallback, &JSCustomDialogController::DestructorCallback);
502 }
503 } // namespace OHOS::Ace::Framework
504