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

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

Issue 12326052: Using the new webkit CSS change notification instead of a mutation observer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 5c2bb7ea5d0e58de7577ae758a1851e8c39a3cde..ccbea0b3863efaa7697646bc65e4c87ee5e91c7b 100644
--- a/chrome/renderer/extensions/content_watcher.cc
+++ b/chrome/renderer/extensions/content_watcher.cc
@@ -15,76 +15,86 @@
namespace extensions {
-namespace {
-class MutationHandler : public ChromeV8Extension {
- public:
- explicit MutationHandler(Dispatcher* dispatcher,
- base::WeakPtr<ContentWatcher> content_watcher)
- : ChromeV8Extension(dispatcher),
- content_watcher_(content_watcher) {
- RouteFunction("FrameMutated",
- base::Bind(&MutationHandler::FrameMutated,
- base::Unretained(this)));
- }
-
- private:
- v8::Handle<v8::Value> FrameMutated(const v8::Arguments& args) {
- if (content_watcher_) {
- content_watcher_->ScanAndNotify(
- WebKit::WebFrame::frameForCurrentContext());
- }
- return v8::Undefined();
- }
-
- base::WeakPtr<ContentWatcher> content_watcher_;
-};
-
-} // namespace
+using WebKit::WebString;
+using WebKit::WebVector;
+using WebKit::WebView;
ContentWatcher::ContentWatcher(Dispatcher* dispatcher)
: weak_ptr_factory_(this),
dispatcher_(dispatcher) {}
ContentWatcher::~ContentWatcher() {}
-scoped_ptr<NativeHandler> ContentWatcher::MakeNatives() {
- return scoped_ptr<NativeHandler>(
- new MutationHandler(dispatcher_, weak_ptr_factory_.GetWeakPtr()));
-}
-
void ContentWatcher::OnWatchPages(
const std::vector<std::string>& new_css_selectors) {
if (new_css_selectors == css_selectors_)
return;
+ std::string rules;
+ // Turn off callbacks for old selectors.
+ for (size_t i = 0; i < css_selectors_.size(); ++i) {
+ rules.append(css_selectors_[i]);
+ rules.append("{callback:none}\n");
+ }
+
css_selectors_ = new_css_selectors;
- for (std::map<WebKit::WebFrame*,
- std::vector<base::StringPiece> >::iterator
+ // Turn on callbacks for new selectors.
+ for (size_t i = 0; i < css_selectors_.size(); ++i) {
+ rules.append(css_selectors_[i]);
+ rules.append("{-webkit-callback:-webkit-presence}\n");
+ }
+
+ for (std::map<WebKit::WebFrame*, std::set<std::string> >::iterator
it = matching_selectors_.begin();
it != matching_selectors_.end(); ++it) {
WebKit::WebFrame* frame = it->first;
if (!css_selectors_.empty())
EnsureWatchingMutations(frame);
- // Make sure to replace the contents of it->second because it contains
- // dangling StringPieces that referred into the old css_selectors_ content.
+ // Update the contents of it->second since css_selectors_ could have changed
+ // completely.
it->second = FindMatchingSelectors(frame);
}
// For each top-level frame, inform the browser about its new matching set of
- // selectors.
+ // selectors, and set a user style sheet to watch for changes in the future.
struct NotifyVisitor : public content::RenderViewVisitor {
- explicit NotifyVisitor(ContentWatcher* watcher) : watcher_(watcher) {}
+ explicit NotifyVisitor(ContentWatcher* watcher, WebString rules)
+ : watcher_(watcher),
+ rules_(rules) {}
virtual bool Visit(content::RenderView* view) OVERRIDE {
- watcher_->NotifyBrowserOfChange(view->GetWebView()->mainFrame());
+ WebView* web_view = view->GetWebView();
+ // Notify of the matching selectors found above.
+ watcher_->NotifyBrowserOfChange(web_view->mainFrame());
+
+ // Watch for future changes.
+ web_view->addUserStyleSheet(rules_,
+ WebKit::WebVector<WebString>(), // All URLs.
+ WebView::UserContentInjectInAllFrames,
+ WebView::UserStyleInjectInExistingDocuments);
return true; // Continue visiting.
}
ContentWatcher* watcher_;
+ WebString rules_;
};
- NotifyVisitor visitor(this);
+ NotifyVisitor visitor(this, WebString::fromUTF8(rules));
content::RenderView::ForEach(&visitor);
}
+void ContentWatcher::OnWebViewCreated(WebKit::WebView* view) {
+ std::string rules;
+ // Turn on callbacks for watched selectors.
+ for (size_t i = 0; i < css_selectors_.size(); ++i) {
+ rules.append(css_selectors_[i]);
+ rules.append("{-webkit-callback:-webkit-presence}\n");
+ }
+
+ view->addUserStyleSheet(WebString::fromUTF8(rules),
+ WebKit::WebVector<WebString>(), // All URLs.
+ WebView::UserContentInjectInAllFrames,
+ WebView::UserStyleInjectInExistingDocuments);
+}
+
void ContentWatcher::DidCreateDocumentElement(WebKit::WebFrame* frame) {
// Make sure the frame is represented in the matching_selectors_ map.
matching_selectors_[frame];
@@ -113,20 +123,25 @@ ModuleSystem* ContentWatcher::GetModuleSystem(WebKit::WebFrame* frame) const {
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;
+void ContentWatcher::CssMatches(
+ WebKit::WebFrame* frame,
+ const WebVector<WebString>& newlyMatchingSelectors,
+ const WebVector<WebString>& stoppedMatchingSelectors) {
+ std::set<std::string>& frame_selectors = matching_selectors_[frame];
+ for (size_t i = 0; i < stoppedMatchingSelectors.size(); ++i)
+ frame_selectors.erase(stoppedMatchingSelectors[i].utf8());
+ for (size_t i = 0; i < newlyMatchingSelectors.size(); ++i)
+ frame_selectors.insert(newlyMatchingSelectors[i].utf8());
+
+ if (frame_selectors.empty())
+ matching_selectors_.erase(frame);
- using std::swap;
- swap(old_matches, new_matches);
NotifyBrowserOfChange(frame);
}
-std::vector<base::StringPiece> ContentWatcher::FindMatchingSelectors(
+std::set<std::string> ContentWatcher::FindMatchingSelectors(
WebKit::WebFrame* frame) const {
- std::vector<base::StringPiece> result;
+ std::set<std::string> result;
v8::HandleScope scope;
// Get the indices within |css_selectors_| that match elements in
@@ -153,7 +168,6 @@ std::vector<base::StringPiece> ContentWatcher::FindMatchingSelectors(
// converting them back to integers.
v8::Local<v8::Array> index_array = selector_indices.As<v8::Array>();
const size_t length = index_array->Length();
- result.reserve(length);
for (size_t i = 0; i < length; ++i) {
v8::Local<v8::Value> index_value = index_array->Get(i);
if (!index_value->IsNumber())
@@ -162,9 +176,8 @@ std::vector<base::StringPiece> ContentWatcher::FindMatchingSelectors(
// Make sure the index is within bounds.
if (index < 0 || css_selectors_.size() <= index)
continue;
- // Push a StringPiece referring to the CSS selector onto the result.
- result.push_back(
- base::StringPiece(css_selectors_[static_cast<size_t>(index)]));
+ // Add the CSS selector to the result.
+ result.insert(css_selectors_[static_cast<size_t>(index)]);
}
return result;
}
@@ -186,8 +199,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