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