1 /*
2 * Copyright (c) 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 "napi_webview_controller.h"
17
18 #include <securec.h>
19 #include <unistd.h>
20 #include <uv.h>
21
22 #include "business_error.h"
23 #include "context/application_context.h"
24 #include "napi_parse_utils.h"
25 #include "nweb.h"
26 #include "nweb_helper.h"
27 #include "nweb_log.h"
28 #include "pixel_map.h"
29 #include "pixel_map_napi.h"
30 #include "web_errors.h"
31 #include "webview_javascript_execute_callback.h"
32
33 namespace OHOS {
34 namespace NWeb {
35 using namespace NWebError;
36 using NWebError::NO_ERROR;
37 thread_local napi_ref g_classWebMsgPort;
38 thread_local napi_ref g_historyListRef;
Init(napi_env env,napi_value exports)39 napi_value NapiWebviewController::Init(napi_env env, napi_value exports)
40 {
41 napi_property_descriptor properties[] = {
42 DECLARE_NAPI_STATIC_FUNCTION("initializeWebEngine", NapiWebviewController::InitializeWebEngine),
43 DECLARE_NAPI_STATIC_FUNCTION("setWebDebuggingAccess", NapiWebviewController::SetWebDebuggingAccess),
44 DECLARE_NAPI_FUNCTION("getWebDebuggingAccess", NapiWebviewController::InnerGetWebDebuggingAccess),
45 DECLARE_NAPI_FUNCTION("setWebId", NapiWebviewController::SetWebId),
46 DECLARE_NAPI_FUNCTION("jsProxy", NapiWebviewController::InnerJsProxy),
47 DECLARE_NAPI_FUNCTION("getCustomeSchemeCmdLine", NapiWebviewController::InnerGetCustomeSchemeCmdLine),
48 DECLARE_NAPI_FUNCTION("accessForward", NapiWebviewController::AccessForward),
49 DECLARE_NAPI_FUNCTION("accessBackward", NapiWebviewController::AccessBackward),
50 DECLARE_NAPI_FUNCTION("accessStep", NapiWebviewController::AccessStep),
51 DECLARE_NAPI_FUNCTION("clearHistory", NapiWebviewController::ClearHistory),
52 DECLARE_NAPI_FUNCTION("forward", NapiWebviewController::Forward),
53 DECLARE_NAPI_FUNCTION("backward", NapiWebviewController::Backward),
54 DECLARE_NAPI_FUNCTION("onActive", NapiWebviewController::OnActive),
55 DECLARE_NAPI_FUNCTION("onInactive", NapiWebviewController::OnInactive),
56 DECLARE_NAPI_FUNCTION("refresh", NapiWebviewController::Refresh),
57 DECLARE_NAPI_FUNCTION("zoomIn", NapiWebviewController::ZoomIn),
58 DECLARE_NAPI_FUNCTION("zoomOut", NapiWebviewController::ZoomOut),
59 DECLARE_NAPI_FUNCTION("getWebId", NapiWebviewController::GetWebId),
60 DECLARE_NAPI_FUNCTION("getUserAgent", NapiWebviewController::GetUserAgent),
61 DECLARE_NAPI_FUNCTION("getTitle", NapiWebviewController::GetTitle),
62 DECLARE_NAPI_FUNCTION("getPageHeight", NapiWebviewController::GetPageHeight),
63 DECLARE_NAPI_FUNCTION("backOrForward", NapiWebviewController::BackOrForward),
64 DECLARE_NAPI_FUNCTION("storeWebArchive", NapiWebviewController::StoreWebArchive),
65 DECLARE_NAPI_FUNCTION("createWebMessagePorts", NapiWebviewController::CreateWebMessagePorts),
66 DECLARE_NAPI_FUNCTION("postMessage", NapiWebviewController::PostMessage),
67 DECLARE_NAPI_FUNCTION("getHitTestValue", NapiWebviewController::GetHitTestValue),
68 DECLARE_NAPI_FUNCTION("requestFocus", NapiWebviewController::RequestFocus),
69 DECLARE_NAPI_FUNCTION("loadUrl", NapiWebviewController::LoadUrl),
70 DECLARE_NAPI_FUNCTION("loadData", NapiWebviewController::LoadData),
71 DECLARE_NAPI_FUNCTION("getHitTest", NapiWebviewController::GetHitTest),
72 DECLARE_NAPI_FUNCTION("clearMatches", NapiWebviewController::ClearMatches),
73 DECLARE_NAPI_FUNCTION("searchNext", NapiWebviewController::SearchNext),
74 DECLARE_NAPI_FUNCTION("searchAllAsync", NapiWebviewController::SearchAllAsync),
75 DECLARE_NAPI_FUNCTION("clearSslCache", NapiWebviewController::ClearSslCache),
76 DECLARE_NAPI_FUNCTION("clearClientAuthenticationCache", NapiWebviewController::ClearClientAuthenticationCache),
77 DECLARE_NAPI_FUNCTION("stop", NapiWebviewController::Stop),
78 DECLARE_NAPI_FUNCTION("zoom", NapiWebviewController::Zoom),
79 DECLARE_NAPI_FUNCTION("registerJavaScriptProxy", NapiWebviewController::RegisterJavaScriptProxy),
80 DECLARE_NAPI_FUNCTION("deleteJavaScriptRegister", NapiWebviewController::DeleteJavaScriptRegister),
81 DECLARE_NAPI_FUNCTION("runJavaScript", NapiWebviewController::RunJavaScript),
82 DECLARE_NAPI_FUNCTION("getUrl", NapiWebviewController::GetUrl),
83 DECLARE_NAPI_FUNCTION("getOriginalUrl", NapiWebviewController::GetOriginalUrl),
84 DECLARE_NAPI_FUNCTION("setNetworkAvailable", NapiWebviewController::SetNetworkAvailable),
85 DECLARE_NAPI_FUNCTION("innerGetWebId", NapiWebviewController::InnerGetWebId),
86 DECLARE_NAPI_FUNCTION("hasImage", NapiWebviewController::HasImage),
87 DECLARE_NAPI_FUNCTION("removeCache", NapiWebviewController::RemoveCache),
88 DECLARE_NAPI_FUNCTION("getFavicon", NapiWebviewController::GetFavicon),
89 DECLARE_NAPI_FUNCTION("getBackForwardEntries", NapiWebviewController::getBackForwardEntries),
90 DECLARE_NAPI_FUNCTION("serializeWebState", NapiWebviewController::SerializeWebState),
91 DECLARE_NAPI_FUNCTION("restoreWebState", NapiWebviewController::RestoreWebState),
92 DECLARE_NAPI_FUNCTION("pageDown", NapiWebviewController::ScrollPageDown),
93 DECLARE_NAPI_FUNCTION("pageUp", NapiWebviewController::ScrollPageUp),
94 DECLARE_NAPI_FUNCTION("scrollTo", NapiWebviewController::ScrollTo),
95 DECLARE_NAPI_FUNCTION("scrollBy", NapiWebviewController::ScrollBy),
96 DECLARE_NAPI_FUNCTION("slideScroll", NapiWebviewController::SlideScroll),
97 DECLARE_NAPI_STATIC_FUNCTION("customizeSchemes", NapiWebviewController::CustomizeSchemes),
98 DECLARE_NAPI_FUNCTION("innerGetThisVar", NapiWebviewController::InnerGetThisVar),
99 };
100 napi_value constructor = nullptr;
101 napi_define_class(env, WEBVIEW_CONTROLLER_CLASS_NAME.c_str(), WEBVIEW_CONTROLLER_CLASS_NAME.length(),
102 NapiWebviewController::JsConstructor, nullptr, sizeof(properties) / sizeof(properties[0]),
103 properties, &constructor);
104 NAPI_ASSERT(env, constructor != nullptr, "define js class WebviewController failed");
105 napi_status status = napi_set_named_property(env, exports, "WebviewController", constructor);
106 NAPI_ASSERT(env, status == napi_ok, "set property WebviewController failed");
107
108 napi_value msgPortCons = nullptr;
109 napi_property_descriptor msgPortProperties[] = {
110 DECLARE_NAPI_FUNCTION("close", NapiWebMessagePort::Close),
111 DECLARE_NAPI_FUNCTION("postMessageEvent", NapiWebMessagePort::PostMessageEvent),
112 DECLARE_NAPI_FUNCTION("onMessageEvent", NapiWebMessagePort::OnMessageEvent),
113 };
114 NAPI_CALL(env, napi_define_class(env, WEB_MESSAGE_PORT_CLASS_NAME.c_str(), WEB_MESSAGE_PORT_CLASS_NAME.length(),
115 NapiWebMessagePort::JsConstructor, nullptr, sizeof(msgPortProperties) / sizeof(msgPortProperties[0]),
116 msgPortProperties, &msgPortCons));
117 NAPI_CALL(env, napi_create_reference(env, msgPortCons, 1, &g_classWebMsgPort));
118 NAPI_CALL(env, napi_set_named_property(env, exports, WEB_MESSAGE_PORT_CLASS_NAME.c_str(), msgPortCons));
119
120 napi_value hitTestTypeEnum = nullptr;
121 napi_property_descriptor hitTestTypeProperties[] = {
122 DECLARE_NAPI_STATIC_PROPERTY("EditText", NapiParseUtils::ToInt32Value(env,
123 static_cast<int32_t>(WebHitTestType::EDIT))),
124 DECLARE_NAPI_STATIC_PROPERTY("Email", NapiParseUtils::ToInt32Value(env,
125 static_cast<int32_t>(WebHitTestType::EMAIL))),
126 DECLARE_NAPI_STATIC_PROPERTY("HttpAnchor", NapiParseUtils::ToInt32Value(env,
127 static_cast<int32_t>(WebHitTestType::HTTP))),
128 DECLARE_NAPI_STATIC_PROPERTY("HttpAnchorImg", NapiParseUtils::ToInt32Value(env,
129 static_cast<int32_t>(WebHitTestType::HTTP_IMG))),
130 DECLARE_NAPI_STATIC_PROPERTY("Img", NapiParseUtils::ToInt32Value(env,
131 static_cast<int32_t>(WebHitTestType::IMG))),
132 DECLARE_NAPI_STATIC_PROPERTY("Map", NapiParseUtils::ToInt32Value(env,
133 static_cast<int32_t>(WebHitTestType::MAP))),
134 DECLARE_NAPI_STATIC_PROPERTY("Phone", NapiParseUtils::ToInt32Value(env,
135 static_cast<int32_t>(WebHitTestType::PHONE))),
136 DECLARE_NAPI_STATIC_PROPERTY("Unknown", NapiParseUtils::ToInt32Value(env,
137 static_cast<int32_t>(WebHitTestType::UNKNOWN))),
138 };
139 napi_define_class(env, WEB_HITTESTTYPE_V9_ENUM_NAME.c_str(), WEB_HITTESTTYPE_V9_ENUM_NAME.length(),
140 NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(hitTestTypeProperties) /
141 sizeof(hitTestTypeProperties[0]), hitTestTypeProperties, &hitTestTypeEnum);
142 napi_set_named_property(env, exports, WEB_HITTESTTYPE_V9_ENUM_NAME.c_str(), hitTestTypeEnum);
143
144 napi_define_class(env, WEB_HITTESTTYPE_ENUM_NAME.c_str(), WEB_HITTESTTYPE_ENUM_NAME.length(),
145 NapiParseUtils::CreateEnumConstructor, nullptr, sizeof(hitTestTypeProperties) /
146 sizeof(hitTestTypeProperties[0]), hitTestTypeProperties, &hitTestTypeEnum);
147 napi_set_named_property(env, exports, WEB_HITTESTTYPE_ENUM_NAME.c_str(), hitTestTypeEnum);
148
149 napi_value historyList = nullptr;
150 napi_property_descriptor historyListProperties[] = {
151 DECLARE_NAPI_FUNCTION("getItemAtIndex", NapiWebHistoryList::GetItem)
152 };
153 napi_define_class(env, WEB_HISTORY_LIST_CLASS_NAME.c_str(), WEB_HISTORY_LIST_CLASS_NAME.length(),
154 NapiWebHistoryList::JsConstructor, nullptr, sizeof(historyListProperties) / sizeof(historyListProperties[0]),
155 historyListProperties, &historyList);
156 napi_create_reference(env, historyList, 1, &g_historyListRef);
157 napi_set_named_property(env, exports, WEB_HISTORY_LIST_CLASS_NAME.c_str(), historyList);
158
159 return exports;
160 }
161
JsConstructor(napi_env env,napi_callback_info info)162 napi_value NapiWebviewController::JsConstructor(napi_env env, napi_callback_info info)
163 {
164 napi_value thisVar = nullptr;
165 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
166
167 WebviewController *webviewController = new (std::nothrow) WebviewController();
168 if (webviewController == nullptr) {
169 WVLOG_E("new webview controller failed");
170 return nullptr;
171 }
172 napi_status status = napi_wrap(
173 env, thisVar, webviewController,
174 [](napi_env env, void *data, void *hint) {
175 WebviewController *webviewController = static_cast<WebviewController *>(data);
176 delete webviewController;
177 },
178 nullptr, nullptr);
179 if (status != napi_ok) {
180 WVLOG_E("Wrap native webviewController failed.");
181 return nullptr;
182 }
183 return thisVar;
184 }
185
InitializeWebEngine(napi_env env,napi_callback_info info)186 napi_value NapiWebviewController::InitializeWebEngine(napi_env env, napi_callback_info info)
187 {
188 WVLOG_D("InitializeWebEngine invoked.");
189
190 // obtain bundle path
191 std::shared_ptr<AbilityRuntime::ApplicationContext> ctx =
192 AbilityRuntime::ApplicationContext::GetApplicationContext();
193 if (!ctx) {
194 WVLOG_E("Failed to init web engine due to nil application context.");
195 return nullptr;
196 }
197
198 // load so
199 const std::string& bundle_path = ctx->GetBundleCodeDir();
200 NWebHelper::Instance().SetBundlePath(bundle_path);
201 if (!NWebHelper::Instance().Init(true)) {
202 WVLOG_E("Failed to init web engine due to NWebHelper failure.");
203 return nullptr;
204 }
205
206 napi_value result = nullptr;
207 NAPI_CALL(env, napi_get_undefined(env, &result));
208 WVLOG_I("NWebHelper initialized, init web engine done, bundle_path: %{public}s", bundle_path.c_str());
209 return result;
210 }
211
SetWebDebuggingAccess(napi_env env,napi_callback_info info)212 napi_value NapiWebviewController::SetWebDebuggingAccess(napi_env env, napi_callback_info info)
213 {
214 WVLOG_D("SetWebDebuggingAccess start");
215
216 napi_value thisVar = nullptr;
217 napi_value result = nullptr;
218 size_t argc = INTEGER_ONE;
219 napi_value argv[INTEGER_ONE] = {0};
220
221 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
222 if (argc != INTEGER_ONE) {
223 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
224 return result;
225 }
226
227 bool webDebuggingAccess = false;
228 if (!NapiParseUtils::ParseBoolean(env, argv[0], webDebuggingAccess)) {
229 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
230 return result;
231 }
232 WebviewController::webDebuggingAccess_ = webDebuggingAccess;
233
234 NAPI_CALL(env, napi_get_undefined(env, &result));
235 return result;
236 }
237
InnerGetWebDebuggingAccess(napi_env env,napi_callback_info info)238 napi_value NapiWebviewController::InnerGetWebDebuggingAccess(napi_env env, napi_callback_info info)
239 {
240 WVLOG_D("InnerGetWebDebuggingAccess start");
241 bool webDebuggingAccess = WebviewController::webDebuggingAccess_;
242 napi_value result = nullptr;
243 napi_get_boolean(env, webDebuggingAccess, &result);
244 return result;
245 }
246
InnerGetThisVar(napi_env env,napi_callback_info info)247 napi_value NapiWebviewController::InnerGetThisVar(napi_env env, napi_callback_info info)
248 {
249 WVLOG_D("InnerGetThisVar start");
250 napi_value thisVar = nullptr;
251 napi_value result = nullptr;
252 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
253 WebviewController *webviewController = nullptr;
254 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
255 if ((!webviewController) || (status != napi_ok)) {
256 WVLOG_E("webviewController is nullptr.");
257 napi_create_int64(env, 0, &result);
258 } else {
259 napi_create_int64(env, reinterpret_cast<int64_t>(webviewController), &result);
260 }
261 return result;
262 }
263
SetWebId(napi_env env,napi_callback_info info)264 napi_value NapiWebviewController::SetWebId(napi_env env, napi_callback_info info)
265 {
266 napi_value thisVar = nullptr;
267 size_t argc = INTEGER_ONE;
268 napi_value argv[INTEGER_ONE];
269 void* data = nullptr;
270 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
271
272 int32_t webId = -1;
273 if (!NapiParseUtils::ParseInt32(env, argv[0], webId)) {
274 WVLOG_E("Parse web id failed.");
275 return nullptr;
276 }
277 WebviewController *webviewController = nullptr;
278 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
279 if ((!webviewController) || (status != napi_ok)) {
280 WVLOG_E("webviewController is nullptr.");
281 return nullptr;
282 }
283 webviewController->SetWebId(webId);
284 return thisVar;
285 }
286
InnerJsProxy(napi_env env,napi_callback_info info)287 napi_value NapiWebviewController::InnerJsProxy(napi_env env, napi_callback_info info)
288 {
289 WVLOG_D("NapiWebviewController::InnerJsProxy");
290 napi_value thisVar = nullptr;
291 napi_value result = nullptr;
292 size_t argc = INTEGER_THREE;
293 napi_value argv[INTEGER_THREE] = { 0 };
294
295 napi_get_undefined(env, &result);
296 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
297 if (argc != INTEGER_THREE) {
298 WVLOG_E("Failed to run InnerJsProxy beacuse of wrong Param number.");
299 return result;
300 }
301
302 napi_valuetype valueType = napi_undefined;
303 napi_typeof(env, argv[INTEGER_ZERO], &valueType);
304 if (valueType != napi_object) {
305 WVLOG_E("Failed to run InnerJsProxy beacuse of wrong Param type.");
306 return result;
307 }
308
309 std::string objName;
310 std::vector<std::string> methodList;
311 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], objName) ||
312 !NapiParseUtils::ParseStringArray(env, argv[INTEGER_TWO], methodList)) {
313 WVLOG_E("Failed to run InnerJsProxy beacuse of wrong Param type.");
314 return result;
315 }
316
317 WebviewController *controller = nullptr;
318 napi_unwrap(env, thisVar, (void **)&controller);
319 if (!controller || !controller->IsInit()) {
320 WVLOG_E("Failed to run InnerJsProxy. The WebviewController must be associted with a Web component.");
321 return result;
322 }
323 controller->SetNWebJavaScriptResultCallBack();
324 controller->RegisterJavaScriptProxy(env, argv[INTEGER_ZERO], objName, methodList);
325 return result;
326 }
327
InnerGetCustomeSchemeCmdLine(napi_env env,napi_callback_info info)328 napi_value NapiWebviewController::InnerGetCustomeSchemeCmdLine(napi_env env, napi_callback_info info)
329 {
330 WebviewController::existNweb_ = true;
331 napi_value result = nullptr;
332 std::string cmdLine = WebviewController::customeSchemeCmdLine_;
333 napi_create_string_utf8(env, cmdLine.c_str(), cmdLine.length(), &result);
334 return result;
335 }
336
AccessForward(napi_env env,napi_callback_info info)337 napi_value NapiWebviewController::AccessForward(napi_env env, napi_callback_info info)
338 {
339 napi_value thisVar = nullptr;
340 napi_value result = nullptr;
341 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
342
343 WebviewController *webviewController = nullptr;
344 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
345 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
346 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
347 return nullptr;
348 }
349
350 bool access = webviewController->AccessForward();
351 NAPI_CALL(env, napi_get_boolean(env, access, &result));
352 return result;
353 }
354
AccessBackward(napi_env env,napi_callback_info info)355 napi_value NapiWebviewController::AccessBackward(napi_env env, napi_callback_info info)
356 {
357 napi_value thisVar = nullptr;
358 napi_value result = nullptr;
359 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
360
361 WebviewController *webviewController = nullptr;
362 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
363 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
364 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
365 return nullptr;
366 }
367
368 bool access = webviewController->AccessBackward();
369 NAPI_CALL(env, napi_get_boolean(env, access, &result));
370 return result;
371 }
372
Forward(napi_env env,napi_callback_info info)373 napi_value NapiWebviewController::Forward(napi_env env, napi_callback_info info)
374 {
375 napi_value thisVar = nullptr;
376 napi_value result = nullptr;
377 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
378
379 WebviewController *webviewController = nullptr;
380 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
381 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
382 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
383 return nullptr;
384 }
385
386 webviewController->Forward();
387 NAPI_CALL(env, napi_get_undefined(env, &result));
388 return result;
389 }
390
Backward(napi_env env,napi_callback_info info)391 napi_value NapiWebviewController::Backward(napi_env env, napi_callback_info info)
392 {
393 napi_value thisVar = nullptr;
394 napi_value result = nullptr;
395 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
396
397 WebviewController *webviewController = nullptr;
398 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
399 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
400 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
401 return nullptr;
402 }
403
404 webviewController->Backward();
405 NAPI_CALL(env, napi_get_undefined(env, &result));
406 return result;
407 }
408
AccessStep(napi_env env,napi_callback_info info)409 napi_value NapiWebviewController::AccessStep(napi_env env, napi_callback_info info)
410 {
411 napi_value thisVar = nullptr;
412 napi_value result = nullptr;
413 size_t argc = INTEGER_ONE;
414 napi_value argv[INTEGER_ONE];
415 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
416 if (argc != INTEGER_ONE) {
417 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
418 return nullptr;
419 }
420
421 int32_t step = INTEGER_ZERO;
422 if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], step)) {
423 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
424 return nullptr;
425 }
426
427 WebviewController *webviewController = nullptr;
428 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
429 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
430 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
431 return nullptr;
432 }
433
434 bool access = webviewController->AccessStep(step);
435 NAPI_CALL(env, napi_get_boolean(env, access, &result));
436 return result;
437 }
438
ClearHistory(napi_env env,napi_callback_info info)439 napi_value NapiWebviewController::ClearHistory(napi_env env, napi_callback_info info)
440 {
441 napi_value thisVar = nullptr;
442 napi_value result = nullptr;
443 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
444
445 WebviewController *webviewController = nullptr;
446 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
447 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
448 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
449 return nullptr;
450 }
451
452 webviewController->ClearHistory();
453 NAPI_CALL(env, napi_get_undefined(env, &result));
454 return result;
455 }
456
OnActive(napi_env env,napi_callback_info info)457 napi_value NapiWebviewController::OnActive(napi_env env, napi_callback_info info)
458 {
459 napi_value thisVar = nullptr;
460 napi_value result = nullptr;
461 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
462
463 WebviewController *webviewController = nullptr;
464 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
465 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
466 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
467 return nullptr;
468 }
469
470 webviewController->OnActive();
471 WVLOG_D("The web component has been successfully activated");
472 NAPI_CALL(env, napi_get_undefined(env, &result));
473 return result;
474 }
475
OnInactive(napi_env env,napi_callback_info info)476 napi_value NapiWebviewController::OnInactive(napi_env env, napi_callback_info info)
477 {
478 napi_value thisVar = nullptr;
479 napi_value result = nullptr;
480 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
481
482 WebviewController *webviewController = nullptr;
483 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
484 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
485 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
486 return nullptr;
487 }
488
489 webviewController->OnInactive();
490 WVLOG_D("The web component has been successfully inactivated");
491 NAPI_CALL(env, napi_get_undefined(env, &result));
492 return result;
493 }
494
Refresh(napi_env env,napi_callback_info info)495 napi_value NapiWebviewController::Refresh(napi_env env, napi_callback_info info)
496 {
497 napi_value thisVar = nullptr;
498 napi_value result = nullptr;
499 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
500
501 WebviewController *webviewController = nullptr;
502 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
503 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
504 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
505 return nullptr;
506 }
507
508 webviewController->Refresh();
509 NAPI_CALL(env, napi_get_undefined(env, &result));
510 return result;
511 }
512
CreateWebMessagePorts(napi_env env,napi_callback_info info)513 napi_value NapiWebviewController::CreateWebMessagePorts(napi_env env, napi_callback_info info)
514 {
515 WVLOG_D("create web message port");
516 napi_value thisVar = nullptr;
517 napi_value result = nullptr;
518 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
519
520 WebviewController *webviewController = nullptr;
521 NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
522 if (webviewController == nullptr || !webviewController->IsInit()) {
523 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
524 WVLOG_E("create message port failed, napi unwrap webviewController failed");
525 return nullptr;
526 }
527 int32_t nwebId = webviewController->GetWebId();
528 std::vector<std::string> ports;
529 webviewController->CreateWebMessagePorts(ports);
530 if (ports.size() != INTEGER_TWO) {
531 WVLOG_E("create web message port failed");
532 return result;
533 }
534 napi_value msgPortcons = nullptr;
535 NAPI_CALL(env, napi_get_reference_value(env, g_classWebMsgPort, &msgPortcons));
536 napi_create_array(env, &result);
537 napi_value consParam[INTEGER_TWO][INTEGER_TWO] = {{0}};
538 for (uint32_t i = 0; i < INTEGER_TWO; i++) {
539 napi_value msgPortObj = nullptr;
540 NAPI_CALL(env, napi_create_int32(env, nwebId, &consParam[i][INTEGER_ZERO]));
541 NAPI_CALL(env, napi_create_string_utf8(env, ports[i].c_str(), ports[i].length(), &consParam[i][INTEGER_ONE]));
542 NAPI_CALL(env, napi_new_instance(env, msgPortcons, INTEGER_TWO, consParam[i], &msgPortObj));
543 napi_set_element(env, result, i, msgPortObj);
544 }
545
546 return result;
547 }
548
PostMessage(napi_env env,napi_callback_info info)549 napi_value NapiWebviewController::PostMessage(napi_env env, napi_callback_info info)
550 {
551 WVLOG_D("post message port");
552 napi_value thisVar = nullptr;
553 napi_value result = nullptr;
554 size_t argc = INTEGER_THREE;
555 napi_value argv[INTEGER_THREE];
556 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
557 if (argc != INTEGER_THREE) {
558 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
559 return result;
560 }
561
562 std::string portName;
563 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], portName)) {
564 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
565 return result;
566 }
567
568 bool isArray = false;
569 NAPI_CALL(env, napi_is_array(env, argv[INTEGER_ONE], &isArray));
570 if (!isArray) {
571 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
572 return result;
573 }
574 uint32_t arrayLen = 0;
575 NAPI_CALL(env, napi_get_array_length(env, argv[INTEGER_ONE], &arrayLen));
576 if (arrayLen == 0) {
577 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
578 return result;
579 }
580 std::vector<std::string> sendPorts;
581 napi_valuetype valueType = napi_undefined;
582 for (uint32_t i = 0; i < arrayLen; i++) {
583 napi_value portItem = nullptr;
584 napi_get_element(env, argv[INTEGER_ONE], i, &portItem);
585 NAPI_CALL(env, napi_typeof(env, portItem, &valueType));
586 if (valueType != napi_object) {
587 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
588 return result;
589 }
590 WebMessagePort *msgPort = nullptr;
591 NAPI_CALL(env, napi_unwrap(env, portItem, (void **)&msgPort));
592 if (!msgPort) {
593 WVLOG_E("post port to html failed, napi unwrap msg port fail");
594 return nullptr;
595 }
596 std::string portHandle = msgPort->GetPortHandle();
597 sendPorts.emplace_back(portHandle);
598 }
599
600 std::string urlStr;
601 if (!NapiParseUtils::ParseString(env, argv[INTEGER_TWO], urlStr)) {
602 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
603 return result;
604 }
605
606 WebviewController *webviewController = nullptr;
607 NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
608 if (webviewController == nullptr || !webviewController->IsInit()) {
609 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
610 WVLOG_E("post port to html failed, napi unwrap webviewController failed");
611 return nullptr;
612 }
613
614 webviewController->PostWebMessage(portName, sendPorts, urlStr);
615 NAPI_CALL(env, napi_get_undefined(env, &result));
616
617 return result;
618 }
619
JsConstructor(napi_env env,napi_callback_info info)620 napi_value NapiWebMessagePort::JsConstructor(napi_env env, napi_callback_info info)
621 {
622 WVLOG_D("web message port construct");
623 napi_value thisVar = nullptr;
624 size_t argc = INTEGER_TWO;
625 napi_value argv[INTEGER_TWO] = {0};
626 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
627
628 int32_t webId = -1;
629 if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], webId)) {
630 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
631 return nullptr;
632 }
633
634 std::string portHandle;
635 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], portHandle)) {
636 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
637 return nullptr;
638 }
639 WebMessagePort *msgPort = new (std::nothrow) WebMessagePort(webId, portHandle);
640 if (msgPort == nullptr) {
641 WVLOG_E("new msg port failed");
642 return nullptr;
643 }
644 NAPI_CALL(env, napi_wrap(env, thisVar, msgPort,
645 [](napi_env env, void *data, void *hint) {
646 WebMessagePort *msgPort = static_cast<WebMessagePort *>(data);
647 delete msgPort;
648 },
649 nullptr, nullptr));
650 return thisVar;
651 }
652
Close(napi_env env,napi_callback_info info)653 napi_value NapiWebMessagePort::Close(napi_env env, napi_callback_info info)
654 {
655 WVLOG_D("close message port");
656 napi_value thisVar = nullptr;
657 napi_value result = nullptr;
658 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
659
660 WebMessagePort *msgPort = nullptr;
661 NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
662 if (msgPort == nullptr) {
663 WVLOG_E("close message port failed, napi unwrap msg port failed");
664 return nullptr;
665 }
666 ErrCode ret = msgPort->ClosePort();
667 if (ret != NO_ERROR) {
668 BusinessError::ThrowErrorByErrcode(env, ret);
669 return result;
670 }
671 NAPI_CALL(env, napi_get_undefined(env, &result));
672
673 return result;
674 }
675
PostMessageEvent(napi_env env,napi_callback_info info)676 napi_value NapiWebMessagePort::PostMessageEvent(napi_env env, napi_callback_info info)
677 {
678 WVLOG_D("message port post message");
679 napi_value thisVar = nullptr;
680 napi_value result = nullptr;
681 size_t argc = INTEGER_ONE;
682 napi_value argv[INTEGER_ONE];
683 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
684 if (argc != INTEGER_ONE) {
685 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
686 return result;
687 }
688 napi_valuetype valueType = napi_undefined;
689 napi_typeof(env, argv[INTEGER_ZERO], &valueType);
690
691 bool isArrayBuffer = false;
692 NAPI_CALL(env, napi_is_arraybuffer(env, argv[INTEGER_ZERO], &isArrayBuffer));
693 if (valueType != napi_string && !isArrayBuffer) {
694 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
695 return result;
696 }
697
698 auto webMsg = std::make_shared<OHOS::NWeb::NWebMessage>(NWebValue::Type::NONE);
699 if (valueType == napi_string) {
700 size_t bufferSize = 0;
701 napi_get_value_string_utf8(env, argv[INTEGER_ZERO], nullptr, 0, &bufferSize);
702 if (bufferSize > UINT_MAX) {
703 WVLOG_E("String length is too long");
704 return result;
705 }
706 char* stringValue = new (std::nothrow) char[bufferSize + 1];
707 if (stringValue == nullptr) {
708 BusinessError::ThrowErrorByErrcode(env, NEW_OOM);
709 return result;
710 }
711 size_t jsStringLength = 0;
712 napi_get_value_string_utf8(env, argv[INTEGER_ZERO], stringValue, bufferSize + 1, &jsStringLength);
713 std::string message(stringValue);
714 delete [] stringValue;
715 stringValue = nullptr;
716
717 webMsg->SetType(NWebValue::Type::STRING);
718 webMsg->SetString(message);
719 } else if (isArrayBuffer) {
720 uint8_t *arrBuf = nullptr;
721 size_t byteLength = 0;
722 napi_get_arraybuffer_info(env, argv[INTEGER_ZERO], (void**)&arrBuf, &byteLength);
723 std::vector<uint8_t> vecData(arrBuf, arrBuf + byteLength);
724 webMsg->SetType(NWebValue::Type::BINARY);
725 webMsg->SetBinary(vecData);
726 }
727
728 WebMessagePort *msgPort = nullptr;
729 NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
730 if (msgPort == nullptr) {
731 WVLOG_E("post message failed, napi unwrap msg port failed");
732 return nullptr;
733 }
734 ErrCode ret = msgPort->PostPortMessage(webMsg);
735 if (ret != NO_ERROR) {
736 BusinessError::ThrowErrorByErrcode(env, ret);
737 return result;
738 }
739 NAPI_CALL(env, napi_get_undefined(env, &result));
740
741 return result;
742 }
743
UvWebMessageOnReceiveValueCallback(uv_work_t * work,int status)744 void NWebValueCallbackImpl::UvWebMessageOnReceiveValueCallback(uv_work_t *work, int status)
745 {
746 if (work == nullptr) {
747 WVLOG_E("uv work is null");
748 return;
749 }
750 NapiWebMessagePort::WebMsgPortParam *data = reinterpret_cast<NapiWebMessagePort::WebMsgPortParam*>(work->data);
751 if (data == nullptr) {
752 WVLOG_E("WebMsgPortParam is null");
753 delete work;
754 work = nullptr;
755 return;
756 }
757 napi_handle_scope scope = nullptr;
758 napi_open_handle_scope(data->env_, &scope);
759 if (scope == nullptr) {
760 return;
761 }
762
763 napi_value result[INTEGER_ONE] = {0};
764 std::shared_ptr<NWebMessage> webMsg = data->msg_;
765 if (webMsg->GetType() == NWebValue::Type::STRING) {
766 std::string msgStr = webMsg->GetString();
767 napi_create_string_utf8(data->env_, msgStr.c_str(), msgStr.length(), &result[INTEGER_ZERO]);
768 } else if (webMsg->GetType() == NWebValue::Type::BINARY) {
769 std::vector<uint8_t> msgArr = webMsg->GetBinary();
770 void *arrayData = nullptr;
771 napi_create_arraybuffer(data->env_, msgArr.size(), &arrayData, &result[INTEGER_ZERO]);
772 if (arrayData == nullptr) {
773 WVLOG_E("Create arraybuffer failed");
774 napi_close_handle_scope(data->env_, scope);
775 return;
776 }
777 for (size_t i = 0; i < msgArr.size(); ++i) {
778 *(uint8_t*)((uint8_t*)arrayData + i) = msgArr[i];
779 }
780 }
781 napi_value onMsgEventFunc = nullptr;
782 napi_get_reference_value(data->env_, data->callback_, &onMsgEventFunc);
783 napi_value placeHodler = nullptr;
784 napi_call_function(data->env_, nullptr, onMsgEventFunc, INTEGER_ONE, &result[INTEGER_ZERO], &placeHodler);
785
786 std::unique_lock<std::mutex> lock(data->mutex_);
787 data->ready_ = true;
788 data->condition_.notify_all();
789 napi_close_handle_scope(data->env_, scope);
790 }
791
OnReceiveValue(std::shared_ptr<NWebMessage> result)792 void NWebValueCallbackImpl::OnReceiveValue(std::shared_ptr<NWebMessage> result)
793 {
794 WVLOG_D("message port received msg");
795 uv_loop_s *loop = nullptr;
796 uv_work_t *work = nullptr;
797 napi_get_uv_event_loop(env_, &loop);
798 if (loop == nullptr) {
799 WVLOG_E("get uv event loop failed");
800 return;
801 }
802 work = new (std::nothrow) uv_work_t;
803 if (work == nullptr) {
804 WVLOG_E("new uv work failed");
805 return;
806 }
807 NapiWebMessagePort::WebMsgPortParam *param = new (std::nothrow) NapiWebMessagePort::WebMsgPortParam();
808 if (param == nullptr) {
809 WVLOG_E("new WebMsgPortParam failed");
810 delete work;
811 return;
812 }
813 param->env_ = env_;
814 param->callback_ = callback_;
815 param->msg_ = result;
816 work->data = reinterpret_cast<void*>(param);
817 uv_queue_work(loop, work, [](uv_work_t *work) {}, UvWebMessageOnReceiveValueCallback);
818 std::unique_lock<std::mutex> lock(param->mutex_);
819 param->condition_.wait(lock, [¶m] { return param->ready_; });
820 if (param != nullptr) {
821 delete param;
822 param = nullptr;
823 }
824 if (work != nullptr) {
825 delete work;
826 work = nullptr;
827 }
828 }
829
~NWebValueCallbackImpl()830 NWebValueCallbackImpl::~NWebValueCallbackImpl()
831 {
832 WVLOG_D("~NWebValueCallbackImpl");
833 uv_loop_s *loop = nullptr;
834 uv_work_t *work = nullptr;
835 napi_get_uv_event_loop(env_, &loop);
836 if (loop == nullptr) {
837 WVLOG_E("get uv event loop failed");
838 return;
839 }
840 work = new (std::nothrow) uv_work_t;
841 if (work == nullptr) {
842 WVLOG_E("new uv work failed");
843 return;
844 }
845 NapiWebMessagePort::WebMsgPortParam *param = new (std::nothrow) NapiWebMessagePort::WebMsgPortParam();
846 if (param == nullptr) {
847 WVLOG_E("new WebMsgPortParam failed");
848 delete work;
849 return;
850 }
851 param->env_ = env_;
852 param->callback_ = callback_;
853 work->data = reinterpret_cast<void*>(param);
854 int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
855 if (work == nullptr) {
856 WVLOG_E("uv work is null");
857 return;
858 }
859 NapiWebMessagePort::WebMsgPortParam *data = reinterpret_cast<NapiWebMessagePort::WebMsgPortParam*>(work->data);
860 if (data == nullptr) {
861 WVLOG_E("WebMsgPortParam is null");
862 delete work;
863 work = nullptr;
864 return;
865 }
866
867 napi_delete_reference(data->env_, data->callback_);
868 delete data;
869 data = nullptr;
870 delete work;
871 work = nullptr;
872 });
873 if (ret != 0) {
874 if (param != nullptr) {
875 delete param;
876 param = nullptr;
877 }
878 if (work != nullptr) {
879 delete work;
880 work = nullptr;
881 }
882 }
883 }
884
OnMessageEvent(napi_env env,napi_callback_info info)885 napi_value NapiWebMessagePort::OnMessageEvent(napi_env env, napi_callback_info info)
886 {
887 WVLOG_D("message port set OnMessageEvent callback");
888 napi_value thisVar = nullptr;
889 napi_value result = nullptr;
890 size_t argc = INTEGER_ONE;
891 napi_value argv[INTEGER_ONE];
892 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
893 if (argc != INTEGER_ONE) {
894 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
895 return result;
896 }
897 napi_valuetype valueType = napi_undefined;
898 napi_typeof(env, argv[INTEGER_ZERO], &valueType);
899 if (valueType != napi_function) {
900 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
901 return result;
902 }
903
904 napi_ref onMsgEventFunc = nullptr;
905 NAPI_CALL(env, napi_create_reference(env, argv[INTEGER_ZERO], INTEGER_ONE, &onMsgEventFunc));
906
907 auto callbackImpl = std::make_shared<NWebValueCallbackImpl>(env, onMsgEventFunc);
908
909 WebMessagePort *msgPort = nullptr;
910 NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&msgPort));
911 if (msgPort == nullptr) {
912 WVLOG_E("set message event callback failed, napi unwrap msg port failed");
913 return nullptr;
914 }
915 ErrCode ret = msgPort->SetPortMessageCallback(callbackImpl);
916 if (ret != NO_ERROR) {
917 BusinessError::ThrowErrorByErrcode(env, ret);
918 }
919 NAPI_CALL(env, napi_get_undefined(env, &result));
920 return result;
921 }
922
ZoomIn(napi_env env,napi_callback_info info)923 napi_value NapiWebviewController::ZoomIn(napi_env env, napi_callback_info info)
924 {
925 napi_value thisVar = nullptr;
926 napi_value result = nullptr;
927 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
928
929 WebviewController *webviewController = nullptr;
930 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
931 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
932 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
933 return nullptr;
934 }
935
936 ErrCode ret = webviewController->ZoomIn();
937 if (ret != NO_ERROR) {
938 if (ret == NWEB_ERROR) {
939 WVLOG_E("ZoomIn failed.");
940 return nullptr;
941 }
942 BusinessError::ThrowErrorByErrcode(env, ret);
943 }
944
945 NAPI_CALL(env, napi_get_undefined(env, &result));
946 return result;
947 }
948
ZoomOut(napi_env env,napi_callback_info info)949 napi_value NapiWebviewController::ZoomOut(napi_env env, napi_callback_info info)
950 {
951 napi_value thisVar = nullptr;
952 napi_value result = nullptr;
953 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
954
955 WebviewController *webviewController = nullptr;
956 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
957 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
958 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
959 return nullptr;
960 }
961
962 ErrCode ret = webviewController->ZoomOut();
963 if (ret != NO_ERROR) {
964 if (ret == NWEB_ERROR) {
965 WVLOG_E("ZoomOut failed.");
966 return nullptr;
967 }
968 BusinessError::ThrowErrorByErrcode(env, ret);
969 }
970
971 NAPI_CALL(env, napi_get_undefined(env, &result));
972 return result;
973 }
974
GetWebId(napi_env env,napi_callback_info info)975 napi_value NapiWebviewController::GetWebId(napi_env env, napi_callback_info info)
976 {
977 napi_value thisVar = nullptr;
978 napi_value result = nullptr;
979 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
980
981 WebviewController *webviewController = nullptr;
982 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
983 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
984 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
985 return nullptr;
986 }
987
988 int32_t webId = webviewController->GetWebId();
989 napi_create_int32(env, webId, &result);
990
991 return result;
992 }
993
GetUserAgent(napi_env env,napi_callback_info info)994 napi_value NapiWebviewController::GetUserAgent(napi_env env, napi_callback_info info)
995 {
996 napi_value thisVar = nullptr;
997 napi_value result = nullptr;
998 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
999
1000 WebviewController *webviewController = nullptr;
1001 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1002 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1003 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1004 return nullptr;
1005 }
1006
1007 std::string userAgent = "";
1008 userAgent = webviewController->GetUserAgent();
1009 napi_create_string_utf8(env, userAgent.c_str(), userAgent.length(), &result);
1010
1011 return result;
1012 }
1013
GetTitle(napi_env env,napi_callback_info info)1014 napi_value NapiWebviewController::GetTitle(napi_env env, napi_callback_info info)
1015 {
1016 napi_value thisVar = nullptr;
1017 napi_value result = nullptr;
1018 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1019
1020 WebviewController *webviewController = nullptr;
1021 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1022 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1023 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1024 return nullptr;
1025 }
1026
1027 std::string title = "";
1028 title = webviewController->GetTitle();
1029 napi_create_string_utf8(env, title.c_str(), title.length(), &result);
1030
1031 return result;
1032 }
1033
GetPageHeight(napi_env env,napi_callback_info info)1034 napi_value NapiWebviewController::GetPageHeight(napi_env env, napi_callback_info info)
1035 {
1036 napi_value thisVar = nullptr;
1037 napi_value result = nullptr;
1038 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1039
1040 WebviewController *webviewController = nullptr;
1041 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1042 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1043 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1044 return nullptr;
1045 }
1046
1047 int32_t pageHeight = webviewController->GetPageHeight();
1048 napi_create_int32(env, pageHeight, &result);
1049
1050 return result;
1051 }
1052
BackOrForward(napi_env env,napi_callback_info info)1053 napi_value NapiWebviewController::BackOrForward(napi_env env, napi_callback_info info)
1054 {
1055 napi_value thisVar = nullptr;
1056 napi_value result = nullptr;
1057 size_t argc = INTEGER_ONE;
1058 napi_value argv[INTEGER_ONE] = {0};
1059 void* data = nullptr;
1060 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1061
1062 if (argc != INTEGER_ONE) {
1063 WVLOG_E("Requires 1 parameters.");
1064 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1065 return nullptr;
1066 }
1067
1068 int32_t step = -1;
1069 if (!NapiParseUtils::ParseInt32(env, argv[INTEGER_ZERO], step)) {
1070 WVLOG_E("Parameter is not integer number type.");
1071 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1072 return nullptr;
1073 }
1074
1075 WebviewController *webviewController = nullptr;
1076 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1077 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1078 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1079 return nullptr;
1080 }
1081
1082 ErrCode ret = webviewController->BackOrForward(step);
1083 if (ret != NO_ERROR) {
1084 BusinessError::ThrowErrorByErrcode(env, ret);
1085 }
1086
1087 NAPI_CALL(env, napi_get_undefined(env, &result));
1088 return result;
1089 }
1090
StoreWebArchive(napi_env env,napi_callback_info info)1091 napi_value NapiWebviewController::StoreWebArchive(napi_env env, napi_callback_info info)
1092 {
1093 napi_value thisVar = nullptr;
1094 napi_value result = nullptr;
1095 size_t argc = INTEGER_ONE;
1096 size_t argcPromise = INTEGER_TWO;
1097 size_t argcCallback = INTEGER_THREE;
1098 napi_value argv[INTEGER_THREE] = { 0 };
1099
1100 napi_get_undefined(env, &result);
1101 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1102
1103 if (argc != argcPromise && argc != argcCallback) {
1104 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
1105 return result;
1106 }
1107 std::string baseName;
1108 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], baseName)) {
1109 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
1110 return result;
1111 }
1112
1113 if (baseName.empty()) {
1114 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
1115 return result;
1116 }
1117
1118 bool autoName = false;
1119 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1120 if (!NapiParseUtils::ParseBoolean(env, argv[INTEGER_ONE], autoName)) {
1121 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
1122 return result;
1123 }
1124
1125 if (argc == argcCallback) {
1126 napi_valuetype valueType = napi_null;
1127 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1128 napi_typeof(env, argv[argcCallback - 1], &valueType);
1129 if (valueType != napi_function) {
1130 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
1131 return result;
1132 }
1133 }
1134 return StoreWebArchiveInternal(env, info, baseName, autoName);
1135 }
1136
StoreWebArchiveInternal(napi_env env,napi_callback_info info,const std::string & baseName,bool autoName)1137 napi_value NapiWebviewController::StoreWebArchiveInternal(napi_env env, napi_callback_info info,
1138 const std::string &baseName, bool autoName)
1139 {
1140 napi_value thisVar = nullptr;
1141 size_t argc = INTEGER_ONE;
1142 size_t argcPromise = INTEGER_TWO;
1143 size_t argcCallback = INTEGER_THREE;
1144 napi_value argv[INTEGER_THREE] = {0};
1145
1146 napi_value result = nullptr;
1147 napi_get_undefined(env, &result);
1148 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1149
1150 WebviewController *webviewController = nullptr;
1151 napi_unwrap(env, thisVar, (void **)&webviewController);
1152
1153 if (!webviewController || !webviewController->IsInit()) {
1154 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1155 return result;
1156 }
1157
1158 if (argc == argcCallback) {
1159 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1160 napi_ref jsCallback = nullptr;
1161 napi_create_reference(env, argv[argcCallback - 1], 1, &jsCallback);
1162
1163 if (jsCallback) {
1164 webviewController->StoreWebArchiveCallback(baseName, autoName, env, std::move(jsCallback));
1165 }
1166 return result;
1167 } else if (argc == argcPromise) {
1168 napi_deferred deferred = nullptr;
1169 napi_value promise = nullptr;
1170 napi_create_promise(env, &deferred, &promise);
1171 if (promise && deferred) {
1172 webviewController->StoreWebArchivePromise(baseName, autoName, env, deferred);
1173 }
1174 return promise;
1175 }
1176 return result;
1177 }
1178
GetHitTestValue(napi_env env,napi_callback_info info)1179 napi_value NapiWebviewController::GetHitTestValue(napi_env env, napi_callback_info info)
1180 {
1181 napi_value thisVar = nullptr;
1182 napi_value result = nullptr;
1183 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1184
1185 WebviewController *webviewController = nullptr;
1186 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1187 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1188 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1189 return nullptr;
1190 }
1191
1192 HitTestResult nwebResult = webviewController->GetHitTestValue();
1193
1194 napi_create_object(env, &result);
1195
1196 napi_value type;
1197 napi_create_uint32(env, nwebResult.GetType(), &type);
1198 napi_set_named_property(env, result, "type", type);
1199
1200 napi_value extra;
1201 napi_create_string_utf8(env, nwebResult.GetExtra().c_str(), NAPI_AUTO_LENGTH, &extra);
1202 napi_set_named_property(env, result, "extra", extra);
1203
1204 return result;
1205 }
1206
RequestFocus(napi_env env,napi_callback_info info)1207 napi_value NapiWebviewController::RequestFocus(napi_env env, napi_callback_info info)
1208 {
1209 napi_value thisVar = nullptr;
1210 napi_value result = nullptr;
1211 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1212
1213 WebviewController *webviewController = nullptr;
1214 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1215 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1216 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1217 return nullptr;
1218 }
1219
1220 webviewController->RequestFocus();
1221 NAPI_CALL(env, napi_get_undefined(env, &result));
1222 return result;
1223 }
1224
LoadUrl(napi_env env,napi_callback_info info)1225 napi_value NapiWebviewController::LoadUrl(napi_env env, napi_callback_info info)
1226 {
1227 napi_value thisVar = nullptr;
1228 napi_value result = nullptr;
1229 size_t argc = INTEGER_TWO;
1230 napi_value argv[INTEGER_TWO];
1231 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1232 if ((argc != INTEGER_ONE) && (argc != INTEGER_TWO)) {
1233 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1234 return nullptr;
1235 }
1236 WebviewController *webviewController = nullptr;
1237 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1238 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1239 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1240 return nullptr;
1241 }
1242 napi_valuetype webSrcType;
1243 napi_typeof(env, argv[INTEGER_ZERO], &webSrcType);
1244 if (webSrcType != napi_string && webSrcType != napi_object) {
1245 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1246 return nullptr;
1247 }
1248 std::string webSrc;
1249 ErrCode ret = webviewController->ParseUrl(env, argv[INTEGER_ZERO], webSrc);
1250 if (ret != NO_ERROR) {
1251 BusinessError::ThrowErrorByErrcode(env, ret);
1252 return nullptr;
1253 }
1254 if (argc == INTEGER_ONE) {
1255 ret = webviewController->LoadUrl(webSrc);
1256 if (ret != NO_ERROR) {
1257 if (ret == NWEB_ERROR) {
1258 return nullptr;
1259 }
1260 BusinessError::ThrowErrorByErrcode(env, ret);
1261 return nullptr;
1262 }
1263 NAPI_CALL(env, napi_get_undefined(env, &result));
1264 return result;
1265 }
1266 return LoadUrlWithHttpHeaders(env, info, webSrc, argv, webviewController);
1267 }
1268
LoadUrlWithHttpHeaders(napi_env env,napi_callback_info info,const std::string & url,const napi_value * argv,WebviewController * webviewController)1269 napi_value NapiWebviewController::LoadUrlWithHttpHeaders(napi_env env, napi_callback_info info, const std::string& url,
1270 const napi_value* argv, WebviewController* webviewController)
1271 {
1272 napi_value result = nullptr;
1273 std::map<std::string, std::string> httpHeaders;
1274 napi_value array = argv[INTEGER_ONE];
1275 bool isArray = false;
1276 napi_is_array(env, array, &isArray);
1277 if (isArray) {
1278 uint32_t arrayLength = INTEGER_ZERO;
1279 napi_get_array_length(env, array, &arrayLength);
1280 for (uint32_t i = 0; i < arrayLength; ++i) {
1281 std::string key;
1282 std::string value;
1283 napi_value obj = nullptr;
1284 napi_value keyObj = nullptr;
1285 napi_value valueObj = nullptr;
1286 napi_get_element(env, array, i, &obj);
1287 if (napi_get_named_property(env, obj, "headerKey", &keyObj) != napi_ok) {
1288 continue;
1289 }
1290 if (napi_get_named_property(env, obj, "headerValue", &valueObj) != napi_ok) {
1291 continue;
1292 }
1293 NapiParseUtils::ParseString(env, keyObj, key);
1294 NapiParseUtils::ParseString(env, valueObj, value);
1295 httpHeaders[key] = value;
1296 }
1297 } else {
1298 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1299 return nullptr;
1300 }
1301
1302 ErrCode ret = webviewController->LoadUrl(url, httpHeaders);
1303 if (ret != NO_ERROR) {
1304 if (ret == NWEB_ERROR) {
1305 WVLOG_E("LoadUrl failed.");
1306 return nullptr;
1307 }
1308 BusinessError::ThrowErrorByErrcode(env, ret);
1309 return nullptr;
1310 }
1311 NAPI_CALL(env, napi_get_undefined(env, &result));
1312 return result;
1313 }
1314
LoadData(napi_env env,napi_callback_info info)1315 napi_value NapiWebviewController::LoadData(napi_env env, napi_callback_info info)
1316 {
1317 napi_value thisVar = nullptr;
1318 napi_value result = nullptr;
1319 size_t argc = INTEGER_FIVE;
1320 napi_value argv[INTEGER_FIVE];
1321 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1322 if ((argc != INTEGER_THREE) && (argc != INTEGER_FOUR) &&
1323 (argc != INTEGER_FIVE)) {
1324 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1325 return nullptr;
1326 }
1327 WebviewController *webviewController = nullptr;
1328 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1329 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1330 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1331 return nullptr;
1332 }
1333 std::string data;
1334 std::string mimeType;
1335 std::string encoding;
1336 std::string baseUrl;
1337 std::string historyUrl;
1338 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], data) ||
1339 !NapiParseUtils::ParseString(env, argv[INTEGER_ONE], mimeType) ||
1340 !NapiParseUtils::ParseString(env, argv[INTEGER_TWO], encoding)) {
1341 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1342 return nullptr;
1343 }
1344 if ((argc >= INTEGER_FOUR) && !NapiParseUtils::ParseString(env, argv[INTEGER_THREE], baseUrl)) {
1345 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1346 return nullptr;
1347 }
1348 if ((argc == INTEGER_FIVE) && !NapiParseUtils::ParseString(env, argv[INTEGER_FOUR], historyUrl)) {
1349 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1350 return nullptr;
1351 }
1352 ErrCode ret = webviewController->LoadData(data, mimeType, encoding, baseUrl, historyUrl);
1353 if (ret != NO_ERROR) {
1354 if (ret == NWEB_ERROR) {
1355 WVLOG_E("LoadData failed.");
1356 return nullptr;
1357 }
1358 BusinessError::ThrowErrorByErrcode(env, ret);
1359 return nullptr;
1360 }
1361
1362 NAPI_CALL(env, napi_get_undefined(env, &result));
1363 return result;
1364 }
1365
GetHitTest(napi_env env,napi_callback_info info)1366 napi_value NapiWebviewController::GetHitTest(napi_env env, napi_callback_info info)
1367 {
1368 napi_value thisVar = nullptr;
1369 napi_value result = nullptr;
1370 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1371
1372 WebviewController *webviewController = nullptr;
1373 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1374 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1375 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1376 return nullptr;
1377 }
1378
1379 int32_t type = webviewController->GetHitTest();
1380 napi_create_int32(env, type, &result);
1381 return result;
1382 }
1383
ClearMatches(napi_env env,napi_callback_info info)1384 napi_value NapiWebviewController::ClearMatches(napi_env env, napi_callback_info info)
1385 {
1386 napi_value thisVar = nullptr;
1387 napi_value result = nullptr;
1388
1389 NAPI_CALL(env, napi_get_undefined(env, &result));
1390 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1391
1392 WebviewController *controller = nullptr;
1393 napi_unwrap(env, thisVar, (void **)&controller);
1394 if (!controller || !controller->IsInit()) {
1395 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1396 return result;
1397 }
1398 controller->ClearMatches();
1399 return result;
1400 }
1401
SearchNext(napi_env env,napi_callback_info info)1402 napi_value NapiWebviewController::SearchNext(napi_env env, napi_callback_info info)
1403 {
1404 napi_value thisVar = nullptr;
1405 napi_value result = nullptr;
1406 size_t argc = INTEGER_ONE;
1407 napi_value argv[INTEGER_ONE] = { 0 };
1408
1409 NAPI_CALL(env, napi_get_undefined(env, &result));
1410 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1411 if (argc != INTEGER_ONE) {
1412 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1413 return result;
1414 }
1415 bool forward;
1416 if (!NapiParseUtils::ParseBoolean(env, argv[0], forward)) {
1417 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1418 return result;
1419 }
1420
1421 WebviewController *controller = nullptr;
1422 napi_unwrap(env, thisVar, (void **)&controller);
1423 if (!controller || !controller->IsInit()) {
1424 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1425 return result;
1426 }
1427 controller->SearchNext(forward);
1428 return result;
1429 }
1430
SearchAllAsync(napi_env env,napi_callback_info info)1431 napi_value NapiWebviewController::SearchAllAsync(napi_env env, napi_callback_info info)
1432 {
1433 napi_value thisVar = nullptr;
1434 napi_value result = nullptr;
1435 size_t argc = INTEGER_ONE;
1436 napi_value argv[INTEGER_ONE] = { 0 };
1437
1438 NAPI_CALL(env, napi_get_undefined(env, &result));
1439 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1440 if (argc != INTEGER_ONE) {
1441 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1442 return result;
1443 }
1444 std::string searchString;
1445 if (!NapiParseUtils::ParseString(env, argv[0], searchString)) {
1446 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1447 return result;
1448 }
1449
1450 WebviewController *controller = nullptr;
1451 napi_unwrap(env, thisVar, (void **)&controller);
1452 if (!controller || !controller->IsInit()) {
1453 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1454 return result;
1455 }
1456 controller->SearchAllAsync(searchString);
1457 return result;
1458 }
1459
ClearSslCache(napi_env env,napi_callback_info info)1460 napi_value NapiWebviewController::ClearSslCache(napi_env env, napi_callback_info info)
1461 {
1462 napi_value thisVar = nullptr;
1463 napi_value result = nullptr;
1464
1465 NAPI_CALL(env, napi_get_undefined(env, &result));
1466 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1467
1468 WebviewController *controller = nullptr;
1469 napi_unwrap(env, thisVar, (void **)&controller);
1470 if (!controller || !controller->IsInit()) {
1471 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1472 return result;
1473 }
1474 controller->ClearSslCache();
1475 return result;
1476 }
1477
ClearClientAuthenticationCache(napi_env env,napi_callback_info info)1478 napi_value NapiWebviewController::ClearClientAuthenticationCache(napi_env env, napi_callback_info info)
1479 {
1480 napi_value thisVar = nullptr;
1481 napi_value result = nullptr;
1482
1483 NAPI_CALL(env, napi_get_undefined(env, &result));
1484 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1485
1486 WebviewController *controller = nullptr;
1487 napi_unwrap(env, thisVar, (void **)&controller);
1488 if (!controller || !controller->IsInit()) {
1489 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1490 return result;
1491 }
1492 controller->ClearClientAuthenticationCache();
1493
1494 return result;
1495 }
1496
Stop(napi_env env,napi_callback_info info)1497 napi_value NapiWebviewController::Stop(napi_env env, napi_callback_info info)
1498 {
1499 napi_value thisVar = nullptr;
1500 napi_value result = nullptr;
1501 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1502
1503 WebviewController *controller = nullptr;
1504 napi_unwrap(env, thisVar, (void **)&controller);
1505 if (!controller || !controller->IsInit()) {
1506 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1507 return result;
1508 }
1509 controller->Stop();
1510
1511 NAPI_CALL(env, napi_get_undefined(env, &result));
1512 return result;
1513 }
1514
Zoom(napi_env env,napi_callback_info info)1515 napi_value NapiWebviewController::Zoom(napi_env env, napi_callback_info info)
1516 {
1517 napi_value thisVar = nullptr;
1518 napi_value result = nullptr;
1519 size_t argc = INTEGER_ONE;
1520 napi_value argv[INTEGER_ONE] = { 0 };
1521
1522 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1523 if (argc != INTEGER_ONE) {
1524 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1525 return result;
1526 }
1527 float factor = 0.0;
1528 if (!NapiParseUtils::ParseFloat(env, argv[0], factor)) {
1529 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1530 return result;
1531 }
1532
1533 WebviewController *controller = nullptr;
1534 napi_unwrap(env, thisVar, (void **)&controller);
1535 if (!controller || !controller->IsInit()) {
1536 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1537 return result;
1538 }
1539
1540 ErrCode ret = controller->Zoom(factor);
1541 if (ret != NO_ERROR) {
1542 if (ret == NWEB_ERROR) {
1543 WVLOG_E("Zoom failed.");
1544 return result;
1545 }
1546 BusinessError::ThrowErrorByErrcode(env, ret);
1547 }
1548
1549 NAPI_CALL(env, napi_get_undefined(env, &result));
1550 return result;
1551 }
1552
RegisterJavaScriptProxy(napi_env env,napi_callback_info info)1553 napi_value NapiWebviewController::RegisterJavaScriptProxy(napi_env env, napi_callback_info info)
1554 {
1555 WVLOG_D("NapiWebviewController::RegisterJavaScriptProxy");
1556 napi_value thisVar = nullptr;
1557 napi_value result = nullptr;
1558 size_t argc = INTEGER_THREE;
1559 napi_value argv[INTEGER_THREE] = { 0 };
1560
1561 napi_get_undefined(env, &result);
1562 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1563 if (argc != INTEGER_THREE) {
1564 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1565 return result;
1566 }
1567
1568 napi_valuetype valueType = napi_undefined;
1569 napi_typeof(env, argv[INTEGER_ZERO], &valueType);
1570 if (valueType != napi_object) {
1571 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1572 return result;
1573 }
1574
1575 std::string objName;
1576 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ONE], objName)) {
1577 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1578 return result;
1579 }
1580
1581 std::vector<std::string> methodList;
1582 if (!NapiParseUtils::ParseStringArray(env, argv[INTEGER_TWO], methodList)) {
1583 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1584 return result;
1585 }
1586
1587 WebviewController *controller = nullptr;
1588 napi_unwrap(env, thisVar, (void **)&controller);
1589 if (!controller || !controller->IsInit()) {
1590 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1591 return result;
1592 }
1593 controller->SetNWebJavaScriptResultCallBack();
1594 controller->RegisterJavaScriptProxy(env, argv[INTEGER_ZERO], objName, methodList);
1595 return result;
1596 }
1597
DeleteJavaScriptRegister(napi_env env,napi_callback_info info)1598 napi_value NapiWebviewController::DeleteJavaScriptRegister(napi_env env, napi_callback_info info)
1599 {
1600 napi_value thisVar = nullptr;
1601 napi_value result = nullptr;
1602 size_t argc = INTEGER_ONE;
1603 napi_value argv[INTEGER_ONE] = { 0 };
1604
1605 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1606 if (argc != INTEGER_ONE) {
1607 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1608 return result;
1609 }
1610
1611 std::string objName;
1612 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], objName)) {
1613 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1614 return result;
1615 }
1616
1617 WebviewController *controller = nullptr;
1618 napi_unwrap(env, thisVar, (void **)&controller);
1619 if (!controller || !controller->IsInit()) {
1620 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1621 return result;
1622 }
1623 ErrCode ret = controller->DeleteJavaScriptRegister(objName, {});
1624 if (ret != NO_ERROR) {
1625 BusinessError::ThrowErrorByErrcode(env, ret);
1626 return result;
1627 }
1628
1629 NAPI_CALL(env, napi_get_undefined(env, &result));
1630 return result;
1631 }
1632
RunJavaScript(napi_env env,napi_callback_info info)1633 napi_value NapiWebviewController::RunJavaScript(napi_env env, napi_callback_info info)
1634 {
1635 napi_value thisVar = nullptr;
1636 napi_value result = nullptr;
1637 size_t argc = INTEGER_ONE;
1638 size_t argcPromise = INTEGER_ONE;
1639 size_t argcCallback = INTEGER_TWO;
1640 napi_value argv[INTEGER_TWO] = { 0 };
1641
1642 napi_get_undefined(env, &result);
1643 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1644
1645 if (argc != argcPromise && argc != argcCallback) {
1646 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1647 return result;
1648 }
1649 std::string script;
1650 if (!NapiParseUtils::ParseString(env, argv[INTEGER_ZERO], script)) {
1651 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1652 return result;
1653 }
1654
1655 if (argc == argcCallback) {
1656 napi_valuetype valueType = napi_null;
1657 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1658 napi_typeof(env, argv[argcCallback - 1], &valueType);
1659 if (valueType != napi_function) {
1660 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1661 return result;
1662 }
1663 }
1664 return RunJavaScriptInternal(env, info, script);
1665 }
1666
RunJavaScriptInternal(napi_env env,napi_callback_info info,const std::string & script)1667 napi_value NapiWebviewController::RunJavaScriptInternal(napi_env env, napi_callback_info info,
1668 const std::string &script)
1669 {
1670 napi_value thisVar = nullptr;
1671 size_t argc = INTEGER_ONE;
1672 size_t argcPromise = INTEGER_ONE;
1673 size_t argcCallback = INTEGER_TWO;
1674 napi_value argv[INTEGER_TWO] = {0};
1675
1676 napi_value result = nullptr;
1677 napi_get_undefined(env, &result);
1678 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1679
1680 WebviewController *webviewController = nullptr;
1681 napi_unwrap(env, thisVar, (void **)&webviewController);
1682
1683 if (!webviewController || !webviewController->IsInit()) {
1684 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1685 return result;
1686 }
1687
1688 if (argc == argcCallback) {
1689 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1690 napi_ref jsCallback = nullptr;
1691 napi_create_reference(env, argv[argcCallback - 1], 1, &jsCallback);
1692
1693 if (jsCallback) {
1694 webviewController->RunJavaScriptCallback(script, env, std::move(jsCallback));
1695 }
1696 return result;
1697 } else if (argc == argcPromise) {
1698 napi_deferred deferred = nullptr;
1699 napi_value promise = nullptr;
1700 napi_create_promise(env, &deferred, &promise);
1701 if (promise && deferred) {
1702 webviewController->RunJavaScriptPromise(script, env, deferred);
1703 }
1704 return promise;
1705 }
1706 return result;
1707 }
1708
GetUrl(napi_env env,napi_callback_info info)1709 napi_value NapiWebviewController::GetUrl(napi_env env, napi_callback_info info)
1710 {
1711 napi_value thisVar = nullptr;
1712 napi_value result = nullptr;
1713 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1714
1715 WebviewController *webviewController = nullptr;
1716 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1717 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1718 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1719 return nullptr;
1720 }
1721
1722 std::string url = "";
1723 url = webviewController->GetUrl();
1724 napi_create_string_utf8(env, url.c_str(), url.length(), &result);
1725
1726 return result;
1727 }
1728
GetOriginalUrl(napi_env env,napi_callback_info info)1729 napi_value NapiWebviewController::GetOriginalUrl(napi_env env, napi_callback_info info)
1730 {
1731 napi_value thisVar = nullptr;
1732 napi_value result = nullptr;
1733 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1734
1735 WebviewController *webviewController = nullptr;
1736 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1737 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1738 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1739 return nullptr;
1740 }
1741
1742 std::string url = "";
1743 url = webviewController->GetOriginalUrl();
1744 napi_create_string_utf8(env, url.c_str(), url.length(), &result);
1745 return result;
1746 }
1747
SetNetworkAvailable(napi_env env,napi_callback_info info)1748 napi_value NapiWebviewController::SetNetworkAvailable(napi_env env, napi_callback_info info)
1749 {
1750 napi_value thisVar = nullptr;
1751 napi_value result = nullptr;
1752 size_t argc = INTEGER_ONE;
1753 napi_value argv[INTEGER_ONE] = { 0 };
1754 bool enable;
1755
1756 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1757 if (argc != INTEGER_ONE) {
1758 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1759 return result;
1760 }
1761
1762 if (!NapiParseUtils::ParseBoolean(env, argv[0], enable)) {
1763 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1764 return result;
1765 }
1766
1767 WebviewController *webviewController = nullptr;
1768 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1769 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1770 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1771 return nullptr;
1772 }
1773 webviewController->PutNetworkAvailable(enable);
1774 return result;
1775 }
1776
InnerGetWebId(napi_env env,napi_callback_info info)1777 napi_value NapiWebviewController::InnerGetWebId(napi_env env, napi_callback_info info)
1778 {
1779 napi_value thisVar = nullptr;
1780 napi_value result = nullptr;
1781 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1782
1783 WebviewController *webviewController = nullptr;
1784 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1785 int32_t webId = -1;
1786 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1787 WVLOG_E("Init error. The WebviewController must be associated with a Web component.");
1788 napi_create_int32(env, webId, &result);
1789 return result;
1790 }
1791
1792 webId = webviewController->GetWebId();
1793 napi_create_int32(env, webId, &result);
1794
1795 return result;
1796 }
1797
HasImage(napi_env env,napi_callback_info info)1798 napi_value NapiWebviewController::HasImage(napi_env env, napi_callback_info info)
1799 {
1800 napi_value thisVar = nullptr;
1801 napi_value result = nullptr;
1802 size_t argc = INTEGER_ONE;
1803 size_t argcPromiseParaNum = INTEGER_ZERO;
1804 size_t argcCallbackParaNum = INTEGER_ONE;
1805 napi_value argv[INTEGER_ONE] = { 0 };
1806
1807 napi_get_undefined(env, &result);
1808 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1809
1810 if (argc != argcPromiseParaNum && argc != argcCallbackParaNum) {
1811 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
1812 return result;
1813 }
1814
1815 if (argc == argcCallbackParaNum) {
1816 napi_valuetype valueType = napi_null;
1817 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1818 napi_typeof(env, argv[argcCallbackParaNum - 1], &valueType);
1819 if (valueType != napi_function) {
1820 NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
1821 return result;
1822 }
1823 }
1824 return HasImageInternal(env, info);
1825 }
1826
HasImageInternal(napi_env env,napi_callback_info info)1827 napi_value NapiWebviewController::HasImageInternal(napi_env env, napi_callback_info info)
1828 {
1829 napi_value thisVar = nullptr;
1830 size_t argc = INTEGER_ONE;
1831 size_t argcPromiseParaNum = INTEGER_ZERO;
1832 size_t argcCallbackParaNum = INTEGER_ONE;
1833 napi_value argv[INTEGER_ONE] = { 0 };
1834
1835 napi_value result = nullptr;
1836 napi_get_undefined(env, &result);
1837 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1838
1839 WebviewController *webviewController = nullptr;
1840 napi_unwrap(env, thisVar, (void **)&webviewController);
1841
1842 if (!webviewController || !webviewController->IsInit()) {
1843 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1844 return result;
1845 }
1846
1847 if (argc == argcCallbackParaNum) {
1848 napi_ref jsCallback = nullptr;
1849 napi_create_reference(env, argv[argcCallbackParaNum - 1], 1, &jsCallback);
1850
1851 if (jsCallback) {
1852 ErrCode ret = webviewController->HasImagesCallback(env, std::move(jsCallback));
1853 if (ret != NO_ERROR) {
1854 if (ret == NWEB_ERROR) {
1855 return nullptr;
1856 }
1857 BusinessError::ThrowErrorByErrcode(env, ret);
1858 return nullptr;
1859 }
1860 }
1861 return result;
1862 } else if (argc == argcPromiseParaNum) {
1863 napi_deferred deferred = nullptr;
1864 napi_value promise = nullptr;
1865 napi_create_promise(env, &deferred, &promise);
1866 if (promise && deferred) {
1867 ErrCode ret = webviewController->HasImagesPromise(env, deferred);
1868 if (ret != NO_ERROR) {
1869 if (ret == NWEB_ERROR) {
1870 return nullptr;
1871 }
1872 BusinessError::ThrowErrorByErrcode(env, ret);
1873 return nullptr;
1874 }
1875 }
1876 return promise;
1877 }
1878 return result;
1879 }
1880
RemoveCache(napi_env env,napi_callback_info info)1881 napi_value NapiWebviewController::RemoveCache(napi_env env, napi_callback_info info)
1882 {
1883 napi_value thisVar = nullptr;
1884 napi_value result = nullptr;
1885 size_t argc = INTEGER_ONE;
1886 napi_value argv[INTEGER_ONE] = { 0 };
1887 bool include_disk_files;
1888
1889 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1890 if (argc != INTEGER_ONE) {
1891 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1892 return result;
1893 }
1894
1895 if (!NapiParseUtils::ParseBoolean(env, argv[0], include_disk_files)) {
1896 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
1897 return result;
1898 }
1899
1900 WebviewController *webviewController = nullptr;
1901 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
1902 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
1903 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
1904 return nullptr;
1905 }
1906 webviewController->RemoveCache(include_disk_files);
1907 return result;
1908 }
1909
JsConstructor(napi_env env,napi_callback_info info)1910 napi_value NapiWebHistoryList::JsConstructor(napi_env env, napi_callback_info info)
1911 {
1912 napi_value thisVar = nullptr;
1913 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1914 return thisVar;
1915 }
1916
getColorType(ImageColorType colorType)1917 Media::PixelFormat getColorType(ImageColorType colorType)
1918 {
1919 Media::PixelFormat pixelFormat_;
1920 switch (colorType) {
1921 case ImageColorType::COLOR_TYPE_UNKNOWN:
1922 pixelFormat_ = Media::PixelFormat::UNKNOWN;
1923 break;
1924 case ImageColorType::COLOR_TYPE_RGBA_8888:
1925 pixelFormat_ = Media::PixelFormat::RGBA_8888;
1926 break;
1927 case ImageColorType::COLOR_TYPE_BGRA_8888:
1928 pixelFormat_ = Media::PixelFormat::BGRA_8888;
1929 break;
1930 default:
1931 pixelFormat_ = Media::PixelFormat::UNKNOWN;
1932 break;
1933 }
1934 return pixelFormat_;
1935 }
1936
getAlphaType(ImageAlphaType alphaType)1937 Media::AlphaType getAlphaType(ImageAlphaType alphaType)
1938 {
1939 Media::AlphaType alphaType_;
1940 switch (alphaType) {
1941 case ImageAlphaType::ALPHA_TYPE_UNKNOWN:
1942 alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
1943 break;
1944 case ImageAlphaType::ALPHA_TYPE_OPAQUE:
1945 alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
1946 break;
1947 case ImageAlphaType::ALPHA_TYPE_PREMULTIPLIED:
1948 alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
1949 break;
1950 case ImageAlphaType::ALPHA_TYPE_POSTMULTIPLIED:
1951 alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
1952 break;
1953 default:
1954 alphaType_ = Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
1955 break;
1956 }
1957 return alphaType_;
1958 }
1959
GetFavicon(napi_env env,std::shared_ptr<NWebHistoryItem> item)1960 napi_value NapiWebHistoryList::GetFavicon(napi_env env, std::shared_ptr<NWebHistoryItem> item)
1961 {
1962 napi_value result = nullptr;
1963 void *data = nullptr;
1964 int32_t width = 0;
1965 int32_t height = 0;
1966 ImageColorType colorType = ImageColorType::COLOR_TYPE_UNKNOWN;
1967 ImageAlphaType alphaType = ImageAlphaType::ALPHA_TYPE_UNKNOWN;
1968 bool isGetFavicon = item->GetFavicon(&data, width, height, colorType, alphaType);
1969 napi_get_null(env, &result);
1970
1971 if (!isGetFavicon) {
1972 return result;
1973 }
1974
1975 Media::InitializationOptions opt;
1976 opt.size.width = width;
1977 opt.size.height = height;
1978 opt.pixelFormat = getColorType(colorType);
1979 opt.alphaType = getAlphaType(alphaType);
1980 opt.editable = true;
1981 auto pixelMap = Media::PixelMap::Create(opt);
1982 if (pixelMap == nullptr) {
1983 return result;
1984 }
1985 uint64_t stride = static_cast<uint64_t>(width) << 2;
1986 uint64_t bufferSize = stride * static_cast<uint64_t>(height);
1987 pixelMap->WritePixels(static_cast<const uint8_t *>(data), bufferSize);
1988 std::shared_ptr<Media::PixelMap> pixelMapToJs(pixelMap.release());
1989 napi_value jsPixelMap = OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelMapToJs);
1990 return jsPixelMap;
1991 }
1992
GetItem(napi_env env,napi_callback_info info)1993 napi_value NapiWebHistoryList::GetItem(napi_env env, napi_callback_info info)
1994 {
1995 napi_value thisVar = nullptr;
1996 napi_value result = nullptr;
1997 size_t argc = INTEGER_ONE;
1998 napi_value argv[INTEGER_ONE] = { 0 };
1999 int32_t index;
2000 WebHistoryList *historyList = nullptr;
2001
2002 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
2003 NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&historyList));
2004 if (historyList == nullptr) {
2005 WVLOG_E("unwrap historyList failed.");
2006 return result;
2007 }
2008 if (argc != INTEGER_ONE) {
2009 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2010 return result;
2011 }
2012 if (!NapiParseUtils::ParseInt32(env, argv[0], index)) {
2013 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2014 return result;
2015 }
2016 if (index >= historyList->GetListSize() || index < 0) {
2017 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2018 return result;
2019 }
2020
2021 std::shared_ptr<NWebHistoryItem> item = historyList->GetItem(index);
2022 if (!item) {
2023 return result;
2024 }
2025
2026 napi_create_object(env, &result);
2027 std::string historyUrl = item->GetHistoryUrl();
2028 std::string historyRawUrl = item->GetHistoryRawUrl();
2029 std::string title = item->GetHistoryTitle();
2030
2031 napi_value js_historyUrl;
2032 napi_create_string_utf8(env, historyUrl.c_str(), historyUrl.length(), &js_historyUrl);
2033 napi_set_named_property(env, result, "historyUrl", js_historyUrl);
2034
2035 napi_value js_historyRawUrl;
2036 napi_create_string_utf8(env, historyRawUrl.c_str(), historyRawUrl.length(), &js_historyRawUrl);
2037 napi_set_named_property(env, result, "historyRawUrl", js_historyRawUrl);
2038
2039 napi_value js_title;
2040 napi_create_string_utf8(env, title.c_str(), title.length(), &js_title);
2041 napi_set_named_property(env, result, "title", js_title);
2042
2043 napi_value js_icon = GetFavicon(env, item);
2044 napi_set_named_property(env, result, "icon", js_icon);
2045 return result;
2046 }
2047
getBackForwardEntries(napi_env env,napi_callback_info info)2048 napi_value NapiWebviewController::getBackForwardEntries(napi_env env, napi_callback_info info)
2049 {
2050 napi_value thisVar = nullptr;
2051 napi_value result = nullptr;
2052 WebviewController *webviewController = nullptr;
2053
2054 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
2055 NAPI_CALL(env, napi_unwrap(env, thisVar, (void **)&webviewController));
2056 if (webviewController == nullptr || !webviewController->IsInit()) {
2057 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2058 return nullptr;
2059 }
2060
2061 std::shared_ptr<NWebHistoryList> list = webviewController->GetHistoryList();
2062 if (!list) {
2063 return result;
2064 }
2065
2066 WebHistoryList *webHistoryList = new (std::nothrow) WebHistoryList(list);
2067 if (webHistoryList == nullptr) {
2068 return result;
2069 }
2070
2071 int32_t currentIndex = list->GetCurrentIndex();
2072 int32_t size = list->GetListSize();
2073
2074 napi_value historyList = nullptr;
2075 NAPI_CALL(env, napi_get_reference_value(env, g_historyListRef, &historyList));
2076 NAPI_CALL(env, napi_new_instance(env, historyList, 0, NULL, &result));
2077
2078 napi_value js_currentIndex;
2079 napi_create_int32(env, currentIndex, &js_currentIndex);
2080 napi_set_named_property(env, result, "currentIndex", js_currentIndex);
2081
2082 napi_value js_size;
2083 napi_create_int32(env, size, &js_size);
2084 napi_set_named_property(env, result, "size", js_size);
2085 NAPI_CALL(env, napi_wrap(env, result, webHistoryList,
2086 [](napi_env env, void *data, void *hint) {
2087 WebHistoryList *webHistoryList = static_cast<WebHistoryList *>(data);
2088 delete webHistoryList;
2089 },
2090 nullptr, nullptr));
2091
2092 return result;
2093 }
2094
GetFavicon(napi_env env,napi_callback_info info)2095 napi_value NapiWebviewController::GetFavicon(napi_env env, napi_callback_info info)
2096 {
2097 napi_value thisVar = nullptr;
2098 napi_value result = nullptr;
2099 napi_get_null(env, &result);
2100 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
2101
2102 WebviewController *webviewController = nullptr;
2103 napi_unwrap(env, thisVar, (void **)&webviewController);
2104
2105 if (!webviewController || !webviewController->IsInit()) {
2106 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2107 return result;
2108 }
2109
2110 const void *data = nullptr;
2111 size_t width = 0;
2112 size_t height = 0;
2113 ImageColorType colorType = ImageColorType::COLOR_TYPE_UNKNOWN;
2114 ImageAlphaType alphaType = ImageAlphaType::ALPHA_TYPE_UNKNOWN;
2115 bool isGetFavicon = webviewController->GetFavicon(&data, width, height, colorType, alphaType);
2116 if (!isGetFavicon) {
2117 return result;
2118 }
2119
2120 Media::InitializationOptions opt;
2121 opt.size.width = static_cast<int32_t>(width);
2122 opt.size.height = static_cast<int32_t>(height);
2123 opt.pixelFormat = getColorType(colorType);
2124 opt.alphaType = getAlphaType(alphaType);
2125 opt.editable = true;
2126 auto pixelMap = Media::PixelMap::Create(opt);
2127 if (pixelMap == nullptr) {
2128 return result;
2129 }
2130 uint64_t stride = static_cast<uint64_t>(width) << 2;
2131 uint64_t bufferSize = stride * static_cast<uint64_t>(height);
2132 pixelMap->WritePixels(static_cast<const uint8_t *>(data), bufferSize);
2133 std::shared_ptr<Media::PixelMap> pixelMapToJs(pixelMap.release());
2134 napi_value jsPixelMap = OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelMapToJs);
2135 return jsPixelMap;
2136 }
2137
SerializeWebState(napi_env env,napi_callback_info info)2138 napi_value NapiWebviewController::SerializeWebState(napi_env env, napi_callback_info info)
2139 {
2140 napi_value thisVar = nullptr;
2141 napi_value result = nullptr;
2142 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
2143 napi_get_null(env, &result);
2144
2145 WebviewController *webviewController = nullptr;
2146 napi_unwrap(env, thisVar, (void **)&webviewController);
2147 if (!webviewController || !webviewController->IsInit()) {
2148 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2149 return result;
2150 }
2151
2152 void *data = nullptr;
2153 napi_value buffer = nullptr;
2154 auto webState = webviewController->SerializeWebState();
2155 if (!webState) {
2156 return result;
2157 }
2158
2159 NAPI_CALL(env, napi_create_arraybuffer(env, webState->size(), &data, &buffer));
2160 int retCode = memcpy_s(data, webState->size(), webState->data(), webState->size());
2161 if (retCode != 0) {
2162 return result;
2163 }
2164 NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, webState->size(), buffer, 0, &result));
2165 return result;
2166 }
2167
RestoreWebState(napi_env env,napi_callback_info info)2168 napi_value NapiWebviewController::RestoreWebState(napi_env env, napi_callback_info info)
2169 {
2170 napi_value thisVar = nullptr;
2171 napi_value result = nullptr;
2172 size_t argc = INTEGER_ONE;
2173 napi_value argv[INTEGER_ONE] = { 0 };
2174 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
2175 napi_get_null(env, &result);
2176
2177 WebviewController *webviewController = nullptr;
2178 napi_unwrap(env, thisVar, (void **)&webviewController);
2179 if (!webviewController || !webviewController->IsInit()) {
2180 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2181 return result;
2182 }
2183
2184 bool isTypedArray = false;
2185 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2186 if (argc != INTEGER_ONE) {
2187 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2188 return result;
2189 }
2190 NAPI_CALL(env, napi_is_typedarray(env, argv[0], &isTypedArray));
2191 if (!isTypedArray) {
2192 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2193 return result;
2194 }
2195
2196 napi_typedarray_type type;
2197 size_t length = 0;
2198 napi_value buffer = nullptr;
2199 size_t offset = 0;
2200 NAPI_CALL(env, napi_get_typedarray_info(env, argv[0], &type, &length, nullptr, &buffer, &offset));
2201 if (type != napi_uint8_array) {
2202 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2203 return result;
2204 }
2205 uint8_t *data = nullptr;
2206 size_t total = 0;
2207 NAPI_CALL(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total));
2208 length = std::min<size_t>(length, total - offset);
2209 std::vector<uint8_t> state(length);
2210 int retCode = memcpy_s(state.data(), state.size(), &data[offset], length);
2211 if (retCode != 0) {
2212 return result;
2213 }
2214 webviewController->RestoreWebState(std::make_shared<std::vector<uint8_t>>(state));
2215 return result;
2216 }
2217
ScrollPageDown(napi_env env,napi_callback_info info)2218 napi_value NapiWebviewController::ScrollPageDown(napi_env env, napi_callback_info info)
2219 {
2220 napi_value thisVar = nullptr;
2221 napi_value result = nullptr;
2222 size_t argc = INTEGER_ONE;
2223 napi_value argv[INTEGER_ONE] = { 0 };
2224 bool bottom;
2225
2226 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2227 if (argc != INTEGER_ONE) {
2228 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2229 return result;
2230 }
2231
2232 if (!NapiParseUtils::ParseBoolean(env, argv[0], bottom)) {
2233 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2234 return result;
2235 }
2236
2237 WebviewController *webviewController = nullptr;
2238 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2239 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2240 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2241 return nullptr;
2242 }
2243 webviewController->ScrollPageDown(bottom);
2244 return result;
2245 }
2246
ScrollPageUp(napi_env env,napi_callback_info info)2247 napi_value NapiWebviewController::ScrollPageUp(napi_env env, napi_callback_info info)
2248 {
2249 napi_value thisVar = nullptr;
2250 napi_value result = nullptr;
2251 size_t argc = INTEGER_ONE;
2252 napi_value argv[INTEGER_ONE] = { 0 };
2253 bool top;
2254
2255 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2256 if (argc != INTEGER_ONE) {
2257 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2258 return result;
2259 }
2260
2261 if (!NapiParseUtils::ParseBoolean(env, argv[0], top)) {
2262 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2263 return result;
2264 }
2265
2266 WebviewController *webviewController = nullptr;
2267 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2268 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2269 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2270 return nullptr;
2271 }
2272 webviewController->ScrollPageUp(top);
2273 return result;
2274 }
2275
CheckSchemeName(const std::string & schemeName)2276 bool CheckSchemeName(const std::string& schemeName)
2277 {
2278 if (schemeName.empty() || schemeName.size() > MAX_CUSTOM_SCHEME_NAME_LENGTH) {
2279 WVLOG_E("Invalid scheme name length");
2280 return false;
2281 }
2282 for (auto it = schemeName.begin(); it != schemeName.end(); it++) {
2283 char chr = *it;
2284 if (!((chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9') ||
2285 (chr == '.') || (chr == '+') || (chr == '-'))) {
2286 WVLOG_E("invalid character %{public}c", chr);
2287 return false;
2288 }
2289 }
2290 return true;
2291 }
2292
CustomizeSchemes(napi_env env,napi_callback_info info)2293 napi_value NapiWebviewController::CustomizeSchemes(napi_env env, napi_callback_info info)
2294 {
2295 if (WebviewController::existNweb_) {
2296 WVLOG_E("There exist web component which has been already created.");
2297 }
2298
2299 napi_value result = nullptr;
2300 napi_value thisVar = nullptr;
2301 size_t argc = INTEGER_ONE;
2302 napi_value argv[INTEGER_ONE];
2303 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2304 if (argc != INTEGER_ONE) {
2305 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2306 return nullptr;
2307 }
2308 napi_value array = argv[INTEGER_ZERO];
2309 bool isArray = false;
2310 napi_is_array(env, array, &isArray);
2311 if (isArray) {
2312 std::string cmdLine;
2313 uint32_t arrayLength = INTEGER_ZERO;
2314 napi_get_array_length(env, array, &arrayLength);
2315 if (arrayLength > MAX_CUSTOM_SCHEME_SIZE) {
2316 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2317 return nullptr;
2318 }
2319 for (uint32_t i = 0; i < arrayLength; ++i) {
2320 std::string schemeName;
2321 bool isSupportCORS;
2322 bool isSupportFetch;
2323 napi_value schemeNameObj = nullptr;
2324 napi_value isSupportCORSObj = nullptr;
2325 napi_value isSupportFetchObj = nullptr;
2326 napi_value obj = nullptr;
2327 napi_get_element(env, array, i, &obj);
2328 if ((napi_get_named_property(env, obj, "schemeName", &schemeNameObj) != napi_ok) ||
2329 (napi_get_named_property(env, obj, "isSupportCORS", &isSupportCORSObj) != napi_ok) ||
2330 (napi_get_named_property(env, obj, "isSupportFetch", &isSupportFetchObj) != napi_ok)) {
2331 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2332 return nullptr;
2333 }
2334 NapiParseUtils::ParseString(env, schemeNameObj, schemeName);
2335 if (!CheckSchemeName(schemeName)) {
2336 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2337 return nullptr;
2338 }
2339 NapiParseUtils::ParseBoolean(env, isSupportCORSObj, isSupportCORS);
2340 NapiParseUtils::ParseBoolean(env, isSupportFetchObj, isSupportFetch);
2341 std::string corsCmdLine = isSupportCORS ? "1," : "0,";
2342 std::string fetchCmdLine = isSupportFetch ? "1;" : "0;";
2343 cmdLine.append(schemeName + "," + corsCmdLine + fetchCmdLine);
2344 }
2345 cmdLine.pop_back();
2346 WVLOG_I("Reg scheme cmdline %{public}s", cmdLine.c_str());
2347 WebviewController::customeSchemeCmdLine_ = cmdLine;
2348 } else {
2349 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2350 return nullptr;
2351 }
2352 NAPI_CALL(env, napi_get_undefined(env, &result));
2353 return result;
2354 }
2355
ScrollTo(napi_env env,napi_callback_info info)2356 napi_value NapiWebviewController::ScrollTo(napi_env env, napi_callback_info info)
2357 {
2358 napi_value thisVar = nullptr;
2359 napi_value result = nullptr;
2360 size_t argc = INTEGER_TWO;
2361 napi_value argv[INTEGER_TWO] = { 0 };
2362 float x;
2363 float y;
2364
2365 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2366 if (argc != INTEGER_TWO) {
2367 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2368 return result;
2369 }
2370
2371 if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ZERO], x)) {
2372 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2373 return result;
2374 }
2375
2376 if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ONE], y)) {
2377 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2378 return result;
2379 }
2380
2381 WebviewController *webviewController = nullptr;
2382 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2383 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2384 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2385 return nullptr;
2386 }
2387 webviewController->ScrollTo(x, y);
2388 return result;
2389 }
2390
ScrollBy(napi_env env,napi_callback_info info)2391 napi_value NapiWebviewController::ScrollBy(napi_env env, napi_callback_info info)
2392 {
2393 napi_value thisVar = nullptr;
2394 napi_value result = nullptr;
2395 size_t argc = INTEGER_TWO;
2396 napi_value argv[INTEGER_TWO] = { 0 };
2397 float deltaX;
2398 float deltaY;
2399
2400 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2401 if (argc != INTEGER_TWO) {
2402 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2403 return result;
2404 }
2405
2406 if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ZERO], deltaX)) {
2407 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2408 return result;
2409 }
2410
2411 if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ONE], deltaY)) {
2412 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2413 return result;
2414 }
2415
2416 WebviewController *webviewController = nullptr;
2417 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2418 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2419 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2420 return nullptr;
2421 }
2422 webviewController->ScrollBy(deltaX, deltaY);
2423 return result;
2424 }
2425
SlideScroll(napi_env env,napi_callback_info info)2426 napi_value NapiWebviewController::SlideScroll(napi_env env, napi_callback_info info)
2427 {
2428 napi_value thisVar = nullptr;
2429 napi_value result = nullptr;
2430 size_t argc = INTEGER_TWO;
2431 napi_value argv[INTEGER_TWO] = { 0 };
2432 float vx;
2433 float vy;
2434
2435 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2436 if (argc != INTEGER_TWO) {
2437 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2438 return result;
2439 }
2440
2441 if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ZERO], vx)) {
2442 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2443 return result;
2444 }
2445
2446 if (!NapiParseUtils::ParseFloat(env, argv[INTEGER_ONE], vy)) {
2447 BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR);
2448 return result;
2449 }
2450
2451 WebviewController *webviewController = nullptr;
2452 napi_status status = napi_unwrap(env, thisVar, (void **)&webviewController);
2453 if ((!webviewController) || (status != napi_ok) || !webviewController->IsInit()) {
2454 BusinessError::ThrowErrorByErrcode(env, INIT_ERROR);
2455 return nullptr;
2456 }
2457 webviewController->SlideScroll(vx, vy);
2458 return result;
2459 }
2460 } // namespace NWeb
2461 } // namespace OHOS
2462