1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
// Copyright 2015 The Chromium Authors
// 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 <memory>
#include <utility>
#include "base/functional/bind.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "extensions/common/api/declarative/declarative_constants.h"
namespace extensions {
namespace {
// 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'";
} // namespace
ContentCondition::ContentCondition(
std::vector<std::unique_ptr<const ContentPredicate>> predicates)
: predicates(std::move(predicates)) {}
ContentCondition::~ContentCondition() = default;
std::unique_ptr<ContentCondition> CreateContentCondition(
const Extension* extension,
const std::map<std::string, ContentPredicateFactory*>& predicate_factories,
const base::Value& api_condition,
std::string* error) {
if (!api_condition.is_dict()) {
*error = kExpectedDictionary;
return nullptr;
}
const base::Value::Dict& api_condition_dict = api_condition.GetDict();
// Verify that we are dealing with a Condition whose type we understand.
const std::string* instance_type = api_condition_dict.FindString(
declarative_content_constants::kInstanceType);
if (!instance_type) {
*error = kConditionWithoutInstanceType;
return nullptr;
}
if (*instance_type != declarative_content_constants::kPageStateMatcherType) {
*error = kExpectedOtherConditionType;
return nullptr;
}
std::vector<std::unique_ptr<const ContentPredicate>> predicates;
for (const auto iter : api_condition_dict) {
const std::string& predicate_name = iter.first;
const base::Value& predicate_value = iter.second;
if (predicate_name == declarative_content_constants::kInstanceType)
continue;
const auto loc = predicate_factories.find(predicate_name);
if (loc != predicate_factories.end())
predicates.push_back(loc->second->CreatePredicate(extension,
predicate_value,
error));
else
*error = base::StringPrintf(kUnknownConditionAttribute,
predicate_name.c_str());
if (!error->empty())
return nullptr;
}
return std::make_unique<ContentCondition>(std::move(predicates));
}
} // namespace extensions
|