1 /*
2 * Copyright (c) 2023 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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_nav_destination_bridge.h"
16
17 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_navigation_utils.h"
18 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
19 #include "bridge/declarative_frontend/jsview/js_utils.h"
20 #include "core/components_ng/pattern/navrouter/navdestination_model_ng.h"
21 namespace OHOS::Ace::NG {
22 constexpr int NUM_0 = 0;
23 constexpr int NUM_1 = 1;
24 constexpr int NUM_2 = 2;
25 constexpr int32_t JS_EMUN_TRANSITIONTYPE_NONE = 1;
26 constexpr int32_t JS_EMUN_TRANSITIONTYPE_TITLE = 2;
27 constexpr int32_t JS_EMUN_TRANSITIONTYPE_CONTENT = 3;
28
ParseTransitionType(int32_t value)29 NavigationSystemTransitionType ParseTransitionType(int32_t value)
30 {
31 switch (value) {
32 case JS_EMUN_TRANSITIONTYPE_NONE:
33 return NG::NavigationSystemTransitionType::NONE;
34 case JS_EMUN_TRANSITIONTYPE_TITLE:
35 return NG::NavigationSystemTransitionType::TITLE;
36 case JS_EMUN_TRANSITIONTYPE_CONTENT:
37 return NG::NavigationSystemTransitionType::CONTENT;
38 default:
39 return NG::NavigationSystemTransitionType::DEFAULT;
40 }
41 }
42
SetHideTitleBar(ArkUIRuntimeCallInfo * runtimeCallInfo)43 ArkUINativeModuleValue NavDestinationBridge::SetHideTitleBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
44 {
45 EcmaVM* vm = runtimeCallInfo->GetVM();
46 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
47 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
48 Local<JSValueRef> hideArg = runtimeCallInfo->GetCallArgRef(1);
49 const int32_t argsNum = 2; // 2: parameter index
50 Local<JSValueRef> animatedArg = runtimeCallInfo->GetCallArgRef(argsNum);
51 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
52 bool hide = false;
53 bool animated = false;
54 if (!hideArg->IsNull() && !hideArg->IsUndefined() && hideArg->IsBoolean()) {
55 hide = hideArg->ToBoolean(vm)->Value();
56 }
57 if (!animatedArg->IsNull() && !animatedArg->IsUndefined() && animatedArg->IsBoolean()) {
58 animated = animatedArg->ToBoolean(vm)->Value();
59 }
60 GetArkUINodeModifiers()->getNavDestinationModifier()->setHideTitleBar(nativeNode, hide, animated);
61 return panda::JSValueRef::Undefined(vm);
62 }
63
ResetHideTitleBar(ArkUIRuntimeCallInfo * runtimeCallInfo)64 ArkUINativeModuleValue NavDestinationBridge::ResetHideTitleBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
65 {
66 EcmaVM* vm = runtimeCallInfo->GetVM();
67 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
68 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
69 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
70 GetArkUINodeModifiers()->getNavDestinationModifier()->resetHideTitleBar(nativeNode);
71 return panda::JSValueRef::Undefined(vm);
72 }
73
SetHideToolBar(ArkUIRuntimeCallInfo * runtimeCallInfo)74 ArkUINativeModuleValue NavDestinationBridge::SetHideToolBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
75 {
76 EcmaVM* vm = runtimeCallInfo->GetVM();
77 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
78 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
79 Local<JSValueRef> hideArg = runtimeCallInfo->GetCallArgRef(1);
80 const int32_t argsNum = 2; // 2: parameter index
81 Local<JSValueRef> animatedArg = runtimeCallInfo->GetCallArgRef(argsNum);
82 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
83 bool hide = false;
84 bool animated = false;
85 if (!hideArg->IsNull() && !hideArg->IsUndefined() && hideArg->IsBoolean()) {
86 hide = hideArg->ToBoolean(vm)->Value();
87 }
88 if (!animatedArg->IsNull() && !animatedArg->IsUndefined() && animatedArg->IsBoolean()) {
89 animated = animatedArg->ToBoolean(vm)->Value();
90 }
91 GetArkUINodeModifiers()->getNavDestinationModifier()->setNavDestinationHideToolBar(nativeNode, hide, animated);
92 return panda::JSValueRef::Undefined(vm);
93 }
94
ResetHideToolBar(ArkUIRuntimeCallInfo * runtimeCallInfo)95 ArkUINativeModuleValue NavDestinationBridge::ResetHideToolBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
96 {
97 EcmaVM* vm = runtimeCallInfo->GetVM();
98 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
99 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
100 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
101 GetArkUINodeModifiers()->getNavDestinationModifier()->resetNavDestinationHideToolBar(nativeNode);
102 return panda::JSValueRef::Undefined(vm);
103 }
104
SetBackButtonIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)105 ArkUINativeModuleValue NavDestinationBridge::SetBackButtonIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
106 {
107 EcmaVM* vm = runtimeCallInfo->GetVM();
108 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
109 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
110 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
111 auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
112
113 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
114 std::string src;
115 auto noPixMap = Framework::JSViewAbstract::ParseJsMedia(info[1], src);
116
117 RefPtr<PixelMap> pixMap = nullptr;
118 #if defined(PIXEL_MAP_SUPPORTED)
119 if (!noPixMap) {
120 pixMap = CreatePixelMapFromNapiValue(info[1]);
121 }
122 #endif
123 std::string bundleName;
124 std::string moduleName;
125
126 Framework::JSViewAbstract::GetJsMediaBundleInfo(info[1], bundleName, moduleName);
127 NavDestinationModelNG::SetBackButtonIcon(frameNode, src, noPixMap, pixMap);
128 return panda::JSValueRef::Undefined(vm);
129 }
130
ResetBackButtonIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)131 ArkUINativeModuleValue NavDestinationBridge::ResetBackButtonIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
132 {
133 EcmaVM* vm = runtimeCallInfo->GetVM();
134 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
135 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
136 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
137 auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
138 bool noPixMap = false;
139 RefPtr<PixelMap> pixMap = nullptr;
140 std::string src;
141 NavDestinationModelNG::SetBackButtonIcon(frameNode, src, noPixMap, pixMap);
142 return panda::JSValueRef::Undefined(vm);
143 }
144
SetNavDestinationMode(ArkUIRuntimeCallInfo * runtimeCallInfo)145 ArkUINativeModuleValue NavDestinationBridge::SetNavDestinationMode(ArkUIRuntimeCallInfo* runtimeCallInfo)
146 {
147 EcmaVM* vm = runtimeCallInfo->GetVM();
148 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
149 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
150 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
151 auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
152
153 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
154 if (!info[1]->IsNumber()) {
155 // set default back ground color
156 GetArkUINodeModifiers()->getNavDestinationModifier()->resetNavDestinationMode(nativeNode);
157 return panda::JSValueRef::Undefined(vm);
158 }
159 auto mode = info[1]->ToNumber<int32_t>();
160 NavDestinationModelNG::SetNavDestinationMode(frameNode, static_cast<NG::NavDestinationMode>(mode));
161 return panda::JSValueRef::Undefined(vm);
162 }
163
ResetNavDestinationMode(ArkUIRuntimeCallInfo * runtimeCallInfo)164 ArkUINativeModuleValue NavDestinationBridge::ResetNavDestinationMode(ArkUIRuntimeCallInfo* runtimeCallInfo)
165 {
166 EcmaVM* vm = runtimeCallInfo->GetVM();
167 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
168 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
169 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
170 GetArkUINodeModifiers()->getNavDestinationModifier()->resetNavDestinationMode(nativeNode);
171 return panda::JSValueRef::Undefined(vm);
172 }
173
SetIgnoreLayoutSafeArea(ArkUIRuntimeCallInfo * runtimeCallInfo)174 ArkUINativeModuleValue NavDestinationBridge::SetIgnoreLayoutSafeArea(ArkUIRuntimeCallInfo *runtimeCallInfo)
175 {
176 EcmaVM* vm = runtimeCallInfo->GetVM();
177 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
178 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
179 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
180 Local<JSValueRef> thirdArg = runtimeCallInfo->GetCallArgRef(NUM_2);
181 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
182 std::string typeCppStr;
183 std::string edgesCppStr;
184 if (secondArg->IsString(vm)) {
185 typeCppStr = secondArg->ToString(vm)->ToString(vm);
186 } else {
187 //type system
188 typeCppStr = "0";
189 }
190
191 if (thirdArg->IsString(vm)) {
192 edgesCppStr = thirdArg->ToString(vm)->ToString(vm);
193 } else {
194 //edge top and bottom
195 edgesCppStr = "0|1";
196 }
197 const char* typeStr = typeCppStr.c_str();
198 const char* edgesStr = edgesCppStr.c_str();
199 GetArkUINodeModifiers()->getNavDestinationModifier()->setIgnoreLayoutSafeArea(nativeNode, typeStr, edgesStr);
200 return panda::JSValueRef::Undefined(vm);
201 }
202
ResetIgnoreLayoutSafeArea(ArkUIRuntimeCallInfo * runtimeCallInfo)203 ArkUINativeModuleValue NavDestinationBridge::ResetIgnoreLayoutSafeArea(ArkUIRuntimeCallInfo* runtimeCallInfo)
204 {
205 EcmaVM* vm = runtimeCallInfo->GetVM();
206 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
207 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
208 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
209 GetArkUINodeModifiers()->getNavDestinationModifier()->resetIgnoreLayoutSafeArea(nativeNode);
210 return panda::JSValueRef::Undefined(vm);
211 }
212
SetTitle(ArkUIRuntimeCallInfo * runtimeCallInfo)213 ArkUINativeModuleValue NavDestinationBridge::SetTitle(ArkUIRuntimeCallInfo* runtimeCallInfo)
214 {
215 EcmaVM* vm = runtimeCallInfo->GetVM();
216 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
217 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
218 Local<JSValueRef> titleArg = runtimeCallInfo->GetCallArgRef(1);
219 Local<JSValueRef> optionsArg = runtimeCallInfo->GetCallArgRef(2);
220 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
221 std::string title;
222 std::string subtitle;
223 bool hasMain = false;
224 bool hasSub = false;
225 if (ArkTSUtils::ParseJsString(vm, titleArg, title)) {
226 // Resource and string type.
227 subtitle = "";
228 hasMain = true;
229 hasSub = false;
230 } else if (titleArg->IsObject(vm)) {
231 // NavigationCommonTitle
232 auto obj = titleArg->ToObject(vm);
233 auto main = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "main"));
234 auto sub = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "sub"));
235 hasMain = ArkTSUtils::ParseJsString(vm, main, title);
236 hasSub = ArkTSUtils::ParseJsString(vm, sub, subtitle);
237 // NavigationCustomTitle or CustomBuilder is not supported
238 } else {
239 GetArkUINodeModifiers()->getNavDestinationModifier()->resetTitle(nativeNode);
240 return panda::JSValueRef::Undefined(vm);
241 }
242
243 ArkUINavigationTitlebarOptions options;
244 if (optionsArg->IsObject(vm)) {
245 NativeNavigationUtils::ParseTitleOptions(vm, optionsArg, options);
246 }
247 ArkUINavigationTitleInfo titleInfo = { hasSub, hasMain, subtitle.c_str(), title.c_str() };
248 GetArkUINodeModifiers()->getNavDestinationModifier()->setTitle(nativeNode, titleInfo, options);
249 return panda::JSValueRef::Undefined(vm);
250 }
251
ResetTitle(ArkUIRuntimeCallInfo * runtimeCallInfo)252 ArkUINativeModuleValue NavDestinationBridge::ResetTitle(ArkUIRuntimeCallInfo* runtimeCallInfo)
253 {
254 EcmaVM* vm = runtimeCallInfo->GetVM();
255 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
256 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
257 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
258 GetArkUINodeModifiers()->getNavDestinationModifier()->resetTitle(nativeNode);
259 return panda::JSValueRef::Undefined(vm);
260 }
261
SetMenus(ArkUIRuntimeCallInfo * runtimeCallInfo)262 ArkUINativeModuleValue NavDestinationBridge::SetMenus(ArkUIRuntimeCallInfo* runtimeCallInfo)
263 {
264 EcmaVM* vm = runtimeCallInfo->GetVM();
265 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
266 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
267 Local<JSValueRef> menusArg = runtimeCallInfo->GetCallArgRef(1);
268 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
269 std::vector<ArkUIBarItem> menuItems;
270 if (menusArg->IsArray(vm)) {
271 NativeNavigationUtils::ParseBarItems(vm, menusArg, menuItems);
272 GetArkUINodeModifiers()->getNavDestinationModifier()->setMenus(nativeNode, menuItems.data(), menuItems.size());
273 // get action and symbolModifier single
274 auto actionSendFunc = GetArkUINodeModifiers()->getNavDestinationModifier()->setMenuItemAction;
275 auto symbolSendFunc = GetArkUINodeModifiers()->getNavDestinationModifier()->setMenuItemSymbol;
276 NativeNavigationUtils::ParseAndSendFunctionParam(runtimeCallInfo, menusArg, actionSendFunc, symbolSendFunc);
277 } else if (menusArg->IsUndefined()) {
278 menuItems = {};
279 GetArkUINodeModifiers()->getNavDestinationModifier()->setMenus(nativeNode, menuItems.data(), menuItems.size());
280 } else if (menusArg->IsObject(vm)) {
281 GetArkUINodeModifiers()->getNavDestinationModifier()->resetMenus(nativeNode);
282 }
283 return panda::JSValueRef::Undefined(vm);
284 }
285
ResetMenus(ArkUIRuntimeCallInfo * runtimeCallInfo)286 ArkUINativeModuleValue NavDestinationBridge::ResetMenus(ArkUIRuntimeCallInfo* runtimeCallInfo)
287 {
288 EcmaVM* vm = runtimeCallInfo->GetVM();
289 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
290 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
291 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
292 GetArkUINodeModifiers()->getNavDestinationModifier()->resetMenus(nativeNode);
293 return panda::JSValueRef::Undefined(vm);
294 }
295
SetNavDestinationSystemTransition(ArkUIRuntimeCallInfo * runtimeCallInfo)296 ArkUINativeModuleValue NavDestinationBridge::SetNavDestinationSystemTransition(ArkUIRuntimeCallInfo* runtimeCallInfo)
297 {
298 EcmaVM* vm = runtimeCallInfo->GetVM();
299 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
300 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
301 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
302 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
303 if (!info[1]->IsNumber()) {
304 GetArkUINodeModifiers()->getNavDestinationModifier()->resetNavDestinationSystemTransition(nativeNode);
305 return panda::JSValueRef::Undefined(vm);
306 }
307 auto value = info[1]->ToNumber<int32_t>();
308 NavigationSystemTransitionType type = ParseTransitionType(value);
309 GetArkUINodeModifiers()->getNavDestinationModifier()->setNavDestinationSystemTransition(
310 nativeNode,
311 static_cast<ArkUI_Int32>(type));
312 return panda::JSValueRef::Undefined(vm);
313 }
314
ResetNavDestinationSystemTransition(ArkUIRuntimeCallInfo * runtimeCallInfo)315 ArkUINativeModuleValue NavDestinationBridge::ResetNavDestinationSystemTransition(ArkUIRuntimeCallInfo* runtimeCallInfo)
316 {
317 EcmaVM* vm = runtimeCallInfo->GetVM();
318 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
319 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
320 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
321 GetArkUINodeModifiers()->getNavDestinationModifier()->resetNavDestinationSystemTransition(nativeNode);
322 return panda::JSValueRef::Undefined(vm);
323 }
324
SetRecoverable(ArkUIRuntimeCallInfo * runtimeCallInfo)325 ArkUINativeModuleValue NavDestinationBridge::SetRecoverable(ArkUIRuntimeCallInfo* runtimeCallInfo)
326 {
327 EcmaVM* vm = runtimeCallInfo->GetVM();
328 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
329 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
330 Local<JSValueRef> recoverableArg = runtimeCallInfo->GetCallArgRef(1);
331 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
332 if (recoverableArg->IsNull() || recoverableArg->IsUndefined() || !recoverableArg->IsBoolean()) {
333 GetArkUINodeModifiers()->getNavDestinationModifier()->resetRecoverable(nativeNode);
334 } else {
335 bool recoverable = recoverableArg->ToBoolean(vm)->Value();
336 GetArkUINodeModifiers()->getNavDestinationModifier()->setRecoverable(nativeNode, recoverable);
337 }
338 return panda::JSValueRef::Undefined(vm);
339 }
340
ResetRecoverable(ArkUIRuntimeCallInfo * runtimeCallInfo)341 ArkUINativeModuleValue NavDestinationBridge::ResetRecoverable(ArkUIRuntimeCallInfo* runtimeCallInfo)
342 {
343 EcmaVM* vm = runtimeCallInfo->GetVM();
344 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
345 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
346 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
347 GetArkUINodeModifiers()->getNavDestinationModifier()->resetRecoverable(nativeNode);
348 return panda::JSValueRef::Undefined(vm);
349 }
350 } // namespace OHOS::Ace::NG
351