Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(473)

Side by Side Diff: chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc

Issue 1159733004: Encapsulate CSS selector declarative content condition tracking (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@stars-declarative-content-range-for
Patch Set: multiple updates Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/extensions/api/declarative_content/declarative_content_ css_condition_tracker.h"
6
7 #include <algorithm>
8
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "content/public/browser/navigation_details.h"
12 #include "content/public/browser/notification_service.h"
13 #include "content/public/browser/notification_source.h"
14 #include "content/public/browser/render_process_host.h"
15 #include "extensions/common/extension_messages.h"
16 #include "ipc/ipc_message.h"
17 #include "ipc/ipc_message_macros.h"
18
19 namespace extensions {
20
21 //
22 // PerWebContentsTracker
23 //
24
25 // Monitors CSS selector matching state on one WebContents.
26 class DeclarativeContentCssConditionTracker::
27 PerWebContentsTracker : public content::WebContentsObserver {
28 public:
29 using RequestEvaluationCallback =
30 DeclarativeContentCssConditionTrackerDelegate::WebContentsCallback;
31 using DestroyingCallback =
32 base::Callback<void(PerWebContentsTracker*)>;
33
34 PerWebContentsTracker(
35 content::WebContents* contents,
36 const RequestEvaluationCallback& request_evaluation,
37 const DestroyingCallback& destroying);
38 ~PerWebContentsTracker() override;
39
40 void OnWebContentsNavigation(const content::LoadCommittedDetails& details,
41 const content::FrameNavigateParams& params);
42
43 // See comment on similar function above.
44 void UpdateMatchingCssSelectorsForTesting(
45 const std::vector<std::string>& matching_css_selectors);
46
47 const std::vector<std::string>& matching_css_selectors() const {
48 return matching_css_selectors_;
49 }
50
51 private:
52 // content::WebContentsObserver overrides.
53 bool OnMessageReceived(const IPC::Message& message) override;
54 void WebContentsDestroyed() override;
55
56 void OnWatchedPageChange(const std::vector<std::string>& css_selectors);
57
58 const RequestEvaluationCallback request_evaluation_;
59 const DestroyingCallback destroying_;
60
61 std::vector<std::string> matching_css_selectors_;
62
63 DISALLOW_COPY_AND_ASSIGN(PerWebContentsTracker);
64 };
65
66 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
67 PerWebContentsTracker(
68 content::WebContents* contents,
69 const RequestEvaluationCallback& request_evaluation,
70 const DestroyingCallback& destroying)
71 : WebContentsObserver(contents),
72 request_evaluation_(request_evaluation),
73 destroying_(destroying) {
74 }
75
76 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
77 ~PerWebContentsTracker() {
78 }
79
80 void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
81 OnWebContentsNavigation(const content::LoadCommittedDetails& details,
82 const content::FrameNavigateParams& params) {
83 if (details.is_in_page) {
84 // Within-page navigations don't change the set of elements that
85 // exist, and we only support filtering on the top-level URL, so
86 // this can't change which rules match.
87 return;
88 }
89
90 // Top-level navigation produces a new document. Initially, the
91 // document's empty, so no CSS rules match. The renderer will send
92 // an ExtensionHostMsg_OnWatchedPageChange later if any CSS rules
93 // match.
94 matching_css_selectors_.clear();
95 request_evaluation_.Run(web_contents());
96 }
97
98 void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
99 UpdateMatchingCssSelectorsForTesting(
100 const std::vector<std::string>& matching_css_selectors) {
101 matching_css_selectors_ = matching_css_selectors;
102 }
103
104 bool
105 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
106 OnMessageReceived(
107 const IPC::Message& message) {
108 bool handled = true;
109 IPC_BEGIN_MESSAGE_MAP(PerWebContentsTracker, message)
110 IPC_MESSAGE_HANDLER(ExtensionHostMsg_OnWatchedPageChange,
111 OnWatchedPageChange)
112 IPC_MESSAGE_UNHANDLED(handled = false)
113 IPC_END_MESSAGE_MAP()
114 return handled;
115 }
116
117 void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
118 WebContentsDestroyed() {
119 destroying_.Run(this);
120 delete this;
121 }
122
123 void
124 DeclarativeContentCssConditionTracker::PerWebContentsTracker::
125 OnWatchedPageChange(
126 const std::vector<std::string>& css_selectors) {
127 matching_css_selectors_ = css_selectors;
128 request_evaluation_.Run(web_contents());
129 }
130
131 //
132 // DeclarativeContentCssConditionTrackerDelegate
133 //
134
135 DeclarativeContentCssConditionTrackerDelegate::
136 DeclarativeContentCssConditionTrackerDelegate() {}
137
138 DeclarativeContentCssConditionTrackerDelegate::
139 ~DeclarativeContentCssConditionTrackerDelegate() {}
140
141 //
142 // DeclarativeContentCssConditionTracker
143 //
144
145 DeclarativeContentCssConditionTracker::DeclarativeContentCssConditionTracker(
146 content::BrowserContext* context,
147 DeclarativeContentCssConditionTrackerDelegate* delegate)
148 : context_(context),
149 delegate_(delegate) {
150 // Observe all the existing WebContents for matched CSS selector changes.
151 delegate_->ForEachWebContents(base::Bind(
152 &DeclarativeContentCssConditionTracker::CreatePerWebContentsTracker,
153 base::Unretained(this)));
154
155 registrar_.Add(this,
156 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
157 content::NotificationService::AllBrowserContextsAndSources());
158 }
159
160 DeclarativeContentCssConditionTracker::
161 ~DeclarativeContentCssConditionTracker() {
162 // All monitored WebContents are expected to be destroyed before this object.
163 DCHECK(per_web_contents_tracker_.empty());
164 }
165
166 // We use the sorted propery of the set for equality checks with
167 // watched_css_selectors_, which is guaranteed to be sorted because it's set
168 // from the set contents.
169 void DeclarativeContentCssConditionTracker::SetWatchedCssSelectors(
170 const std::set<std::string>& new_watched_css_selectors) {
171 if (new_watched_css_selectors.size() != watched_css_selectors_.size() ||
172 !std::equal(new_watched_css_selectors.begin(),
173 new_watched_css_selectors.end(),
174 watched_css_selectors_.begin())) {
175 watched_css_selectors_.assign(new_watched_css_selectors.begin(),
176 new_watched_css_selectors.end());
177
178 for (content::RenderProcessHost::iterator it(
179 content::RenderProcessHost::AllHostsIterator());
180 !it.IsAtEnd();
181 it.Advance()) {
182 InstructRenderProcessIfManagingBrowserContext(it.GetCurrentValue());
183 }
184 }
185 }
186
187 void DeclarativeContentCssConditionTracker::TrackForWebContents(
188 content::WebContents* contents) {
189 CreatePerWebContentsTracker(contents);
190 }
191
192 void DeclarativeContentCssConditionTracker::OnWebContentsNavigation(
193 content::WebContents* contents,
194 const content::LoadCommittedDetails& details,
195 const content::FrameNavigateParams& params) {
196 per_web_contents_tracker_[contents]->OnWebContentsNavigation(details, params);
197 }
198
199 void DeclarativeContentCssConditionTracker::GetMatchingCssSelectors(
200 content::WebContents* contents,
201 base::hash_set<std::string>* css_selectors) {
202 const std::vector<std::string>& matching_css_selectors =
203 per_web_contents_tracker_[contents]->matching_css_selectors();
204 css_selectors->insert(matching_css_selectors.begin(),
205 matching_css_selectors.end());
206 }
207
208 void DeclarativeContentCssConditionTracker::
209 UpdateMatchingCssSelectorsForTesting(
210 content::WebContents* contents,
211 const std::vector<std::string>& matching_css_selectors) {
212 per_web_contents_tracker_[contents]->
213 UpdateMatchingCssSelectorsForTesting(matching_css_selectors);
214 }
215
216 void DeclarativeContentCssConditionTracker::CreatePerWebContentsTracker(
217 content::WebContents* contents) {
218 // This is a weak pointer; PerWebContentsTracker owns itself.
219 per_web_contents_tracker_[contents] =
220 new PerWebContentsTracker(
221 contents,
222 base::Bind(&DeclarativeContentCssConditionTrackerDelegate::
223 RequestEvaluation,
224 base::Unretained(delegate_)),
225 base::Bind(&DeclarativeContentCssConditionTracker::
226 RemovePerWebContentsTracker,
227 base::Unretained(this)));
228 }
229
230 void DeclarativeContentCssConditionTracker::Observe(
231 int type,
232 const content::NotificationSource& source,
233 const content::NotificationDetails& details) {
234 switch (type) {
235 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: {
236 content::RenderProcessHost* process =
237 content::Source<content::RenderProcessHost>(source).ptr();
238 InstructRenderProcessIfManagingBrowserContext(process);
239 break;
240 }
241 }
242 }
243
244 void DeclarativeContentCssConditionTracker::
245 InstructRenderProcessIfManagingBrowserContext(
246 content::RenderProcessHost* process) {
247 if (delegate_->ShouldManageConditionsForBrowserContext(
248 process->GetBrowserContext())) {
249 process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_));
250 }
251 }
252
253 void DeclarativeContentCssConditionTracker::RemovePerWebContentsTracker(
254 PerWebContentsTracker* tracker) {
255 per_web_contents_tracker_.erase(tracker->web_contents());
256 }
257
258 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698