refactor: use constexpr lookup tables in gin helper (#38818)
* feat: add gin_helper::FromV8WithLookup() feat: add gin_helper::FromV8WithLowerLookup() * refactor: use constexpr lookup table in gin Converters
This commit is contained in:
parent
41ab5f327f
commit
97132ece33
6 changed files with 255 additions and 400 deletions
|
@ -8,12 +8,14 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/fixed_flat_map.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "gin/converter.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/keyboard_util.h"
|
||||
|
@ -130,86 +132,77 @@ struct Converter<blink::WebMouseEvent::Button> {
|
|||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
blink::WebMouseEvent::Button* out) {
|
||||
std::string button = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (button == "left")
|
||||
*out = blink::WebMouseEvent::Button::kLeft;
|
||||
else if (button == "middle")
|
||||
*out = blink::WebMouseEvent::Button::kMiddle;
|
||||
else if (button == "right")
|
||||
*out = blink::WebMouseEvent::Button::kRight;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
using Val = blink::WebMouseEvent::Button;
|
||||
static constexpr auto Lookup =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, Val>({
|
||||
{"left", Val::kLeft},
|
||||
{"middle", Val::kMiddle},
|
||||
{"right", Val::kRight},
|
||||
});
|
||||
return FromV8WithLowerLookup(isolate, val, Lookup, out);
|
||||
}
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
|
||||
// these are the modifier names we both accept and return
|
||||
static constexpr auto Modifiers =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, blink::WebInputEvent::Modifiers>({
|
||||
{"alt", blink::WebInputEvent::Modifiers::kAltKey},
|
||||
{"capslock", blink::WebInputEvent::Modifiers::kCapsLockOn},
|
||||
{"control", blink::WebInputEvent::Modifiers::kControlKey},
|
||||
{"isautorepeat", blink::WebInputEvent::Modifiers::kIsAutoRepeat},
|
||||
{"iskeypad", blink::WebInputEvent::Modifiers::kIsKeyPad},
|
||||
{"left", blink::WebInputEvent::Modifiers::kIsLeft},
|
||||
{"leftbuttondown", blink::WebInputEvent::Modifiers::kLeftButtonDown},
|
||||
{"meta", blink::WebInputEvent::Modifiers::kMetaKey},
|
||||
{"middlebuttondown", blink::WebInputEvent::Modifiers::kMiddleButtonDown},
|
||||
{"numlock", blink::WebInputEvent::Modifiers::kNumLockOn},
|
||||
{"right", blink::WebInputEvent::Modifiers::kIsRight},
|
||||
{"rightbuttondown", blink::WebInputEvent::Modifiers::kRightButtonDown},
|
||||
{"shift", blink::WebInputEvent::Modifiers::kShiftKey},
|
||||
// TODO(nornagon): the rest of the modifiers
|
||||
});
|
||||
|
||||
// these are the modifier names we accept but do not return
|
||||
static constexpr auto ModifierAliases =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, blink::WebInputEvent::Modifiers>({
|
||||
{"cmd", blink::WebInputEvent::Modifiers::kMetaKey},
|
||||
{"command", blink::WebInputEvent::Modifiers::kMetaKey},
|
||||
{"ctrl", blink::WebInputEvent::Modifiers::kControlKey},
|
||||
});
|
||||
|
||||
static constexpr auto ReferrerPolicies =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, network::mojom::ReferrerPolicy>({
|
||||
{"default", network::mojom::ReferrerPolicy::kDefault},
|
||||
{"no-referrer", network::mojom::ReferrerPolicy::kNever},
|
||||
{"no-referrer-when-downgrade", network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade},
|
||||
{"origin", network::mojom::ReferrerPolicy::kOrigin},
|
||||
{"same-origin", network::mojom::ReferrerPolicy::kSameOrigin},
|
||||
{"strict-origin", network::mojom::ReferrerPolicy::kStrictOrigin},
|
||||
{"strict-origin-when-cross-origin", network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin},
|
||||
{"unsafe-url", network::mojom::ReferrerPolicy::kAlways},
|
||||
});
|
||||
|
||||
// clang-format on
|
||||
|
||||
template <>
|
||||
struct Converter<blink::WebInputEvent::Modifiers> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
blink::WebInputEvent::Modifiers* out) {
|
||||
std::string modifier = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (modifier == "shift")
|
||||
*out = blink::WebInputEvent::Modifiers::kShiftKey;
|
||||
else if (modifier == "control" || modifier == "ctrl")
|
||||
*out = blink::WebInputEvent::Modifiers::kControlKey;
|
||||
else if (modifier == "alt")
|
||||
*out = blink::WebInputEvent::Modifiers::kAltKey;
|
||||
else if (modifier == "meta" || modifier == "command" || modifier == "cmd")
|
||||
*out = blink::WebInputEvent::Modifiers::kMetaKey;
|
||||
else if (modifier == "iskeypad")
|
||||
*out = blink::WebInputEvent::Modifiers::kIsKeyPad;
|
||||
else if (modifier == "isautorepeat")
|
||||
*out = blink::WebInputEvent::Modifiers::kIsAutoRepeat;
|
||||
else if (modifier == "leftbuttondown")
|
||||
*out = blink::WebInputEvent::Modifiers::kLeftButtonDown;
|
||||
else if (modifier == "middlebuttondown")
|
||||
*out = blink::WebInputEvent::Modifiers::kMiddleButtonDown;
|
||||
else if (modifier == "rightbuttondown")
|
||||
*out = blink::WebInputEvent::Modifiers::kRightButtonDown;
|
||||
else if (modifier == "capslock")
|
||||
*out = blink::WebInputEvent::Modifiers::kCapsLockOn;
|
||||
else if (modifier == "numlock")
|
||||
*out = blink::WebInputEvent::Modifiers::kNumLockOn;
|
||||
else if (modifier == "left")
|
||||
*out = blink::WebInputEvent::Modifiers::kIsLeft;
|
||||
else if (modifier == "right")
|
||||
*out = blink::WebInputEvent::Modifiers::kIsRight;
|
||||
// TODO(nornagon): the rest of the modifiers
|
||||
return true;
|
||||
return FromV8WithLowerLookup(isolate, val, Modifiers, out) ||
|
||||
FromV8WithLowerLookup(isolate, val, ModifierAliases, out);
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<base::StringPiece> ModifiersToArray(int modifiers) {
|
||||
using Modifiers = blink::WebInputEvent::Modifiers;
|
||||
std::vector<base::StringPiece> modifier_strings;
|
||||
if (modifiers & Modifiers::kShiftKey)
|
||||
modifier_strings.push_back("shift");
|
||||
if (modifiers & Modifiers::kControlKey)
|
||||
modifier_strings.push_back("control");
|
||||
if (modifiers & Modifiers::kAltKey)
|
||||
modifier_strings.push_back("alt");
|
||||
if (modifiers & Modifiers::kMetaKey)
|
||||
modifier_strings.push_back("meta");
|
||||
if (modifiers & Modifiers::kIsKeyPad)
|
||||
modifier_strings.push_back("iskeypad");
|
||||
if (modifiers & Modifiers::kIsAutoRepeat)
|
||||
modifier_strings.push_back("isautorepeat");
|
||||
if (modifiers & Modifiers::kLeftButtonDown)
|
||||
modifier_strings.push_back("leftbuttondown");
|
||||
if (modifiers & Modifiers::kMiddleButtonDown)
|
||||
modifier_strings.push_back("middlebuttondown");
|
||||
if (modifiers & Modifiers::kRightButtonDown)
|
||||
modifier_strings.push_back("rightbuttondown");
|
||||
if (modifiers & Modifiers::kCapsLockOn)
|
||||
modifier_strings.push_back("capslock");
|
||||
if (modifiers & Modifiers::kNumLockOn)
|
||||
modifier_strings.push_back("numlock");
|
||||
if (modifiers & Modifiers::kIsLeft)
|
||||
modifier_strings.push_back("left");
|
||||
if (modifiers & Modifiers::kIsRight)
|
||||
modifier_strings.push_back("right");
|
||||
// TODO(nornagon): the rest of the modifiers
|
||||
|
||||
for (const auto& [name, mask] : Modifiers)
|
||||
if (mask & modifiers)
|
||||
modifier_strings.emplace_back(name);
|
||||
|
||||
return modifier_strings;
|
||||
}
|
||||
|
||||
|
@ -553,26 +546,11 @@ v8::Local<v8::Value> Converter<blink::WebCacheResourceTypeStats>::ToV8(
|
|||
v8::Local<v8::Value> Converter<network::mojom::ReferrerPolicy>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const network::mojom::ReferrerPolicy& in) {
|
||||
switch (in) {
|
||||
case network::mojom::ReferrerPolicy::kDefault:
|
||||
return StringToV8(isolate, "default");
|
||||
case network::mojom::ReferrerPolicy::kAlways:
|
||||
return StringToV8(isolate, "unsafe-url");
|
||||
case network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade:
|
||||
return StringToV8(isolate, "no-referrer-when-downgrade");
|
||||
case network::mojom::ReferrerPolicy::kNever:
|
||||
return StringToV8(isolate, "no-referrer");
|
||||
case network::mojom::ReferrerPolicy::kOrigin:
|
||||
return StringToV8(isolate, "origin");
|
||||
case network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin:
|
||||
return StringToV8(isolate, "strict-origin-when-cross-origin");
|
||||
case network::mojom::ReferrerPolicy::kSameOrigin:
|
||||
return StringToV8(isolate, "same-origin");
|
||||
case network::mojom::ReferrerPolicy::kStrictOrigin:
|
||||
return StringToV8(isolate, "strict-origin");
|
||||
default:
|
||||
return StringToV8(isolate, "no-referrer");
|
||||
}
|
||||
for (const auto& [name, val] : ReferrerPolicies)
|
||||
if (val == in)
|
||||
return StringToV8(isolate, name);
|
||||
|
||||
return StringToV8(isolate, "no-referrer");
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -580,26 +558,7 @@ bool Converter<network::mojom::ReferrerPolicy>::FromV8(
|
|||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
network::mojom::ReferrerPolicy* out) {
|
||||
std::string policy = base::ToLowerASCII(gin::V8ToString(isolate, val));
|
||||
if (policy == "default")
|
||||
*out = network::mojom::ReferrerPolicy::kDefault;
|
||||
else if (policy == "unsafe-url")
|
||||
*out = network::mojom::ReferrerPolicy::kAlways;
|
||||
else if (policy == "no-referrer-when-downgrade")
|
||||
*out = network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade;
|
||||
else if (policy == "no-referrer")
|
||||
*out = network::mojom::ReferrerPolicy::kNever;
|
||||
else if (policy == "origin")
|
||||
*out = network::mojom::ReferrerPolicy::kOrigin;
|
||||
else if (policy == "strict-origin-when-cross-origin")
|
||||
*out = network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin;
|
||||
else if (policy == "same-origin")
|
||||
*out = network::mojom::ReferrerPolicy::kSameOrigin;
|
||||
else if (policy == "strict-origin")
|
||||
*out = network::mojom::ReferrerPolicy::kStrictOrigin;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
return FromV8WithLowerLookup(isolate, val, ReferrerPolicies, out);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -689,57 +689,28 @@ v8::Local<v8::Value> Converter<net::IPEndPoint>::ToV8(
|
|||
bool Converter<net::DnsQueryType>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
net::DnsQueryType* out) {
|
||||
std::string query_type;
|
||||
if (!ConvertFromV8(isolate, val, &query_type))
|
||||
return false;
|
||||
|
||||
if (query_type == "A") {
|
||||
*out = net::DnsQueryType::A;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "AAAA") {
|
||||
*out = net::DnsQueryType::AAAA;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
static constexpr auto Lookup =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, net::DnsQueryType>({
|
||||
{"A", net::DnsQueryType::A},
|
||||
{"AAAA", net::DnsQueryType::AAAA},
|
||||
});
|
||||
return FromV8WithLookup(isolate, val, Lookup, out);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<net::HostResolverSource>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
net::HostResolverSource* out) {
|
||||
std::string query_type;
|
||||
if (!ConvertFromV8(isolate, val, &query_type))
|
||||
return false;
|
||||
|
||||
if (query_type == "any") {
|
||||
*out = net::HostResolverSource::ANY;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "system") {
|
||||
*out = net::HostResolverSource::SYSTEM;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "dns") {
|
||||
*out = net::HostResolverSource::DNS;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "mdns") {
|
||||
*out = net::HostResolverSource::MULTICAST_DNS;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "localOnly") {
|
||||
*out = net::HostResolverSource::LOCAL_ONLY;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
using Val = net::HostResolverSource;
|
||||
static constexpr auto Lookup =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, Val>({
|
||||
{"any", Val::ANY},
|
||||
{"dns", Val::DNS},
|
||||
{"localOnly", Val::LOCAL_ONLY},
|
||||
{"mdns", Val::MULTICAST_DNS},
|
||||
{"system", Val::SYSTEM},
|
||||
});
|
||||
return FromV8WithLookup(isolate, val, Lookup, out);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -747,26 +718,14 @@ bool Converter<network::mojom::ResolveHostParameters::CacheUsage>::FromV8(
|
|||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
network::mojom::ResolveHostParameters::CacheUsage* out) {
|
||||
std::string query_type;
|
||||
if (!ConvertFromV8(isolate, val, &query_type))
|
||||
return false;
|
||||
|
||||
if (query_type == "allowed") {
|
||||
*out = network::mojom::ResolveHostParameters::CacheUsage::ALLOWED;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "staleAllowed") {
|
||||
*out = network::mojom::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "disallowed") {
|
||||
*out = network::mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
using Val = network::mojom::ResolveHostParameters::CacheUsage;
|
||||
static constexpr auto Lookup =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, Val>({
|
||||
{"allowed", Val::ALLOWED},
|
||||
{"disallowed", Val::DISALLOWED},
|
||||
{"staleAllowed", Val::STALE_ALLOWED},
|
||||
});
|
||||
return FromV8WithLookup(isolate, val, Lookup, out);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -774,21 +733,13 @@ bool Converter<network::mojom::SecureDnsPolicy>::FromV8(
|
|||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
network::mojom::SecureDnsPolicy* out) {
|
||||
std::string query_type;
|
||||
if (!ConvertFromV8(isolate, val, &query_type))
|
||||
return false;
|
||||
|
||||
if (query_type == "allow") {
|
||||
*out = network::mojom::SecureDnsPolicy::ALLOW;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query_type == "disable") {
|
||||
*out = network::mojom::SecureDnsPolicy::DISABLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
using Val = network::mojom::SecureDnsPolicy;
|
||||
static constexpr auto Lookup =
|
||||
base::MakeFixedFlatMapSorted<base::StringPiece, Val>({
|
||||
{"allow", Val::ALLOW},
|
||||
{"disable", Val::DISABLE},
|
||||
});
|
||||
return FromV8WithLookup(isolate, val, Lookup, out);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -5,12 +5,16 @@
|
|||
#ifndef ELECTRON_SHELL_COMMON_GIN_CONVERTERS_STD_CONVERTER_H_
|
||||
#define ELECTRON_SHELL_COMMON_GIN_CONVERTERS_STD_CONVERTER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "gin/converter.h"
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "base/strings/string_util_win.h"
|
||||
#endif
|
||||
|
@ -210,6 +214,61 @@ struct Converter<std::wstring> {
|
|||
};
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Get a key from `key_val` and check `lookup` for a matching entry.
|
||||
// Return true iff a match is found, and set `*out` to the entry's value.
|
||||
template <typename KeyType, typename Out, typename Map>
|
||||
bool FromV8WithLookup(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> key_val,
|
||||
const Map& table,
|
||||
Out* out,
|
||||
std::function<void(KeyType&)> key_transform = {}) {
|
||||
static_assert(std::is_same_v<typename Map::mapped_type, Out>);
|
||||
|
||||
auto key = KeyType{};
|
||||
if (!ConvertFromV8(isolate, key_val, &key))
|
||||
return false;
|
||||
|
||||
if (key_transform)
|
||||
key_transform(key);
|
||||
|
||||
if (const auto* iter = table.find(key); iter != table.end()) {
|
||||
*out = iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Convert `key_val to a string key and check `lookup` for a matching entry.
|
||||
// Return true iff a match is found, and set `*out` to the entry's value.
|
||||
template <typename Out, typename Map>
|
||||
bool FromV8WithLookup(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> key_val,
|
||||
const Map& table,
|
||||
Out* out) {
|
||||
return detail::FromV8WithLookup<std::string>(isolate, key_val, table, out);
|
||||
}
|
||||
|
||||
// Convert `key_val` to a lowercase string key and check `lookup` for a matching
|
||||
// entry. Return true iff a match is found, and set `*out` to the entry's value.
|
||||
template <typename Out, typename Map>
|
||||
bool FromV8WithLowerLookup(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> key_val,
|
||||
const Map& table,
|
||||
Out* out) {
|
||||
static constexpr auto to_lower_ascii_inplace = [](std::string& str) {
|
||||
for (auto& ch : str)
|
||||
ch = base::ToLowerASCII(ch);
|
||||
};
|
||||
|
||||
return detail::FromV8WithLookup<std::string>(isolate, key_val, table, out,
|
||||
to_lower_ascii_inplace);
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // ELECTRON_SHELL_COMMON_GIN_CONVERTERS_STD_CONVERTER_H_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue