OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "extensions/renderer/extension_frame_helper.h" | 5 #include "extensions/renderer/extension_frame_helper.h" |
6 | 6 |
7 #include "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" |
8 #include "content/public/renderer/render_frame.h" | 8 #include "content/public/renderer/render_frame.h" |
9 #include "extensions/common/api/messaging/message.h" | 9 #include "extensions/common/api/messaging/message.h" |
10 #include "extensions/common/constants.h" | 10 #include "extensions/common/constants.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 !base::EqualsASCII(base::StringPiece16(origin.host()), | 51 !base::EqualsASCII(base::StringPiece16(origin.host()), |
52 match_extension_id.c_str())) | 52 match_extension_id.c_str())) |
53 return false; | 53 return false; |
54 | 54 |
55 if (match_window_id != extension_misc::kUnknownWindowId && | 55 if (match_window_id != extension_misc::kUnknownWindowId && |
56 frame_helper->browser_window_id() != match_window_id) | 56 frame_helper->browser_window_id() != match_window_id) |
57 return false; | 57 return false; |
58 return true; | 58 return true; |
59 } | 59 } |
60 | 60 |
61 // Runs every callback in |callbacks_to_be_run_and_cleared| while |frame_helper| | |
62 // is valid, and clears |callbacks_to_be_run_and_cleared|. | |
63 void RunCallbacksWhileFrameIsValid( | |
64 base::WeakPtr<ExtensionFrameHelper> frame_helper, | |
65 std::vector<base::Closure>* callbacks_to_be_run_and_cleared) { | |
66 // The JavaScript code can cause re-entrancy. To avoid a deadlock, don't run | |
67 // callbacks that are added during the iteration. | |
68 std::vector<base::Closure> callbacks; | |
69 callbacks_to_be_run_and_cleared->swap(callbacks); | |
70 for (auto& callback : callbacks) { | |
71 callback.Run(); | |
72 if (!frame_helper.get()) | |
73 return; // Frame and ExtensionFrameHelper invalidated by callback. | |
74 } | |
75 } | |
76 | |
61 } // namespace | 77 } // namespace |
62 | 78 |
63 ExtensionFrameHelper::ExtensionFrameHelper(content::RenderFrame* render_frame, | 79 ExtensionFrameHelper::ExtensionFrameHelper(content::RenderFrame* render_frame, |
64 Dispatcher* extension_dispatcher) | 80 Dispatcher* extension_dispatcher) |
65 : content::RenderFrameObserver(render_frame), | 81 : content::RenderFrameObserver(render_frame), |
66 content::RenderFrameObserverTracker<ExtensionFrameHelper>(render_frame), | 82 content::RenderFrameObserverTracker<ExtensionFrameHelper>(render_frame), |
67 view_type_(VIEW_TYPE_INVALID), | 83 view_type_(VIEW_TYPE_INVALID), |
68 tab_id_(-1), | 84 tab_id_(-1), |
69 browser_window_id_(-1), | 85 browser_window_id_(-1), |
70 extension_dispatcher_(extension_dispatcher), | 86 extension_dispatcher_(extension_dispatcher), |
71 did_create_current_document_element_(false) { | 87 did_create_current_document_element_(false), |
88 weak_ptr_factory_(this) { | |
72 g_frame_helpers.Get().insert(this); | 89 g_frame_helpers.Get().insert(this); |
73 } | 90 } |
74 | 91 |
75 ExtensionFrameHelper::~ExtensionFrameHelper() { | 92 ExtensionFrameHelper::~ExtensionFrameHelper() { |
76 g_frame_helpers.Get().erase(this); | 93 g_frame_helpers.Get().erase(this); |
77 } | 94 } |
78 | 95 |
79 // static | 96 // static |
80 std::vector<content::RenderFrame*> ExtensionFrameHelper::GetExtensionFrames( | 97 std::vector<content::RenderFrame*> ExtensionFrameHelper::GetExtensionFrames( |
81 const std::string& extension_id, | 98 const std::string& extension_id, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 void ExtensionFrameHelper::DidCreateDocumentElement() { | 133 void ExtensionFrameHelper::DidCreateDocumentElement() { |
117 did_create_current_document_element_ = true; | 134 did_create_current_document_element_ = true; |
118 extension_dispatcher_->DidCreateDocumentElement( | 135 extension_dispatcher_->DidCreateDocumentElement( |
119 render_frame()->GetWebFrame()); | 136 render_frame()->GetWebFrame()); |
120 } | 137 } |
121 | 138 |
122 void ExtensionFrameHelper::DidCreateNewDocument() { | 139 void ExtensionFrameHelper::DidCreateNewDocument() { |
123 did_create_current_document_element_ = false; | 140 did_create_current_document_element_ = false; |
124 } | 141 } |
125 | 142 |
143 void ExtensionFrameHelper::AfterDidCreateDocumentElement() { | |
144 DCHECK(did_create_current_document_element_); | |
145 RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(), | |
146 &document_element_created_callbacks_); | |
147 // |this| might be dead by now. | |
148 } | |
149 | |
150 void ExtensionFrameHelper::AfterDidFinishDocumentLoad() { | |
151 RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(), | |
152 &document_load_finished_callbacks_); | |
153 // |this| might be dead by now. | |
154 } | |
155 | |
156 void ExtensionFrameHelper::ScheduleAfterDidCreateDocumentElement( | |
157 const base::Closure& callback) { | |
158 document_element_created_callbacks_.push_back(callback); | |
Devlin
2016/02/16 18:37:37
Can we add a pair of bools (did finish doc load, d
robwu
2016/02/22 00:15:02
No. The re-entrancy via JavaScript and Blink makes
dcheng
2016/02/22 00:28:34
FWIW this already exists in the form of WebFrameCl
dcheng
2016/02/22 00:28:34
FWIW this already exists in the form of WebFrameCl
robwu
2016/02/22 00:52:31
Is that also called upon navigation? I thought tha
| |
159 } | |
160 | |
161 void ExtensionFrameHelper::ScheduleAfterDidFinishDocumentLoad( | |
162 const base::Closure& callback) { | |
163 document_load_finished_callbacks_.push_back(callback); | |
164 } | |
165 | |
126 void ExtensionFrameHelper::DidMatchCSS( | 166 void ExtensionFrameHelper::DidMatchCSS( |
127 const blink::WebVector<blink::WebString>& newly_matching_selectors, | 167 const blink::WebVector<blink::WebString>& newly_matching_selectors, |
128 const blink::WebVector<blink::WebString>& stopped_matching_selectors) { | 168 const blink::WebVector<blink::WebString>& stopped_matching_selectors) { |
129 extension_dispatcher_->content_watcher()->DidMatchCSS( | 169 extension_dispatcher_->content_watcher()->DidMatchCSS( |
130 render_frame()->GetWebFrame(), newly_matching_selectors, | 170 render_frame()->GetWebFrame(), newly_matching_selectors, |
131 stopped_matching_selectors); | 171 stopped_matching_selectors); |
132 } | 172 } |
133 | 173 |
134 void ExtensionFrameHelper::DidCreateScriptContext( | 174 void ExtensionFrameHelper::DidCreateScriptContext( |
135 v8::Local<v8::Context> context, | 175 v8::Local<v8::Context> context, |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 const std::string& module_name, | 268 const std::string& module_name, |
229 const std::string& function_name, | 269 const std::string& function_name, |
230 const base::ListValue& args, | 270 const base::ListValue& args, |
231 bool user_gesture) { | 271 bool user_gesture) { |
232 extension_dispatcher_->InvokeModuleSystemMethod(render_frame(), extension_id, | 272 extension_dispatcher_->InvokeModuleSystemMethod(render_frame(), extension_id, |
233 module_name, function_name, | 273 module_name, function_name, |
234 args, user_gesture); | 274 args, user_gesture); |
235 } | 275 } |
236 | 276 |
237 } // namespace extensions | 277 } // namespace extensions |
OLD | NEW |