| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/renderer/extensions/event_bindings.h" | 5 #include "chrome/renderer/extensions/event_bindings.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
| 9 #include "chrome/common/render_messages.h" | 9 #include "chrome/common/render_messages.h" |
| 10 #include "chrome/common/url_constants.h" | 10 #include "chrome/common/url_constants.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 // static | 111 // static |
| 112 void EventBindings::SetRenderThread(RenderThreadBase* thread) { | 112 void EventBindings::SetRenderThread(RenderThreadBase* thread) { |
| 113 render_thread = thread; | 113 render_thread = thread; |
| 114 } | 114 } |
| 115 | 115 |
| 116 // static | 116 // static |
| 117 RenderThreadBase* EventBindings::GetRenderThread() { | 117 RenderThreadBase* EventBindings::GetRenderThread() { |
| 118 return render_thread ? render_thread : RenderThread::current(); | 118 return render_thread ? render_thread : RenderThread::current(); |
| 119 } | 119 } |
| 120 | 120 |
| 121 static void HandleContextDestroyed(ContextList::iterator context_iter) { |
| 122 // Notify the bindings that they're going away. |
| 123 CallFunctionInContext((*context_iter)->context, "dispatchOnUnload", 0, NULL); |
| 124 |
| 125 // Remove all pending requests for this context. |
| 126 PendingRequestMap& pending_requests = GetPendingRequestMap(); |
| 127 for (PendingRequestMap::iterator it = pending_requests.begin(); |
| 128 it != pending_requests.end(); ) { |
| 129 PendingRequestMap::iterator current = it++; |
| 130 if (current->second->context == (*context_iter)->context) { |
| 131 current->second->context.Dispose(); |
| 132 current->second->context.Clear(); |
| 133 pending_requests.erase(current); |
| 134 } |
| 135 } |
| 136 |
| 137 // Unload any content script contexts for this frame. |
| 138 for (ContextList::iterator it = GetContexts().begin(); |
| 139 it != GetContexts().end(); ) { |
| 140 ContextList::iterator current = it++; |
| 141 if ((*current)->parent_context == (*context_iter)->context) |
| 142 HandleContextDestroyed(current); |
| 143 } |
| 144 |
| 145 // Remove it from our registered contexts. |
| 146 (*context_iter)->context.ClearWeak(); |
| 147 (*context_iter)->context.Dispose(); |
| 148 (*context_iter)->context.Clear(); |
| 149 GetContexts().erase(context_iter); |
| 150 } |
| 151 |
| 152 static void ContextWeakReferenceCallback(v8::Persistent<v8::Value> context, |
| 153 void*) |
| 154 { |
| 155 for (ContextList::iterator it = GetContexts().begin(); |
| 156 it != GetContexts().end(); ++it) { |
| 157 if ((*it)->context == context) { |
| 158 HandleContextDestroyed(it); |
| 159 return; |
| 160 } |
| 161 } |
| 162 |
| 163 NOTREACHED(); |
| 164 } |
| 165 |
| 121 void EventBindings::HandleContextCreated(WebFrame* frame) { | 166 void EventBindings::HandleContextCreated(WebFrame* frame) { |
| 122 if (!bindings_registered) | 167 if (!bindings_registered) |
| 123 return; | 168 return; |
| 124 | 169 |
| 125 v8::HandleScope handle_scope; | 170 v8::HandleScope handle_scope; |
| 126 v8::Local<v8::Context> context = frame->GetScriptContext(); | 171 ContextList& contexts = GetContexts(); |
| 172 v8::Local<v8::Context> frame_context = frame->GetScriptContext(); |
| 173 v8::Local<v8::Context> context = v8::Context::GetCurrent(); |
| 127 DCHECK(!context.IsEmpty()); | 174 DCHECK(!context.IsEmpty()); |
| 128 DCHECK(bindings_utils::FindContext(context) == GetContexts().end()); | 175 DCHECK(bindings_utils::FindContext(context) == contexts.end()); |
| 129 | 176 |
| 130 GURL url = frame->GetView()->GetMainFrame()->GetURL(); | 177 GURL url = frame->GetView()->GetMainFrame()->GetURL(); |
| 131 std::string extension_id; | 178 std::string extension_id; |
| 132 if (url.SchemeIs(chrome::kExtensionScheme)) | 179 if (url.SchemeIs(chrome::kExtensionScheme)) |
| 133 extension_id = url.host(); | 180 extension_id = url.host(); |
| 134 | 181 |
| 135 v8::Persistent<v8::Context> persistent_context = | 182 v8::Persistent<v8::Context> persistent_context = |
| 136 v8::Persistent<v8::Context>::New(context); | 183 v8::Persistent<v8::Context>::New(context); |
| 137 GetContexts().push_back(linked_ptr<ContextInfo>( | 184 v8::Persistent<v8::Context> parent_context; |
| 138 new ContextInfo(persistent_context, extension_id))); | 185 |
| 186 if (frame_context != context) { |
| 187 // The new context doesn't belong to the frame: it's a content script. |
| 188 DCHECK(bindings_utils::FindContext(frame_context) != contexts.end()); |
| 189 parent_context = v8::Persistent<v8::Context>::New(frame_context); |
| 190 // Content script contexts can get GCed before their frame goes away, so |
| 191 // set up a GC callback. |
| 192 persistent_context.MakeWeak(NULL, &ContextWeakReferenceCallback); |
| 193 } |
| 194 |
| 195 contexts.push_back(linked_ptr<ContextInfo>( |
| 196 new ContextInfo(persistent_context, extension_id, parent_context))); |
| 139 | 197 |
| 140 v8::Handle<v8::Value> argv[1]; | 198 v8::Handle<v8::Value> argv[1]; |
| 141 argv[0] = v8::String::New(extension_id.c_str()); | 199 argv[0] = v8::String::New(extension_id.c_str()); |
| 142 CallFunctionInContext(context, "dispatchOnLoad", arraysize(argv), argv); | 200 CallFunctionInContext(context, "dispatchOnLoad", arraysize(argv), argv); |
| 143 } | 201 } |
| 144 | 202 |
| 145 // static | 203 // static |
| 146 void EventBindings::HandleContextDestroyed(WebFrame* frame) { | 204 void EventBindings::HandleContextDestroyed(WebFrame* frame) { |
| 147 if (!bindings_registered) | 205 if (!bindings_registered) |
| 148 return; | 206 return; |
| 149 | 207 |
| 150 v8::HandleScope handle_scope; | 208 v8::HandleScope handle_scope; |
| 151 v8::Local<v8::Context> context = frame->GetScriptContext(); | 209 v8::Local<v8::Context> context = frame->GetScriptContext(); |
| 152 DCHECK(!context.IsEmpty()); | 210 DCHECK(!context.IsEmpty()); |
| 153 | 211 |
| 154 ContextList::iterator it = bindings_utils::FindContext(context); | 212 ContextList::iterator context_iter = bindings_utils::FindContext(context); |
| 155 DCHECK(it != GetContexts().end()); | 213 DCHECK(context_iter != GetContexts().end()); |
| 156 | 214 ::HandleContextDestroyed(context_iter); |
| 157 // Notify the bindings that they're going away. | |
| 158 CallFunctionInContext(context, "dispatchOnUnload", 0, NULL); | |
| 159 | |
| 160 // Remove all pending requests for this context. | |
| 161 PendingRequestMap& pending_requests = GetPendingRequestMap(); | |
| 162 for (PendingRequestMap::iterator it = pending_requests.begin(); | |
| 163 it != pending_requests.end(); ) { | |
| 164 PendingRequestMap::iterator current = it++; | |
| 165 if (current->second->context == context) { | |
| 166 current->second->context.Dispose(); | |
| 167 current->second->context.Clear(); | |
| 168 pending_requests.erase(current); | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 // Remove it from our registered contexts. | |
| 173 (*it)->context.Dispose(); | |
| 174 (*it)->context.Clear(); | |
| 175 GetContexts().erase(it); | |
| 176 } | 215 } |
| 177 | 216 |
| 178 // static | 217 // static |
| 179 void EventBindings::CallFunction(const std::string& function_name, | 218 void EventBindings::CallFunction(const std::string& function_name, |
| 180 int argc, v8::Handle<v8::Value>* argv) { | 219 int argc, v8::Handle<v8::Value>* argv) { |
| 181 for (ContextList::iterator it = GetContexts().begin(); | 220 for (ContextList::iterator it = GetContexts().begin(); |
| 182 it != GetContexts().end(); ++it) { | 221 it != GetContexts().end(); ++it) { |
| 183 CallFunctionInContext((*it)->context, function_name, argc, argv); | 222 CallFunctionInContext((*it)->context, function_name, argc, argv); |
| 184 } | 223 } |
| 185 } | 224 } |
| OLD | NEW |