1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "frameworks/bridge/declarative_frontend/jsview/js_web_controller.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "base/utils/linear_map.h"
20 #include "base/utils/utils.h"
21 #include "bridge/declarative_frontend/engine/functions/js_webview_function.h"
22 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
23 #include "core/components_ng/base/view_stack_processor.h"
24 
25 namespace OHOS::Ace::Framework {
26 namespace {
ToJsValueHelper(const EcmaVM * vm,std::shared_ptr<WebJSValue> argument)27 panda::Local<panda::JSValueRef> ToJsValueHelper(const EcmaVM* vm, std::shared_ptr<WebJSValue> argument)
28 {
29     if (!argument || !vm) {
30         TAG_LOGE(AceLogTag::ACE_WEB, "ToJsValueHelper: argument or vm is null");
31         return panda::JSValueRef::Undefined(vm);
32     }
33     switch (argument->GetType()) {
34         case WebJSValue::Type::INTEGER:
35             return ToJSValue(argument->GetInt());
36         case WebJSValue::Type::DOUBLE:
37             return ToJSValue(argument->GetDouble());
38         case WebJSValue::Type::BOOLEAN:
39             return ToJSValue(argument->GetBoolean());
40         case WebJSValue::Type::STRING:
41             return ToJSValue(argument->GetString());
42         case WebJSValue::Type::LIST: {
43             size_t length = argument->GetListValueSize();
44             auto arr = panda::ArrayRef::New(vm, length);
45             for (size_t i = 0; i < length; ++i) {
46                 auto nPtr = std::make_shared<WebJSValue>(argument->GetListValue(i));
47                 if (!panda::ArrayRef::SetValueAt(vm, arr, i, ToJsValueHelper(vm, nPtr))) {
48                     TAG_LOGE(AceLogTag::ACE_WEB, "ToJsValueHelper: SetValueAt api call failed");
49                     return panda::JSValueRef::Undefined(vm);
50                 }
51             }
52             return arr;
53         }
54         case WebJSValue::Type::DICTIONARY: {
55             auto obj = panda::ObjectRef::New(vm);
56             auto dict = argument->GetDictionaryValue();
57             for (auto& item : dict) {
58                 auto nPtr = std::make_shared<WebJSValue>(item.second);
59                 obj->Set(vm, panda::StringRef::NewFromUtf8(vm, item.first.c_str()), ToJsValueHelper(vm, nPtr));
60             }
61             return obj;
62         }
63         case WebJSValue::Type::BINARY: {
64             auto size = argument->GetBinaryValueSize();
65             auto buff = argument->GetBinaryValue();
66             return panda::ArrayBufferRef::New(vm, (void*)buff, (int32_t)size, nullptr, (void*)buff);
67         }
68         case WebJSValue::Type::NONE:
69             return panda::JSValueRef::Undefined(vm);
70         default:
71             TAG_LOGE(AceLogTag::ACE_WEB, "ToJsValueHelper: jsvalue type not support!");
72             break;
73     }
74     return panda::JSValueRef::Undefined(vm);
75 }
76 
ParseWebViewValueToJsValue(std::shared_ptr<WebJSValue> value,std::vector<JSRef<JSVal>> & argv)77 void ParseWebViewValueToJsValue(std::shared_ptr<WebJSValue> value, std::vector<JSRef<JSVal>>& argv)
78 {
79     if (!value) {
80         return;
81     }
82     auto vm = GetEcmaVm();
83     argv.push_back(JSRef<JSVal>::Make(ToJsValueHelper(vm, value)));
84 }
85 
ParseValue(const JSRef<JSVal> & resultValue,std::shared_ptr<WebJSValue> webviewValue)86 std::shared_ptr<WebJSValue> ParseValue(const JSRef<JSVal>& resultValue, std::shared_ptr<WebJSValue> webviewValue)
87 {
88     if (!webviewValue) {
89         TAG_LOGE(AceLogTag::ACE_WEB, "ParseValue: webviewValue or resultValue is null");
90         return std::make_shared<WebJSValue>();
91     }
92 
93     webviewValue->error_ = static_cast<int>(WebJavaScriptBridgeError::NO_ERROR);
94     if (resultValue->IsBoolean()) {
95         webviewValue->SetType(WebJSValue::Type::BOOLEAN);
96         webviewValue->SetBoolean(resultValue->ToBoolean());
97     } else if (resultValue->IsNull()) {
98         webviewValue->SetType(WebJSValue::Type::NONE);
99     } else if (resultValue->IsString()) {
100         webviewValue->SetType(WebJSValue::Type::STRING);
101         webviewValue->SetString(resultValue->ToString());
102     } else if (resultValue->IsNumber()) {
103         webviewValue->SetType(WebJSValue::Type::DOUBLE);
104         webviewValue->SetDouble(resultValue->ToNumber<double>());
105     } else if (resultValue->IsArray()) {
106         webviewValue->SetType(WebJSValue::Type::LIST);
107         JSRef<JSArray> array = JSRef<JSArray>::Cast(resultValue);
108         for (size_t i = 0; i < array->Length(); i++) {
109             JSRef<JSVal> value = array->GetValueAt(i);
110             auto nVal = std::make_shared<WebJSValue>();
111             webviewValue->AddListValue(*ParseValue(value, nVal));
112         }
113     } else if (resultValue->IsObject()) {
114         webviewValue->SetType(WebJSValue::Type::DICTIONARY);
115         JSRef<JSObject> dic = JSRef<JSObject>::Cast(resultValue);
116         auto names = dic->GetPropertyNames();
117         for (size_t i = 0; i < names->Length(); i++) {
118             JSRef<JSVal> key = names->GetValueAt(i);
119             if (!(key->IsString())) {
120                 continue;
121             }
122             JSRef<JSVal> property = dic->GetProperty(key->ToString().c_str());
123             auto nwebValueTmp = std::make_shared<WebJSValue>();
124             auto nwebKeyTmp = std::make_shared<WebJSValue>();
125             ParseValue(key, nwebKeyTmp);
126             ParseValue(property, nwebValueTmp);
127             webviewValue->AddDictionaryValue(nwebKeyTmp->GetString(), *nwebValueTmp);
128         }
129     } else if (resultValue->IsFunction()) {
130         TAG_LOGE(AceLogTag::ACE_WEB, "ParseValue: object is not supported");
131         webviewValue->SetType(WebJSValue::Type::NONE);
132     } else if (resultValue->IsUndefined()) {
133         webviewValue->SetType(WebJSValue::Type::NONE);
134         webviewValue->error_ = static_cast<int>(WebJavaScriptBridgeError::OBJECT_IS_GONE);
135     }
136     return webviewValue;
137 }
138 } // namespace
139 
140 class JSWebCookie : public Referenced {
141 public:
JSBind(BindingTarget globalObj)142     static void JSBind(BindingTarget globalObj)
143     {
144         JSClass<JSWebCookie>::Declare("WebCookie");
145         JSClass<JSWebCookie>::CustomMethod("setCookie", &JSWebCookie::SetCookie);
146         JSClass<JSWebCookie>::CustomMethod("getCookie", &JSWebCookie::GetCookie);
147         JSClass<JSWebCookie>::CustomMethod("deleteEntireCookie", &JSWebCookie::DeleteEntirelyCookie);
148         JSClass<JSWebCookie>::CustomMethod("saveCookie", &JSWebCookie::SaveCookieSync);
149         JSClass<JSWebCookie>::Bind(globalObj, JSWebCookie::Constructor, JSWebCookie::Destructor);
150     }
151 
SetWebCookie(WebCookie * manager)152     void SetWebCookie(WebCookie* manager)
153     {
154         if (manager != nullptr) {
155             manager_ = manager;
156         }
157     }
158 
SetCookie(const JSCallbackInfo & args)159     void SetCookie(const JSCallbackInfo& args)
160     {
161         std::string url;
162         std::string value;
163         bool result = false;
164         if (args.Length() >= 2 && args[0]->IsString() && args[1]->IsString()) {
165             url = args[0]->ToString();
166             value = args[1]->ToString();
167             if (manager_ != nullptr) {
168                 result = manager_->SetCookie(url, value);
169             }
170         }
171         auto jsVal = JSVal(ToJSValue(result));
172         auto returnValue = JSRef<JSVal>::Make(jsVal);
173         args.SetReturnValue(returnValue);
174     }
175 
GetCookie(const JSCallbackInfo & args)176     void GetCookie(const JSCallbackInfo& args)
177     {
178         std::string result = "";
179         if (manager_ != nullptr && args.Length() >= 1 && args[0]->IsString()) {
180             std::string url = args[0]->ToString();
181             result = manager_->GetCookie(url);
182         }
183         auto jsVal = JSVal(ToJSValue(result));
184         auto returnValue = JSRef<JSVal>::Make(jsVal);
185         args.SetReturnValue(returnValue);
186     }
187 
DeleteEntirelyCookie(const JSCallbackInfo & args)188     void DeleteEntirelyCookie(const JSCallbackInfo& args)
189     {
190         if (manager_ == nullptr) {
191             return;
192         }
193         manager_->DeleteEntirelyCookie();
194     }
195 
SaveCookieSync(const JSCallbackInfo & args)196     void SaveCookieSync(const JSCallbackInfo& args)
197     {
198         bool result = false;
199         if (manager_ != nullptr) {
200             result = manager_->SaveCookieSync();
201         }
202         auto jsVal = JSVal(ToJSValue(result));
203         auto returnValue = JSRef<JSVal>::Make(jsVal);
204         args.SetReturnValue(returnValue);
205     }
206 
207 private:
Constructor(const JSCallbackInfo & args)208     static void Constructor(const JSCallbackInfo& args)
209     {
210         auto jsWebCookie = Referenced::MakeRefPtr<JSWebCookie>();
211         jsWebCookie->IncRefCount();
212         args.SetReturnValue(Referenced::RawPtr(jsWebCookie));
213     }
214 
Destructor(JSWebCookie * jsWebCookie)215     static void Destructor(JSWebCookie* jsWebCookie)
216     {
217         if (jsWebCookie != nullptr) {
218             jsWebCookie->DecRefCount();
219         }
220     }
221     WebCookie* manager_;
222 };
223 
224 class JSHitTestValue : public Referenced {
225 public:
JSBind(BindingTarget globalObj)226     static void JSBind(BindingTarget globalObj)
227     {
228         JSClass<JSHitTestValue>::Declare("HitTestValue");
229         JSClass<JSHitTestValue>::CustomMethod("getType", &JSHitTestValue::GetType);
230         JSClass<JSHitTestValue>::CustomMethod("getExtra", &JSHitTestValue::GetExtra);
231         JSClass<JSHitTestValue>::Bind(globalObj, JSHitTestValue::Constructor, JSHitTestValue::Destructor);
232     }
233 
SetType(int type)234     void SetType(int type)
235     {
236         type_ = type;
237     }
238 
SetExtra(const std::string & extra)239     void SetExtra(const std::string& extra)
240     {
241         extra_ = extra;
242     }
243 
GetType(const JSCallbackInfo & args)244     void GetType(const JSCallbackInfo& args)
245     {
246         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(type_)));
247     }
248 
GetExtra(const JSCallbackInfo & args)249     void GetExtra(const JSCallbackInfo& args)
250     {
251         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(extra_)));
252     }
253 
254 private:
Constructor(const JSCallbackInfo & args)255     static void Constructor(const JSCallbackInfo& args)
256     {
257         auto jSHitTestResult = Referenced::MakeRefPtr<JSHitTestValue>();
258         jSHitTestResult->IncRefCount();
259         args.SetReturnValue(Referenced::RawPtr(jSHitTestResult));
260     }
261 
Destructor(JSHitTestValue * jSHitTestResult)262     static void Destructor(JSHitTestValue* jSHitTestResult)
263     {
264         if (jSHitTestResult != nullptr) {
265             jSHitTestResult->DecRefCount();
266         }
267     }
268 
269     std::string extra_;
270     int type_ = static_cast<int>(WebHitTestType::UNKNOWN);
271 };
272 
JSWebController()273 JSWebController::JSWebController()
274 {
275     instanceId_ = Container::CurrentId();
276 }
277 
GetJavaScriptResult(const std::string & objectName,const std::string & objectMethod,const std::vector<std::shared_ptr<WebJSValue>> & args)278 std::shared_ptr<WebJSValue> JSWebController::GetJavaScriptResult(const std::string& objectName,
279     const std::string& objectMethod, const std::vector<std::shared_ptr<WebJSValue>>& args)
280 {
281     std::vector<JSRef<JSVal>> argv = {};
282     std::shared_ptr<WebJSValue> jsResult = std::make_shared<WebJSValue>(WebJSValue::Type::NONE);
283     auto iter = objectorMap_.find(objectName);
284     if (iter == objectorMap_.end()) {
285         return jsResult;
286     }
287     auto jsObject = iter->second;
288     if (jsObject->IsEmpty()) {
289         return jsResult;
290     }
291     for (std::shared_ptr<WebJSValue> input : args) {
292         ParseWebViewValueToJsValue(input, argv);
293     }
294 
295     if (jsObject->GetProperty(objectMethod.c_str())->IsEmpty() ||
296         !(jsObject->GetProperty(objectMethod.c_str())->IsFunction())) {
297         return jsResult;
298     }
299 
300     JSRef<JSFunc> func = JSRef<JSFunc>::Cast(jsObject->GetProperty(objectMethod.c_str()));
301     if (func->IsEmpty()) {
302         jsResult->error_ = static_cast<int>(WebJavaScriptBridgeError::OBJECT_IS_GONE);
303         return jsResult;
304     }
305     JSRef<JSVal> result = argv.empty() ? func->Call(jsObject, 0, {}) : func->Call(jsObject, argv.size(), &argv[0]);
306     return ParseValue(result, jsResult);
307 }
308 
309 class JSWebMessageEvent;
310 class JSWebMessagePort : public Referenced {
311 public:
JSBind(BindingTarget globalObj)312     static void JSBind(BindingTarget globalObj)
313     {
314         JSClass<JSWebMessagePort>::Declare("WebMessagePort");
315         JSClass<JSWebMessagePort>::CustomMethod("close", &JSWebMessagePort::Close);
316         JSClass<JSWebMessagePort>::CustomMethod("postMessageEvent", &JSWebMessagePort::PostMessage);
317         JSClass<JSWebMessagePort>::CustomMethod("onMessageEvent", &JSWebMessagePort::SetWebMessageCallback);
318         JSClass<JSWebMessagePort>::Bind(globalObj, JSWebMessagePort::Constructor, JSWebMessagePort::Destructor);
319     }
320 
321     void PostMessage(const JSCallbackInfo& args);
322 
Close(const JSCallbackInfo & args)323     void Close(const JSCallbackInfo& args)
324     {
325         if (port_ != nullptr) {
326             port_->Close();
327         }
328     }
329 
SetWebMessageCallback(const JSCallbackInfo & args)330     void SetWebMessageCallback(const JSCallbackInfo& args)
331     {
332         if (args.Length() < 1 || !args[0]->IsObject()) {
333             return;
334         }
335 
336         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
337         JSRef<JSVal> tsCallback = JSRef<JSVal>::Cast(obj);
338         std::function<void(std::string)> callback = nullptr;
339         if (tsCallback->IsFunction()) {
340             auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
341             auto jsCallback = AceType::MakeRefPtr<JsWebViewFunction>(JSRef<JSFunc>::Cast(tsCallback));
342             callback = [execCtx = args.GetExecutionContext(), func = std::move(jsCallback), node = frameNode](
343                             std::string result) {
344                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
345                 ACE_SCORING_EVENT("onMessageEvent CallBack");
346                 auto pipelineContext = PipelineContext::GetCurrentContext();
347                 CHECK_NULL_VOID(pipelineContext);
348                 pipelineContext->UpdateCurrentActiveNode(node);
349                 func->Execute(result);
350             };
351             if (port_ != nullptr) {
352                 port_->SetWebMessageCallback(std::move(callback));
353             }
354         }
355     }
356 
SetWebMessagePort(const RefPtr<WebMessagePort> & port)357     void SetWebMessagePort(const RefPtr<WebMessagePort>& port)
358     {
359         port_ = port;
360     }
361 
GetWebMessagePort()362     RefPtr<WebMessagePort> GetWebMessagePort()
363     {
364         return port_;
365     }
366 
367 private:
368     RefPtr<WebMessagePort> port_;
369 
Constructor(const JSCallbackInfo & args)370     static void Constructor(const JSCallbackInfo& args)
371     {
372         auto jsWebMessagePort = Referenced::MakeRefPtr<JSWebMessagePort>();
373         jsWebMessagePort->IncRefCount();
374         args.SetReturnValue(Referenced::RawPtr(jsWebMessagePort));
375     }
376 
Destructor(JSWebMessagePort * jsWebMessagePort)377     static void Destructor(JSWebMessagePort* jsWebMessagePort)
378     {
379         if (jsWebMessagePort != nullptr) {
380             jsWebMessagePort->DecRefCount();
381         }
382     }
383 };
384 
385 class JSWebMessageEvent : public Referenced {
386 public:
JSBind(BindingTarget globalObj)387     static void JSBind(BindingTarget globalObj)
388     {
389         JSClass<JSWebMessageEvent>::Declare("WebMessageEvent");
390         JSClass<JSWebMessageEvent>::CustomMethod("getData", &JSWebMessageEvent::GetData);
391         JSClass<JSWebMessageEvent>::CustomMethod("setData", &JSWebMessageEvent::SetData);
392         JSClass<JSWebMessageEvent>::CustomMethod("getPorts", &JSWebMessageEvent::GetPorts);
393         JSClass<JSWebMessageEvent>::CustomMethod("setPorts", &JSWebMessageEvent::SetPorts);
394         JSClass<JSWebMessageEvent>::Bind(globalObj, JSWebMessageEvent::Constructor, JSWebMessageEvent::Destructor);
395     }
396 
GetData(const JSCallbackInfo & args)397     void GetData(const JSCallbackInfo& args)
398     {
399         auto jsVal = JSVal(ToJSValue(data_));
400         auto retVal = JSRef<JSVal>::Make(jsVal);
401         args.SetReturnValue(retVal);
402     }
403 
SetData(const JSCallbackInfo & args)404     void SetData(const JSCallbackInfo& args)
405     {
406         if (args.Length() < 1 || !args[0]->IsString()) {
407             return;
408         }
409         data_ = args[0]->ToString();
410     }
411 
SetPorts(const JSCallbackInfo & args)412     void SetPorts(const JSCallbackInfo& args)
413     {
414         if (args.Length() <= 0) {
415             return;
416         }
417         if (!args[0]->IsArray()) {
418             return;
419         }
420         JSRef<JSArray> jsPorts = JSRef<JSArray>::Cast(args[0]);
421         std::vector<RefPtr<WebMessagePort>> sendPorts;
422         if (jsPorts->IsArray()) {
423             JSRef<JSArray> array = JSRef<JSArray>::Cast(jsPorts);
424             for (size_t i = 0; i < array->Length(); i++) {
425                 JSRef<JSVal> jsValue = array->GetValueAt(i);
426                 if (!jsValue->IsObject()) {
427                     continue;
428                 }
429                 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
430                 RefPtr<JSWebMessagePort> jswebPort = Referenced::Claim(jsObj->Unwrap<JSWebMessagePort>());
431                 if (jswebPort) {
432                     ports_.push_back(jswebPort);
433                 }
434             }
435         }
436     }
437 
GetPorts(const JSCallbackInfo & args)438     void GetPorts(const JSCallbackInfo& args)
439     {
440         JSRef<JSArray> jsPorts = JSRef<JSArray>::New();
441         JSRef<JSObject> jsObj;
442         RefPtr<JSWebMessagePort> jswebPort;
443         for (size_t i = 0; i < ports_.size(); i++) {
444             jsObj = JSClass<JSWebMessagePort>::NewInstance();
445             jswebPort = Referenced::Claim(jsObj->Unwrap<JSWebMessagePort>());
446             jswebPort->SetWebMessagePort(ports_[i]->GetWebMessagePort());
447             jsPorts->SetValueAt(i, jsObj);
448         }
449         args.SetReturnValue(jsPorts);
450     }
451 
GetDataInternal()452     std::string GetDataInternal()
453     {
454         return data_;
455     }
456 
GetPortsInternal()457     std::vector<RefPtr<JSWebMessagePort>> GetPortsInternal()
458     {
459         return ports_;
460     }
461 
462 private:
463     std::string data_;
464     std::vector<RefPtr<JSWebMessagePort>> ports_;
465 
Constructor(const JSCallbackInfo & args)466     static void Constructor(const JSCallbackInfo& args)
467     {
468         auto jsWebMessageEvent = Referenced::MakeRefPtr<JSWebMessageEvent>();
469         jsWebMessageEvent->IncRefCount();
470         args.SetReturnValue(Referenced::RawPtr(jsWebMessageEvent));
471     }
472 
Destructor(JSWebMessageEvent * jsWebMessageEvent)473     static void Destructor(JSWebMessageEvent* jsWebMessageEvent)
474     {
475         if (jsWebMessageEvent != nullptr) {
476             jsWebMessageEvent->DecRefCount();
477         }
478     }
479 };
480 
PostMessage(const JSCallbackInfo & args)481 void JSWebMessagePort::PostMessage(const JSCallbackInfo& args)
482 {
483     if (args.Length() <= 0 || !(args[0]->IsObject())) {
484         return;
485     }
486     // get ports
487     JSRef<JSVal> jsPorts = JSRef<JSVal>::Cast(args[0]);
488     if (!jsPorts->IsObject()) {
489         return;
490     }
491     auto jsRes = Referenced::Claim(JSRef<JSObject>::Cast(jsPorts)->Unwrap<JSWebMessageEvent>());
492     std::string data = jsRes->GetDataInternal();
493     if (port_) {
494         port_->PostMessage(data);
495     }
496 }
497 
JSBind(BindingTarget globalObj)498 void JSWebController::JSBind(BindingTarget globalObj)
499 {
500     JSClass<JSWebController>::Declare("WebController");
501     JSClass<JSWebController>::CustomMethod("loadUrl", &JSWebController::LoadUrl);
502     JSClass<JSWebController>::CustomMethod("runJavaScript", &JSWebController::ExecuteTypeScript);
503     JSClass<JSWebController>::CustomMethod("refresh", &JSWebController::Refresh);
504     JSClass<JSWebController>::CustomMethod("stop", &JSWebController::StopLoading);
505     JSClass<JSWebController>::CustomMethod("getHitTest", &JSWebController::GetHitTestResult);
506     JSClass<JSWebController>::CustomMethod("registerJavaScriptProxy", &JSWebController::AddJavascriptInterface);
507     JSClass<JSWebController>::CustomMethod("deleteJavaScriptRegister", &JSWebController::RemoveJavascriptInterface);
508     JSClass<JSWebController>::CustomMethod("onInactive", &JSWebController::OnInactive);
509     JSClass<JSWebController>::CustomMethod("onActive", &JSWebController::OnActive);
510     JSClass<JSWebController>::CustomMethod("zoom", &JSWebController::Zoom);
511     JSClass<JSWebController>::CustomMethod("requestFocus", &JSWebController::RequestFocus);
512     JSClass<JSWebController>::CustomMethod("loadData", &JSWebController::LoadDataWithBaseUrl);
513     JSClass<JSWebController>::CustomMethod("backward", &JSWebController::Backward);
514     JSClass<JSWebController>::CustomMethod("forward", &JSWebController::Forward);
515     JSClass<JSWebController>::CustomMethod("accessStep", &JSWebController::AccessStep);
516     JSClass<JSWebController>::CustomMethod("accessForward", &JSWebController::AccessForward);
517     JSClass<JSWebController>::CustomMethod("accessBackward", &JSWebController::AccessBackward);
518     JSClass<JSWebController>::CustomMethod("clearHistory", &JSWebController::ClearHistory);
519     JSClass<JSWebController>::CustomMethod("clearSslCache", &JSWebController::ClearSslCache);
520     JSClass<JSWebController>::CustomMethod(
521         "clearClientAuthenticationCache", &JSWebController::ClearClientAuthenticationCache);
522     JSClass<JSWebController>::CustomMethod("getCookieManager", &JSWebController::GetCookieManager);
523     JSClass<JSWebController>::CustomMethod("getHitTestValue", &JSWebController::GetHitTestValue);
524     JSClass<JSWebController>::CustomMethod("backOrForward", &JSWebController::BackOrForward);
525     JSClass<JSWebController>::CustomMethod("zoomIn", &JSWebController::ZoomIn);
526     JSClass<JSWebController>::CustomMethod("zoomOut", &JSWebController::ZoomOut);
527     JSClass<JSWebController>::CustomMethod("getPageHeight", &JSWebController::GetPageHeight);
528     JSClass<JSWebController>::CustomMethod("getTitle", &JSWebController::GetTitle);
529     JSClass<JSWebController>::CustomMethod("createWebMessagePorts", &JSWebController::CreateWebMessagePorts);
530     JSClass<JSWebController>::CustomMethod("postMessage", &JSWebController::PostWebMessage);
531     JSClass<JSWebController>::CustomMethod("getWebId", &JSWebController::GetWebId);
532     JSClass<JSWebController>::CustomMethod("getDefaultUserAgent", &JSWebController::GetDefaultUserAgent);
533     JSClass<JSWebController>::CustomMethod("searchAllAsync", &JSWebController::SearchAllAsync);
534     JSClass<JSWebController>::CustomMethod("clearMatches", &JSWebController::ClearMatches);
535     JSClass<JSWebController>::CustomMethod("searchNext", &JSWebController::SearchNext);
536     JSClass<JSWebController>::CustomMethod("getUrl", &JSWebController::GetUrl);
537     JSClass<JSWebController>::Bind(globalObj, JSWebController::Constructor, JSWebController::Destructor);
538     JSWebCookie::JSBind(globalObj);
539     JSHitTestValue::JSBind(globalObj);
540     JSWebMessagePort::JSBind(globalObj);
541     JSWebMessageEvent::JSBind(globalObj);
542 }
543 
Constructor(const JSCallbackInfo & args)544 void JSWebController::Constructor(const JSCallbackInfo& args)
545 {
546     auto webController = Referenced::MakeRefPtr<JSWebController>();
547     webController->IncRefCount();
548     RefPtr<WebController> controller = AceType::MakeRefPtr<WebController>();
549     webController->SetController(controller);
550     args.SetReturnValue(Referenced::RawPtr(webController));
551 }
552 
Destructor(JSWebController * webController)553 void JSWebController::Destructor(JSWebController* webController)
554 {
555     if (webController != nullptr) {
556         webController->DecRefCount();
557     }
558 }
559 
Reload() const560 void JSWebController::Reload() const
561 {
562     if (webController_) {
563         webController_->Reload();
564     }
565 }
566 
CreateWebMessagePorts(const JSCallbackInfo & args)567 void JSWebController::CreateWebMessagePorts(const JSCallbackInfo& args)
568 {
569     ContainerScope scope(instanceId_);
570     if (webController_) {
571         std::vector<RefPtr<WebMessagePort>> ports;
572         webController_->CreateMsgPorts(ports);
573         JSRef<JSObject> jsPort0 = JSClass<JSWebMessagePort>::NewInstance();
574         auto port0 = Referenced::Claim(jsPort0->Unwrap<JSWebMessagePort>());
575         port0->SetWebMessagePort(ports.at(0));
576 
577         JSRef<JSObject> jsPort1 = JSClass<JSWebMessagePort>::NewInstance();
578         auto port1 = Referenced::Claim(jsPort1->Unwrap<JSWebMessagePort>());
579         port1->SetWebMessagePort(ports.at(1));
580 
581         JSRef<JSArray> result = JSRef<JSArray>::New();
582         result->SetValueAt(0, jsPort0);
583         result->SetValueAt(1, jsPort1);
584         args.SetReturnValue(result);
585     }
586 }
587 
PostWebMessage(const JSCallbackInfo & args)588 void JSWebController::PostWebMessage(const JSCallbackInfo& args)
589 {
590     if (args.Length() < 1 || !args[0]->IsObject()) {
591         return;
592     }
593 
594     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
595     std::string uri;
596     if (!ConvertFromJSValue(obj->GetProperty("uri"), uri)) {
597         return;
598     }
599 
600     JSRef<JSVal> jsPorts = obj->GetProperty("message");
601     if (!jsPorts->IsObject()) {
602         return;
603     }
604     auto jsRes = Referenced::Claim(JSRef<JSObject>::Cast(jsPorts)->Unwrap<JSWebMessageEvent>());
605     std::string eventData = jsRes->GetDataInternal();
606     std::vector<RefPtr<JSWebMessagePort>> eventPorts = jsRes->GetPortsInternal();
607     std::vector<RefPtr<WebMessagePort>> sendPorts;
608     for (auto jsport : eventPorts) {
609         auto webPort = jsport->GetWebMessagePort();
610         if (webPort) {
611             sendPorts.push_back(webPort);
612         }
613     }
614 
615     if (webController_ && sendPorts.size() >= 1) {
616         webController_->PostWebMessage(eventData, sendPorts, uri);
617     }
618 }
619 
LoadUrl(const JSCallbackInfo & args)620 void JSWebController::LoadUrl(const JSCallbackInfo& args)
621 {
622     ContainerScope scope(instanceId_);
623     if (args.Length() < 1 || !args[0]->IsObject()) {
624         return;
625     }
626 
627     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
628     JSRef<JSVal> valUrl = obj->GetProperty("url");
629     std::string url;
630     if (valUrl->IsObject()) {
631         // same as src process of JSWeb::Create
632         std::string webSrc;
633         if (!JSViewAbstract::ParseJsMedia(valUrl, webSrc)) {
634             return;
635         }
636         auto np = webSrc.find_first_of("/");
637         url = (np == std::string::npos) ? webSrc : webSrc.erase(np, 1);
638     } else if (!ConvertFromJSValue(valUrl, url)) {
639         return;
640     }
641 
642     JSRef<JSVal> headers = obj->GetProperty("headers");
643     std::map<std::string, std::string> httpHeaders;
644     if (headers->IsArray()) {
645         JSRef<JSArray> array = JSRef<JSArray>::Cast(headers);
646         for (size_t i = 0; i < array->Length(); i++) {
647             JSRef<JSVal> jsValue = array->GetValueAt(i);
648             if (!jsValue->IsObject()) {
649                 continue;
650             }
651             JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
652             std::string key;
653             if (!ConvertFromJSValue(obj->GetProperty("headerKey"), key)) {
654                 continue;
655             }
656             std::string value;
657             if (!ConvertFromJSValue(obj->GetProperty("headerValue"), value)) {
658                 continue;
659             }
660             httpHeaders[key] = value;
661         }
662     }
663     if (webController_) {
664         webController_->LoadUrl(url, httpHeaders);
665     }
666 }
667 
ExecuteTypeScript(const JSCallbackInfo & args)668 void JSWebController::ExecuteTypeScript(const JSCallbackInfo& args)
669 {
670     ContainerScope scope(instanceId_);
671     if (args.Length() < 1 || !args[0]->IsObject()) {
672         return;
673     }
674 
675     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
676     std::string script;
677     if (!ConvertFromJSValue(obj->GetProperty("script"), script)) {
678         return;
679     }
680     JSRef<JSVal> tsCallback = obj->GetProperty("callback");
681     std::function<void(std::string)> callback = nullptr;
682     if (tsCallback->IsFunction()) {
683         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
684         auto jsCallback = AceType::MakeRefPtr<JsWebViewFunction>(JSRef<JSFunc>::Cast(tsCallback));
685         callback = [execCtx = args.GetExecutionContext(), func = std::move(jsCallback), node = frameNode](
686                         std::string result) {
687             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
688             ACE_SCORING_EVENT("ExecuteTypeScript CallBack");
689             auto pipelineContext = PipelineContext::GetCurrentContext();
690             CHECK_NULL_VOID(pipelineContext);
691             pipelineContext->UpdateCurrentActiveNode(node);
692             func->Execute(result);
693         };
694     }
695     if (webController_) {
696         webController_->ExecuteTypeScript(script, std::move(callback));
697     }
698 }
699 
LoadDataWithBaseUrl(const JSCallbackInfo & args)700 void JSWebController::LoadDataWithBaseUrl(const JSCallbackInfo& args)
701 {
702     ContainerScope scope(instanceId_);
703     if (args.Length() >= 1 && args[0]->IsObject()) {
704         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
705 
706         std::string data;
707         if (!ConvertFromJSValue(obj->GetProperty("data"), data)) {
708             return;
709         }
710 
711         std::string mimeType;
712         if (!ConvertFromJSValue(obj->GetProperty("mimeType"), mimeType)) {
713             return;
714         }
715 
716         std::string encoding;
717         if (!ConvertFromJSValue(obj->GetProperty("encoding"), encoding)) {
718             return;
719         }
720 
721         std::string baseUrl;
722         std::string historyUrl;
723         ConvertFromJSValue(obj->GetProperty("baseUrl"), baseUrl);
724         ConvertFromJSValue(obj->GetProperty("historyUrl"), historyUrl);
725         if (webController_) {
726             webController_->LoadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);
727         }
728     }
729 }
730 
Backward(const JSCallbackInfo & args)731 void JSWebController::Backward(const JSCallbackInfo& args)
732 {
733     ContainerScope scope(instanceId_);
734     if (webController_) {
735         webController_->Backward();
736     }
737 }
738 
Forward(const JSCallbackInfo & args)739 void JSWebController::Forward(const JSCallbackInfo& args)
740 {
741     ContainerScope scope(instanceId_);
742     if (webController_) {
743         webController_->Forward();
744     }
745 }
746 
AccessStep(const JSCallbackInfo & args)747 void JSWebController::AccessStep(const JSCallbackInfo& args)
748 {
749     ContainerScope scope(instanceId_);
750     int32_t step = 0;
751     if (args.Length() < 1 || !ConvertFromJSValue(args[0], step)) {
752         return;
753     }
754     if (webController_) {
755         auto canAccess = webController_->AccessStep(step);
756         auto jsVal = JSVal(ToJSValue(canAccess));
757         auto returnValue = JSRef<JSVal>::Make(jsVal);
758         args.SetReturnValue(returnValue);
759     }
760 }
761 
AccessBackward(const JSCallbackInfo & args)762 void JSWebController::AccessBackward(const JSCallbackInfo& args)
763 {
764     ContainerScope scope(instanceId_);
765     if (webController_) {
766         auto canAccess = webController_->AccessBackward();
767         auto jsVal = JSVal(ToJSValue(canAccess));
768         auto returnValue = JSRef<JSVal>::Make(jsVal);
769         args.SetReturnValue(returnValue);
770     }
771 }
772 
AccessForward(const JSCallbackInfo & args)773 void JSWebController::AccessForward(const JSCallbackInfo& args)
774 {
775     ContainerScope scope(instanceId_);
776     if (webController_) {
777         auto canAccess = webController_->AccessForward();
778         auto jsVal = JSVal(ToJSValue(canAccess));
779         auto returnValue = JSRef<JSVal>::Make(jsVal);
780         args.SetReturnValue(returnValue);
781     }
782 }
783 
ClearHistory(const JSCallbackInfo & args)784 void JSWebController::ClearHistory(const JSCallbackInfo& args)
785 {
786     ContainerScope scope(instanceId_);
787     if (webController_) {
788         webController_->ClearHistory();
789     }
790 }
791 
ClearSslCache(const JSCallbackInfo & args)792 void JSWebController::ClearSslCache(const JSCallbackInfo& args)
793 {
794     ContainerScope scope(instanceId_);
795     if (webController_) {
796         webController_->ClearSslCache();
797     }
798 }
799 
ClearClientAuthenticationCache(const JSCallbackInfo & args)800 void JSWebController::ClearClientAuthenticationCache(const JSCallbackInfo& args)
801 {
802     ContainerScope scope(instanceId_);
803     if (webController_) {
804         webController_->ClearClientAuthenticationCache();
805     }
806 }
807 
Refresh(const JSCallbackInfo & args)808 void JSWebController::Refresh(const JSCallbackInfo& args)
809 {
810     ContainerScope scope(instanceId_);
811     if (webController_) {
812         webController_->Refresh();
813     }
814 }
815 
StopLoading(const JSCallbackInfo & args)816 void JSWebController::StopLoading(const JSCallbackInfo& args)
817 {
818     ContainerScope scope(instanceId_);
819     if (webController_) {
820         webController_->StopLoading();
821     }
822 }
823 
GetHitTestResult(const JSCallbackInfo & args)824 void JSWebController::GetHitTestResult(const JSCallbackInfo& args)
825 {
826     ContainerScope scope(instanceId_);
827     if (webController_) {
828         int result = webController_->GetHitTestResult();
829         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
830     }
831 }
832 
GetHitTestValue(const JSCallbackInfo & args)833 void JSWebController::GetHitTestValue(const JSCallbackInfo& args)
834 {
835     ContainerScope scope(instanceId_);
836     if (!webController_) {
837         return;
838     }
839     HitTestResult hitResult;
840     webController_->GetHitTestValue(hitResult);
841     JSRef<JSObject> resultObj = JSClass<JSHitTestValue>::NewInstance();
842     auto result = Referenced::Claim(resultObj->Unwrap<JSHitTestValue>());
843     result->SetType(hitResult.GetHitType());
844     result->SetExtra(hitResult.GetExtraData());
845     args.SetReturnValue(resultObj);
846 }
847 
GetCookieManager(const JSCallbackInfo & args)848 void JSWebController::GetCookieManager(const JSCallbackInfo& args)
849 {
850     ContainerScope scope(instanceId_);
851     if (webController_) {
852         if (!webController_->GetCookieManager()) {
853             return;
854         }
855         if (!jsWebCookieInit_) {
856             jsWebCookie_ = JSClass<JSWebCookie>::NewInstance();
857             auto jsWebCookieVal = Referenced::Claim(jsWebCookie_->Unwrap<JSWebCookie>());
858             jsWebCookieVal->SetWebCookie(webController_->GetCookieManager());
859             jsWebCookieInit_ = true;
860         }
861         args.SetReturnValue(jsWebCookie_);
862     }
863 }
864 
BackOrForward(const JSCallbackInfo & args)865 void JSWebController::BackOrForward(const JSCallbackInfo& args)
866 {
867     ContainerScope scope(instanceId_);
868     int32_t step = 0;
869     if (args.Length() < 1 || !ConvertFromJSValue(args[0], step)) {
870         return;
871     }
872     if (webController_) {
873         webController_->BackOrForward(step);
874     }
875 }
876 
ZoomIn(const JSCallbackInfo & args)877 void JSWebController::ZoomIn(const JSCallbackInfo& args)
878 {
879     ContainerScope scope(instanceId_);
880     if (webController_) {
881         bool result = webController_->ZoomIn();
882         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
883     }
884 }
885 
ZoomOut(const JSCallbackInfo & args)886 void JSWebController::ZoomOut(const JSCallbackInfo& args)
887 {
888     ContainerScope scope(instanceId_);
889     if (webController_) {
890         bool result = webController_->ZoomOut();
891         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
892     }
893 }
894 
GetPageHeight(const JSCallbackInfo & args)895 void JSWebController::GetPageHeight(const JSCallbackInfo& args)
896 {
897     ContainerScope scope(instanceId_);
898     if (webController_) {
899         int result = webController_->GetPageHeight();
900         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
901     }
902 }
903 
GetTitle(const JSCallbackInfo & args)904 void JSWebController::GetTitle(const JSCallbackInfo& args)
905 {
906     ContainerScope scope(instanceId_);
907     if (webController_) {
908         std::string result = webController_->GetTitle();
909         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
910     }
911 }
912 
GetWebId(const JSCallbackInfo & args)913 void JSWebController::GetWebId(const JSCallbackInfo& args)
914 {
915     ContainerScope scope(instanceId_);
916     if (webController_) {
917         int result = webController_->GetWebId();
918         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
919     }
920 }
921 
GetDefaultUserAgent(const JSCallbackInfo & args)922 void JSWebController::GetDefaultUserAgent(const JSCallbackInfo& args)
923 {
924     ContainerScope scope(instanceId_);
925     if (webController_) {
926         std::string result = webController_->GetDefaultUserAgent();
927         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
928     }
929 }
930 
SetJavascriptCallBackImpl()931 void JSWebController::SetJavascriptCallBackImpl()
932 {
933     if (!webController_) {
934         return;
935     }
936 
937     WebController::JavaScriptCallBackImpl callback = [weak = WeakClaim(this)](const std::string& objectName,
938                                                          const std::string& objectMethod,
939                                                          const std::vector<std::shared_ptr<WebJSValue>>& args) {
940         auto jsWebController = weak.Upgrade();
941         if (jsWebController == nullptr) {
942             return std::make_shared<WebJSValue>(WebJSValue::Type::NONE);
943         }
944         return jsWebController->GetJavaScriptResult(objectName, objectMethod, args);
945     };
946     webController_->SetJavaScriptCallBackImpl(std::move(callback));
947 }
948 
AddJavascriptInterface(const JSCallbackInfo & args)949 void JSWebController::AddJavascriptInterface(const JSCallbackInfo& args)
950 {
951     ContainerScope scope(instanceId_);
952     if (args.Length() < 1 || !args[0]->IsObject()) {
953         return;
954     }
955     if (webController_ == nullptr) {
956         return;
957     }
958     // Init webview callback
959     SetJavascriptCallBackImpl();
960 
961     // options
962     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
963     // options.name
964     std::string objName;
965     if (!ConvertFromJSValue(obj->GetProperty("name"), objName)) {
966         return;
967     }
968     // options.obj
969     JSRef<JSVal> jsClassObj = obj->GetProperty("object");
970     if (!jsClassObj->IsObject()) {
971         return;
972     }
973     if (objectorMap_.find(objName) == objectorMap_.end()) {
974         objectorMap_[objName] = JSRef<JSObject>::Cast(jsClassObj);
975     }
976     // options.methodList
977     std::vector<std::string> methods;
978     JSRef<JSVal> methodList = obj->GetProperty("methodList");
979     if (methodList->IsArray()) {
980         JSRef<JSArray> array = JSRef<JSArray>::Cast(methodList);
981         for (size_t i = 0; i < array->Length(); i++) {
982             JSRef<JSVal> method = array->GetValueAt(i);
983             if (method->IsString()) {
984                 methods.push_back(method->ToString());
985             }
986         }
987     }
988 
989     webController_->AddJavascriptInterface(objName, methods);
990 }
991 
InitJavascriptInterface()992 void JSWebController::InitJavascriptInterface()
993 {
994     if (!webController_) {
995         return;
996     }
997     // Init webview callback
998     SetJavascriptCallBackImpl();
999     for (auto& entry : methods_) {
1000         webController_->AddJavascriptInterface(entry.first, entry.second);
1001     }
1002 }
1003 
SetJavascriptInterface(const JSCallbackInfo & args)1004 void JSWebController::SetJavascriptInterface(const JSCallbackInfo& args)
1005 {
1006     if (args.Length() < 1 || !args[0]->IsObject()) {
1007         return;
1008     }
1009     if (!webController_) {
1010         return;
1011     }
1012     // options
1013     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
1014     // options.name
1015     std::string objName;
1016     if (!ConvertFromJSValue(obj->GetProperty("name"), objName)) {
1017         return;
1018     }
1019     // options.obj
1020     JSRef<JSVal> jsClassObj = obj->GetProperty("object");
1021     if (!jsClassObj->IsObject()) {
1022         return;
1023     }
1024     objectorMap_[objName] = JSRef<JSObject>::Cast(jsClassObj);
1025     std::vector<std::string> methods;
1026     methods_.clear();
1027     JSRef<JSVal> methodList = obj->GetProperty("methodList");
1028     if (!methodList->IsArray()) {
1029         return;
1030     }
1031     JSRef<JSArray> array = JSRef<JSArray>::Cast(methodList);
1032     if (array->IsArray()) {
1033         for (size_t i = 0; i < array->Length(); i++) {
1034             JSRef<JSVal> method = array->GetValueAt(i);
1035             if (method->IsString()) {
1036                 methods.emplace_back(method->ToString());
1037             }
1038         }
1039     }
1040 
1041     JSRef<JSVal> asyncMethodList = obj->GetProperty("asyncMethodList");
1042     if (asyncMethodList->IsArray()) {
1043         JSRef<JSArray> asyncArray = JSRef<JSArray>::Cast(asyncMethodList);
1044         for (size_t i = 0; i < asyncArray->Length(); i++) {
1045             JSRef<JSVal> asyncMethod = asyncArray->GetValueAt(i);
1046             if (asyncMethod->IsString()) {
1047                 methods.emplace_back(asyncMethod->ToString());
1048             }
1049         }
1050     }
1051     methods_[objName] = methods;
1052 
1053     webController_->SetInitJavascriptInterface([weak = WeakClaim(this)]() {
1054         auto jsWebcontroller = weak.Upgrade();
1055         if (jsWebcontroller) {
1056             jsWebcontroller->InitJavascriptInterface();
1057         }
1058     });
1059 }
1060 
RemoveJavascriptInterface(const JSCallbackInfo & args)1061 void JSWebController::RemoveJavascriptInterface(const JSCallbackInfo& args)
1062 {
1063     ContainerScope scope(instanceId_);
1064     std::string objName;
1065     if (args.Length() < 1 || !ConvertFromJSValue(args[0], objName)) {
1066         return;
1067     }
1068     if (objectorMap_.find(objName) == objectorMap_.end()) {
1069         return;
1070     }
1071     objectorMap_.erase(objName);
1072     if (webController_) {
1073         webController_->RemoveJavascriptInterface(objName, {});
1074     }
1075 }
1076 
OnInactive(const JSCallbackInfo & args)1077 void JSWebController::OnInactive(const JSCallbackInfo& args)
1078 {
1079     ContainerScope scope(instanceId_);
1080     if (webController_) {
1081         webController_->OnInactive();
1082     }
1083 }
1084 
OnActive(const JSCallbackInfo & args)1085 void JSWebController::OnActive(const JSCallbackInfo& args)
1086 {
1087     ContainerScope scope(instanceId_);
1088     if (webController_) {
1089         webController_->OnActive();
1090     }
1091 }
1092 
Zoom(const JSCallbackInfo & args)1093 void JSWebController::Zoom(const JSCallbackInfo& args)
1094 {
1095     ContainerScope scope(instanceId_);
1096     float factor = 1.0;
1097     if (args.Length() < 1 || !ConvertFromJSValue(args[0], factor)) {
1098         return;
1099     }
1100     if (webController_) {
1101         webController_->Zoom(factor);
1102     }
1103 }
1104 
RequestFocus(const JSCallbackInfo & args)1105 void JSWebController::RequestFocus(const JSCallbackInfo& args)
1106 {
1107     ContainerScope scope(instanceId_);
1108     if (webController_) {
1109         webController_->RequestFocus();
1110     }
1111 }
1112 
SearchAllAsync(const JSCallbackInfo & args)1113 void JSWebController::SearchAllAsync(const JSCallbackInfo& args)
1114 {
1115     ContainerScope scope(instanceId_);
1116     std::string searchStr;
1117     if (args.Length() < 1 || !ConvertFromJSValue(args[0], searchStr)) {
1118         return;
1119     }
1120     if (webController_) {
1121         webController_->SearchAllAsync(searchStr);
1122     }
1123 }
ClearMatches(const JSCallbackInfo & args)1124 void JSWebController::ClearMatches(const JSCallbackInfo& args)
1125 {
1126     ContainerScope scope(instanceId_);
1127     if (webController_) {
1128         webController_->ClearMatches();
1129     }
1130 }
SearchNext(const JSCallbackInfo & args)1131 void JSWebController::SearchNext(const JSCallbackInfo& args)
1132 {
1133     ContainerScope scope(instanceId_);
1134     bool forward = false;
1135     if (args.Length() < 1 || !ConvertFromJSValue(args[0], forward)) {
1136         return;
1137     }
1138 
1139     if (webController_) {
1140         webController_->SearchNext(forward);
1141     }
1142 }
GetUrl(const JSCallbackInfo & args)1143 void JSWebController::GetUrl(const JSCallbackInfo& args)
1144 {
1145     ContainerScope scope(instanceId_);
1146     if (webController_) {
1147         std::string result = webController_->GetUrl();
1148         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
1149     }
1150 }
1151 
1152 } // namespace OHOS::Ace::Framework
1153