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

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

Powered by Google App Engine
This is Rietveld 408576698