Chromium Code Reviews| Index: chrome/renderer/extensions/event_bindings.cc |
| diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc |
| index 498a9d10da909f33683c3101464b961335807083..51c64ac93e5a632455d8b6dfb9e7eda992de6899 100644 |
| --- a/chrome/renderer/extensions/event_bindings.cc |
| +++ b/chrome/renderer/extensions/event_bindings.cc |
| @@ -189,21 +189,15 @@ class ExtensionImpl : public ExtensionBase { |
| // Returns true if the extension running in the given |context| has sufficient |
| // permissions to access the data. |
| -static bool HasSufficientPermissions(ContextInfo* context, |
| +static bool HasSufficientPermissions(RenderView* render_view, |
| const GURL& event_url) { |
| - v8::Context::Scope context_scope(context->context); |
| - |
| // During unit tests, we might be invoked without a v8 context. In these |
| // cases, we only allow empty event_urls and short-circuit before retrieving |
| // the render view from the current context. |
| if (!event_url.is_valid()) |
| return true; |
| - RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); |
| - if (!renderview) |
| - return false; |
| - |
| - WebDocument document = renderview->webview()->mainFrame()->document(); |
| + WebDocument document = render_view->webview()->mainFrame()->document(); |
| return GURL(document.url()).SchemeIs(chrome::kExtensionScheme) && |
| document.securityOrigin().canRequest(event_url); |
| } |
| @@ -298,6 +292,7 @@ void EventBindings::HandleContextCreated( |
| ContextList& contexts = GetContexts(); |
| v8::Persistent<v8::Context> persistent_context; |
| + v8::Persistent<v8::Context> main_world_context; |
| std::string extension_id; |
| if (content_script) { |
| @@ -305,6 +300,11 @@ void EventBindings::HandleContextCreated( |
| // set up a GC callback. |
| persistent_context = v8::Persistent<v8::Context>::New(context); |
| persistent_context.MakeWeak(NULL, &ContextWeakReferenceCallback); |
| + |
| + main_world_context = v8::Persistent<v8::Context>::New( |
| + frame->mainWorldScriptContext()); |
| + main_world_context.MakeWeak(NULL, NULL); |
| + |
| extension_id = |
| extension_dispatcher->user_script_slave()-> |
| GetExtensionIdForIsolatedWorld(isolated_world_id); |
| @@ -336,7 +336,7 @@ void EventBindings::HandleContextCreated( |
| } |
| contexts.push_back(linked_ptr<ContextInfo>( |
| - new ContextInfo(persistent_context, extension_id, frame))); |
| + new ContextInfo(persistent_context, main_world_context, extension_id))); |
| // Content scripts get initialized in user_script_slave.cc. |
| if (!content_script) { |
| @@ -354,17 +354,22 @@ void EventBindings::HandleContextDestroyed(WebFrame* frame) { |
| v8::HandleScope handle_scope; |
| v8::Local<v8::Context> context = frame->mainWorldScriptContext(); |
| - if (!context.IsEmpty()) { |
| - ContextList::iterator context_iter = bindings_utils::FindContext(context); |
| - if (context_iter != GetContexts().end()) |
| - UnregisterContext(context_iter, false); |
| + |
| + if (context.IsEmpty()) { |
| + NOTREACHED(); |
|
Aaron Boodman
2011/08/24 02:58:16
According to the code upstream, this should not ha
|
| + return; |
| } |
| - // Unload any content script contexts for this frame. Note that the frame |
| - // itself might not be registered, but can still be a parent frame. |
| + ContextList::iterator context_iter = bindings_utils::FindContext(context); |
| + if (context_iter != GetContexts().end()) |
| + UnregisterContext(context_iter, false); |
| + |
| + // Unload any associated content script contexts. Note that the main world |
| + // context itself might not be registered, but can still be associated with a |
| + // content script that is. |
| for (ContextList::iterator it = GetContexts().begin(); |
| it != GetContexts().end(); ) { |
| - if ((*it)->frame == frame) { |
| + if ((*it)->main_world_context == context) { |
| UnregisterContext(it, false); |
| // UnregisterContext will remove |it| from the list, but may also |
| // modify the rest of the list as a result of calling into javascript. |
| @@ -391,20 +396,25 @@ void EventBindings::CallFunction(const std::string& extension_id, |
| V8ValueConverter converter; |
| for (ContextList::iterator it = contexts.begin(); |
| it != contexts.end(); ++it) { |
| - if (render_view) { |
| - RenderView* context_render_view = |
| - RenderView::FromWebView((*it)->frame->view()); |
| - if (render_view != context_render_view) |
| - continue; |
| - } |
| + if ((*it)->context.IsEmpty()) |
| + continue; |
| if (!extension_id.empty() && extension_id != (*it)->extension_id) |
| continue; |
| - if ((*it)->context.IsEmpty()) |
| + WebFrame* context_frame = WebFrame::frameForContext((*it)->context); |
|
Aaron Boodman
2011/08/24 02:58:16
It will return NULL if the context is detached fro
|
| + if (!context_frame || !context_frame->view()) |
| + continue; |
| + |
| + RenderView* context_render_view = |
| + RenderView::FromWebView(context_frame->view()); |
| + if (!context_render_view) |
| + continue; |
| + |
| + if (render_view && render_view != context_render_view) |
| continue; |
| - if (!HasSufficientPermissions(it->get(), event_url)) |
| + if (!HasSufficientPermissions(render_view, event_url)) |
| continue; |
| v8::Local<v8::Context> context(*((*it)->context)); |