1 /*
2 * Copyright (c) 2021-2024 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_navigation.h"
17
18 #include <vector>
19
20 #include "base/log/ace_scoring_log.h"
21 #include "base/memory/referenced.h"
22 #include "base/system_bar/system_bar_style.h"
23 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
24 #include "bridge/declarative_frontend/engine/functions/js_navigation_function.h"
25 #include "bridge/declarative_frontend/engine/js_converter.h"
26 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
27 #include "bridge/declarative_frontend/engine/js_types.h"
28 #include "bridge/declarative_frontend/jsview/js_nav_path_stack.h"
29 #include "bridge/declarative_frontend/jsview/js_navigation_stack.h"
30 #include "bridge/declarative_frontend/jsview/js_navigation_utils.h"
31 #include "bridge/declarative_frontend/jsview/js_utils.h"
32 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
33 #include "bridge/declarative_frontend/jsview/models/navigation_model_impl.h"
34 #include "core/components_ng/base/view_abstract_model.h"
35 #include "core/components_ng/base/view_stack_model.h"
36 #include "core/components_ng/base/view_stack_processor.h"
37 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
38 #include "core/components_ng/pattern/navigation/navigation_model_data.h"
39 #include "core/components_ng/pattern/navigation/navigation_model_ng.h"
40 #include "core/components_ng/pattern/navigation/navigation_options.h"
41
42 namespace OHOS::Ace {
43 std::unique_ptr<NavigationModel> NavigationModel::instance_ = nullptr;
44 std::mutex NavigationModel::mutex_;
45 constexpr int32_t NAVIGATION_ANIMATION_TIMEOUT = 1000; // ms
46
GetInstance()47 NavigationModel* NavigationModel::GetInstance()
48 {
49 if (!instance_) {
50 std::lock_guard<std::mutex> lock(mutex_);
51 if (!instance_) {
52 #ifdef NG_BUILD
53 instance_.reset(new NG::NavigationModelNG());
54 #else
55 if (Container::IsCurrentUseNewPipeline()) {
56 instance_.reset(new NG::NavigationModelNG());
57 } else {
58 instance_.reset(new Framework::NavigationModelImpl());
59 }
60 #endif
61 }
62 }
63 return instance_.get();
64 }
65 } // namespace OHOS::Ace
66
67 namespace OHOS::Ace::Framework {
68 namespace {
69 constexpr int32_t TITLE_MODE_RANGE = 2;
70 constexpr int32_t NAVIGATION_MODE_RANGE = 2;
71 constexpr int32_t NAV_BAR_POSITION_RANGE = 1;
72 constexpr int32_t DEFAULT_NAV_BAR_WIDTH = 240;
73 constexpr Dimension DEFAULT_MIN_CONTENT_WIDTH = 360.0_vp;
74 constexpr uint32_t SAFE_AREA_TYPE_LIMIT = 3;
75 constexpr uint32_t SAFE_AREA_EDGE_LIMIT = 4;
76 constexpr uint32_t SAFE_AREA_EDGE_SYSTEM = 0;
77 constexpr uint32_t SAFE_AREA_EDGE_TOP = 0;
78 constexpr uint32_t SAFE_AREA_EDGE_BOTTOM = 1;
79 constexpr int32_t PARAMETER_LENGTH_ONE = 1;
80 constexpr int32_t PARAMETER_LENGTH_TWO = 2;
81 constexpr int32_t FIRST_INDEX = 0;
82 constexpr int32_t SECOND_INDEX = 1;
83 constexpr bool ENABLE_TOOLBAR_ADAPTATION_DEFULT = true;
84 constexpr char MORE_BUTTON_OPTIONS_PROPERTY[] = "moreButtonOptions";
85
TitleModeChangeEventToJSValue(const NavigationTitleModeChangeEvent & eventInfo)86 JSRef<JSVal> TitleModeChangeEventToJSValue(const NavigationTitleModeChangeEvent& eventInfo)
87 {
88 return JSRef<JSVal>::Make(ToJSValue(eventInfo.IsMiniBar() ? static_cast<int32_t>(NavigationTitleMode::MINI)
89 : static_cast<int32_t>(NavigationTitleMode::FULL)));
90 }
91 } // namespace
92
ParseToolBarItems(const JSCallbackInfo & info,std::list<RefPtr<AceType>> & items)93 void JSNavigation::ParseToolBarItems(const JSCallbackInfo& info, std::list<RefPtr<AceType>>& items)
94 {
95 if (info[0]->IsUndefined()) {
96 return;
97 }
98 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(info[0]);
99 auto length = jsArray->Length();
100 for (size_t i = 0; i < length; i++) {
101 auto item = jsArray->GetValueAt(i);
102 if (!item->IsObject()) {
103 continue;
104 }
105
106 auto itemObject = JSRef<JSObject>::Cast(item);
107 auto toolBarItem = AceType::MakeRefPtr<ToolBarItem>();
108 auto itemValueObject = itemObject->GetProperty("value");
109 if (itemValueObject->IsString()) {
110 toolBarItem->value = itemValueObject->ToString();
111 }
112
113 auto itemIconObject = itemObject->GetProperty("icon");
114 std::string icon;
115 ParseJsMedia(itemIconObject, icon);
116 toolBarItem->icon = icon;
117
118 auto itemActionValue = itemObject->GetProperty("action");
119 if (itemActionValue->IsFunction()) {
120 auto onClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(itemActionValue));
121 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
122 toolBarItem->action =
123 EventMarker([func = std::move(onClickFunc), node = targetNode, execCtx = info.GetExecutionContext()]() {
124 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
125 ACE_SCORING_EVENT("Navigation.toolBarItemClick");
126 PipelineContext::SetCallBackNode(node);
127 func->Execute();
128 });
129 auto onClickWithParamFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(itemActionValue));
130 toolBarItem->actionWithParam =
131 EventMarker([func = std::move(onClickWithParamFunc), node = targetNode,
132 execCtx = info.GetExecutionContext()](const BaseEventInfo* info) {
133 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
134 ACE_SCORING_EVENT("Navigation.menuItemButtonClick");
135 PipelineContext::SetCallBackNode(node);
136 func->Execute();
137 });
138 }
139 items.push_back(toolBarItem);
140 }
141 }
142
ParseCommonTitle(const JSRef<JSObject> & jsObj)143 bool JSNavigation::ParseCommonTitle(const JSRef<JSObject>& jsObj)
144 {
145 JSRef<JSVal> subtitle = jsObj->GetProperty("sub");
146 JSRef<JSVal> title = jsObj->GetProperty("main");
147 std::string mainTitle;
148 std::string subTitle;
149 bool hasSub = ParseJsString(subtitle, subTitle);
150 bool hasMain = ParseJsString(title, mainTitle);
151 if (hasSub || hasMain) {
152 return NavigationModel::GetInstance()->ParseCommonTitle(
153 hasSub, hasMain, subTitle, mainTitle);
154 }
155 return false;
156 }
157
Create(const JSCallbackInfo & info)158 void JSNavigation::Create(const JSCallbackInfo& info)
159 {
160 JSRef<JSObject> newObj;
161 std::string moduleName;
162 std::string pagePath;
163 if (info.Length() == 1) {
164 // input format: navPathStack/pathInfo
165 if (!info[0]->IsObject()) {
166 return;
167 }
168 // instance of NavPathStack
169 JSValueWrapper valueWrapper = info[0].Get().GetLocalHandle();
170 if (!JSNavPathStack::CheckIsValid(valueWrapper)) {
171 // first parameter = pathInfo{'moduleName': stringA, 'pagePath': stringB, 'isUserCreateStack': bool}
172 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "current stack is not navPathStack");
173 auto infoObj = JSRef<JSObject>::Cast(info[0]);
174 if (!infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->IsString() ||
175 !infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->IsString()) {
176 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "current pageInfo is invalid");
177 return;
178 }
179 moduleName = infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->ToString();
180 pagePath = infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->ToString();
181 } else {
182 // first parameter = navPathStack
183 newObj = JSRef<JSObject>::Cast(info[0]);
184 }
185 } else if (info.Length() == 2) {
186 // parameter = navPathStack(maybe empty) + pathInfo
187 if (!info[0]->IsObject() || !info[1]->IsObject()) {
188 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "stack or pageInfo is invalid");
189 return;
190 }
191 // instance of NavPathStack
192 JSValueWrapper valueWrapper = info[0].Get().GetLocalHandle();
193 if (!JSNavPathStack::CheckIsValid(valueWrapper)) {
194 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "current stack is not navPathStack");
195 return;
196 }
197 // pathInfo{'moduleName': stringA, 'pagePath': stringB, 'isUserCreateStack': bool}
198 auto infoObj = JSRef<JSObject>::Cast(info[1]);
199 auto isUserCreateStack = infoObj->GetProperty(NG::IS_USER_CREATE_STACK);
200 bool isUserDefined = true;
201 if (isUserCreateStack->IsBoolean()) {
202 isUserDefined = isUserCreateStack->ToBoolean();
203 }
204 if (isUserDefined) {
205 newObj = JSRef<JSObject>::Cast(info[0]);
206 }
207 if (!infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->IsString() ||
208 !infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->IsString()) {
209 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "current pageInfo is invalid");
210 return;
211 }
212 moduleName = infoObj->GetProperty(NG::NAVIGATION_MODULE_NAME)->ToString();
213 pagePath = infoObj->GetProperty(NG::NAVIGATION_PAGE_PATH)->ToString();
214 }
215
216 NavigationModel::GetInstance()->Create();
217 auto stackCreator = []() -> RefPtr<JSNavigationStack> { return AceType::MakeRefPtr<JSNavigationStack>(); };
218 auto stackUpdater = [&newObj, &info](RefPtr<NG::NavigationStack> stack) {
219 NavigationModel::GetInstance()->SetNavigationStackProvided(!newObj->IsEmpty());
220 auto jsStack = AceType::DynamicCast<JSNavigationStack>(stack);
221 CHECK_NULL_VOID(jsStack);
222 jsStack->SetJSExecutionContext(info.GetExecutionContext());
223 const auto& oldObj = jsStack->GetDataSourceObj();
224 if (oldObj->IsEmpty()) {
225 if (newObj->IsEmpty()) {
226 newObj = JSNavPathStack::CreateNewNavPathStackJSObject();
227 }
228 auto nativeObj = JSClass<JSNavPathStack>::NewInstance();
229 JSNavPathStack::SetNativeNavPathStack(newObj, nativeObj);
230 jsStack->SetDataSourceObj(newObj);
231 } else if (!newObj->IsEmpty()) {
232 auto objStrictEqual = [](const JSRef<JSVal>& obja, const JSRef<JSVal>& objb) -> bool {
233 return obja->GetLocalHandle()->IsStrictEquals(obja->GetEcmaVM(), objb->GetLocalHandle());
234 };
235 if (objStrictEqual(newObj, oldObj)) {
236 return;
237 }
238 auto nativeObj = JSClass<JSNavPathStack>::NewInstance();
239 JSNavPathStack::SetNativeNavPathStack(newObj, nativeObj);
240 jsStack->SetDataSourceObj(newObj);
241 }
242 };
243 NavigationModel::GetInstance()->SetNavigationStackWithCreatorAndUpdater(stackCreator, stackUpdater);
244 NavigationModel::GetInstance()->SetNavigationPathInfo(moduleName, pagePath);
245 }
246
JSBind(BindingTarget globalObj)247 void JSNavigation::JSBind(BindingTarget globalObj)
248 {
249 JsNavigationTransitionProxy::JSBind(globalObj);
250 JSClass<JSNavigation>::Declare("Navigation");
251 MethodOptions opt = MethodOptions::NONE;
252 JSClass<JSNavigation>::StaticMethod("create", &JSNavigation::Create);
253 JSClass<JSNavigation>::StaticMethod("title", &JSNavigation::SetTitle, opt);
254 JSClass<JSNavigation>::StaticMethod("subTitle", &JSNavigation::SetSubTitle, opt);
255 JSClass<JSNavigation>::StaticMethod("titleMode", &JSNavigation::SetTitleMode, opt);
256 JSClass<JSNavigation>::StaticMethod("hideTitleBar", &JSNavigation::SetHideTitleBar, opt);
257 JSClass<JSNavigation>::StaticMethod("hideBackButton", &JSNavigation::SetHideBackButton, opt);
258 JSClass<JSNavigation>::StaticMethod("hideToolBar", &JSNavigation::SetHideToolBar, opt);
259 JSClass<JSNavigation>::StaticMethod("toolBar", &JSNavigation::SetToolBar);
260 JSClass<JSNavigation>::StaticMethod("enableToolBarAdaptation", &JSNavigation::SetEnableToolBarAdaptation);
261 JSClass<JSNavigation>::StaticMethod("toolbarConfiguration", &JSNavigation::SetToolbarConfiguration);
262 JSClass<JSNavigation>::StaticMethod("menus", &JSNavigation::SetMenus);
263 JSClass<JSNavigation>::StaticMethod("menuCount", &JSNavigation::SetMenuCount);
264 JSClass<JSNavigation>::StaticMethod("onTitleModeChange", &JSNavigation::SetOnTitleModeChanged);
265 JSClass<JSNavigation>::StaticMethod("onNavigationModeChange", &JSNavigation::SetOnNavigationModeChange);
266 JSClass<JSNavigation>::StaticMethod("mode", &JSNavigation::SetUsrNavigationMode);
267 JSClass<JSNavigation>::StaticMethod("navBarWidth", &JSNavigation::SetNavBarWidth);
268 JSClass<JSNavigation>::StaticMethod("minContentWidth", &JSNavigation::SetMinContentWidth);
269 JSClass<JSNavigation>::StaticMethod("navBarWidthRange", &JSNavigation::SetNavBarWidthRange);
270 JSClass<JSNavigation>::StaticMethod("navBarPosition", &JSNavigation::SetNavBarPosition);
271 JSClass<JSNavigation>::StaticMethod("hideNavBar", &JSNavigation::SetHideNavBar);
272 JSClass<JSNavigation>::StaticMethod("backButtonIcon", &JSNavigation::SetBackButtonIcon);
273 JSClass<JSNavigation>::StaticMethod("onNavBarStateChange", &JSNavigation::SetOnNavBarStateChange);
274 JSClass<JSNavigation>::StaticMethod("navDestination", &JSNavigation::SetNavDestination);
275 JSClass<JSNavigation>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
276 JSClass<JSNavigation>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
277 JSClass<JSNavigation>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
278 JSClass<JSNavigation>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
279 JSClass<JSNavigation>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
280 JSClass<JSNavigation>::StaticMethod("customNavContentTransition", &JSNavigation::SetCustomNavContentTransition);
281 JSClass<JSNavigation>::StaticMethod("ignoreLayoutSafeArea", &JSNavigation::SetIgnoreLayoutSafeArea);
282 JSClass<JSNavigation>::StaticMethod("systemBarStyle", &JSNavigation::SetSystemBarStyle);
283 JSClass<JSNavigation>::StaticMethod("recoverable", &JSNavigation::SetRecoverable);
284 JSClass<JSNavigation>::StaticMethod("enableDragBar", &JSNavigation::SetEnableDragBar);
285 JSClass<JSNavigation>::StaticMethod("enableModeChangeAnimation", &JSNavigation::SetEnableModeChangeAnimation);
286 JSClass<JSNavigation>::InheritAndBind<JSContainerBase>(globalObj);
287 }
288
SetTitle(const JSCallbackInfo & info)289 void JSNavigation::SetTitle(const JSCallbackInfo& info)
290 {
291 if (info.Length() < 1) {
292 return;
293 }
294 // Resource and string type.
295 std::string title;
296 if (ParseJsString(info[0], title)) {
297 NavigationModel::GetInstance()->ParseCommonTitle(false, true, "", title);
298 } else if (info[0]->IsObject()) {
299 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
300 do {
301 // NavigationCommonTitle
302 if (ParseCommonTitle(jsObj)) {
303 break;
304 }
305 // CustomBuilder | NavigationCustomTitle
306 CalcDimension titleHeight;
307 if (!jsObj->HasProperty("height")) {
308 NavigationModel::GetInstance()->SetTitleHeight(titleHeight, false);
309 break;
310 }
311 JSRef<JSVal> height = jsObj->GetProperty("height");
312 bool isValid = JSContainerBase::ParseJsDimensionVpNG(height, titleHeight);
313 if (height->IsString()) {
314 std::string heightValue;
315 ParseJsString(height, heightValue);
316 if (heightValue == NG::TITLE_MAIN_WITH_SUB) {
317 NavigationModel::GetInstance()->SetTitleHeight(NG::DOUBLE_LINE_TITLEBAR_HEIGHT);
318 break;
319 }
320 if (heightValue == NG::TITLE_MAIN) {
321 NavigationModel::GetInstance()->SetTitleHeight(NG::SINGLE_LINE_TITLEBAR_HEIGHT);
322 break;
323 }
324 }
325 if (!isValid || titleHeight.Value() < 0) {
326 NavigationModel::GetInstance()->SetTitleHeight(Dimension(), true);
327 break;
328 }
329 NavigationModel::GetInstance()->SetTitleHeight(titleHeight);
330 } while (0);
331 JSRef<JSVal> builderObject = jsObj->GetProperty("builder");
332 if (builderObject->IsFunction()) {
333 ViewStackModel::GetInstance()->NewScope();
334 JsFunction jsBuilderFunc(info.This(), JSRef<JSFunc>::Cast(builderObject));
335 ACE_SCORING_EVENT("Navigation.title.builder");
336 jsBuilderFunc.Execute();
337 auto customNode = ViewStackModel::GetInstance()->Finish();
338 NavigationModel::GetInstance()->SetCustomTitle(customNode);
339 }
340 } else {
341 NavigationModel::GetInstance()->ParseCommonTitle(false, false, "", "");
342 }
343
344 NG::NavigationTitlebarOptions options;
345 JSNavigationUtils::ParseTitleBarOptions(info, true, options);
346 NavigationModel::GetInstance()->SetTitlebarOptions(std::move(options));
347 }
348
SetTitleMode(int32_t value)349 void JSNavigation::SetTitleMode(int32_t value)
350 {
351 if (value >= 0 && value <= TITLE_MODE_RANGE) {
352 NavigationModel::GetInstance()->SetTitleMode(static_cast<NG::NavigationTitleMode>(value));
353 }
354 }
355
SetSubTitle(const std::string & subTitle)356 void JSNavigation::SetSubTitle(const std::string& subTitle)
357 {
358 NavigationModel::GetInstance()->SetSubtitle(subTitle);
359 }
360
SetHideTitleBar(const JSCallbackInfo & info)361 void JSNavigation::SetHideTitleBar(const JSCallbackInfo& info)
362 {
363 bool isHide = false;
364 if (info.Length() > 0 && info[0]->IsBoolean()) {
365 isHide = info[0]->ToBoolean();
366 }
367 bool isAnimated = false;
368 if (info.Length() > 1 && info[1]->IsBoolean()) {
369 isAnimated = info[1]->ToBoolean();
370 }
371 NavigationModel::GetInstance()->SetHideTitleBar(isHide, isAnimated);
372 }
373
SetEnableToolBarAdaptation(const JSCallbackInfo & info)374 void JSNavigation::SetEnableToolBarAdaptation(const JSCallbackInfo& info)
375 {
376 if (!info[0]->IsBoolean()) {
377 NavigationModel::GetInstance()->SetEnableToolBarAdaptation(ENABLE_TOOLBAR_ADAPTATION_DEFULT);
378 return;
379 }
380 auto enable = info[0]->ToBoolean();
381 NavigationModel::GetInstance()->SetEnableToolBarAdaptation(enable);
382 }
383
SetEnableModeChangeAnimation(const JSCallbackInfo & info)384 void JSNavigation::SetEnableModeChangeAnimation(const JSCallbackInfo& info)
385 {
386 if (info.Length() < 1) {
387 return;
388 }
389 if (info[0]->IsBoolean()) {
390 NavigationModel::GetInstance()->SetEnableModeChangeAnimation(info[0]->ToBoolean());
391 return;
392 }
393 NavigationModel::GetInstance()->SetEnableModeChangeAnimation(true);
394 }
395
SetHideNavBar(bool hide)396 void JSNavigation::SetHideNavBar(bool hide)
397 {
398 NavigationModel::GetInstance()->SetHideNavBar(hide);
399 }
400
SetBackButtonIcon(const JSCallbackInfo & info)401 void JSNavigation::SetBackButtonIcon(const JSCallbackInfo& info)
402 {
403 if (info.Length() < 1) {
404 return;
405 }
406 std::string src;
407 auto noPixMap = ParseJsMedia(info[0], src);
408 auto isValidImage = false;
409 RefPtr<PixelMap> pixMap = nullptr;
410 #if defined(PIXEL_MAP_SUPPORTED)
411 if (!noPixMap) {
412 pixMap = CreatePixelMapFromNapiValue(info[0]);
413 }
414 #endif
415 if (noPixMap || pixMap != nullptr) {
416 isValidImage = true;
417 }
418 std::vector<std::string> nameList;
419 NG::ImageOption imageOption;
420 std::string bundleName;
421 std::string moduleName;
422 GetJsMediaBundleInfo(info[0], bundleName, moduleName);
423 nameList.emplace_back(bundleName);
424 nameList.emplace_back(moduleName);
425 imageOption.noPixMap = noPixMap;
426 imageOption.isValidImage = isValidImage;
427 std::function<void(WeakPtr<NG::FrameNode>)> iconSymbol = nullptr;
428 auto isSymbol = info[0]->IsObject() && src.empty() && pixMap == nullptr;
429 if (isSymbol) {
430 SetSymbolOptionApply(info, iconSymbol, info[0]);
431 }
432 if (info.Length() > 1) {
433 if (!info[1]->IsNull() && !info[1]->IsUndefined()) {
434 std::string backButtonAccessibilityText;
435 ParseJsString(info[1], backButtonAccessibilityText);
436 NavigationModel::GetInstance()->SetBackButtonIcon(iconSymbol, src, imageOption, pixMap, nameList,
437 true, backButtonAccessibilityText);
438 return;
439 }
440 }
441 NavigationModel::GetInstance()->SetBackButtonIcon(iconSymbol, src, imageOption, pixMap, nameList);
442 }
443
SetHideBackButton(bool hide)444 void JSNavigation::SetHideBackButton(bool hide)
445 {
446 NavigationModel::GetInstance()->SetHideBackButton(hide);
447 }
448
SetHideToolBar(const JSCallbackInfo & info)449 void JSNavigation::SetHideToolBar(const JSCallbackInfo& info)
450 {
451 bool isHide = false;
452 if (info.Length() > 0 && info[0]->IsBoolean()) {
453 isHide = info[0]->ToBoolean();
454 }
455 bool isAnimated = false;
456 if (info.Length() > 1 && info[1]->IsBoolean()) {
457 isAnimated = info[1]->ToBoolean();
458 }
459 NavigationModel::GetInstance()->SetHideToolBar(isHide, isAnimated);
460 }
461
SetToolBar(const JSCallbackInfo & info)462 void JSNavigation::SetToolBar(const JSCallbackInfo& info)
463 {
464 if (info.Length() < 1) {
465 return;
466 }
467 if (!info[0]->IsObject() && !info[0]->IsUndefined()) {
468 return;
469 }
470 if (info[0]->IsUndefined()) {
471 NavigationModel::GetInstance()->SetToolBarItems({});
472 return;
473 }
474 auto builderFuncParam = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
475 if (builderFuncParam->IsFunction()) {
476 ViewStackModel::GetInstance()->NewScope();
477 JsFunction jsBuilderFunc(builderFuncParam);
478 jsBuilderFunc.Execute();
479 auto customNode = ViewStackModel::GetInstance()->Finish();
480 NavigationModel::GetInstance()->SetCustomToolBar(customNode);
481 }
482
483 auto itemsValue = JSRef<JSObject>::Cast(info[0])->GetProperty("items");
484 if (!itemsValue->IsObject() || !itemsValue->IsArray()) {
485 return;
486 }
487 if (NavigationModel::GetInstance()->NeedSetItems()) {
488 std::vector<NG::BarItem> toolBarItems;
489 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
490 JSNavigationUtils::ParseBarItems(targetNode, info, JSRef<JSArray>::Cast(itemsValue), toolBarItems);
491 NavigationModel::GetInstance()->SetToolBarItems(std::move(toolBarItems));
492 return;
493 }
494 std::list<RefPtr<AceType>> items;
495 NavigationModel::GetInstance()->GetToolBarItems(items);
496 ParseToolBarItems(info, items);
497 }
498
SetToolbarConfiguration(const JSCallbackInfo & info)499 void JSNavigation::SetToolbarConfiguration(const JSCallbackInfo& info)
500 {
501 bool hideText = false;
502 JSNavigationUtils::ParseHideToolBarText(info, hideText);
503 NavigationModel::GetInstance()->SetHideItemText(hideText);
504 if (info[0]->IsUndefined() || info[0]->IsArray()) {
505 if (NavigationModel::GetInstance()->NeedSetItems()) {
506 std::vector<NG::BarItem> toolbarItems;
507 if (info[0]->IsUndefined()) {
508 toolbarItems = {};
509 } else {
510 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
511 JSNavigationUtils::ParseToolbarItemsConfiguration(
512 targetNode, info, JSRef<JSArray>::Cast(info[0]), toolbarItems);
513 }
514 NG::MoreButtonOptions toolbarMoreButtonOptions;
515 if (info.Length() > 1) {
516 auto optObj = JSRef<JSObject>::Cast(info[1]);
517 auto moreButtonProperty = optObj->GetProperty(MORE_BUTTON_OPTIONS_PROPERTY);
518 JSNavigationUtils::ParseToolBarMoreButtonOptions(moreButtonProperty, toolbarMoreButtonOptions);
519 }
520 NavigationModel::GetInstance()->SetToolbarMorebuttonOptions(std::move(toolbarMoreButtonOptions));
521 NavigationModel::GetInstance()->SetToolbarConfiguration(std::move(toolbarItems));
522 } else {
523 std::list<RefPtr<AceType>> items;
524 NavigationModel::GetInstance()->GetToolBarItems(items);
525 ParseToolBarItems(info, items);
526 }
527 } else if (info[0]->IsObject()) {
528 auto builderFuncParam = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
529 if (builderFuncParam->IsFunction()) {
530 ViewStackModel::GetInstance()->NewScope();
531 JsFunction jsBuilderFunc(builderFuncParam);
532 jsBuilderFunc.Execute();
533 auto customNode = ViewStackModel::GetInstance()->Finish();
534 NavigationModel::GetInstance()->SetCustomToolBar(customNode);
535 }
536 }
537
538 NG::NavigationToolbarOptions options;
539 JSNavigationUtils::ParseToolbarOptions(info, options);
540 NavigationModel::GetInstance()->SetToolbarOptions(std::move(options));
541 }
542
SetMenus(const JSCallbackInfo & info)543 void JSNavigation::SetMenus(const JSCallbackInfo& info)
544 {
545 if (info.Length() < 1) {
546 return;
547 }
548
549 NG::NavigationMenuOptions options;
550 if (info.Length() > 1) {
551 auto optObj = JSRef<JSObject>::Cast(info[1]);
552 auto moreButtonProperty = optObj->GetProperty(MORE_BUTTON_OPTIONS_PROPERTY);
553 JSNavigationUtils::ParseMenuOptions(moreButtonProperty, options);
554 }
555 if (info[0]->IsUndefined() || info[0]->IsArray()) {
556 if (NavigationModel::GetInstance()->NeedSetItems()) {
557 std::vector<NG::BarItem> menuItems;
558 if (info[0]->IsUndefined()) {
559 menuItems = {};
560 } else {
561 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
562 JSNavigationUtils::ParseBarItems(targetNode, info, JSRef<JSArray>::Cast(info[0]), menuItems);
563 }
564 NavigationModel::GetInstance()->SetMenuItems(std::move(menuItems));
565 NavigationModel::GetInstance()->SetMenuOptions(std::move(options));
566 return;
567 }
568 std::list<RefPtr<AceType>> items;
569 NavigationModel::GetInstance()->GetMenuItems(items);
570 ParseToolBarItems(info, items);
571 } else if (info[0]->IsObject()) {
572 auto builderObject = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
573 if (builderObject->IsFunction()) {
574 ViewStackModel::GetInstance()->NewScope();
575 JsFunction jsBuilderFunc(info.This(), JSRef<JSFunc>::Cast(builderObject));
576 ACE_SCORING_EVENT("Navigation.menu.builder");
577 jsBuilderFunc.Execute();
578 auto customNode = ViewStackModel::GetInstance()->Finish();
579 NavigationModel::GetInstance()->SetCustomMenu(customNode);
580 NavigationModel::GetInstance()->SetMenuOptions(std::move(options));
581 }
582 }
583 }
584
SetMenuCount(int32_t menuCount)585 void JSNavigation::SetMenuCount(int32_t menuCount)
586 {
587 NavigationModel::GetInstance()->SetMenuCount(menuCount);
588 }
589
SetOnTitleModeChanged(const JSCallbackInfo & info)590 void JSNavigation::SetOnTitleModeChanged(const JSCallbackInfo& info)
591 {
592 if (info.Length() < 1) {
593 return;
594 }
595 if (info[0]->IsFunction()) {
596 auto onTitleModeChangeCallback =
597 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
598 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
599 auto onTitleModeChange = [execCtx = info.GetExecutionContext(), func = std::move(onTitleModeChangeCallback),
600 node = targetNode](NG::NavigationTitleMode mode) {
601 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
602 ACE_SCORING_EVENT("OnTitleModeChange");
603 PipelineContext::SetCallBackNode(node);
604 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(mode));
605 func->ExecuteJS(1, ¶m);
606 };
607 auto changeHandler = AceType::MakeRefPtr<JsEventFunction<NavigationTitleModeChangeEvent, 1>>(
608 JSRef<JSFunc>::Cast(info[0]), TitleModeChangeEventToJSValue);
609 auto eventInfo = [executionContext = info.GetExecutionContext(), func = std::move(changeHandler),
610 node = targetNode](const BaseEventInfo* baseInfo) {
611 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
612 auto eventInfo = TypeInfoHelper::DynamicCast<NavigationTitleModeChangeEvent>(baseInfo);
613 if (!eventInfo) {
614 return;
615 }
616 ACE_SCORING_EVENT("Navigation.onTitleModeChanged");
617 PipelineContext::SetCallBackNode(node);
618 func->Execute(*eventInfo);
619 };
620 NavigationModel::GetInstance()->SetOnTitleModeChange(std::move(onTitleModeChange), std::move(eventInfo));
621 }
622 info.ReturnSelf();
623 }
624
SetUsrNavigationMode(const JSCallbackInfo & info)625 void JSNavigation::SetUsrNavigationMode(const JSCallbackInfo& info)
626 {
627 if (!info[0]->IsNumber()) {
628 NavigationModel::GetInstance()->SetUsrNavigationMode(NG::NavigationMode::AUTO);
629 return;
630 }
631 int32_t value = info[0]->ToNumber<int32_t>();
632 if (value >= 0 && value <= NAVIGATION_MODE_RANGE) {
633 NavigationModel::GetInstance()->SetUsrNavigationMode(static_cast<NG::NavigationMode>(value));
634 }
635 }
636
SetNavBarPosition(int32_t value)637 void JSNavigation::SetNavBarPosition(int32_t value)
638 {
639 if (value >= 0 && value <= NAV_BAR_POSITION_RANGE) {
640 NavigationModel::GetInstance()->SetNavBarPosition(static_cast<NG::NavBarPosition>(value));
641 }
642 }
643
ParseNavBarWidthObject(const JSCallbackInfo & info,JSRef<JSVal> arrowFunc,bool isNumber)644 void ParseNavBarWidthObject(const JSCallbackInfo& info, JSRef<JSVal> arrowFunc, bool isNumber)
645 {
646 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(arrowFunc));
647 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
648 auto onChangeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
649 node = targetNode, useNumber = isNumber](const Dimension& navBarWidth) {
650 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
651 ACE_SCORING_EVENT("Navigation.onNavBarWidthChangeEvent");
652 PipelineContext::SetCallBackNode(node);
653 auto newJSVal = useNumber ? JSRef<JSVal>::Make(ToJSValue(navBarWidth.ConvertToVp())) :
654 JSRef<JSVal>::Make(ToJSValue(navBarWidth.ToString()));
655 func->ExecuteJS(1, &newJSVal);
656 };
657 NavigationModel::GetInstance()->SetOnNavBarWidthChangeEvent(std::move(onChangeEvent));
658 }
659
SetNavBarWidth(const JSCallbackInfo & info)660 void JSNavigation::SetNavBarWidth(const JSCallbackInfo& info)
661 {
662 if (info.Length() < 1) {
663 return;
664 }
665
666 if (info[0]->IsObject()) {
667 JSRef<JSObject> callbackObj = JSRef<JSObject>::Cast(info[0]);
668 CalcDimension value;
669 auto navBarWidthValue = callbackObj->GetProperty("value");
670 auto navBarWidthCallbackValue = callbackObj->GetProperty("$value");
671 auto isValid = JSViewAbstract::ParseJsDimensionVpNG(navBarWidthValue, value);
672 if (value.Value() <= 0) {
673 value.SetValue(DEFAULT_NAV_BAR_WIDTH);
674 }
675 bool isNumber = navBarWidthValue->IsNumber();
676 if (isValid && navBarWidthCallbackValue->IsFunction()) {
677 NavigationModel::GetInstance()->SetNavBarWidth(value, true);
678 ParseNavBarWidthObject(info, navBarWidthCallbackValue, isNumber);
679 return;
680 }
681 }
682
683 CalcDimension navBarWidth;
684 if (!ParseJsDimensionVp(info[0], navBarWidth)) {
685 return;
686 }
687
688 if (navBarWidth.Value() <= 0) {
689 navBarWidth.SetValue(DEFAULT_NAV_BAR_WIDTH);
690 }
691
692 NavigationModel::GetInstance()->SetNavBarWidth(navBarWidth);
693 }
694
SetMinContentWidth(const JSCallbackInfo & info)695 void JSNavigation::SetMinContentWidth(const JSCallbackInfo& info)
696 {
697 if (info.Length() < 1) {
698 return;
699 }
700
701 CalcDimension minContentWidth;
702 if (!ParseJsDimensionVp(info[0], minContentWidth)) {
703 NavigationModel::GetInstance()->SetMinContentWidth(DEFAULT_MIN_CONTENT_WIDTH);
704 return;
705 }
706
707 if (LessNotEqual(minContentWidth.Value(), 0.0)) {
708 minContentWidth = DEFAULT_MIN_CONTENT_WIDTH;
709 }
710
711 NavigationModel::GetInstance()->SetMinContentWidth(minContentWidth);
712 }
713
SetNavBarWidthRange(const JSCallbackInfo & info)714 void JSNavigation::SetNavBarWidthRange(const JSCallbackInfo& info)
715 {
716 if (info.Length() < 1) {
717 return;
718 }
719 if (info[0]->IsNull() || info[0]->IsUndefined()) {
720 NavigationModel::GetInstance()->SetMinNavBarWidth(NG::DEFAULT_MIN_NAV_BAR_WIDTH);
721 NavigationModel::GetInstance()->SetMaxNavBarWidth(NG::DEFAULT_MAX_NAV_BAR_WIDTH);
722 return;
723 }
724 if (!info[0]->IsArray()) {
725 return;
726 }
727 auto rangeArray = JSRef<JSArray>::Cast(info[0]);
728 JSRef<JSVal> min = rangeArray->GetValueAt(0);
729 JSRef<JSVal> max = rangeArray->GetValueAt(1);
730
731 CalcDimension minNavBarWidth;
732 CalcDimension maxNavBarWidth;
733 if (min->IsNull() || min->IsUndefined() || !ParseJsDimensionVp(min, minNavBarWidth)) {
734 minNavBarWidth = NG::DEFAULT_MIN_NAV_BAR_WIDTH;
735 }
736 if (LessNotEqual(minNavBarWidth.Value(), 0.0)) {
737 minNavBarWidth.SetValue(0);
738 }
739 NavigationModel::GetInstance()->SetMinNavBarWidth(minNavBarWidth);
740
741 if (max->IsNull() || max->IsUndefined() || !ParseJsDimensionVp(max, maxNavBarWidth)) {
742 maxNavBarWidth = NG::DEFAULT_MAX_NAV_BAR_WIDTH;
743 }
744 if (LessNotEqual(maxNavBarWidth.Value(), 0.0)) {
745 maxNavBarWidth.SetValue(0);
746 }
747 NavigationModel::GetInstance()->SetMaxNavBarWidth(maxNavBarWidth);
748 }
749
SetOnNavBarStateChange(const JSCallbackInfo & info)750 void JSNavigation::SetOnNavBarStateChange(const JSCallbackInfo& info)
751 {
752 if (info.Length() < 1) {
753 return;
754 }
755
756 if (info[0]->IsFunction()) {
757 auto onNavBarStateChangeCallback =
758 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
759 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
760 auto onNavBarStateChange = [execCtx = info.GetExecutionContext(), func = std::move(onNavBarStateChangeCallback),
761 node = targetNode](bool isVisible) {
762 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
763 ACE_SCORING_EVENT("OnNavBarStateChange");
764 PipelineContext::SetCallBackNode(node);
765 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(isVisible));
766 func->ExecuteJS(1, ¶m);
767 };
768 NavigationModel::GetInstance()->SetOnNavBarStateChange(std::move(onNavBarStateChange));
769 }
770 info.ReturnSelf();
771 }
772
SetNavDestination(const JSCallbackInfo & info)773 void JSNavigation::SetNavDestination(const JSCallbackInfo& info)
774 {
775 if (info.Length() < 1) {
776 return;
777 }
778
779 if (!info[0]->IsObject()) {
780 return;
781 }
782
783 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
784 auto builder = obj->GetProperty("builder");
785 if (!builder->IsFunction()) {
786 return;
787 }
788
789 auto navigationStack = NavigationModel::GetInstance()->GetNavigationStack();
790 auto jsNavigationStack = AceType::DynamicCast<JSNavigationStack>(navigationStack);
791 if (jsNavigationStack) {
792 jsNavigationStack->SetNavDestBuilderFunc(JSRef<JSFunc>::Cast(builder));
793 }
794 }
795
SetOnNavigationModeChange(const JSCallbackInfo & info)796 void JSNavigation::SetOnNavigationModeChange(const JSCallbackInfo& info)
797 {
798 if (info.Length() < 1) {
799 return;
800 }
801 if (!info[0]->IsFunction()) {
802 info.ReturnSelf();
803 return;
804 }
805 auto onModeChangeCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
806 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
807 auto onModeChange = [execCtx = info.GetExecutionContext(), func = std::move(onModeChangeCallback),
808 node = targetNode](NG::NavigationMode mode) {
809 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
810 ACE_SCORING_EVENT("OnNavigationModeChange");
811 PipelineContext::SetCallBackNode(node);
812 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(static_cast<int8_t>(mode)));
813 func->ExecuteJS(1, ¶m);
814 };
815 NavigationModel::GetInstance()->SetOnNavigationModeChange(std::move(onModeChange));
816 info.ReturnSelf();
817 }
818
SetCustomNavContentTransition(const JSCallbackInfo & info)819 void JSNavigation::SetCustomNavContentTransition(const JSCallbackInfo& info)
820 {
821 if (info.Length() == 0 || !info[0]->IsFunction()) {
822 NavigationModel::GetInstance()->SetIsCustomAnimation(false);
823 return;
824 }
825 RefPtr<JsNavigationFunction> jsNavigationFunction =
826 AceType::MakeRefPtr<JsNavigationFunction>(JSRef<JSFunc>::Cast(info[0]));
827 auto onNavigationAnimation = [execCtx = info.GetExecutionContext(), func = std::move(jsNavigationFunction)](
828 RefPtr<NG::NavDestinationContext> from, RefPtr<NG::NavDestinationContext> to,
829 NG::NavigationOperation operation) -> NG::NavigationTransition {
830 NG::NavigationTransition transition;
831 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, transition);
832 auto ret = func->Execute(from, to, operation);
833 if (!ret->IsObject()) {
834 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "custom transition is invalid, do default animation");
835 transition.isValid = false;
836 return transition;
837 }
838
839 auto transitionObj = JSRef<JSObject>::Cast(ret);
840 JSRef<JSVal> interactive = transitionObj->GetProperty("isInteractive");
841 if (interactive->IsBoolean()) {
842 transition.interactive = interactive->ToBoolean();
843 } else {
844 transition.interactive = false;
845 }
846 int32_t timeout = -1;
847 JSRef<JSVal> time = transitionObj->GetProperty("timeout");
848 if (time->IsNumber()) {
849 timeout = time->ToNumber<int32_t>();
850 }
851 if (!transition.interactive) {
852 timeout = timeout < 0 ? NAVIGATION_ANIMATION_TIMEOUT : timeout;
853 }
854 transition.timeout = timeout;
855 JSRef<JSVal> transitionContext = transitionObj->GetProperty("transition");
856 if (!transitionContext->IsFunction()) {
857 return transition;
858 }
859 auto jsOnTransition = AceType::MakeRefPtr<JsNavigationFunction>(JSRef<JSFunc>::Cast(transitionContext));
860 if (transitionContext->IsFunction()) {
861 auto onTransition = [execCtx, func = std::move(jsOnTransition)](
862 const RefPtr<NG::NavigationTransitionProxy>& proxy) {
863 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
864 ACE_SCORING_EVENT("transition");
865 func->Execute(proxy);
866 };
867 transition.transition = std::move(onTransition);
868 }
869 JSRef<JSVal> endCallback = transitionObj->GetProperty("onTransitionEnd");
870 if (endCallback->IsFunction()) {
871 auto onEndedCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(endCallback));
872 auto onEndTransition = [execCtx, func = std::move(onEndedCallback)](bool isSuccess) {
873 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
874 ACE_SCORING_EVENT("onTransitionEnded");
875 JSRef<JSVal> successVal = JSRef<JSVal>::Make(ToJSValue(isSuccess));
876 func->ExecuteJS(1, &successVal);
877 };
878 transition.endCallback = std::move(onEndTransition);
879 }
880 return transition;
881 };
882 NavigationModel::GetInstance()->SetIsCustomAnimation(true);
883 NavigationModel::GetInstance()->SetCustomTransition(onNavigationAnimation);
884 }
885
SetIgnoreLayoutSafeArea(const JSCallbackInfo & info)886 void JSNavigation::SetIgnoreLayoutSafeArea(const JSCallbackInfo& info)
887 {
888 NG::SafeAreaExpandOpts opts { .type = NG::SAFE_AREA_TYPE_SYSTEM, .edges = NG::SAFE_AREA_EDGE_ALL};
889 if (info.Length() >= PARAMETER_LENGTH_ONE && info[FIRST_INDEX]->IsArray()) {
890 auto paramArray = JSRef<JSArray>::Cast(info[0]);
891 uint32_t safeAreaType = NG::SAFE_AREA_TYPE_NONE;
892 for (size_t i = 0; i < paramArray->Length(); ++i) {
893 auto value = paramArray->GetValueAt(i);
894 if (!value->IsNumber() ||
895 value->ToNumber<uint32_t>() >= SAFE_AREA_TYPE_LIMIT ||
896 value->ToNumber<uint32_t>() == SAFE_AREA_EDGE_SYSTEM) {
897 safeAreaType = NG::SAFE_AREA_TYPE_SYSTEM;
898 break;
899 }
900 }
901 opts.type = safeAreaType;
902 }
903
904 if (info.Length() >= PARAMETER_LENGTH_TWO && info[SECOND_INDEX]->IsArray()) {
905 auto paramArray = JSRef<JSArray>::Cast(info[1]);
906 uint32_t safeAreaEdge = NG::SAFE_AREA_EDGE_NONE;
907 for (size_t i = 0; i < paramArray->Length(); ++i) {
908 auto value = paramArray->GetValueAt(i);
909 if (!value->IsNumber() ||
910 value->ToNumber<uint32_t>() >= SAFE_AREA_EDGE_LIMIT) {
911 safeAreaEdge = NG::SAFE_AREA_EDGE_ALL;
912 break;
913 }
914 if (value->ToNumber<uint32_t>() == SAFE_AREA_EDGE_TOP ||
915 value->ToNumber<uint32_t>() == SAFE_AREA_EDGE_BOTTOM) {
916 safeAreaEdge |= (1 << value->ToNumber<uint32_t>());
917 }
918 }
919 opts.edges = safeAreaEdge;
920 }
921 NavigationModel::GetInstance()->SetIgnoreLayoutSafeArea(opts);
922 }
923
SetSystemBarStyle(const JSCallbackInfo & info)924 void JSNavigation::SetSystemBarStyle(const JSCallbackInfo& info)
925 {
926 RefPtr<SystemBarStyle> style = nullptr;
927 if (info.Length() == 1 && info[0]->IsObject()) {
928 auto styleObj = JsConverter::ConvertJsValToNapiValue(info[0]);
929 auto env = GetCurrentEnv();
930 if (env) {
931 style = SystemBarStyle::CreateStyleFromJsObj(env, styleObj);
932 }
933 }
934 NavigationModel::GetInstance()->SetSystemBarStyle(style);
935 }
936
SetRecoverable(const JSCallbackInfo & info)937 void JSNavigation::SetRecoverable(const JSCallbackInfo& info)
938 {
939 if (!info[0]->IsBoolean()) {
940 // the default value of navigation's recoverable is false
941 NavigationModel::GetInstance()->SetRecoverable(false);
942 return;
943 }
944 auto recoverable = info[0]->ToBoolean();
945 NavigationModel::GetInstance()->SetRecoverable(recoverable);
946 }
947
SetEnableDragBar(const JSCallbackInfo & info)948 void JSNavigation::SetEnableDragBar(const JSCallbackInfo& info)
949 {
950 if (!info[0]->IsBoolean()) {
951 // the default value of navigation's drag bar is false
952 NavigationModel::GetInstance()->SetEnableDragBar(false);
953 return;
954 }
955 auto enableDragBar = info[0]->ToBoolean();
956 NavigationModel::GetInstance()->SetEnableDragBar(enableDragBar);
957 }
958 } // namespace OHOS::Ace::Framework
959