Chromium Code Reviews| Index: chrome/browser/extensions/api/declarative_content/content_condition.cc |
| diff --git a/chrome/browser/extensions/api/declarative_content/content_condition.cc b/chrome/browser/extensions/api/declarative_content/content_condition.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2c818d077c8ceb3ae664aecb1378338ef9508a89 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/api/declarative_content/content_condition.cc |
| @@ -0,0 +1,140 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/extensions/api/declarative_content/content_condition.h" |
| + |
| +#include "base/bind.h" |
|
battre
2012/12/15 11:54:10
nit: can you check whether all of these are needed
Jeffrey Yasskin
2013/01/17 09:22:56
Done.
|
| +#include "base/logging.h" |
| +#include "base/stringprintf.h" |
| +#include "base/values.h" |
| +#include "chrome/browser/extensions/api/declarative_content/content_constants.h" |
| +#include "chrome/common/extensions/matcher/url_matcher.h" |
| +#include "chrome/common/extensions/matcher/url_matcher_factory.h" |
| + |
| +namespace keys = extensions::declarative_content_constants; |
| + |
| +namespace { |
| +static extensions::URLMatcherConditionSet::ID g_next_id = 0; |
| + |
| +// TODO(jyasskin): improve error messaging to give more meaningful messages |
| +// to the extension developer. |
| +// Error messages: |
| +const char kExpectedDictionary[] = "A condition has to be a dictionary."; |
| +const char kConditionWithoutInstanceType[] = "A condition had no instanceType"; |
| +const char kExpectedOtherConditionType[] = "Expected a condition of type " |
| + "declarativeContent.PageStateMatcher"; |
| +const char kUnknownConditionAttribute[] = "Unknown condition attribute '%s'"; |
| +const char kInvalidTypeOfParamter[] = "Attribute '%s' has an invalid type"; |
| +} // namespace |
| + |
| +namespace extensions { |
| + |
| +namespace keys = declarative_content_constants; |
| + |
| +RendererContentMatchData::RendererContentMatchData() {} |
| +RendererContentMatchData::~RendererContentMatchData() {} |
| + |
| +// |
| +// ContentCondition |
| +// |
| + |
| +ContentCondition::ContentCondition( |
| + scoped_refptr<URLMatcherConditionSet> url_matcher_conditions, |
| + const std::vector<std::string>& css_rules) |
| + : url_matcher_conditions_(url_matcher_conditions), |
| + css_rules_(css_rules) { |
| + CHECK(url_matcher_conditions.get()); |
| +} |
| + |
| +ContentCondition::~ContentCondition() {} |
| + |
| +bool ContentCondition::IsFulfilled( |
| + const RendererContentMatchData& renderer_data) const { |
| + // Assume the URL matches or this condition wouldn't get checked. |
| + |
| + // All attributes must be fulfilled for a fulfilled condition. |
| + for (std::vector<std::string>::const_iterator i = |
| + css_rules_.begin(); i != css_rules_.end(); ++i) { |
| + if (!ContainsKey(renderer_data.css_rules, *i)) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +// static |
| +scoped_ptr<ContentCondition> ContentCondition::Create( |
| + URLMatcherConditionFactory* url_matcher_condition_factory, |
| + const base::Value& condition, |
| + std::string* error) { |
| + const base::DictionaryValue* condition_dict = NULL; |
| + if (!condition.GetAsDictionary(&condition_dict)) { |
| + *error = kExpectedDictionary; |
| + return scoped_ptr<ContentCondition>(NULL); |
| + } |
| + |
| + // Verify that we are dealing with a Condition whose type we understand. |
| + std::string instance_type; |
| + if (!condition_dict->GetString(keys::kInstanceType, &instance_type)) { |
| + *error = kConditionWithoutInstanceType; |
| + return scoped_ptr<ContentCondition>(NULL); |
| + } |
| + if (instance_type != keys::kPageStateMatcherType) { |
| + *error = kExpectedOtherConditionType; |
| + return scoped_ptr<ContentCondition>(NULL); |
| + } |
| + |
| + scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set; |
| + std::vector<std::string> css_rules; |
| + |
| + for (base::DictionaryValue::Iterator iter(*condition_dict); |
| + iter.HasNext(); iter.Advance()) { |
| + const std::string& condition_attribute_name = iter.key(); |
| + const Value& condition_attribute_value = iter.value(); |
| + if (condition_attribute_name == keys::kInstanceType) { |
| + // Skip this. |
| + } else if (condition_attribute_name == keys::kPageUrl) { |
| + const base::DictionaryValue* dict = NULL; |
| + if (!condition_attribute_value.GetAsDictionary(&dict)) { |
| + *error = base::StringPrintf(kInvalidTypeOfParamter, |
| + condition_attribute_name.c_str()); |
| + } else { |
| + url_matcher_condition_set = |
| + URLMatcherFactory::CreateFromURLFilterDictionary( |
| + url_matcher_condition_factory, dict, ++g_next_id, error); |
| + } |
| + } else if (condition_attribute_name == keys::kCss) { |
| + const base::ListValue* css_rules_value = NULL; |
| + if (!condition_attribute_value.GetAsList(&css_rules_value)) { |
| + *error = base::StringPrintf(kInvalidTypeOfParamter, |
| + condition_attribute_name.c_str()); |
| + } |
| + for (size_t i = 0; i < css_rules_value->GetSize(); ++i) { |
| + std::string css_rule; |
| + if (!css_rules_value->GetString(i, &css_rule)) { |
| + *error = base::StringPrintf(kInvalidTypeOfParamter, |
| + condition_attribute_name.c_str()); |
| + break; |
| + } |
| + css_rules.push_back(css_rule); |
| + } |
| + } else { |
| + *error = base::StringPrintf(kUnknownConditionAttribute, |
| + condition_attribute_name.c_str()); |
| + } |
| + if (!error->empty()) |
| + return scoped_ptr<ContentCondition>(NULL); |
| + } |
| + |
| + if (!url_matcher_condition_set) { |
| + URLMatcherConditionSet::Conditions url_matcher_conditions; |
| + url_matcher_conditions.insert( |
| + url_matcher_condition_factory->CreateHostPrefixCondition("")); |
| + url_matcher_condition_set = |
| + new URLMatcherConditionSet(++g_next_id, url_matcher_conditions); |
| + } |
| + return scoped_ptr<ContentCondition>( |
| + new ContentCondition(url_matcher_condition_set, css_rules)); |
| +} |
| + |
| +} // namespace extensions |