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

Unified Diff: extensions/common/api/declarative/declarative_manifest_data.cc

Issue 1158693006: Create a mechanism define declarative rules via the extension manifest. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add a manifest handler Created 5 years, 6 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
Index: extensions/common/api/declarative/declarative_manifest_data.cc
diff --git a/extensions/common/api/declarative/declarative_manifest_data.cc b/extensions/common/api/declarative/declarative_manifest_data.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d37857f0144ac641edb605d369b754cf21d84edd
--- /dev/null
+++ b/extensions/common/api/declarative/declarative_manifest_data.cc
@@ -0,0 +1,160 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/common/api/declarative/declarative_manifest_data.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "extensions/common/api/extensions_manifest_types.h"
not at google - send to devlin 2015/06/08 21:44:58 What are you using from this?
danduong 2015/06/09 01:21:26 Done.
+#include "extensions/common/manifest_constants.h"
+
+using base::UTF8ToUTF16;
+
+namespace extensions {
+
+namespace {
+
+std::string ValueTypeToString(base::Value::Type type) {
not at google - send to devlin 2015/06/08 21:44:58 You might as well pass the whole Value into here,
danduong 2015/06/09 01:21:26 Done.
+ static const char* strings[] = {"null",
+ "boolean",
+ "integer",
+ "double",
+ "string",
+ "binary",
+ "dictionary",
+ "list"};
+ CHECK(static_cast<size_t>(type) < arraysize(strings));
+ return std::string(strings[type]);
not at google - send to devlin 2015/06/08 21:44:58 you could also make it return a const char* if you
+}
+
+// Converts a rule defined in the manifest into a JSON internal format. The
+// difference is that actions and conditions use a "type" key to define the
+// type of rule/condition, while the internal format uses a "instanceType" key
+// for this. This function walks through all the conditions and rules to swap
+// the manifest key for the internal key.
+bool ConvertManifestRule(const linked_ptr<DeclarativeManifestData::Rule>& rule,
+ base::string16* error) {
+ auto convert_list = [error](std::vector<linked_ptr<base::Value>>& list) {
+ for (const linked_ptr<base::Value>& value : list) {
+ base::DictionaryValue* dictionary = nullptr;
+ if (!value->GetAsDictionary(&dictionary)) {
+ if (error->length())
+ error->append(UTF8ToUTF16("; "));
+ error->append(UTF8ToUTF16("expected dictionary, got " +
+ ValueTypeToString(value->GetType())));
+ return false;
+ }
+ std::string type;
+ if (!dictionary->GetString("type", &type)) {
+ if (error->length())
+ error->append(UTF8ToUTF16("; "));
+ error->append(UTF8ToUTF16("'type' is required"));
+ return false;
+ }
+ dictionary->Remove("type", nullptr);
+ dictionary->SetString("instanceType", type);
+ }
+ return true;
+ };
+ return convert_list(rule->actions) && convert_list(rule->conditions);
+}
+
+} // namespace
+
+DeclarativeManifestData::DeclarativeManifestData() {
+}
+
+DeclarativeManifestData::~DeclarativeManifestData() {
+}
+
+// static
+DeclarativeManifestData* DeclarativeManifestData::Get(
+ const Extension* extension) {
+ return static_cast<DeclarativeManifestData*>(
+ extension->GetManifestData(manifest_keys::kEventRules));
+}
+
+// static
+scoped_ptr<DeclarativeManifestData> DeclarativeManifestData::FromValue(
+ const base::Value& value,
+ base::string16* error) {
+ // The following is an example of how an event programmatic rule definition
+ // translates to a manifest definition.
+ //
+ // From javascript:
+ //
+ // chrome.declarativeContent.onPageChanged.addRules([{
+ // actions: [
+ // new chrome.declarativeContent.ShowPageAction()
+ // ],
+ // conditions: [
+ // new chrome.declarativeContent.PageStateMatcher({css: ["video"]})
+ // ]
+ // }]);
+ //
+ // In manifest:
+ //
+ // "event_rules": [{
+ // "event" : "declarativeContent.onPageChanged",
+ // "actions" : [{
+ // "type": "declarativeContent.ShowPageAction"
+ // }],
+ // "conditions" : [{
+ // "css": ["video"],
+ // "type" : "declarativeContent.PageStateMatcher"
+ // }]
+ // }]
+ //
+ // The javascript objects get translated into JSON objects with a "type"
+ // field to indicate the instance type. Instead of adding rules to a
+ // specific event list, each rule has an "event" field to indicate which
+ // event it applies to.
+ //
+ scoped_ptr<DeclarativeManifestData> result(new DeclarativeManifestData());
+ const base::ListValue* list = nullptr;
+ if (!value.GetAsList(&list)) {
+ if (error->length())
+ error->append(UTF8ToUTF16("; "));
+ error->append(UTF8ToUTF16("'event_rules' expected list, got " +
+ ValueTypeToString(value.GetType())));
+ return scoped_ptr<DeclarativeManifestData>();
+ }
+
not at google - send to devlin 2015/06/08 21:44:58 There is a lot of code here for generating errors.
danduong 2015/06/09 01:21:26 Done.
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ const base::DictionaryValue* dict = nullptr;
+ if (!list->GetDictionary(i, &dict)) {
+ if (error->length())
+ error->append(base::UTF8ToUTF16("; "));
+ const base::Value* value = nullptr;
+ if (list->Get(i, &value))
+ error->append(base::UTF8ToUTF16("expected dictionary, got " +
+ ValueTypeToString(value->GetType())));
+ else
+ error->append(base::UTF8ToUTF16("expected dictionary"));
+ return scoped_ptr<DeclarativeManifestData>();
+ }
+ std::string event;
+ if (!dict->GetString("event", &event)) {
+ if (error->length())
+ error->append(UTF8ToUTF16("; "));
+ error->append(UTF8ToUTF16("'event' is required"));
+ }
+ linked_ptr<Rule> rule(new Rule());
+ if (Rule::Populate(*dict, rule.get()) && ConvertManifestRule(rule, error)) {
+ result->event_rules_map_[event].push_back(rule);
+ } else {
+ if (error->length())
+ error->append(UTF8ToUTF16("; "));
+ error->append(UTF8ToUTF16("rule failed to populate"));
+ return scoped_ptr<DeclarativeManifestData>();
+ }
+ }
+ return result.Pass();
+}
+
+std::vector<linked_ptr<DeclarativeManifestData::Rule>>&
+DeclarativeManifestData::RulesForEvent(const std::string& event) {
+ return event_rules_map_[event];
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698