Chromium Code Reviews| 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..417fcb39ae3706091a7213887b4637f593f6d2a2 100644 |
| --- a/chrome/renderer/extensions/content_watcher.cc |
| +++ b/chrome/renderer/extensions/content_watcher.cc |
| @@ -2,133 +2,93 @@ |
| // 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())); |
| - } |
| - } |
| - |
| - 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() {} |
| 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) { |
| + std::vector<WebKit::WebString> new_css_selectors( |
| + new_css_selectors_utf8.size()); |
| + bool unchanged = new_css_selectors.size() == css_selectors_.size(); |
|
Matt Perry
2013/10/02 22:20:22
nit: negative bools always confuse me. how about "
Jeffrey Yasskin
2013/10/03 00:31:57
Sounds good. Done.
|
| + for (size_t i = 0; i < new_css_selectors.size(); ++i) { |
| + new_css_selectors[i] = |
| + WebKit::WebString::fromUTF8(new_css_selectors_utf8[i]); |
| + if (unchanged && new_css_selectors[i] != css_selectors_[i]) |
| + unchanged = false; |
| + } |
| + |
| + if (unchanged) |
| return; |
| - matching_selectors_.clear(); |
| css_selectors_ = new_css_selectors; |
|
Matt Perry
2013/10/02 22:20:22
more efficient to do css_selectors_.swap(new_css_s
Jeffrey Yasskin
2013/10/03 00:31:57
Ah, it does work now to build new_css_selectors as
|
| - // 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"); |
| - } |
| -} |
| - |
| -ModuleSystem* ContentWatcher::GetModuleSystem(WebKit::WebFrame* frame) const { |
| - ChromeV8Context* v8_context = |
| - dispatcher_->v8_context_set().GetByV8Context( |
| - frame->mainWorldScriptContext()); |
| +void ContentWatcher::DidMatchCSS( |
| + 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 (!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; |
| + 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( |
|
Matt Perry
2013/10/02 22:20:22
I don't see this method called anywhere in this CL
Jeffrey Yasskin
2013/10/03 00:31:57
You're right, it's obsolete. Deleted.
|
| WebKit::WebFrame* frame) const { |
| - std::vector<base::StringPiece> result; |
| + std::set<std::string> 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]), |
| + if (!document.querySelector(css_selectors_[i], |
| exception).isNull()) |
| - result.push_back(css_selectors_[i]); |
| + result.insert(css_selectors_[i].utf8()); |
| DCHECK_EQ(0, exception) |
| << "We should already have checked that the selectors are valid."; |
| } |
| @@ -152,8 +112,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(), |