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