diff options
author | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-08 20:53:24 +0000 |
---|---|---|
committer | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-08 20:53:24 +0000 |
commit | 0281b06f8bbde4c064a9276e6d70484ba2a3eaec (patch) | |
tree | fb2a4a873c32f45d27d982a8eb5068349d311c4d /chrome/renderer/extensions | |
parent | b6f05b3fd9422fd9b5c8142fa4224ba2d8abf1d4 (diff) | |
download | chromium_src-0281b06f8bbde4c064a9276e6d70484ba2a3eaec.zip chromium_src-0281b06f8bbde4c064a9276e6d70484ba2a3eaec.tar.gz chromium_src-0281b06f8bbde4c064a9276e6d70484ba2a3eaec.tar.bz2 |
Revert 17889. It broke the extensions_uitests. And I didn't even get it
reviewed! (Wow, brainfart.)
TBR=aa
Review URL: http://codereview.chromium.org/119324
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17893 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/extensions')
-rw-r--r-- | chrome/renderer/extensions/bindings_utils.cc | 23 | ||||
-rw-r--r-- | chrome/renderer/extensions/bindings_utils.h | 5 | ||||
-rw-r--r-- | chrome/renderer/extensions/event_bindings.cc | 15 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_api_client_unittest.cc | 7 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_process_bindings.cc | 125 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_process_bindings.h | 16 |
6 files changed, 79 insertions, 112 deletions
diff --git a/chrome/renderer/extensions/bindings_utils.cc b/chrome/renderer/extensions/bindings_utils.cc index 81e2058..097c8d0 100644 --- a/chrome/renderer/extensions/bindings_utils.cc +++ b/chrome/renderer/extensions/bindings_utils.cc @@ -4,7 +4,6 @@ #include "chrome/renderer/extensions/bindings_utils.h" -#include "base/string_util.h" #include "chrome/renderer/render_view.h" #include "webkit/glue/webframe.h" @@ -22,25 +21,3 @@ RenderView* GetRenderViewForCurrentContext() { DCHECK(renderview) << "Encountered a WebView without a WebViewDelegate"; return renderview; } - -void CallFunctionInContext(v8::Handle<v8::Context> context, - const std::string& function_name, int argc, - v8::Handle<v8::Value>* argv) { - v8::Context::Scope context_scope(context); - - // Look up the function name, which may be a sub-property like - // "chrome.handleResponse_" in the global variable. - v8::Local<v8::Value> value = context->Global(); - std::vector<std::string> components; - SplitStringDontTrim(function_name, '.', &components); - for (size_t i = 0; i < components.size(); ++i) { - if (value->IsObject()) - value = value->ToObject()->Get(v8::String::New(components[i].c_str())); - } - if (!value->IsFunction()) - return; - - v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value); - if (!function.IsEmpty()) - function->Call(v8::Object::New(), argc, argv); -} diff --git a/chrome/renderer/extensions/bindings_utils.h b/chrome/renderer/extensions/bindings_utils.h index c4be3ad..7596952 100644 --- a/chrome/renderer/extensions/bindings_utils.h +++ b/chrome/renderer/extensions/bindings_utils.h @@ -8,7 +8,6 @@ #include "app/resource_bundle.h" #include "base/singleton.h" #include "base/string_piece.h" -#include "v8/include/v8.h" #include <string> @@ -33,8 +32,4 @@ const char* GetStringResource() { // an error to call this when not in a V8 context. RenderView* GetRenderViewForCurrentContext(); -void CallFunctionInContext(v8::Handle<v8::Context> context, - const std::string& function_name, int argc, - v8::Handle<v8::Value>* argv); - #endif // CHROME_RENDERER_EXTENSIONS_BINDINGS_UTILS_H_ diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc index 576beba..19a9245 100644 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -168,6 +168,19 @@ void EventBindings::CallFunction(const std::string& function_name, int argc, v8::Handle<v8::Value>* argv) { for (ContextList::iterator it = GetRegisteredContexts().begin(); it != GetRegisteredContexts().end(); ++it) { - CallFunctionInContext(*it, function_name, argc, argv); + DCHECK(!it->IsEmpty()); + v8::Context::Scope context_scope(*it); + v8::Local<v8::Object> global = (*it)->Global(); + + v8::Local<v8::Script> script = v8::Script::Compile( + v8::String::New(function_name.c_str())); + v8::Local<v8::Value> function_obj = script->Run(); + if (!function_obj->IsFunction()) + continue; + + v8::Local<v8::Function> function = + v8::Local<v8::Function>::Cast(function_obj); + if (!function.IsEmpty()) + function->Call(v8::Object::New(), argc, argv); } } diff --git a/chrome/renderer/extensions/extension_api_client_unittest.cc b/chrome/renderer/extensions/extension_api_client_unittest.cc index b77394c0..ddc7c42 100644 --- a/chrome/renderer/extensions/extension_api_client_unittest.cc +++ b/chrome/renderer/extensions/extension_api_client_unittest.cc @@ -90,9 +90,10 @@ TEST_F(ExtensionAPIClientTest, CallbackDispatching) { int callback_id = params.c; ASSERT_TRUE(callback_id >= 0); - //// Now send the callback a response - ExtensionProcessBindings::HandleResponse( - callback_id, true, "{\"foo\":\"bar\"}", ""); + // Now send the callback a response + ExtensionProcessBindings::CallContext call(GetMainFrame(), "CreateTab"); + ExtensionProcessBindings::ExecuteResponseInFrame( + &call, callback_id, true, "{\"foo\":\"bar\"}", ""); // And verify that it worked ASSERT_EQ("pass", GetConsoleMessage()); diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index 5580e8d..6057a3e 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -5,7 +5,6 @@ #include "chrome/renderer/extensions/extension_process_bindings.h" #include "base/singleton.h" -#include "base/stl_util-inl.h" #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "chrome/renderer/extensions/bindings_utils.h" @@ -34,41 +33,10 @@ const char* kExtensionDeps[] = { // |extension_id| -> <List of v8 Contexts for the "views" of that extension> typedef std::list< v8::Persistent<v8::Context> > ContextList; typedef std::map<std::string, ContextList> ExtensionIdContextsMap; - -// Contains info relevant to a pending request. -struct CallContext { - public : - CallContext(v8::Persistent<v8::Context> context, const std::string& name) - : context(context), name(name) { - } - v8::Persistent<v8::Context> context; - std::string name; -}; -typedef std::map<int, CallContext*> PendingRequestMap; - -struct SingletonData { - std::set<std::string> function_names_; +struct ExtensionViewContexts { ExtensionIdContextsMap contexts; - PendingRequestMap pending_requests; - - ~SingletonData() { - STLDeleteContainerPairSecondPointers(pending_requests.begin(), - pending_requests.end()); - } }; -static std::set<std::string>* GetFunctionNameSet() { - return &Singleton<SingletonData>()->function_names_; -} - -static ContextList& GetRegisteredContexts(std::string extension_id) { - return Singleton<SingletonData>::get()->contexts[extension_id]; -} - -static PendingRequestMap& GetPendingRequestMap() { - return Singleton<SingletonData>::get()->pending_requests; -} - class ExtensionImpl : public v8::Extension { public: ExtensionImpl() : v8::Extension( @@ -101,6 +69,18 @@ class ExtensionImpl : public v8::Extension { } private: + struct SingletonData { + std::set<std::string> function_names_; + }; + + static std::set<std::string>* GetFunctionNameSet() { + return &Singleton<SingletonData>()->function_names_; + } + + static ContextList& GetRegisteredContexts(std::string extension_id) { + return Singleton<ExtensionViewContexts>::get()->contexts[extension_id]; + } + static v8::Handle<v8::Value> RegisterExtension(const v8::Arguments& args) { RenderView* renderview = GetRenderViewForCurrentContext(); DCHECK(renderview); @@ -120,24 +100,11 @@ class ExtensionImpl : public v8::Extension { DCHECK_EQ(args.Length(), 1); DCHECK(args[0]->IsString()); + std::string extension_id(*v8::String::Utf8Value(args[0])); + ContextList& contexts = GetRegisteredContexts(extension_id); v8::Local<v8::Context> current_context = v8::Context::GetCurrent(); DCHECK(!current_context.IsEmpty()); - // Remove all pending requests for this context. - PendingRequestMap pending_requests = GetPendingRequestMap(); - for (PendingRequestMap::iterator it = pending_requests.begin(); - it != pending_requests.end(); ) { - PendingRequestMap::iterator current = it++; - if (current->second->context == current_context) { - current->second->context.Dispose(); - current->second->context.Clear(); - delete current->second; - pending_requests.erase(current); - } - } - - std::string extension_id(*v8::String::Utf8Value(args[0])); - ContextList& contexts = GetRegisteredContexts(extension_id); ContextList::iterator it = std::find(contexts.begin(), contexts.end(), current_context); if (it == contexts.end()) { @@ -182,26 +149,22 @@ class ExtensionImpl : public v8::Extension { static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { // Get the current RenderView so that we can send a routed IPC message from // the correct source. + WebFrame* webframe = WebFrame::RetrieveFrameForCurrentContext(); RenderView* renderview = GetRenderViewForCurrentContext(); - if (!renderview) + if (!webframe || !renderview) return v8::Undefined(); if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsInt32() || !args[2]->IsBoolean()) return v8::Undefined(); - std::string name = *v8::String::AsciiValue(args.Data()); - std::string json_args = *v8::String::Utf8Value(args[0]); int request_id = args[1]->Int32Value(); bool has_callback = args[2]->BooleanValue(); - v8::Persistent<v8::Context> current_context = - v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); - DCHECK(!current_context.IsEmpty()); - GetPendingRequestMap()[request_id] = - new CallContext(current_context, *v8::String::AsciiValue(args.Data())); - - renderview->SendExtensionRequest(name, json_args, request_id, has_callback); + renderview->SendExtensionRequest( + std::string(*v8::String::AsciiValue(args.Data())), + std::string(*v8::String::Utf8Value(args[0])), + request_id, has_callback, webframe); return v8::Undefined(); } @@ -223,23 +186,31 @@ void ExtensionProcessBindings::RegisterExtensionContext(WebFrame* frame) { "chrome.self.register_();"))); } -void ExtensionProcessBindings::HandleResponse(int request_id, bool success, - const std::string& response, - const std::string& error) { - CallContext* call = GetPendingRequestMap()[request_id]; - if (!call) - return; // The frame went away. - - v8::HandleScope handle_scope; - v8::Handle<v8::Value> argv[5]; - argv[0] = v8::Integer::New(request_id); - argv[1] = v8::String::New(call->name.c_str()); - argv[2] = v8::Boolean::New(success); - argv[3] = v8::String::New(response.c_str()); - argv[4] = v8::String::New(error.c_str()); - CallFunctionInContext(call->context, "chrome.handleResponse_", - arraysize(argv), argv); - - GetPendingRequestMap().erase(request_id); - delete call; +void ExtensionProcessBindings::ExecuteResponseInFrame( + CallContext *call, int request_id, bool success, + const std::string& response, + const std::string& error) { + std::string code = "chrome.handleResponse_("; + code += IntToString(request_id); + + code += ", '" + call->name_; + + if (success) + code += "', true"; + else + code += "', false"; + + code += ", '"; + size_t offset = code.length(); + code += response; + ReplaceSubstringsAfterOffset(&code, offset, "\\", "\\\\"); + ReplaceSubstringsAfterOffset(&code, offset, "'", "\\'"); + code += "', '"; + offset = code.length(); + code += error; + ReplaceSubstringsAfterOffset(&code, offset, "\\", "\\\\"); + ReplaceSubstringsAfterOffset(&code, offset, "'", "\\'"); + code += "')"; + + call->frame_->ExecuteScript(WebScriptSource(WebString::fromUTF8(code))); } diff --git a/chrome/renderer/extensions/extension_process_bindings.h b/chrome/renderer/extensions/extension_process_bindings.h index 9639090..d5798cd 100644 --- a/chrome/renderer/extensions/extension_process_bindings.h +++ b/chrome/renderer/extensions/extension_process_bindings.h @@ -16,12 +16,22 @@ class WebFrame; class ExtensionProcessBindings { public: + struct CallContext { + public : + CallContext(WebFrame *frame, const std::string& name) + : frame_(frame), + name_(name) {} + WebFrame* frame_; + std::string name_; + }; + static void SetFunctionNames(const std::vector<std::string>& names); static v8::Extension* Get(); static void RegisterExtensionContext(WebFrame* frame); - static void HandleResponse(int request_id, bool success, - const std::string& response, - const std::string& error); + static void ExecuteResponseInFrame(CallContext *call, int request_id, + bool success, + const std::string& response, + const std::string& error); }; #endif // CHROME_RENDERER_EXTENSIONS_EXTENSION_PROCESS_BINDINGS_H_ |