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

Unified Diff: chrome/renderer/extensions/content_watcher.cc

Issue 19045002: Use Blink support to watch CSS selectors directly instead of using a MutationObserver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: unCamelCase in Chrome code. Created 7 years, 2 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
« no previous file with comments | « chrome/renderer/extensions/content_watcher.h ('k') | chrome/renderer/extensions/dispatcher.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/extensions/content_watcher.cc
diff --git a/chrome/renderer/extensions/content_watcher.cc b/chrome/renderer/extensions/content_watcher.cc
index b41dce59131055a84b0c0e7c8886b3912eb61c4a..d6435a059ebf783e861d1c648ca5012576709b95 100644
--- a/chrome/renderer/extensions/content_watcher.cc
+++ b/chrome/renderer/extensions/content_watcher.cc
@@ -2,139 +2,84 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/common/extensions/extension_messages.h"
-#include "chrome/renderer/extensions/chrome_v8_context.h"
-#include "chrome/renderer/extensions/chrome_v8_extension.h"
#include "chrome/renderer/extensions/content_watcher.h"
-#include "chrome/renderer/extensions/dispatcher.h"
+
+#include "chrome/common/extensions/extension_messages.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_visitor.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebScriptBindings.h"
#include "third_party/WebKit/public/web/WebView.h"
namespace extensions {
-namespace {
-
-class MutationHandler : public ChromeV8Extension {
- public:
- explicit MutationHandler(Dispatcher* dispatcher,
- ChromeV8Context* context,
- base::WeakPtr<ContentWatcher> content_watcher)
- : ChromeV8Extension(dispatcher, context),
- content_watcher_(content_watcher) {
- RouteFunction("FrameMutated",
- base::Bind(&MutationHandler::FrameMutated,
- base::Unretained(this)));
- }
-
- private:
- void FrameMutated(const v8::FunctionCallbackInfo<v8::Value>& args) {
- if (content_watcher_.get()) {
- content_watcher_->ScanAndNotify(
- WebKit::WebFrame::frameForContext(context()->v8_context()));
- }
- }
+using WebKit::WebString;
+using WebKit::WebVector;
+using WebKit::WebView;
- base::WeakPtr<ContentWatcher> content_watcher_;
-};
-
-} // namespace
-
-ContentWatcher::ContentWatcher(Dispatcher* dispatcher)
- : weak_ptr_factory_(this),
- dispatcher_(dispatcher) {}
+ContentWatcher::ContentWatcher() {}
ContentWatcher::~ContentWatcher() {}
-scoped_ptr<NativeHandler> ContentWatcher::MakeNatives(
- ChromeV8Context* context) {
- return scoped_ptr<NativeHandler>(new MutationHandler(
- dispatcher_, context, weak_ptr_factory_.GetWeakPtr()));
-}
-
void ContentWatcher::OnWatchPages(
- const std::vector<std::string>& new_css_selectors) {
- if (new_css_selectors == css_selectors_)
+ const std::vector<std::string>& new_css_selectors_utf8) {
+ WebKit::WebVector<WebKit::WebString> new_css_selectors(
+ new_css_selectors_utf8.size());
+ bool changed = new_css_selectors.size() != css_selectors_.size();
+ for (size_t i = 0; i < new_css_selectors.size(); ++i) {
+ new_css_selectors[i] =
+ WebKit::WebString::fromUTF8(new_css_selectors_utf8[i]);
+ if (!changed && new_css_selectors[i] != css_selectors_[i])
+ changed = true;
+ }
+
+ if (!changed)
return;
- matching_selectors_.clear();
- css_selectors_ = new_css_selectors;
+ css_selectors_.swap(new_css_selectors);
- // For each top-level frame, inform the browser about its new matching set of
- // selectors.
+ // Tell each frame's document about the new set of watched selectors. These
+ // will trigger calls to DidMatchCSS after Blink has a chance to apply the new
+ // style, which will in turn notify the browser about the changes.
struct WatchSelectors : public content::RenderViewVisitor {
- explicit WatchSelectors(ContentWatcher* watcher) : watcher_(watcher) {}
+ explicit WatchSelectors(const WebVector<WebString>& css_selectors)
+ : css_selectors_(css_selectors) {}
+
virtual bool Visit(content::RenderView* view) OVERRIDE {
for (WebKit::WebFrame* frame = view->GetWebView()->mainFrame(); frame;
- frame = frame->traverseNext(/*wrap=*/false)) {
- if (!watcher_->css_selectors_.empty())
- watcher_->EnsureWatchingMutations(frame);
+ frame = frame->traverseNext(/*wrap=*/false))
+ frame->document().watchCSSSelectors(css_selectors_);
- watcher_->matching_selectors_[frame] =
- watcher_->FindMatchingSelectors(frame);
- }
- watcher_->NotifyBrowserOfChange(view->GetWebView()->mainFrame());
return true; // Continue visiting.
}
- ContentWatcher* watcher_;
+
+ const WebVector<WebString>& css_selectors_;
};
- WatchSelectors visitor(this);
+ WatchSelectors visitor(css_selectors_);
content::RenderView::ForEach(&visitor);
}
void ContentWatcher::DidCreateDocumentElement(WebKit::WebFrame* frame) {
- if (!css_selectors_.empty()) {
- EnsureWatchingMutations(frame);
- }
+ frame->document().watchCSSSelectors(css_selectors_);
}
-void ContentWatcher::EnsureWatchingMutations(WebKit::WebFrame* frame) {
- v8::HandleScope scope(v8::Isolate::GetCurrent());
- v8::Context::Scope context_scope(frame->mainWorldScriptContext());
- if (ModuleSystem* module_system = GetModuleSystem(frame)) {
- ModuleSystem::NativesEnabledScope scope(module_system);
- module_system->Require("contentWatcher");
- }
-}
+void ContentWatcher::DidMatchCSS(
+ WebKit::WebFrame* frame,
+ const WebVector<WebString>& newly_matching_selectors,
+ const WebVector<WebString>& stopped_matching_selectors) {
+ std::set<std::string>& frame_selectors = matching_selectors_[frame];
+ for (size_t i = 0; i < stopped_matching_selectors.size(); ++i)
+ frame_selectors.erase(stopped_matching_selectors[i].utf8());
+ for (size_t i = 0; i < newly_matching_selectors.size(); ++i)
+ frame_selectors.insert(newly_matching_selectors[i].utf8());
-ModuleSystem* ContentWatcher::GetModuleSystem(WebKit::WebFrame* frame) const {
- ChromeV8Context* v8_context =
- dispatcher_->v8_context_set().GetByV8Context(
- frame->mainWorldScriptContext());
+ if (frame_selectors.empty())
+ matching_selectors_.erase(frame);
- if (!v8_context)
- return NULL;
- return v8_context->module_system();
-}
-
-void ContentWatcher::ScanAndNotify(WebKit::WebFrame* frame) {
- std::vector<base::StringPiece> new_matches = FindMatchingSelectors(frame);
- std::vector<base::StringPiece>& old_matches = matching_selectors_[frame];
- if (new_matches == old_matches)
- return;
-
- using std::swap;
- swap(old_matches, new_matches);
NotifyBrowserOfChange(frame);
}
-std::vector<base::StringPiece> ContentWatcher::FindMatchingSelectors(
- WebKit::WebFrame* frame) const {
- std::vector<base::StringPiece> result;
- WebKit::WebDocument document = frame->document();
- for (size_t i = 0; i < css_selectors_.size(); ++i) {
- WebKit::WebExceptionCode exception = 0;
- if (!document.querySelector(WebKit::WebString::fromUTF8(css_selectors_[i]),
- exception).isNull())
- result.push_back(css_selectors_[i]);
- DCHECK_EQ(0, exception)
- << "We should already have checked that the selectors are valid.";
- }
- return result;
-}
-
void ContentWatcher::NotifyBrowserOfChange(
WebKit::WebFrame* changed_frame) const {
WebKit::WebFrame* const top_frame = changed_frame->top();
@@ -152,8 +97,7 @@ void ContentWatcher::NotifyBrowserOfChange(
for (WebKit::WebFrame* frame = top_frame; frame;
frame = frame->traverseNext(/*wrap=*/false)) {
if (top_origin.canAccess(frame->document().securityOrigin())) {
- std::map<WebKit::WebFrame*,
- std::vector<base::StringPiece> >::const_iterator
+ std::map<WebKit::WebFrame*, std::set<std::string> >::const_iterator
frame_selectors = matching_selectors_.find(frame);
if (frame_selectors != matching_selectors_.end()) {
transitive_selectors.insert(frame_selectors->second.begin(),
« no previous file with comments | « chrome/renderer/extensions/content_watcher.h ('k') | chrome/renderer/extensions/dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698