From 5792d936fb199d7875e7670e82f812fc2c7bee51 Mon Sep 17 00:00:00 2001 From: "mpcomplete@chromium.org" Date: Tue, 18 Jan 2011 20:33:29 +0000 Subject: Fix race condition where chrome.tabs.executeScript sometimes wouldn't inject scripts. This is done by reusing the same UserScriptIdleScheduler for reference fragment navigations. BUG=64093 TEST=See bug for repro. Review URL: http://codereview.chromium.org/6099013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71693 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/renderer/navigation_state.cc | 5 +++++ chrome/renderer/navigation_state.h | 1 + chrome/renderer/render_view.cc | 22 ++++++++++------------ chrome/renderer/user_script_idle_scheduler.h | 2 -- 4 files changed, 16 insertions(+), 14 deletions(-) (limited to 'chrome/renderer') diff --git a/chrome/renderer/navigation_state.cc b/chrome/renderer/navigation_state.cc index 49ee7a7..47759f8 100644 --- a/chrome/renderer/navigation_state.cc +++ b/chrome/renderer/navigation_state.cc @@ -15,6 +15,11 @@ void NavigationState::set_user_script_idle_scheduler( user_script_idle_scheduler_.reset(scheduler); } +void NavigationState::swap_user_script_idle_scheduler( + NavigationState* state) { + user_script_idle_scheduler_.swap(state->user_script_idle_scheduler_); +} + void NavigationState::set_password_form_data(webkit_glue::PasswordForm* data) { password_form_data_.reset(data); } diff --git a/chrome/renderer/navigation_state.h b/chrome/renderer/navigation_state.h index bc2ff3a..6a4cdb5 100644 --- a/chrome/renderer/navigation_state.h +++ b/chrome/renderer/navigation_state.h @@ -66,6 +66,7 @@ class NavigationState : public WebKit::WebDataSource::ExtraData { return user_script_idle_scheduler_.get(); } void set_user_script_idle_scheduler(UserScriptIdleScheduler* scheduler); + void swap_user_script_idle_scheduler(NavigationState* state); // Contains the page_id for this navigation or -1 if there is none yet. int32 pending_page_id() const { return pending_page_id_; } diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 9b71058..fe84d68 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -3181,8 +3181,16 @@ void RenderView::didCreateDataSource(WebFrame* frame, WebDataSource* ds) { } } - state->set_user_script_idle_scheduler( - new UserScriptIdleScheduler(this, frame)); + // If this datasource already has a UserScriptIdleScheduler, reuse that one. + // This is for navigations within a page (didNavigateWithinPage). See + // http://code.google.com/p/chromium/issues/detail?id=64093 + NavigationState* old_state = NavigationState::FromDataSource(ds); + if (old_state && old_state->user_script_idle_scheduler()) { + state->swap_user_script_idle_scheduler(old_state); + } else { + state->set_user_script_idle_scheduler( + new UserScriptIdleScheduler(this, frame)); + } ds->setExtraData(state); } @@ -3507,11 +3515,6 @@ void RenderView::didFinishLoad(WebFrame* frame) { void RenderView::didNavigateWithinPage( WebFrame* frame, bool is_new_navigation) { - // Determine if the UserScriptIdleScheduler already ran scripts on this page, - // since a new one gets created by didCreateDataSource. - NavigationState* state = NavigationState::FromDataSource(frame->dataSource()); - bool idle_scheduler_ran = state->user_script_idle_scheduler()->has_run(); - // If this was a reference fragment navigation that we initiated, then we // could end up having a non-null pending navigation state. We just need to // update the ExtraData on the datasource so that others who read the @@ -3525,11 +3528,6 @@ void RenderView::didNavigateWithinPage( NavigationState::FromDataSource(frame->dataSource()); new_state->set_was_within_same_page(true); - if (idle_scheduler_ran) { - // Update the new UserScriptIdleScheduler so we don't re-run scripts. - new_state->user_script_idle_scheduler()->set_has_run(true); - } - didCommitProvisionalLoad(frame, is_new_navigation); UpdateTitle(frame, frame->view()->mainFrame()->dataSource()->pageTitle()); diff --git a/chrome/renderer/user_script_idle_scheduler.h b/chrome/renderer/user_script_idle_scheduler.h index d287d75..165db5a 100644 --- a/chrome/renderer/user_script_idle_scheduler.h +++ b/chrome/renderer/user_script_idle_scheduler.h @@ -31,8 +31,6 @@ class UserScriptIdleScheduler { bool has_run() { return has_run_; } - void set_has_run(bool has_run) { has_run_ = has_run; } - // Called when the DOM has been completely constructed. void DidFinishDocumentLoad(); -- cgit v1.1