• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "frameworks/bridge/declarative_frontend/jsview/js_navigation.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "base/memory/referenced.h"
20 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
21 #include "bridge/declarative_frontend/jsview/js_utils.h"
22 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
23 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
24 #include "bridge/declarative_frontend/view_stack_processor.h"
25 #include "core/components/navigation_bar/navigation_bar_component_v2.h"
26 #include "core/components/navigation_bar/navigation_container_component.h"
27 #include "core/components/option/option_component.h"
28 #include "core/components_ng/base/view_stack_processor.h"
29 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
30 #include "core/components_ng/pattern/navigation/navigation_view.h"
31 
32 namespace OHOS::Ace::Framework {
33 namespace {
34 constexpr int32_t TITLE_MODE_RANGE = 2;
35 constexpr int32_t NAVIGATION_MODE_RANGE = 2;
36 constexpr int32_t NAV_BAR_POSITION_RANGE = 1;
37 constexpr int32_t DEFAULT_NAV_BAR_WIDTH = 200;
TitleModeChangeEventToJSValue(const NavigationTitleModeChangeEvent & eventInfo)38 JSRef<JSVal> TitleModeChangeEventToJSValue(const NavigationTitleModeChangeEvent& eventInfo)
39 {
40     return JSRef<JSVal>::Make(ToJSValue(eventInfo.IsMiniBar() ? static_cast<int32_t>(NavigationTitleMode::MINI)
41                                                               : static_cast<int32_t>(NavigationTitleMode::FULL)));
42 }
43 
44 } // namespace
45 
ParseToolBarItems(const JSRef<JSArray> & jsArray,std::list<RefPtr<ToolBarItem>> & items)46 void JSNavigation::ParseToolBarItems(const JSRef<JSArray>& jsArray, std::list<RefPtr<ToolBarItem>>& items)
47 {
48     auto length = jsArray->Length();
49     for (size_t i = 0; i < length; i++) {
50         auto item = jsArray->GetValueAt(i);
51         if (!item->IsObject()) {
52             LOGE("tool bar item is not object");
53             continue;
54         }
55 
56         auto itemObject = JSRef<JSObject>::Cast(item);
57         auto toolBarItem = AceType::MakeRefPtr<ToolBarItem>();
58         auto itemValueObject = itemObject->GetProperty("value");
59         if (itemValueObject->IsString()) {
60             toolBarItem->value = itemValueObject->ToString();
61         }
62 
63         auto itemIconObject = itemObject->GetProperty("icon");
64         std::string icon;
65         if (!ParseJsMedia(itemIconObject, icon)) {
66             LOGE("iconValue is null");
67         }
68         toolBarItem->icon = icon;
69 
70         auto itemActionValue = itemObject->GetProperty("action");
71         if (itemActionValue->IsFunction()) {
72             auto onClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(itemActionValue));
73             toolBarItem->action = EventMarker([func = std::move(onClickFunc)]() {
74                 ACE_SCORING_EVENT("Navigation.toolBarItemClick");
75                 func->Execute();
76             });
77             auto onClickWithParamFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(itemActionValue));
78             toolBarItem->actionWithParam =
79                 EventMarker([func = std::move(onClickWithParamFunc)](const BaseEventInfo* info) {
80                     ACE_SCORING_EVENT("Navigation.menuItemButtonClick");
81                     func->Execute();
82                 });
83         }
84         items.push_back(toolBarItem);
85     }
86 }
87 
ParseBarItems(const JSCallbackInfo & info,const JSRef<JSArray> & jsArray,std::vector<NG::BarItem> & items)88 void JSNavigation::ParseBarItems(
89     const JSCallbackInfo& info, const JSRef<JSArray>& jsArray, std::vector<NG::BarItem>& items)
90 {
91     auto length = jsArray->Length();
92     for (size_t i = 0; i < length; i++) {
93         auto item = jsArray->GetValueAt(i);
94         if (!item->IsObject()) {
95             LOGE("tool bar item is not object");
96             continue;
97         }
98         auto itemObject = JSRef<JSObject>::Cast(item);
99         NG::BarItem toolBarItem;
100         auto itemValueObject = itemObject->GetProperty("value");
101         if (itemValueObject->IsString()) {
102             toolBarItem.text = itemValueObject->ToString();
103         }
104 
105         auto itemIconObject = itemObject->GetProperty("icon");
106         if (itemIconObject->IsString()) {
107             toolBarItem.icon = itemIconObject->ToString();
108         }
109 
110         auto itemActionValue = itemObject->GetProperty("action");
111         if (itemActionValue->IsFunction()) {
112             RefPtr<JsFunction> onClickFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(itemActionValue));
113             auto onItemClick = [execCtx = info.GetExecutionContext(), func = std::move(onClickFunc)]() {
114                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
115                 if (func) {
116                     func->ExecuteJS();
117                 }
118             };
119             toolBarItem.action = onItemClick;
120         }
121         items.push_back(toolBarItem);
122     }
123 }
124 
ParseCommonTitle(const JSRef<JSVal> & jsValue)125 bool JSNavigation::ParseCommonTitle(const JSRef<JSVal>& jsValue)
126 {
127     if (!Container::IsCurrentUseNewPipeline()) {
128         return false;
129     }
130 
131     bool isCommonTitle = false;
132     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
133     JSRef<JSVal> subtitle = jsObj->GetProperty("sub");
134     if (subtitle->IsString()) {
135         NG::NavigationView::SetSubtitle(subtitle->ToString());
136         isCommonTitle = true;
137     }
138     JSRef<JSVal> title = jsObj->GetProperty("main");
139     if (title->IsString()) {
140         // if no subtitle, title's maxLine = 2
141         NG::NavigationView::SetTitle(title->ToString(), (subtitle->IsString()));
142         isCommonTitle = true;
143     }
144     return isCommonTitle;
145 }
146 
Create()147 void JSNavigation::Create()
148 {
149     if (Container::IsCurrentUseNewPipeline()) {
150         NG::NavigationView::Create();
151         return;
152     }
153     auto navigationContainer = AceType::MakeRefPtr<NavigationContainerComponent>();
154     ViewStackProcessor::GetInstance()->Push(navigationContainer);
155 }
156 
JSBind(BindingTarget globalObj)157 void JSNavigation::JSBind(BindingTarget globalObj)
158 {
159     JSClass<JSNavigation>::Declare("Navigation");
160     MethodOptions opt = MethodOptions::NONE;
161     JSClass<JSNavigation>::StaticMethod("create", &JSNavigation::Create, opt);
162     JSClass<JSNavigation>::StaticMethod("title", &JSNavigation::SetTitle, opt);
163     JSClass<JSNavigation>::StaticMethod("subTitle", &JSNavigation::SetSubTitle, opt);
164     JSClass<JSNavigation>::StaticMethod("titleMode", &JSNavigation::SetTitleMode, opt);
165     JSClass<JSNavigation>::StaticMethod("hideTitleBar", &JSNavigation::SetHideTitleBar, opt);
166     JSClass<JSNavigation>::StaticMethod("hideBackButton", &JSNavigation::SetHideBackButton, opt);
167     JSClass<JSNavigation>::StaticMethod("hideToolBar", &JSNavigation::SetHideToolBar, opt);
168     JSClass<JSNavigation>::StaticMethod("toolBar", &JSNavigation::SetToolBar);
169     JSClass<JSNavigation>::StaticMethod("menus", &JSNavigation::SetMenus);
170     JSClass<JSNavigation>::StaticMethod("menuCount", &JSNavigation::SetMenuCount);
171     JSClass<JSNavigation>::StaticMethod("onTitleModeChange", &JSNavigation::SetOnTitleModeChanged);
172     JSClass<JSNavigation>::StaticMethod("mode", &JSNavigation::SetUsrNavigationMode);
173     JSClass<JSNavigation>::StaticMethod("navBarWidth", &JSNavigation::SetNavBarWidth);
174     JSClass<JSNavigation>::StaticMethod("navBarPosition", &JSNavigation::SetNavBarPosition);
175     JSClass<JSNavigation>::StaticMethod("hideNavBar", &JSNavigation::SetHideNavBar);
176     JSClass<JSNavigation>::StaticMethod("backButtonIcon", &JSNavigation::SetBackButtonIcon);
177     JSClass<JSNavigation>::StaticMethod("onNavBarStateChange", &JSNavigation::SetOnNavBarStateChange);
178     JSClass<JSNavigation>::Inherit<JSContainerBase>();
179     JSClass<JSNavigation>::Inherit<JSViewAbstract>();
180     JSClass<JSNavigation>::Bind(globalObj);
181 }
182 
SetTitle(const JSCallbackInfo & info)183 void JSNavigation::SetTitle(const JSCallbackInfo& info)
184 {
185     if (info.Length() < 1) {
186         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
187         return;
188     }
189     if (info[0]->IsString()) {
190         if (Container::IsCurrentUseNewPipeline()) {
191             NG::NavigationView::SetTitle(info[0]->ToString());
192             return;
193         }
194         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
195         auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
196         if (!navigationContainer) {
197             LOGI("component is not navigationContainer.");
198             return;
199         }
200         navigationContainer->GetDeclaration()->title = info[0]->ToString();
201     } else if (info[0]->IsObject()) {
202         if (ParseCommonTitle(info[0])) {
203             return;
204         }
205 
206         // CustomBuilder | NavigationCustomTitle
207         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
208         JSRef<JSVal> builderObject = jsObj->GetProperty("builder");
209         if (builderObject->IsFunction()) {
210             if (Container::IsCurrentUseNewPipeline()) {
211                 RefPtr<NG::UINode> customNode;
212                 {
213                     NG::ScopedViewStackProcessor builderViewStackProcessor;
214                     JsFunction jsBuilderFunc(info.This(), JSRef<JSObject>::Cast(builderObject));
215                     ACE_SCORING_EVENT("Navigation.title.builder");
216                     jsBuilderFunc.Execute();
217                     customNode = NG::ViewStackProcessor::GetInstance()->Finish();
218                 }
219                 NG::NavigationView::SetCustomTitle(customNode);
220             } else {
221                 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
222                 auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
223                 if (!navigationContainer) {
224                     LOGI("component is not navigationContainer.");
225                     return;
226                 }
227                 {
228                     ScopedViewStackProcessor builderViewStackProcessor;
229                     JsFunction jsBuilderFunc(info.This(), JSRef<JSObject>::Cast(builderObject));
230                     ACE_SCORING_EVENT("Navigation.title.builder");
231                     jsBuilderFunc.Execute();
232                     auto customTile = ViewStackProcessor::GetInstance()->Finish();
233 #if defined(PREVIEW)
234                     auto composedComponent =
235                         ViewStackProcessor::GetInstance()->CreateInspectorWrapper("NavigationTitle");
236                     composedComponent->SetChild(customTile);
237                     navigationContainer->GetDeclaration()->customTitle = composedComponent;
238 #else
239                     navigationContainer->GetDeclaration()->customTitle = customTile;
240 #endif
241                 }
242             }
243         }
244 
245         if (!Container::IsCurrentUseNewPipeline()) {
246             return;
247         }
248         JSRef<JSVal> height = jsObj->GetProperty("height");
249         if (height->IsNumber()) {
250             if (height->ToNumber<int32_t>() == 0) {
251                 NG::NavigationView::SetTitleHeight(NG::FULL_SINGLE_LINE_TITLEBAR_HEIGHT);
252                 return;
253             }
254             if (height->ToNumber<int32_t>() == 1) {
255                 NG::NavigationView::SetTitleHeight(NG::FULL_DOUBLE_LINE_TITLEBAR_HEIGHT);
256                 return;
257             }
258             Dimension titleHeight;
259             if (!JSContainerBase::ParseJsDimensionVp(height, titleHeight)) {
260                 return;
261             }
262             NG::NavigationView::SetTitleHeight(titleHeight);
263         }
264     } else {
265         LOGE("arg is not [String|Function].");
266     }
267 }
268 
SetTitleMode(int32_t value)269 void JSNavigation::SetTitleMode(int32_t value)
270 {
271     if (value >= 0 && value <= TITLE_MODE_RANGE) {
272         if (Container::IsCurrentUseNewPipeline()) {
273             NG::NavigationView::SetTitleMode(static_cast<NG::NavigationTitleMode>(value));
274             return;
275         }
276         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
277         auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
278         if (navigationContainer) {
279             navigationContainer->GetDeclaration()->titleMode = static_cast<NavigationTitleMode>(value);
280         }
281     } else {
282         LOGE("invalid value for titleMode");
283     }
284 }
285 
SetSubTitle(const std::string & subTitle)286 void JSNavigation::SetSubTitle(const std::string& subTitle)
287 {
288     if (Container::IsCurrentUseNewPipeline()) {
289         NG::NavigationView::SetSubtitle(subTitle);
290         return;
291     }
292     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
293     auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
294     if (navigationContainer) {
295         navigationContainer->GetDeclaration()->subTitle = subTitle;
296     }
297 }
298 
SetHideTitleBar(bool hide)299 void JSNavigation::SetHideTitleBar(bool hide)
300 {
301     if (Container::IsCurrentUseNewPipeline()) {
302         NG::NavigationView::SetHideTitleBar(hide);
303         return;
304     }
305     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
306     auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
307     if (navigationContainer) {
308         auto declaration = navigationContainer->GetDeclaration();
309         declaration->hideBar = hide;
310         declaration->animationOption = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
311     }
312 }
313 
SetHideNavBar(bool hide)314 void JSNavigation::SetHideNavBar(bool hide)
315 {
316     if (!Container::IsCurrentUseNewPipeline()) {
317         return;
318     }
319     NG::NavigationView::SetHideNavBar(hide);
320 }
321 
SetBackButtonIcon(const JSCallbackInfo & info)322 void JSNavigation::SetBackButtonIcon(const JSCallbackInfo& info)
323 {
324     if (!Container::IsCurrentUseNewPipeline()) {
325         return;
326     }
327     if (info.Length() < 1) {
328         LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
329         return;
330     }
331     std::string src;
332     auto noPixMap = ParseJsMedia(info[0], src);
333 
334     RefPtr<PixelMap> pixMap = nullptr;
335 #if defined(PIXEL_MAP_SUPPORTED)
336     if (!noPixMap) {
337         pixMap = CreatePixelMapFromNapiValue(info[0]);
338     }
339 #endif
340     NG::NavigationView::SetBackButtonIcon(src, noPixMap, pixMap);
341 }
342 
SetHideBackButton(bool hide)343 void JSNavigation::SetHideBackButton(bool hide)
344 {
345     if (Container::IsCurrentUseNewPipeline()) {
346         NG::NavigationView::SetHideBackButton(hide);
347         return;
348     }
349     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
350     auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
351     if (navigationContainer) {
352         navigationContainer->GetDeclaration()->hideBarBackButton = hide;
353     }
354 }
355 
SetHideToolBar(bool hide)356 void JSNavigation::SetHideToolBar(bool hide)
357 {
358     if (Container::IsCurrentUseNewPipeline()) {
359         NG::NavigationView::SetHideToolBar(hide);
360         return;
361     }
362     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
363     auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
364     if (navigationContainer) {
365         auto declaration = navigationContainer->GetDeclaration();
366         declaration->hideToolbar = hide;
367         declaration->animationOption = ViewStackProcessor::GetInstance()->GetImplicitAnimationOption();
368     }
369 }
370 
SetToolBar(const JSCallbackInfo & info)371 void JSNavigation::SetToolBar(const JSCallbackInfo& info)
372 {
373     if (info.Length() < 1) {
374         LOGE("The arg is wrong, it is supposed to have at least one argument");
375         return;
376     }
377     if (!info[0]->IsObject()) {
378         LOGE("arg is not a object.");
379         return;
380     }
381     auto builderFuncParam = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
382     if (builderFuncParam->IsFunction()) {
383         if (Container::IsCurrentUseNewPipeline()) {
384             RefPtr<NG::UINode> customNode;
385             {
386                 NG::ScopedViewStackProcessor builderViewStackProcessor;
387                 JsFunction jsBuilderFunc(builderFuncParam);
388                 jsBuilderFunc.Execute();
389                 customNode = NG::ViewStackProcessor::GetInstance()->Finish();
390             }
391             NG::NavigationView::SetCustomToolBar(customNode);
392             return;
393         }
394         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
395         auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
396         if (!navigationContainer) {
397             LOGI("component is not navigationContainer.");
398             return;
399         }
400         {
401             ScopedViewStackProcessor builderViewStackProcessor;
402             JsFunction jsBuilderFunc(builderFuncParam);
403             jsBuilderFunc.Execute();
404             RefPtr<Component> builderGeneratedRootComponent = ViewStackProcessor::GetInstance()->Finish();
405             navigationContainer->GetDeclaration()->toolBarBuilder = builderGeneratedRootComponent;
406         }
407         return;
408     }
409 
410     auto itemsValue = JSRef<JSObject>::Cast(info[0])->GetProperty("items");
411     if (!itemsValue->IsObject() || !itemsValue->IsArray()) {
412         LOGE("arg format error: not find items");
413         return;
414     }
415     if (Container::IsCurrentUseNewPipeline()) {
416         std::vector<NG::BarItem> toolBarItems;
417         ParseBarItems(info, JSRef<JSArray>::Cast(itemsValue), toolBarItems);
418         NG::NavigationView::SetToolBarItems(std::move(toolBarItems));
419         return;
420     }
421     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
422     auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
423     if (!navigationContainer) {
424         LOGI("component is not navigationContainer.");
425         return;
426     }
427     ParseToolBarItems(JSRef<JSArray>::Cast(itemsValue), navigationContainer->GetDeclaration()->toolbarItems);
428 }
429 
SetMenus(const JSCallbackInfo & info)430 void JSNavigation::SetMenus(const JSCallbackInfo& info)
431 {
432     if (info.Length() < 1) {
433         LOGE("The arg is wrong, it is supposed to have at least one argument");
434         return;
435     }
436 
437     if (info[0]->IsArray()) {
438         if (Container::IsCurrentUseNewPipeline()) {
439             std::vector<NG::BarItem> menuItems;
440             ParseBarItems(info, JSRef<JSArray>::Cast(info[0]), menuItems);
441             NG::NavigationView::SetMenuItems(std::move(menuItems));
442             return;
443         }
444         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
445         auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
446         if (!navigationContainer) {
447             LOGI("component is not navigationContainer.");
448             return;
449         }
450         ParseToolBarItems(JSRef<JSArray>::Cast(info[0]), navigationContainer->GetDeclaration()->menuItems);
451     } else if (info[0]->IsObject()) {
452         auto builderObject = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
453         if (builderObject->IsFunction()) {
454             if (Container::IsCurrentUseNewPipeline()) {
455                 RefPtr<NG::UINode> customNode;
456                 {
457                     NG::ScopedViewStackProcessor builderViewStackProcessor;
458                     JsFunction jsBuilderFunc(info.This(), JSRef<JSObject>::Cast(builderObject));
459                     ACE_SCORING_EVENT("Navigation.menu.builder");
460                     jsBuilderFunc.Execute();
461                     customNode = NG::ViewStackProcessor::GetInstance()->Finish();
462                 }
463                 NG::NavigationView::SetCustomMenu(customNode);
464                 return;
465             }
466             auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
467             auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
468             if (!navigationContainer) {
469                 LOGI("component is not navigationContainer.");
470                 return;
471             }
472             {
473                 ScopedViewStackProcessor builderViewStackProcessor;
474                 JsFunction jsBuilderFunc(info.This(), JSRef<JSObject>::Cast(builderObject));
475                 ACE_SCORING_EVENT("Navigation.menu.builder");
476                 jsBuilderFunc.Execute();
477                 auto customMenus = ViewStackProcessor::GetInstance()->Finish();
478 #if defined(PREVIEW)
479                 auto composedComponent = ViewStackProcessor::GetInstance()->CreateInspectorWrapper("NavigationMenus");
480                 composedComponent->SetChild(customMenus);
481                 navigationContainer->GetDeclaration()->customMenus = composedComponent;
482 #else
483                 navigationContainer->GetDeclaration()->customMenus = customMenus;
484 #endif
485             }
486         }
487     } else {
488         LOGE("arg is not [String|Function].");
489     }
490 }
491 
SetMenuCount(int32_t menuCount)492 void JSNavigation::SetMenuCount(int32_t menuCount)
493 {
494     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
495     auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
496     if (navigationContainer) {
497         navigationContainer->SetMenuCount(menuCount);
498     }
499 }
500 
SetOnTitleModeChanged(const JSCallbackInfo & info)501 void JSNavigation::SetOnTitleModeChanged(const JSCallbackInfo& info)
502 {
503     if (info.Length() < 1) {
504         LOGE("The arg is wrong, it is supposed to have at least one argument");
505         return;
506     }
507     if (info[0]->IsFunction()) {
508         if (Container::IsCurrentUseNewPipeline()) {
509             auto onTitleModeChangeCallback =
510                 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
511             auto onTitleModeChange = [execCtx = info.GetExecutionContext(),
512                                          func = std::move(onTitleModeChangeCallback)](NG::NavigationTitleMode mode) {
513                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
514                 ACE_SCORING_EVENT("OnTitleModeChange");
515                 JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(mode));
516                 func->ExecuteJS(1, &param);
517             };
518             NG::NavigationView::SetOnTitleModeChange(std::move(onTitleModeChange));
519             return;
520         }
521         auto changeHandler = AceType::MakeRefPtr<JsEventFunction<NavigationTitleModeChangeEvent, 1>>(
522             JSRef<JSFunc>::Cast(info[0]), TitleModeChangeEventToJSValue);
523         auto eventMarker = EventMarker([executionContext = info.GetExecutionContext(), func = std::move(changeHandler)](
524                                            const BaseEventInfo* baseInfo) {
525             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
526             auto eventInfo = TypeInfoHelper::DynamicCast<NavigationTitleModeChangeEvent>(baseInfo);
527             if (!eventInfo) {
528                 LOGE("HandleChangeEvent eventInfo == nullptr");
529                 return;
530             }
531             ACE_SCORING_EVENT("Navigation.onTitleModeChanged");
532             func->Execute(*eventInfo);
533         });
534         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
535         auto navigationContainer = AceType::DynamicCast<OHOS::Ace::NavigationContainerComponent>(component);
536         if (navigationContainer) {
537             navigationContainer->GetDeclaration()->titleModeChangedEvent = eventMarker;
538         }
539     }
540     info.ReturnSelf();
541 }
542 
SetUsrNavigationMode(int32_t value)543 void JSNavigation::SetUsrNavigationMode(int32_t value)
544 {
545     if (!Container::IsCurrentUseNewPipeline()) {
546         return;
547     }
548 
549     if (value >= 0 && value <= NAVIGATION_MODE_RANGE) {
550         NG::NavigationView::SetUsrNavigationMode(static_cast<NG::NavigationMode>(value));
551     } else {
552         LOGE("invalid value for navigationMode");
553     }
554 }
555 
SetNavBarPosition(int32_t value)556 void JSNavigation::SetNavBarPosition(int32_t value)
557 {
558     if (!Container::IsCurrentUseNewPipeline()) {
559         return;
560     }
561 
562     if (value >= 0 && value <= NAV_BAR_POSITION_RANGE) {
563         NG::NavigationView::SetNavBarPosition(static_cast<NG::NavBarPosition>(value));
564     } else {
565         LOGE("invalid value for navBarPosition");
566     }
567 }
568 
SetNavBarWidth(const JSCallbackInfo & info)569 void JSNavigation::SetNavBarWidth(const JSCallbackInfo& info)
570 {
571     if (!Container::IsCurrentUseNewPipeline()) {
572         return;
573     }
574     if (info.Length() < 1) {
575         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
576         return;
577     }
578 
579     Dimension navBarWidth;
580     if (!ParseJsDimensionVp(info[0], navBarWidth)) {
581         return;
582     }
583 
584     if (navBarWidth.Value() <= 0) {
585         navBarWidth.SetValue(DEFAULT_NAV_BAR_WIDTH);
586     }
587 
588     NG::NavigationView::SetNavBarWidth(navBarWidth);
589 }
590 
SetOnNavBarStateChange(const JSCallbackInfo & info)591 void JSNavigation::SetOnNavBarStateChange(const JSCallbackInfo& info)
592 {
593     if (!Container::IsCurrentUseNewPipeline()) {
594         return;
595     }
596     if (info.Length() < 1) {
597         LOGE("The arg is wrong, it is supposed to have at least one argument");
598         return;
599     }
600 
601     if (info[0]->IsFunction()) {
602         auto onNavBarStateChangeCallback =
603             AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
604         auto onNavBarStateChange = [execCtx = info.GetExecutionContext(),
605                                        func = std::move(onNavBarStateChangeCallback)](bool isVisible) {
606             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
607             ACE_SCORING_EVENT("OnNavBarStateChange");
608             JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(isVisible));
609             func->ExecuteJS(1, &param);
610         };
611         NG::NavigationView::SetOnNavBarStateChange(std::move(onNavBarStateChange));
612     }
613     info.ReturnSelf();
614 }
615 
616 } // namespace OHOS::Ace::Framework
617