Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / declarative_content / content_condition.cc
blob5f217cba18cfcb4ebd5e1a29d77dabccb417ab47
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.
5 #include "chrome/browser/extensions/api/declarative_content/content_condition.h"
7 #include "base/bind.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/values.h"
10 #include "chrome/browser/extensions/api/declarative_content/content_constants.h"
12 namespace extensions {
14 namespace {
16 // TODO(jyasskin): improve error messaging to give more meaningful messages
17 // to the extension developer.
18 // Error messages:
19 const char kExpectedDictionary[] = "A condition has to be a dictionary.";
20 const char kConditionWithoutInstanceType[] = "A condition had no instanceType";
21 const char kExpectedOtherConditionType[] = "Expected a condition of type "
22 "declarativeContent.PageStateMatcher";
23 const char kUnknownConditionAttribute[] = "Unknown condition attribute '%s'";
25 } // namespace
27 ContentCondition::ContentCondition(
28 ScopedVector<const ContentPredicate> predicates)
29 : predicates(predicates.Pass()) {
32 ContentCondition::~ContentCondition() {}
34 scoped_ptr<ContentCondition> CreateContentCondition(
35 const Extension* extension,
36 const std::map<std::string, ContentPredicateFactory*>& predicate_factories,
37 const base::Value& api_condition,
38 std::string* error) {
39 const base::DictionaryValue* api_condition_dict = nullptr;
40 if (!api_condition.GetAsDictionary(&api_condition_dict)) {
41 *error = kExpectedDictionary;
42 return scoped_ptr<ContentCondition>();
45 // Verify that we are dealing with a Condition whose type we understand.
46 std::string instance_type;
47 if (!api_condition_dict->GetString(
48 declarative_content_constants::kInstanceType, &instance_type)) {
49 *error = kConditionWithoutInstanceType;
50 return scoped_ptr<ContentCondition>();
52 if (instance_type != declarative_content_constants::kPageStateMatcherType) {
53 *error = kExpectedOtherConditionType;
54 return scoped_ptr<ContentCondition>();
57 ScopedVector<const ContentPredicate> predicates;
58 for (base::DictionaryValue::Iterator iter(*api_condition_dict);
59 !iter.IsAtEnd(); iter.Advance()) {
60 const std::string& predicate_name = iter.key();
61 const base::Value& predicate_value = iter.value();
62 if (predicate_name == declarative_content_constants::kInstanceType)
63 continue;
65 const auto loc = predicate_factories.find(predicate_name);
66 if (loc != predicate_factories.end())
67 predicates.push_back(loc->second->CreatePredicate(extension,
68 predicate_value,
69 error));
70 else
71 *error = base::StringPrintf(kUnknownConditionAttribute,
72 predicate_name.c_str());
74 if (!error->empty())
75 return scoped_ptr<ContentCondition>();
78 return scoped_ptr<ContentCondition>(new ContentCondition(predicates.Pass()));
81 } // namespace extensions