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