summaryrefslogtreecommitdiffstats
path: root/chrome/browser
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/browser
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/browser')
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/greasemonkey_master.cc73
-rw-r--r--chrome/browser/greasemonkey_master.h47
-rw-r--r--chrome/browser/render_process_host.cc70
4 files changed, 183 insertions, 15 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index be4e198..743e775 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -2143,6 +2143,14 @@
>
</File>
<File
+ RelativePath=".\greasemonkey_master.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\greasemonkey_master.h"
+ >
+ </File>
+ <File
RelativePath=".\interstitial_page.cc"
>
</File>
diff --git a/chrome/browser/greasemonkey_master.cc b/chrome/browser/greasemonkey_master.cc
new file mode 100644
index 0000000..829b47b
--- /dev/null
+++ b/chrome/browser/greasemonkey_master.cc
@@ -0,0 +1,73 @@
+// 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/browser/greasemonkey_master.h"
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/pickle.h"
+#include "base/string_util.h"
+#include "chrome/common/chrome_paths.h"
+
+bool GreasemonkeyMaster::UpdateScripts() {
+ std::vector<std::string> scripts;
+ std::wstring path;
+
+ PathService::Get(chrome::DIR_USER_SCRIPTS, &path);
+ file_util::FileEnumerator enumerator(path, false,
+ file_util::FileEnumerator::FILES,
+ L"*.user.js");
+ for (std::wstring file = enumerator.Next(); !file.empty();
+ file = enumerator.Next()) {
+ // TODO(aa): Support unicode script files.
+ std::string contents;
+ file_util::ReadFileToString(file, &contents);
+ scripts.push_back(contents);
+ }
+
+ // Pickle scripts data.
+ Pickle pickle;
+ pickle.WriteSize(scripts.size());
+ for (std::vector<std::string>::iterator script = scripts.begin();
+ script != scripts.end(); ++script) {
+ // Write script body as 'data' so that we can read it out in the slave
+ // without allocating a new string.
+ pickle.WriteData(script->c_str(), script->size());
+ }
+
+ // Create the shared memory object.
+ scoped_ptr<SharedMemory> temp_shared_memory(new SharedMemory());
+ if (!temp_shared_memory.get()) {
+ return false;
+ }
+
+ shared_memory_serial_++;
+ if (!temp_shared_memory->Create(std::wstring(), // anonymous
+ false, // read-only
+ false, // open existing
+ pickle.size())) {
+ return false;
+ }
+
+ // Map into our process.
+ if (!temp_shared_memory->Map(pickle.size())) {
+ return false;
+ }
+
+ // Copy the pickle to shared memory.
+ memcpy(temp_shared_memory->memory(), pickle.data(), pickle.size());
+
+ shared_memory_.reset(temp_shared_memory.release());
+ return true;
+}
+
+bool GreasemonkeyMaster::ShareToProcess(ProcessHandle process,
+ SharedMemoryHandle* new_handle) {
+ if (shared_memory_.get())
+ return shared_memory_->ShareToProcess(process, new_handle);
+
+ NOTREACHED();
+ return false;
+}
diff --git a/chrome/browser/greasemonkey_master.h b/chrome/browser/greasemonkey_master.h
new file mode 100644
index 0000000..6dcbc6e
--- /dev/null
+++ b/chrome/browser/greasemonkey_master.h
@@ -0,0 +1,47 @@
+// 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_BROWSER_GREASEMONKEY_MASTER_H__
+#define CHROME_BROWSER_GREASEMONKEY_MASTER_H__
+
+#include <vector>
+
+#include "base/process.h"
+#include "base/scoped_ptr.h"
+#include "base/shared_memory.h"
+
+// Manages a segment of shared memory that contains the Greasemonkey scripts the
+// user has installed.
+class GreasemonkeyMaster {
+ public:
+ GreasemonkeyMaster()
+ : shared_memory_serial_(0) {}
+
+ // Reloads scripts from disk into a new chunk of shared memory and notifies
+ // renderers.
+ bool UpdateScripts();
+
+ // Creates a handle to the shared memory that can be used in the specified
+ // process.
+ bool ShareToProcess(ProcessHandle process, SharedMemoryHandle* new_handle);
+
+ // Gets the segment of shared memory for the scripts.
+ SharedMemory* GetSharedMemory() const {
+ return shared_memory_.get();
+ }
+
+ private:
+ // Contains the scripts that were found the last time UpdateScripts() was
+ // called.
+ scoped_ptr<SharedMemory> shared_memory_;
+
+ // A counter that is incremented each time a new shared memory segment is
+ // created. This is used to uniquely identify segments created at different
+ // times by this class.
+ int shared_memory_serial_;
+
+ DISALLOW_COPY_AND_ASSIGN(GreasemonkeyMaster);
+};
+
+#endif // CHROME_BROWSER_GREASEMONKEY_MASTER_H__
diff --git a/chrome/browser/render_process_host.cc b/chrome/browser/render_process_host.cc
index bcf5d72..62a73ee 100644
--- a/chrome/browser/render_process_host.cc
+++ b/chrome/browser/render_process_host.cc
@@ -21,6 +21,7 @@
#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/shared_memory.h"
+#include "base/singleton.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "base/thread.h"
@@ -38,6 +39,7 @@
#include "chrome/browser/sandbox_policy.h"
#include "chrome/browser/spellchecker.h"
#include "chrome/browser/visitedlink_master.h"
+#include "chrome/browser/greasemonkey_master.h"
#include "chrome/browser/web_contents.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
@@ -268,6 +270,7 @@ bool RenderProcessHost::Init() {
switches::kDisablePopupBlocking,
switches::kUseLowFragHeapCrt,
switches::kGearsInRenderer,
+ switches::kEnableGreasemonkey,
};
for (int i = 0; i < arraysize(switch_names); ++i) {
@@ -423,29 +426,66 @@ bool RenderProcessHost::Init() {
// Now that the process is created, set it's backgrounding accordingly.
SetBackgrounded(backgrounded_);
- VisitedLinkMaster* visitedlink_master = profile_->GetVisitedLinkMaster();
- if (visitedlink_master) {
- std::wstring history_table_name = visitedlink_master->GetSharedMemoryName();
- SharedMemoryHandle handle_for_process = NULL;
- HANDLE target_process = process_.handle();
- if (!target_process) {
- // Target process can be null if it's started with the --single-process
- // flag.
- target_process = GetCurrentProcess();
- }
-
- visitedlink_master->ShareToProcess(target_process, &handle_for_process);
- DCHECK(handle_for_process);
-
- channel_->Send(new ViewMsg_VisitedLink_NewTable(handle_for_process));
+ // Send the process its initial VisitedLink and Greasemonkey data.
+ HANDLE target_process = process_.handle();
+ if (!target_process) {
+ // Target process can be null if it's started with the --single-process
+ // flag.
+ target_process = GetCurrentProcess();
}
+ InitVisitedLinks(target_process);
+ InitGreasemonkeyScripts(target_process);
+
if (max_page_id_ != -1)
channel_->Send(new ViewMsg_SetNextPageID(max_page_id_ + 1));
return true;
}
+void RenderProcessHost::InitVisitedLinks(HANDLE target_process) {
+ VisitedLinkMaster* visitedlink_master = profile_->GetVisitedLinkMaster();
+ if (!visitedlink_master) {
+ return;
+ }
+
+ SharedMemoryHandle handle_for_process = NULL;
+ visitedlink_master->ShareToProcess(target_process, &handle_for_process);
+ DCHECK(handle_for_process);
+ if (handle_for_process) {
+ channel_->Send(new ViewMsg_VisitedLink_NewTable(handle_for_process));
+ }
+}
+
+void RenderProcessHost::InitGreasemonkeyScripts(HANDLE target_process) {
+ CommandLine command_line;
+ if (!command_line.HasSwitch(switches::kEnableGreasemonkey)) {
+ return;
+ }
+
+ // TODO(aa): Figure out lifetime and ownership of this object
+ // - VisitedLinkMaster is owned by Profile, but there has been talk of
+ // having scripts live elsewhere besides the profile.
+ // - File IO should be asynchronous (see VisitedLinkMaster), but how do we
+ // get scripts to the first renderer without blocking startup? Should we
+ // cache some information across restarts?
+ GreasemonkeyMaster* greasemonkey_master =
+ Singleton<GreasemonkeyMaster>::get();
+ if (!greasemonkey_master) {
+ return;
+ }
+
+ // TODO(aa): This does blocking IO. Move to background thread.
+ greasemonkey_master->UpdateScripts();
+
+ SharedMemoryHandle handle_for_process = NULL;
+ greasemonkey_master->ShareToProcess(target_process, &handle_for_process);
+ DCHECK(handle_for_process);
+ if (handle_for_process) {
+ channel_->Send(new ViewMsg_Greasemonkey_NewScripts(handle_for_process));
+ }
+}
+
void RenderProcessHost::Attach(IPC::Channel::Listener* listener,
int routing_id) {
listeners_.AddWithID(listener, routing_id);