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 
16 #include "frameworks/bridge/declarative_frontend/engine/functions/js_navigation_function.h"
17 #include "frameworks/bridge/declarative_frontend/jsview/js_navigation_stack.h"
18 #include "frameworks/bridge/declarative_frontend/jsview/js_navdestination_context.h"
19 
20 namespace OHOS::Ace::Framework {
21 
JSBind(BindingTarget globalObj)22 void JsNavigationTransitionProxy::JSBind(BindingTarget globalObj)
23 {
24     JSClass<JsNavigationTransitionProxy>::Declare("NavigationTransitionProxy");
25     JSClass<JsNavigationTransitionProxy>::CustomProperty(
26         "from", &JsNavigationTransitionProxy::GetFromContentInfo, &JsNavigationTransitionProxy::SetFromContentInfo);
27     JSClass<JsNavigationTransitionProxy>::CustomProperty(
28         "to", &JsNavigationTransitionProxy::GetToContentInfo, &JsNavigationTransitionProxy::SetToContentInfo);
29     JSClass<JsNavigationTransitionProxy>::CustomMethod(
30         "finishTransition", &JsNavigationTransitionProxy::FinishTransition);
31     JSClass<JsNavigationTransitionProxy>::CustomProperty("isInteractive", &JsNavigationTransitionProxy::GetInteractive,
32         &JsNavigationTransitionProxy::SetInteractive);
33     JSClass<JsNavigationTransitionProxy>::CustomMethod("cancelTransition",
34         &JsNavigationTransitionProxy::CancelAnimation);
35     JSClass<JsNavigationTransitionProxy>::CustomMethod("updateTransition",
36         &JsNavigationTransitionProxy::UpdateTransition);
37     JSClass<JsNavigationTransitionProxy>::Bind(
38         globalObj, &JsNavigationTransitionProxy::Constructor, &JsNavigationTransitionProxy::Destructor);
39 }
40 
SetFromContentInfo(const JSCallbackInfo & args)41 void JsNavigationTransitionProxy::SetFromContentInfo(const JSCallbackInfo& args)
42 {
43     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "navigation transition proxy can not support modify from attribute");
44 }
45 
GetFromContentInfo(const JSCallbackInfo & args)46 void JsNavigationTransitionProxy::GetFromContentInfo(const JSCallbackInfo& args)
47 {
48     RefPtr<NG::NavDestinationContext> from;
49     if (proxy_) {
50         from = proxy_->GetPreDestinationContext();
51     }
52     auto fromVal = ConvertContentInfo(from);
53     args.SetReturnValue(fromVal);
54 }
55 
SetToContentInfo(const JSCallbackInfo & args)56 void JsNavigationTransitionProxy::SetToContentInfo(const JSCallbackInfo& args)
57 {
58     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "navigation transition context can not support modify to attribute");
59 }
60 
GetToContentInfo(const JSCallbackInfo & args)61 void JsNavigationTransitionProxy::GetToContentInfo(const JSCallbackInfo& args)
62 {
63     RefPtr<NG::NavDestinationContext> to;
64     if (proxy_) {
65         to = proxy_->GetTopDestinationContext();
66     }
67     auto toVal = ConvertContentInfo(to);
68     args.SetReturnValue(toVal);
69 }
70 
FinishTransition(const JSCallbackInfo & info)71 void JsNavigationTransitionProxy::FinishTransition(const JSCallbackInfo& info)
72 {
73     if (proxy_) {
74         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "fire custom animation finish");
75         proxy_->FireFinishCallback();
76     } else {
77         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "finish interactive animation failed");
78     }
79 }
80 
Constructor(const JSCallbackInfo & info)81 void JsNavigationTransitionProxy::Constructor(const JSCallbackInfo& info)
82 {
83     auto proxy = Referenced::MakeRefPtr<JsNavigationTransitionProxy>();
84     proxy->IncRefCount();
85     info.SetReturnValue(Referenced::RawPtr(proxy));
86 }
87 
Destructor(JsNavigationTransitionProxy * proxy)88 void JsNavigationTransitionProxy::Destructor(JsNavigationTransitionProxy* proxy)
89 {
90     if (proxy != nullptr) {
91         proxy->DecRefCount();
92     }
93 }
94 
ConvertContentInfo(RefPtr<NG::NavDestinationContext> context)95 JSRef<JSVal> JsNavigationTransitionProxy::ConvertContentInfo(RefPtr<NG::NavDestinationContext> context)
96 {
97     auto value = JSRef<JSObject>::New();
98     if (!context) {
99         // current nav content is navBar.Don't need to set name and mode.
100         value->SetProperty<int32_t>("index", -1);
101         return value;
102     }
103     auto info = context->GetNavPathInfo();
104     CHECK_NULL_RETURN(info, value);
105     value->SetProperty<std::string>("name", info->GetName());
106     value->SetProperty<int32_t>("index", context->GetIndex());
107     value->SetProperty<int32_t>("mode", static_cast<int32_t>(context->GetMode()));
108     value->SetProperty<std::string>("navDestinationId", std::to_string(context->GetNavDestinationId()));
109     auto jsPathInfo = AceType::DynamicCast<JSNavPathInfo>(info);
110     if (jsPathInfo) {
111         value->SetPropertyObject("param", jsPathInfo->GetParam());
112     }
113     return value;
114 }
115 
JSBind(BindingTarget globalObj)116 void JsNavigationFunction::JSBind(BindingTarget globalObj)
117 {
118     JsNavigationTransitionProxy::JSBind(globalObj);
119 }
120 
Execute(RefPtr<NG::NavDestinationContext> from,RefPtr<NG::NavDestinationContext> to,NG::NavigationOperation navigationOperation)121 JSRef<JSVal> JsNavigationFunction::Execute(RefPtr<NG::NavDestinationContext> from,
122     RefPtr<NG::NavDestinationContext> to, NG::NavigationOperation navigationOperation)
123 {
124     JSRef<JSVal> fromVal = JsNavigationTransitionProxy::ConvertContentInfo(from);
125     JSRef<JSVal> toVal = JsNavigationTransitionProxy::ConvertContentInfo(to);
126     JSRef<JSVal> operation = JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(navigationOperation)));
127     JSRef<JSVal> params[] = { fromVal, toVal, operation };
128     const int32_t argsNum = 3;
129     return JsFunction::ExecuteJS(argsNum, params);
130 }
131 
Execute(const RefPtr<NG::NavigationTransitionProxy> & proxy)132 void JsNavigationFunction::Execute(const RefPtr<NG::NavigationTransitionProxy>& proxy)
133 {
134     JSRef<JSObject> proxyObj = JSClass<JsNavigationTransitionProxy>::NewInstance();
135     auto jsProxy = Referenced::Claim(proxyObj->Unwrap<JsNavigationTransitionProxy>());
136     jsProxy->SetProxy(proxy);
137     JSRef<JSVal> param = JSRef<JSObject>::Cast(proxyObj);
138     JsFunction::ExecuteJS(1, &param);
139 }
140 
SetInteractive(const JSCallbackInfo & info)141 void JsNavigationTransitionProxy::SetInteractive(const JSCallbackInfo& info)
142 {
143     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "not support set interactive attribute");
144 }
145 
GetInteractive(const JSCallbackInfo & info)146 void JsNavigationTransitionProxy::GetInteractive(const JSCallbackInfo& info)
147 {
148     auto interactive = proxy_ ? proxy_->GetInteractive() : false;
149     info.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(interactive)));
150 }
151 
CancelAnimation(const JSCallbackInfo & info)152 void JsNavigationTransitionProxy::CancelAnimation(const JSCallbackInfo& info)
153 {
154     if (proxy_ == nullptr) {
155         TAG_LOGE(AceLogTag::ACE_NAVIGATION, "cancel interactive animation failed");
156         return;
157     }
158     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "fire cancel interactive animation");
159     proxy_->CancelInteractiveAnimation();
160 }
161 
UpdateTransition(const JSCallbackInfo & info)162 void JsNavigationTransitionProxy::UpdateTransition(const JSCallbackInfo& info)
163 {
164     if (!proxy_) {
165         return;
166     }
167     float progress = 0;
168     if (info[0]->IsNumber()) {
169         progress = info[0]->ToNumber<float>();
170     }
171     if (progress >= 0 && progress <= 1) {
172         proxy_->UpdateTransition(progress);
173     }
174 }
175 }; // namespace OHOS::Ace::Framework