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
22 namespace OHOS::Ace::Framework {
23
DeclarativeParseRouteUrl(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)24 std::string DeclarativeParseRouteUrl(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg,
25 const std::string& key)
26 {
27 std::string argStr = arg->GetJsonString(runtime);
28 if (argStr.empty()) {
29 return argStr;
30 }
31
32 std::string pageRoute;
33 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
34 if (argsPtr != nullptr && argsPtr->GetValue(key) != nullptr && argsPtr->GetValue(key)->IsString()) {
35 pageRoute = argsPtr->GetValue(key)->GetString();
36 }
37
38 return pageRoute;
39 }
40
DeclarativeParseRouteParams(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)41 std::string DeclarativeParseRouteParams(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg,
42 const std::string& key)
43 {
44 std::string argStr = arg->GetJsonString(runtime);
45 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
46 std::string params;
47 if (argsPtr != nullptr && argsPtr->Contains(key) && argsPtr->GetValue(key)->IsObject()) {
48 params = argsPtr->GetValue(key)->ToString();
49 }
50 return params;
51 }
52
PagePush(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)53 shared_ptr<JsValue> PagePush(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
54 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
55 {
56 if (argc != 1) {
57 return runtime->NewNull();
58 }
59
60 std::string uri = DeclarativeParseRouteUrl(runtime, argv[0], ROUTE_KEY_URI);
61 std::string params = DeclarativeParseRouteParams(runtime, argv[0], ROUTE_KEY_PARAMS);
62 auto delegate = EngineHelper::GetCurrentDelegate();
63 if (delegate == nullptr) {
64 return runtime->NewNull();
65 }
66
67 delegate->Push(uri, params);
68 return runtime->NewNull();
69 }
70
PageReplace(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)71 shared_ptr<JsValue> PageReplace(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
72 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
73 {
74 if (argc != 1) {
75 return runtime->NewNull();
76 }
77
78 std::string uri = DeclarativeParseRouteUrl(runtime, argv[0], ROUTE_KEY_URI);
79 std::string params = DeclarativeParseRouteParams(runtime, argv[0], ROUTE_KEY_PARAMS);
80 auto delegate = EngineHelper::GetCurrentDelegate();
81 if (delegate == nullptr) {
82 return runtime->NewNull();
83 }
84
85 delegate->Replace(uri, params);
86 return runtime->NewNull();
87 }
88
PageBack(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)89 shared_ptr<JsValue> PageBack(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
90 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
91 {
92 if (argc != 1 && argc != 0) {
93 return runtime->NewNull();
94 }
95
96 std::string uri;
97 std::string params;
98 if (argc == 1) {
99 uri = DeclarativeParseRouteUrl(runtime, argv[0], ROUTE_KEY_URI);
100 params = DeclarativeParseRouteParams(runtime, argv[0], ROUTE_KEY_PARAMS);
101 }
102 auto delegate = EngineHelper::GetCurrentDelegate();
103 if (delegate == nullptr) {
104 return runtime->NewNull();
105 }
106
107 delegate->Back(uri, params);
108 return runtime->NewNull();
109 }
110
PageClear(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)111 shared_ptr<JsValue> PageClear(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
112 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
113 {
114 auto delegate = EngineHelper::GetCurrentDelegate();
115 if (delegate == nullptr) {
116 return runtime->NewNull();
117 }
118
119 delegate->Clear();
120 return runtime->NewNull();
121 }
122
PageGetLength(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)123 shared_ptr<JsValue> PageGetLength(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
124 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
125 {
126 auto delegate = EngineHelper::GetCurrentDelegate();
127 if (delegate == nullptr) {
128 return runtime->NewNull();
129 }
130
131 int32_t routeLength = delegate->GetStackSize();
132 return runtime->NewString(std::to_string(routeLength));
133 }
134
PageGetState(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)135 shared_ptr<JsValue> PageGetState(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
136 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
137 {
138 auto delegate = EngineHelper::GetCurrentDelegate();
139 if (delegate == nullptr) {
140 return runtime->NewNull();
141 }
142
143 int32_t routeIndex = 0;
144 std::string routeName;
145 std::string routePath;
146 delegate->GetState(routeIndex, routeName, routePath);
147 shared_ptr<JsValue> jsState = runtime->NewObject();
148 jsState->SetProperty(runtime, "index", runtime->NewNumber(routeIndex));
149 jsState->SetProperty(runtime, "name", runtime->NewString(routeName));
150 jsState->SetProperty(runtime, "path", runtime->NewString(routePath));
151 return jsState;
152 }
153
PageGetParams(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)154 shared_ptr<JsValue> PageGetParams(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
155 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
156 {
157 auto delegate = EngineHelper::GetCurrentDelegate();
158 if (delegate == nullptr) {
159 return runtime->NewNull();
160 }
161
162 std::string paramsStr = delegate->GetParams();
163 if (paramsStr.empty()) {
164 return runtime->NewNull();
165 }
166 return runtime->ParseJson(paramsStr);
167 }
168
InitRouterModule(const shared_ptr<JsRuntime> & runtime,shared_ptr<JsValue> & moduleObj)169 void InitRouterModule(const shared_ptr<JsRuntime>& runtime, shared_ptr<JsValue>& moduleObj)
170 {
171 moduleObj->SetProperty(runtime, ROUTE_PAGE_PUSH, runtime->NewFunction(PagePush));
172 moduleObj->SetProperty(runtime, ROUTE_PAGE_REPLACE, runtime->NewFunction(PageReplace));
173 moduleObj->SetProperty(runtime, ROUTE_PAGE_BACK, runtime->NewFunction(PageBack));
174 moduleObj->SetProperty(runtime, ROUTE_PAGE_CLEAR, runtime->NewFunction(PageClear));
175 moduleObj->SetProperty(runtime, ROUTE_PAGE_GET_LENGTH, runtime->NewFunction(PageGetLength));
176 moduleObj->SetProperty(runtime, ROUTE_PAGE_GET_STATE, runtime->NewFunction(PageGetState));
177 moduleObj->SetProperty(runtime, ROUTE_PAGE_GET_PARAMS, runtime->NewFunction(PageGetParams));
178
179 shared_ptr<JsValue> global = runtime->GetGlobal();
180 shared_ptr<JsValue> requireNapiFunc = global->GetProperty(runtime, "requireNapi");
181 if (!requireNapiFunc || !requireNapiFunc->IsFunction(runtime)) {
182 return;
183 }
184 std::vector<shared_ptr<JsValue>> argv = { runtime->NewString("router") };
185 shared_ptr<JsValue> napiObj = requireNapiFunc->Call(runtime, global, argv, argv.size());
186 moduleObj->SetProperty(runtime,
187 ROUTE_ENABLE_ALERT_BEFORE_BACK_PAGE, napiObj->GetProperty(runtime, ROUTE_ENABLE_ALERT_BEFORE_BACK_PAGE));
188 moduleObj->SetProperty(runtime,
189 ROUTE_DISABLE_ALERT_BEFORE_BACK_PAGE, napiObj->GetProperty(runtime, ROUTE_DISABLE_ALERT_BEFORE_BACK_PAGE));
190 }
191
192 } // namespace OHOS::Ace::Framework
193