| Index: chrome/browser/extensions/api/declarative_content/declarative_content_rule.cc
|
| diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_rule.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_rule.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8cdce6416149a65d2f3fbff05a349daa46f0e871
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_rule.cc
|
| @@ -0,0 +1,226 @@
|
| +// Copyright 2015 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/declarative_content_rule.h"
|
| +
|
| +#include <limits>
|
| +
|
| +#include "base/time/time.h"
|
| +#include "extensions/common/extension.h"
|
| +
|
| +namespace extensions {
|
| +
|
| +//
|
| +// DeclarativeContentConditionSet
|
| +//
|
| +
|
| +bool DeclarativeContentConditionSet::IsFulfilled(
|
| + url_matcher::URLMatcherConditionSet::ID url_match_trigger,
|
| + const RendererContentMatchData& match_data) const {
|
| + if (url_match_trigger == -1) {
|
| + // Invalid trigger -- indication that we should only check conditions
|
| + // without URL attributes.
|
| + for (const ContentCondition* condition : conditions_without_urls_) {
|
| + if (condition->IsFulfilled(match_data))
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + URLMatcherIdToCondition::const_iterator triggered =
|
| + match_id_to_condition_.find(url_match_trigger);
|
| + return (triggered != match_id_to_condition_.end() &&
|
| + triggered->second->IsFulfilled(match_data));
|
| +}
|
| +
|
| +void DeclarativeContentConditionSet::GetURLMatcherConditionSets(
|
| + url_matcher::URLMatcherConditionSet::Vector* condition_sets) const {
|
| + for (const linked_ptr<const ContentCondition>& condition : conditions_)
|
| + condition->GetURLMatcherConditionSets(condition_sets);
|
| +}
|
| +
|
| +// static
|
| +scoped_ptr<DeclarativeContentConditionSet>
|
| +DeclarativeContentConditionSet::Create(
|
| + const Extension* extension,
|
| + url_matcher::URLMatcherConditionFactory* url_matcher_condition_factory,
|
| + const Values& condition_values,
|
| + std::string* error) {
|
| + Conditions result;
|
| +
|
| + for (const linked_ptr<base::Value>& value : condition_values) {
|
| + CHECK(value.get());
|
| + scoped_ptr<ContentCondition> condition = ContentCondition::Create(
|
| + extension, url_matcher_condition_factory, *value, error);
|
| + if (!error->empty())
|
| + return scoped_ptr<DeclarativeContentConditionSet>();
|
| + result.push_back(make_linked_ptr(condition.release()));
|
| + }
|
| +
|
| + URLMatcherIdToCondition match_id_to_condition;
|
| + std::vector<const ContentCondition*> conditions_without_urls;
|
| + url_matcher::URLMatcherConditionSet::Vector condition_sets;
|
| +
|
| + for (const linked_ptr<const ContentCondition>& condition : result) {
|
| + condition_sets.clear();
|
| + condition->GetURLMatcherConditionSets(&condition_sets);
|
| + if (condition_sets.empty()) {
|
| + conditions_without_urls.push_back(condition.get());
|
| + } else {
|
| + for (const scoped_refptr<url_matcher::URLMatcherConditionSet>& match_set :
|
| + condition_sets)
|
| + match_id_to_condition[match_set->id()] = condition.get();
|
| + }
|
| + }
|
| +
|
| + return make_scoped_ptr(new DeclarativeContentConditionSet(
|
| + result, match_id_to_condition, conditions_without_urls));
|
| +}
|
| +
|
| +DeclarativeContentConditionSet::~DeclarativeContentConditionSet() {
|
| +}
|
| +
|
| +DeclarativeContentConditionSet::DeclarativeContentConditionSet(
|
| + const Conditions& conditions,
|
| + const URLMatcherIdToCondition& match_id_to_condition,
|
| + const std::vector<const ContentCondition*>& conditions_without_urls)
|
| + : match_id_to_condition_(match_id_to_condition),
|
| + conditions_(conditions),
|
| + conditions_without_urls_(conditions_without_urls) {}
|
| +
|
| +//
|
| +// DeclarativeContentActionSet
|
| +//
|
| +
|
| +DeclarativeContentActionSet::DeclarativeContentActionSet(const Actions& actions)
|
| + : actions_(actions) {}
|
| +
|
| +DeclarativeContentActionSet::~DeclarativeContentActionSet() {}
|
| +
|
| +// static
|
| +scoped_ptr<DeclarativeContentActionSet>
|
| +DeclarativeContentActionSet::Create(content::BrowserContext* browser_context,
|
| + const Extension* extension,
|
| + const Values& action_values,
|
| + std::string* error,
|
| + bool* bad_message) {
|
| + *error = "";
|
| + *bad_message = false;
|
| + Actions result;
|
| +
|
| + for (const linked_ptr<base::Value>& value : action_values) {
|
| + CHECK(value.get());
|
| + scoped_refptr<const ContentAction> action =
|
| + ContentAction::Create(browser_context, extension, *value, error,
|
| + bad_message);
|
| + if (!error->empty() || *bad_message)
|
| + return scoped_ptr<DeclarativeContentActionSet>();
|
| + result.push_back(action);
|
| + }
|
| +
|
| + return make_scoped_ptr(new DeclarativeContentActionSet(result));
|
| +}
|
| +
|
| +void DeclarativeContentActionSet::Apply(
|
| + const std::string& extension_id,
|
| + const base::Time& extension_install_time,
|
| + ContentAction::ApplyInfo* apply_info) const {
|
| + for (const scoped_refptr<const ContentAction>& action : actions_)
|
| + action->Apply(extension_id, extension_install_time, apply_info);
|
| +}
|
| +
|
| +void DeclarativeContentActionSet::Reapply(
|
| + const std::string& extension_id,
|
| + const base::Time& extension_install_time,
|
| + ContentAction::ApplyInfo* apply_info) const {
|
| + for (const scoped_refptr<const ContentAction>& action : actions_)
|
| + action->Reapply(extension_id, extension_install_time, apply_info);
|
| +}
|
| +
|
| +void DeclarativeContentActionSet::Revert(
|
| + const std::string& extension_id,
|
| + const base::Time& extension_install_time,
|
| + ContentAction::ApplyInfo* apply_info) const {
|
| + for (const scoped_refptr<const ContentAction>& action : actions_)
|
| + action->Revert(extension_id, extension_install_time, apply_info);
|
| +}
|
| +
|
| +//
|
| +// DeclarativeContentRule
|
| +//
|
| +
|
| +DeclarativeContentRule::DeclarativeContentRule(
|
| + const GlobalRuleId& id,
|
| + const Tags& tags,
|
| + base::Time extension_installation_time,
|
| + scoped_ptr<ConditionSet> conditions,
|
| + scoped_ptr<ActionSet> actions,
|
| + Priority priority)
|
| + : id_(id),
|
| + tags_(tags),
|
| + extension_installation_time_(extension_installation_time),
|
| + conditions_(conditions.release()),
|
| + actions_(actions.release()),
|
| + priority_(priority) {
|
| + CHECK(conditions_.get());
|
| + CHECK(actions_.get());
|
| +}
|
| +
|
| +DeclarativeContentRule::~DeclarativeContentRule() {}
|
| +
|
| +// static
|
| +scoped_ptr<DeclarativeContentRule> DeclarativeContentRule::Create(
|
| + url_matcher::URLMatcherConditionFactory* url_matcher_condition_factory,
|
| + content::BrowserContext* browser_context,
|
| + const Extension* extension,
|
| + base::Time extension_installation_time,
|
| + linked_ptr<JsonRule> rule,
|
| + ConsistencyChecker check_consistency,
|
| + std::string* error) {
|
| + scoped_ptr<DeclarativeContentRule> error_result;
|
| +
|
| + scoped_ptr<ConditionSet> conditions = ConditionSet::Create(
|
| + extension, url_matcher_condition_factory, rule->conditions, error);
|
| + if (!error->empty())
|
| + return error_result.Pass();
|
| + CHECK(conditions.get());
|
| +
|
| + bool bad_message = false;
|
| + scoped_ptr<ActionSet> actions =
|
| + ActionSet::Create(
|
| + browser_context, extension, rule->actions, error, &bad_message);
|
| + if (bad_message) {
|
| + // TODO(battre) Export concept of bad_message to caller, the extension
|
| + // should be killed in case it is true.
|
| + *error = "An action of a rule set had an invalid "
|
| + "structure that should have been caught by the JSON validator.";
|
| + return error_result.Pass();
|
| + }
|
| + if (!error->empty() || bad_message)
|
| + return error_result.Pass();
|
| + CHECK(actions.get());
|
| +
|
| + if (!check_consistency.is_null() &&
|
| + !check_consistency.Run(conditions.get(), actions.get(), error)) {
|
| + DCHECK(!error->empty());
|
| + return error_result.Pass();
|
| + }
|
| +
|
| + CHECK(rule->priority.get());
|
| + int priority = *(rule->priority);
|
| +
|
| + GlobalRuleId rule_id(extension->id(), *(rule->id));
|
| + Tags tags = rule->tags ? *rule->tags : Tags();
|
| + return scoped_ptr<DeclarativeContentRule>(
|
| + new DeclarativeContentRule(rule_id, tags, extension_installation_time,
|
| + conditions.Pass(), actions.Pass(), priority));
|
| +}
|
| +
|
| +void DeclarativeContentRule::Apply(ContentAction::ApplyInfo* apply_info) const {
|
| + return actions_->Apply(extension_id(),
|
| + extension_installation_time_,
|
| + apply_info);
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|