OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/user_script_idle_scheduler.h" | 5 #include "chrome/renderer/extensions/user_script_idle_scheduler.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "chrome/common/extensions/extension_error_utils.h" | 9 #include "chrome/common/extensions/extension_error_utils.h" |
10 #include "chrome/common/extensions/extension_messages.h" | 10 #include "chrome/common/extensions/extension_messages.h" |
11 #include "chrome/common/extensions/user_script.h" | |
11 #include "chrome/renderer/extensions/extension_dispatcher.h" | 12 #include "chrome/renderer/extensions/extension_dispatcher.h" |
12 #include "chrome/renderer/extensions/extension_groups.h" | 13 #include "chrome/renderer/extensions/extension_groups.h" |
13 #include "chrome/renderer/extensions/extension_helper.h" | 14 #include "chrome/renderer/extensions/extension_helper.h" |
14 #include "chrome/renderer/extensions/user_script_slave.h" | 15 #include "chrome/renderer/extensions/user_script_slave.h" |
15 #include "content/public/renderer/render_view.h" | 16 #include "content/public/renderer/render_view.h" |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
20 | 21 |
21 namespace { | 22 namespace { |
22 // The length of time to wait after the DOM is complete to try and run user | 23 // The length of time to wait after the DOM is complete to try and run user |
23 // scripts. | 24 // scripts. |
24 const int kUserScriptIdleTimeoutMs = 200; | 25 const int kUserScriptIdleTimeoutMs = 200; |
25 } | 26 } |
26 | 27 |
27 using WebKit::WebDocument; | 28 using WebKit::WebDocument; |
28 using WebKit::WebFrame; | 29 using WebKit::WebFrame; |
29 using WebKit::WebString; | 30 using WebKit::WebString; |
30 using WebKit::WebView; | 31 using WebKit::WebView; |
31 | 32 |
32 UserScriptIdleScheduler::UserScriptIdleScheduler( | 33 UserScriptIdleScheduler::UserScriptIdleScheduler( |
33 WebFrame* frame, ExtensionDispatcher* extension_dispatcher) | 34 WebFrame* frame, ExtensionDispatcher* extension_dispatcher) |
34 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 35 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
35 frame_(frame), | 36 frame_(frame), |
36 has_run_(false), | 37 has_run_(false), |
38 current_location_(-1), | |
37 extension_dispatcher_(extension_dispatcher) { | 39 extension_dispatcher_(extension_dispatcher) { |
40 for (int i = 0; i < UserScript::RUN_LOCATION_LAST; ++i) | |
41 pending_code_execution_queue_.push_back( | |
Aaron Boodman
2012/03/03 00:59:10
You're essentially using this like a map. So why n
eaugusti
2012/03/27 00:43:33
Done.
| |
42 std::queue<linked_ptr<ExtensionMsg_ExecuteCode_Params> >()); | |
38 } | 43 } |
39 | 44 |
40 UserScriptIdleScheduler::~UserScriptIdleScheduler() { | 45 UserScriptIdleScheduler::~UserScriptIdleScheduler() { |
41 } | 46 } |
42 | 47 |
43 void UserScriptIdleScheduler::ExecuteCode( | 48 void UserScriptIdleScheduler::ExecuteCode( |
44 const ExtensionMsg_ExecuteCode_Params& params) { | 49 const ExtensionMsg_ExecuteCode_Params& params) { |
45 if (!has_run_) { | 50 if (!has_run_ && |
46 pending_code_execution_queue_.push( | 51 params.run_at != UserScript::DOCUMENT_NOW && |
Mihai Parparita -not on Chrome
2012/03/01 00:40:08
Is it OK to always immediately execute script when
Aaron Boodman
2012/03/03 00:59:10
Agree with Mihai that we should always wait until
eaugusti
2012/03/27 00:43:33
Done.
eaugusti
2012/03/27 00:43:34
Done.
| |
52 current_location_ < params.run_at) { | |
53 pending_code_execution_queue_[params.run_at].push( | |
47 linked_ptr<ExtensionMsg_ExecuteCode_Params>( | 54 linked_ptr<ExtensionMsg_ExecuteCode_Params>( |
48 new ExtensionMsg_ExecuteCode_Params(params))); | 55 new ExtensionMsg_ExecuteCode_Params(params))); |
49 return; | 56 return; |
50 } | 57 } |
51 | |
52 ExecuteCodeImpl(params); | 58 ExecuteCodeImpl(params); |
53 } | 59 } |
54 | 60 |
61 void UserScriptIdleScheduler::DidCreateDocumentElement() { | |
62 current_location_ = UserScript::DOCUMENT_START; | |
63 MessageLoop::current()->PostTask( | |
Aaron Boodman
2012/03/03 00:59:10
Why PostTask as opposed to running immediately? Th
eaugusti
2012/03/27 00:43:34
Done.
| |
64 FROM_HERE, base::Bind(&UserScriptIdleScheduler::MaybeRun, | |
65 weak_factory_.GetWeakPtr())); | |
66 } | |
67 | |
55 void UserScriptIdleScheduler::DidFinishDocumentLoad() { | 68 void UserScriptIdleScheduler::DidFinishDocumentLoad() { |
69 current_location_ = UserScript::DOCUMENT_END; | |
70 // Schedule a run for DOCUMENT_END | |
71 MessageLoop::current()->PostTask( | |
Aaron Boodman
2012/03/03 00:59:10
Same here. Don't think PostTask is necessary.
eaugusti
2012/03/27 00:43:34
Done.
| |
72 FROM_HERE, base::Bind(&UserScriptIdleScheduler::MaybeRun, | |
73 weak_factory_.GetWeakPtr())); | |
74 // Schedule a run for DOCUMENT_IDLE | |
56 MessageLoop::current()->PostDelayedTask( | 75 MessageLoop::current()->PostDelayedTask( |
57 FROM_HERE, base::Bind(&UserScriptIdleScheduler::MaybeRun, | 76 FROM_HERE, base::Bind(&UserScriptIdleScheduler::IdleTimeout, |
58 weak_factory_.GetWeakPtr()), | 77 weak_factory_.GetWeakPtr()), |
59 base::TimeDelta::FromMilliseconds(kUserScriptIdleTimeoutMs)); | 78 base::TimeDelta::FromMilliseconds(kUserScriptIdleTimeoutMs)); |
60 } | 79 } |
61 | 80 |
62 void UserScriptIdleScheduler::DidFinishLoad() { | 81 void UserScriptIdleScheduler::DidFinishLoad() { |
82 current_location_ = UserScript::DOCUMENT_IDLE; | |
63 // Ensure that running scripts does not keep any progress UI running. | 83 // Ensure that running scripts does not keep any progress UI running. |
64 MessageLoop::current()->PostTask( | 84 MessageLoop::current()->PostTask( |
65 FROM_HERE, base::Bind(&UserScriptIdleScheduler::MaybeRun, | 85 FROM_HERE, base::Bind(&UserScriptIdleScheduler::MaybeRun, |
66 weak_factory_.GetWeakPtr())); | 86 weak_factory_.GetWeakPtr())); |
67 } | 87 } |
68 | 88 |
69 void UserScriptIdleScheduler::DidStartProvisionalLoad() { | 89 void UserScriptIdleScheduler::DidStartProvisionalLoad() { |
70 // The frame is navigating, so reset the state since we'll want to inject | 90 // The frame is navigating, so reset the state since we'll want to inject |
71 // scripts once the load finishes. | 91 // scripts once the load finishes. |
92 current_location_ = -1; | |
72 has_run_ = false; | 93 has_run_ = false; |
73 weak_factory_.InvalidateWeakPtrs(); | 94 weak_factory_.InvalidateWeakPtrs(); |
74 while (!pending_code_execution_queue_.empty()) | 95 Schedule::iterator itr = pending_code_execution_queue_.begin(); |
75 pending_code_execution_queue_.pop(); | 96 for (itr = pending_code_execution_queue_.begin(); |
97 itr != pending_code_execution_queue_.end(); ++itr) { | |
98 while (!itr->empty()) | |
99 itr->pop(); | |
100 } | |
101 } | |
102 | |
103 void UserScriptIdleScheduler::IdleTimeout() { | |
104 current_location_ = UserScript::DOCUMENT_IDLE; | |
105 MessageLoop::current()->PostTask( | |
106 FROM_HERE, base::Bind(&UserScriptIdleScheduler::MaybeRun, | |
107 weak_factory_.GetWeakPtr())); | |
76 } | 108 } |
77 | 109 |
78 void UserScriptIdleScheduler::MaybeRun() { | 110 void UserScriptIdleScheduler::MaybeRun() { |
79 if (has_run_) | 111 if (has_run_ || current_location_ == -1) |
80 return; | 112 return; |
81 | 113 |
82 // Note: we must set this before calling ExecuteCodeImpl, because that may | 114 // Note: we must set this before calling ExecuteCodeImpl, because that may |
Mihai Parparita -not on Chrome
2012/03/01 00:40:08
This comment doesn't seem to be true anymore (Exec
eaugusti
2012/03/27 00:43:34
Done.
| |
83 // result in a synchronous call back into MaybeRun if there is a pending task | 115 // result in a synchronous call back into MaybeRun if there is a pending task |
84 // currently in the queue. | 116 // currently in the queue. |
85 // http://code.google.com/p/chromium/issues/detail?id=29644 | 117 // http://code.google.com/p/chromium/issues/detail?id=29644 |
86 has_run_ = true; | 118 has_run_ = true; |
87 | 119 |
88 extension_dispatcher_->user_script_slave()->InjectScripts( | 120 extension_dispatcher_->user_script_slave()->InjectScripts( |
89 frame_, UserScript::DOCUMENT_IDLE); | 121 frame_, (UserScript::RunLocation)current_location_); |
Mihai Parparita -not on Chrome
2012/03/01 00:40:08
Use C++-style casts: http://google-styleguide.goog
eaugusti
2012/03/27 00:43:34
Done.
| |
90 | 122 |
91 while (!pending_code_execution_queue_.empty()) { | 123 // Run all tasks from the current time and earlier. |
92 linked_ptr<ExtensionMsg_ExecuteCode_Params>& params = | 124 for (int runTime = 0; runTime <= current_location_; ++runTime) { |
93 pending_code_execution_queue_.front(); | 125 while (!pending_code_execution_queue_[runTime].empty()) { |
94 ExecuteCodeImpl(*params); | 126 linked_ptr<ExtensionMsg_ExecuteCode_Params>& params = |
95 pending_code_execution_queue_.pop(); | 127 pending_code_execution_queue_[runTime].front(); |
128 ExecuteCodeImpl(*params); | |
129 pending_code_execution_queue_[runTime].pop(); | |
130 } | |
96 } | 131 } |
97 } | 132 } |
98 | 133 |
99 void UserScriptIdleScheduler::ExecuteCodeImpl( | 134 void UserScriptIdleScheduler::ExecuteCodeImpl( |
100 const ExtensionMsg_ExecuteCode_Params& params) { | 135 const ExtensionMsg_ExecuteCode_Params& params) { |
101 const Extension* extension = extension_dispatcher_->extensions()->GetByID( | 136 const Extension* extension = extension_dispatcher_->extensions()->GetByID( |
102 params.extension_id); | 137 params.extension_id); |
103 content::RenderView* render_view = | 138 content::RenderView* render_view = |
104 content::RenderView::FromWebView(frame_->view()); | 139 content::RenderView::FromWebView(frame_->view()); |
105 | 140 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 if (!parent_frame) | 208 if (!parent_frame) |
174 return false; | 209 return false; |
175 | 210 |
176 for (WebFrame* child_frame = parent_frame->firstChild(); child_frame; | 211 for (WebFrame* child_frame = parent_frame->firstChild(); child_frame; |
177 child_frame = child_frame->nextSibling()) { | 212 child_frame = child_frame->nextSibling()) { |
178 frames_vector->push_back(child_frame); | 213 frames_vector->push_back(child_frame); |
179 GetAllChildFrames(child_frame, frames_vector); | 214 GetAllChildFrames(child_frame, frames_vector); |
180 } | 215 } |
181 return true; | 216 return true; |
182 } | 217 } |
OLD | NEW |