1 // Copyright (c) 2012 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 #ifndef CHROME_RENDERER_EXTENSIONS_CONTENT_WATCHER_H_ 6 #define CHROME_RENDERER_EXTENSIONS_CONTENT_WATCHER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/strings/string_piece.h" 15 #include "v8/include/v8.h" 16 17 namespace WebKit { 18 class WebFrame; 19 } 20 21 namespace extensions { 22 class Dispatcher; 23 class Extension; 24 class NativeHandler; 25 26 // Watches the content of WebFrames to notify extensions when they match various 27 // patterns. This class tracks the set of relevant patterns (set by 28 // ExtensionMsg_WatchPages) and the set that match on each WebFrame, and sends a 29 // ExtensionHostMsg_OnWatchedPageChange whenever a RenderView's set changes. 30 // 31 // There's one ContentWatcher per Dispatcher rather than per RenderView because 32 // WebFrames can move between RenderViews through adoptNode. 33 class ContentWatcher { 34 public: 35 explicit ContentWatcher(Dispatcher* dispatcher); 36 ~ContentWatcher(); 37 38 // Returns the callback to call on a frame change. 39 scoped_ptr<NativeHandler> MakeNatives(ChromeV8Context* context); 40 41 // Handler for ExtensionMsg_WatchPages. 42 void OnWatchPages(const std::vector<std::string>& css_selectors); 43 44 // Registers the MutationObserver to call back into this object whenever the 45 // content of |frame| changes. 46 void DidCreateDocumentElement(WebKit::WebFrame* frame); 47 48 // Scans *frame for the current set of interesting CSS selectors, and if 49 // they've changed sends ExtensionHostMsg_OnWatchedPageChange back to the 50 // RenderViewHost that owns the frame. 51 void ScanAndNotify(WebKit::WebFrame* frame); 52 53 private: 54 void EnsureWatchingMutations(WebKit::WebFrame* frame); 55 56 ModuleSystem* GetModuleSystem(WebKit::WebFrame* frame) const; 57 std::vector<base::StringPiece> FindMatchingSelectors( 58 WebKit::WebFrame* frame) const; 59 60 // Given that we saw a change in the CSS selectors that |changed_frame| 61 // matched, tell the browser about the new set of matching selectors in its 62 // top-level page. We filter this so that if an extension were to be granted 63 // activeTab permission on that top-level page, we only send CSS selectors for 64 // frames that it could run on. 65 void NotifyBrowserOfChange(WebKit::WebFrame* changed_frame) const; 66 67 base::WeakPtrFactory<ContentWatcher> weak_ptr_factory_; 68 Dispatcher* dispatcher_; 69 70 // If any of these selectors match on a page, we need to send an 71 // ExtensionHostMsg_OnWatchedPageChange back to the browser. 72 std::vector<std::string> css_selectors_; 73 74 // Maps live WebFrames to the set of CSS selectors they match. This lets us 75 // traverse a top-level frame's sub-frames without rescanning them all each 76 // time any one changes. 77 // 78 // The StringPieces point into css_selectors_ above, so when it changes, they 79 // all need to be regenerated. 80 std::map<WebKit::WebFrame*, 81 std::vector<base::StringPiece> > matching_selectors_; 82 }; 83 84 } // namespace extensions 85 86 #endif // CHROME_RENDERER_EXTENSIONS_CONTENT_WATCHER_H_ 87