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, ¶m);
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, ¶m);
610 };
611 NG::NavigationView::SetOnNavBarStateChange(std::move(onNavBarStateChange));
612 }
613 info.ReturnSelf();
614 }
615
616 } // namespace OHOS::Ace::Framework
617