summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-16 02:41:28 +0000
committerrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-16 02:41:28 +0000
commitb68d5ed3f9d1b49b24713431bfe212b7601b75b1 (patch)
tree9d374ca1d7c1f5f8a25fefacde0bcf3396595da6
parentf606747ffb21e9d0c6d55c9b57d42445503728f1 (diff)
downloadchromium_src-b68d5ed3f9d1b49b24713431bfe212b7601b75b1.zip
chromium_src-b68d5ed3f9d1b49b24713431bfe212b7601b75b1.tar.gz
chromium_src-b68d5ed3f9d1b49b24713431bfe212b7601b75b1.tar.bz2
Initial plumbing for sending events from the browser to extension renderers. Implement onTabMoved.
Review URL: http://codereview.chromium.org/73065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13824 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.cc93
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.h55
-rwxr-xr-xchrome/browser/extensions/extension_message_service.cc15
-rwxr-xr-xchrome/browser/extensions/extension_message_service.h2
-rwxr-xr-xchrome/browser/extensions/extension_process_manager.cc21
-rwxr-xr-xchrome/browser/extensions/extension_process_manager.h8
-rw-r--r--chrome/browser/extensions/extension_tabs_module.cc12
-rw-r--r--chrome/browser/extensions/extension_tabs_module.h8
-rw-r--r--chrome/browser/extensions/extensions_service.cc4
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc2
-rwxr-xr-xchrome/renderer/extensions/renderer_extension_bindings.cc11
-rwxr-xr-xchrome/renderer/extensions/renderer_extension_bindings.h6
-rw-r--r--chrome/renderer/render_thread.cc9
-rw-r--r--chrome/renderer/render_thread.h3
-rwxr-xr-xchrome/renderer/renderer_resources.grd2
-rw-r--r--chrome/renderer/resources/event_bindings.js27
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js5
-rw-r--r--chrome/renderer/resources/renderer_extension_bindings.js2
-rw-r--r--chrome/test/data/extensions/test/TabsAPI/1/tabs_api.html5
22 files changed, 284 insertions, 21 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 4b74265..d4d9057 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -1894,6 +1894,14 @@
>
</File>
<File
+ RelativePath=".\extensions\extension_browser_event_router.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\extensions\extension_browser_event_router.h"
+ >
+ </File>
+ <File
RelativePath=".\extensions\extension_error_reporter.cc"
>
</File>
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc
new file mode 100644
index 0000000..a80abea
--- /dev/null
+++ b/chrome/browser/extensions/extension_browser_event_router.cc
@@ -0,0 +1,93 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/extension_browser_event_router.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/extensions/extension.h"
+#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/common/notification_service.h"
+
+const char* kOnTabMoved = "tab-moved";
+
+ExtensionBrowserEventRouter* ExtensionBrowserEventRouter::GetInstance() {
+ return Singleton<ExtensionBrowserEventRouter>::get();
+}
+
+void ExtensionBrowserEventRouter::Init() {
+ if (initialized_)
+ return;
+
+ NotificationService::current()->AddObserver(this,
+ NotificationType::BROWSER_OPENED, NotificationService::AllSources());
+ NotificationService::current()->AddObserver(this,
+ NotificationType::BROWSER_CLOSED, NotificationService::AllSources());
+
+ initialized_ = true;
+}
+
+ExtensionBrowserEventRouter::ExtensionBrowserEventRouter()
+ : initialized_(false) { }
+
+// NotificationObserver
+void ExtensionBrowserEventRouter::Observe(NotificationType type,
+ const NotificationSource& source, const NotificationDetails& details) {
+ Browser* browser;
+
+ switch (type.value) {
+ case(NotificationType::BROWSER_OPENED) :
+ browser = Source<Browser>(source).ptr();
+ browser->tabstrip_model()->AddObserver(this);
+ break;
+ case(NotificationType::BROWSER_CLOSED) :
+ browser = Source<Browser>(source).ptr();
+ browser->tabstrip_model()->RemoveObserver(this);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents,
+ int index,
+ bool foreground) { }
+
+void ExtensionBrowserEventRouter::TabClosingAt(TabContents* contents,
+ int index) { }
+
+void ExtensionBrowserEventRouter::TabDetachedAt(TabContents* contents,
+ int index) { }
+
+void ExtensionBrowserEventRouter::TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture) { }
+
+void ExtensionBrowserEventRouter::TabMoved(TabContents* contents,
+ int from_index,
+ int to_index) {
+ Profile *profile = contents->profile();
+
+ ListValue args;
+ DictionaryValue *object_args = new DictionaryValue();
+
+ object_args->Set(L"tabId", Value::CreateIntegerValue(
+ ExtensionTabUtil::GetTabId(contents)));
+ object_args->Set(L"windowId", Value::CreateIntegerValue(
+ ExtensionTabUtil::GetWindowIdOfTab(contents)));
+ object_args->Set(L"fromIndex", Value::CreateIntegerValue(from_index));
+ object_args->Set(L"toIndex", Value::CreateIntegerValue(to_index));
+
+ args.Append(object_args);
+ ExtensionProcessManager::GetInstance()->DispatchEventToRenderers(profile,
+ kOnTabMoved, args);
+}
+
+void ExtensionBrowserEventRouter::TabChangedAt(TabContents* contents,
+ int index,
+ bool loading_only) { }
+
+void ExtensionBrowserEventRouter::TabStripEmpty() { }
diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h
new file mode 100644
index 0000000..a438e66
--- /dev/null
+++ b/chrome/browser/extensions/extension_browser_event_router.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
+
+#include <vector>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/singleton.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/common/notification_observer.h"
+
+// The ExtensionBrowserEventRouter listens to Browser window & tab events
+// and routes them to listeners inside extension process renderers.
+// ExtensionBrowserEventRouter listens to *all* events, but will only route
+// events from windows/tabs within a profile to extension processes in the same
+// profile.
+class ExtensionBrowserEventRouter : public TabStripModelObserver,
+ public NotificationObserver {
+ public:
+ // Get Browser-Global instance
+ static ExtensionBrowserEventRouter* GetInstance();
+
+ // Must be called once. Subsequent calls have no effect.
+ void Init();
+
+ // TabStripModelObserver
+ void TabInsertedAt(TabContents* contents, int index, bool foreground);
+ void TabClosingAt(TabContents* contents, int index);
+ void TabDetachedAt(TabContents* contents, int index);
+ void TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture);
+ void TabMoved(TabContents* contents, int from_index, int to_index);
+ void TabChangedAt(TabContents* contents, int index, bool loading_only);
+ void TabStripEmpty();
+
+ // NotificationObserver
+ void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+ private:
+ ExtensionBrowserEventRouter();
+ friend struct DefaultSingletonTraits<ExtensionBrowserEventRouter>;
+
+ bool initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionBrowserEventRouter);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_BROWSER_EVENT_ROUTER_H_
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 74e2757..3c2c1de 100755
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -54,12 +54,20 @@ ExtensionMessageService::ExtensionMessageService()
: next_port_id_(0) {
}
+std::set<int> ExtensionMessageService::GetUniqueProcessIds() {
+ std::set<int> ids;
+ ProcessIDMap::iterator it;
+ AutoLock lock(renderers_lock_);
+
+ for (it = process_ids_.begin(); it != process_ids_.end(); it++) {
+ ids.insert(it->second);
+ }
+ return ids;
+}
+
void ExtensionMessageService::RegisterExtension(
const std::string& extension_id, int render_process_id) {
AutoLock lock(renderers_lock_);
- // TODO(mpcomplete): We need to ensure an extension always ends up in a single
- // process. I think this means having an ExtensionProcessManager which holds
- // a BrowsingContext for each extension.
DCHECK(process_ids_.find(extension_id) == process_ids_.end() ||
process_ids_[extension_id] == render_process_id);
process_ids_[extension_id] = render_process_id;
@@ -174,4 +182,3 @@ void ExtensionMessageService::Observe(NotificationType type,
source);
}
}
-
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index 1238338..f938b51 100755
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -61,6 +61,8 @@ class ExtensionMessageService : public NotificationObserver {
const NotificationSource& source,
const NotificationDetails& details);
+ std::set<int> GetUniqueProcessIds();
+
private:
// A map of extension ID to the render_process_id that the extension lives in.
typedef std::map<std::string, int> ProcessIDMap;
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index e9d7bc9..b2fb63e 100755
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -4,10 +4,14 @@
#include "chrome/browser/extensions/extension_process_manager.h"
+#include "base/json_writer.h"
#include "base/singleton.h"
+#include "base/values.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/extensions/extension_view.h"
+#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/tab_contents/site_instance.h"
+#include "chrome/common/render_messages.h"
// static
ExtensionProcessManager* ExtensionProcessManager::GetInstance() {
@@ -23,7 +27,7 @@ ExtensionProcessManager::~ExtensionProcessManager() {
ExtensionView* ExtensionProcessManager::CreateView(Extension* extension,
const GURL& url,
Browser* browser) {
- return new ExtensionView(extension, url,
+ return new ExtensionView(extension, url,
GetSiteInstanceForURL(url, browser->profile()),
browser);
}
@@ -34,6 +38,21 @@ SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(
return browsing_instance->GetSiteInstanceForURL(url);
}
+void ExtensionProcessManager::DispatchEventToRenderers(Profile *profile,
+ const std::string& event_name, const ListValue& data) {
+ std::string json_data;
+ JSONWriter::Write(&data, false, &json_data);
+
+ std::set<int> process_ids = ExtensionMessageService::GetInstance(
+ profile->GetRequestContext())->GetUniqueProcessIds();
+
+ std::set<int>::iterator id;
+ for (id = process_ids.begin(); id != process_ids.end(); ++id) {
+ RenderProcessHost* rph = RenderProcessHost::FromID(*id);
+ rph->Send(new ViewMsg_ExtensionHandleEvent(event_name, json_data));
+ }
+}
+
BrowsingInstance* ExtensionProcessManager::GetBrowsingInstance(
Profile* profile) {
BrowsingInstance* instance = browsing_instance_map_[profile];
diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h
index fdbff8a..7e56fc8 100755
--- a/chrome/browser/extensions/extension_process_manager.h
+++ b/chrome/browser/extensions/extension_process_manager.h
@@ -8,12 +8,14 @@
#include "base/ref_counted.h"
#include <map>
+#include <string>
class Browser;
class BrowsingInstance;
class Extension;
class ExtensionView;
class GURL;
+class ListValue;
class Profile;
class SiteInstance;
@@ -41,6 +43,12 @@ class ExtensionProcessManager {
// Returns the SiteInstance that the given URL belongs to in this profile.
SiteInstance* GetSiteInstanceForURL(const GURL& url, Profile* profile);
+
+ // Sends the event to each renderer process within the current profile that
+ // contain at least one extension renderer.
+ void DispatchEventToRenderers(Profile *profile,
+ const std::string& event_name,
+ const ListValue& data);
private:
// Returns our BrowsingInstance for the given profile. Lazily created and
// cached.
diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc
index 811bc97..86fcf49 100644
--- a/chrome/browser/extensions/extension_tabs_module.cc
+++ b/chrome/browser/extensions/extension_tabs_module.cc
@@ -17,6 +17,14 @@ static DictionaryValue* CreateTabValue(TabStripModel* tab_strip_model,
static bool GetIndexOfTabId(const TabStripModel* tab_strip, int tab_id,
int* tab_index);
+int ExtensionTabUtil::GetTabId(const TabContents* tab_contents) {
+ return tab_contents->controller()->session_id().id();
+}
+
+int ExtensionTabUtil::GetWindowIdOfTab(const TabContents* tab_contents) {
+ return tab_contents->controller()->window_id().id();
+}
+
bool GetTabsForWindowFunction::RunImpl() {
if (!args_->IsType(Value::TYPE_NULL))
return false;
@@ -198,9 +206,9 @@ static DictionaryValue* CreateTabValue(TabStripModel* tab_strip,
DCHECK(controller); // TODO(aa): Is this a valid assumption?
DictionaryValue* result = new DictionaryValue();
- result->SetInteger(L"id", controller->session_id().id());
+ result->SetInteger(L"id", ExtensionTabUtil::GetTabId(contents));
result->SetInteger(L"index", tab_index);
- result->SetInteger(L"windowId", controller->window_id().id());
+ result->SetInteger(L"windowId", ExtensionTabUtil::GetWindowIdOfTab(contents));
result->SetString(L"url", contents->GetURL().spec());
result->SetString(L"title", UTF16ToWide(contents->GetTitle()));
result->SetBoolean(L"selected", tab_index == tab_strip->selected_index());
diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h
index c358529..3aa4520 100644
--- a/chrome/browser/extensions/extension_tabs_module.h
+++ b/chrome/browser/extensions/extension_tabs_module.h
@@ -7,6 +7,14 @@
#include "chrome/browser/extensions/extension_function.h"
+class TabContents;
+
+class ExtensionTabUtil {
+ public:
+ static int GetTabId(const TabContents* tab_contents);
+ static int GetWindowIdOfTab(const TabContents* tab_contents);
+};
+
class GetTabsForWindowFunction : public SyncExtensionFunction {
virtual bool RunImpl();
};
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 942d23c..ecc69a1 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -14,6 +14,7 @@
#include "base/values.h"
#include "net/base/file_stream.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/extensions/extension_view.h"
@@ -85,6 +86,9 @@ ExtensionsService::~ExtensionsService() {
}
bool ExtensionsService::Init() {
+ // Start up the extension event routers.
+ ExtensionBrowserEventRouter::GetInstance()->Init();
+
#if defined(OS_WIN)
// TODO(port): ExtensionsServiceBackend::CheckForExternalUpdates depends on
// the Windows registry.
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index dc23b07..4f20c80 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -672,6 +672,8 @@
'browser/extensions/extension_message_service.h',
'browser/extensions/extension_process_manager.cc',
'browser/extensions/extension_process_manager.h',
+ 'browser/extensions/extension_browser_event_router.cc',
+ 'browser/extensions/extension_browser_event_router.h',
'browser/extensions/extension_protocols.cc',
'browser/extensions/extension_protocols.h',
'browser/extensions/extension_tabs_module.cc',
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 06170ed..6bad5b23 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -546,6 +546,11 @@ IPC_BEGIN_MESSAGES(View)
std::string /* message */,
int /* source_port_id */)
+ // Route a browser event to all extension renderers within this process.
+ IPC_MESSAGE_CONTROL2(ViewMsg_ExtensionHandleEvent,
+ std::string /* event_name */,
+ std::string /* event_data */)
+
// Tell the renderer process all known extension function names.
IPC_MESSAGE_CONTROL1(ViewMsg_Extension_SetFunctionNames,
std::vector<std::string>)
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index 5de1817..5952463 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -7,6 +7,7 @@
#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/extensions/renderer_extension_bindings.h"
#include "chrome/renderer/js_only_v8_extensions.h"
#include "chrome/renderer/render_view.h"
@@ -22,6 +23,7 @@ namespace {
const char kExtensionName[] = "chrome/ExtensionProcessBindings";
const char* kExtensionDeps[] = {
BaseJsV8Extension::kName,
+ EventBindings::kName,
JsonJsV8Extension::kName,
JsonSchemaJsV8Extension::kName,
RendererExtensionBindings::kName,
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc
index 8035422..63214d73 100755
--- a/chrome/renderer/extensions/renderer_extension_bindings.cc
+++ b/chrome/renderer/extensions/renderer_extension_bindings.cc
@@ -100,3 +100,14 @@ void RendererExtensionBindings::HandleMessage(const std::string& message,
EventBindings::CallFunction("chromium.Port.dispatchOnMessage_",
arraysize(argv), argv);
}
+
+void RendererExtensionBindings::HandleEvent(const std::string& event_name,
+ const std::string& args) {
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::Value> argv[2];
+ argv[0] = v8::String::New(event_name.c_str());
+ argv[1] = v8::String::New(args.c_str());
+
+ EventBindings::CallFunction("chromium.Event.dispatchJSON_",
+ arraysize(argv), argv);
+}
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.h b/chrome/renderer/extensions/renderer_extension_bindings.h
index 3fc1fb4..374dfb6 100755
--- a/chrome/renderer/extensions/renderer_extension_bindings.h
+++ b/chrome/renderer/extensions/renderer_extension_bindings.h
@@ -27,6 +27,12 @@ class RendererExtensionBindings {
// Dispatch the given message sent on this channel.
static void HandleMessage(const std::string& message, int port_id);
+
+ // Send this event to all extensions in this process. |args| is a JSON-
+ // serialized array that will be deserialized and provided to the callback
+ // function in event_bindings.js
+ static void HandleEvent(const std::string& event_name,
+ const std::string& args);
};
#endif // CHROME_RENDERER_EXTENSIONS_RENDERER_EXTENSION_BINDINGS_H_
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index e1bf797..7909ec0 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -184,10 +184,14 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
OnGetCacheResourceStats)
IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_NewScripts,
OnUpdateUserScripts)
+ // TODO(rafaelw): create an ExtensionDispatcher that handles extension
+ // messages seperates their handling from the RenderThread.
IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleConnect,
OnExtensionHandleConnect)
IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleMessage,
OnExtensionHandleMessage)
+ IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleEvent,
+ OnExtensionHandleEvent)
IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetFunctionNames,
OnSetExtensionFunctionNames)
IPC_END_MESSAGE_MAP()
@@ -323,3 +327,8 @@ void RenderThread::OnExtensionHandleMessage(const std::string& message,
int port_id) {
RendererExtensionBindings::HandleMessage(message, port_id);
}
+
+void RenderThread::OnExtensionHandleEvent(const std::string event_name,
+ const std::string event_data) {
+ RendererExtensionBindings::HandleEvent(event_name, event_data);
+}
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 0d5da09..637c4c5 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -5,6 +5,7 @@
#ifndef CHROME_RENDERER_RENDER_THREAD_H_
#define CHROME_RENDERER_RENDER_THREAD_H_
+#include <string>
#include <vector>
#include "base/gfx/native_widget_types.h"
@@ -125,6 +126,8 @@ class RenderThread : public RenderThreadBase,
void OnExtensionHandleConnect(int channel_id);
void OnExtensionHandleMessage(const std::string& message, int channel_id);
+ void OnExtensionHandleEvent(const std::string event_name,
+ const std::string event_data);
// Gather usage statistics from the in-memory cache and inform our host.
// These functions should be call periodically so that the host can make
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index cda253b..c59e98c 100755
--- a/chrome/renderer/renderer_resources.grd
+++ b/chrome/renderer/renderer_resources.grd
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. -->
+without changes to the corresponding grd file. -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/renderer_resources.h" type="rc_header">
diff --git a/chrome/renderer/resources/event_bindings.js b/chrome/renderer/resources/event_bindings.js
index f8a6517..81dddde 100644
--- a/chrome/renderer/resources/event_bindings.js
+++ b/chrome/renderer/resources/event_bindings.js
@@ -8,9 +8,9 @@ var chromium = chromium || {};
// with that name will route through this object's listeners.
//
// Example:
- // chromium.ontabchanged = new Event('tabchanged');
- // chromium.ontabchanged.addListener(function(data) { alert(data); });
- // chromium.Event.dispatch_('tabchanged', 'hi');
+ // chromium.tabs.onTabChanged = new chromium.Event("tab-changed");
+ // chromium.tabs.onTabChanged.addListener(function(data) { alert(data); });
+ // chromium.Event.dispatch_("tab-changed", "hi");
// will result in an alert dialog that says 'hi'.
chromium.Event = function(opt_eventName) {
this.eventName_ = opt_eventName;
@@ -20,21 +20,24 @@ var chromium = chromium || {};
// A map of event names to the event object that is registered to that name.
chromium.Event.attached_ = {};
- // Dispatches a named event with the given JSON data, which is deserialized
- // before dispatch.
- chromium.Event.dispatchJSON_ = function(name, data) {
+ // Dispatches a named event with the given JSON array, which is deserialized
+ // before dispatch. The JSON array is the list of arguments that will be
+ // sent with the event callback.
+ chromium.Event.dispatchJSON_ = function(name, args) {
if (chromium.Event.attached_[name]) {
- if (data) {
- data = goog.json.parse(data);
+ if (args) {
+ args = goog.json.parse(args);
}
- chromium.Event.attached_[name].dispatch(data);
+ chromium.Event.attached_[name].dispatch.apply(
+ chromium.Event.attached_[name], args);
}
};
- // Dispatches a named event with the given object data.
- chromium.Event.dispatch_ = function(name, data) {
+ // Dispatches a named event with the given arguments, supplied as an array.
+ chromium.Event.dispatch_ = function(name, args) {
if (chromium.Event.attached_[name]) {
- chromium.Event.attached_[name].dispatch(data);
+ chromium.Event.attached_[name].dispatch.apply(
+ chromium.Event.attached_[name], args);
}
};
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index 454a9b0..7b74283 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -129,6 +129,10 @@ var chromium;
chromium.tabs.removeTab.params = [
chromium.types.pInt
];
+
+ // onTabMoved sends ({tabId, windowId, fromIndex, toIndex}) as named
+ // arguments.
+ chromium.tabs.onTabMoved = new chromium.Event("tab-moved");
//----------------------------------------------------------------------------
@@ -136,3 +140,4 @@ var chromium;
chromium.self = {};
chromium.self.onConnect = new chromium.Event("channel-connect");
})();
+
diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js
index fafd491..ef71f90 100644
--- a/chrome/renderer/resources/renderer_extension_bindings.js
+++ b/chrome/renderer/resources/renderer_extension_bindings.js
@@ -23,7 +23,7 @@ var chromium = chromium || {};
// Called by native code when a channel has been opened to this context.
chromium.Port.dispatchOnConnect_ = function(portId) {
var port = new chromium.Port(portId);
- chromium.Event.dispatch_("channel-connect", port);
+ chromium.Event.dispatch_("channel-connect", [port]);
};
// Called by native code when a message has been sent to the given port.
diff --git a/chrome/test/data/extensions/test/TabsAPI/1/tabs_api.html b/chrome/test/data/extensions/test/TabsAPI/1/tabs_api.html
index 1ee9417..948dea4 100644
--- a/chrome/test/data/extensions/test/TabsAPI/1/tabs_api.html
+++ b/chrome/test/data/extensions/test/TabsAPI/1/tabs_api.html
@@ -38,6 +38,11 @@ function updateAll() {
chromium.tabs.updateTab(getTabData(tabs[i].id));
}
}
+
+chromium.tabs.onTabMoved.addListener(function(updateParams) {
+ loadTabList();
+});
+
</script>
</head>
<body onload="loadTabList();">