• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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/js_navdestination.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "base/memory/ace_type.h"
20 #include "base/utils/utils.h"
21 #include "base/system_bar/system_bar_style.h"
22 #include "bridge/declarative_frontend/engine/functions/js_function.h"
23 #include "bridge/declarative_frontend/engine/js_converter.h"
24 #include "bridge/declarative_frontend/engine/js_execution_scope_defines.h"
25 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
26 #include "bridge/declarative_frontend/engine/js_types.h"
27 #include "bridge/declarative_frontend/jsview/js_navdestination_context.h"
28 #include "bridge/declarative_frontend/jsview/js_navigation.h"
29 #include "bridge/declarative_frontend/jsview/js_navigation_utils.h"
30 #include "bridge/declarative_frontend/jsview/js_navdestination_scrollable_processor.h"
31 #include "bridge/declarative_frontend/jsview/js_utils.h"
32 #include "core/components_ng/base/view_stack_model.h"
33 #include "core/components_ng/base/view_stack_processor.h"
34 #include "core/components_ng/manager/navigation/navigation_manager.h"
35 #include "core/components_ng/pattern/navigation/navigation_options.h"
36 #include "core/components_ng/pattern/navrouter/navdestination_model_ng.h"
37 
38 namespace OHOS::Ace {
39 std::unique_ptr<NavDestinationModel> NavDestinationModel::instance_ = nullptr;
40 std::mutex NavDestinationModel::mutex_;
41 
GetInstance()42 NavDestinationModel* NavDestinationModel::GetInstance()
43 {
44     if (!instance_) {
45         std::lock_guard<std::mutex> lock(mutex_);
46         instance_.reset(new NG::NavDestinationModelNG());
47     }
48     return instance_.get();
49 }
50 
51 } // namespace OHOS::Ace
52 
53 namespace OHOS::Ace::Framework {
54 
55 namespace {
56 constexpr int32_t PARAMATER_LENGTH_ONE = 1;
57 constexpr int32_t PARAMATER_LENGTH_TWO = 2;
58 constexpr int32_t JS_ENUM_TRANSITIONTYPE_NONE = 1;
59 constexpr int32_t JS_ENUM_TRANSITIONTYPE_TITLE = 2;
60 constexpr int32_t JS_ENUM_TRANSITIONTYPE_CONTENT = 3;
61 constexpr int32_t JS_ENUM_TRANSITIONTYPE_FADE = 4;
62 constexpr int32_t JS_ENUM_TRANSITIONTYPE_EXPLODE = 5;
63 constexpr int32_t JS_ENUM_TRANSITIONTYPE_SLIDE_RIGHT = 6;
64 constexpr int32_t JS_ENUM_TRANSITIONTYPE_SLIDE_BOTTOM = 7;
65 constexpr int32_t LAYOUT_SAFE_AREA_TYPE_LIMIT = 2;
66 constexpr int32_t LAYOUT_SAFE_AREA_EDGE_LIMIT = 6;
67 constexpr char MORE_BUTTON_OPTIONS_PROPERTY[] = "moreButtonOptions";
68 
69 // sources in js_window_utils.h
70 enum class ApiOrientation : uint32_t {
71     BEGIN = 0,
72     UNSPECIFIED = BEGIN,
73     PORTRAIT = 1,
74     LANDSCAPE = 2,
75     PORTRAIT_INVERTED = 3,
76     LANDSCAPE_INVERTED = 4,
77     AUTO_ROTATION = 5,
78     AUTO_ROTATION_PORTRAIT = 6,
79     AUTO_ROTATION_LANDSCAPE = 7,
80     AUTO_ROTATION_RESTRICTED = 8,
81     AUTO_ROTATION_PORTRAIT_RESTRICTED = 9,
82     AUTO_ROTATION_LANDSCAPE_RESTRICTED = 10,
83     LOCKED = 11,
84     AUTO_ROTATION_UNSPECIFIED = 12,
85     USER_ROTATION_PORTRAIT = 13,
86     USER_ROTATION_LANDSCAPE = 14,
87     USER_ROTATION_PORTRAIT_INVERTED = 15,
88     USER_ROTATION_LANDSCAPE_INVERTED = 16,
89     FOLLOW_DESKTOP = 17,
90     END = FOLLOW_DESKTOP,
91 };
92 
93 const std::map<ApiOrientation, Orientation> JS_TO_NATIVE_ORIENTATION_MAP {
94     {ApiOrientation::UNSPECIFIED,                           Orientation::UNSPECIFIED                        },
95     {ApiOrientation::PORTRAIT,                              Orientation::VERTICAL                           },
96     {ApiOrientation::LANDSCAPE,                             Orientation::HORIZONTAL                         },
97     {ApiOrientation::PORTRAIT_INVERTED,                     Orientation::REVERSE_VERTICAL                   },
98     {ApiOrientation::LANDSCAPE_INVERTED,                    Orientation::REVERSE_HORIZONTAL                 },
99     {ApiOrientation::AUTO_ROTATION,                         Orientation::SENSOR                             },
100     {ApiOrientation::AUTO_ROTATION_PORTRAIT,                Orientation::SENSOR_VERTICAL                    },
101     {ApiOrientation::AUTO_ROTATION_LANDSCAPE,               Orientation::SENSOR_HORIZONTAL                  },
102     {ApiOrientation::AUTO_ROTATION_RESTRICTED,              Orientation::AUTO_ROTATION_RESTRICTED           },
103     {ApiOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED,     Orientation::AUTO_ROTATION_PORTRAIT_RESTRICTED  },
104     {ApiOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED,    Orientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED },
105     {ApiOrientation::LOCKED,                                Orientation::LOCKED                             },
106     {ApiOrientation::AUTO_ROTATION_UNSPECIFIED,             Orientation::AUTO_ROTATION_UNSPECIFIED          },
107     {ApiOrientation::USER_ROTATION_PORTRAIT,                Orientation::USER_ROTATION_PORTRAIT             },
108     {ApiOrientation::USER_ROTATION_LANDSCAPE,               Orientation::USER_ROTATION_LANDSCAPE            },
109     {ApiOrientation::USER_ROTATION_PORTRAIT_INVERTED,       Orientation::USER_ROTATION_PORTRAIT_INVERTED    },
110     {ApiOrientation::USER_ROTATION_LANDSCAPE_INVERTED,      Orientation::USER_ROTATION_LANDSCAPE_INVERTED   },
111     {ApiOrientation::FOLLOW_DESKTOP,                        Orientation::FOLLOW_DESKTOP                     },
112 };
113 
ParseTransitionType(int32_t value)114 NG::NavigationSystemTransitionType ParseTransitionType(int32_t value)
115 {
116     switch (value) {
117         case JS_ENUM_TRANSITIONTYPE_NONE:
118             return NG::NavigationSystemTransitionType::NONE;
119         case JS_ENUM_TRANSITIONTYPE_TITLE:
120             return NG::NavigationSystemTransitionType::TITLE;
121         case JS_ENUM_TRANSITIONTYPE_CONTENT:
122             return NG::NavigationSystemTransitionType::CONTENT;
123         case JS_ENUM_TRANSITIONTYPE_FADE:
124             return NG::NavigationSystemTransitionType::FADE;
125         case JS_ENUM_TRANSITIONTYPE_EXPLODE:
126             return NG::NavigationSystemTransitionType::EXPLODE;
127         case JS_ENUM_TRANSITIONTYPE_SLIDE_RIGHT:
128             return NG::NavigationSystemTransitionType::SLIDE_RIGHT;
129         case JS_ENUM_TRANSITIONTYPE_SLIDE_BOTTOM:
130             return NG::NavigationSystemTransitionType::SLIDE_BOTTOM;
131         default:
132             return NG::NavigationSystemTransitionType::DEFAULT;
133     }
134 }
135 
ParseCommonTitle(const JSRef<JSObject> & jsObj)136 bool ParseCommonTitle(const JSRef<JSObject>& jsObj)
137 {
138     JSRef<JSVal> subtitle = jsObj->GetProperty("sub");
139     JSRef<JSVal> title = jsObj->GetProperty("main");
140     std::string mainTitle;
141     std::string subTitle;
142     RefPtr<ResourceObject> subResObj;
143     RefPtr<ResourceObject> mainResObj;
144     bool hasSub = JSViewAbstract::ParseJsString(subtitle, subTitle, subResObj);
145     bool hasMain = JSViewAbstract::ParseJsString(title, mainTitle, mainResObj);
146     if (hasSub || hasMain) {
147         if (SystemProperties::ConfigChangePerform() && (mainResObj || subResObj)) {
148             return NG::NavDestinationModelNG::GetInstance()->ParseCommonTitle(
149                 hasSub, hasMain, subResObj, mainResObj);
150         } else {
151             return NG::NavDestinationModelNG::GetInstance()->ParseCommonTitle(
152                 hasSub, hasMain, subTitle, mainTitle);
153         }
154     }
155     return false;
156 }
157 
ParseCommonAndCustomTitle(const JSRef<JSObject> & jsObj)158 void ParseCommonAndCustomTitle(const JSRef<JSObject>& jsObj)
159 {
160     // NavigationCommonTitle
161     if (ParseCommonTitle(jsObj)) {
162         return;
163     }
164     // CustomBuilder | NavigationCustomTitle
165     CalcDimension titleHeight;
166     if (!jsObj->HasProperty("height")) {
167         NavDestinationModel::GetInstance()->SetTitleHeight(titleHeight, false);
168         return;
169     }
170     JSRef<JSVal> height = jsObj->GetProperty("height");
171     RefPtr<ResourceObject> heightResObj;
172     bool isValid = JSContainerBase::ParseJsDimensionVpNG(height, titleHeight, heightResObj);
173     if (height->IsString()) {
174         std::string heightValue;
175         JSViewAbstract::ParseJsString(height, heightValue);
176         if (heightValue == NG::TITLE_MAIN_WITH_SUB) {
177             NavDestinationModel::GetInstance()->SetTitleHeight(NG::DOUBLE_LINE_TITLEBAR_HEIGHT);
178             return;
179         }
180         if (heightValue == NG::TITLE_MAIN) {
181             NavDestinationModel::GetInstance()->SetTitleHeight(NG::SINGLE_LINE_TITLEBAR_HEIGHT);
182             return;
183         }
184     }
185     if (!isValid || titleHeight.Value() < 0) {
186         NavDestinationModel::GetInstance()->SetTitleHeight(Dimension(), true);
187         return;
188     }
189     if (SystemProperties::ConfigChangePerform() && heightResObj) {
190         NavDestinationModel::GetInstance()->SetTitleHeight(titleHeight, heightResObj);
191         return;
192     }
193     NavDestinationModel::GetInstance()->SetTitleHeight(titleHeight);
194 }
195 
ParseBackButtonText(const JSCallbackInfo & info,RefPtr<PixelMap> & pixMap,const NG::ImageOption & imageOption,const std::function<void (WeakPtr<NG::FrameNode>)> & iconSymbol,std::string src,const std::vector<std::string> & nameList,RefPtr<ResourceObject> & backButtonIconResObj)196 void ParseBackButtonText(const JSCallbackInfo& info, RefPtr<PixelMap>& pixMap,
197     const NG::ImageOption& imageOption, const std::function<void(WeakPtr<NG::FrameNode>)>& iconSymbol, std::string src,
198     const std::vector<std::string>& nameList, RefPtr<ResourceObject>& backButtonIconResObj)
199 {
200     std::string backButtonAccessibilityText;
201     RefPtr<ResourceObject> backButtonTextResObj;
202     JSViewAbstract::ParseJsString(info[1], backButtonAccessibilityText, backButtonTextResObj);
203     if (SystemProperties::ConfigChangePerform()) {
204         if (backButtonIconResObj && backButtonTextResObj) {
205             NavDestinationModel::GetInstance()->SetBackButtonIconSrcAndTextRes(
206                 iconSymbol, backButtonIconResObj, imageOption, pixMap, nameList, true, backButtonTextResObj);
207             return;
208         }
209         if (backButtonTextResObj) {
210             NavDestinationModel::GetInstance()->SetBackButtonIconTextRes(
211                 iconSymbol, src, imageOption, pixMap, nameList, true, backButtonTextResObj);
212             return;
213         }
214         if (backButtonIconResObj) {
215             NavDestinationModel::GetInstance()->SetBackButtonIcon(
216                 iconSymbol, backButtonIconResObj, imageOption, pixMap, nameList, true, backButtonAccessibilityText);
217             return;
218         }
219     }
220     NavDestinationModel::GetInstance()->SetBackButtonIcon(
221         iconSymbol, src, imageOption, pixMap, nameList, true, backButtonAccessibilityText);
222 }
223 } // namespace
224 
Create()225 void JSNavDestination::Create()
226 {
227     NavDestinationModel::GetInstance()->Create();
228     NavDestinationModel::GetInstance()->SetScrollableProcessor(
229         []() { return AceType::MakeRefPtr<JSNavDestinationScrollableProcessor>(); });
230 }
231 
Create(const JSCallbackInfo & info)232 void JSNavDestination::Create(const JSCallbackInfo& info)
233 {
234     if (info.Length() <= 0) {
235         NavDestinationModel::GetInstance()->Create();
236         NavDestinationModel::GetInstance()->SetScrollableProcessor(
237             []() { return AceType::MakeRefPtr<JSNavDestinationScrollableProcessor>(); });
238         return;
239     }
240 
241     std::string moduleName;
242     std::string pagePath;
243     if (info.Length() == 1) {
244         // input format: builder/pathInfo
245         if (info[0]->IsFunction()) {
246             // first parameter = builder
247             auto builderFunctionJS = info[0];
248             auto builderFunc = [context = info.GetExecutionContext(), builder = std::move(builderFunctionJS)]() {
249                 JAVASCRIPT_EXECUTION_SCOPE(context)
250                 JSRef<JSFunc>::Cast(builder)->Call(JSRef<JSObject>());
251             };
252             auto ctx = AceType::MakeRefPtr<NG::NavDestinationContext>();
253             auto navPathInfo = AceType::MakeRefPtr<JSNavPathInfo>();
254             ctx->SetNavPathInfo(navPathInfo);
255             NavDestinationModel::GetInstance()->Create(std::move(builderFunc), std::move(ctx));
256             NavDestinationModel::GetInstance()->SetScrollableProcessor(
257                 []() { return AceType::MakeRefPtr<JSNavDestinationScrollableProcessor>(); });
258             return;
259         } else if (info[0]->IsObject()) {
260             // first parameter = pathInfo{'moduleName': stringA, 'pagePath': stringB}
261             auto infoObj = JSRef<JSObject>::Cast(info[0]);
262             if (!infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->IsString() ||
263                 !infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->IsString()) {
264                 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "navDestination current pageInfo is invalid");
265                 return;
266             }
267             moduleName = infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->ToString();
268             pagePath = infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->ToString();
269             NavDestinationModel::GetInstance()->Create();
270             NavDestinationModel::GetInstance()->SetScrollableProcessor(
271                 []() { return AceType::MakeRefPtr<JSNavDestinationScrollableProcessor>(); });
272             NavDestinationModel::GetInstance()->SetNavDestinationPathInfo(moduleName, pagePath);
273             return;
274         }
275         TAG_LOGE(AceLogTag::ACE_NAVIGATION,
276             "current input info is neither buildFunction or navDestination usefulInfo");
277         return;
278     } else if (info.Length() == 2) {
279         // parameter = builder(maybe empty) + pathInfo
280         if (!info[0]->IsFunction() || !info[1]->IsObject()) {
281             TAG_LOGE(AceLogTag::ACE_NAVIGATION, "buider or pageInfo is invalid");
282             return;
283         }
284         auto builderFunctionJS = info[0];
285         auto builderFunc = [context = info.GetExecutionContext(), builder = std::move(builderFunctionJS)]() {
286             JAVASCRIPT_EXECUTION_SCOPE(context)
287             JSRef<JSFunc>::Cast(builder)->Call(JSRef<JSObject>());
288         };
289         auto ctx = AceType::MakeRefPtr<NG::NavDestinationContext>();
290         auto navPathInfo = AceType::MakeRefPtr<JSNavPathInfo>();
291         ctx->SetNavPathInfo(navPathInfo);
292 
293         auto infoObj = JSRef<JSObject>::Cast(info[1]);
294         if (!infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->IsString() ||
295             !infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->IsString()) {
296             TAG_LOGE(AceLogTag::ACE_NAVIGATION, "navDestination current pageInfo is invalid");
297             return;
298         }
299         moduleName = infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->ToString();
300         pagePath = infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->ToString();
301         NavDestinationModel::GetInstance()->Create(std::move(builderFunc), std::move(ctx));
302         NavDestinationModel::GetInstance()->SetScrollableProcessor(
303             []() { return AceType::MakeRefPtr<JSNavDestinationScrollableProcessor>(); });
304         NavDestinationModel::GetInstance()->SetNavDestinationPathInfo(moduleName, pagePath);
305     }
306 }
307 
SetHideTitleBar(const JSCallbackInfo & info)308 void JSNavDestination::SetHideTitleBar(const JSCallbackInfo& info)
309 {
310     bool isHide = false;
311     if (info.Length() > 0 && info[0]->IsBoolean()) {
312         isHide = info[0]->ToBoolean();
313     }
314     bool isAnimated = false;
315     if (info.Length() > 1 && info[1]->IsBoolean()) {
316         isAnimated = info[1]->ToBoolean();
317     }
318     NavDestinationModel::GetInstance()->SetHideTitleBar(isHide, isAnimated);
319 }
320 
SetHideBackButton(const JSCallbackInfo & info)321 void JSNavDestination::SetHideBackButton(const JSCallbackInfo& info)
322 {
323     bool isHide = false;
324     if (info.Length() > 0 && info[0]->IsBoolean()) {
325         isHide = info[0]->ToBoolean();
326     }
327     NavDestinationModel::GetInstance()->SetHideBackButton(isHide);
328 }
329 
SetTitle(const JSCallbackInfo & info)330 void JSNavDestination::SetTitle(const JSCallbackInfo& info)
331 {
332     // Resource and string type.
333     std::string title;
334     RefPtr<ResourceObject> mainResObj;
335     NavDestinationModel::GetInstance()->ResetResObj(
336         NavDestinationPatternType::TITLE_BAR, "navDestination.title.commonMainTitle");
337     NavDestinationModel::GetInstance()->ResetResObj(
338         NavDestinationPatternType::TITLE_BAR, "navDestination.title.commonSubTitle");
339     NavDestinationModel::GetInstance()->ResetResObj(
340         NavDestinationPatternType::TITLE_BAR, "navDestination.title.customtitle");
341     if (JSViewAbstract::ParseJsString(info[0], title, mainResObj)) {
342         if (SystemProperties::ConfigChangePerform() && mainResObj) {
343             NavDestinationModel::GetInstance()->ParseCommonTitle(false, true, nullptr, mainResObj);
344         } else {
345             NavDestinationModel::GetInstance()->ParseCommonTitle(false, true, "", title);
346         }
347     } else if (info[0]->IsObject()) {
348         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
349         ParseCommonAndCustomTitle(jsObj);
350         JSRef<JSVal> builderObject = jsObj->GetProperty("builder");
351         if (builderObject->IsFunction()) {
352             ViewStackModel::GetInstance()->NewScope();
353             JsFunction jsBuilderFunc(info.This(), JSRef<JSFunc>::Cast(builderObject));
354             ACE_SCORING_EVENT("Navdestination.title.builder");
355             jsBuilderFunc.Execute();
356             auto customNode = ViewStackModel::GetInstance()->Finish();
357             NavDestinationModel::GetInstance()->SetCustomTitle(customNode);
358         }
359     } else {
360         NavDestinationModel::GetInstance()->ParseCommonTitle(false, false, "", "");
361     }
362 
363     NG::NavigationTitlebarOptions options;
364     NavDestinationModel::GetInstance()->ResetResObj(
365         NavDestinationPatternType::TITLE_BAR, "navDestination.navigationTitlebarOptions");
366     JSNavigationUtils::ParseTitleBarOptions(info, false, options);
367     NavDestinationModel::GetInstance()->SetTitlebarOptions(std::move(options));
368 }
369 
SetBackButtonIcon(const JSCallbackInfo & info)370 void JSNavDestination::SetBackButtonIcon(const JSCallbackInfo& info)
371 {
372     // srcType、pixmap、string
373     if (info.Length() < 1) {
374         return;
375     }
376     NavDestinationModel::GetInstance()->ResetResObj(
377         NavDestinationPatternType::TITLE_BAR, "navDestination.backButtonIcon.icon");
378     NavDestinationModel::GetInstance()->ResetResObj(
379         NavDestinationPatternType::TITLE_BAR, "navDestination.backButtonIcon.accessibilityText");
380     std::string src;
381     RefPtr<ResourceObject> backButtonIconResObj;
382     auto noPixMap = ParseJsMedia(info[0], src, backButtonIconResObj);
383 
384     RefPtr<PixelMap> pixMap = nullptr;
385     auto isValidImage = false;
386 #if defined(PIXEL_MAP_SUPPORTED)
387     if (!noPixMap) {
388         pixMap = CreatePixelMapFromNapiValue(info[0]);
389     }
390 #endif
391     if (noPixMap || pixMap != nullptr) {
392         isValidImage = true;
393     }
394     std::vector<std::string> nameList;
395     NG::ImageOption imageOption;
396     std::string bundleName;
397     std::string moduleName;
398     GetJsMediaBundleInfo(info[0], bundleName, moduleName);
399     nameList.emplace_back(bundleName);
400     nameList.emplace_back(moduleName);
401     imageOption.noPixMap = noPixMap;
402     imageOption.isValidImage = isValidImage;
403     std::function<void(WeakPtr<NG::FrameNode>)> iconSymbol = nullptr;
404     auto isSymbol = info[0]->IsObject() && src.empty() && pixMap == nullptr;
405     if (isSymbol) {
406         SetSymbolOptionApply(info, iconSymbol, info[0]);
407     }
408     std::string backButtonAccessibilityText;
409     bool configChange = SystemProperties::ConfigChangePerform();
410     if (info.Length() > 1) {
411         if (!info[1]->IsNull() && !info[1]->IsUndefined()) {
412             ParseBackButtonText(info, pixMap, imageOption, iconSymbol, src, nameList, backButtonIconResObj);
413             return;
414         }
415     }
416     if (configChange && backButtonIconResObj) {
417         NavDestinationModel::GetInstance()->SetBackButtonIcon(
418             iconSymbol, backButtonIconResObj, imageOption, pixMap, nameList);
419     } else {
420         NavDestinationModel::GetInstance()->SetBackButtonIcon(iconSymbol, src, imageOption, pixMap, nameList);
421     }
422 }
423 
SetOnShown(const JSCallbackInfo & info)424 void JSNavDestination::SetOnShown(const JSCallbackInfo& info)
425 {
426     if (!info[0]->IsFunction()) {
427         return;
428     }
429 
430     auto onShownCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
431     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
432     auto onShown = [execCtx = info.GetExecutionContext(), func = std::move(onShownCallback), node = targetNode]() {
433         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
434         ACE_SCORING_EVENT("NavDestination.onShown");
435         PipelineContext::SetCallBackNode(node);
436         JSRef<JSVal> params[1];
437         params[0] = JSRef<JSVal>::Make(ToJSValue("undefined"));
438         func->ExecuteJS(1, params);
439     };
440     NavDestinationModel::GetInstance()->SetOnShown(std::move(onShown));
441     info.ReturnSelf();
442 }
443 
SetOnHidden(const JSCallbackInfo & info)444 void JSNavDestination::SetOnHidden(const JSCallbackInfo& info)
445 {
446     if (!info[0]->IsFunction()) {
447         return;
448     }
449     auto onHiddenCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
450     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
451     auto onHidden = [execCtx = info.GetExecutionContext(), func = std::move(onHiddenCallback), node = targetNode]() {
452         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
453         ACE_SCORING_EVENT("NavDestination.onHidden");
454         PipelineContext::SetCallBackNode(node);
455         func->ExecuteJS();
456     };
457     NavDestinationModel::GetInstance()->SetOnHidden(std::move(onHidden));
458     info.ReturnSelf();
459 }
460 
SetOnBackPressed(const JSCallbackInfo & info)461 void JSNavDestination::SetOnBackPressed(const JSCallbackInfo& info)
462 {
463     if (!info[0]->IsFunction()) {
464         return;
465     }
466     auto onBackPressedCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
467     auto onBackPressed = [execCtx = info.GetExecutionContext(), func = std::move(onBackPressedCallback)]() -> bool {
468         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false);
469         ACE_SCORING_EVENT("NavDestination.onBackPressed");
470         return (func->ExecuteJS())->ToBoolean();
471     };
472     NavDestinationModel::GetInstance()->SetOnBackPressed(std::move(onBackPressed));
473     info.ReturnSelf();
474 }
475 
SetOnReady(const JSCallbackInfo & info)476 void JSNavDestination::SetOnReady(const JSCallbackInfo& info)
477 {
478     if (!info[0]->IsFunction()) {
479         return;
480     }
481     auto onReadyCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
482     auto onReady = [execCtx = info.GetExecutionContext(), func = std::move(onReadyCallback)](
483                        RefPtr<NG::NavDestinationContext> context) {
484         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
485         auto jsContext = JSClass<JSNavDestinationContext>::NewInstance();
486         auto jsNavDestinationContext = Referenced::Claim(jsContext->Unwrap<JSNavDestinationContext>());
487         CHECK_NULL_VOID(jsNavDestinationContext);
488         jsNavDestinationContext->SetNavDestinationContext(context);
489         ACE_SCORING_EVENT("NavDestination.onReady");
490         JSRef<JSVal> params[1];
491         params[0] = jsContext;
492         func->ExecuteJS(1, params);
493     };
494     NavDestinationModel::GetInstance()->SetOnReady(std::move(onReady));
495     info.ReturnSelf();
496 }
497 
SetMode(const JSCallbackInfo & info)498 void JSNavDestination::SetMode(const JSCallbackInfo& info)
499 {
500     if (!info[0]->IsNumber()) {
501         // set default back ground color
502         NavDestinationModel::GetInstance()->SetNavDestinationMode(NG::NavDestinationMode::STANDARD);
503         return;
504     }
505     auto mode = info[0]->ToNumber<int32_t>();
506     NavDestinationModel::GetInstance()->SetNavDestinationMode(static_cast<NG::NavDestinationMode>(mode));
507 }
508 
SetMenus(const JSCallbackInfo & info)509 void JSNavDestination::SetMenus(const JSCallbackInfo& info)
510 {
511     if (info.Length() < 1) {
512         return;
513     }
514 
515     NavDestinationModel::GetInstance()->ResetResObj(
516         NavDestinationPatternType::NAV_DESTINATION, "navDestination.menuItems");
517     NavDestinationModel::GetInstance()->ResetResObj(
518         NavDestinationPatternType::NAV_DESTINATION, "navDestination.navigationMenuOptions");
519     NG::NavigationMenuOptions options;
520     if (info.Length() > 1 && info[1]->IsObject()) {
521         auto optObj = JSRef<JSObject>::Cast(info[1]);
522         auto moreButtonProperty = optObj->GetProperty(MORE_BUTTON_OPTIONS_PROPERTY);
523         JSNavigationUtils::ParseMenuOptions(moreButtonProperty, options);
524     }
525     if (info[0]->IsUndefined() || info[0]->IsArray()) {
526         std::vector<NG::BarItem> menuItems;
527         if (info[0]->IsUndefined()) {
528             menuItems = {};
529         } else {
530             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
531             JSNavigationUtils::ParseBarItems(targetNode, info, JSRef<JSArray>::Cast(info[0]), menuItems);
532         }
533         NavDestinationModel::GetInstance()->SetMenuItems(std::move(menuItems));
534         NavDestinationModel::GetInstance()->SetMenuOptions(std::move(options));
535         return;
536     } else if (info[0]->IsObject()) {
537         auto builderObject = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
538         if (builderObject->IsFunction()) {
539             ViewStackModel::GetInstance()->NewScope();
540             JsFunction jsBuilderFunc(info.This(), JSRef<JSObject>::Cast(builderObject));
541             ACE_SCORING_EVENT("NavDestiNation.menu.builder");
542             jsBuilderFunc.Execute();
543             auto customNode = ViewStackModel::GetInstance()->Finish();
544             NavDestinationModel::GetInstance()->SetCustomMenu(customNode);
545             NavDestinationModel::GetInstance()->SetMenuOptions(std::move(options));
546         }
547     }
548 }
549 
SetBackgroundColor(const JSCallbackInfo & info)550 void JSNavDestination::SetBackgroundColor(const JSCallbackInfo& info)
551 {
552     Color backgroundColor;
553     RefPtr<ResourceObject> backgroundColorResObj;
554     bool isValid = ParseJsColor(info[0], backgroundColor, backgroundColorResObj);
555     NavDestinationModel::GetInstance()->SetBackgroundColor(backgroundColor, isValid, backgroundColorResObj);
556 }
557 
SetWillAppear(const JSCallbackInfo & info)558 void JSNavDestination::SetWillAppear(const JSCallbackInfo& info)
559 {
560     if (!info[0]->IsFunction()) {
561         return;
562     }
563 
564     auto willAppear = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
565     auto onWillAppear = [execCtx = info.GetExecutionContext(), func = std::move(willAppear)]() {
566         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
567         ACE_SCORING_EVENT("NavDestination.WillAppear");
568         func->ExecuteJS();
569     };
570     NavDestinationModel::GetInstance()->SetOnWillAppear(std::move(onWillAppear));
571     info.ReturnSelf();
572 }
573 
SetWillHide(const JSCallbackInfo & info)574 void JSNavDestination::SetWillHide(const JSCallbackInfo& info)
575 {
576     if (!info[0]->IsFunction()) {
577         return;
578     }
579 
580     auto willHideCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
581     auto onWillHide = [execCtx = info.GetExecutionContext(), func = std::move(willHideCallback)]() {
582         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
583         ACE_SCORING_EVENT("NavDestination.WillHide");
584         func->ExecuteJS();
585     };
586     NavDestinationModel::GetInstance()->SetOnWillHide(std::move(onWillHide));
587     info.ReturnSelf();
588 }
589 
SetWillShow(const JSCallbackInfo & info)590 void JSNavDestination::SetWillShow(const JSCallbackInfo& info)
591 {
592     if (!info[0]->IsFunction()) {
593         return;
594     }
595 
596     auto willShowCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
597     auto onWillShow = [execCtx = info.GetExecutionContext(), func = std::move(willShowCallback)]() {
598         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
599         ACE_SCORING_EVENT("NavDestination.WillShow");
600         func->ExecuteJS();
601     };
602     NavDestinationModel::GetInstance()->SetOnWillShow(std::move(onWillShow));
603     info.ReturnSelf();
604 }
605 
SetWillDisAppear(const JSCallbackInfo & info)606 void JSNavDestination::SetWillDisAppear(const JSCallbackInfo& info)
607 {
608     if (!info[0]->IsFunction()) {
609         return;
610     }
611 
612     auto WillDisAppear = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
613     auto onWillDisAppear = [execCtx = info.GetExecutionContext(), func = std::move(WillDisAppear)]() {
614         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
615         ACE_SCORING_EVENT("NavDestination.WillDisAppear");
616         func->ExecuteJS();
617     };
618     NavDestinationModel::GetInstance()->SetOnWillDisAppear(std::move(onWillDisAppear));
619     info.ReturnSelf();
620 }
621 
SetIgnoreLayoutSafeArea(const JSCallbackInfo & info)622 void JSNavDestination::SetIgnoreLayoutSafeArea(const JSCallbackInfo& info)
623 {
624     NG::IgnoreLayoutSafeAreaOpts opts { .type = NG::LAYOUT_SAFE_AREA_TYPE_SYSTEM,
625         .rawEdges = NG::LAYOUT_SAFE_AREA_EDGE_ALL };
626     if (info.Length() >= PARAMATER_LENGTH_ONE && info[0]->IsArray()) {
627         auto paramArray = JSRef<JSArray>::Cast(info[0]);
628         uint32_t layoutSafeAreaType = NG::LAYOUT_SAFE_AREA_TYPE_NONE;
629         for (size_t i = 0; i < paramArray->Length(); ++i) {
630             if (!paramArray->GetValueAt(i)->IsNumber() ||
631                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_TYPE_LIMIT) {
632                 layoutSafeAreaType = NG::SAFE_AREA_TYPE_SYSTEM;
633                 break;
634             }
635             layoutSafeAreaType |=
636                 NG::IgnoreLayoutSafeAreaOpts::TypeToMask(paramArray->GetValueAt(i)->ToNumber<uint32_t>());
637         }
638         opts.type = layoutSafeAreaType;
639     }
640     if (info.Length() >= PARAMATER_LENGTH_TWO && info[1]->IsArray()) {
641         auto paramArray = JSRef<JSArray>::Cast(info[1]);
642         uint32_t layoutSafeAreaEdge = NG::LAYOUT_SAFE_AREA_EDGE_NONE;
643         for (size_t i = 0; i < paramArray->Length(); ++i) {
644             if (!paramArray->GetValueAt(i)->IsNumber() ||
645                 paramArray->GetValueAt(i)->ToNumber<uint32_t>() > LAYOUT_SAFE_AREA_EDGE_LIMIT) {
646                 layoutSafeAreaEdge = NG::LAYOUT_SAFE_AREA_EDGE_ALL;
647                 break;
648             }
649             layoutSafeAreaEdge |=
650                 NG::IgnoreLayoutSafeAreaOpts::EdgeToMask(paramArray->GetValueAt(i)->ToNumber<uint32_t>());
651         }
652         opts.rawEdges = layoutSafeAreaEdge;
653     }
654     NavDestinationModel::GetInstance()->SetIgnoreLayoutSafeArea(opts);
655 }
656 
SetRecoverable(const JSCallbackInfo & info)657 void JSNavDestination::SetRecoverable(const JSCallbackInfo& info)
658 {
659     if (!info[0]->IsBoolean()) {
660         // the default value of navDestination's recoverable is true
661         NavDestinationModel::GetInstance()->SetRecoverable(true);
662         return;
663     }
664     auto recoverable = info[0]->ToBoolean();
665     NavDestinationModel::GetInstance()->SetRecoverable(recoverable);
666 }
667 
SetToolBarConfiguration(const JSCallbackInfo & info)668 void JSNavDestination::SetToolBarConfiguration(const JSCallbackInfo& info)
669 {
670     bool hideText = false;
671     JSNavigationUtils::ParseHideToolBarText(info, hideText);
672     NavDestinationModel::GetInstance()->SetHideItemText(hideText);
673     NavDestinationModel::GetInstance()->ResetResObj(
674         NavDestinationPatternType::NAV_DESTINATION, "navDestination.toolbarConfiguration");
675     if (info[0]->IsUndefined() || info[0]->IsArray()) {
676         std::vector<NG::BarItem> toolBarItems;
677         if (info[0]->IsArray()) {
678             auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
679             JSNavigationUtils::ParseToolbarItemsConfiguration(
680                 targetNode, info, JSRef<JSArray>::Cast(info[0]), toolBarItems);
681         }
682         NG::MoreButtonOptions toolbarMoreButtonOptions;
683         if (info.Length() > 1 && info[1]->IsObject()) {
684             auto optObj = JSRef<JSObject>::Cast(info[1]);
685             auto moreButtonProperty = optObj->GetProperty(MORE_BUTTON_OPTIONS_PROPERTY);
686             JSNavigationUtils::ParseToolBarMoreButtonOptions(moreButtonProperty, toolbarMoreButtonOptions);
687         }
688         if (SystemProperties::ConfigChangePerform()) {
689             NavDestinationModel::GetInstance()->SetToolbarConfiguration(
690                 std::move(toolBarItems), std::move(toolbarMoreButtonOptions));
691         } else {
692             NavDestinationModel::GetInstance()->SetToolbarMorebuttonOptions(std::move(toolbarMoreButtonOptions));
693             NavDestinationModel::GetInstance()->SetToolbarConfiguration(std::move(toolBarItems));
694         }
695     } else if (info[0]->IsObject()) {
696         auto builderFuncParam = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
697         if (builderFuncParam->IsFunction()) {
698             ViewStackModel::GetInstance()->NewScope();
699             JsFunction jsBuilderFunc(builderFuncParam);
700             jsBuilderFunc.Execute();
701             auto customNode = ViewStackModel::GetInstance()->Finish();
702             NavDestinationModel::GetInstance()->SetCustomToolBar(customNode);
703         }
704     }
705     NG::NavigationToolbarOptions options;
706     NavDestinationModel::GetInstance()->ResetResObj(
707         NavDestinationPatternType::NAV_DESTINATION, "navigation.navigationToolbarOptions");
708     JSNavigationUtils::ParseToolbarOptions(info, options);
709     NavDestinationModel::GetInstance()->SetToolBarOptions(std::move(options));
710 }
711 
SetHideToolBar(const JSCallbackInfo & info)712 void JSNavDestination::SetHideToolBar(const JSCallbackInfo& info)
713 {
714     bool isHide = false;
715     if (info.Length() > 0 && info[0]->IsBoolean()) {
716         isHide = info[0]->ToBoolean();
717     }
718     bool isAnimated = false;
719     if (info.Length() > 1 && info[1]->IsBoolean()) {
720         isAnimated = info[1]->ToBoolean();
721     }
722     NavDestinationModel::GetInstance()->SetHideToolBar(isHide, isAnimated);
723 }
724 
BindToScrollable(const JSCallbackInfo & info)725 void JSNavDestination::BindToScrollable(const JSCallbackInfo& info)
726 {
727     auto bindFunc = [&info](const RefPtr<NG::NavDestinationScrollableProcessor>& processor) {
728         auto jsProcessor = AceType::DynamicCast<JSNavDestinationScrollableProcessor>(processor);
729         CHECK_NULL_VOID(jsProcessor);
730         jsProcessor->BindToScrollable(info);
731     };
732     NavDestinationModel::GetInstance()->UpdateBindingWithScrollable(std::move(bindFunc));
733 }
734 
BindToNestedScrollable(const JSCallbackInfo & info)735 void JSNavDestination::BindToNestedScrollable(const JSCallbackInfo& info)
736 {
737     auto bindFunc = [&info](const RefPtr<NG::NavDestinationScrollableProcessor>& processor) {
738         auto jsProcessor = AceType::DynamicCast<JSNavDestinationScrollableProcessor>(processor);
739         CHECK_NULL_VOID(jsProcessor);
740         jsProcessor->BindToNestedScrollable(info);
741     };
742     NavDestinationModel::GetInstance()->UpdateBindingWithScrollable(std::move(bindFunc));
743 }
744 
SetCustomTransition(const JSCallbackInfo & info)745 void JSNavDestination::SetCustomTransition(const JSCallbackInfo& info)
746 {
747     if (info.Length() != 1 || !info[0]->IsFunction()) {
748         NavDestinationModel::GetInstance()->SetCustomTransition(nullptr);
749         return;
750     }
751     auto jsTransitionDelegate = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(info[0]));
752     auto transitionDelegate = [execCtx = info.GetExecutionContext(), delegate = std::move(jsTransitionDelegate)](
753         NG::NavigationOperation operation, bool isEnter) -> std::optional<std::vector<NG::NavDestinationTransition>> {
754         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, std::nullopt);
755         JSRef<JSVal> params[2];
756         params[0] = JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(operation)));
757         params[1] = JSRef<JSVal>::Make(ToJSValue(isEnter));
758         auto ret = delegate->ExecuteJS(2, params);
759         if (!ret->IsArray()) {
760             TAG_LOGI(AceLogTag::ACE_NAVIGATION, "NavDestination custom transition invalid!");
761             return std::nullopt;
762         }
763         std::vector<NG::NavDestinationTransition> allTransitions;
764         auto allTransitionObj = JSRef<JSArray>::Cast(ret);
765         for (size_t index = 0; index < allTransitionObj->Length(); ++index) {
766             auto transitionValue = allTransitionObj->GetValueAt(index);
767             if (!transitionValue->IsObject()) {
768                 continue;
769             }
770             auto navDestinationTransition = JSNavigationUtils::ParseNavDestinationTransition(
771                 JSRef<JSObject>::Cast(transitionValue), execCtx);
772             if (navDestinationTransition.has_value()) {
773                 allTransitions.emplace_back(navDestinationTransition.value());
774             }
775         }
776         return allTransitions;
777     };
778 
779     NavDestinationModel::GetInstance()->SetCustomTransition(std::move(transitionDelegate));
780 }
781 
JSBind(BindingTarget globalObj)782 void JSNavDestination::JSBind(BindingTarget globalObj)
783 {
784     JSNavDestinationContext::JSBind(globalObj);
785     JSClass<JSNavDestination>::Declare("NavDestination");
786     JSClass<JSNavDestination>::StaticMethod("create", &JSNavDestination::Create);
787     JSClass<JSNavDestination>::StaticMethod("title", &JSNavDestination::SetTitle);
788     JSClass<JSNavDestination>::StaticMethod("hideTitleBar", &JSNavDestination::SetHideTitleBar);
789     JSClass<JSNavDestination>::StaticMethod("hideBackButton", &JSNavDestination::SetHideBackButton);
790     JSClass<JSNavDestination>::StaticMethod("backButtonIcon", &JSNavDestination::SetBackButtonIcon);
791     JSClass<JSNavDestination>::StaticMethod("backgroundColor", &JSNavDestination::SetBackgroundColor);
792     JSClass<JSNavDestination>::StaticMethod("onShown", &JSNavDestination::SetOnShown);
793     JSClass<JSNavDestination>::StaticMethod("onHidden", &JSNavDestination::SetOnHidden);
794     JSClass<JSNavDestination>::StaticMethod("onBackPressed", &JSNavDestination::SetOnBackPressed);
795     JSClass<JSNavDestination>::StaticMethod("onReady", &JSNavDestination::SetOnReady);
796     JSClass<JSNavDestination>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
797     JSClass<JSNavDestination>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
798     JSClass<JSNavDestination>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
799     JSClass<JSNavDestination>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
800     JSClass<JSNavDestination>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
801     JSClass<JSNavDestination>::StaticMethod("id", &JSViewAbstract::JsId);
802     JSClass<JSNavDestination>::StaticMethod("mode", &JSNavDestination::SetMode);
803     JSClass<JSNavDestination>::StaticMethod("menus", &JSNavDestination::SetMenus);
804     JSClass<JSNavDestination>::StaticMethod("onWillAppear", &JSNavDestination::SetWillAppear);
805     JSClass<JSNavDestination>::StaticMethod("onWillShow", &JSNavDestination::SetWillShow);
806     JSClass<JSNavDestination>::StaticMethod("onWillHide", &JSNavDestination::SetWillHide);
807     JSClass<JSNavDestination>::StaticMethod("onWillDisappear", &JSNavDestination::SetWillDisAppear);
808     JSClass<JSNavDestination>::StaticMethod("onActive", &JSNavDestination::SetOnActive);
809     JSClass<JSNavDestination>::StaticMethod("onInactive", &JSNavDestination::SetOnInactive);
810     JSClass<JSNavDestination>::StaticMethod("onResult", &JSNavDestination::SetResultCallback);
811     JSClass<JSNavDestination>::StaticMethod("ignoreLayoutSafeArea", &JSNavDestination::SetIgnoreLayoutSafeArea);
812     JSClass<JSNavDestination>::StaticMethod("systemBarStyle", &JSNavDestination::SetSystemBarStyle);
813     JSClass<JSNavDestination>::StaticMethod("recoverable", &JSNavDestination::SetRecoverable);
814     JSClass<JSNavDestination>::StaticMethod("toolbarConfiguration", &JSNavDestination::SetToolBarConfiguration);
815     JSClass<JSNavDestination>::StaticMethod("hideToolBar", &JSNavDestination::SetHideToolBar);
816     JSClass<JSNavDestination>::StaticMethod("systemTransition", &JSNavDestination::SetSystemTransition);
817     JSClass<JSNavDestination>::StaticMethod("bindToScrollable", &JSNavDestination::BindToScrollable);
818     JSClass<JSNavDestination>::StaticMethod("bindToNestedScrollable", &JSNavDestination::BindToNestedScrollable);
819     JSClass<JSNavDestination>::StaticMethod("customTransition", &JSNavDestination::SetCustomTransition);
820     JSClass<JSNavDestination>::StaticMethod("onNewParam", &JSNavDestination::SetOnNewParam);
821     JSClass<JSNavDestination>::StaticMethod("preferredOrientation", &JSNavDestination::SetPreferredOrientation);
822     JSClass<JSNavDestination>::StaticMethod("enableStatusBar", &JSNavDestination::EnableStatusBar);
823     JSClass<JSNavDestination>::StaticMethod("enableNavigationIndicator", &JSNavDestination::EnableNavigationIndicator);
824     JSClass<JSNavDestination>::InheritAndBind<JSContainerBase>(globalObj);
825 }
826 
SetSystemBarStyle(const JSCallbackInfo & info)827 void JSNavDestination::SetSystemBarStyle(const JSCallbackInfo& info)
828 {
829     RefPtr<SystemBarStyle> style = nullptr;
830     if (info.Length() == 1 && info[0]->IsObject()) {
831         auto styleObj = JsConverter::ConvertJsValToNapiValue(info[0]);
832         auto env = GetCurrentEnv();
833         if (env) {
834             style = SystemBarStyle::CreateStyleFromJsObj(env, styleObj);
835         }
836     }
837     NavDestinationModel::GetInstance()->SetSystemBarStyle(style);
838 }
839 
SetSystemTransition(const JSCallbackInfo & info)840 void JSNavDestination::SetSystemTransition(const JSCallbackInfo& info)
841 {
842     if (!info[0]->IsNumber()) {
843         NavDestinationModel::GetInstance()->SetSystemTransitionType(NG::NavigationSystemTransitionType::DEFAULT);
844         return;
845     }
846     auto value = info[0]->ToNumber<int32_t>();
847     NG::NavigationSystemTransitionType type = ParseTransitionType(value);
848     NavDestinationModel::GetInstance()->SetSystemTransitionType(type);
849 }
850 
SetResultCallback(const JSCallbackInfo & info)851 void JSNavDestination::SetResultCallback(const JSCallbackInfo& info)
852 {
853     if (info.Length() < 1) {
854         return;
855     }
856     if (!info[0]->IsFunction()) {
857         return;
858     }
859     auto func = JSRef<JSFunc>::Cast(info[0]);
860     if (func->IsEmpty()) {
861         return;
862     }
863     auto setPopCallback = [func](const RefPtr<NG::NavPathInfo>& info) {
864         auto pathInfo = AceType::DynamicCast<JSNavPathInfo>(info);
865         CHECK_NULL_VOID(pathInfo);
866         pathInfo->SetNavDestinationPopCallback(func);
867     };
868     NavDestinationModel::GetInstance()->SetOnPop(setPopCallback);
869 }
870 
SetOnActive(const JSCallbackInfo & info)871 void JSNavDestination::SetOnActive(const JSCallbackInfo& info)
872 {
873     if (info.Length() <= 0) {
874         return;
875     }
876     if (!info[0]->IsFunction()) {
877         return;
878     }
879     auto onActive = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
880     auto onActiveCallback = [exeCtx = info.GetExecutionContext(), func = std::move(onActive)](int32_t reason) {
881         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(exeCtx);
882         ACE_SCORING_EVENT("NavDestination.OnActive");
883         JSRef<JSVal> params[1];
884         params[0] = JSRef<JSVal>::Make(ToJSValue(reason));
885         func->ExecuteJS(1, params);
886     };
887     NavDestinationModel::GetInstance()->SetOnActive(std::move(onActiveCallback));
888     info.ReturnSelf();
889 }
890 
SetOnInactive(const JSCallbackInfo & info)891 void JSNavDestination::SetOnInactive(const JSCallbackInfo& info)
892 {
893     if (info.Length() <= 0) {
894         return;
895     }
896     if (!info[0]->IsFunction()) {
897         return;
898     }
899     auto onInactive = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
900     auto onInactiveCallback = [execCtx = info.GetExecutionContext(), func = std::move(onInactive)](int32_t reason) {
901         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
902         ACE_SCORING_EVENT("NavDestination.OnInactive");
903         JSRef<JSVal> params[1];
904         params[0] = JSRef<JSVal>::Make(ToJSValue(reason));
905         func->ExecuteJS(1, params);
906     };
907     NavDestinationModel::GetInstance()->SetOnInactive(std::move(onInactiveCallback));
908     info.ReturnSelf();
909 }
910 
SetOnNewParam(const JSCallbackInfo & info)911 void JSNavDestination::SetOnNewParam(const JSCallbackInfo& info)
912 {
913     if (info.Length() <= 0 || !info[0]->IsFunction()) {
914         return;
915     }
916     auto onNewParam = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(info[0]));
917     auto onNewParamCallback = [execCtx = info.GetExecutionContext(), func = std::move(onNewParam)](napi_value param) {
918         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
919         ACE_SCORING_EVENT("NavDestination.onNewParam");
920         JSRef<JSVal> params[1];
921         params[0] = JsConverter::ConvertNapiValueToJsVal(param);
922         func->ExecuteJS(1, params);
923     };
924     NavDestinationModel::GetInstance()->SetOnNewParam(std::move(onNewParamCallback));
925     info.ReturnSelf();
926 }
927 
SetPreferredOrientation(const JSCallbackInfo & info)928 void JSNavDestination::SetPreferredOrientation(const JSCallbackInfo& info)
929 {
930     std::optional<Orientation> orientation;
931     if (info.Length() > 0 && info[0]->IsNumber()) {
932         auto ori = info[0]->ToNumber<int32_t>();
933         if (ori >= static_cast<int32_t>(ApiOrientation::BEGIN) && ori <= static_cast<int32_t>(ApiOrientation::END)) {
934             orientation = JS_TO_NATIVE_ORIENTATION_MAP.at(static_cast<ApiOrientation>(ori));
935         }
936     }
937     NavDestinationModel::GetInstance()->SetPreferredOrientation(orientation);
938 }
939 
EnableStatusBar(const JSCallbackInfo & info)940 void JSNavDestination::EnableStatusBar(const JSCallbackInfo& info)
941 {
942     std::optional<std::pair<bool, bool>> statusBar;
943     if (info.Length() > 0 && info[0]->IsBoolean()) {
944         bool enable = info[0]->ToBoolean();
945         bool animated = false;
946         if (info.Length() > 1 && info[1]->IsBoolean()) {
947             animated = info[1]->ToBoolean();
948         }
949         statusBar = std::make_pair(enable, animated);
950     }
951     NavDestinationModel::GetInstance()->SetEnableStatusBar(statusBar);
952 }
953 
EnableNavigationIndicator(const JSCallbackInfo & info)954 void JSNavDestination::EnableNavigationIndicator(const JSCallbackInfo& info)
955 {
956     std::optional<bool> navigationIndicator;
957     if (info.Length() > 0 && info[0]->IsBoolean()) {
958         navigationIndicator = info[0]->ToBoolean();
959     }
960     NavDestinationModel::GetInstance()->SetEnableNavigationIndicator(navigationIndicator);
961 }
962 } // namespace OHOS::Ace::Framework
963