summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-14 05:43:53 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-14 05:43:53 +0000
commit7b291f9c1394495724ddd81306e982e840075c08 (patch)
treefa2a2ef45f1b17018e716101395300da731d8599 /chrome/renderer
parentcc4219ad7dd27008da3db5f0e23da9a6ab2f0387 (diff)
downloadchromium_src-7b291f9c1394495724ddd81306e982e840075c08.zip
chromium_src-7b291f9c1394495724ddd81306e982e840075c08.tar.gz
chromium_src-7b291f9c1394495724ddd81306e982e840075c08.tar.bz2
Implementation of getBackgroundPage(), getToolstrips(), and
getTabContentses(). This lands http://codereview.chromium.org/159067. Raf, the only thing you need to look at is the changes to extensions_process_bindings.js and extension_api.json. BUG=13577 TEST=Browser tests added Review URL: http://codereview.chromium.org/164458 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23422 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/extensions/bindings_utils.cc4
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc74
-rw-r--r--chrome/renderer/render_view.cc17
-rw-r--r--chrome/renderer/render_view.h21
-rw-r--r--chrome/renderer/renderer_resources.grd2
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js163
6 files changed, 189 insertions, 92 deletions
diff --git a/chrome/renderer/extensions/bindings_utils.cc b/chrome/renderer/extensions/bindings_utils.cc
index 3d29f4b..13deb2a 100644
--- a/chrome/renderer/extensions/bindings_utils.cc
+++ b/chrome/renderer/extensions/bindings_utils.cc
@@ -68,8 +68,8 @@ ContextList::iterator FindContext(v8::Handle<v8::Context> context) {
ContextList::iterator it = all_contexts.begin();
for (; it != all_contexts.end(); ++it) {
- if ((*it)->context == context)
- break;
+ if ((*it)->context == context)
+ break;
}
return it;
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index cf0f344..cb22bce 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -92,8 +92,8 @@ class ExtensionImpl : public ExtensionBase {
v8::Handle<v8::String> name) {
if (name->Equals(v8::String::New("GetExtensionAPIDefinition"))) {
return v8::FunctionTemplate::New(GetExtensionAPIDefinition);
- } else if (name->Equals(v8::String::New("GetViews"))) {
- return v8::FunctionTemplate::New(GetViews);
+ } else if (name->Equals(v8::String::New("GetExtensionViews"))) {
+ return v8::FunctionTemplate::New(GetExtensionViews);
} else if (name->Equals(v8::String::New("GetNextRequestId"))) {
return v8::FunctionTemplate::New(GetNextRequestId);
} else if (name->Equals(v8::String::New("OpenChannelToTab"))) {
@@ -113,22 +113,66 @@ class ExtensionImpl : public ExtensionBase {
return v8::String::New(GetStringResource<IDR_EXTENSION_API_JSON>());
}
- static v8::Handle<v8::Value> GetViews(const v8::Arguments& args) {
- std::string extension_id = ExtensionIdForCurrentContext();
+ static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) {
+ if (args.Length() != 2)
+ return v8::Undefined();
+
+ if (!args[0]->IsInt32() || !args[1]->IsString())
+ return v8::Undefined();
- ContextList contexts =
- bindings_utils::GetContextsForExtension(extension_id);
- DCHECK(contexts.size() > 0);
+ // |browser_window_id| == -1 means getting views attached to any browser
+ // window.
+ int browser_window_id = args[0]->Int32Value();
+
+ std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString());
+ // |view_type| == ViewType::INVALID means getting any type of views.
+ ViewType::Type view_type = ViewType::INVALID;
+ if (view_type_string == "TOOLSTRIP") {
+ view_type = ViewType::EXTENSION_TOOLSTRIP;
+ } else if (view_type_string == "BACKGROUND") {
+ view_type = ViewType::EXTENSION_BACKGROUND_PAGE;
+ } else if (view_type_string == "TAB") {
+ view_type = ViewType::TAB_CONTENTS;
+ } else if (view_type_string != "ALL") {
+ return v8::Undefined();
+ }
- v8::Local<v8::Array> views = v8::Array::New(contexts.size());
+ v8::Local<v8::Array> views = v8::Array::New();
int index = 0;
- ContextList::const_iterator it = contexts.begin();
- for (; it != contexts.end(); ++it) {
- v8::Local<v8::Value> window = (*it)->context->Global()->Get(
- v8::String::New("window"));
- DCHECK(!window.IsEmpty());
- views->Set(v8::Integer::New(index), window);
- index++;
+ RenderView::RenderViewSet* render_view_set_pointer =
+ Singleton<RenderView::RenderViewSet>::get();
+ DCHECK(render_view_set_pointer->render_view_set_.size() > 0);
+
+ v8::Local<v8::Value> window;
+ std::string current_extension_id = ExtensionIdForCurrentContext();
+ std::set<RenderView* >::iterator it =
+ render_view_set_pointer->render_view_set_.begin();
+ for (; it != render_view_set_pointer->render_view_set_.end(); ++it) {
+ if (view_type != ViewType::INVALID && (*it)->view_type() != view_type)
+ continue;
+
+ GURL url = (*it)->webview()->GetMainFrame()->url();
+ if (!url.SchemeIs(chrome::kExtensionScheme))
+ continue;
+ std::string extension_id = url.host();
+ if (extension_id != current_extension_id)
+ continue;
+
+ if (browser_window_id != -1 &&
+ (*it)->browser_window_id() != browser_window_id) {
+ continue;
+ }
+
+ v8::Local<v8::Context> context =
+ (*it)->webview()->GetMainFrame()->mainWorldScriptContext();
+ if (!context.IsEmpty()) {
+ v8::Local<v8::Value> window = context->Global();
+ DCHECK(!window.IsEmpty());
+ views->Set(v8::Integer::New(index), window);
+ index++;
+ if (view_type == ViewType::EXTENSION_BACKGROUND_PAGE)
+ break;
+ }
}
return views;
}
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 1ddf4cc..9fd1f1d 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -19,6 +19,7 @@
#include "base/gfx/png_encoder.h"
#include "base/gfx/native_widget_types.h"
#include "base/process_util.h"
+#include "base/singleton.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "build/build_config.h"
@@ -201,10 +202,14 @@ RenderView::RenderView(RenderThreadBase* render_thread)
preferred_width_(0),
send_preferred_width_changes_(false),
determine_page_text_after_loading_stops_(false),
+ view_type_(ViewType::INVALID),
+ browser_window_id_(-1),
last_top_level_navigation_page_id_(-1) {
+ Singleton<RenderViewSet>()->render_view_set_.insert(this);
}
RenderView::~RenderView() {
+ Singleton<RenderViewSet>()->render_view_set_.erase(this);
if (decrement_shared_popup_at_destruction_)
shared_popup_counter_->data--;
@@ -427,6 +432,10 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
OnEnableIntrinsicWidthChangedMode)
IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
+ IPC_MESSAGE_HANDLER(ViewMsg_UpdateBrowserWindowId,
+ OnUpdateBrowserWindowId)
+ IPC_MESSAGE_HANDLER(ViewMsg_NotifyRenderViewType,
+ OnNotifyRendererViewType)
IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
@@ -2777,6 +2786,14 @@ void RenderView::OnMediaPlayerActionAt(int x,
webview()->MediaPlayerActionAt(x, y, action);
}
+void RenderView::OnNotifyRendererViewType(ViewType::Type type) {
+ view_type_ = type;
+}
+
+void RenderView::OnUpdateBrowserWindowId(int window_id) {
+ browser_window_id_ = window_id;
+}
+
void RenderView::OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count) {
history_back_list_count_ = back_list_count;
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index ef29a81..d7781e2 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -19,6 +19,7 @@
#include "build/build_config.h"
#include "chrome/common/id_map.h"
#include "chrome/common/renderer_preferences.h"
+#include "chrome/common/view_types.h"
#include "chrome/renderer/automation/dom_automation_controller.h"
#include "chrome/renderer/dom_ui_bindings.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
@@ -98,6 +99,9 @@ class RenderView : public RenderWidget,
public WebViewDelegate,
public webkit_glue::DomSerializerDelegate {
public:
+ struct RenderViewSet {
+ std::set<RenderView* > render_view_set_;
+ };
// Creates a new RenderView. The parent_hwnd specifies a HWND to use as the
// parent of the WebView HWND that will be created. The modal_dialog_event
// is set by the RenderView whenever a modal dialog alert is shown, so that
@@ -132,6 +136,14 @@ class RenderView : public RenderWidget,
return modal_dialog_event_.get();
}
+ int browser_window_id() {
+ return browser_window_id_;
+ }
+
+ ViewType::Type view_type() {
+ return view_type_;
+ }
+
// IPC::Channel::Listener
virtual void OnMessageReceived(const IPC::Message& msg);
@@ -543,6 +555,8 @@ class RenderView : public RenderWidget,
void OnMediaPlayerActionAt(int x,
int y,
const MediaPlayerAction& action);
+ void OnNotifyRendererViewType(ViewType::Type view_type);
+ void OnUpdateBrowserWindowId(int window_id);
void OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count);
void OnGetAccessibilityInfo(
@@ -837,6 +851,13 @@ class RenderView : public RenderWidget,
RendererPreferences renderer_preferences_;
+ // Type of view attached with RenderView, it could be INVALID, TAB_CONTENTS,
+ // EXTENSION_TOOLSTRIP, EXTENSION_BACKGROUND_PAGE, DEV_TOOLS_UI.
+ ViewType::Type view_type_;
+
+ // Id number of browser window which RenderView is attached to.
+ int browser_window_id_;
+
// page id for the last navigation sent to the browser.
int32 last_top_level_navigation_page_id_;
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index e5c7fcf..eb128c7 100644
--- 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. rw2 -->
+without changes to the corresponding grd file. aa1 -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/renderer_resources.h" type="rc_header">
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index e828bd5..f132e55 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -15,7 +15,7 @@ var chrome = chrome || {};
native function GetExtensionAPIDefinition();
native function StartRequest();
native function GetCurrentPageActions(extensionId);
- native function GetViews();
+ native function GetExtensionViews();
native function GetChromeHidden();
native function GetNextRequestId();
native function OpenChannelToTab();
@@ -122,19 +122,6 @@ var chrome = chrome || {};
return StartRequest(functionName, sargs, requestId, hasCallback);
}
- // Read api definitions and setup api functions in the chrome namespace.
- // TODO(rafaelw): Consider defining a json schema for an api definition
- // and validating either here, in a unit_test or both.
- // TODO(rafaelw): Handle synchronous functions.
- // TOOD(rafaelw): Consider providing some convenient override points
- // for api functions that wish to insert themselves into the call.
- var apiDefinitions = JSON.parse(GetExtensionAPIDefinition());
-
- // |apiFunctions| is a hash of name -> object that stores the
- // name & definition of the apiFunction. Custom handling of api functions
- // is implemented by adding a "handleRequest" function to the object.
- var apiFunctions = {};
-
// Using forEach for convenience, and to bind |module|s & |apiDefs|s via
// closures.
function forEach(a, f) {
@@ -149,49 +136,6 @@ var chrome = chrome || {};
};
}
- forEach(apiDefinitions, function(apiDef) {
- chrome[apiDef.namespace] = chrome[apiDef.namespace] || {};
- var module = chrome[apiDef.namespace];
-
- // Setup Functions.
- if (apiDef.functions) {
- forEach(apiDef.functions, function(functionDef) {
- // Module functions may have been defined earlier by hand. Don't clobber
- // them.
- if (module[functionDef.name])
- return;
-
- var apiFunction = {};
- apiFunction.definition = functionDef;
- apiFunction.name = apiDef.namespace + "." + functionDef.name;;
- apiFunctions[apiFunction.name] = apiFunction;
-
- module[functionDef.name] = bind(apiFunction, function() {
- validate(arguments, this.definition.parameters);
-
- if (this.handleRequest)
- return this.handleRequest.apply(this, arguments);
- else
- return sendRequest(this.name, arguments,
- this.definition.parameters);
- });
- });
- }
-
- // Setup Events
- if (apiDef.events) {
- forEach(apiDef.events, function(eventDef) {
- // Module events may have been defined earlier by hand. Don't clobber
- // them.
- if (module[eventDef.name])
- return;
-
- var eventName = apiDef.namespace + "." + eventDef.name;
- module[eventDef.name] = new chrome.Event(eventName);
- });
- }
- });
-
// --- Setup additional api's not currently handled in common/extensions/api
// Page action events send (pageActionId, {tabId, tabUrl}).
@@ -205,26 +149,97 @@ var chrome = chrome || {};
}
}
- // Tabs connect()
- apiFunctions["tabs.connect"].handleRequest = function(tabId, opt_name) {
- var portId = OpenChannelToTab(tabId, chrome.extension.id_, opt_name || "");
- return chromeHidden.Port.createPort(portId, opt_name);
- }
-
- // chrome.self / chrome.extension.
- chrome.self = chrome.self || {};
-
chromeHidden.onLoad.addListener(function (extensionId) {
chrome.extension = new chrome.Extension(extensionId);
- // TODO(mpcomplete): self.onConnect is deprecated. Remove it at 1.0.
+
+ // TODO(mpcomplete): chrome.self is deprecated. Remove it at 1.0.
// http://code.google.com/p/chromium/issues/detail?id=16356
- chrome.self.onConnect = chrome.extension.onConnect;
+ chrome.self = chrome.extension;
+
+ // |apiFunctions| is a hash of name -> object that stores the
+ // name & definition of the apiFunction. Custom handling of api functions
+ // is implemented by adding a "handleRequest" function to the object.
+ var apiFunctions = {};
+
+ // Read api definitions and setup api functions in the chrome namespace.
+ // TODO(rafaelw): Consider defining a json schema for an api definition
+ // and validating either here, in a unit_test or both.
+ // TODO(rafaelw): Handle synchronous functions.
+ // TOOD(rafaelw): Consider providing some convenient override points
+ // for api functions that wish to insert themselves into the call.
+ var apiDefinitions = JSON.parse(GetExtensionAPIDefinition());
+
+ forEach(apiDefinitions, function(apiDef) {
+ chrome[apiDef.namespace] = chrome[apiDef.namespace] || {};
+ var module = chrome[apiDef.namespace];
+
+ // Setup Functions.
+ if (apiDef.functions) {
+ forEach(apiDef.functions, function(functionDef) {
+ // Module functions may have been defined earlier by hand. Don't
+ // clobber them.
+ if (module[functionDef.name])
+ return;
+
+ var apiFunction = {};
+ apiFunction.definition = functionDef;
+ apiFunction.name = apiDef.namespace + "." + functionDef.name;;
+ apiFunctions[apiFunction.name] = apiFunction;
+
+ module[functionDef.name] = bind(apiFunction, function() {
+ validate(arguments, this.definition.parameters);
+
+ if (this.handleRequest)
+ return this.handleRequest.apply(this, arguments);
+ else
+ return sendRequest(this.name, arguments,
+ this.definition.parameters);
+ });
+ });
+ }
+
+ // Setup Events
+ if (apiDef.events) {
+ forEach(apiDef.events, function(eventDef) {
+ // Module events may have been defined earlier by hand. Don't clobber
+ // them.
+ if (module[eventDef.name])
+ return;
+
+ var eventName = apiDef.namespace + "." + eventDef.name;
+ module[eventDef.name] = new chrome.Event(eventName);
+ });
+ }
+ });
+
+ apiFunctions["tabs.connect"].handleRequest = function(tabId, opt_name) {
+ var portId = OpenChannelToTab(
+ tabId, chrome.extension.id_, opt_name || "");
+ return chromeHidden.Port.createPort(portId, opt_name);
+ }
+
+ apiFunctions["extension.getViews"].handleRequest = function() {
+ return GetExtensionViews(-1, "ALL");
+ }
+
+ apiFunctions["extension.getBackgroundPage"].handleRequest = function() {
+ return GetExtensionViews(-1, "BACKGROUND")[0] || null;
+ }
+
+ apiFunctions["extension.getToolstrips"].handleRequest =
+ function(windowId) {
+ if (typeof(windowId) == "undefined")
+ windowId = -1;
+ return GetExtensionViews(windowId, "TOOLSTRIP");
+ }
+
+ apiFunctions["extension.getTabContentses"].handleRequest =
+ function(windowId) {
+ if (typeof(windowId) == "undefined")
+ windowId = -1;
+ return GetExtensionViews(windowId, "TAB");
+ }
setupPageActionEvents(extensionId);
});
-
- // Self getViews();
- apiFunctions["self.getViews"].handleRequest = function() {
- return GetViews();
- }
-})();
+ })();