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"
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
{
16 // TODO(jyasskin): improve error messaging to give more meaningful messages
17 // to the extension developer.
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'";
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
,
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
)
65 const auto loc
= predicate_factories
.find(predicate_name
);
66 if (loc
!= predicate_factories
.end())
67 predicates
.push_back(loc
->second
->CreatePredicate(extension
,
71 *error
= base::StringPrintf(kUnknownConditionAttribute
,
72 predicate_name
.c_str());
75 return scoped_ptr
<ContentCondition
>();
78 return scoped_ptr
<ContentCondition
>(new ContentCondition(predicates
.Pass()));
81 } // namespace extensions