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 if (objectorMap_.find(objectName) == objectorMap_.end()) {
284 return jsResult;
285 }
286 auto jsObject = objectorMap_[objectName];
287 if (jsObject->IsEmpty()) {
288 return jsResult;
289 }
290 for (std::shared_ptr<WebJSValue> input : args) {
291 ParseWebViewValueToJsValue(input, argv);
292 }
293
294 if (jsObject->GetProperty(objectMethod.c_str())->IsEmpty() ||
295 !(jsObject->GetProperty(objectMethod.c_str())->IsFunction())) {
296 return jsResult;
297 }
298
299 JSRef<JSFunc> func = JSRef<JSFunc>::Cast(jsObject->GetProperty(objectMethod.c_str()));
300 if (func->IsEmpty()) {
301 jsResult->error_ = static_cast<int>(WebJavaScriptBridgeError::OBJECT_IS_GONE);
302 return jsResult;
303 }
304 JSRef<JSVal> result = argv.empty() ? func->Call(jsObject, 0, {}) : func->Call(jsObject, argv.size(), &argv[0]);
305 return ParseValue(result, jsResult);
306 }
307
308 class JSWebMessageEvent;
309 class JSWebMessagePort : public Referenced {
310 public:
JSBind(BindingTarget globalObj)311 static void JSBind(BindingTarget globalObj)
312 {
313 JSClass<JSWebMessagePort>::Declare("WebMessagePort");
314 JSClass<JSWebMessagePort>::CustomMethod("close", &JSWebMessagePort::Close);
315 JSClass<JSWebMessagePort>::CustomMethod("postMessageEvent", &JSWebMessagePort::PostMessage);
316 JSClass<JSWebMessagePort>::CustomMethod("onMessageEvent", &JSWebMessagePort::SetWebMessageCallback);
317 JSClass<JSWebMessagePort>::Bind(globalObj, JSWebMessagePort::Constructor, JSWebMessagePort::Destructor);
318 }
319
320 void PostMessage(const JSCallbackInfo& args);
321
Close(const JSCallbackInfo & args)322 void Close(const JSCallbackInfo& args)
323 {
324 if (port_ != nullptr) {
325 port_->Close();
326 }
327 }
328
SetWebMessageCallback(const JSCallbackInfo & args)329 void SetWebMessageCallback(const JSCallbackInfo& args)
330 {
331 if (args.Length() < 1 || !args[0]->IsObject()) {
332 return;
333 }
334
335 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
336 JSRef<JSVal> tsCallback = JSRef<JSVal>::Cast(obj);
337 std::function<void(std::string)> callback = nullptr;
338 if (tsCallback->IsFunction()) {
339 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
340 auto jsCallback = AceType::MakeRefPtr<JsWebViewFunction>(JSRef<JSFunc>::Cast(tsCallback));
341 callback = [execCtx = args.GetExecutionContext(), func = std::move(jsCallback), node = frameNode](
342 std::string result) {
343 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
344 ACE_SCORING_EVENT("onMessageEvent CallBack");
345 auto pipelineContext = PipelineContext::GetCurrentContext();
346 CHECK_NULL_VOID(pipelineContext);
347 pipelineContext->UpdateCurrentActiveNode(node);
348 func->Execute(result);
349 };
350 if (port_ != nullptr) {
351 port_->SetWebMessageCallback(std::move(callback));
352 }
353 }
354 }
355
SetWebMessagePort(const RefPtr<WebMessagePort> & port)356 void SetWebMessagePort(const RefPtr<WebMessagePort>& port)
357 {
358 port_ = port;
359 }
360
GetWebMessagePort()361 RefPtr<WebMessagePort> GetWebMessagePort()
362 {
363 return port_;
364 }
365
366 private:
367 RefPtr<WebMessagePort> port_;
368
Constructor(const JSCallbackInfo & args)369 static void Constructor(const JSCallbackInfo& args)
370 {
371 auto jsWebMessagePort = Referenced::MakeRefPtr<JSWebMessagePort>();
372 jsWebMessagePort->IncRefCount();
373 args.SetReturnValue(Referenced::RawPtr(jsWebMessagePort));
374 }
375
Destructor(JSWebMessagePort * jsWebMessagePort)376 static void Destructor(JSWebMessagePort* jsWebMessagePort)
377 {
378 if (jsWebMessagePort != nullptr) {
379 jsWebMessagePort->DecRefCount();
380 }
381 }
382 };
383
384 class JSWebMessageEvent : public Referenced {
385 public:
JSBind(BindingTarget globalObj)386 static void JSBind(BindingTarget globalObj)
387 {
388 JSClass<JSWebMessageEvent>::Declare("WebMessageEvent");
389 JSClass<JSWebMessageEvent>::CustomMethod("getData", &JSWebMessageEvent::GetData);
390 JSClass<JSWebMessageEvent>::CustomMethod("setData", &JSWebMessageEvent::SetData);
391 JSClass<JSWebMessageEvent>::CustomMethod("getPorts", &JSWebMessageEvent::GetPorts);
392 JSClass<JSWebMessageEvent>::CustomMethod("setPorts", &JSWebMessageEvent::SetPorts);
393 JSClass<JSWebMessageEvent>::Bind(globalObj, JSWebMessageEvent::Constructor, JSWebMessageEvent::Destructor);
394 }
395
GetData(const JSCallbackInfo & args)396 void GetData(const JSCallbackInfo& args)
397 {
398 auto jsVal = JSVal(ToJSValue(data_));
399 auto retVal = JSRef<JSVal>::Make(jsVal);
400 args.SetReturnValue(retVal);
401 }
402
SetData(const JSCallbackInfo & args)403 void SetData(const JSCallbackInfo& args)
404 {
405 if (args.Length() < 1 || !args[0]->IsString()) {
406 return;
407 }
408 data_ = args[0]->ToString();
409 }
410
SetPorts(const JSCallbackInfo & args)411 void SetPorts(const JSCallbackInfo& args)
412 {
413 if (args.Length() <= 0) {
414 return;
415 }
416 JSRef<JSArray> jsPorts = JSRef<JSArray>::Cast(args[0]);
417 std::vector<RefPtr<WebMessagePort>> sendPorts;
418 if (jsPorts->IsArray()) {
419 JSRef<JSArray> array = JSRef<JSArray>::Cast(jsPorts);
420 for (size_t i = 0; i < array->Length(); i++) {
421 JSRef<JSVal> jsValue = array->GetValueAt(i);
422 if (!jsValue->IsObject()) {
423 continue;
424 }
425 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
426 RefPtr<JSWebMessagePort> jswebPort = Referenced::Claim(jsObj->Unwrap<JSWebMessagePort>());
427 if (jswebPort) {
428 ports_.push_back(jswebPort);
429 }
430 }
431 }
432 }
433
GetPorts(const JSCallbackInfo & args)434 void GetPorts(const JSCallbackInfo& args)
435 {
436 JSRef<JSArray> jsPorts = JSRef<JSArray>::New();
437 JSRef<JSObject> jsObj;
438 RefPtr<JSWebMessagePort> jswebPort;
439 for (size_t i = 0; i < ports_.size(); i++) {
440 jsObj = JSClass<JSWebMessagePort>::NewInstance();
441 jswebPort = Referenced::Claim(jsObj->Unwrap<JSWebMessagePort>());
442 jswebPort->SetWebMessagePort(ports_[i]->GetWebMessagePort());
443 jsPorts->SetValueAt(i, jsObj);
444 }
445 args.SetReturnValue(jsPorts);
446 }
447
GetDataInternal()448 std::string GetDataInternal()
449 {
450 return data_;
451 }
452
GetPortsInternal()453 std::vector<RefPtr<JSWebMessagePort>> GetPortsInternal()
454 {
455 return ports_;
456 }
457
458 private:
459 std::string data_;
460 std::vector<RefPtr<JSWebMessagePort>> ports_;
461
Constructor(const JSCallbackInfo & args)462 static void Constructor(const JSCallbackInfo& args)
463 {
464 auto jsWebMessageEvent = Referenced::MakeRefPtr<JSWebMessageEvent>();
465 jsWebMessageEvent->IncRefCount();
466 args.SetReturnValue(Referenced::RawPtr(jsWebMessageEvent));
467 }
468
Destructor(JSWebMessageEvent * jsWebMessageEvent)469 static void Destructor(JSWebMessageEvent* jsWebMessageEvent)
470 {
471 if (jsWebMessageEvent != nullptr) {
472 jsWebMessageEvent->DecRefCount();
473 }
474 }
475 };
476
PostMessage(const JSCallbackInfo & args)477 void JSWebMessagePort::PostMessage(const JSCallbackInfo& args)
478 {
479 if (args.Length() <= 0 || !(args[0]->IsObject())) {
480 return;
481 }
482 // get ports
483 JSRef<JSVal> jsPorts = JSRef<JSVal>::Cast(args[0]);
484 if (!jsPorts->IsObject()) {
485 return;
486 }
487 auto jsRes = Referenced::Claim(JSRef<JSObject>::Cast(jsPorts)->Unwrap<JSWebMessageEvent>());
488 std::string data = jsRes->GetDataInternal();
489 if (port_) {
490 port_->PostMessage(data);
491 }
492 }
493
JSBind(BindingTarget globalObj)494 void JSWebController::JSBind(BindingTarget globalObj)
495 {
496 JSClass<JSWebController>::Declare("WebController");
497 JSClass<JSWebController>::CustomMethod("loadUrl", &JSWebController::LoadUrl);
498 JSClass<JSWebController>::CustomMethod("runJavaScript", &JSWebController::ExecuteTypeScript);
499 JSClass<JSWebController>::CustomMethod("refresh", &JSWebController::Refresh);
500 JSClass<JSWebController>::CustomMethod("stop", &JSWebController::StopLoading);
501 JSClass<JSWebController>::CustomMethod("getHitTest", &JSWebController::GetHitTestResult);
502 JSClass<JSWebController>::CustomMethod("registerJavaScriptProxy", &JSWebController::AddJavascriptInterface);
503 JSClass<JSWebController>::CustomMethod("deleteJavaScriptRegister", &JSWebController::RemoveJavascriptInterface);
504 JSClass<JSWebController>::CustomMethod("onInactive", &JSWebController::OnInactive);
505 JSClass<JSWebController>::CustomMethod("onActive", &JSWebController::OnActive);
506 JSClass<JSWebController>::CustomMethod("zoom", &JSWebController::Zoom);
507 JSClass<JSWebController>::CustomMethod("requestFocus", &JSWebController::RequestFocus);
508 JSClass<JSWebController>::CustomMethod("loadData", &JSWebController::LoadDataWithBaseUrl);
509 JSClass<JSWebController>::CustomMethod("backward", &JSWebController::Backward);
510 JSClass<JSWebController>::CustomMethod("forward", &JSWebController::Forward);
511 JSClass<JSWebController>::CustomMethod("accessStep", &JSWebController::AccessStep);
512 JSClass<JSWebController>::CustomMethod("accessForward", &JSWebController::AccessForward);
513 JSClass<JSWebController>::CustomMethod("accessBackward", &JSWebController::AccessBackward);
514 JSClass<JSWebController>::CustomMethod("clearHistory", &JSWebController::ClearHistory);
515 JSClass<JSWebController>::CustomMethod("clearSslCache", &JSWebController::ClearSslCache);
516 JSClass<JSWebController>::CustomMethod(
517 "clearClientAuthenticationCache", &JSWebController::ClearClientAuthenticationCache);
518 JSClass<JSWebController>::CustomMethod("getCookieManager", &JSWebController::GetCookieManager);
519 JSClass<JSWebController>::CustomMethod("getHitTestValue", &JSWebController::GetHitTestValue);
520 JSClass<JSWebController>::CustomMethod("backOrForward", &JSWebController::BackOrForward);
521 JSClass<JSWebController>::CustomMethod("zoomIn", &JSWebController::ZoomIn);
522 JSClass<JSWebController>::CustomMethod("zoomOut", &JSWebController::ZoomOut);
523 JSClass<JSWebController>::CustomMethod("getPageHeight", &JSWebController::GetPageHeight);
524 JSClass<JSWebController>::CustomMethod("getTitle", &JSWebController::GetTitle);
525 JSClass<JSWebController>::CustomMethod("createWebMessagePorts", &JSWebController::CreateWebMessagePorts);
526 JSClass<JSWebController>::CustomMethod("postMessage", &JSWebController::PostWebMessage);
527 JSClass<JSWebController>::CustomMethod("getWebId", &JSWebController::GetWebId);
528 JSClass<JSWebController>::CustomMethod("getDefaultUserAgent", &JSWebController::GetDefaultUserAgent);
529 JSClass<JSWebController>::CustomMethod("searchAllAsync", &JSWebController::SearchAllAsync);
530 JSClass<JSWebController>::CustomMethod("clearMatches", &JSWebController::ClearMatches);
531 JSClass<JSWebController>::CustomMethod("searchNext", &JSWebController::SearchNext);
532 JSClass<JSWebController>::CustomMethod("getUrl", &JSWebController::GetUrl);
533 JSClass<JSWebController>::Bind(globalObj, JSWebController::Constructor, JSWebController::Destructor);
534 JSWebCookie::JSBind(globalObj);
535 JSHitTestValue::JSBind(globalObj);
536 JSWebMessagePort::JSBind(globalObj);
537 JSWebMessageEvent::JSBind(globalObj);
538 }
539
Constructor(const JSCallbackInfo & args)540 void JSWebController::Constructor(const JSCallbackInfo& args)
541 {
542 auto webController = Referenced::MakeRefPtr<JSWebController>();
543 webController->IncRefCount();
544 RefPtr<WebController> controller = AceType::MakeRefPtr<WebController>();
545 webController->SetController(controller);
546 args.SetReturnValue(Referenced::RawPtr(webController));
547 }
548
Destructor(JSWebController * webController)549 void JSWebController::Destructor(JSWebController* webController)
550 {
551 if (webController != nullptr) {
552 webController->DecRefCount();
553 }
554 }
555
Reload() const556 void JSWebController::Reload() const
557 {
558 if (webController_) {
559 webController_->Reload();
560 }
561 }
562
CreateWebMessagePorts(const JSCallbackInfo & args)563 void JSWebController::CreateWebMessagePorts(const JSCallbackInfo& args)
564 {
565 ContainerScope scope(instanceId_);
566 if (webController_) {
567 std::vector<RefPtr<WebMessagePort>> ports;
568 webController_->CreateMsgPorts(ports);
569 JSRef<JSObject> jsPort0 = JSClass<JSWebMessagePort>::NewInstance();
570 auto port0 = Referenced::Claim(jsPort0->Unwrap<JSWebMessagePort>());
571 port0->SetWebMessagePort(ports.at(0));
572
573 JSRef<JSObject> jsPort1 = JSClass<JSWebMessagePort>::NewInstance();
574 auto port1 = Referenced::Claim(jsPort1->Unwrap<JSWebMessagePort>());
575 port1->SetWebMessagePort(ports.at(1));
576
577 JSRef<JSArray> result = JSRef<JSArray>::New();
578 result->SetValueAt(0, jsPort0);
579 result->SetValueAt(1, jsPort1);
580 args.SetReturnValue(result);
581 }
582 }
583
PostWebMessage(const JSCallbackInfo & args)584 void JSWebController::PostWebMessage(const JSCallbackInfo& args)
585 {
586 if (args.Length() < 1 || !args[0]->IsObject()) {
587 return;
588 }
589
590 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
591 std::string uri;
592 if (!ConvertFromJSValue(obj->GetProperty("uri"), uri)) {
593 return;
594 }
595
596 JSRef<JSVal> jsPorts = obj->GetProperty("message");
597 if (!jsPorts->IsObject()) {
598 return;
599 }
600 auto jsRes = Referenced::Claim(JSRef<JSObject>::Cast(jsPorts)->Unwrap<JSWebMessageEvent>());
601 std::string eventData = jsRes->GetDataInternal();
602 std::vector<RefPtr<JSWebMessagePort>> eventPorts = jsRes->GetPortsInternal();
603 std::vector<RefPtr<WebMessagePort>> sendPorts;
604 for (auto jsport : eventPorts) {
605 auto webPort = jsport->GetWebMessagePort();
606 if (webPort) {
607 sendPorts.push_back(webPort);
608 }
609 }
610
611 if (webController_ && sendPorts.size() >= 1) {
612 webController_->PostWebMessage(eventData, sendPorts, uri);
613 }
614 }
615
LoadUrl(const JSCallbackInfo & args)616 void JSWebController::LoadUrl(const JSCallbackInfo& args)
617 {
618 ContainerScope scope(instanceId_);
619 if (args.Length() < 1 || !args[0]->IsObject()) {
620 return;
621 }
622
623 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
624 JSRef<JSVal> valUrl = obj->GetProperty("url");
625 std::string url;
626 if (valUrl->IsObject()) {
627 // same as src process of JSWeb::Create
628 std::string webSrc;
629 if (!JSViewAbstract::ParseJsMedia(valUrl, webSrc)) {
630 return;
631 }
632 auto np = webSrc.find_first_of("/");
633 url = (np == std::string::npos) ? webSrc : webSrc.erase(np, 1);
634 } else if (!ConvertFromJSValue(valUrl, url)) {
635 return;
636 }
637
638 JSRef<JSVal> headers = obj->GetProperty("headers");
639 std::map<std::string, std::string> httpHeaders;
640 if (headers->IsArray()) {
641 JSRef<JSArray> array = JSRef<JSArray>::Cast(headers);
642 for (size_t i = 0; i < array->Length(); i++) {
643 JSRef<JSVal> jsValue = array->GetValueAt(i);
644 if (!jsValue->IsObject()) {
645 continue;
646 }
647 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
648 std::string key;
649 if (!ConvertFromJSValue(obj->GetProperty("headerKey"), key)) {
650 continue;
651 }
652 std::string value;
653 if (!ConvertFromJSValue(obj->GetProperty("headerValue"), value)) {
654 continue;
655 }
656 httpHeaders[key] = value;
657 }
658 }
659 if (webController_) {
660 webController_->LoadUrl(url, httpHeaders);
661 }
662 }
663
ExecuteTypeScript(const JSCallbackInfo & args)664 void JSWebController::ExecuteTypeScript(const JSCallbackInfo& args)
665 {
666 ContainerScope scope(instanceId_);
667 if (args.Length() < 1 || !args[0]->IsObject()) {
668 return;
669 }
670
671 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
672 std::string script;
673 if (!ConvertFromJSValue(obj->GetProperty("script"), script)) {
674 return;
675 }
676 JSRef<JSVal> tsCallback = obj->GetProperty("callback");
677 std::function<void(std::string)> callback = nullptr;
678 if (tsCallback->IsFunction()) {
679 WeakPtr<NG::FrameNode> frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
680 auto jsCallback = AceType::MakeRefPtr<JsWebViewFunction>(JSRef<JSFunc>::Cast(tsCallback));
681 callback = [execCtx = args.GetExecutionContext(), func = std::move(jsCallback), node = frameNode](
682 std::string result) {
683 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
684 ACE_SCORING_EVENT("ExecuteTypeScript CallBack");
685 auto pipelineContext = PipelineContext::GetCurrentContext();
686 CHECK_NULL_VOID(pipelineContext);
687 pipelineContext->UpdateCurrentActiveNode(node);
688 func->Execute(result);
689 };
690 }
691 if (webController_) {
692 webController_->ExecuteTypeScript(script, std::move(callback));
693 }
694 }
695
LoadDataWithBaseUrl(const JSCallbackInfo & args)696 void JSWebController::LoadDataWithBaseUrl(const JSCallbackInfo& args)
697 {
698 ContainerScope scope(instanceId_);
699 if (args.Length() >= 1 && args[0]->IsObject()) {
700 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
701
702 std::string data;
703 if (!ConvertFromJSValue(obj->GetProperty("data"), data)) {
704 return;
705 }
706
707 std::string mimeType;
708 if (!ConvertFromJSValue(obj->GetProperty("mimeType"), mimeType)) {
709 return;
710 }
711
712 std::string encoding;
713 if (!ConvertFromJSValue(obj->GetProperty("encoding"), encoding)) {
714 return;
715 }
716
717 std::string baseUrl;
718 std::string historyUrl;
719 ConvertFromJSValue(obj->GetProperty("baseUrl"), baseUrl);
720 ConvertFromJSValue(obj->GetProperty("historyUrl"), historyUrl);
721 if (webController_) {
722 webController_->LoadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);
723 }
724 }
725 }
726
Backward(const JSCallbackInfo & args)727 void JSWebController::Backward(const JSCallbackInfo& args)
728 {
729 ContainerScope scope(instanceId_);
730 if (webController_) {
731 webController_->Backward();
732 }
733 }
734
Forward(const JSCallbackInfo & args)735 void JSWebController::Forward(const JSCallbackInfo& args)
736 {
737 ContainerScope scope(instanceId_);
738 if (webController_) {
739 webController_->Forward();
740 }
741 }
742
AccessStep(const JSCallbackInfo & args)743 void JSWebController::AccessStep(const JSCallbackInfo& args)
744 {
745 ContainerScope scope(instanceId_);
746 int32_t step = 0;
747 if (args.Length() < 1 || !ConvertFromJSValue(args[0], step)) {
748 return;
749 }
750 if (webController_) {
751 auto canAccess = webController_->AccessStep(step);
752 auto jsVal = JSVal(ToJSValue(canAccess));
753 auto returnValue = JSRef<JSVal>::Make(jsVal);
754 args.SetReturnValue(returnValue);
755 }
756 }
757
AccessBackward(const JSCallbackInfo & args)758 void JSWebController::AccessBackward(const JSCallbackInfo& args)
759 {
760 ContainerScope scope(instanceId_);
761 if (webController_) {
762 auto canAccess = webController_->AccessBackward();
763 auto jsVal = JSVal(ToJSValue(canAccess));
764 auto returnValue = JSRef<JSVal>::Make(jsVal);
765 args.SetReturnValue(returnValue);
766 }
767 }
768
AccessForward(const JSCallbackInfo & args)769 void JSWebController::AccessForward(const JSCallbackInfo& args)
770 {
771 ContainerScope scope(instanceId_);
772 if (webController_) {
773 auto canAccess = webController_->AccessForward();
774 auto jsVal = JSVal(ToJSValue(canAccess));
775 auto returnValue = JSRef<JSVal>::Make(jsVal);
776 args.SetReturnValue(returnValue);
777 }
778 }
779
ClearHistory(const JSCallbackInfo & args)780 void JSWebController::ClearHistory(const JSCallbackInfo& args)
781 {
782 ContainerScope scope(instanceId_);
783 if (webController_) {
784 webController_->ClearHistory();
785 }
786 }
787
ClearSslCache(const JSCallbackInfo & args)788 void JSWebController::ClearSslCache(const JSCallbackInfo& args)
789 {
790 ContainerScope scope(instanceId_);
791 if (webController_) {
792 webController_->ClearSslCache();
793 }
794 }
795
ClearClientAuthenticationCache(const JSCallbackInfo & args)796 void JSWebController::ClearClientAuthenticationCache(const JSCallbackInfo& args)
797 {
798 ContainerScope scope(instanceId_);
799 if (webController_) {
800 webController_->ClearClientAuthenticationCache();
801 }
802 }
803
Refresh(const JSCallbackInfo & args)804 void JSWebController::Refresh(const JSCallbackInfo& args)
805 {
806 ContainerScope scope(instanceId_);
807 if (webController_) {
808 webController_->Refresh();
809 }
810 }
811
StopLoading(const JSCallbackInfo & args)812 void JSWebController::StopLoading(const JSCallbackInfo& args)
813 {
814 ContainerScope scope(instanceId_);
815 if (webController_) {
816 webController_->StopLoading();
817 }
818 }
819
GetHitTestResult(const JSCallbackInfo & args)820 void JSWebController::GetHitTestResult(const JSCallbackInfo& args)
821 {
822 ContainerScope scope(instanceId_);
823 if (webController_) {
824 int result = webController_->GetHitTestResult();
825 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
826 }
827 }
828
GetHitTestValue(const JSCallbackInfo & args)829 void JSWebController::GetHitTestValue(const JSCallbackInfo& args)
830 {
831 ContainerScope scope(instanceId_);
832 if (!webController_) {
833 return;
834 }
835 HitTestResult hitResult;
836 webController_->GetHitTestValue(hitResult);
837 JSRef<JSObject> resultObj = JSClass<JSHitTestValue>::NewInstance();
838 auto result = Referenced::Claim(resultObj->Unwrap<JSHitTestValue>());
839 result->SetType(hitResult.GetHitType());
840 result->SetExtra(hitResult.GetExtraData());
841 args.SetReturnValue(resultObj);
842 }
843
GetCookieManager(const JSCallbackInfo & args)844 void JSWebController::GetCookieManager(const JSCallbackInfo& args)
845 {
846 ContainerScope scope(instanceId_);
847 if (webController_) {
848 if (!webController_->GetCookieManager()) {
849 return;
850 }
851 if (!jsWebCookieInit_) {
852 jsWebCookie_ = JSClass<JSWebCookie>::NewInstance();
853 auto jsWebCookieVal = Referenced::Claim(jsWebCookie_->Unwrap<JSWebCookie>());
854 jsWebCookieVal->SetWebCookie(webController_->GetCookieManager());
855 jsWebCookieInit_ = true;
856 }
857 args.SetReturnValue(jsWebCookie_);
858 }
859 }
860
BackOrForward(const JSCallbackInfo & args)861 void JSWebController::BackOrForward(const JSCallbackInfo& args)
862 {
863 ContainerScope scope(instanceId_);
864 int32_t step = 0;
865 if (args.Length() < 1 || !ConvertFromJSValue(args[0], step)) {
866 return;
867 }
868 if (webController_) {
869 webController_->BackOrForward(step);
870 }
871 }
872
ZoomIn(const JSCallbackInfo & args)873 void JSWebController::ZoomIn(const JSCallbackInfo& args)
874 {
875 ContainerScope scope(instanceId_);
876 if (webController_) {
877 bool result = webController_->ZoomIn();
878 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
879 }
880 }
881
ZoomOut(const JSCallbackInfo & args)882 void JSWebController::ZoomOut(const JSCallbackInfo& args)
883 {
884 ContainerScope scope(instanceId_);
885 if (webController_) {
886 bool result = webController_->ZoomOut();
887 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
888 }
889 }
890
GetPageHeight(const JSCallbackInfo & args)891 void JSWebController::GetPageHeight(const JSCallbackInfo& args)
892 {
893 ContainerScope scope(instanceId_);
894 if (webController_) {
895 int result = webController_->GetPageHeight();
896 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
897 }
898 }
899
GetTitle(const JSCallbackInfo & args)900 void JSWebController::GetTitle(const JSCallbackInfo& args)
901 {
902 ContainerScope scope(instanceId_);
903 if (webController_) {
904 std::string result = webController_->GetTitle();
905 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
906 }
907 }
908
GetWebId(const JSCallbackInfo & args)909 void JSWebController::GetWebId(const JSCallbackInfo& args)
910 {
911 ContainerScope scope(instanceId_);
912 if (webController_) {
913 int result = webController_->GetWebId();
914 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
915 }
916 }
917
GetDefaultUserAgent(const JSCallbackInfo & args)918 void JSWebController::GetDefaultUserAgent(const JSCallbackInfo& args)
919 {
920 ContainerScope scope(instanceId_);
921 if (webController_) {
922 std::string result = webController_->GetDefaultUserAgent();
923 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
924 }
925 }
926
SetJavascriptCallBackImpl()927 void JSWebController::SetJavascriptCallBackImpl()
928 {
929 if (!webController_) {
930 return;
931 }
932
933 WebController::JavaScriptCallBackImpl callback = [weak = WeakClaim(this)](const std::string& objectName,
934 const std::string& objectMethod,
935 const std::vector<std::shared_ptr<WebJSValue>>& args) {
936 auto jsWebController = weak.Upgrade();
937 if (jsWebController == nullptr) {
938 return std::make_shared<WebJSValue>(WebJSValue::Type::NONE);
939 }
940 return jsWebController->GetJavaScriptResult(objectName, objectMethod, args);
941 };
942 webController_->SetJavaScriptCallBackImpl(std::move(callback));
943 }
944
AddJavascriptInterface(const JSCallbackInfo & args)945 void JSWebController::AddJavascriptInterface(const JSCallbackInfo& args)
946 {
947 ContainerScope scope(instanceId_);
948 if (args.Length() < 1 || !args[0]->IsObject()) {
949 return;
950 }
951 if (webController_ == nullptr) {
952 return;
953 }
954 // Init webview callback
955 SetJavascriptCallBackImpl();
956
957 // options
958 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
959 // options.name
960 std::string objName;
961 if (!ConvertFromJSValue(obj->GetProperty("name"), objName)) {
962 return;
963 }
964 // options.obj
965 JSRef<JSVal> jsClassObj = obj->GetProperty("object");
966 if (!jsClassObj->IsObject()) {
967 return;
968 }
969 if (objectorMap_.find(objName) == objectorMap_.end()) {
970 objectorMap_[objName] = JSRef<JSObject>::Cast(jsClassObj);
971 }
972 // options.methodList
973 std::vector<std::string> methods;
974 JSRef<JSVal> methodList = obj->GetProperty("methodList");
975 if (methodList->IsArray()) {
976 JSRef<JSArray> array = JSRef<JSArray>::Cast(methodList);
977 for (size_t i = 0; i < array->Length(); i++) {
978 JSRef<JSVal> method = array->GetValueAt(i);
979 if (method->IsString()) {
980 methods.push_back(method->ToString());
981 }
982 }
983 }
984
985 webController_->AddJavascriptInterface(objName, methods);
986 }
987
InitJavascriptInterface()988 void JSWebController::InitJavascriptInterface()
989 {
990 if (!webController_) {
991 return;
992 }
993 // Init webview callback
994 SetJavascriptCallBackImpl();
995 for (auto& entry : methods_) {
996 webController_->AddJavascriptInterface(entry.first, entry.second);
997 }
998 }
999
SetJavascriptInterface(const JSCallbackInfo & args)1000 void JSWebController::SetJavascriptInterface(const JSCallbackInfo& args)
1001 {
1002 if (args.Length() < 1 || !args[0]->IsObject()) {
1003 return;
1004 }
1005 if (!webController_) {
1006 return;
1007 }
1008 // options
1009 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
1010 // options.name
1011 std::string objName;
1012 if (!ConvertFromJSValue(obj->GetProperty("name"), objName)) {
1013 return;
1014 }
1015 // options.obj
1016 JSRef<JSVal> jsClassObj = obj->GetProperty("object");
1017 if (!jsClassObj->IsObject()) {
1018 return;
1019 }
1020 objectorMap_[objName] = JSRef<JSObject>::Cast(jsClassObj);
1021 std::vector<std::string> methods;
1022 methods_.clear();
1023 JSRef<JSVal> methodList = obj->GetProperty("methodList");
1024 JSRef<JSArray> array = JSRef<JSArray>::Cast(methodList);
1025 if (array->IsArray()) {
1026 for (size_t i = 0; i < array->Length(); i++) {
1027 JSRef<JSVal> method = array->GetValueAt(i);
1028 if (method->IsString()) {
1029 methods.emplace_back(method->ToString());
1030 }
1031 }
1032 }
1033 methods_[objName] = methods;
1034
1035 webController_->SetInitJavascriptInterface([weak = WeakClaim(this)]() {
1036 auto jsWebcontroller = weak.Upgrade();
1037 if (jsWebcontroller) {
1038 jsWebcontroller->InitJavascriptInterface();
1039 }
1040 });
1041 }
1042
RemoveJavascriptInterface(const JSCallbackInfo & args)1043 void JSWebController::RemoveJavascriptInterface(const JSCallbackInfo& args)
1044 {
1045 ContainerScope scope(instanceId_);
1046 std::string objName;
1047 if (args.Length() < 1 || !ConvertFromJSValue(args[0], objName)) {
1048 return;
1049 }
1050 if (objectorMap_.find(objName) == objectorMap_.end()) {
1051 return;
1052 }
1053 objectorMap_.erase(objName);
1054 if (webController_) {
1055 webController_->RemoveJavascriptInterface(objName, {});
1056 }
1057 }
1058
OnInactive(const JSCallbackInfo & args)1059 void JSWebController::OnInactive(const JSCallbackInfo& args)
1060 {
1061 ContainerScope scope(instanceId_);
1062 if (webController_) {
1063 webController_->OnInactive();
1064 }
1065 }
1066
OnActive(const JSCallbackInfo & args)1067 void JSWebController::OnActive(const JSCallbackInfo& args)
1068 {
1069 ContainerScope scope(instanceId_);
1070 if (webController_) {
1071 webController_->OnActive();
1072 }
1073 }
1074
Zoom(const JSCallbackInfo & args)1075 void JSWebController::Zoom(const JSCallbackInfo& args)
1076 {
1077 ContainerScope scope(instanceId_);
1078 float factor = 1.0;
1079 if (args.Length() < 1 || !ConvertFromJSValue(args[0], factor)) {
1080 return;
1081 }
1082 if (webController_) {
1083 webController_->Zoom(factor);
1084 }
1085 }
1086
RequestFocus(const JSCallbackInfo & args)1087 void JSWebController::RequestFocus(const JSCallbackInfo& args)
1088 {
1089 ContainerScope scope(instanceId_);
1090 if (webController_) {
1091 webController_->RequestFocus();
1092 }
1093 }
1094
SearchAllAsync(const JSCallbackInfo & args)1095 void JSWebController::SearchAllAsync(const JSCallbackInfo& args)
1096 {
1097 ContainerScope scope(instanceId_);
1098 std::string searchStr;
1099 if (args.Length() < 1 || !ConvertFromJSValue(args[0], searchStr)) {
1100 return;
1101 }
1102 if (webController_) {
1103 webController_->SearchAllAsync(searchStr);
1104 }
1105 }
ClearMatches(const JSCallbackInfo & args)1106 void JSWebController::ClearMatches(const JSCallbackInfo& args)
1107 {
1108 ContainerScope scope(instanceId_);
1109 if (webController_) {
1110 webController_->ClearMatches();
1111 }
1112 }
SearchNext(const JSCallbackInfo & args)1113 void JSWebController::SearchNext(const JSCallbackInfo& args)
1114 {
1115 ContainerScope scope(instanceId_);
1116 bool forward = false;
1117 if (args.Length() < 1 || !ConvertFromJSValue(args[0], forward)) {
1118 return;
1119 }
1120
1121 if (webController_) {
1122 webController_->SearchNext(forward);
1123 }
1124 }
GetUrl(const JSCallbackInfo & args)1125 void JSWebController::GetUrl(const JSCallbackInfo& args)
1126 {
1127 ContainerScope scope(instanceId_);
1128 if (webController_) {
1129 std::string result = webController_->GetUrl();
1130 args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(result)));
1131 }
1132 }
1133
1134 } // namespace OHOS::Ace::Framework
1135