Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / declarative_content / declarative_content_css_condition_tracker.cc
blobe69e27f1c6336bf741b367959c85e56685208e16
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/declarative_content_css_condition_tracker.h"
7 #include <algorithm>
9 #include "base/stl_util.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/extensions/api/declarative_content/declarative_content_condition_tracker_delegate.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "content/public/browser/navigation_details.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_source.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "extensions/common/extension_messages.h"
18 #include "ipc/ipc_message.h"
19 #include "ipc/ipc_message_macros.h"
21 namespace extensions {
24 // PerWebContentsTracker
27 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
28 PerWebContentsTracker(
29 content::WebContents* contents,
30 const RequestEvaluationCallback& request_evaluation,
31 const WebContentsDestroyedCallback& web_contents_destroyed)
32 : WebContentsObserver(contents),
33 request_evaluation_(request_evaluation),
34 web_contents_destroyed_(web_contents_destroyed) {
37 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
38 ~PerWebContentsTracker() {
41 void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
42 OnWebContentsNavigation(const content::LoadCommittedDetails& details,
43 const content::FrameNavigateParams& params) {
44 if (details.is_in_page) {
45 // Within-page navigations don't change the set of elements that
46 // exist, and we only support filtering on the top-level URL, so
47 // this can't change which rules match.
48 return;
51 // Top-level navigation produces a new document. Initially, the
52 // document's empty, so no CSS rules match. The renderer will send
53 // an ExtensionHostMsg_OnWatchedPageChange later if any CSS rules
54 // match.
55 matching_css_selectors_.clear();
56 request_evaluation_.Run(web_contents());
59 void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
60 UpdateMatchingCssSelectorsForTesting(
61 const std::vector<std::string>& matching_css_selectors) {
62 matching_css_selectors_ = matching_css_selectors;
63 request_evaluation_.Run(web_contents());
66 bool
67 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
68 OnMessageReceived(
69 const IPC::Message& message) {
70 bool handled = true;
71 IPC_BEGIN_MESSAGE_MAP(PerWebContentsTracker, message)
72 IPC_MESSAGE_HANDLER(ExtensionHostMsg_OnWatchedPageChange,
73 OnWatchedPageChange)
74 IPC_MESSAGE_UNHANDLED(handled = false)
75 IPC_END_MESSAGE_MAP()
76 return handled;
79 void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
80 WebContentsDestroyed() {
81 web_contents_destroyed_.Run(web_contents());
84 void
85 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
86 OnWatchedPageChange(
87 const std::vector<std::string>& css_selectors) {
88 matching_css_selectors_ = css_selectors;
89 request_evaluation_.Run(web_contents());
93 // DeclarativeContentCssConditionTracker
96 DeclarativeContentCssConditionTracker::DeclarativeContentCssConditionTracker(
97 content::BrowserContext* context,
98 DeclarativeContentConditionTrackerDelegate* delegate)
99 : context_(context),
100 delegate_(delegate) {
101 registrar_.Add(this,
102 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
103 content::NotificationService::AllBrowserContextsAndSources());
106 DeclarativeContentCssConditionTracker::
107 ~DeclarativeContentCssConditionTracker() {}
109 // We use the sorted propery of the set for equality checks with
110 // watched_css_selectors_, which is guaranteed to be sorted because it's set
111 // from the set contents.
112 void DeclarativeContentCssConditionTracker::SetWatchedCssSelectors(
113 const std::set<std::string>& new_watched_css_selectors) {
114 if (new_watched_css_selectors.size() != watched_css_selectors_.size() ||
115 !std::equal(new_watched_css_selectors.begin(),
116 new_watched_css_selectors.end(),
117 watched_css_selectors_.begin())) {
118 watched_css_selectors_.assign(new_watched_css_selectors.begin(),
119 new_watched_css_selectors.end());
121 for (content::RenderProcessHost::iterator it(
122 content::RenderProcessHost::AllHostsIterator());
123 !it.IsAtEnd();
124 it.Advance()) {
125 InstructRenderProcessIfManagingBrowserContext(it.GetCurrentValue());
130 void DeclarativeContentCssConditionTracker::TrackForWebContents(
131 content::WebContents* contents) {
132 per_web_contents_tracker_[contents] =
133 make_linked_ptr(new PerWebContentsTracker(
134 contents,
135 base::Bind(&DeclarativeContentConditionTrackerDelegate::
136 RequestEvaluation,
137 base::Unretained(delegate_)),
138 base::Bind(&DeclarativeContentCssConditionTracker::
139 DeletePerWebContentsTracker,
140 base::Unretained(this))));
141 // Note: the condition is always false until we receive OnWatchedPageChange,
142 // so there's no need to evaluate it here.
145 void DeclarativeContentCssConditionTracker::OnWebContentsNavigation(
146 content::WebContents* contents,
147 const content::LoadCommittedDetails& details,
148 const content::FrameNavigateParams& params) {
149 DCHECK(ContainsKey(per_web_contents_tracker_, contents));
150 per_web_contents_tracker_[contents]->OnWebContentsNavigation(details, params);
153 void DeclarativeContentCssConditionTracker::GetMatchingCssSelectors(
154 content::WebContents* contents,
155 base::hash_set<std::string>* css_selectors) {
156 DCHECK(ContainsKey(per_web_contents_tracker_, contents));
157 const std::vector<std::string>& matching_css_selectors =
158 per_web_contents_tracker_[contents]->matching_css_selectors();
159 css_selectors->insert(matching_css_selectors.begin(),
160 matching_css_selectors.end());
163 void DeclarativeContentCssConditionTracker::
164 UpdateMatchingCssSelectorsForTesting(
165 content::WebContents* contents,
166 const std::vector<std::string>& matching_css_selectors) {
167 DCHECK(ContainsKey(per_web_contents_tracker_, contents));
168 per_web_contents_tracker_[contents]->
169 UpdateMatchingCssSelectorsForTesting(matching_css_selectors);
172 void DeclarativeContentCssConditionTracker::Observe(
173 int type,
174 const content::NotificationSource& source,
175 const content::NotificationDetails& details) {
176 switch (type) {
177 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: {
178 content::RenderProcessHost* process =
179 content::Source<content::RenderProcessHost>(source).ptr();
180 InstructRenderProcessIfManagingBrowserContext(process);
181 break;
186 void DeclarativeContentCssConditionTracker::
187 InstructRenderProcessIfManagingBrowserContext(
188 content::RenderProcessHost* process) {
189 if (delegate_->ShouldManageConditionsForBrowserContext(
190 process->GetBrowserContext())) {
191 process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_));
195 void DeclarativeContentCssConditionTracker::DeletePerWebContentsTracker(
196 content::WebContents* contents) {
197 DCHECK(ContainsKey(per_web_contents_tracker_, contents));
198 per_web_contents_tracker_.erase(contents);
201 } // namespace extensions