diff options
author | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-01 15:12:56 +0000 |
---|---|---|
committer | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-01 15:12:56 +0000 |
commit | c02b7c98f49e94910d622162455293e52841089e (patch) | |
tree | 709d9ab5c72a99198cb47ebd46f3b07a580bb280 /chrome/renderer/extensions | |
parent | 43b24b69d766df5f801daa86656c50d361fe8a6b (diff) | |
download | chromium_src-c02b7c98f49e94910d622162455293e52841089e.zip chromium_src-c02b7c98f49e94910d622162455293e52841089e.tar.gz chromium_src-c02b7c98f49e94910d622162455293e52841089e.tar.bz2 |
Only send events to renderers that are listening to an event.Notify browser when a renderer is listening to an event.
Review URL: http://codereview.chromium.org/100214
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15050 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/extensions')
-rwxr-xr-x | chrome/renderer/extensions/event_bindings.cc | 50 | ||||
-rwxr-xr-x | chrome/renderer/extensions/event_bindings.h | 5 |
2 files changed, 52 insertions, 3 deletions
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc index 59ed319..06479dc 100755 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -6,6 +6,7 @@ #include "base/basictypes.h" #include "base/singleton.h" +#include "chrome/common/render_messages.h" #include "chrome/renderer/extensions/bindings_utils.h" #include "chrome/renderer/extensions/event_bindings.h" #include "chrome/renderer/js_only_v8_extensions.h" @@ -14,15 +15,32 @@ namespace { +// Keep a local cache of RenderThread so that we can mock it out for unit tests. +static RenderThreadBase* render_thread = NULL; + +static RenderThreadBase* GetRenderThread() { + return render_thread ? render_thread : RenderThread::current(); +} + // 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 ExtensionData { ContextList contexts; + std::map<std::string, int> listener_count; }; ContextList& GetRegisteredContexts() { return Singleton<ExtensionData>::get()->contexts; } +int EventIncrementListenerCount(const std::string& event_name) { + ExtensionData *data = Singleton<ExtensionData>::get(); + return ++(data->listener_count[event_name]); +} +int EventDecrementListenerCount(const std::string& event_name) { + ExtensionData *data = Singleton<ExtensionData>::get(); + return --(data->listener_count[event_name]); +} + const char* kExtensionDeps[] = { JsonJsV8Extension::kName }; const char* kContextAttachCount = "chromium.attachCount"; @@ -47,10 +65,11 @@ class ExtensionImpl : public v8::Extension { } // Attach an event name to an object. - // TODO(mpcomplete): I'm just using this to register the v8 Context right now. - // The idea is to eventually notify the browser about what events are being - // listened to, so it can dispatch appropriately. static v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) { + DCHECK(args.Length() == 1); + // TODO(erikkay) should enforce that event name is a string in the bindings + DCHECK(args[0]->IsString() || args[0]->IsUndefined()); + v8::Persistent<v8::Context> context = v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); v8::Local<v8::Object> global = context->Global(); @@ -71,10 +90,22 @@ class ExtensionImpl : public v8::Extension { v8::String::New(kContextAttachCount), v8::Integer::New(account_count_value + 1)); + if (args[0]->IsString()) { + std::string event_name(*v8::String::AsciiValue(args[0])); + if (EventIncrementListenerCount(event_name) == 1) { + GetRenderThread()->Send( + new ViewHostMsg_ExtensionAddListener(event_name)); + } + } + return v8::Undefined(); } static v8::Handle<v8::Value> DetachEvent(const v8::Arguments& args) { + DCHECK(args.Length() == 1); + // TODO(erikkay) should enforce that event name is a string in the bindings + DCHECK(args[0]->IsString() || args[0]->IsUndefined()); + v8::Local<v8::Context> context = v8::Context::GetCurrent(); v8::Local<v8::Object> global = context->Global(); v8::Local<v8::Value> attach_count = global->GetHiddenValue( @@ -90,6 +121,14 @@ class ExtensionImpl : public v8::Extension { v8::String::New(kContextAttachCount), v8::Integer::New(account_count_value - 1)); + if (args[0]->IsString()) { + std::string event_name(*v8::String::AsciiValue(args[0])); + if (EventDecrementListenerCount(event_name) == 0) { + GetRenderThread()->Send( + new ViewHostMsg_ExtensionRemoveListener(event_name)); + } + } + return v8::Undefined(); } @@ -122,6 +161,11 @@ v8::Extension* EventBindings::Get() { return new ExtensionImpl(); } +// static +void EventBindings::SetRenderThread(RenderThreadBase* thread) { + render_thread = thread; +} + void EventBindings::CallFunction(const std::string& function_name, int argc, v8::Handle<v8::Value>* argv) { for (ContextList::iterator it = GetRegisteredContexts().begin(); diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h index dd91811..0ca59c0 100755 --- a/chrome/renderer/extensions/event_bindings.h +++ b/chrome/renderer/extensions/event_bindings.h @@ -9,12 +9,17 @@ #include <string> +class RenderThreadBase; + // This class deals with the javascript bindings related to Event objects. class EventBindings { public: static const char* kName; // The v8::Extension name, for dependencies. static v8::Extension* Get(); + // Allow RenderThread to be mocked out. + static void SetRenderThread(RenderThreadBase* thread); + // Calls the given function in each registered context which is listening // for events. The function can be an object property, ie: // "chromium.Event.dispatch_". |