1 /*
2 * Copyright (c) 2021-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/engine/jsi/modules/jsi_router_module.h"
17
18 #include "base/json/json_util.h"
19 #include "base/log/log.h"
20 #include "frameworks/bridge/common/utils/engine_helper.h"
21 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
22 #include "frameworks/bridge/js_frontend/engine/common/js_constants.h"
23 #include "frameworks/core/common/container.h"
24
25 namespace OHOS::Ace::Framework {
26
DeclarativeParseRouteUrl(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)27 std::string DeclarativeParseRouteUrl(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg,
28 const std::string& key)
29 {
30 LOGD("DeclarativeParseRouteUrl");
31 std::string argStr = arg->GetJsonString(runtime);
32 if (argStr.empty()) {
33 return argStr;
34 }
35
36 std::string pageRoute;
37 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
38 if (argsPtr != nullptr && argsPtr->GetValue(key) != nullptr && argsPtr->GetValue(key)->IsString()) {
39 pageRoute = argsPtr->GetValue(key)->GetString();
40 }
41 LOGD("JsDeclarativeParseRouteUrl pageRoute = %{private}s", pageRoute.c_str());
42
43 return pageRoute;
44 }
45
DeclarativeParseRouteParams(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)46 std::string DeclarativeParseRouteParams(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg,
47 const std::string& key)
48 {
49 std::string argStr = arg->GetJsonString(runtime);
50 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
51 std::string params;
52 if (argsPtr != nullptr && argsPtr->Contains(key) && argsPtr->GetValue(key)->IsObject()) {
53 params = argsPtr->GetValue(key)->ToString();
54 }
55 return params;
56 }
57
PagePush(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)58 shared_ptr<JsValue> PagePush(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
59 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
60 {
61 LOGI("PagePush Start");
62 if (argc != 1) {
63 LOGE("PagePush args count is invalid");
64 return runtime->NewNull();
65 }
66
67 std::string uri = DeclarativeParseRouteUrl(runtime, argv[0], ROUTE_KEY_URI);
68 std::string params = DeclarativeParseRouteParams(runtime, argv[0], ROUTE_KEY_PARAMS);
69 auto delegate = EngineHelper::GetCurrentDelegate();
70 if (delegate == nullptr) {
71 LOGE("get jsi delegate failed");
72 return runtime->NewNull();
73 }
74
75 delegate->Push(uri, params);
76 return runtime->NewNull();
77 }
78
PageReplace(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)79 shared_ptr<JsValue> PageReplace(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
80 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
81 {
82 LOGI("PageReplace Start");
83 if (argc != 1) {
84 LOGE("PageReplace args count is invalid");
85 return runtime->NewNull();
86 }
87
88 std::string uri = DeclarativeParseRouteUrl(runtime, argv[0], ROUTE_KEY_URI);
89 std::string params = DeclarativeParseRouteParams(runtime, argv[0], ROUTE_KEY_PARAMS);
90 auto delegate = EngineHelper::GetCurrentDelegate();
91 if (delegate == nullptr) {
92 LOGE("get jsi delegate failed");
93 return runtime->NewNull();
94 }
95
96 delegate->Replace(uri, params);
97 return runtime->NewNull();
98 }
99
PageBack(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)100 shared_ptr<JsValue> PageBack(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
101 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
102 {
103 LOGI("PageBack Start");
104 if (argc != 1 && argc != 0) {
105 LOGE("PageBack args count is invalid");
106 return runtime->NewNull();
107 }
108
109 std::string uri;
110 std::string params;
111 if (argc == 1) {
112 uri = DeclarativeParseRouteUrl(runtime, argv[0], ROUTE_KEY_URI);
113 params = DeclarativeParseRouteParams(runtime, argv[0], ROUTE_KEY_PARAMS);
114 }
115 auto delegate = EngineHelper::GetCurrentDelegate();
116 if (delegate == nullptr) {
117 LOGE("get jsi delegate failed");
118 return runtime->NewNull();
119 }
120
121 delegate->Back(uri, params);
122 return runtime->NewNull();
123 }
124
PageClear(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)125 shared_ptr<JsValue> PageClear(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
126 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
127 {
128 LOGI("PageClear Start");
129 auto delegate = EngineHelper::GetCurrentDelegate();
130 if (delegate == nullptr) {
131 LOGE("get jsi delegate failed");
132 return runtime->NewNull();
133 }
134
135 delegate->Clear();
136 return runtime->NewNull();
137 }
138
PageGetLength(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)139 shared_ptr<JsValue> PageGetLength(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
140 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
141 {
142 LOGI("PageGetLength Start");
143 auto delegate = EngineHelper::GetCurrentDelegate();
144 if (delegate == nullptr) {
145 LOGE("get jsi delegate failed");
146 return runtime->NewNull();
147 }
148
149 int32_t routeLength = delegate->GetStackSize();
150 return runtime->NewString(std::to_string(routeLength));
151 }
152
PageGetState(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)153 shared_ptr<JsValue> PageGetState(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
154 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
155 {
156 LOGI("PageGetState Start");
157 auto delegate = EngineHelper::GetCurrentDelegate();
158 if (delegate == nullptr) {
159 LOGE("get jsi delegate failed");
160 return runtime->NewNull();
161 }
162
163 int32_t routeIndex = 0;
164 std::string routeName;
165 std::string routePath;
166 delegate->GetState(routeIndex, routeName, routePath);
167 shared_ptr<JsValue> jsState = runtime->NewObject();
168 jsState->SetProperty(runtime, "index", runtime->NewNumber(routeIndex));
169 jsState->SetProperty(runtime, "name", runtime->NewString(routeName));
170 jsState->SetProperty(runtime, "path", runtime->NewString(routePath));
171 return jsState;
172 }
173
PageGetParams(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)174 shared_ptr<JsValue> PageGetParams(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
175 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
176 {
177 LOGI("PageGetParams Start");
178 auto delegate = EngineHelper::GetCurrentDelegate();
179 if (delegate == nullptr) {
180 LOGE("get jsi delegate failed");
181 return runtime->NewNull();
182 }
183
184 std::string paramsStr = delegate->GetParams();
185 if (paramsStr.empty()) {
186 LOGI("PageGetParams params is null");
187 return runtime->NewNull();
188 }
189 return runtime->ParseJson(paramsStr);
190 }
191
InitRouterModule(const shared_ptr<JsRuntime> & runtime,shared_ptr<JsValue> & moduleObj)192 void InitRouterModule(const shared_ptr<JsRuntime>& runtime, shared_ptr<JsValue>& moduleObj)
193 {
194 moduleObj->SetProperty(runtime, ROUTE_PAGE_PUSH, runtime->NewFunction(PagePush));
195 moduleObj->SetProperty(runtime, ROUTE_PAGE_REPLACE, runtime->NewFunction(PageReplace));
196 moduleObj->SetProperty(runtime, ROUTE_PAGE_BACK, runtime->NewFunction(PageBack));
197 moduleObj->SetProperty(runtime, ROUTE_PAGE_CLEAR, runtime->NewFunction(PageClear));
198 moduleObj->SetProperty(runtime, ROUTE_PAGE_GET_LENGTH, runtime->NewFunction(PageGetLength));
199 moduleObj->SetProperty(runtime, ROUTE_PAGE_GET_STATE, runtime->NewFunction(PageGetState));
200 moduleObj->SetProperty(runtime, ROUTE_PAGE_GET_PARAMS, runtime->NewFunction(PageGetParams));
201
202 shared_ptr<JsValue> global = runtime->GetGlobal();
203 shared_ptr<JsValue> requireNapiFunc = global->GetProperty(runtime, "requireNapi");
204 if (!requireNapiFunc || !requireNapiFunc->IsFunction(runtime)) {
205 LOGW("requireNapi func not found");
206 return;
207 }
208 std::vector<shared_ptr<JsValue>> argv = { runtime->NewString("router") };
209 shared_ptr<JsValue> napiObj = requireNapiFunc->Call(runtime, global, argv, argv.size());
210 moduleObj->SetProperty(runtime,
211 ROUTE_ENABLE_ALERT_BEFORE_BACK_PAGE, napiObj->GetProperty(runtime, ROUTE_ENABLE_ALERT_BEFORE_BACK_PAGE));
212 moduleObj->SetProperty(runtime,
213 ROUTE_DISABLE_ALERT_BEFORE_BACK_PAGE, napiObj->GetProperty(runtime, ROUTE_DISABLE_ALERT_BEFORE_BACK_PAGE));
214 }
215
216 } // namespace OHOS::Ace::Framework
217