| Index: chrome/renderer/extensions/extension_process_bindings.cc
|
| diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
|
| index dccc32aa26d79cea397c023e202c9ac2027e9a22..96f02568967bc871a389c6bede80c3d85a29054f 100644
|
| --- a/chrome/renderer/extensions/extension_process_bindings.cc
|
| +++ b/chrome/renderer/extensions/extension_process_bindings.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "base/singleton.h"
|
| #include "chrome/common/render_messages.h"
|
| +#include "chrome/common/url_constants.h"
|
| #include "chrome/renderer/extensions/bindings_utils.h"
|
| #include "chrome/renderer/extensions/event_bindings.h"
|
| #include "chrome/renderer/extensions/renderer_extension_bindings.h"
|
| @@ -29,6 +30,14 @@ const char* kExtensionDeps[] = {
|
| RendererExtensionBindings::kName,
|
| };
|
|
|
| +// Types for storage of per-renderer-singleton data structure that maps
|
| +// |extension_id| -> <List of v8 Contexts for the "views" of that extension>
|
| +typedef std::list< v8::Persistent<v8::Context> > ContextList;
|
| +typedef std::map<std::string, ContextList> ExtensionIdContextsMap;
|
| +struct ExtensionViewContexts {
|
| + ExtensionIdContextsMap contexts;
|
| +};
|
| +
|
| class ExtensionImpl : public v8::Extension {
|
| public:
|
| ExtensionImpl() : v8::Extension(
|
| @@ -48,6 +57,12 @@ class ExtensionImpl : public v8::Extension {
|
|
|
| if (name->Equals(v8::String::New("GetNextRequestId")))
|
| return v8::FunctionTemplate::New(GetNextRequestId);
|
| + else if (name->Equals(v8::String::New("RegisterExtension")))
|
| + return v8::FunctionTemplate::New(RegisterExtension);
|
| + else if (name->Equals(v8::String::New("UnregisterExtension")))
|
| + return v8::FunctionTemplate::New(UnregisterExtension);
|
| + else if (name->Equals(v8::String::New("GetViews")))
|
| + return v8::FunctionTemplate::New(GetViews);
|
| else if (names->find(*v8::String::AsciiValue(name)) != names->end())
|
| return v8::FunctionTemplate::New(StartRequest, name);
|
|
|
| @@ -63,6 +78,70 @@ class ExtensionImpl : public v8::Extension {
|
| return &Singleton<SingletonData>()->function_names_;
|
| }
|
|
|
| + static ContextList& GetRegisteredContexts(std::string extension_id) {
|
| + return Singleton<ExtensionViewContexts>::get()->contexts[extension_id];
|
| + }
|
| +
|
| + static v8::Handle<v8::Value> RegisterExtension(const v8::Arguments& args) {
|
| + RenderView* renderview = GetRenderViewForCurrentContext();
|
| + DCHECK(renderview);
|
| + GURL url = renderview->webview()->GetMainFrame()->GetURL();
|
| + DCHECK(url.scheme() == chrome::kExtensionScheme);
|
| +
|
| + v8::Persistent<v8::Context> current_context =
|
| + v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
|
| + DCHECK(!current_context.IsEmpty());
|
| +
|
| + std::string extension_id = url.host();
|
| + GetRegisteredContexts(extension_id).push_back(current_context);
|
| + return v8::String::New(extension_id.c_str());
|
| + }
|
| +
|
| + static v8::Handle<v8::Value> UnregisterExtension(const v8::Arguments& args) {
|
| + DCHECK_EQ(args.Length(), 1);
|
| + DCHECK(args[0]->IsString());
|
| +
|
| + std::string extension_id(*v8::String::Utf8Value(args[0]));
|
| + ContextList& contexts = GetRegisteredContexts(extension_id);
|
| + v8::Local<v8::Context> current_context = v8::Context::GetCurrent();
|
| + DCHECK(!current_context.IsEmpty());
|
| +
|
| + ContextList::iterator it = std::find(contexts.begin(), contexts.end(),
|
| + current_context);
|
| + if (it == contexts.end()) {
|
| + NOTREACHED();
|
| + return v8::Undefined();
|
| + }
|
| +
|
| + it->Dispose();
|
| + it->Clear();
|
| + contexts.erase(it);
|
| +
|
| + return v8::Undefined();
|
| + }
|
| +
|
| + static v8::Handle<v8::Value> GetViews(const v8::Arguments& args) {
|
| + RenderView* renderview = GetRenderViewForCurrentContext();
|
| + DCHECK(renderview);
|
| + GURL url = renderview->webview()->GetMainFrame()->GetURL();
|
| + std::string extension_id = url.host();
|
| +
|
| + ContextList& contexts = GetRegisteredContexts(extension_id);
|
| + DCHECK(contexts.size() > 0);
|
| +
|
| + v8::Local<v8::Array> views = v8::Array::New(contexts.size());
|
| + int index = 0;
|
| + ContextList::const_iterator it = contexts.begin();
|
| + for (; it != contexts.end(); ++it) {
|
| + v8::Local<v8::Value> window = (*it)->Global()->Get(
|
| + v8::String::New("window"));
|
| + DCHECK(!window.IsEmpty());
|
| + views->Set(v8::Integer::New(index), window);
|
| + index++;
|
| + }
|
| + return views;
|
| + }
|
| +
|
| static v8::Handle<v8::Value> GetNextRequestId(const v8::Arguments& args) {
|
| static int next_request_id = 0;
|
| return v8::Integer::New(next_request_id++);
|
| @@ -103,6 +182,11 @@ void ExtensionProcessBindings::SetFunctionNames(
|
| ExtensionImpl::SetFunctionNames(names);
|
| }
|
|
|
| +void ExtensionProcessBindings::RegisterExtensionContext(WebFrame* frame) {
|
| + frame->ExecuteScript(WebScriptSource(WebString::fromUTF8(
|
| + "chrome.self.register_();")));
|
| +}
|
| +
|
| void ExtensionProcessBindings::ExecuteResponseInFrame(
|
| CallContext *call, int request_id, bool success,
|
| const std::string& response,
|
|
|