OLD | NEW |
---|---|
(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 | |
OLD | NEW |