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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extensions/common/api/declarative/declarative_manifest_data.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #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.
9 #include "extensions/common/manifest_constants.h"
10
11 using base::UTF8ToUTF16;
12
13 namespace extensions {
14
15 namespace {
16
17 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.
18 static const char* strings[] = {"null",
19 "boolean",
20 "integer",
21 "double",
22 "string",
23 "binary",
24 "dictionary",
25 "list"};
26 CHECK(static_cast<size_t>(type) < arraysize(strings));
27 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
28 }
29
30 // Converts a rule defined in the manifest into a JSON internal format. The
31 // difference is that actions and conditions use a "type" key to define the
32 // type of rule/condition, while the internal format uses a "instanceType" key
33 // for this. This function walks through all the conditions and rules to swap
34 // the manifest key for the internal key.
35 bool ConvertManifestRule(const linked_ptr<DeclarativeManifestData::Rule>& rule,
36 base::string16* error) {
37 auto convert_list = [error](std::vector<linked_ptr<base::Value>>& list) {
38 for (const linked_ptr<base::Value>& value : list) {
39 base::DictionaryValue* dictionary = nullptr;
40 if (!value->GetAsDictionary(&dictionary)) {
41 if (error->length())
42 error->append(UTF8ToUTF16("; "));
43 error->append(UTF8ToUTF16("expected dictionary, got " +
44 ValueTypeToString(value->GetType())));
45 return false;
46 }
47 std::string type;
48 if (!dictionary->GetString("type", &type)) {
49 if (error->length())
50 error->append(UTF8ToUTF16("; "));
51 error->append(UTF8ToUTF16("'type' is required"));
52 return false;
53 }
54 dictionary->Remove("type", nullptr);
55 dictionary->SetString("instanceType", type);
56 }
57 return true;
58 };
59 return convert_list(rule->actions) && convert_list(rule->conditions);
60 }
61
62 } // namespace
63
64 DeclarativeManifestData::DeclarativeManifestData() {
65 }
66
67 DeclarativeManifestData::~DeclarativeManifestData() {
68 }
69
70 // static
71 DeclarativeManifestData* DeclarativeManifestData::Get(
72 const Extension* extension) {
73 return static_cast<DeclarativeManifestData*>(
74 extension->GetManifestData(manifest_keys::kEventRules));
75 }
76
77 // static
78 scoped_ptr<DeclarativeManifestData> DeclarativeManifestData::FromValue(
79 const base::Value& value,
80 base::string16* error) {
81 // The following is an example of how an event programmatic rule definition
82 // translates to a manifest definition.
83 //
84 // From javascript:
85 //
86 // chrome.declarativeContent.onPageChanged.addRules([{
87 // actions: [
88 // new chrome.declarativeContent.ShowPageAction()
89 // ],
90 // conditions: [
91 // new chrome.declarativeContent.PageStateMatcher({css: ["video"]})
92 // ]
93 // }]);
94 //
95 // In manifest:
96 //
97 // "event_rules": [{
98 // "event" : "declarativeContent.onPageChanged",
99 // "actions" : [{
100 // "type": "declarativeContent.ShowPageAction"
101 // }],
102 // "conditions" : [{
103 // "css": ["video"],
104 // "type" : "declarativeContent.PageStateMatcher"
105 // }]
106 // }]
107 //
108 // The javascript objects get translated into JSON objects with a "type"
109 // field to indicate the instance type. Instead of adding rules to a
110 // specific event list, each rule has an "event" field to indicate which
111 // event it applies to.
112 //
113 scoped_ptr<DeclarativeManifestData> result(new DeclarativeManifestData());
114 const base::ListValue* list = nullptr;
115 if (!value.GetAsList(&list)) {
116 if (error->length())
117 error->append(UTF8ToUTF16("; "));
118 error->append(UTF8ToUTF16("'event_rules' expected list, got " +
119 ValueTypeToString(value.GetType())));
120 return scoped_ptr<DeclarativeManifestData>();
121 }
122
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.
123 for (size_t i = 0; i < list->GetSize(); ++i) {
124 const base::DictionaryValue* dict = nullptr;
125 if (!list->GetDictionary(i, &dict)) {
126 if (error->length())
127 error->append(base::UTF8ToUTF16("; "));
128 const base::Value* value = nullptr;
129 if (list->Get(i, &value))
130 error->append(base::UTF8ToUTF16("expected dictionary, got " +
131 ValueTypeToString(value->GetType())));
132 else
133 error->append(base::UTF8ToUTF16("expected dictionary"));
134 return scoped_ptr<DeclarativeManifestData>();
135 }
136 std::string event;
137 if (!dict->GetString("event", &event)) {
138 if (error->length())
139 error->append(UTF8ToUTF16("; "));
140 error->append(UTF8ToUTF16("'event' is required"));
141 }
142 linked_ptr<Rule> rule(new Rule());
143 if (Rule::Populate(*dict, rule.get()) && ConvertManifestRule(rule, error)) {
144 result->event_rules_map_[event].push_back(rule);
145 } else {
146 if (error->length())
147 error->append(UTF8ToUTF16("; "));
148 error->append(UTF8ToUTF16("rule failed to populate"));
149 return scoped_ptr<DeclarativeManifestData>();
150 }
151 }
152 return result.Pass();
153 }
154
155 std::vector<linked_ptr<DeclarativeManifestData::Rule>>&
156 DeclarativeManifestData::RulesForEvent(const std::string& event) {
157 return event_rules_map_[event];
158 }
159
160 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698