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

Unified Diff: chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc

Issue 1166393002: Reland "Encapsulate CSS selector declarative content condition tracking" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkcr
Patch Set: address comments 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e2e474acfe94bf58d031ffcb1116761420638421
--- /dev/null
+++ b/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc
@@ -0,0 +1,208 @@
+// 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_css_condition_tracker.h"
+
+#include <algorithm>
+
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/profiles/profile.h"
+#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 "extensions/common/extension_messages.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_macros.h"
+
+namespace extensions {
+
+//
+// PerWebContentsTracker
+//
+
+DeclarativeContentCssConditionTracker::PerWebContentsTracker::
+PerWebContentsTracker(
+ content::WebContents* contents,
+ const RequestEvaluationCallback& request_evaluation,
+ const WebContentsDestroyedCallback& web_contents_destroyed)
+ : WebContentsObserver(contents),
+ request_evaluation_(request_evaluation),
+ web_contents_destroyed_(web_contents_destroyed) {
+}
+
+DeclarativeContentCssConditionTracker::PerWebContentsTracker::
+~PerWebContentsTracker() {
+}
+
+void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
+OnWebContentsNavigation(const content::LoadCommittedDetails& details,
+ const content::FrameNavigateParams& params) {
+ if (details.is_in_page) {
+ // 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_.clear();
+ request_evaluation_.Run(web_contents());
+}
+
+void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
+UpdateMatchingCssSelectorsForTesting(
+ const std::vector<std::string>& matching_css_selectors) {
+ matching_css_selectors_ = matching_css_selectors;
+ request_evaluation_.Run(web_contents());
+}
+
+bool
+DeclarativeContentCssConditionTracker::PerWebContentsTracker::
+OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PerWebContentsTracker, message)
+ IPC_MESSAGE_HANDLER(ExtensionHostMsg_OnWatchedPageChange,
+ OnWatchedPageChange)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void DeclarativeContentCssConditionTracker::PerWebContentsTracker::
+WebContentsDestroyed() {
+ web_contents_destroyed_.Run(web_contents());
+}
+
+void
+DeclarativeContentCssConditionTracker::PerWebContentsTracker::
+OnWatchedPageChange(
+ const std::vector<std::string>& css_selectors) {
+ matching_css_selectors_ = css_selectors;
+ request_evaluation_.Run(web_contents());
+}
+
+//
+// DeclarativeContentCssConditionTrackerDelegate
+//
+
+DeclarativeContentCssConditionTrackerDelegate::
+DeclarativeContentCssConditionTrackerDelegate() {}
+
+DeclarativeContentCssConditionTrackerDelegate::
+~DeclarativeContentCssConditionTrackerDelegate() {}
+
+//
+// DeclarativeContentCssConditionTracker
+//
+
+DeclarativeContentCssConditionTracker::DeclarativeContentCssConditionTracker(
+ content::BrowserContext* context,
+ DeclarativeContentCssConditionTrackerDelegate* delegate)
+ : context_(context),
+ delegate_(delegate) {
+ registrar_.Add(this,
+ content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+ content::NotificationService::AllBrowserContextsAndSources());
+}
+
+DeclarativeContentCssConditionTracker::
+~DeclarativeContentCssConditionTracker() {}
+
+// We use the sorted propery of the set for equality checks with
+// watched_css_selectors_, which is guaranteed to be sorted because it's set
+// from the set contents.
+void DeclarativeContentCssConditionTracker::SetWatchedCssSelectors(
+ const std::set<std::string>& new_watched_css_selectors) {
+ if (new_watched_css_selectors.size() != watched_css_selectors_.size() ||
+ !std::equal(new_watched_css_selectors.begin(),
+ new_watched_css_selectors.end(),
+ watched_css_selectors_.begin())) {
+ watched_css_selectors_.assign(new_watched_css_selectors.begin(),
+ new_watched_css_selectors.end());
+
+ for (content::RenderProcessHost::iterator it(
+ content::RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd();
+ it.Advance()) {
+ InstructRenderProcessIfManagingBrowserContext(it.GetCurrentValue());
+ }
+ }
+}
+
+void DeclarativeContentCssConditionTracker::TrackForWebContents(
+ content::WebContents* contents) {
+ CreatePerWebContentsTracker(contents);
+}
+
+void DeclarativeContentCssConditionTracker::OnWebContentsNavigation(
+ content::WebContents* contents,
+ const content::LoadCommittedDetails& details,
+ const content::FrameNavigateParams& params) {
+ per_web_contents_tracker_[contents]->OnWebContentsNavigation(details, params);
+}
+
+void DeclarativeContentCssConditionTracker::GetMatchingCssSelectors(
+ content::WebContents* contents,
+ base::hash_set<std::string>* css_selectors) {
+ const std::vector<std::string>& matching_css_selectors =
+ per_web_contents_tracker_[contents]->matching_css_selectors();
+ css_selectors->insert(matching_css_selectors.begin(),
+ matching_css_selectors.end());
+}
+
+void DeclarativeContentCssConditionTracker::
+UpdateMatchingCssSelectorsForTesting(
+ content::WebContents* contents,
+ const std::vector<std::string>& matching_css_selectors) {
+ per_web_contents_tracker_[contents]->
+ UpdateMatchingCssSelectorsForTesting(matching_css_selectors);
+}
+
+void DeclarativeContentCssConditionTracker::CreatePerWebContentsTracker(
+ content::WebContents* contents) {
+ per_web_contents_tracker_[contents] =
+ make_linked_ptr(new PerWebContentsTracker(
+ contents,
+ base::Bind(&DeclarativeContentCssConditionTrackerDelegate::
+ RequestEvaluation,
+ base::Unretained(delegate_)),
+ base::Bind(&DeclarativeContentCssConditionTracker::
+ DeletePerWebContentsTracker,
+ base::Unretained(this))));
+}
+
+void DeclarativeContentCssConditionTracker::Observe(
+ int type,
+ 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();
+ InstructRenderProcessIfManagingBrowserContext(process);
+ break;
+ }
+ }
+}
+
+void DeclarativeContentCssConditionTracker::
+InstructRenderProcessIfManagingBrowserContext(
+ content::RenderProcessHost* process) {
+ if (delegate_->ShouldManageConditionsForBrowserContext(
+ process->GetBrowserContext())) {
+ process->Send(new ExtensionMsg_WatchPages(watched_css_selectors_));
+ }
+}
+
+void DeclarativeContentCssConditionTracker::DeletePerWebContentsTracker(
+ content::WebContents* contents) {
+ per_web_contents_tracker_.erase(contents);
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698