From 0ee7f14190e75d0e7b669661c81235a4a2bfadb4 Mon Sep 17 00:00:00 2001 From: Jeremy Rose Date: Tue, 5 Jul 2022 08:25:18 -0700 Subject: [PATCH] chore: modernize Value usage in converters (#34794) * chore: modernize Value usage in converters * Date is parsed as an empty object now --- filenames.gni | 2 - shell/browser/api/electron_api_base_window.cc | 2 +- shell/browser/api/electron_api_base_window.h | 2 +- .../api/electron_api_content_tracing.cc | 5 +- shell/browser/api/electron_api_cookies.cc | 47 +- shell/browser/api/electron_api_cookies.h | 8 +- shell/browser/api/electron_api_debugger.cc | 66 +-- shell/browser/api/electron_api_debugger.h | 2 +- shell/browser/api/electron_api_session.cc | 4 +- shell/browser/api/electron_api_session.h | 7 +- .../api/electron_api_system_preferences.h | 6 +- .../electron_api_system_preferences_mac.mm | 43 +- shell/browser/browser.h | 6 +- shell/browser/browser_linux.cc | 4 +- shell/browser/browser_mac.mm | 15 +- shell/browser/browser_win.cc | 4 +- shell/browser/electron_browser_context.cc | 6 +- shell/browser/electron_browser_context.h | 10 +- shell/browser/native_window.cc | 5 +- shell/browser/native_window.h | 2 +- shell/browser/native_window_observer.h | 2 +- .../net/electron_url_loader_factory.cc | 6 +- shell/browser/net/url_pipe_loader.cc | 12 +- shell/browser/net/url_pipe_loader.h | 4 +- shell/browser/ui/cocoa/electron_touch_bar.mm | 45 +- shell/common/api/electron_api_native_image.cc | 21 +- shell/common/api/electron_api_native_image.h | 2 +- .../gin_converters/extension_converter.cc | 3 +- shell/common/gin_converters/net_converter.cc | 10 +- .../common/gin_converters/value_converter.cc | 59 +- shell/common/gin_converters/value_converter.h | 19 +- shell/common/v8_value_converter.cc | 524 ------------------ shell/common/v8_value_converter.h | 78 --- spec-main/api-system-preferences-spec.ts | 1 - 34 files changed, 203 insertions(+), 829 deletions(-) delete mode 100644 shell/common/v8_value_converter.cc delete mode 100644 shell/common/v8_value_converter.h diff --git a/filenames.gni b/filenames.gni index 3ce306928a..912d11ac9a 100644 --- a/filenames.gni +++ b/filenames.gni @@ -643,8 +643,6 @@ filenames = { "shell/common/process_util.h", "shell/common/skia_util.cc", "shell/common/skia_util.h", - "shell/common/v8_value_converter.cc", - "shell/common/v8_value_converter.h", "shell/common/v8_value_serializer.cc", "shell/common/v8_value_serializer.h", "shell/common/world_ids.h", diff --git a/shell/browser/api/electron_api_base_window.cc b/shell/browser/api/electron_api_base_window.cc index 3f4e529023..3a87a11d22 100644 --- a/shell/browser/api/electron_api_base_window.cc +++ b/shell/browser/api/electron_api_base_window.cc @@ -288,7 +288,7 @@ void BaseWindow::OnExecuteAppCommand(const std::string& command_name) { } void BaseWindow::OnTouchBarItemResult(const std::string& item_id, - const base::DictionaryValue& details) { + const base::Value::Dict& details) { Emit("-touch-bar-interaction", item_id, details); } diff --git a/shell/browser/api/electron_api_base_window.h b/shell/browser/api/electron_api_base_window.h index 98fa9a5556..482f510f4e 100644 --- a/shell/browser/api/electron_api_base_window.h +++ b/shell/browser/api/electron_api_base_window.h @@ -80,7 +80,7 @@ class BaseWindow : public gin_helper::TrackableObject, void OnWindowAlwaysOnTopChanged() override; void OnExecuteAppCommand(const std::string& command_name) override; void OnTouchBarItemResult(const std::string& item_id, - const base::DictionaryValue& details) override; + const base::Value::Dict& details) override; void OnNewWindowForTab() override; void OnSystemContextMenu(int x, int y, bool* prevent_default) override; #if BUILDFLAG(IS_WIN) diff --git a/shell/browser/api/electron_api_content_tracing.cc b/shell/browser/api/electron_api_content_tracing.cc index aa1047c403..a1628bb7f3 100644 --- a/shell/browser/api/electron_api_content_tracing.cc +++ b/shell/browser/api/electron_api_content_tracing.cc @@ -42,9 +42,10 @@ struct Converter { } } - base::DictionaryValue memory_dump_config; + base::Value::Dict memory_dump_config; if (ConvertFromV8(isolate, val, &memory_dump_config)) { - *out = base::trace_event::TraceConfig(memory_dump_config); + *out = base::trace_event::TraceConfig( + base::Value(std::move(memory_dump_config))); return true; } diff --git a/shell/browser/api/electron_api_cookies.cc b/shell/browser/api/electron_api_cookies.cc index 7970f87474..e4cebe4fb5 100644 --- a/shell/browser/api/electron_api_cookies.cc +++ b/shell/browser/api/electron_api_cookies.cc @@ -117,27 +117,27 @@ bool MatchesDomain(std::string filter, const std::string& domain) { } // Returns whether |cookie| matches |filter|. -bool MatchesCookie(const base::Value& filter, +bool MatchesCookie(const base::Value::Dict& filter, const net::CanonicalCookie& cookie) { const std::string* str; - if ((str = filter.FindStringKey("name")) && *str != cookie.Name()) + if ((str = filter.FindString("name")) && *str != cookie.Name()) return false; - if ((str = filter.FindStringKey("path")) && *str != cookie.Path()) + if ((str = filter.FindString("path")) && *str != cookie.Path()) return false; - if ((str = filter.FindStringKey("domain")) && + if ((str = filter.FindString("domain")) && !MatchesDomain(*str, cookie.Domain())) return false; - absl::optional secure_filter = filter.FindBoolKey("secure"); + absl::optional secure_filter = filter.FindBool("secure"); if (secure_filter && *secure_filter == cookie.IsSecure()) return false; - absl::optional session_filter = filter.FindBoolKey("session"); + absl::optional session_filter = filter.FindBool("session"); if (session_filter && *session_filter != !cookie.IsPersistent()) return false; return true; } // Remove cookies from |list| not matching |filter|, and pass it to |callback|. -void FilterCookies(const base::Value& filter, +void FilterCookies(base::Value::Dict filter, gin_helper::Promise promise, const net::CookieList& cookies) { net::CookieList result; @@ -149,11 +149,11 @@ void FilterCookies(const base::Value& filter, } void FilterCookieWithStatuses( - const base::Value& filter, + base::Value::Dict filter, gin_helper::Promise promise, const net::CookieAccessResultList& list, const net::CookieAccessResultList& excluded_list) { - FilterCookies(filter, std::move(promise), + FilterCookies(std::move(filter), std::move(promise), net::cookie_util::StripAccessResults(list)); } @@ -231,7 +231,7 @@ v8::Local Cookies::Get(v8::Isolate* isolate, auto* storage_partition = browser_context_->GetDefaultStoragePartition(); auto* manager = storage_partition->GetCookieManagerForBrowserProcess(); - base::DictionaryValue dict; + base::Value::Dict dict; gin::ConvertFromV8(isolate, filter.GetHandle(), &dict); std::string url; @@ -280,31 +280,31 @@ v8::Local Cookies::Remove(v8::Isolate* isolate, } v8::Local Cookies::Set(v8::Isolate* isolate, - const base::DictionaryValue& details) { + base::Value::Dict details) { gin_helper::Promise promise(isolate); v8::Local handle = promise.GetHandle(); - const std::string* url_string = details.FindStringKey("url"); + const std::string* url_string = details.FindString("url"); if (!url_string) { promise.RejectWithErrorMessage("Missing required option 'url'"); return handle; } - const std::string* name = details.FindStringKey("name"); - const std::string* value = details.FindStringKey("value"); - const std::string* domain = details.FindStringKey("domain"); - const std::string* path = details.FindStringKey("path"); - bool http_only = details.FindBoolKey("httpOnly").value_or(false); - const std::string* same_site_string = details.FindStringKey("sameSite"); + const std::string* name = details.FindString("name"); + const std::string* value = details.FindString("value"); + const std::string* domain = details.FindString("domain"); + const std::string* path = details.FindString("path"); + bool http_only = details.FindBool("httpOnly").value_or(false); + const std::string* same_site_string = details.FindString("sameSite"); net::CookieSameSite same_site; std::string error = StringToCookieSameSite(same_site_string, &same_site); if (!error.empty()) { promise.RejectWithErrorMessage(error); return handle; } - bool secure = details.FindBoolKey("secure").value_or( + bool secure = details.FindBool("secure").value_or( same_site == net::CookieSameSite::NO_RESTRICTION); bool same_party = - details.FindBoolKey("sameParty") + details.FindBool("sameParty") .value_or(secure && same_site != net::CookieSameSite::STRICT_MODE); GURL url(url_string ? *url_string : ""); @@ -317,10 +317,9 @@ v8::Local Cookies::Set(v8::Isolate* isolate, auto canonical_cookie = net::CanonicalCookie::CreateSanitizedCookie( url, name ? *name : "", value ? *value : "", domain ? *domain : "", - path ? *path : "", - ParseTimeProperty(details.FindDoubleKey("creationDate")), - ParseTimeProperty(details.FindDoubleKey("expirationDate")), - ParseTimeProperty(details.FindDoubleKey("lastAccessDate")), secure, + path ? *path : "", ParseTimeProperty(details.FindDouble("creationDate")), + ParseTimeProperty(details.FindDouble("expirationDate")), + ParseTimeProperty(details.FindDouble("lastAccessDate")), secure, http_only, same_site, net::COOKIE_PRIORITY_DEFAULT, same_party, absl::nullopt); if (!canonical_cookie || !canonical_cookie->IsCanonical()) { diff --git a/shell/browser/api/electron_api_cookies.h b/shell/browser/api/electron_api_cookies.h index fbfa335ce9..3b98c033af 100644 --- a/shell/browser/api/electron_api_cookies.h +++ b/shell/browser/api/electron_api_cookies.h @@ -8,6 +8,7 @@ #include #include "base/callback_list.h" +#include "base/values.h" #include "gin/handle.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_change_dispatcher.h" @@ -15,10 +16,6 @@ #include "shell/common/gin_helper/promise.h" #include "shell/common/gin_helper/trackable_object.h" -namespace base { -class DictionaryValue; -} - namespace gin_helper { class Dictionary; } @@ -51,8 +48,7 @@ class Cookies : public gin::Wrappable, v8::Local Get(v8::Isolate*, const gin_helper::Dictionary& filter); - v8::Local Set(v8::Isolate*, - const base::DictionaryValue& details); + v8::Local Set(v8::Isolate*, base::Value::Dict details); v8::Local Remove(v8::Isolate*, const GURL& url, const std::string& name); diff --git a/shell/browser/api/electron_api_debugger.cc b/shell/browser/api/electron_api_debugger.cc index fcd44205d7..e24c0dca3d 100644 --- a/shell/browser/api/electron_api_debugger.cc +++ b/shell/browser/api/electron_api_debugger.cc @@ -45,44 +45,35 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, base::StringPiece message_str(reinterpret_cast(message.data()), message.size()); - std::unique_ptr parsed_message = - base::JSONReader::ReadDeprecated(message_str, - base::JSON_REPLACE_INVALID_CHARACTERS); + absl::optional parsed_message = base::JSONReader::Read( + message_str, base::JSON_REPLACE_INVALID_CHARACTERS); if (!parsed_message || !parsed_message->is_dict()) return; - auto* dict = static_cast(parsed_message.get()); - int id; - if (!dict->GetInteger("id", &id)) { - std::string method; - if (!dict->GetString("method", &method)) + base::Value::Dict& dict = parsed_message->GetDict(); + absl::optional id = dict.FindInt("id"); + if (!id) { + std::string* method = dict.FindString("method"); + if (!method) return; - std::string session_id; - dict->GetString("sessionId", &session_id); - base::DictionaryValue* params_value = nullptr; - base::DictionaryValue params; - if (dict->GetDictionary("params", ¶ms_value)) - params.Swap(params_value); - Emit("message", method, params, session_id); + std::string* session_id = dict.FindString("sessionId"); + base::Value::Dict* params = dict.FindDict("params"); + Emit("message", *method, params ? std::move(*params) : base::Value::Dict(), + session_id ? *session_id : ""); } else { - auto it = pending_requests_.find(id); + auto it = pending_requests_.find(*id); if (it == pending_requests_.end()) return; - gin_helper::Promise promise = std::move(it->second); + gin_helper::Promise promise = std::move(it->second); pending_requests_.erase(it); - base::DictionaryValue* error = nullptr; - if (dict->GetDictionary("error", &error)) { - std::string message; - error->GetString("message", &message); - promise.RejectWithErrorMessage(message); + base::Value::Dict* error = dict.FindDict("error"); + if (error) { + std::string* message = error->FindString("message"); + promise.RejectWithErrorMessage(message ? *message : ""); } else { - base::DictionaryValue* result_body = nullptr; - base::DictionaryValue result; - if (dict->GetDictionary("result", &result_body)) { - result.Swap(result_body); - } - promise.Resolve(result); + base::Value::Dict* result = dict.FindDict("result"); + promise.Resolve(result ? std::move(*result) : base::Value::Dict()); } } } @@ -133,7 +124,7 @@ void Debugger::Detach() { v8::Local Debugger::SendCommand(gin::Arguments* args) { v8::Isolate* isolate = args->isolate(); - gin_helper::Promise promise(isolate); + gin_helper::Promise promise(isolate); v8::Local handle = promise.GetHandle(); if (!agent_host_) { @@ -147,7 +138,7 @@ v8::Local Debugger::SendCommand(gin::Arguments* args) { return handle; } - base::DictionaryValue command_params; + base::Value::Dict command_params; args->GetNext(&command_params); std::string session_id; @@ -156,22 +147,21 @@ v8::Local Debugger::SendCommand(gin::Arguments* args) { return handle; } - base::DictionaryValue request; + base::Value::Dict request; int request_id = ++previous_request_id_; pending_requests_.emplace(request_id, std::move(promise)); - request.SetInteger("id", request_id); - request.SetString("method", method); - if (!command_params.DictEmpty()) { - request.Set("params", - base::Value::ToUniquePtrValue(command_params.Clone())); + request.Set("id", request_id); + request.Set("method", method); + if (!command_params.empty()) { + request.Set("params", base::Value(std::move(command_params))); } if (!session_id.empty()) { - request.SetString("sessionId", session_id); + request.Set("sessionId", session_id); } std::string json_args; - base::JSONWriter::Write(request, &json_args); + base::JSONWriter::Write(base::Value(std::move(request)), &json_args); agent_host_->DispatchProtocolMessage( this, base::as_bytes(base::make_span(json_args))); diff --git a/shell/browser/api/electron_api_debugger.h b/shell/browser/api/electron_api_debugger.h index dc4f3b7eec..e9388df8b2 100644 --- a/shell/browser/api/electron_api_debugger.h +++ b/shell/browser/api/electron_api_debugger.h @@ -57,7 +57,7 @@ class Debugger : public gin::Wrappable, private: using PendingRequestMap = - std::map>; + std::map>; void Attach(gin::Arguments* args); bool IsAttached(); diff --git a/shell/browser/api/electron_api_session.cc b/shell/browser/api/electron_api_session.cc index 3d2a13be44..c02eddd57f 100644 --- a/shell/browser/api/electron_api_session.cc +++ b/shell/browser/api/electron_api_session.cc @@ -1160,7 +1160,7 @@ gin::Handle Session::CreateFrom( // static gin::Handle Session::FromPartition(v8::Isolate* isolate, const std::string& partition, - base::DictionaryValue options) { + base::Value::Dict options) { ElectronBrowserContext* browser_context; if (partition.empty()) { browser_context = @@ -1265,7 +1265,7 @@ v8::Local FromPartition(const std::string& partition, args->ThrowTypeError("Session can only be received when app is ready"); return v8::Null(args->isolate()); } - base::DictionaryValue options; + base::Value::Dict options; args->GetNext(&options); return Session::FromPartition(args->isolate(), partition, std::move(options)) .ToV8(); diff --git a/shell/browser/api/electron_api_session.h b/shell/browser/api/electron_api_session.h index e9b69380df..c5f21920dc 100644 --- a/shell/browser/api/electron_api_session.h +++ b/shell/browser/api/electron_api_session.h @@ -75,10 +75,9 @@ class Session : public gin::Wrappable, static Session* FromBrowserContext(content::BrowserContext* context); // Gets the Session of |partition|. - static gin::Handle FromPartition( - v8::Isolate* isolate, - const std::string& partition, - base::DictionaryValue options = base::DictionaryValue()); + static gin::Handle FromPartition(v8::Isolate* isolate, + const std::string& partition, + base::Value::Dict options = {}); ElectronBrowserContext* browser_context() const { return browser_context_; } diff --git a/shell/browser/api/electron_api_system_preferences.h b/shell/browser/api/electron_api_system_preferences.h index b3ef33f5ff..b311e97fc6 100644 --- a/shell/browser/api/electron_api_system_preferences.h +++ b/shell/browser/api/electron_api_system_preferences.h @@ -72,18 +72,18 @@ class SystemPreferences void(const std::string&, base::Value, const std::string&)>; void PostNotification(const std::string& name, - base::DictionaryValue user_info, + base::Value::Dict user_info, gin::Arguments* args); int SubscribeNotification(v8::Local maybe_name, const NotificationCallback& callback); void UnsubscribeNotification(int id); void PostLocalNotification(const std::string& name, - base::DictionaryValue user_info); + base::Value::Dict user_info); int SubscribeLocalNotification(v8::Local maybe_name, const NotificationCallback& callback); void UnsubscribeLocalNotification(int request_id); void PostWorkspaceNotification(const std::string& name, - base::DictionaryValue user_info); + base::Value::Dict user_info); int SubscribeWorkspaceNotification(v8::Local maybe_name, const NotificationCallback& callback); void UnsubscribeWorkspaceNotification(int request_id); diff --git a/shell/browser/api/electron_api_system_preferences_mac.mm b/shell/browser/api/electron_api_system_preferences_mac.mm index d8ef89fa4d..bbd37e3c38 100644 --- a/shell/browser/api/electron_api_system_preferences_mac.mm +++ b/shell/browser/api/electron_api_system_preferences_mac.mm @@ -138,7 +138,7 @@ NSNotificationCenter* GetNotificationCenter(NotificationCenterKind kind) { } // namespace void SystemPreferences::PostNotification(const std::string& name, - base::DictionaryValue user_info, + base::Value::Dict user_info, gin::Arguments* args) { bool immediate = false; args->GetNext(&immediate); @@ -148,7 +148,7 @@ void SystemPreferences::PostNotification(const std::string& name, [center postNotificationName:base::SysUTF8ToNSString(name) object:nil - userInfo:DictionaryValueToNSDictionary(user_info.GetDict()) + userInfo:DictionaryValueToNSDictionary(std::move(user_info)) deliverImmediately:immediate]; } @@ -166,12 +166,12 @@ void SystemPreferences::UnsubscribeNotification(int request_id) { } void SystemPreferences::PostLocalNotification(const std::string& name, - base::DictionaryValue user_info) { + base::Value::Dict user_info) { NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center postNotificationName:base::SysUTF8ToNSString(name) object:nil - userInfo:DictionaryValueToNSDictionary(user_info.GetDict())]; + userInfo:DictionaryValueToNSDictionary(std::move(user_info))]; } int SystemPreferences::SubscribeLocalNotification( @@ -186,15 +186,14 @@ void SystemPreferences::UnsubscribeLocalNotification(int request_id) { NotificationCenterKind::kNSNotificationCenter); } -void SystemPreferences::PostWorkspaceNotification( - const std::string& name, - base::DictionaryValue user_info) { +void SystemPreferences::PostWorkspaceNotification(const std::string& name, + base::Value::Dict user_info) { NSNotificationCenter* center = [[NSWorkspace sharedWorkspace] notificationCenter]; [center postNotificationName:base::SysUTF8ToNSString(name) object:nil - userInfo:DictionaryValueToNSDictionary(user_info.GetDict())]; + userInfo:DictionaryValueToNSDictionary(std::move(user_info))]; } int SystemPreferences::SubscribeWorkspaceNotification( @@ -246,7 +245,7 @@ int SystemPreferences::DoSubscribeNotification( } else { copied_callback.Run( base::SysNSStringToUTF8(notification.name), - base::DictionaryValue(), object); + base::Value(base::Value::Dict()), object); } }]; return request_id; @@ -295,24 +294,24 @@ v8::Local SystemPreferences::GetUserDefault( } void SystemPreferences::RegisterDefaults(gin::Arguments* args) { - base::DictionaryValue value; + base::Value::Dict value; if (!args->GetNext(&value)) { args->ThrowError(); - } else { - @try { - NSDictionary* dict = DictionaryValueToNSDictionary(value.GetDict()); - for (id key in dict) { - id value = [dict objectForKey:key]; - if ([value isKindOfClass:[NSNull class]] || value == nil) { - args->ThrowError(); - return; - } + return; + } + @try { + NSDictionary* dict = DictionaryValueToNSDictionary(std::move(value)); + for (id key in dict) { + id value = [dict objectForKey:key]; + if ([value isKindOfClass:[NSNull class]] || value == nil) { + args->ThrowError(); + return; } - [[NSUserDefaults standardUserDefaults] registerDefaults:dict]; - } @catch (NSException* exception) { - args->ThrowError(); } + [[NSUserDefaults standardUserDefaults] registerDefaults:dict]; + } @catch (NSException* exception) { + args->ThrowError(); } } diff --git a/shell/browser/browser.h b/shell/browser/browser.h index aaae1b774f..7fc47ef826 100644 --- a/shell/browser/browser.h +++ b/shell/browser/browser.h @@ -165,7 +165,7 @@ class Browser : public WindowListObserver { // Creates an activity and sets it as the one currently in use. void SetUserActivity(const std::string& type, - base::DictionaryValue user_info, + base::Value::Dict user_info, gin::Arguments* args); // Returns the type name of the current user activity. @@ -180,7 +180,7 @@ class Browser : public WindowListObserver { // Updates the current user activity void UpdateCurrentActivity(const std::string& type, - base::DictionaryValue user_info); + base::Value::Dict user_info); // Indicates that an user activity is about to be resumed. bool WillContinueUserActivity(const std::string& type); @@ -231,7 +231,7 @@ class Browser : public WindowListObserver { #endif // BUILDFLAG(IS_MAC) void ShowAboutPanel(); - void SetAboutPanelOptions(base::DictionaryValue options); + void SetAboutPanelOptions(base::Value::Dict options); #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) void ShowEmojiPanel(); diff --git a/shell/browser/browser_linux.cc b/shell/browser/browser_linux.cc index 8b38c9ca67..d7b7b96dfa 100644 --- a/shell/browser/browser_linux.cc +++ b/shell/browser/browser_linux.cc @@ -224,8 +224,8 @@ void Browser::ShowAboutPanel() { gtk_widget_destroy(dialogWidget); } -void Browser::SetAboutPanelOptions(base::DictionaryValue options) { - about_panel_options_ = std::move(options); +void Browser::SetAboutPanelOptions(base::Value::Dict options) { + about_panel_options_ = base::Value(std::move(options)); } } // namespace electron diff --git a/shell/browser/browser_mac.mm b/shell/browser/browser_mac.mm index f155160f55..ed35f421ce 100644 --- a/shell/browser/browser_mac.mm +++ b/shell/browser/browser_mac.mm @@ -235,14 +235,14 @@ bool Browser::SetBadgeCount(absl::optional count) { } void Browser::SetUserActivity(const std::string& type, - base::DictionaryValue user_info, + base::Value::Dict user_info, gin::Arguments* args) { std::string url_string; args->GetNext(&url_string); [[AtomApplication sharedApplication] setCurrentActivity:base::SysUTF8ToNSString(type) - withUserInfo:DictionaryValueToNSDictionary(user_info.GetDict()) + withUserInfo:DictionaryValueToNSDictionary(std::move(user_info)) withWebpageURL:net::NSURLWithGURL(GURL(url_string))]; } @@ -261,10 +261,11 @@ void Browser::ResignCurrentActivity() { } void Browser::UpdateCurrentActivity(const std::string& type, - base::DictionaryValue user_info) { + base::Value::Dict user_info) { [[AtomApplication sharedApplication] updateCurrentActivity:base::SysUTF8ToNSString(type) - withUserInfo:DictionaryValueToNSDictionary(user_info.GetDict())]; + withUserInfo:DictionaryValueToNSDictionary( + std::move(user_info))]; } bool Browser::WillContinueUserActivity(const std::string& type) { @@ -511,11 +512,11 @@ void Browser::ShowAboutPanel() { orderFrontStandardAboutPanelWithOptions:options]; } -void Browser::SetAboutPanelOptions(base::DictionaryValue options) { +void Browser::SetAboutPanelOptions(base::Value::Dict options) { about_panel_options_.DictClear(); - for (const auto pair : options.DictItems()) { - std::string key = std::string(pair.first); + for (const auto pair : options) { + std::string key = pair.first; if (!key.empty() && pair.second.is_string()) { key[0] = base::ToUpperASCII(key[0]); auto val = std::make_unique(pair.second.Clone()); diff --git a/shell/browser/browser_win.cc b/shell/browser/browser_win.cc index ced835e59c..43364d6508 100644 --- a/shell/browser/browser_win.cc +++ b/shell/browser/browser_win.cc @@ -851,8 +851,8 @@ void Browser::ShowAboutPanel() { electron::ShowMessageBoxSync(settings); } -void Browser::SetAboutPanelOptions(base::DictionaryValue options) { - about_panel_options_ = std::move(options); +void Browser::SetAboutPanelOptions(base::Value::Dict options) { + about_panel_options_ = base::Value(std::move(options)); } } // namespace electron diff --git a/shell/browser/electron_browser_context.cc b/shell/browser/electron_browser_context.cc index e2408f01e9..ff4ed57d35 100644 --- a/shell/browser/electron_browser_context.cc +++ b/shell/browser/electron_browser_context.cc @@ -103,7 +103,7 @@ ElectronBrowserContext::browser_context_map() { ElectronBrowserContext::ElectronBrowserContext(const std::string& partition, bool in_memory, - base::DictionaryValue options) + base::Value::Dict options) : storage_policy_(base::MakeRefCounted()), protocol_registry_(base::WrapUnique(new ProtocolRegistry)), in_memory_(in_memory), @@ -111,7 +111,7 @@ ElectronBrowserContext::ElectronBrowserContext(const std::string& partition, // Read options. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); use_cache_ = !command_line->HasSwitch(switches::kDisableHttpCache); - if (auto use_cache_opt = options.FindBoolKey("cache")) { + if (auto use_cache_opt = options.FindBool("cache")) { use_cache_ = use_cache_opt.value(); } @@ -530,7 +530,7 @@ bool ElectronBrowserContext::CheckDevicePermission( ElectronBrowserContext* ElectronBrowserContext::From( const std::string& partition, bool in_memory, - base::DictionaryValue options) { + base::Value::Dict options) { PartitionKey key(partition, in_memory); ElectronBrowserContext* browser_context = browser_context_map()[key].get(); if (browser_context) { diff --git a/shell/browser/electron_browser_context.h b/shell/browser/electron_browser_context.h index 844df7f65e..baaa2ee4ee 100644 --- a/shell/browser/electron_browser_context.h +++ b/shell/browser/electron_browser_context.h @@ -44,7 +44,6 @@ using DevicePermissionMap = std::map>>>; -class ElectronBrowserContext; class ElectronDownloadManagerDelegate; class ElectronPermissionManager; class CookieChangeNotifier; @@ -82,10 +81,9 @@ class ElectronBrowserContext : public content::BrowserContext { // Get or create the BrowserContext according to its |partition| and // |in_memory|. The |options| will be passed to constructor when there is no // existing BrowserContext. - static ElectronBrowserContext* From( - const std::string& partition, - bool in_memory, - base::DictionaryValue options = base::DictionaryValue()); + static ElectronBrowserContext* From(const std::string& partition, + bool in_memory, + base::Value::Dict options = {}); static BrowserContextMap& browser_context_map(); @@ -177,7 +175,7 @@ class ElectronBrowserContext : public content::BrowserContext { private: ElectronBrowserContext(const std::string& partition, bool in_memory, - base::DictionaryValue options); + base::Value::Dict options); // Initialize pref registry. void InitPrefs(); diff --git a/shell/browser/native_window.cc b/shell/browser/native_window.cc index 414cb2ec4e..8979399911 100644 --- a/shell/browser/native_window.cc +++ b/shell/browser/native_window.cc @@ -658,9 +658,8 @@ void NativeWindow::NotifyWindowExecuteAppCommand(const std::string& command) { observer.OnExecuteAppCommand(command); } -void NativeWindow::NotifyTouchBarItemInteraction( - const std::string& item_id, - const base::DictionaryValue& details) { +void NativeWindow::NotifyTouchBarItemInteraction(const std::string& item_id, + base::Value::Dict details) { for (NativeWindowObserver& observer : observers_) observer.OnTouchBarItemResult(item_id, details); } diff --git a/shell/browser/native_window.h b/shell/browser/native_window.h index 3170c1911c..13de702f18 100644 --- a/shell/browser/native_window.h +++ b/shell/browser/native_window.h @@ -304,7 +304,7 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowAlwaysOnTopChanged(); void NotifyWindowExecuteAppCommand(const std::string& command); void NotifyTouchBarItemInteraction(const std::string& item_id, - const base::DictionaryValue& details); + base::Value::Dict details); void NotifyNewWindowForTab(); void NotifyWindowSystemContextMenu(int x, int y, bool* prevent_default); void NotifyLayoutWindowControlsOverlay(); diff --git a/shell/browser/native_window_observer.h b/shell/browser/native_window_observer.h index 64f06179ff..6cbc941450 100644 --- a/shell/browser/native_window_observer.h +++ b/shell/browser/native_window_observer.h @@ -93,7 +93,7 @@ class NativeWindowObserver : public base::CheckedObserver { virtual void OnWindowLeaveHtmlFullScreen() {} virtual void OnWindowAlwaysOnTopChanged() {} virtual void OnTouchBarItemResult(const std::string& item_id, - const base::DictionaryValue& details) {} + const base::Value::Dict& details) {} virtual void OnNewWindowForTab() {} virtual void OnSystemContextMenu(int x, int y, bool* prevent_default) {} diff --git a/shell/browser/net/electron_url_loader_factory.cc b/shell/browser/net/electron_url_loader_factory.cc index 02a93aae14..b7418c8253 100644 --- a/shell/browser/net/electron_url_loader_factory.cc +++ b/shell/browser/net/electron_url_loader_factory.cc @@ -114,9 +114,9 @@ network::mojom::URLResponseHeadPtr ToResponseHead( bool has_mime_type = dict.Get("mimeType", &head->mime_type); bool has_content_type = false; - base::DictionaryValue headers; + base::Value::Dict headers; if (dict.Get("headers", &headers)) { - for (const auto iter : headers.DictItems()) { + for (const auto iter : headers) { if (iter.second.is_string()) { // key, value head->headers->AddHeader(iter.first, iter.second.GetString()); @@ -513,7 +513,7 @@ void ElectronURLLoaderFactory::StartLoadingHttp( if (!dict.Get("method", &request->method)) request->method = original_request.method; - base::DictionaryValue upload_data; + base::Value::Dict upload_data; if (request->method != net::HttpRequestHeaders::kGetMethod && request->method != net::HttpRequestHeaders::kHeadMethod) dict.Get("uploadData", &upload_data); diff --git a/shell/browser/net/url_pipe_loader.cc b/shell/browser/net/url_pipe_loader.cc index 63895e6e3d..1729ded04a 100644 --- a/shell/browser/net/url_pipe_loader.cc +++ b/shell/browser/net/url_pipe_loader.cc @@ -19,7 +19,7 @@ URLPipeLoader::URLPipeLoader( mojo::PendingReceiver loader, mojo::PendingRemote client, const net::NetworkTrafficAnnotationTag& annotation, - base::DictionaryValue upload_data) + base::Value::Dict upload_data) : url_loader_(this, std::move(loader)), client_(std::move(client)) { url_loader_.set_disconnect_handler(base::BindOnce( &URLPipeLoader::NotifyComplete, base::Unretained(this), net::ERR_FAILED)); @@ -37,17 +37,17 @@ void URLPipeLoader::Start( scoped_refptr factory, std::unique_ptr request, const net::NetworkTrafficAnnotationTag& annotation, - base::DictionaryValue upload_data) { + base::Value::Dict upload_data) { loader_ = network::SimpleURLLoader::Create(std::move(request), annotation); loader_->SetOnResponseStartedCallback(base::BindOnce( &URLPipeLoader::OnResponseStarted, weak_factory_.GetWeakPtr())); // TODO(zcbenz): The old protocol API only supports string as upload data, // we should seek to support more types in future. - std::string content_type, data; - if (upload_data.GetString("contentType", &content_type) && - upload_data.GetString("data", &data)) - loader_->AttachStringForUpload(data, content_type); + std::string* content_type = upload_data.FindString("contentType"); + std::string* data = upload_data.FindString("data"); + if (content_type && data) + loader_->AttachStringForUpload(*data, *content_type); loader_->DownloadAsStream(factory.get(), this); } diff --git a/shell/browser/net/url_pipe_loader.h b/shell/browser/net/url_pipe_loader.h index 09baa5f142..e55a771ea1 100644 --- a/shell/browser/net/url_pipe_loader.h +++ b/shell/browser/net/url_pipe_loader.h @@ -39,7 +39,7 @@ class URLPipeLoader : public network::mojom::URLLoader, mojo::PendingReceiver loader, mojo::PendingRemote client, const net::NetworkTrafficAnnotationTag& annotation, - base::DictionaryValue upload_data); + base::Value::Dict upload_data); // disable copy URLPipeLoader(const URLPipeLoader&) = delete; @@ -51,7 +51,7 @@ class URLPipeLoader : public network::mojom::URLLoader, void Start(scoped_refptr factory, std::unique_ptr request, const net::NetworkTrafficAnnotationTag& annotation, - base::DictionaryValue upload_data); + base::Value::Dict upload_data); void NotifyComplete(int result); void OnResponseStarted(const GURL& final_url, const network::mojom::URLResponseHead& response_head); diff --git a/shell/browser/ui/cocoa/electron_touch_bar.mm b/shell/browser/ui/cocoa/electron_touch_bar.mm index 3272ebc652..ae866e8629 100644 --- a/shell/browser/ui/cocoa/electron_touch_bar.mm +++ b/shell/browser/ui/cocoa/electron_touch_bar.mm @@ -241,8 +241,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; - (void)buttonAction:(id)sender { NSString* item_id = [NSString stringWithFormat:@"%ld", ((NSButton*)sender).tag]; - window_->NotifyTouchBarItemInteraction([item_id UTF8String], - base::DictionaryValue()); + window_->NotifyTouchBarItemInteraction([item_id UTF8String], {}); } - (void)colorPickerAction:(id)sender { @@ -252,19 +251,20 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; NSColor* color = ((NSColorPickerTouchBarItem*)sender).color; std::string hex_color = electron::ToRGBHex(skia::NSDeviceColorToSkColor(color)); - base::DictionaryValue details; - details.SetString("color", hex_color); - window_->NotifyTouchBarItemInteraction([item_id UTF8String], details); + base::Value::Dict details; + details.Set("color", hex_color); + window_->NotifyTouchBarItemInteraction([item_id UTF8String], + std::move(details)); } - (void)sliderAction:(id)sender { NSString* identifier = ((NSSliderTouchBarItem*)sender).identifier; NSString* item_id = [self idFromIdentifier:identifier withPrefix:SliderIdentifier]; - base::DictionaryValue details; - details.SetInteger("value", - [((NSSliderTouchBarItem*)sender).slider intValue]); - window_->NotifyTouchBarItemInteraction([item_id UTF8String], details); + base::Value::Dict details; + details.Set("value", [((NSSliderTouchBarItem*)sender).slider intValue]); + window_->NotifyTouchBarItemInteraction([item_id UTF8String], + std::move(details)); } - (NSString*)idFromIdentifier:(NSString*)identifier @@ -275,32 +275,33 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; - (void)segmentedControlAction:(id)sender { NSString* item_id = [NSString stringWithFormat:@"%ld", ((NSSegmentedControl*)sender).tag]; - base::DictionaryValue details; - details.SetInteger("selectedIndex", - ((NSSegmentedControl*)sender).selectedSegment); - details.SetBoolean( + base::Value::Dict details; + details.Set("selectedIndex", + static_cast(((NSSegmentedControl*)sender).selectedSegment)); + details.Set( "isSelected", [((NSSegmentedControl*)sender) isSelectedForSegment:((NSSegmentedControl*)sender).selectedSegment]); - window_->NotifyTouchBarItemInteraction([item_id UTF8String], details); + window_->NotifyTouchBarItemInteraction([item_id UTF8String], + std::move(details)); } - (void)scrubber:(NSScrubber*)scrubber didSelectItemAtIndex:(NSInteger)selectedIndex { - base::DictionaryValue details; - details.SetInteger("selectedIndex", selectedIndex); - details.SetString("type", "select"); + base::Value::Dict details; + details.Set("selectedIndex", static_cast(selectedIndex)); + details.Set("type", "select"); window_->NotifyTouchBarItemInteraction([scrubber.identifier UTF8String], - details); + std::move(details)); } - (void)scrubber:(NSScrubber*)scrubber didHighlightItemAtIndex:(NSInteger)highlightedIndex { - base::DictionaryValue details; - details.SetInteger("highlightedIndex", highlightedIndex); - details.SetString("type", "highlight"); + base::Value::Dict details; + details.Set("highlightedIndex", static_cast(highlightedIndex)); + details.Set("type", "highlight"); window_->NotifyTouchBarItemInteraction([scrubber.identifier UTF8String], - details); + std::move(details)); } - (NSTouchBarItemIdentifier)identifierFromID:(const std::string&)item_id diff --git a/shell/common/api/electron_api_native_image.cc b/shell/common/api/electron_api_native_image.cc index 060c7022fc..dfb6b8cf1d 100644 --- a/shell/common/api/electron_api_native_image.cc +++ b/shell/common/api/electron_api_native_image.cc @@ -329,24 +329,24 @@ float NativeImage::GetAspectRatio(const absl::optional scale_factor) { } gin::Handle NativeImage::Resize(gin::Arguments* args, - base::DictionaryValue options) { + base::Value::Dict options) { float scale_factor = GetScaleFactorFromOptions(args); gfx::Size size = GetSize(scale_factor); - int width = size.width(); - int height = size.height(); - bool width_set = options.GetInteger("width", &width); - bool height_set = options.GetInteger("height", &height); + absl::optional new_width = options.FindInt("width"); + absl::optional new_height = options.FindInt("height"); + int width = new_width.value_or(size.width()); + int height = new_height.value_or(size.height()); size.SetSize(width, height); if (width <= 0 && height <= 0) { return CreateEmpty(args->isolate()); - } else if (width_set && !height_set) { + } else if (new_width && !new_height) { // Scale height to preserve original aspect ratio size.set_height(width); size = gfx::ScaleToRoundedSize(size, 1.f, 1.f / GetAspectRatio(scale_factor)); - } else if (height_set && !width_set) { + } else if (new_height && !new_width) { // Scale width to preserve original aspect ratio size.set_width(height); size = gfx::ScaleToRoundedSize(size, GetAspectRatio(scale_factor), 1.f); @@ -354,11 +354,10 @@ gin::Handle NativeImage::Resize(gin::Arguments* args, skia::ImageOperations::ResizeMethod method = skia::ImageOperations::ResizeMethod::RESIZE_BEST; - std::string quality; - options.GetString("quality", &quality); - if (quality == "good") + std::string* quality = options.FindString("quality"); + if (quality && *quality == "good") method = skia::ImageOperations::ResizeMethod::RESIZE_GOOD; - else if (quality == "better") + else if (quality && *quality == "better") method = skia::ImageOperations::ResizeMethod::RESIZE_BETTER; gfx::ImageSkia resized = gfx::ImageSkiaOperations::CreateResizedImage( diff --git a/shell/common/api/electron_api_native_image.h b/shell/common/api/electron_api_native_image.h index 16c4f8ec0f..3330765ff5 100644 --- a/shell/common/api/electron_api_native_image.h +++ b/shell/common/api/electron_api_native_image.h @@ -112,7 +112,7 @@ class NativeImage : public gin::Wrappable { v8::Local GetBitmap(gin::Arguments* args); v8::Local GetNativeHandle(gin_helper::ErrorThrower thrower); gin::Handle Resize(gin::Arguments* args, - base::DictionaryValue options); + base::Value::Dict options); gin::Handle Crop(v8::Isolate* isolate, const gfx::Rect& rect); std::string ToDataURL(gin::Arguments* args); bool IsEmpty(); diff --git a/shell/common/gin_converters/extension_converter.cc b/shell/common/gin_converters/extension_converter.cc index a81d6a81dc..49e99e9390 100644 --- a/shell/common/gin_converters/extension_converter.cc +++ b/shell/common/gin_converters/extension_converter.cc @@ -22,7 +22,8 @@ v8::Local Converter::ToV8( dict.Set("path", extension->path()); dict.Set("url", extension->url()); dict.Set("version", extension->VersionString()); - dict.Set("manifest", *(extension->manifest()->value())); + dict.Set("manifest", + *static_cast(extension->manifest()->value())); return gin::ConvertToV8(isolate, dict); } diff --git a/shell/common/gin_converters/net_converter.cc b/shell/common/gin_converters/net_converter.cc index 8b467d5509..687d7610a8 100644 --- a/shell/common/gin_converters/net_converter.cc +++ b/shell/common/gin_converters/net_converter.cc @@ -234,13 +234,13 @@ v8::Local Converter::ToV8( bool Converter::FromV8(v8::Isolate* isolate, v8::Local val, net::HttpRequestHeaders* out) { - base::DictionaryValue dict; + base::Value::Dict dict; if (!ConvertFromV8(isolate, val, &dict)) return false; - for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { - if (it.value().is_string()) { - std::string value = it.value().GetString(); - out->SetHeader(it.key(), value); + for (const auto it : dict) { + if (it.second.is_string()) { + std::string value = it.second.GetString(); + out->SetHeader(it.first, value); } } return true; diff --git a/shell/common/gin_converters/value_converter.cc b/shell/common/gin_converters/value_converter.cc index db89b6a63e..414d535db5 100644 --- a/shell/common/gin_converters/value_converter.cc +++ b/shell/common/gin_converters/value_converter.cc @@ -7,38 +7,38 @@ #include #include -#include "base/values.h" -#include "shell/common/v8_value_converter.h" +#include "content/public/renderer/v8_value_converter.h" namespace gin { -bool Converter::FromV8(v8::Isolate* isolate, - v8::Local val, - base::DictionaryValue* out) { - electron::V8ValueConverter converter; - std::unique_ptr value( - converter.FromV8Value(val, isolate->GetCurrentContext())); +bool Converter::FromV8(v8::Isolate* isolate, + v8::Local val, + base::Value::Dict* out) { + std::unique_ptr value = + content::V8ValueConverter::Create()->FromV8Value( + val, isolate->GetCurrentContext()); if (value && value->is_dict()) { - out->Swap(static_cast(value.get())); + *out = std::move(value->GetDict()); return true; } else { return false; } } -v8::Local Converter::ToV8( +v8::Local Converter::ToV8( v8::Isolate* isolate, - const base::DictionaryValue& val) { - electron::V8ValueConverter converter; - return converter.ToV8Value(&val, isolate->GetCurrentContext()); + const base::Value::Dict& val) { + base::Value value(val.Clone()); + return content::V8ValueConverter::Create()->ToV8Value( + &value, isolate->GetCurrentContext()); } bool Converter::FromV8(v8::Isolate* isolate, v8::Local val, base::Value* out) { - electron::V8ValueConverter converter; - std::unique_ptr value( - converter.FromV8Value(val, isolate->GetCurrentContext())); + std::unique_ptr value = + content::V8ValueConverter::Create()->FromV8Value( + val, isolate->GetCurrentContext()); if (value) { *out = std::move(*value); return true; @@ -49,29 +49,30 @@ bool Converter::FromV8(v8::Isolate* isolate, v8::Local Converter::ToV8(v8::Isolate* isolate, const base::Value& val) { - electron::V8ValueConverter converter; - return converter.ToV8Value(&val, isolate->GetCurrentContext()); + return content::V8ValueConverter::Create()->ToV8Value( + &val, isolate->GetCurrentContext()); } -bool Converter::FromV8(v8::Isolate* isolate, - v8::Local val, - base::ListValue* out) { - electron::V8ValueConverter converter; - std::unique_ptr value( - converter.FromV8Value(val, isolate->GetCurrentContext())); +bool Converter::FromV8(v8::Isolate* isolate, + v8::Local val, + base::Value::List* out) { + std::unique_ptr value = + content::V8ValueConverter::Create()->FromV8Value( + val, isolate->GetCurrentContext()); if (value && value->is_list()) { - out->Swap(static_cast(value.get())); + *out = std::move(value->GetList()); return true; } else { return false; } } -v8::Local Converter::ToV8( +v8::Local Converter::ToV8( v8::Isolate* isolate, - const base::ListValue& val) { - electron::V8ValueConverter converter; - return converter.ToV8Value(&val, isolate->GetCurrentContext()); + const base::Value::List& val) { + base::Value value(val.Clone()); + return content::V8ValueConverter::Create()->ToV8Value( + &value, isolate->GetCurrentContext()); } } // namespace gin diff --git a/shell/common/gin_converters/value_converter.h b/shell/common/gin_converters/value_converter.h index 16a79af43b..a5c7996883 100644 --- a/shell/common/gin_converters/value_converter.h +++ b/shell/common/gin_converters/value_converter.h @@ -5,23 +5,18 @@ #ifndef ELECTRON_SHELL_COMMON_GIN_CONVERTERS_VALUE_CONVERTER_H_ #define ELECTRON_SHELL_COMMON_GIN_CONVERTERS_VALUE_CONVERTER_H_ +#include "base/values.h" #include "gin/converter.h" -namespace base { -class DictionaryValue; -class ListValue; -class Value; -} // namespace base - namespace gin { template <> -struct Converter { +struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, - base::DictionaryValue* out); + base::Value::Dict* out); static v8::Local ToV8(v8::Isolate* isolate, - const base::DictionaryValue& val); + const base::Value::Dict& val); }; template <> @@ -34,12 +29,12 @@ struct Converter { }; template <> -struct Converter { +struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, - base::ListValue* out); + base::Value::List* out); static v8::Local ToV8(v8::Isolate* isolate, - const base::ListValue& val); + const base::Value::List& val); }; } // namespace gin diff --git a/shell/common/v8_value_converter.cc b/shell/common/v8_value_converter.cc deleted file mode 100644 index 971b16b07e..0000000000 --- a/shell/common/v8_value_converter.cc +++ /dev/null @@ -1,524 +0,0 @@ -// Copyright (c) 2013 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "shell/common/v8_value_converter.h" - -#include -#include -#include -#include -#include -#include - -#include "base/logging.h" -#include "base/values.h" -#include "shell/common/gin_helper/dictionary.h" -#include "shell/common/node_bindings.h" -#include "shell/common/node_includes.h" - -namespace electron { - -namespace { - -const int kMaxRecursionDepth = 100; - -} // namespace - -// The state of a call to FromV8Value. -class V8ValueConverter::FromV8ValueState { - public: - // Level scope which updates the current depth of some FromV8ValueState. - class Level { - public: - explicit Level(FromV8ValueState* state) : state_(state) { - state_->max_recursion_depth_--; - } - ~Level() { state_->max_recursion_depth_++; } - - private: - FromV8ValueState* state_; - }; - - FromV8ValueState() : max_recursion_depth_(kMaxRecursionDepth) {} - - // If |handle| is not in |unique_map_|, then add it to |unique_map_| and - // return true. - // - // Otherwise do nothing and return false. Here "A is unique" means that no - // other handle B in the map points to the same object as A. Note that A can - // be unique even if there already is another handle with the same identity - // hash (key) in the map, because two objects can have the same hash. - bool AddToUniquenessCheck(v8::Local handle) { - int hash; - auto iter = GetIteratorInMap(handle, &hash); - if (iter != unique_map_.end()) - return false; - - unique_map_.insert(std::make_pair(hash, handle)); - return true; - } - - bool RemoveFromUniquenessCheck(v8::Local handle) { - int unused_hash; - auto iter = GetIteratorInMap(handle, &unused_hash); - if (iter == unique_map_.end()) - return false; - unique_map_.erase(iter); - return true; - } - - bool HasReachedMaxRecursionDepth() { return max_recursion_depth_ < 0; } - - private: - using HashToHandleMap = std::multimap>; - using Iterator = HashToHandleMap::const_iterator; - - Iterator GetIteratorInMap(v8::Local handle, int* hash) { - *hash = handle->GetIdentityHash(); - // We only compare using == with handles to objects with the same identity - // hash. Different hash obviously means different objects, but two objects - // in a couple of thousands could have the same identity hash. - std::pair range = unique_map_.equal_range(*hash); - for (auto it = range.first; it != range.second; ++it) { - // Operator == for handles actually compares the underlying objects. - if (it->second == handle) - return it; - } - // Not found. - return unique_map_.end(); - } - - HashToHandleMap unique_map_; - - int max_recursion_depth_; -}; - -// A class to ensure that objects/arrays that are being converted by -// this V8ValueConverterImpl do not have cycles. -// -// An example of cycle: var v = {}; v = {key: v}; -// Not an example of cycle: var v = {}; a = [v, v]; or w = {a: v, b: v}; -class V8ValueConverter::ScopedUniquenessGuard { - public: - ScopedUniquenessGuard(V8ValueConverter::FromV8ValueState* state, - v8::Local value) - : state_(state), - value_(value), - is_valid_(state_->AddToUniquenessCheck(value_)) {} - ~ScopedUniquenessGuard() { - if (is_valid_) { - bool removed = state_->RemoveFromUniquenessCheck(value_); - DCHECK(removed); - } - } - - // disable copy - ScopedUniquenessGuard(const ScopedUniquenessGuard&) = delete; - ScopedUniquenessGuard& operator=(const ScopedUniquenessGuard&) = delete; - - bool is_valid() const { return is_valid_; } - - private: - typedef std::multimap> HashToHandleMap; - V8ValueConverter::FromV8ValueState* state_; - v8::Local value_; - bool is_valid_; -}; - -V8ValueConverter::V8ValueConverter() = default; - -void V8ValueConverter::SetRegExpAllowed(bool val) { - reg_exp_allowed_ = val; -} - -void V8ValueConverter::SetFunctionAllowed(bool val) { - function_allowed_ = val; -} - -void V8ValueConverter::SetStripNullFromObjects(bool val) { - strip_null_from_objects_ = val; -} - -v8::Local V8ValueConverter::ToV8Value( - const base::Value* value, - v8::Local context) const { - v8::Context::Scope context_scope(context); - v8::EscapableHandleScope handle_scope(context->GetIsolate()); - return handle_scope.Escape(ToV8ValueImpl(context->GetIsolate(), value)); -} - -std::unique_ptr V8ValueConverter::FromV8Value( - v8::Local val, - v8::Local context) const { - v8::Context::Scope context_scope(context); - v8::HandleScope handle_scope(context->GetIsolate()); - FromV8ValueState state; - return FromV8ValueImpl(&state, val, context->GetIsolate()); -} - -v8::Local V8ValueConverter::ToV8ValueImpl( - v8::Isolate* isolate, - const base::Value* value) const { - switch (value->type()) { - case base::Value::Type::NONE: - return v8::Null(isolate); - - case base::Value::Type::BOOLEAN: { - bool val = value->GetBool(); - return v8::Boolean::New(isolate, val); - } - - case base::Value::Type::INTEGER: { - int val = value->GetInt(); - return v8::Integer::New(isolate, val); - } - - case base::Value::Type::DOUBLE: { - double val = value->GetDouble(); - return v8::Number::New(isolate, val); - } - - case base::Value::Type::STRING: { - std::string val = value->GetString(); - return v8::String::NewFromUtf8(isolate, val.c_str(), - v8::NewStringType::kNormal, val.length()) - .ToLocalChecked(); - } - - case base::Value::Type::LIST: - return ToV8Array(isolate, static_cast(value)); - - case base::Value::Type::DICTIONARY: - return ToV8Object(isolate, - static_cast(value)); - - case base::Value::Type::BINARY: - return ToArrayBuffer(isolate, static_cast(value)); - - default: - LOG(ERROR) << "Unexpected value type: " << value->type(); - return v8::Null(isolate); - } -} - -v8::Local V8ValueConverter::ToV8Array( - v8::Isolate* isolate, - const base::ListValue* val) const { - v8::Local result( - v8::Array::New(isolate, val->GetListDeprecated().size())); - auto context = isolate->GetCurrentContext(); - - for (size_t i = 0; i < val->GetListDeprecated().size(); ++i) { - const base::Value& child = val->GetListDeprecated()[i]; - - v8::Local child_v8 = ToV8ValueImpl(isolate, &child); - - v8::TryCatch try_catch(isolate); - result->Set(context, static_cast(i), child_v8).Check(); - if (try_catch.HasCaught()) - LOG(ERROR) << "Setter for index " << i << " threw an exception."; - } - - return result; -} - -v8::Local V8ValueConverter::ToV8Object( - v8::Isolate* isolate, - const base::DictionaryValue* val) const { - gin_helper::Dictionary result = gin::Dictionary::CreateEmpty(isolate); - result.SetHidden("simple", true); - - for (base::DictionaryValue::Iterator iter(*val); !iter.IsAtEnd(); - iter.Advance()) { - const std::string& key = iter.key(); - v8::Local child_v8 = ToV8ValueImpl(isolate, &iter.value()); - - v8::TryCatch try_catch(isolate); - result.Set(key, child_v8); - if (try_catch.HasCaught()) { - LOG(ERROR) << "Setter for property " << key.c_str() << " threw an " - << "exception."; - } - } - - return result.GetHandle(); -} - -v8::Local V8ValueConverter::ToArrayBuffer( - v8::Isolate* isolate, - const base::Value* value) const { - const auto* data = reinterpret_cast(value->GetBlob().data()); - size_t length = value->GetBlob().size(); - - if (NodeBindings::IsInitialized()) { - return node::Buffer::Copy(isolate, data, length).ToLocalChecked(); - } - - if (length > node::Buffer::kMaxLength) { - return v8::Local(); - } - auto context = isolate->GetCurrentContext(); - auto array_buffer = v8::ArrayBuffer::New(isolate, length); - std::shared_ptr backing_store = - array_buffer->GetBackingStore(); - memcpy(backing_store->Data(), data, length); - // From this point, if something goes wrong(can't find Buffer class for - // example) we'll simply return a Uint8Array based on the created ArrayBuffer. - // This can happen if no preload script was specified to the renderer. - gin_helper::Dictionary global(isolate, context->Global()); - v8::Local buffer_value; - - // Get the Buffer class stored as a hidden value in the global object. We'll - // use it return a browserified Buffer. - if (!global.GetHidden("Buffer", &buffer_value) || - !buffer_value->IsFunction()) { - return v8::Uint8Array::New(array_buffer, 0, length); - } - - gin::Dictionary buffer_class( - isolate, - buffer_value->ToObject(isolate->GetCurrentContext()).ToLocalChecked()); - v8::Local from_value; - if (!buffer_class.Get("from", &from_value) || !from_value->IsFunction()) { - return v8::Uint8Array::New(array_buffer, 0, length); - } - - v8::Local args[] = {array_buffer}; - auto func = from_value.As(); - auto result = func->Call(context, v8::Null(isolate), std::size(args), args); - if (!result.IsEmpty()) { - return result.ToLocalChecked(); - } - - return v8::Uint8Array::New(array_buffer, 0, length); -} - -std::unique_ptr V8ValueConverter::FromV8ValueImpl( - FromV8ValueState* state, - v8::Local val, - v8::Isolate* isolate) const { - FromV8ValueState::Level state_level(state); - if (state->HasReachedMaxRecursionDepth()) - return nullptr; - - if (val->IsExternal()) - return std::make_unique(); - - if (val->IsNull()) - return std::make_unique(); - - auto context = isolate->GetCurrentContext(); - - if (val->IsBoolean()) - return std::make_unique(val->ToBoolean(isolate)->Value()); - - if (val->IsInt32()) - return std::make_unique(val.As()->Value()); - - if (val->IsNumber()) { - double val_as_double = val.As()->Value(); - if (!std::isfinite(val_as_double)) - return nullptr; - return std::make_unique(val_as_double); - } - - if (val->IsString()) { - v8::String::Utf8Value utf8(isolate, val); - return std::make_unique(std::string(*utf8, utf8.length())); - } - - if (val->IsUndefined()) - // JSON.stringify ignores undefined. - return nullptr; - - if (val->IsDate()) { - v8::Date* date = v8::Date::Cast(*val); - v8::Local toISOString = - date->Get(context, v8::String::NewFromUtf8(isolate, "toISOString", - v8::NewStringType::kNormal) - .ToLocalChecked()) - .ToLocalChecked(); - if (toISOString->IsFunction()) { - v8::MaybeLocal result = - toISOString.As()->Call(context, val, 0, nullptr); - if (!result.IsEmpty()) { - v8::String::Utf8Value utf8(isolate, result.ToLocalChecked()); - return std::make_unique(std::string(*utf8, utf8.length())); - } - } - } - - if (val->IsRegExp()) { - if (!reg_exp_allowed_) - // JSON.stringify converts to an object. - return FromV8Object(val.As(), state, isolate); - return std::make_unique(*v8::String::Utf8Value(isolate, val)); - } - - // v8::Value doesn't have a ToArray() method for some reason. - if (val->IsArray()) - return FromV8Array(val.As(), state, isolate); - - if (val->IsFunction()) { - if (!function_allowed_) - // JSON.stringify refuses to convert function(){}. - return nullptr; - return FromV8Object(val.As(), state, isolate); - } - - if (node::Buffer::HasInstance(val)) { - return FromNodeBuffer(val, state, isolate); - } - - if (val->IsObject()) { - return FromV8Object(val.As(), state, isolate); - } - - LOG(ERROR) << "Unexpected v8 value type encountered."; - return nullptr; -} - -std::unique_ptr V8ValueConverter::FromV8Array( - v8::Local val, - FromV8ValueState* state, - v8::Isolate* isolate) const { - ScopedUniquenessGuard uniqueness_guard(state, val); - if (!uniqueness_guard.is_valid()) - return std::make_unique(); - - std::unique_ptr scope; - // If val was created in a different context than our current one, change to - // that context, but change back after val is converted. - if (!val->GetCreationContextChecked().IsEmpty() && - val->GetCreationContextChecked() != isolate->GetCurrentContext()) - scope = - std::make_unique(val->GetCreationContextChecked()); - - std::unique_ptr result(new base::ListValue()); - - // Only fields with integer keys are carried over to the ListValue. - for (uint32_t i = 0; i < val->Length(); ++i) { - v8::TryCatch try_catch(isolate); - v8::Local child_v8; - v8::MaybeLocal maybe_child = - val->Get(isolate->GetCurrentContext(), i); - if (try_catch.HasCaught() || !maybe_child.ToLocal(&child_v8)) { - LOG(ERROR) << "Getter for index " << i << " threw an exception."; - child_v8 = v8::Null(isolate); - } - - if (!val->HasRealIndexedProperty(isolate->GetCurrentContext(), i) - .FromMaybe(false)) { - result->Append(base::Value()); - continue; - } - - std::unique_ptr child = - FromV8ValueImpl(state, child_v8, isolate); - if (child) { - result->Append(base::Value::FromUniquePtrValue(std::move(child))); - } else { - // JSON.stringify puts null in places where values don't serialize, for - // example undefined and functions. Emulate that behavior. - result->Append(base::Value()); - } - } - return std::move(result); -} - -std::unique_ptr V8ValueConverter::FromNodeBuffer( - v8::Local value, - FromV8ValueState* state, - v8::Isolate* isolate) const { - std::vector buffer( - node::Buffer::Data(value), - node::Buffer::Data(value) + node::Buffer::Length(value)); - return std::make_unique(std::move(buffer)); -} - -std::unique_ptr V8ValueConverter::FromV8Object( - v8::Local val, - FromV8ValueState* state, - v8::Isolate* isolate) const { - ScopedUniquenessGuard uniqueness_guard(state, val); - if (!uniqueness_guard.is_valid()) - return std::make_unique(); - - std::unique_ptr scope; - // If val was created in a different context than our current one, change to - // that context, but change back after val is converted. - if (!val->GetCreationContextChecked().IsEmpty() && - val->GetCreationContextChecked() != isolate->GetCurrentContext()) - scope = - std::make_unique(val->GetCreationContextChecked()); - - auto result = std::make_unique(); - v8::Local property_names; - if (!val->GetOwnPropertyNames(isolate->GetCurrentContext()) - .ToLocal(&property_names)) { - return std::move(result); - } - - for (uint32_t i = 0; i < property_names->Length(); ++i) { - v8::Local key = - property_names->Get(isolate->GetCurrentContext(), i).ToLocalChecked(); - - // Extend this test to cover more types as necessary and if sensible. - if (!key->IsString() && !key->IsNumber()) { - NOTREACHED() << "Key \"" << *v8::String::Utf8Value(isolate, key) - << "\" " - "is neither a string nor a number"; - continue; - } - - v8::String::Utf8Value name_utf8(isolate, key); - - v8::TryCatch try_catch(isolate); - v8::Local child_v8; - v8::MaybeLocal maybe_child = - val->Get(isolate->GetCurrentContext(), key); - if (try_catch.HasCaught() || !maybe_child.ToLocal(&child_v8)) { - LOG(ERROR) << "Getter for property " << *name_utf8 - << " threw an exception."; - child_v8 = v8::Null(isolate); - } - - std::unique_ptr child = - FromV8ValueImpl(state, child_v8, isolate); - if (!child) - // JSON.stringify skips properties whose values don't serialize, for - // example undefined and functions. Emulate that behavior. - continue; - - // Strip null if asked (and since undefined is turned into null, undefined - // too). The use case for supporting this is JSON-schema support, - // specifically for extensions, where "optional" JSON properties may be - // represented as null, yet due to buggy legacy code elsewhere isn't - // treated as such (potentially causing crashes). For example, the - // "tabs.create" function takes an object as its first argument with an - // optional "windowId" property. - // - // Given just - // - // tabs.create({}) - // - // this will work as expected on code that only checks for the existence of - // a "windowId" property (such as that legacy code). However given - // - // tabs.create({windowId: null}) - // - // there *is* a "windowId" property, but since it should be an int, code - // on the browser which doesn't additionally check for null will fail. - // We can avoid all bugs related to this by stripping null. - if (strip_null_from_objects_ && child->is_none()) - continue; - - result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()), - std::move(child)); - } - - return std::move(result); -} - -} // namespace electron diff --git a/shell/common/v8_value_converter.h b/shell/common/v8_value_converter.h deleted file mode 100644 index 5a1c5e21b9..0000000000 --- a/shell/common/v8_value_converter.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2013 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ELECTRON_SHELL_COMMON_V8_VALUE_CONVERTER_H_ -#define ELECTRON_SHELL_COMMON_V8_VALUE_CONVERTER_H_ - -#include - -#include "base/compiler_specific.h" -#include "v8/include/v8.h" - -namespace base { -class DictionaryValue; -class ListValue; -class Value; -} // namespace base - -namespace electron { - -class V8ValueConverter { - public: - V8ValueConverter(); - - // disable copy - V8ValueConverter(const V8ValueConverter&) = delete; - V8ValueConverter& operator=(const V8ValueConverter&) = delete; - - void SetRegExpAllowed(bool val); - void SetFunctionAllowed(bool val); - void SetStripNullFromObjects(bool val); - v8::Local ToV8Value(const base::Value* value, - v8::Local context) const; - std::unique_ptr FromV8Value( - v8::Local value, - v8::Local context) const; - - private: - class FromV8ValueState; - class ScopedUniquenessGuard; - - v8::Local ToV8ValueImpl(v8::Isolate* isolate, - const base::Value* value) const; - v8::Local ToV8Array(v8::Isolate* isolate, - const base::ListValue* list) const; - v8::Local ToV8Object( - v8::Isolate* isolate, - const base::DictionaryValue* dictionary) const; - v8::Local ToArrayBuffer(v8::Isolate* isolate, - const base::Value* value) const; - - std::unique_ptr FromV8ValueImpl(FromV8ValueState* state, - v8::Local value, - v8::Isolate* isolate) const; - std::unique_ptr FromV8Array(v8::Local array, - FromV8ValueState* state, - v8::Isolate* isolate) const; - std::unique_ptr FromNodeBuffer(v8::Local value, - FromV8ValueState* state, - v8::Isolate* isolate) const; - std::unique_ptr FromV8Object(v8::Local object, - FromV8ValueState* state, - v8::Isolate* isolate) const; - - // If true, we will convert RegExp JavaScript objects to string. - bool reg_exp_allowed_ = false; - - // If true, we will convert Function JavaScript objects to dictionaries. - bool function_allowed_ = false; - - // If true, undefined and null values are ignored when converting v8 objects - // into Values. - bool strip_null_from_objects_ = false; -}; - -} // namespace electron - -#endif // ELECTRON_SHELL_COMMON_V8_VALUE_CONVERTER_H_ diff --git a/spec-main/api-system-preferences-spec.ts b/spec-main/api-system-preferences-spec.ts index 38a16045dd..d050e40d81 100644 --- a/spec-main/api-system-preferences-spec.ts +++ b/spec-main/api-system-preferences-spec.ts @@ -46,7 +46,6 @@ describe('systemPreferences module', () => { const badDefaults = [ 1, null, - new Date(), { one: null } ];