summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authoraa@google.com <aa@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-16 23:57:47 +0000
committeraa@google.com <aa@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-16 23:57:47 +0000
commit1e0f70402b410a9e274e8d23eeab236b43810a00 (patch)
tree43ebd89055f4666ab3104554551a2177413382db /chrome/renderer
parentc2dacc9ec41232903ba700c6aef5ef98bfcb8af8 (diff)
downloadchromium_src-1e0f70402b410a9e274e8d23eeab236b43810a00.zip
chromium_src-1e0f70402b410a9e274e8d23eeab236b43810a00.tar.gz
chromium_src-1e0f70402b410a9e274e8d23eeab236b43810a00.tar.bz2
Adds a bit of Greasemonkey support hidden behind the --enable-greasemonkey flag. Implementation follows the pattern of the visited links system.
Things still to be done: - stop using a hardcoded script directory - watch script directory and update shared memory when necessary - move file io to background thread - support for @include patterns -- now, all scripts are applied to all pages Review URL: http://codereview.chromium.org/7254 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3496 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/greasemonkey_slave.cc66
-rw-r--r--chrome/renderer/greasemonkey_slave.h62
-rw-r--r--chrome/renderer/render_thread.cc15
-rw-r--r--chrome/renderer/render_thread.h7
-rw-r--r--chrome/renderer/render_view.cc17
-rw-r--r--chrome/renderer/render_view.h3
-rw-r--r--chrome/renderer/renderer.vcproj8
7 files changed, 175 insertions, 3 deletions
diff --git a/chrome/renderer/greasemonkey_slave.cc b/chrome/renderer/greasemonkey_slave.cc
new file mode 100644
index 0000000..7a23017
--- /dev/null
+++ b/chrome/renderer/greasemonkey_slave.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2008 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/renderer/greasemonkey_slave.h"
+
+#include "base/logging.h"
+#include "base/pickle.h"
+#include "base/shared_memory.h"
+
+GreasemonkeySlave::GreasemonkeySlave() : shared_memory_(NULL) {
+}
+
+bool GreasemonkeySlave::UpdateScripts(SharedMemoryHandle shared_memory) {
+ scripts_.clear();
+
+ // Create the shared memory object.
+ shared_memory_.reset(new SharedMemory(shared_memory, true)); // read-only
+ if (!shared_memory_.get())
+ return false;
+
+ // First get the size of the memory block.
+ if (!shared_memory_->Map(sizeof(Pickle::Header)))
+ return false;
+ Pickle::Header* pickle_header =
+ reinterpret_cast<Pickle::Header*>(shared_memory_->memory());
+
+ // Now map in the rest of the block.
+ int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
+ shared_memory_->Unmap();
+ if (!shared_memory_->Map(pickle_size))
+ return false;
+
+ // Unpickle scripts.
+ void* iter = NULL;
+ int num_scripts = 0;
+ Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
+ pickle_size);
+ pickle.ReadInt(&iter, &num_scripts);
+
+ for (int i = 0; i < num_scripts; ++i) {
+ const char* data = NULL;
+ int data_length = 0;
+ pickle.ReadData(&iter, &data, &data_length);
+
+ GreasemonkeyScript script;
+ if (script.Parse(StringPiece(data, data_length))) {
+ scripts_.push_back(script);
+ }
+ }
+
+ return true;
+}
+
+bool GreasemonkeySlave::InjectScripts(WebFrame* frame) {
+ // TODO(aa): Check script patterns here
+
+ for (std::vector<GreasemonkeyScript>::iterator script = scripts_.begin();
+ script != scripts_.end(); ++script) {
+ // TODO(aa): Pass in URL to script when we have it.
+ frame->ExecuteJavaScript(script->GetBody().as_string(),
+ "Greasemonkey Script");
+ }
+
+ return true;
+}
diff --git a/chrome/renderer/greasemonkey_slave.h b/chrome/renderer/greasemonkey_slave.h
new file mode 100644
index 0000000..7f35cec
--- /dev/null
+++ b/chrome/renderer/greasemonkey_slave.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2008 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.
+
+#ifndef CHROME_RENDERER_GREASEMONKEY_SLAVE_H__
+#define CHROME_RENDERER_GREASEMONKEY_SLAVE_H__
+
+#include <vector>
+
+#include "base/scoped_ptr.h"
+#include "base/shared_memory.h"
+#include "base/string_piece.h"
+#include "webkit/glue/webframe.h"
+
+// Parsed representation of a Greasemonkey script.
+class GreasemonkeyScript {
+ public:
+ // TODO(aa): Pass in filename script came from, for errors. Needs to be in
+ // shared memory.
+ GreasemonkeyScript() {}
+
+ const StringPiece& GetBody() const {
+ return body_;
+ }
+
+ bool Parse(const StringPiece& script_text) {
+ // TODO(aa): Parse out includes, convert to regexes.
+ body_ = script_text;
+ return true;
+ }
+
+ private:
+ // References the body of the script in shared memory. The underlying memory
+ // is valid until shared_memory_ is either deleted or Unmap()'d.
+ StringPiece body_;
+};
+
+
+// Manages installed GreasemonkeyScripts for a render process.
+class GreasemonkeySlave {
+ public:
+ GreasemonkeySlave();
+
+ // Update the parsed scripts from shared memory.
+ bool UpdateScripts(SharedMemoryHandle shared_memory);
+
+ // Inject the appropriate scripts into a frame based on its URL.
+ // TODO(aa): Extract a GreasemonkeyFrame interface out of this to improve
+ // testability.
+ bool InjectScripts(WebFrame* frame);
+
+ private:
+ // Shared memory containing raw script data.
+ scoped_ptr<SharedMemory> shared_memory_;
+
+ // Parsed script data.
+ std::vector<GreasemonkeyScript> scripts_;
+
+ DISALLOW_COPY_AND_ASSIGN(GreasemonkeySlave);
+};
+
+#endif // CHROME_RENDERER_GREASEMONKEY_SLAVE_H__
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index c389860..56ed3a8 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -15,6 +15,7 @@
#include "chrome/common/notification_service.h"
#include "chrome/plugin/plugin_channel.h"
#include "chrome/renderer/net/render_dns_master.h"
+#include "chrome/renderer/greasemonkey_slave.h"
#include "chrome/renderer/render_process.h"
#include "chrome/renderer/render_view.h"
#include "chrome/renderer/visitedlink_slave.h"
@@ -41,6 +42,7 @@ RenderThread::RenderThread(const std::wstring& channel_name)
channel_name_(channel_name),
owner_loop_(MessageLoop::current()),
visited_link_slave_(NULL),
+ greasemonkey_slave_(NULL),
render_dns_master_(NULL),
in_send_(0) {
DCHECK(owner_loop_);
@@ -111,9 +113,8 @@ void RenderThread::Init() {
// The renderer thread should wind-up COM.
CoInitialize(0);
- // TODO(darin): We should actually try to share this object between
- // RenderThread instances.
visited_link_slave_ = new VisitedLinkSlave();
+ greasemonkey_slave_ = new GreasemonkeySlave();
render_dns_master_.reset(new RenderDnsMaster());
@@ -141,6 +142,9 @@ void RenderThread::CleanUp() {
delete visited_link_slave_;
visited_link_slave_ = NULL;
+ delete greasemonkey_slave_;
+ greasemonkey_slave_ = NULL;
+
CoUninitialize();
}
@@ -149,6 +153,11 @@ void RenderThread::OnUpdateVisitedLinks(SharedMemoryHandle table) {
visited_link_slave_->Init(table);
}
+void RenderThread::OnUpdateGreasemonkeyScripts(SharedMemoryHandle scripts) {
+ DCHECK(scripts) << "Bad scripts handle";
+ greasemonkey_slave_->UpdateScripts(scripts);
+}
+
void RenderThread::OnMessageReceived(const IPC::Message& msg) {
// NOTE: We could subclass router_ to intercept OnControlMessageReceived, but
// it seems simpler to just process any control messages that we care about
@@ -163,6 +172,8 @@ void RenderThread::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
OnGetCacheResourceStats)
IPC_MESSAGE_HANDLER(ViewMsg_PluginMessage, OnPluginMessage)
+ IPC_MESSAGE_HANDLER(ViewMsg_Greasemonkey_NewScripts,
+ OnUpdateGreasemonkeyScripts)
// send the rest to the router
IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))
IPC_END_MESSAGE_MAP()
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 2d1c198..38fd144 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -18,6 +18,7 @@ class VisitedLinkSlave;
struct WebPreferences;
class RenderDnsMaster;
class NotificationService;
+class GreasemonkeySlave;
// The RenderThreadBase is the minimal interface that a RenderWidget expects
// from a render thread. The interface basically abstracts a way to send and
@@ -64,8 +65,12 @@ class RenderThread : public IPC::Channel::Listener,
// The RenderThread instance for the current thread.
static RenderThread* current();
+ // Gets the VisitedLinkSlave instance for this thread
VisitedLinkSlave* visited_link_slave() const { return visited_link_slave_; }
+ // Gets the GreasemonkeySlave instance for this thread
+ GreasemonkeySlave* greasemonkey_slave() const { return greasemonkey_slave_; }
+
// Do DNS prefetch resolution of a hostname.
void Resolve(const char* name, size_t length);
@@ -89,6 +94,7 @@ class RenderThread : public IPC::Channel::Listener,
private:
void OnUpdateVisitedLinks(SharedMemoryHandle table);
+ void OnUpdateGreasemonkeyScripts(SharedMemoryHandle table);
void OnPluginMessage(const std::wstring& dll_path,
const std::vector<uint8>& data);
@@ -120,6 +126,7 @@ class RenderThread : public IPC::Channel::Listener,
// These objects live solely on the render thread.
VisitedLinkSlave* visited_link_slave_;
+ GreasemonkeySlave* greasemonkey_slave_;
scoped_ptr<RenderDnsMaster> render_dns_master_;
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index ef69bb6..528120b 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -31,6 +31,7 @@
#include "chrome/renderer/about_handler.h"
#include "chrome/renderer/chrome_plugin_host.h"
#include "chrome/renderer/debug_message_handler.h"
+#include "chrome/renderer/greasemonkey_slave.h"
#include "chrome/renderer/localized_error.h"
#include "chrome/renderer/renderer_resources.h"
#include "chrome/renderer/visitedlink_slave.h"
@@ -150,7 +151,8 @@ RenderView::RenderView()
history_back_list_count_(0),
history_forward_list_count_(0),
disable_popup_blocking_(false),
- has_unload_listener_(false) {
+ has_unload_listener_(false),
+ greasemonkey_enabled_(false) {
resource_dispatcher_ = new ResourceDispatcher(this);
#ifdef CHROME_PERSONALIZATION
personalization_ = Personalization::CreateRendererPersonalization();
@@ -261,6 +263,8 @@ void RenderView::Init(HWND parent_hwnd,
command_line.HasSwitch(switches::kDomAutomationController);
disable_popup_blocking_ =
command_line.HasSwitch(switches::kDisablePopupBlocking);
+ greasemonkey_enabled_ =
+ command_line.HasSwitch(switches::kEnableGreasemonkey);
debug_message_handler_ = new DebugMessageHandler(this);
RenderThread::current()->AddFilter(debug_message_handler_);
@@ -1369,6 +1373,17 @@ void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
WebFrame* frame) {
// Check whether we have new encoding name.
UpdateEncoding(frame, webview->GetMainFrameEncodingName());
+
+ // Inject any Greasemonkey scripts. Do not inject into chrome UI pages, but
+ // do inject into any other document.
+ if (greasemonkey_enabled_) {
+ const GURL &gurl = frame->GetURL();
+ if (gurl.SchemeIs("file") ||
+ gurl.SchemeIs("http") ||
+ gurl.SchemeIs("https")) {
+ RenderThread::current()->greasemonkey_slave()->InjectScripts(frame);
+ }
+ }
}
void RenderView::DidHandleOnloadEventsForFrame(WebView* webview,
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index a59f328..d307e48 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -623,6 +623,9 @@ class RenderView : public RenderWidget, public WebViewDelegate,
// maintains the cache and other features of the accessibility tree.
scoped_ptr<GlueAccessibility> glue_accessibility_;
+ // True if Greasemonkey is enabled in this process.
+ bool greasemonkey_enabled_;
+
DISALLOW_COPY_AND_ASSIGN(RenderView);
};
diff --git a/chrome/renderer/renderer.vcproj b/chrome/renderer/renderer.vcproj
index 9d82fecb..2fa8d0c 100644
--- a/chrome/renderer/renderer.vcproj
+++ b/chrome/renderer/renderer.vcproj
@@ -202,6 +202,14 @@
>
</File>
<File
+ RelativePath=".\greasemonkey_slave.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\greasemonkey_slave.h"
+ >
+ </File>
+ <File
RelativePath=".\localized_error.cc"
>
</File>