Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(885)

Unified Diff: extensions/renderer/api_binding.cc

Issue 2615773002: [Extensions Bindings] Add enum support (Closed)
Patch Set: nits Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/renderer/api_binding.h ('k') | extensions/renderer/api_binding_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/api_binding.cc
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc
index 9856a8158e731a151d27875cb6721118f9eca6c9..b4b015c34f5a123fae149a2386ed32b02130b3fb 100644
--- a/extensions/renderer/api_binding.cc
+++ b/extensions/renderer/api_binding.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "extensions/common/extension_api.h"
@@ -23,6 +24,31 @@ namespace extensions {
namespace {
+// Returns the name of the enum value for use in JavaScript; JS enum entries use
+// SCREAMING_STYLE.
+std::string GetJSEnumEntryName(const std::string& original) {
+ std::string result;
+ DCHECK(!original.empty());
+ // If the original starts with a digit, prefix it with an underscore.
+ if (base::IsAsciiDigit(original[0]))
+ result.push_back('_');
+ // Given 'myEnum-Foo':
+ for (size_t i = 0; i < original.size(); ++i) {
+ // Add an underscore between camelcased items:
+ // 'myEnum-Foo' -> 'mY_Enum-Foo'
+ if (i > 0 && base::IsAsciiLower(original[i - 1]) &&
+ base::IsAsciiUpper(original[i])) {
+ result.push_back('_');
+ result.push_back(original[i]);
+ } else if (original[i] == '-') { // 'mY_Enum-Foo' -> 'mY_Enum_Foo'
+ result.push_back('_');
+ } else { // 'mY_Enum_Foo' -> 'MY_ENUM_FOO'
+ result.push_back(base::ToUpperASCII(original[i]));
+ }
+ }
+ return result;
+}
+
const char kExtensionAPIPerContextKey[] = "extension_api_binding";
struct APIPerContextData : public base::SupportsUserData::Data {
@@ -88,6 +114,7 @@ APIBinding::APIBinding(const std::string& api_name,
signatures_[name] = base::MakeUnique<APISignature>(*params);
}
}
+
if (type_definitions) {
for (const auto& type : *type_definitions) {
const base::DictionaryValue* type_dict = nullptr;
@@ -97,9 +124,25 @@ APIBinding::APIBinding(const std::string& api_name,
DCHECK(type_refs->find(id) == type_refs->end());
// TODO(devlin): refs are sometimes preceeded by the API namespace; we
// might need to take that into account.
- (*type_refs)[id] = base::MakeUnique<ArgumentSpec>(*type_dict);
+ auto argument_spec = base::MakeUnique<ArgumentSpec>(*type_dict);
+ const std::set<std::string>& enum_values = argument_spec->enum_values();
+ if (!enum_values.empty()) {
+ // Type names may be prefixed by the api name. If so, remove the prefix.
+ base::Optional<std::string> stripped_id;
+ if (base::StartsWith(id, api_name_, base::CompareCase::SENSITIVE))
+ stripped_id = id.substr(api_name_.size() + 1); // +1 for trailing '.'
+ std::vector<EnumEntry>& entries =
+ enums_[stripped_id ? *stripped_id : id];
+ entries.reserve(enum_values.size());
+ for (const auto& enum_value : enum_values) {
+ entries.push_back(
+ std::make_pair(enum_value, GetJSEnumEntryName(enum_value)));
+ }
+ }
+ (*type_refs)[id] = std::move(argument_spec);
}
}
+
if (event_definitions) {
event_names_.reserve(event_definitions->GetSize());
for (const auto& event : *event_definitions) {
@@ -134,6 +177,7 @@ v8::Local<v8::Object> APIBinding::CreateInstance(
per_context_data->SetUserData(kExtensionAPIPerContextKey,
api_data.release());
}
+
for (const auto& sig : signatures_) {
std::string full_method_name =
base::StringPrintf("%s.%s", api_name_.c_str(), sig.first.c_str());
@@ -169,6 +213,22 @@ v8::Local<v8::Object> APIBinding::CreateInstance(
DCHECK(success.FromJust());
}
+ for (const auto& entry : enums_) {
+ // TODO(devlin): Store these on an ObjectTemplate.
+ v8::Local<v8::Object> enum_object = v8::Object::New(isolate);
+ for (const auto& enum_entry : entry.second) {
+ v8::Maybe<bool> success = enum_object->CreateDataProperty(
+ context, gin::StringToSymbol(isolate, enum_entry.second),
+ gin::StringToSymbol(isolate, enum_entry.first));
+ DCHECK(success.IsJust());
+ DCHECK(success.FromJust());
+ }
+ v8::Maybe<bool> success = object->CreateDataProperty(
+ context, gin::StringToSymbol(isolate, entry.first), enum_object);
+ DCHECK(success.IsJust());
+ DCHECK(success.FromJust());
+ }
+
binding_hooks_->InitializeInContext(context, api_name_);
return object;
« no previous file with comments | « extensions/renderer/api_binding.h ('k') | extensions/renderer/api_binding_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698