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, ¶m);
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