/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "frameworks/bridge/declarative_frontend/jsview/js_navdestination.h" #include "base/log/ace_scoring_log.h" #include "base/memory/ace_type.h" #include "base/utils/utils.h" #include "base/system_bar/system_bar_style.h" #include "bridge/declarative_frontend/engine/functions/js_function.h" #include "bridge/declarative_frontend/engine/js_converter.h" #include "bridge/declarative_frontend/engine/js_execution_scope_defines.h" #include "bridge/declarative_frontend/engine/js_ref_ptr.h" #include "bridge/declarative_frontend/engine/js_types.h" #include "bridge/declarative_frontend/jsview/js_navdestination_context.h" #include "bridge/declarative_frontend/jsview/js_navigation.h" #include "bridge/declarative_frontend/jsview/js_navigation_utils.h" #include "bridge/declarative_frontend/jsview/js_navdestination_scrollable_processor.h" #include "bridge/declarative_frontend/jsview/js_utils.h" #include "core/components_ng/base/view_stack_model.h" #include "core/components_ng/base/view_stack_processor.h" #include "core/components_ng/pattern/navigation/navigation_options.h" #include "core/components_ng/pattern/navrouter/navdestination_model_ng.h" namespace OHOS::Ace { std::unique_ptr NavDestinationModel::instance_ = nullptr; std::mutex NavDestinationModel::mutex_; NavDestinationModel* NavDestinationModel::GetInstance() { if (!instance_) { std::lock_guard lock(mutex_); instance_.reset(new NG::NavDestinationModelNG()); } return instance_.get(); } } // namespace OHOS::Ace namespace OHOS::Ace::Framework { namespace { constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3; constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4; constexpr uint32_t SAFE_AREA_EDGE_SYSTEM = 0; constexpr uint32_t SAFE_AREA_EDGE_TOP = 0; constexpr uint32_t SAFE_AREA_EDGE_BOTTOM = 1; constexpr int32_t PARAMATER_LENGTH_ONE = 1; constexpr int32_t PARAMATER_LENGTH_TWO = 2; constexpr uint32_t FIRST_INDEX = 0; constexpr uint32_t SECOND_INDEX = 1; constexpr int32_t JS_EMUN_TRANSITIONTYPE_NONE = 1; constexpr int32_t JS_EMUN_TRANSITIONTYPE_TITLE = 2; constexpr int32_t JS_EMUN_TRANSITIONTYPE_CONTENT = 3; NG::NavigationSystemTransitionType ParseTransitionType(int32_t value) { switch (value) { case JS_EMUN_TRANSITIONTYPE_NONE: return NG::NavigationSystemTransitionType::NONE; case JS_EMUN_TRANSITIONTYPE_TITLE: return NG::NavigationSystemTransitionType::TITLE; case JS_EMUN_TRANSITIONTYPE_CONTENT: return NG::NavigationSystemTransitionType::CONTENT; default: return NG::NavigationSystemTransitionType::DEFAULT; } } bool ParseCommonTitle(const JSRef& jsObj) { JSRef subtitle = jsObj->GetProperty("sub"); JSRef title = jsObj->GetProperty("main"); std::string mainTitle; std::string subTitle; bool hasSub = JSViewAbstract::ParseJsString(subtitle, subTitle); bool hasMain = JSViewAbstract::ParseJsString(title, mainTitle); if (hasSub || hasMain) { return NG::NavDestinationModelNG::GetInstance()->ParseCommonTitle( hasSub, hasMain, subTitle, mainTitle); } return false; } } // namespace void JSNavDestination::Create() { NavDestinationModel::GetInstance()->Create(); NavDestinationModel::GetInstance()->SetScrollableProcessor( []() { return AceType::MakeRefPtr(); }); } void JSNavDestination::Create(const JSCallbackInfo& info) { if (info.Length() <= 0) { NavDestinationModel::GetInstance()->Create(); NavDestinationModel::GetInstance()->SetScrollableProcessor( []() { return AceType::MakeRefPtr(); }); return; } std::string moduleName; std::string pagePath; if (info.Length() == 1) { // input format: builder/pathInfo if (info[0]->IsFunction()) { // first parameter = builder auto builderFunctionJS = info[0]; auto builderFunc = [context = info.GetExecutionContext(), builder = std::move(builderFunctionJS)]() { JAVASCRIPT_EXECUTION_SCOPE(context) JSRef::Cast(builder)->Call(JSRef()); }; auto ctx = AceType::MakeRefPtr(); auto navPathInfo = AceType::MakeRefPtr(); ctx->SetNavPathInfo(navPathInfo); NavDestinationModel::GetInstance()->Create(std::move(builderFunc), std::move(ctx)); NavDestinationModel::GetInstance()->SetScrollableProcessor( []() { return AceType::MakeRefPtr(); }); return; } else if (info[0]->IsObject()) { // first parameter = pathInfo{'moduleName': stringA, 'pagePath': stringB} auto infoObj = JSRef::Cast(info[0]); if (!infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->IsString() || !infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->IsString()) { TAG_LOGE(AceLogTag::ACE_NAVIGATION, "navDestination current pageInfo is invalid"); return; } moduleName = infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->ToString(); pagePath = infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->ToString(); NavDestinationModel::GetInstance()->Create(); NavDestinationModel::GetInstance()->SetScrollableProcessor( []() { return AceType::MakeRefPtr(); }); NavDestinationModel::GetInstance()->SetNavDestinationPathInfo(moduleName, pagePath); return; } TAG_LOGE(AceLogTag::ACE_NAVIGATION, "current input info is neither buildFunction or navDestination usefulInfo"); return; } else if (info.Length() == 2) { // parameter = builder(maybe empty) + pathInfo if (!info[0]->IsFunction() || !info[1]->IsObject()) { TAG_LOGE(AceLogTag::ACE_NAVIGATION, "buider or pageInfo is invalid"); return; } auto builderFunctionJS = info[0]; auto builderFunc = [context = info.GetExecutionContext(), builder = std::move(builderFunctionJS)]() { JAVASCRIPT_EXECUTION_SCOPE(context) JSRef::Cast(builder)->Call(JSRef()); }; auto ctx = AceType::MakeRefPtr(); auto navPathInfo = AceType::MakeRefPtr(); ctx->SetNavPathInfo(navPathInfo); auto infoObj = JSRef::Cast(info[1]); if (!infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->IsString() || !infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->IsString()) { TAG_LOGE(AceLogTag::ACE_NAVIGATION, "navDestination current pageInfo is invalid"); return; } moduleName = infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->ToString(); pagePath = infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->ToString(); NavDestinationModel::GetInstance()->Create(std::move(builderFunc), std::move(ctx)); NavDestinationModel::GetInstance()->SetScrollableProcessor( []() { return AceType::MakeRefPtr(); }); NavDestinationModel::GetInstance()->SetNavDestinationPathInfo(moduleName, pagePath); } } void JSNavDestination::SetHideTitleBar(const JSCallbackInfo& info) { bool isHide = false; if (info.Length() > 0 && info[0]->IsBoolean()) { isHide = info[0]->ToBoolean(); } bool isAnimated = false; if (info.Length() > 1 && info[1]->IsBoolean()) { isAnimated = info[1]->ToBoolean(); } NavDestinationModel::GetInstance()->SetHideTitleBar(isHide, isAnimated); } void JSNavDestination::SetTitle(const JSCallbackInfo& info) { // Resource and string type. std::string title; if (ParseJsString(info[0], title)) { NavDestinationModel::GetInstance()->ParseCommonTitle(false, true, "", title); } else if (info[0]->IsObject()) { JSRef jsObj = JSRef::Cast(info[0]); do { // NavigationCommonTitle if (ParseCommonTitle(jsObj)) { break; } // CustomBuilder | NavigationCustomTitle CalcDimension titleHeight; if (!jsObj->HasProperty("height")) { NavDestinationModel::GetInstance()->SetTitleHeight(titleHeight, false); break; } JSRef height = jsObj->GetProperty("height"); bool isValid = JSContainerBase::ParseJsDimensionVpNG(height, titleHeight); if (height->IsString()) { std::string heightValue; ParseJsString(height, heightValue); if (heightValue == NG::TITLE_MAIN_WITH_SUB) { NavDestinationModel::GetInstance()->SetTitleHeight(NG::DOUBLE_LINE_TITLEBAR_HEIGHT); break; } if (heightValue == NG::TITLE_MAIN) { NavDestinationModel::GetInstance()->SetTitleHeight(NG::SINGLE_LINE_TITLEBAR_HEIGHT); break; } } if (!isValid || titleHeight.Value() < 0) { NavDestinationModel::GetInstance()->SetTitleHeight(Dimension(), true); break; } NavDestinationModel::GetInstance()->SetTitleHeight(titleHeight); } while (0); JSRef builderObject = jsObj->GetProperty("builder"); if (builderObject->IsFunction()) { ViewStackModel::GetInstance()->NewScope(); JsFunction jsBuilderFunc(info.This(), JSRef::Cast(builderObject)); ACE_SCORING_EVENT("Navdestination.title.builder"); jsBuilderFunc.Execute(); auto customNode = ViewStackModel::GetInstance()->Finish(); NavDestinationModel::GetInstance()->SetCustomTitle(customNode); } } else { NavDestinationModel::GetInstance()->ParseCommonTitle(false, false, "", ""); } NG::NavigationTitlebarOptions options; JSNavigationUtils::ParseTitleBarOptions(info, false, options); NavDestinationModel::GetInstance()->SetTitlebarOptions(std::move(options)); } void JSNavDestination::SetBackButtonIcon(const JSCallbackInfo& info) { // srcType、pixmap、string if (info.Length() < 1) { return; } std::string src; auto noPixMap = ParseJsMedia(info[0], src); RefPtr pixMap = nullptr; auto isValidImage = false; #if defined(PIXEL_MAP_SUPPORTED) if (!noPixMap) { pixMap = CreatePixelMapFromNapiValue(info[0]); } #endif if (noPixMap || pixMap != nullptr) { isValidImage = true; } std::vector nameList; NG::ImageOption imageOption; std::string bundleName; std::string moduleName; GetJsMediaBundleInfo(info[0], bundleName, moduleName); nameList.emplace_back(bundleName); nameList.emplace_back(moduleName); imageOption.noPixMap = noPixMap; imageOption.isValidImage = isValidImage; std::function)> iconSymbol = nullptr; auto isSymbol = info[0]->IsObject() && src.empty() && pixMap == nullptr; if (isSymbol) { SetSymbolOptionApply(info, iconSymbol, info[0]); } NavDestinationModel::GetInstance()->SetBackButtonIcon(iconSymbol, src, imageOption, pixMap, nameList); } void JSNavDestination::SetOnShown(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto onShownCallback = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); WeakPtr targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); auto onShown = [execCtx = info.GetExecutionContext(), func = std::move(onShownCallback), node = targetNode]() { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("NavDestination.onShown"); PipelineContext::SetCallBackNode(node); JSRef params[1]; params[0] = JSRef::Make(ToJSValue("undefined")); func->ExecuteJS(1, params); }; NavDestinationModel::GetInstance()->SetOnShown(std::move(onShown)); info.ReturnSelf(); } void JSNavDestination::SetOnHidden(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto onHiddenCallback = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); WeakPtr targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); auto onHidden = [execCtx = info.GetExecutionContext(), func = std::move(onHiddenCallback), node = targetNode]() { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("NavDestination.onHidden"); PipelineContext::SetCallBackNode(node); func->ExecuteJS(); }; NavDestinationModel::GetInstance()->SetOnHidden(std::move(onHidden)); info.ReturnSelf(); } void JSNavDestination::SetOnBackPressed(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto onBackPressedCallback = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); auto onBackPressed = [execCtx = info.GetExecutionContext(), func = std::move(onBackPressedCallback)]() -> bool { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, false); ACE_SCORING_EVENT("NavDestination.onBackPressed"); return (func->ExecuteJS())->ToBoolean(); }; NavDestinationModel::GetInstance()->SetOnBackPressed(std::move(onBackPressed)); info.ReturnSelf(); } void JSNavDestination::SetOnReady(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto onReadyCallback = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); auto onReady = [execCtx = info.GetExecutionContext(), func = std::move(onReadyCallback)]( RefPtr context) { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); auto jsContext = JSClass::NewInstance(); auto jsNavDestinationContext = Referenced::Claim(jsContext->Unwrap()); CHECK_NULL_VOID(jsNavDestinationContext); jsNavDestinationContext->SetNavDestinationContext(context); ACE_SCORING_EVENT("NavDestination.onReady"); JSRef params[1]; params[0] = jsContext; func->ExecuteJS(1, params); }; NavDestinationModel::GetInstance()->SetOnReady(std::move(onReady)); info.ReturnSelf(); } void JSNavDestination::SetMode(const JSCallbackInfo& info) { if (!info[0]->IsNumber()) { // set default back ground color NavDestinationModel::GetInstance()->SetNavDestinationMode(NG::NavDestinationMode::STANDARD); return; } auto mode = info[0]->ToNumber(); NavDestinationModel::GetInstance()->SetNavDestinationMode(static_cast(mode)); } void JSNavDestination::SetMenus(const JSCallbackInfo& info) { if (info.Length() < 1) { return; } if (info[0]->IsUndefined() || info[0]->IsArray()) { std::vector menuItems; if (info[0]->IsUndefined()) { menuItems = {}; } else { auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); JSNavigationUtils::ParseBarItems(targetNode, info, JSRef::Cast(info[0]), menuItems); } NavDestinationModel::GetInstance()->SetMenuItems(std::move(menuItems)); return; } else if (info[0]->IsObject()) { auto builderObject = JSRef::Cast(info[0])->GetProperty("builder"); if (builderObject->IsFunction()) { ViewStackModel::GetInstance()->NewScope(); JsFunction jsBuilderFunc(info.This(), JSRef::Cast(builderObject)); ACE_SCORING_EVENT("NavDestiNation.menu.builder"); jsBuilderFunc.Execute(); auto customNode = ViewStackModel::GetInstance()->Finish(); NavDestinationModel::GetInstance()->SetCustomMenu(customNode); } } } void JSNavDestination::SetBackgroundColor(const JSCallbackInfo& info) { Color backgroundColor; bool isValid = ParseJsColor(info[0], backgroundColor); NavDestinationModel::GetInstance()->SetBackgroundColor(backgroundColor, isValid); } void JSNavDestination::SetWillAppear(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto willAppear = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); auto onWillAppear = [execCtx = info.GetExecutionContext(), func = std::move(willAppear)]() { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("NavDestination.WillAppear"); func->ExecuteJS(); }; NavDestinationModel::GetInstance()->SetOnWillAppear(std::move(onWillAppear)); info.ReturnSelf(); } void JSNavDestination::SetWillHide(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto willHideCallback = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); auto onWillHide = [execCtx = info.GetExecutionContext(), func = std::move(willHideCallback)]() { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("NavDestination.WillHide"); func->ExecuteJS(); }; NavDestinationModel::GetInstance()->SetOnWillHide(std::move(onWillHide)); info.ReturnSelf(); } void JSNavDestination::SetWillShow(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto willShowCallback = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); auto onWillShow = [execCtx = info.GetExecutionContext(), func = std::move(willShowCallback)]() { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("NavDestination.WillShow"); func->ExecuteJS(); }; NavDestinationModel::GetInstance()->SetOnWillShow(std::move(onWillShow)); info.ReturnSelf(); } void JSNavDestination::SetWillDisAppear(const JSCallbackInfo& info) { if (!info[0]->IsFunction()) { return; } auto WillDisAppear = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); auto onWillDisAppear = [execCtx = info.GetExecutionContext(), func = std::move(WillDisAppear)]() { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); ACE_SCORING_EVENT("NavDestination.WillDisAppear"); func->ExecuteJS(); }; NavDestinationModel::GetInstance()->SetOnWillDisAppear(std::move(onWillDisAppear)); info.ReturnSelf(); } void JSNavDestination::SetIgnoreLayoutSafeArea(const JSCallbackInfo& info) { NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_SYSTEM, .edges = NG::SAFE_AREA_EDGE_ALL}; if (info.Length() >= PARAMATER_LENGTH_ONE && info[FIRST_INDEX]->IsArray()) { auto paramArray = JSRef::Cast(info[0]); uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE; for (size_t i = 0; i < paramArray->Length(); ++i) { auto value = paramArray->GetValueAt(i); if (!value->IsNumber() || value->ToNumber() >= SAFE_AREA_TYPE_LIMIT || value->ToNumber() == SAFE_AREA_EDGE_SYSTEM) { safeAreaType = NG::SAFE_AREA_TYPE_SYSTEM; break; } } opts.type = safeAreaType; } if (info.Length() >= PARAMATER_LENGTH_TWO && info[SECOND_INDEX]->IsArray()) { auto paramArray = JSRef::Cast(info[1]); uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE; for (size_t i = 0; i < paramArray->Length(); ++i) { auto value = paramArray->GetValueAt(i); if (!value->IsNumber() || value->ToNumber() >= SAFE_AREA_EDGE_LIMIT) { safeAreaEdge = NG::SAFE_AREA_EDGE_ALL; break; } if (value->ToNumber() == SAFE_AREA_EDGE_TOP || value->ToNumber() == SAFE_AREA_EDGE_BOTTOM) { safeAreaEdge |= (1 << value->ToNumber()); } } opts.edges = safeAreaEdge; } NavDestinationModel::GetInstance()->SetIgnoreLayoutSafeArea(opts); } void JSNavDestination::SetRecoverable(const JSCallbackInfo& info) { if (!info[0]->IsBoolean()) { // the default value of navDestination's recoverable is true NavDestinationModel::GetInstance()->SetRecoverable(true); return; } auto recoverable = info[0]->ToBoolean(); NavDestinationModel::GetInstance()->SetRecoverable(recoverable); } void JSNavDestination::SetToolBarConfiguration(const JSCallbackInfo& info) { if (info[0]->IsUndefined() || info[0]->IsArray()) { std::vector toolBarItems; if (info[0]->IsArray()) { auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode()); JSNavigationUtils::ParseToolbarItemsConfiguration( targetNode, info, JSRef::Cast(info[0]), toolBarItems); } NavDestinationModel::GetInstance()->SetToolbarConfiguration(std::move(toolBarItems)); } else if (info[0]->IsObject()) { auto builderFuncParam = JSRef::Cast(info[0])->GetProperty("builder"); if (builderFuncParam->IsFunction()) { ViewStackModel::GetInstance()->NewScope(); JsFunction jsBuilderFunc(builderFuncParam); jsBuilderFunc.Execute(); auto customNode = ViewStackModel::GetInstance()->Finish(); NavDestinationModel::GetInstance()->SetCustomToolBar(customNode); } } NG::NavigationToolbarOptions options; JSNavigationUtils::ParseToolbarOptions(info, options); NavDestinationModel::GetInstance()->SetToolBarOptions(std::move(options)); } void JSNavDestination::SetHideToolBar(const JSCallbackInfo& info) { bool isHide = false; if (info.Length() > 0 && info[0]->IsBoolean()) { isHide = info[0]->ToBoolean(); } bool isAnimated = false; if (info.Length() > 1 && info[1]->IsBoolean()) { isAnimated = info[1]->ToBoolean(); } NavDestinationModel::GetInstance()->SetHideToolBar(isHide, isAnimated); } void JSNavDestination::BindToScrollable(const JSCallbackInfo& info) { auto bindFunc = [&info](const RefPtr& processor) { auto jsProcessor = AceType::DynamicCast(processor); CHECK_NULL_VOID(jsProcessor); jsProcessor->BindToScrollable(info); }; NavDestinationModel::GetInstance()->UpdateBindingWithScrollable(std::move(bindFunc)); } void JSNavDestination::BindToNestedScrollable(const JSCallbackInfo& info) { auto bindFunc = [&info](const RefPtr& processor) { auto jsProcessor = AceType::DynamicCast(processor); CHECK_NULL_VOID(jsProcessor); jsProcessor->BindToNestedScrollable(info); }; NavDestinationModel::GetInstance()->UpdateBindingWithScrollable(std::move(bindFunc)); } void JSNavDestination::JSBind(BindingTarget globalObj) { JSNavDestinationContext::JSBind(globalObj); JSClass::Declare("NavDestination"); JSClass::StaticMethod("create", &JSNavDestination::Create); JSClass::StaticMethod("title", &JSNavDestination::SetTitle); JSClass::StaticMethod("hideTitleBar", &JSNavDestination::SetHideTitleBar); JSClass::StaticMethod("backButtonIcon", &JSNavDestination::SetBackButtonIcon); JSClass::StaticMethod("backgroundColor", &JSNavDestination::SetBackgroundColor); JSClass::StaticMethod("onShown", &JSNavDestination::SetOnShown); JSClass::StaticMethod("onHidden", &JSNavDestination::SetOnHidden); JSClass::StaticMethod("onBackPressed", &JSNavDestination::SetOnBackPressed); JSClass::StaticMethod("onReady", &JSNavDestination::SetOnReady); JSClass::StaticMethod("onAttach", &JSInteractableView::JsOnAttach); JSClass::StaticMethod("onAppear", &JSInteractableView::JsOnAppear); JSClass::StaticMethod("onDetach", &JSInteractableView::JsOnDetach); JSClass::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear); JSClass::StaticMethod("onTouch", &JSInteractableView::JsOnTouch); JSClass::StaticMethod("id", &JSViewAbstract::JsId); JSClass::StaticMethod("mode", &JSNavDestination::SetMode); JSClass::StaticMethod("menus", &JSNavDestination::SetMenus); JSClass::StaticMethod("onWillAppear", &JSNavDestination::SetWillAppear); JSClass::StaticMethod("onWillShow", &JSNavDestination::SetWillShow); JSClass::StaticMethod("toolbarConfiguration", &JSNavDestination::SetToolBarConfiguration); JSClass::StaticMethod("hideToolBar", &JSNavDestination::SetHideToolBar); JSClass::StaticMethod("onWillHide", &JSNavDestination::SetWillHide); JSClass::StaticMethod("onWillDisappear", &JSNavDestination::SetWillDisAppear); JSClass::StaticMethod("ignoreLayoutSafeArea", &JSNavDestination::SetIgnoreLayoutSafeArea); JSClass::StaticMethod("systemBarStyle", &JSNavDestination::SetSystemBarStyle); JSClass::StaticMethod("systemTransition", &JSNavDestination::SetSystemTransition); JSClass::StaticMethod("recoverable", &JSNavDestination::SetRecoverable); JSClass::StaticMethod("bindToScrollable", &JSNavDestination::BindToScrollable); JSClass::StaticMethod("bindToNestedScrollable", &JSNavDestination::BindToNestedScrollable); JSClass::InheritAndBind(globalObj); } void JSNavDestination::SetSystemBarStyle(const JSCallbackInfo& info) { RefPtr style = nullptr; if (info.Length() == 1 && info[0]->IsObject()) { auto styleObj = JsConverter::ConvertJsValToNapiValue(info[0]); auto env = GetCurrentEnv(); if (env) { style = SystemBarStyle::CreateStyleFromJsObj(env, styleObj); } } NavDestinationModel::GetInstance()->SetSystemBarStyle(style); } void JSNavDestination::SetSystemTransition(const JSCallbackInfo& info) { if (!info[0]->IsNumber()) { NavDestinationModel::GetInstance()->SetSystemTransitionType(NG::NavigationSystemTransitionType::DEFAULT); return; } auto value = info[0]->ToNumber(); NG::NavigationSystemTransitionType type = ParseTransitionType(value); NavDestinationModel::GetInstance()->SetSystemTransitionType(type); } } // namespace OHOS::Ace::Framework