summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-03 05:02:30 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-03 05:02:30 +0000
commitfa7b6b547368d12ccd61f6cbf251f2ff0d37b504 (patch)
treec28ef0f99dc70cd1dc8acf70f3cc8af5d2cb9072 /chrome
parentd12f7a9539c490b3e008d234526a67d0496972b3 (diff)
downloadchromium_src-fa7b6b547368d12ccd61f6cbf251f2ff0d37b504.zip
chromium_src-fa7b6b547368d12ccd61f6cbf251f2ff0d37b504.tar.gz
chromium_src-fa7b6b547368d12ccd61f6cbf251f2ff0d37b504.tar.bz2
Re-commit "Add new user script injection point:
document_idle." Original code review: http://codereview.chromium.org/339064 BUG=26126 TBR=rafaelw@chromium.org git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30796 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/user_script_master.cc5
-rwxr-xr-xchrome/chrome.gyp2
-rw-r--r--chrome/common/extensions/docs/content_scripts.html19
-rw-r--r--chrome/common/extensions/docs/static/content_scripts.html19
-rw-r--r--chrome/common/extensions/extension.cc2
-rw-r--r--chrome/common/extensions/extension_constants.cc1
-rw-r--r--chrome/common/extensions/extension_constants.h1
-rw-r--r--chrome/common/extensions/user_script.h11
-rw-r--r--chrome/common/extensions/user_script_unittest.cc2
-rw-r--r--chrome/renderer/navigation_state.h12
-rw-r--r--chrome/renderer/render_view.cc73
-rw-r--r--chrome/renderer/render_view.h9
-rw-r--r--chrome/renderer/user_script_idle_scheduler.cc47
-rw-r--r--chrome/renderer/user_script_idle_scheduler.h58
-rw-r--r--chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js38
15 files changed, 250 insertions, 49 deletions
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index b0552e0..69fd746 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -166,6 +166,11 @@ void UserScriptMaster::ScriptReloader::LoadScriptsFromDirectory(
file = enumerator.Next()) {
result->push_back(UserScript());
UserScript& user_script = result->back();
+
+ // We default standalone user scripts to document-end for better
+ // Greasemonkey compatibility.
+ user_script.set_run_location(UserScript::DOCUMENT_END);
+
// Push single js file in this UserScript.
GURL url(std::string(chrome::kUserScriptScheme) + ":/" +
net::FilePathToFileURL(file).ExtractFileName());
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index eaec76b..59946bb 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -3302,6 +3302,8 @@
'renderer/renderer_web_database_observer.h',
'renderer/socket_stream_dispatcher.cc',
'renderer/socket_stream_dispatcher.h',
+ 'renderer/user_script_idle_scheduler.cc',
+ 'renderer/user_script_idle_scheduler.h',
'renderer/user_script_slave.cc',
'renderer/user_script_slave.h',
'renderer/visitedlink_slave.cc',
diff --git a/chrome/common/extensions/docs/content_scripts.html b/chrome/common/extensions/docs/content_scripts.html
index 51beb4d..feba6ba 100644
--- a/chrome/common/extensions/docs/content_scripts.html
+++ b/chrome/common/extensions/docs/content_scripts.html
@@ -346,7 +346,24 @@ learn about the
<tr>
<td>run_at</td>
<td>string</td>
- <td>Optional. Controls when the files in <code>js</code> are injected. Can be <code>"document_start"</code> or <code>"document_end"</code>. Defaults to <code>"document_end"</code>. In the case of <code>"document_start"</code>, the files are injected after any files from <code>"css"</code>, but before any other DOM is constructed or any other script is run. In the case of <code>"document_end"</code>, the files are injected after the DOM is complete, but before subresources like images and frames have necessarily loaded.</td>
+ <td>Optional. Controls when the files in <code>js</code> are injected. Can be <code>"document_start"</code>, <code>"document_end"</code>, or <code>"document_idle"</code>. Defaults to <code>"document_idle"</code>.
+
+ <br><br>
+
+ In the case of <code>"document_start"</code>, the files are injected after any files from <code>"css"</code>, but before any other DOM is constructed or any other script is run.
+
+ <br><br>
+
+ In the case of <code>"document_end"</code>, the files are injected immediately after the DOM is complete, but before subresources like images and frames have loaded.
+
+ <br><br>
+
+ In the case of <code>"document_idle"</code>, the browser chooses a time to inject scripts between <code>"document_end"</code> and immediately after the <code><a href="http://www.whatwg.org/specs/web-apps/current-work/#handler-onload">window.onload</a></code> event fires. The exact moment of injection depends on how complex the document is and how long it is taking to load, and is optimized for page load speed.
+
+ <br><br>
+
+ <b>NOTE:</b> In <code>document_idle</code>, content scripts may not necessarily receive the window.onload event, because they may run after it has
+ already fired. In most cases, listening for the onload event is unnecessary for content scripts running at <code>document_idle</code> because they are guaranteed to run after the DOM is complete. If your script definitely needs to run after <code>window.onload</code> you can check if it has already fired by using the <code><a href="http://www.whatwg.org/specs/web-apps/current-work/#dom-document-readystate">document.readyState</a></code> property.</td>
</tr>
</tbody></table>
diff --git a/chrome/common/extensions/docs/static/content_scripts.html b/chrome/common/extensions/docs/static/content_scripts.html
index cbd738f..9f1edf1 100644
--- a/chrome/common/extensions/docs/static/content_scripts.html
+++ b/chrome/common/extensions/docs/static/content_scripts.html
@@ -104,7 +104,24 @@ learn about the
<tr>
<td>run_at</td>
<td>string</td>
- <td>Optional. Controls when the files in <code>js</code> are injected. Can be <code>"document_start"</code> or <code>"document_end"</code>. Defaults to <code>"document_end"</code>. In the case of <code>"document_start"</code>, the files are injected after any files from <code>"css"</code>, but before any other DOM is constructed or any other script is run. In the case of <code>"document_end"</code>, the files are injected after the DOM is complete, but before subresources like images and frames have necessarily loaded.</td>
+ <td>Optional. Controls when the files in <code>js</code> are injected. Can be <code>"document_start"</code>, <code>"document_end"</code>, or <code>"document_idle"</code>. Defaults to <code>"document_idle"</code>.
+
+ <br><br>
+
+ In the case of <code>"document_start"</code>, the files are injected after any files from <code>"css"</code>, but before any other DOM is constructed or any other script is run.
+
+ <br><br>
+
+ In the case of <code>"document_end"</code>, the files are injected immediately after the DOM is complete, but before subresources like images and frames have loaded.
+
+ <br><br>
+
+ In the case of <code>"document_idle"</code>, the browser chooses a time to inject scripts between <code>"document_end"</code> and immediately after the <code><a href="http://www.whatwg.org/specs/web-apps/current-work/#handler-onload">window.onload</a></code> event fires. The exact moment of injection depends on how complex the document is and how long it is taking to load, and is optimized for page load speed.
+
+ <br><br>
+
+ <b>NOTE:</b> In <code>document_idle</code>, content scripts may not necessarily receive the window.onload event, because they may run after it has
+ already fired. In most cases, listening for the onload event is unnecessary for content scripts running at <code>document_idle</code> because they are guaranteed to run after the DOM is complete. If your script definitely needs to run after <code>window.onload</code> you can check if it has already fired by using the <code><a href="http://www.whatwg.org/specs/web-apps/current-work/#dom-document-readystate">document.readyState</a></code> property.</td>
</tr>
</table>
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 429dfb5..c617232 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -208,6 +208,8 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script,
result->set_run_location(UserScript::DOCUMENT_START);
} else if (run_location == values::kRunAtDocumentEnd) {
result->set_run_location(UserScript::DOCUMENT_END);
+ } else if (run_location == values::kRunAtDocumentIdle) {
+ result->set_run_location(UserScript::DOCUMENT_IDLE);
} else {
*error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidRunAt,
IntToString(definition_index));
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 8259009..59e7c14 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -52,6 +52,7 @@ const wchar_t* kOptionsPage = L"options_page";
namespace extension_manifest_values {
const char* kRunAtDocumentStart = "document_start";
const char* kRunAtDocumentEnd = "document_end";
+const char* kRunAtDocumentIdle = "document_idle";
const char* kPageActionTypeTab = "tab";
const char* kPageActionTypePermanent = "permanent";
} // namespace extension_manifest_values
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 7f44bf6..b7826a7 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -54,6 +54,7 @@ namespace extension_manifest_keys {
namespace extension_manifest_values {
extern const char* kRunAtDocumentStart;
extern const char* kRunAtDocumentEnd;
+ extern const char* kRunAtDocumentIdle;
extern const char* kPageActionTypeTab;
extern const char* kPageActionTypePermanent;
} // namespace extension_manifest_values
diff --git a/chrome/common/extensions/user_script.h b/chrome/common/extensions/user_script.h
index 28b3aae..bdd1e54 100644
--- a/chrome/common/extensions/user_script.h
+++ b/chrome/common/extensions/user_script.h
@@ -28,6 +28,10 @@ class UserScript {
// anything else happens.
DOCUMENT_END, // After the entire document is parsed. Same as
// DOMContentLoaded.
+ DOCUMENT_IDLE, // Sometime after DOMContentLoaded, as soon as the document
+ // is "idle". Currently this uses the simple heuristic of:
+ // min(DOM_CONTENT_LOADED + TIMEOUT, ONLOAD), but no
+ // particular injection point is guaranteed.
RUN_LOCATION_LAST // Leave this as the last item.
};
@@ -88,9 +92,10 @@ class UserScript {
typedef std::vector<File> FileList;
- // Constructor. Default the run location to document end, which is like
- // Greasemonkey and probably more useful for typical scripts.
- UserScript() : run_location_(DOCUMENT_END) {}
+ // Constructor. Default the run location to document idle, which is similar
+ // to Greasemonkey but should result in better page load times for fast-
+ // loading pages.
+ UserScript() : run_location_(DOCUMENT_IDLE) {}
// The place in the document to run the script.
RunLocation run_location() const { return run_location_; }
diff --git a/chrome/common/extensions/user_script_unittest.cc b/chrome/common/extensions/user_script_unittest.cc
index b171f4e..58ef77e 100644
--- a/chrome/common/extensions/user_script_unittest.cc
+++ b/chrome/common/extensions/user_script_unittest.cc
@@ -122,5 +122,5 @@ TEST(UserScriptTest, Pickle) {
TEST(UserScriptTest, Defaults) {
UserScript script;
- ASSERT_EQ(UserScript::DOCUMENT_END, script.run_location());
+ ASSERT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
}
diff --git a/chrome/renderer/navigation_state.h b/chrome/renderer/navigation_state.h
index 46031dd..394aee9 100644
--- a/chrome/renderer/navigation_state.h
+++ b/chrome/renderer/navigation_state.h
@@ -8,6 +8,7 @@
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "chrome/common/page_transition_types.h"
+#include "chrome/renderer/user_script_idle_scheduler.h"
#include "webkit/api/public/WebDataSource.h"
#include "webkit/glue/alt_error_page_resource_fetcher.h"
#include "webkit/glue/password_form.h"
@@ -33,6 +34,13 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
return static_cast<NavigationState*>(ds->extraData());
}
+ UserScriptIdleScheduler* user_script_idle_scheduler() {
+ return user_script_idle_scheduler_.get();
+ }
+ void set_user_script_idle_scheduler(UserScriptIdleScheduler* scheduler) {
+ user_script_idle_scheduler_.reset(scheduler);
+ }
+
// Contains the page_id for this navigation or -1 if there is none yet.
int32 pending_page_id() const { return pending_page_id_; }
@@ -173,7 +181,8 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
request_committed_(false),
is_content_initiated_(is_content_initiated),
pending_page_id_(pending_page_id),
- postpone_loading_data_(false) {
+ postpone_loading_data_(false),
+ user_script_idle_scheduler_(NULL) {
}
PageTransition::Type transition_type_;
@@ -195,6 +204,7 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
std::string security_info_;
bool postpone_loading_data_;
std::string postponed_data_;
+ scoped_ptr<UserScriptIdleScheduler> user_script_idle_scheduler_;
DISALLOW_COPY_AND_ASSIGN(NavigationState);
};
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 95f5e34..ce8a521 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1829,6 +1829,10 @@ void RenderView::willClose(WebFrame* frame) {
if (url.SchemeIs("http") || url.SchemeIs("https"))
DumpLoadHistograms();
}
+
+ WebDataSource* ds = frame->dataSource();
+ NavigationState* navigation_state = NavigationState::FromDataSource(ds);
+ navigation_state->user_script_idle_scheduler()->Cancel();
}
void RenderView::loadURLExternally(
@@ -2031,11 +2035,13 @@ void RenderView::didCompleteClientRedirect(
void RenderView::didCreateDataSource(WebFrame* frame, WebDataSource* ds) {
// The rest of RenderView assumes that a WebDataSource will always have a
// non-null NavigationState.
- if (pending_navigation_state_.get()) {
- ds->setExtraData(pending_navigation_state_.release());
- } else {
- ds->setExtraData(NavigationState::CreateContentInitiated());
- }
+ NavigationState* state = pending_navigation_state_.get() ?
+ pending_navigation_state_.release() :
+ NavigationState::CreateContentInitiated();
+
+ state->set_user_script_idle_scheduler(
+ new UserScriptIdleScheduler(this, frame));
+ ds->setExtraData(state);
}
void RenderView::didStartProvisionalLoad(WebFrame* frame) {
@@ -2250,14 +2256,6 @@ void RenderView::didCreateDocumentElement(WebFrame* frame) {
ExtensionProcessBindings::SetViewType(webview(), view_type_);
}
- while (!pending_code_execution_queue_.empty()) {
- scoped_refptr<CodeExecutionInfo> info =
- pending_code_execution_queue_.front();
- OnExecuteCode(info->request_id, info->extension_id, info->is_js_code,
- info->code_string);
- pending_code_execution_queue_.pop();
- }
-
// Notify the browser about non-blank documents loading in the top frame.
GURL url = frame->url();
if (url.is_valid() && url.spec() != chrome::kAboutBlankURL) {
@@ -2292,6 +2290,26 @@ void RenderView::didFinishDocumentLoad(WebFrame* frame) {
RenderThread::current()->user_script_slave()->InjectScripts(
frame, UserScript::DOCUMENT_END);
}
+
+ navigation_state->user_script_idle_scheduler()->DidFinishDocumentLoad();
+}
+
+void RenderView::OnUserScriptIdleTriggered(WebFrame* frame) {
+ if (RenderThread::current()) { // Will be NULL during unit tests.
+ RenderThread::current()->user_script_slave()->InjectScripts(
+ frame, UserScript::DOCUMENT_IDLE);
+ }
+
+ WebFrame* main_frame = webview()->mainFrame();
+ if (frame == main_frame) {
+ while (!pending_code_execution_queue_.empty()) {
+ scoped_refptr<CodeExecutionInfo> info =
+ pending_code_execution_queue_.front();
+ ExecuteCodeImpl(main_frame, info->request_id, info->extension_id,
+ info->is_js_code, info->code_string);
+ pending_code_execution_queue_.pop();
+ }
+ }
}
void RenderView::didHandleOnloadEvents(WebFrame* frame) {
@@ -2307,6 +2325,7 @@ void RenderView::didFinishLoad(WebFrame* frame) {
NavigationState* navigation_state = NavigationState::FromDataSource(ds);
DCHECK(navigation_state);
navigation_state->set_finish_load_time(Time::Now());
+ navigation_state->user_script_idle_scheduler()->DidFinishLoad();
}
void RenderView::didChangeLocationWithinPage(
@@ -3662,28 +3681,40 @@ void RenderView::OnSetEditCommandsForNextKeyEvent(
void RenderView::OnExecuteCode(int request_id, const std::string& extension_id,
bool is_js_code,
const std::string& code_string) {
- if (is_loading_) {
- scoped_refptr<CodeExecutionInfo> info = new CodeExecutionInfo(
- request_id, extension_id, is_js_code, code_string);
- pending_code_execution_queue_.push(info);
- return;
- }
WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
if (!main_frame) {
Send(new ViewMsg_ExecuteCodeFinished(routing_id_, request_id, false));
return;
}
+ WebDataSource* ds = main_frame->dataSource();
+ NavigationState* navigation_state = NavigationState::FromDataSource(ds);
+ if (!navigation_state->user_script_idle_scheduler()->has_run()) {
+ scoped_refptr<CodeExecutionInfo> info = new CodeExecutionInfo(
+ request_id, extension_id, is_js_code, code_string);
+ pending_code_execution_queue_.push(info);
+ return;
+ }
+
+ ExecuteCodeImpl(main_frame, request_id, extension_id, is_js_code,
+ code_string);
+}
+
+void RenderView::ExecuteCodeImpl(WebFrame* frame,
+ int request_id,
+ const std::string& extension_id,
+ bool is_js_code,
+ const std::string& code_string) {
if (is_js_code) {
std::vector<WebScriptSource> sources;
sources.push_back(
WebScriptSource(WebString::fromUTF8(code_string)));
UserScriptSlave::InsertInitExtensionCode(&sources, extension_id);
- main_frame->executeScriptInIsolatedWorld(
+ frame->executeScriptInIsolatedWorld(
UserScriptSlave::GetIsolatedWorldId(extension_id),
&sources.front(), sources.size(), EXTENSION_GROUP_CONTENT_SCRIPTS);
} else {
- main_frame->insertStyleText(WebString::fromUTF8(code_string), WebString());
+ frame->insertStyleText(WebString::fromUTF8(code_string), WebString());
}
Send(new ViewMsg_ExecuteCodeFinished(routing_id_, request_id, true));
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 900cb2c..814d8bd 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -435,6 +435,10 @@ class RenderView : public RenderWidget,
// Sends a message and runs a nested message loop.
bool SendAndRunNestedMessageLoop(IPC::SyncMessage* message);
+ // Called when the "idle" user script state has been reached. See
+ // UserScript::DOCUMENT_IDLE.
+ void OnUserScriptIdleTriggered(WebKit::WebFrame* frame);
+
protected:
// RenderWidget overrides:
virtual void Close();
@@ -620,6 +624,11 @@ class RenderView : public RenderWidget,
const std::string& extension_id,
bool is_js_code,
const std::string& code_string);
+ void ExecuteCodeImpl(WebKit::WebFrame* frame,
+ int request_id,
+ const std::string& extension_id,
+ bool is_js_code,
+ const std::string& code_string);
void OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count);
void OnGetAccessibilityInfo(
diff --git a/chrome/renderer/user_script_idle_scheduler.cc b/chrome/renderer/user_script_idle_scheduler.cc
new file mode 100644
index 0000000..2468bf1
--- /dev/null
+++ b/chrome/renderer/user_script_idle_scheduler.cc
@@ -0,0 +1,47 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/user_script_idle_scheduler.h"
+
+#include "base/message_loop.h"
+#include "chrome/renderer/render_view.h"
+
+namespace {
+// The length of time to wait after the DOM is complete to try and run user
+// scripts.
+const int kUserScriptIdleTimeoutMs = 200;
+}
+
+UserScriptIdleScheduler::UserScriptIdleScheduler(RenderView* view,
+ WebKit::WebFrame* frame)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), view_(view),
+ frame_(frame), has_run_(false) {
+}
+
+void UserScriptIdleScheduler::DidFinishDocumentLoad() {
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(&UserScriptIdleScheduler::MaybeRun),
+ kUserScriptIdleTimeoutMs);
+}
+
+void UserScriptIdleScheduler::DidFinishLoad() {
+ // Ensure that running scripts does not keep any progress UI running.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(&UserScriptIdleScheduler::MaybeRun));
+}
+
+void UserScriptIdleScheduler::Cancel() {
+ view_ = NULL;
+ frame_ = NULL;
+}
+
+void UserScriptIdleScheduler::MaybeRun() {
+ if (!view_)
+ return;
+
+ DCHECK(frame_);
+ view_->OnUserScriptIdleTriggered(frame_);
+ Cancel();
+ has_run_ = true;
+}
diff --git a/chrome/renderer/user_script_idle_scheduler.h b/chrome/renderer/user_script_idle_scheduler.h
new file mode 100644
index 0000000..772d652
--- /dev/null
+++ b/chrome/renderer/user_script_idle_scheduler.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_USER_SCRIPT_IDLE_SCHEDULER_H_
+#define CHROME_RENDERER_USER_SCRIPT_IDLE_SCHEDULER_H_
+
+#include "base/task.h"
+
+class RenderView;
+
+namespace WebKit {
+class WebFrame;
+}
+
+// Implements support for injecting scripts at "document idle". Currently,
+// determining idleness is simple: it is whichever of the following happens
+// first:
+//
+// a) When the initial DOM for a page is complete + kUserScriptIdleTimeout,
+// b) or when the page has completely loaded including all subresources.
+//
+// The intent of this mechanism is to prevent user scripts from slowing down
+// fast pages (run after load), while still allowing them to run relatively
+// timelily for pages with lots of slow subresources.
+class UserScriptIdleScheduler {
+ public:
+ UserScriptIdleScheduler(RenderView* view, WebKit::WebFrame* frame);
+
+ bool has_run() { return has_run_; }
+
+ // Called when the DOM has been completely constructed.
+ void DidFinishDocumentLoad();
+
+ // Called when the document has completed loading.
+ void DidFinishLoad();
+
+ // Called when the client has gone away and we should no longer run scripts.
+ void Cancel();
+
+ private:
+ // Run user scripts, except if they've already run for this frame, or the
+ // frame has been destroyed.
+ void MaybeRun();
+
+ ScopedRunnableMethodFactory<UserScriptIdleScheduler> method_factory_;
+
+ // The RenderView we will call back to when it is time to run scripts.
+ RenderView* view_;
+
+ // The Frame we will run scripts in.
+ WebKit::WebFrame* frame_;
+
+ // Whether we have already run scripts.
+ bool has_run_;
+};
+
+#endif // CHROME_RENDERER_USER_SCRIPT_IDLE_SCHEDULER_H_
diff --git a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js
index 34d27fc..24f7a9a 100644
--- a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js
+++ b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js
@@ -3,28 +3,24 @@ if (typeof(contentWindow) != 'undefined') {
win = contentWindow;
}
-win.onload = function() {
- // Do this in an onload handler because I'm not sure if chrome.extension
- // is available before then.
- chrome.extension.onConnect.addListener(function(port) {
- console.log('connected');
- port.onMessage.addListener(function(msg) {
- console.log('got ' + msg);
- if (msg.testPostMessage) {
- port.postMessage({success: true});
- } else if (msg.testPostMessageFromTab) {
- testPostMessageFromTab(port);
- } else if (msg.testDisconnect) {
- port.disconnect();
- } else if (msg.testDisconnectOnClose) {
- win.location = "about:blank";
- } else if (msg.testPortName) {
- port.postMessage({portName:port.name});
- }
- // Ignore other messages since they are from us.
- });
+chrome.extension.onConnect.addListener(function(port) {
+ console.log('connected');
+ port.onMessage.addListener(function(msg) {
+ console.log('got ' + msg);
+ if (msg.testPostMessage) {
+ port.postMessage({success: true});
+ } else if (msg.testPostMessageFromTab) {
+ testPostMessageFromTab(port);
+ } else if (msg.testDisconnect) {
+ port.disconnect();
+ } else if (msg.testDisconnectOnClose) {
+ win.location = "about:blank";
+ } else if (msg.testPortName) {
+ port.postMessage({portName:port.name});
+ }
+ // Ignore other messages since they are from us.
});
-};
+});
// Tests that postMessage to the extension and its response works.
function testPostMessageFromTab(origPort) {