• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, [&param] { 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