| Index: chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc
|
| diff --git a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc
|
| index da88ec27948b99e923df6742fd0b29970a7d72de..e0912b51456689ef0649ccdddaa819eb69ab2160 100644
|
| --- a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc
|
| +++ b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc
|
| @@ -8,7 +8,6 @@
|
| #include "chrome/browser/extensions/api/declarative_content/content_action.h"
|
| #include "chrome/browser/extensions/api/declarative_content/content_condition.h"
|
| #include "chrome/browser/extensions/api/declarative_content/content_constants.h"
|
| -#include "chrome/browser/extensions/extension_tab_util.h"
|
| #include "chrome/browser/extensions/extension_util.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/ui/browser.h"
|
| @@ -17,12 +16,10 @@
|
| #include "content/public/browser/navigation_details.h"
|
| #include "content/public/browser/notification_service.h"
|
| #include "content/public/browser/notification_source.h"
|
| -#include "content/public/browser/render_process_host.h"
|
| #include "content/public/browser/web_contents.h"
|
| #include "extensions/browser/api/declarative/rules_registry_service.h"
|
| #include "extensions/browser/extension_registry.h"
|
| #include "extensions/browser/extension_system.h"
|
| -#include "extensions/common/extension_messages.h"
|
|
|
| using url_matcher::URLMatcherConditionSet;
|
|
|
| @@ -35,13 +32,11 @@ ChromeContentRulesRegistry::ChromeContentRulesRegistry(
|
| declarative_content_constants::kOnPageChanged,
|
| content::BrowserThread::UI,
|
| cache_delegate,
|
| - RulesRegistryService::kDefaultRulesRegistryID) {
|
| + RulesRegistryService::kDefaultRulesRegistryID),
|
| + css_condition_tracker_(browser_context, this) {
|
| extension_info_map_ = ExtensionSystem::Get(browser_context)->info_map();
|
|
|
| registrar_.Add(this,
|
| - content::NOTIFICATION_RENDERER_PROCESS_CREATED,
|
| - content::NotificationService::AllBrowserContextsAndSources());
|
| - registrar_.Add(this,
|
| content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
|
| content::NotificationService::AllBrowserContextsAndSources());
|
| }
|
| @@ -51,62 +46,41 @@ void ChromeContentRulesRegistry::Observe(
|
| const content::NotificationSource& source,
|
| const content::NotificationDetails& details) {
|
| switch (type) {
|
| - case content::NOTIFICATION_RENDERER_PROCESS_CREATED: {
|
| - content::RenderProcessHost* process =
|
| - content::Source<content::RenderProcessHost>(source).ptr();
|
| - InstructRenderProcessIfSameBrowserContext(process);
|
| - break;
|
| - }
|
| case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
|
| content::WebContents* tab =
|
| content::Source<content::WebContents>(source).ptr();
|
| // Note that neither non-tab WebContents nor tabs from other browser
|
| // contexts will be in the map.
|
| active_rules_.erase(tab);
|
| - matching_css_selectors_.erase(tab);
|
| break;
|
| }
|
| }
|
| }
|
|
|
| -void ChromeContentRulesRegistry::Apply(
|
| - content::WebContents* contents,
|
| - const std::vector<std::string>& matching_css_selectors) {
|
| - matching_css_selectors_[contents] = matching_css_selectors;
|
| -
|
| +void ChromeContentRulesRegistry::RequestEvaluation(
|
| + content::WebContents* contents) {
|
| EvaluateConditionsForTab(contents);
|
| }
|
|
|
| -void ChromeContentRulesRegistry::DidNavigateMainFrame(
|
| - content::WebContents* contents,
|
| - const content::LoadCommittedDetails& details,
|
| - const content::FrameNavigateParams& params) {
|
| - OnTabNavigation(contents, details.is_in_page);
|
| +bool ChromeContentRulesRegistry::ShouldManageConditionsForBrowserContext(
|
| + content::BrowserContext* context) {
|
| + return ManagingRulesForBrowserContext(context);
|
| +}
|
| +
|
| +void ChromeContentRulesRegistry::MonitorWebContentsForRuleEvaluation(
|
| + content::WebContents* contents) {
|
| + // We rely on active_rules_ to have a key-value pair for |contents| to know
|
| + // which WebContents we are working with.
|
| + active_rules_[contents] = std::set<const ContentRule*>();
|
| + css_condition_tracker_.TrackForWebContents(contents);
|
| }
|
|
|
| -void ChromeContentRulesRegistry::DidNavigateMainFrameOfOriginalContext(
|
| +void ChromeContentRulesRegistry::DidNavigateMainFrame(
|
| content::WebContents* contents,
|
| const content::LoadCommittedDetails& details,
|
| const content::FrameNavigateParams& params) {
|
| - DCHECK(browser_context()->IsOffTheRecord());
|
| - OnTabNavigation(contents, details.is_in_page);
|
| -}
|
| -
|
| -void ChromeContentRulesRegistry::OnTabNavigation(content::WebContents* tab,
|
| - bool is_in_page_navigation) {
|
| - if (is_in_page_navigation) {
|
| - // Within-page navigations don't change the set of elements that
|
| - // exist, and we only support filtering on the top-level URL, so
|
| - // this can't change which rules match.
|
| - return;
|
| - }
|
| -
|
| - // Top-level navigation produces a new document. Initially, the
|
| - // document's empty, so no CSS rules match. The renderer will send
|
| - // an ExtensionHostMsg_OnWatchedPageChange later if any CSS rules
|
| - // match.
|
| - matching_css_selectors_[tab].clear();
|
| - EvaluateConditionsForTab(tab);
|
| + if (ContainsKey(active_rules_, contents))
|
| + css_condition_tracker_.OnWebContentsNavigation(contents, details, params);
|
| }
|
|
|
| bool ChromeContentRulesRegistry::ManagingRulesForBrowserContext(
|
| @@ -219,7 +193,7 @@ std::string ChromeContentRulesRegistry::AddRulesImpl(
|
| }
|
| url_matcher_.AddConditionSets(all_new_condition_sets);
|
|
|
| - UpdateConditionCache();
|
| + UpdateCssSelectorsFromRules();
|
| EvaluateConditionsForAllTabs();
|
|
|
| return std::string();
|
| @@ -266,7 +240,7 @@ std::string ChromeContentRulesRegistry::RemoveRulesImpl(
|
| // Clear URLMatcher based on condition_set_ids that are not needed any more.
|
| url_matcher_.RemoveConditionSets(remove_from_url_matcher);
|
|
|
| - UpdateConditionCache();
|
| + UpdateCssSelectorsFromRules();
|
|
|
| return std::string();
|
| }
|
| @@ -286,7 +260,7 @@ std::string ChromeContentRulesRegistry::RemoveAllRulesImpl(
|
| return RemoveRulesImpl(extension_id, rule_identifiers);
|
| }
|
|
|
| -void ChromeContentRulesRegistry::UpdateConditionCache() {
|
| +void ChromeContentRulesRegistry::UpdateCssSelectorsFromRules() {
|
| std::set<std::string> css_selectors; // We rely on this being sorted.
|
| for (const std::pair<ContentRule::GlobalRuleId,
|
| linked_ptr<const ContentRule>>& rule_id_rule_pair :
|
| @@ -301,34 +275,15 @@ void ChromeContentRulesRegistry::UpdateConditionCache() {
|
| }
|
| }
|
|
|
| - if (css_selectors.size() != watched_css_selectors_.size() ||
|
| - !std::equal(css_selectors.begin(),
|
| - css_selectors.end(),
|
| - watched_css_selectors_.begin())) {
|
| - watched_css_selectors_.assign(css_selectors.begin(), css_selectors.end());
|
| -
|
| - for (content::RenderProcessHost::iterator it(
|
| - content::RenderProcessHost::AllHostsIterator());
|
| - !it.IsAtEnd();
|
| - it.Advance()) {
|
| - content::RenderProcessHost* process = it.GetCurrentValue();
|
| - InstructRenderProcessIfSameBrowserContext(process);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ChromeContentRulesRegistry::InstructRenderProcessIfSameBrowserContext(
|
| - content::RenderProcessHost* process) {
|
| - if (ManagingRulesForBrowserContext(process->GetBrowserContext()))
|
| - process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_));
|
| + css_condition_tracker_.SetWatchedCssSelectors(css_selectors);
|
| }
|
|
|
| void ChromeContentRulesRegistry::EvaluateConditionsForTab(
|
| content::WebContents* tab) {
|
| extensions::RendererContentMatchData renderer_data;
|
| renderer_data.page_url_matches = url_matcher_.MatchURL(tab->GetURL());
|
| - renderer_data.css_selectors.insert(matching_css_selectors_[tab].begin(),
|
| - matching_css_selectors_[tab].end());
|
| + css_condition_tracker_.GetMatchingCssSelectors(tab,
|
| + &renderer_data.css_selectors);
|
| std::set<const ContentRule*> matching_rules =
|
| GetMatches(renderer_data, tab->GetBrowserContext()->IsOffTheRecord());
|
| if (matching_rules.empty() && !ContainsKey(active_rules_, tab))
|
| @@ -352,22 +307,14 @@ void ChromeContentRulesRegistry::EvaluateConditionsForTab(
|
| }
|
|
|
| if (matching_rules.empty())
|
| - active_rules_.erase(tab);
|
| + active_rules_[tab].clear();
|
| else
|
| swap(matching_rules, prev_matching_rules);
|
| }
|
|
|
| void ChromeContentRulesRegistry::EvaluateConditionsForAllTabs() {
|
| - for (chrome::BrowserIterator it; !it.done(); it.Next()) {
|
| - Browser* browser = *it;
|
| - if (!ManagingRulesForBrowserContext(browser->profile()))
|
| - continue;
|
| -
|
| - for (int i = 0, tab_count = browser->tab_strip_model()->count();
|
| - i < tab_count;
|
| - ++i)
|
| - EvaluateConditionsForTab(browser->tab_strip_model()->GetWebContentsAt(i));
|
| - }
|
| + for (const auto& web_contents_active_rules_pair : active_rules_)
|
| + EvaluateConditionsForTab(web_contents_active_rules_pair.first);
|
| }
|
|
|
| bool ChromeContentRulesRegistry::IsEmpty() const {
|
| @@ -375,6 +322,21 @@ bool ChromeContentRulesRegistry::IsEmpty() const {
|
| url_matcher_.IsEmpty();
|
| }
|
|
|
| +void ChromeContentRulesRegistry::UpdateMatchingCssSelectorsForTesting(
|
| + content::WebContents* contents,
|
| + const std::vector<std::string>& matching_css_selectors) {
|
| + css_condition_tracker_.UpdateMatchingCssSelectorsForTesting(
|
| + contents,
|
| + matching_css_selectors);
|
| +}
|
| +
|
| +size_t ChromeContentRulesRegistry::GetActiveRulesCountForTesting() {
|
| + size_t count = 0;
|
| + for (auto web_contents_rules_pair : active_rules_)
|
| + count += web_contents_rules_pair.second.size();
|
| + return count;
|
| +}
|
| +
|
| ChromeContentRulesRegistry::~ChromeContentRulesRegistry() {
|
| }
|
|
|
|
|