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

Side by Side Diff: chrome/browser/extensions/api/declarative_content/content_condition.cc

Issue 11547033: Implement declarativeContent API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync past refactoring and fix build+tests Created 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/declarative_content/content_condition.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/stringprintf.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/api/declarative_content/content_constants.h"
12 #include "chrome/common/extensions/matcher/url_matcher.h"
13 #include "chrome/common/extensions/matcher/url_matcher_factory.h"
14
15 namespace keys = extensions::declarative_content_constants;
16
17 namespace {
18 static extensions::URLMatcherConditionSet::ID g_next_id = 0;
19
20 // TODO(jyasskin): improve error messaging to give more meaningful messages
21 // to the extension developer.
22 // Error messages:
23 const char kExpectedDictionary[] = "A condition has to be a dictionary.";
24 const char kConditionWithoutInstanceType[] = "A condition had no instanceType";
25 const char kExpectedOtherConditionType[] = "Expected a condition of type "
26 "declarativeContent.PageStateMatcher";
27 const char kUnknownConditionAttribute[] = "Unknown condition attribute '%s'";
28 const char kInvalidTypeOfParamter[] = "Attribute '%s' has an invalid type";
29 } // namespace
30
31 namespace extensions {
32
33 namespace keys = declarative_content_constants;
34
35 RendererContentMatchData::RendererContentMatchData() {}
36 RendererContentMatchData::~RendererContentMatchData() {}
37
38 //
39 // ContentCondition
40 //
41
42 ContentCondition::ContentCondition(
43 scoped_refptr<URLMatcherConditionSet> url_matcher_conditions,
44 const std::vector<std::string>& css_rules)
45 : url_matcher_conditions_(url_matcher_conditions),
46 css_rules_(css_rules) {
47 CHECK(url_matcher_conditions.get());
48 }
49
50 ContentCondition::~ContentCondition() {}
51
52 bool ContentCondition::IsFulfilled(
53 const std::set<URLMatcherConditionSet::ID>& url_matches,
54 const RendererContentMatchData& renderer_data) const {
55 if (!ContainsKey(url_matches, url_matcher_conditions_->id()))
56 return false;
57
58 // All attributes must be fulfilled for a fulfilled condition.
59 for (std::vector<std::string>::const_iterator i =
60 css_rules_.begin(); i != css_rules_.end(); ++i) {
61 if (!ContainsKey(renderer_data.css_rules, *i))
62 return false;
63 }
64 return true;
65 }
66
67 // static
68 scoped_ptr<ContentCondition> ContentCondition::Create(
69 URLMatcherConditionFactory* url_matcher_condition_factory,
70 const base::Value& condition,
71 std::string* error) {
72 const base::DictionaryValue* condition_dict = NULL;
73 if (!condition.GetAsDictionary(&condition_dict)) {
74 *error = kExpectedDictionary;
75 return scoped_ptr<ContentCondition>(NULL);
76 }
77
78 // Verify that we are dealing with a Condition whose type we understand.
79 std::string instance_type;
80 if (!condition_dict->GetString(keys::kInstanceType, &instance_type)) {
81 *error = kConditionWithoutInstanceType;
82 return scoped_ptr<ContentCondition>(NULL);
83 }
84 if (instance_type != keys::kPageStateMatcherType) {
85 *error = kExpectedOtherConditionType;
86 return scoped_ptr<ContentCondition>(NULL);
87 }
88
89 scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set;
90 std::vector<std::string> css_rules;
91
92 for (base::DictionaryValue::Iterator iter(*condition_dict);
93 iter.HasNext(); iter.Advance()) {
94 const std::string& condition_attribute_name = iter.key();
95 const Value& condition_attribute_value = iter.value();
96 if (condition_attribute_name == keys::kInstanceType) {
97 // Skip this.
98 } else if (condition_attribute_name == keys::kPageUrl) {
99 const base::DictionaryValue* dict = NULL;
100 if (!condition_attribute_value.GetAsDictionary(&dict)) {
101 *error = base::StringPrintf(kInvalidTypeOfParamter,
102 condition_attribute_name.c_str());
103 } else {
104 url_matcher_condition_set =
105 URLMatcherFactory::CreateFromURLFilterDictionary(
106 url_matcher_condition_factory, dict, ++g_next_id, error);
107 }
108 } else if (condition_attribute_name == keys::kCss) {
109 const base::ListValue* css_rules_value = NULL;
110 if (!condition_attribute_value.GetAsList(&css_rules_value)) {
111 *error = base::StringPrintf(kInvalidTypeOfParamter,
112 condition_attribute_name.c_str());
113 }
114 for (size_t i = 0; i < css_rules_value->GetSize(); ++i) {
115 std::string css_rule;
116 if (!css_rules_value->GetString(i, &css_rule)) {
117 *error = base::StringPrintf(kInvalidTypeOfParamter,
118 condition_attribute_name.c_str());
119 break;
120 }
121 css_rules.push_back(css_rule);
122 }
123 } else {
124 *error = base::StringPrintf(kUnknownConditionAttribute,
125 condition_attribute_name.c_str());
126 }
127 if (!error->empty())
128 return scoped_ptr<ContentCondition>(NULL);
129 }
130
131 if (!url_matcher_condition_set) {
132 URLMatcherConditionSet::Conditions url_matcher_conditions;
133 url_matcher_conditions.insert(
134 url_matcher_condition_factory->CreateHostPrefixCondition(""));
135 url_matcher_condition_set =
136 new URLMatcherConditionSet(++g_next_id, url_matcher_conditions);
137 }
138 return scoped_ptr<ContentCondition>(
139 new ContentCondition(url_matcher_condition_set, css_rules));
140 }
141
142 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698