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