summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/extensions/renderer_extension_bindings.cc
diff options
context:
space:
mode:
authormpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-08 18:35:34 +0000
committermpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-08 18:35:34 +0000
commita40caa97fbdae3760f52f95f6b265bd1f39b19ae (patch)
treeb98dceab49c4efb854c9923660735cbf96addbcd /chrome/renderer/extensions/renderer_extension_bindings.cc
parent1b812ea42f713908a9034fcf2a26e8d4a8a86a04 (diff)
downloadchromium_src-a40caa97fbdae3760f52f95f6b265bd1f39b19ae.zip
chromium_src-a40caa97fbdae3760f52f95f6b265bd1f39b19ae.tar.gz
chromium_src-a40caa97fbdae3760f52f95f6b265bd1f39b19ae.tar.bz2
Add aa's Event class to our javascript bindings and use it in our extension
message passing API. Review URL: http://codereview.chromium.org/62069 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13371 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/extensions/renderer_extension_bindings.cc')
-rwxr-xr-xchrome/renderer/extensions/renderer_extension_bindings.cc118
1 files changed, 16 insertions, 102 deletions
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc
index 8254bc6..572b00c 100755
--- a/chrome/renderer/extensions/renderer_extension_bindings.cc
+++ b/chrome/renderer/extensions/renderer_extension_bindings.cc
@@ -5,53 +5,38 @@
#include "chrome/renderer/extensions/renderer_extension_bindings.h"
#include "base/basictypes.h"
-#include "base/singleton.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/resource_bundle.h"
+#include "chrome/renderer/extensions/bindings_utils.h"
+#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/render_thread.h"
#include "grit/renderer_resources.h"
-#include "webkit/glue/webframe.h"
// Message passing API example (in a content script):
// var extension =
// new chromium.Extension('00123456789abcdef0123456789abcdef0123456');
-// var channel = extension.openChannel();
-// channel.postMessage('Can you hear me now?');
-// channel.onMessage = function(msg, port) {
+// var port = extension.connect();
+// port.postMessage('Can you hear me now?');
+// port.onmessage.addListener(function(msg, port) {
// alert('response=' + msg);
// port.postMessage('I got your reponse');
-// }
+// });
namespace {
-// Keep a list of contexts that have registered themselves with us. This lets
-// us know where to dispatch events when we receive them.
-typedef std::list< v8::Persistent<v8::Context> > ContextList;
-struct SingletonData {
- ContextList contexts;
- std::string js_source;
-
- SingletonData() :
- js_source(ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_RENDERER_EXTENSION_BINDINGS_JS).as_string()) {
- }
-};
-ContextList& GetRegisteredContexts() {
- return Singleton<SingletonData>::get()->contexts;
-}
-const char* GetSource() {
- return Singleton<SingletonData>::get()->js_source.c_str();
-}
-
// We use the generic interface so that unit tests can inject a mock.
RenderThreadBase* render_thread_ = NULL;
const char* kExtensionName = "v8/RendererExtensionBindings";
-const char* kScriptAPI = "chromium.extensions.scriptAPI";
+const char* kExtensionDeps[] = { EventBindings::kName };
class ExtensionImpl : public v8::Extension {
public:
- ExtensionImpl() : v8::Extension(kExtensionName, GetSource()) {}
+ ExtensionImpl()
+ : v8::Extension(kExtensionName,
+ GetStringResource<IDR_RENDERER_EXTENSION_BINDINGS_JS>(),
+ arraysize(kExtensionDeps), kExtensionDeps) {
+ }
~ExtensionImpl() {}
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
@@ -60,8 +45,6 @@ class ExtensionImpl : public v8::Extension {
return v8::FunctionTemplate::New(OpenChannelToExtension);
} else if (name->Equals(v8::String::New("PostMessage"))) {
return v8::FunctionTemplate::New(PostMessage);
- } else if (name->Equals(v8::String::New("RegisterScriptAPI"))) {
- return v8::FunctionTemplate::New(RegisterScriptAPI);
}
return v8::Handle<v8::FunctionTemplate>();
}
@@ -89,77 +72,6 @@ class ExtensionImpl : public v8::Extension {
}
return v8::Undefined();
}
-
- // This method is internal to the extension, and fulfills a dual purpose:
- // 1. Keep track of which v8::Contexts have registered event listeners.
- // 2. Registers a private variable on the context that we use for dispatching
- // events as they come in, by calling designated methods.
- static v8::Handle<v8::Value> RegisterScriptAPI(const v8::Arguments& args) {
- if (args.Length() >= 1 && args[0]->IsObject()) {
- v8::Persistent<v8::Context> context =
- v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
- GetRegisteredContexts().push_back(context);
- context.MakeWeak(NULL, WeakContextCallback);
- context->Global()->SetHiddenValue(v8::String::New(kScriptAPI), args[0]);
- DCHECK(args[0]->ToObject()->Get(v8::String::New("dispatchOnConnect"))->
- IsFunction());
- DCHECK(args[0]->ToObject()->Get(v8::String::New("dispatchOnMessage"))->
- IsFunction());
- return v8::Undefined();
- }
- return v8::Undefined();
- }
-
- // Calls the given chromiumPrivate method in each registered context.
- static void CallMethod(const std::string& method_name, int argc,
- v8::Handle<v8::Value>* argv) {
- for (ContextList::iterator it = GetRegisteredContexts().begin();
- it != GetRegisteredContexts().end(); ++it) {
- DCHECK(!it->IsEmpty());
- v8::Context::Scope context_scope(*it);
- v8::Local<v8::Object> global = (*it)->Global();
-
- // Check if the window object is gone, which means this context's frame
- // has been unloaded.
- v8::Local<v8::Value> window = global->Get(v8::String::New("window"));
- if (!window->IsObject())
- continue;
-
- // Retrieve our hidden variable and call the method on it.
- v8::Local<v8::Value> script_api = global->GetHiddenValue(
- v8::String::New(kScriptAPI));
- if (!script_api->IsObject()) {
- NOTREACHED();
- continue;
- }
-
- v8::Handle<v8::Value> function_obj = script_api->ToObject()->Get(
- v8::String::New(method_name.c_str()));
- if (!function_obj->IsFunction()) {
- NOTREACHED();
- continue;
- }
-
- v8::Handle<v8::Function> function =
- v8::Handle<v8::Function>::Cast(function_obj);
- if (!function.IsEmpty())
- function->Call(v8::Object::New(), argc, argv);
- }
- }
-
- // Called when a registered context is garbage collected.
- static void WeakContextCallback(v8::Persistent<v8::Value> obj, void*) {
- ContextList::iterator it = std::find(GetRegisteredContexts().begin(),
- GetRegisteredContexts().end(), obj);
- if (it == GetRegisteredContexts().end()) {
- NOTREACHED();
- return;
- }
-
- it->Dispose();
- it->Clear();
- GetRegisteredContexts().erase(it);
- }
};
} // namespace
@@ -175,7 +87,8 @@ void RendererExtensionBindings::HandleConnect(int port_id) {
v8::HandleScope handle_scope;
v8::Handle<v8::Value> argv[1];
argv[0] = v8::Integer::New(port_id);
- ExtensionImpl::CallMethod("dispatchOnConnect", arraysize(argv), argv);
+ EventBindings::CallFunction("chromium.Port.dispatchOnConnect_",
+ arraysize(argv), argv);
}
void RendererExtensionBindings::HandleMessage(const std::string& message,
@@ -184,7 +97,8 @@ void RendererExtensionBindings::HandleMessage(const std::string& message,
v8::Handle<v8::Value> argv[2];
argv[0] = v8::String::New(message.c_str());
argv[1] = v8::Integer::New(port_id);
- ExtensionImpl::CallMethod("dispatchOnMessage", arraysize(argv), argv);
+ EventBindings::CallFunction("chromium.Port.dispatchOnMessage_",
+ arraysize(argv), argv);
}
} // namespace extensions_v8