From 2dffc9f6ebed7eef997389bdcc6154221d90b3e9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 11 Aug 2019 13:24:51 +0900 Subject: [PATCH] feat: migrate webRequest module to NetworkService (Part 4) (#19679) * chore: use gin in WebRequest * Add stubs for APIs --- filenames.gni | 3 + shell/browser/api/atom_api_session.cc | 5 +- shell/browser/api/atom_api_web_request_ns.cc | 100 +++++++++++++++--- shell/browser/api/atom_api_web_request_ns.h | 44 ++++++-- .../callback_converter_gin_adapter.h | 44 ++++++++ shell/common/gin_converters/std_converter.h | 52 +++++++++ .../value_converter_gin_adapter.h | 30 ++++++ 7 files changed, 255 insertions(+), 23 deletions(-) create mode 100644 shell/common/gin_converters/callback_converter_gin_adapter.h create mode 100644 shell/common/gin_converters/std_converter.h create mode 100644 shell/common/gin_converters/value_converter_gin_adapter.h diff --git a/filenames.gni b/filenames.gni index 36b85eebb054..bc495669a7c9 100644 --- a/filenames.gni +++ b/filenames.gni @@ -465,6 +465,7 @@ filenames = { "shell/common/crash_reporter/linux/crash_dump_handler.h", "shell/common/crash_reporter/win/crash_service_main.cc", "shell/common/crash_reporter/win/crash_service_main.h", + "shell/common/gin_converters/callback_converter_gin_adapter.h", "shell/common/gin_converters/file_dialog_converter_gin_adapter.h", "shell/common/gin_converters/file_path_converter.h", "shell/common/gin_converters/gurl_converter.h", @@ -473,7 +474,9 @@ filenames = { "shell/common/gin_converters/message_box_converter.h", "shell/common/gin_converters/native_window_converter.h", "shell/common/gin_converters/net_converter_gin_adapter.h", + "shell/common/gin_converters/std_converter.h", "shell/common/gin_converters/string16_converter.h", + "shell/common/gin_converters/value_converter_gin_adapter.h", "shell/common/gin_util.h", "shell/common/heap_snapshot.cc", "shell/common/heap_snapshot.h", diff --git a/shell/browser/api/atom_api_session.cc b/shell/browser/api/atom_api_session.cc index 000f21636d88..58ac12b9b7db 100644 --- a/shell/browser/api/atom_api_session.cc +++ b/shell/browser/api/atom_api_session.cc @@ -575,9 +575,8 @@ v8::Local Session::Protocol(v8::Isolate* isolate) { v8::Local Session::WebRequest(v8::Isolate* isolate) { if (web_request_.IsEmpty()) { - v8::Local handle; - handle = WebRequestNS::Create(isolate, browser_context()).ToV8(); - web_request_.Reset(isolate, handle); + auto handle = WebRequestNS::Create(isolate, browser_context()); + web_request_.Reset(isolate, handle.ToV8()); } return v8::Local::New(isolate, web_request_); } diff --git a/shell/browser/api/atom_api_web_request_ns.cc b/shell/browser/api/atom_api_web_request_ns.cc index 69a307f9c6d2..df2778ba1399 100644 --- a/shell/browser/api/atom_api_web_request_ns.cc +++ b/shell/browser/api/atom_api_web_request_ns.cc @@ -4,33 +4,105 @@ #include "shell/browser/api/atom_api_web_request_ns.h" +#include +#include + +#include "extensions/common/url_pattern.h" +#include "gin/converter.h" +#include "gin/dictionary.h" +#include "gin/object_template_builder.h" #include "shell/browser/atom_browser_context.h" +#include "shell/common/gin_converters/callback_converter_gin_adapter.h" +#include "shell/common/gin_converters/std_converter.h" +#include "shell/common/gin_converters/value_converter_gin_adapter.h" + +namespace gin { + +template <> +struct Converter { + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + URLPattern* out) { + std::string pattern; + if (!ConvertFromV8(isolate, val, &pattern)) + return false; + *out = URLPattern(URLPattern::SCHEME_ALL); + return out->Parse(pattern) == URLPattern::ParseResult::kSuccess; + } +}; + +} // namespace gin namespace electron { namespace api { +gin::WrapperInfo WebRequestNS::kWrapperInfo = {gin::kEmbedderNativeGin}; + WebRequestNS::WebRequestNS(v8::Isolate* isolate, - AtomBrowserContext* browser_context) { - Init(isolate); - AttachAsUserData(browser_context); -} + AtomBrowserContext* browser_context) {} WebRequestNS::~WebRequestNS() = default; -// static -mate::Handle WebRequestNS::Create( - v8::Isolate* isolate, - AtomBrowserContext* browser_context) { - return mate::CreateHandle(isolate, - new WebRequestNS(isolate, browser_context)); +gin::ObjectTemplateBuilder WebRequestNS::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return gin::Wrappable::GetObjectTemplateBuilder(isolate) + .SetMethod("onBeforeRequest", + &WebRequestNS::SetResponseListener) + .SetMethod("onBeforeSendHeaders", + &WebRequestNS::SetResponseListener) + .SetMethod("onHeadersReceived", + &WebRequestNS::SetResponseListener) + .SetMethod("onSendHeaders", + &WebRequestNS::SetSimpleListener) + .SetMethod("onBeforeRedirect", + &WebRequestNS::SetSimpleListener) + .SetMethod("onResponseStarted", + &WebRequestNS::SetSimpleListener) + .SetMethod("onErrorOccurred", + &WebRequestNS::SetSimpleListener) + .SetMethod("onCompleted", &WebRequestNS::SetSimpleListener); +} + +const char* WebRequestNS::GetTypeName() { + return "WebRequest"; +} + +template +void WebRequestNS::SetSimpleListener(gin::Arguments* args) { + SetListener(event, args); +} + +template +void WebRequestNS::SetResponseListener(gin::Arguments* args) { + SetListener(event, args); +} + +template +void WebRequestNS::SetListener(Event event, gin::Arguments* args) { + // { urls }. + std::set patterns; + gin::Dictionary dict(args->isolate()); + args->GetNext(&dict) && dict.Get("urls", &patterns); + + // Function or null. + v8::Local value; + Listener listener; + if (!args->GetNext(&listener) && + !(args->GetNext(&value) && value->IsNull())) { + args->ThrowTypeError("Must pass null or a Function"); + return; + } + + // TODO(zcbenz): Actually set the listeners. + args->ThrowTypeError("This API is not implemented yet"); } // static -void WebRequestNS::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) { - prototype->SetClassName(mate::StringToV8(isolate, "WebRequest")); - mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()); +gin::Handle WebRequestNS::Create( + v8::Isolate* isolate, + AtomBrowserContext* browser_context) { + return gin::CreateHandle(isolate, new WebRequestNS(isolate, browser_context)); } } // namespace api diff --git a/shell/browser/api/atom_api_web_request_ns.h b/shell/browser/api/atom_api_web_request_ns.h index a37c38afc293..50d6699b60b3 100644 --- a/shell/browser/api/atom_api_web_request_ns.h +++ b/shell/browser/api/atom_api_web_request_ns.h @@ -5,9 +5,12 @@ #ifndef SHELL_BROWSER_API_ATOM_API_WEB_REQUEST_NS_H_ #define SHELL_BROWSER_API_ATOM_API_WEB_REQUEST_NS_H_ +#include "base/values.h" +#include "gin/arguments.h" +#include "gin/handle.h" +#include "gin/wrappable.h" #include "native_mate/dictionary.h" #include "native_mate/handle.h" -#include "shell/browser/api/trackable_object.h" namespace electron { @@ -15,17 +18,46 @@ class AtomBrowserContext; namespace api { -class WebRequestNS : public mate::TrackableObject { +class WebRequestNS : public gin::Wrappable { public: - static mate::Handle Create(v8::Isolate* isolate, - AtomBrowserContext* browser_context); + static gin::WrapperInfo kWrapperInfo; - static void BuildPrototype(v8::Isolate* isolate, - v8::Local prototype); + static gin::Handle Create(v8::Isolate* isolate, + AtomBrowserContext* browser_context); + + // gin::Wrappable: + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + const char* GetTypeName() override; private: WebRequestNS(v8::Isolate* isolate, AtomBrowserContext* browser_context); ~WebRequestNS() override; + + enum SimpleEvent { + kOnSendHeaders, + kOnBeforeRedirect, + kOnResponseStarted, + kOnCompleted, + kOnErrorOccurred, + }; + enum ResponseEvent { + kOnBeforeRequest, + kOnBeforeSendHeaders, + kOnHeadersReceived, + }; + + using SimpleListener = base::RepeatingCallback; + using ResponseCallback = base::OnceCallback; + using ResponseListener = + base::RepeatingCallback; + + template + void SetSimpleListener(gin::Arguments* args); + template + void SetResponseListener(gin::Arguments* args); + template + void SetListener(Event event, gin::Arguments* args); }; } // namespace api diff --git a/shell/common/gin_converters/callback_converter_gin_adapter.h b/shell/common/gin_converters/callback_converter_gin_adapter.h new file mode 100644 index 000000000000..e26ffdff9e55 --- /dev/null +++ b/shell/common/gin_converters/callback_converter_gin_adapter.h @@ -0,0 +1,44 @@ +// Copyright (c) 2019 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_ +#define SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_ + +#include "gin/converter.h" +#include "shell/common/native_mate_converters/once_callback.h" + +// TODO(zcbenz): Move the implementations from native_mate_converters to here. + +namespace gin { + +template +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + const base::RepeatingCallback& in) { + return mate::ConvertToV8(isolate, in); + } + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + base::RepeatingCallback* out) { + return mate::ConvertFromV8(isolate, val, out); + } +}; + +template +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + base::OnceCallback in) { + return mate::ConvertToV8(isolate, in); + } + + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + base::OnceCallback* out) { + return mate::ConvertFromV8(isolate, val, out); + } +}; + +} // namespace gin + +#endif // SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_ diff --git a/shell/common/gin_converters/std_converter.h b/shell/common/gin_converters/std_converter.h new file mode 100644 index 000000000000..2710ab3bbe73 --- /dev/null +++ b/shell/common/gin_converters/std_converter.h @@ -0,0 +1,52 @@ +// Copyright (c) 2019 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef SHELL_COMMON_GIN_CONVERTERS_STD_CONVERTER_H_ +#define SHELL_COMMON_GIN_CONVERTERS_STD_CONVERTER_H_ + +#include + +#include "gin/converter.h" + +namespace gin { + +template +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + const std::set& val) { + v8::Local result( + v8::Array::New(isolate, static_cast(val.size()))); + auto context = isolate->GetCurrentContext(); + typename std::set::const_iterator it; + int i; + for (i = 0, it = val.begin(); it != val.end(); ++it, ++i) + result->Set(context, i, Converter::ToV8(isolate, *it)).Check(); + return result; + } + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + std::set* out) { + if (!val->IsArray()) + return false; + + auto context = isolate->GetCurrentContext(); + std::set result; + v8::Local array(v8::Local::Cast(val)); + uint32_t length = array->Length(); + for (uint32_t i = 0; i < length; ++i) { + T item; + if (!Converter::FromV8(isolate, + array->Get(context, i).ToLocalChecked(), &item)) + return false; + result.insert(item); + } + + out->swap(result); + return true; + } +}; + +} // namespace gin + +#endif // SHELL_COMMON_GIN_CONVERTERS_STD_CONVERTER_H_ diff --git a/shell/common/gin_converters/value_converter_gin_adapter.h b/shell/common/gin_converters/value_converter_gin_adapter.h new file mode 100644 index 000000000000..79b1489246a2 --- /dev/null +++ b/shell/common/gin_converters/value_converter_gin_adapter.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef SHELL_COMMON_GIN_CONVERTERS_VALUE_CONVERTER_GIN_ADAPTER_H_ +#define SHELL_COMMON_GIN_CONVERTERS_VALUE_CONVERTER_GIN_ADAPTER_H_ + +#include "gin/converter.h" +#include "shell/common/native_mate_converters/value_converter.h" + +// TODO(zcbenz): Move the implementations from native_mate_converters to here. + +namespace gin { + +template <> +struct Converter { + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + base::Value* out) { + return mate::ConvertFromV8(isolate, val, out); + } + static v8::Local ToV8(v8::Isolate* isolate, + const base::Value& in) { + return mate::ConvertToV8(isolate, in); + } +}; + +} // namespace gin + +#endif // SHELL_COMMON_GIN_CONVERTERS_VALUE_CONVERTER_GIN_ADAPTER_H_