summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/extensions
diff options
context:
space:
mode:
authorerikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 15:12:56 +0000
committererikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 15:12:56 +0000
commitc02b7c98f49e94910d622162455293e52841089e (patch)
tree709d9ab5c72a99198cb47ebd46f3b07a580bb280 /chrome/renderer/extensions
parent43b24b69d766df5f801daa86656c50d361fe8a6b (diff)
downloadchromium_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-xchrome/renderer/extensions/event_bindings.cc50
-rwxr-xr-xchrome/renderer/extensions/event_bindings.h5
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_".