diff options
author | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-16 02:41:28 +0000 |
---|---|---|
committer | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-16 02:41:28 +0000 |
commit | b68d5ed3f9d1b49b24713431bfe212b7601b75b1 (patch) | |
tree | 9d374ca1d7c1f5f8a25fefacde0bcf3396595da6 | |
parent | f606747ffb21e9d0c6d55c9b57d42445503728f1 (diff) | |
download | chromium_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
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();"> |