Chromium Code Reviews| 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 |