diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-18 09:47:35 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-18 09:47:35 +0000 |
commit | 912256b3517241047095dac6946de191029dda27 (patch) | |
tree | 7799ca1544916d7e1f44b06bd0dd43e080b61996 /chrome/renderer | |
parent | 50c4e907cf41e395a5edecd1ae122b9a2b35410d (diff) | |
download | chromium_src-912256b3517241047095dac6946de191029dda27.zip chromium_src-912256b3517241047095dac6946de191029dda27.tar.gz chromium_src-912256b3517241047095dac6946de191029dda27.tar.bz2 |
Try again to land "Implement script API:executeScript"
http://codereview.chromium.org/173556
TBR=mpcomplete@chromium.org
Patch from Jerry Tang <tangjie@google.com>.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26556 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/render_view.cc | 40 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 30 | ||||
-rw-r--r-- | chrome/renderer/user_script_slave.cc | 15 | ||||
-rw-r--r-- | chrome/renderer/user_script_slave.h | 6 |
4 files changed, 86 insertions, 5 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 36f472a..d2c9eec 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -37,6 +37,7 @@ #include "chrome/renderer/audio_message_filter.h" #include "chrome/renderer/devtools_agent.h" #include "chrome/renderer/devtools_client.h" +#include "chrome/renderer/extension_groups.h" #include "chrome/renderer/extensions/event_bindings.h" #include "chrome/renderer/extensions/extension_process_bindings.h" #include "chrome/renderer/extensions/renderer_extension_bindings.h" @@ -443,6 +444,8 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive) IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent, OnSetEditCommandsForNextKeyEvent); + IPC_MESSAGE_HANDLER(ViewMsg_ExecuteCode, + OnExecuteCode) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message)) @@ -2080,6 +2083,14 @@ void RenderView::didCreateDocumentElement(WebFrame* frame) { frame, UserScript::DOCUMENT_START); } + while (!pending_code_execution_queue_.empty()) { + scoped_refptr<CodeExecutionInfo> info = + pending_code_execution_queue_.front(); + OnExecuteCode(info->request_id, info->extension_id, info->is_js_code, + info->code_string); + pending_code_execution_queue_.pop(); + } + // Notify the browser about non-blank documents loading in the top frame. GURL url = frame->url(); if (url.is_valid() && url.spec() != chrome::kAboutBlankURL) { @@ -3481,6 +3492,35 @@ void RenderView::OnSetEditCommandsForNextKeyEvent( edit_commands_ = edit_commands; } +void RenderView::OnExecuteCode(int request_id, const std::string& extension_id, + bool is_js_code, + const std::string& code_string) { + if (is_loading_) { + scoped_refptr<CodeExecutionInfo> info = new CodeExecutionInfo( + request_id, extension_id, is_js_code, code_string); + pending_code_execution_queue_.push(info); + return; + } + WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL; + if (!main_frame) { + Send(new ViewMsg_ExecuteCodeFinished(routing_id_, request_id, false)); + return; + } + + if (is_js_code) { + std::vector<WebScriptSource> sources; + sources.push_back( + WebScriptSource(WebString::fromUTF8(code_string))); + UserScriptSlave::InsertInitExtensionCode(&sources, extension_id); + main_frame->executeScriptInNewWorld(&sources.front(), sources.size(), + EXTENSION_GROUP_CONTENT_SCRIPTS); + } else { + main_frame->insertStyleText(WebString::fromUTF8(code_string), WebString()); + } + + Send(new ViewMsg_ExecuteCodeFinished(routing_id_, request_id, true)); +} + void RenderView::DidHandleKeyEvent() { edit_commands_.clear(); } diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index b647e65..4b35260 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -22,6 +22,7 @@ #include "build/build_config.h" #include "chrome/common/edit_command.h" #include "chrome/common/navigation_gesture.h" +#include "chrome/common/notification_type.h" #include "chrome/common/renderer_preferences.h" #include "chrome/common/view_types.h" #include "chrome/renderer/automation/dom_automation_controller.h" @@ -610,6 +611,10 @@ class RenderView : public RenderWidget, const MediaPlayerAction& action); void OnNotifyRendererViewType(ViewType::Type view_type); void OnUpdateBrowserWindowId(int window_id); + void OnExecuteCode(int request_id, + const std::string& extension_id, + bool is_js_code, + const std::string& code_string); void OnUpdateBackForwardListCount(int back_list_count, int forward_list_count); void OnGetAccessibilityInfo( @@ -909,6 +914,31 @@ class RenderView : public RenderWidget, // Id number of browser window which RenderView is attached to. int browser_window_id_; + // If page is loading, we can't run code, just create CodeExecutionInfo + // objects store pending execution information and delay the execution until + // page is loaded. + struct CodeExecutionInfo : public base::RefCounted<CodeExecutionInfo> { + CodeExecutionInfo(int id_of_request, const std::string& id_of_extension, + bool is_js, const std::string& code) + : request_id(id_of_request), + extension_id(id_of_extension), + code_string(code), + is_js_code(is_js) {} + int request_id; + + // The id of extension who issues the pending executeScript API call. + std::string extension_id; + + // The code which would be executed. + std::string code_string; + + // It's true if |code_string| is JavaScript; otherwise |code_string| is + // CSS text. + bool is_js_code; + }; + + std::queue<scoped_refptr<CodeExecutionInfo> > pending_code_execution_queue_; + // page id for the last navigation sent to the browser. int32 last_top_level_navigation_page_id_; diff --git a/chrome/renderer/user_script_slave.cc b/chrome/renderer/user_script_slave.cc index 7f7ad31..c120c6b 100644 --- a/chrome/renderer/user_script_slave.cc +++ b/chrome/renderer/user_script_slave.cc @@ -14,12 +14,10 @@ #include "chrome/renderer/extension_groups.h" #include "googleurl/src/gurl.h" #include "webkit/api/public/WebFrame.h" -#include "webkit/api/public/WebScriptSource.h" #include "grit/renderer_resources.h" using WebKit::WebFrame; -using WebKit::WebScriptSource; using WebKit::WebString; // These two strings are injected before and after the Greasemonkey API and @@ -109,6 +107,15 @@ bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) { return true; } +// static +void UserScriptSlave::InsertInitExtensionCode( + std::vector<WebScriptSource>* sources, const std::string& extension_id) { + DCHECK(sources); + sources->insert(sources->begin(), + WebScriptSource(WebString::fromUTF8( + StringPrintf(kInitExtension, extension_id.c_str())))); +} + bool UserScriptSlave::InjectScripts(WebFrame* frame, UserScript::RunLocation location) { // Don't bother if this is not a URL we inject script into. @@ -157,9 +164,7 @@ bool UserScriptSlave::InjectScripts(WebFrame* frame, } else { // Setup chrome.self to contain an Extension object with the correct // ID. - sources.insert(sources.begin(), - WebScriptSource(WebString::fromUTF8( - StringPrintf(kInitExtension, script->extension_id().c_str())))); + InsertInitExtensionCode(&sources, script->extension_id()); } frame->executeScriptInNewWorld(&sources.front(), sources.size(), diff --git a/chrome/renderer/user_script_slave.h b/chrome/renderer/user_script_slave.h index 614dd85..39407f1 100644 --- a/chrome/renderer/user_script_slave.h +++ b/chrome/renderer/user_script_slave.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_SLAVE_H_ #include <map> +#include <string> #include <vector> #include "base/scoped_ptr.h" @@ -13,11 +14,14 @@ #include "base/stl_util-inl.h" #include "base/string_piece.h" #include "chrome/common/extensions/user_script.h" +#include "webkit/api/public/WebScriptSource.h" namespace WebKit { class WebFrame; } +using WebKit::WebScriptSource; + // Manages installed UserScripts for a render process. class UserScriptSlave { public: @@ -31,6 +35,8 @@ class UserScriptSlave { // testability. bool InjectScripts(WebKit::WebFrame* frame, UserScript::RunLocation location); + static void InsertInitExtensionCode(std::vector<WebScriptSource>* sources, + const std::string& extension_id); private: // Shared memory containing raw script data. scoped_ptr<base::SharedMemory> shared_memory_; |