diff options
author | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-29 23:28:22 +0000 |
---|---|---|
committer | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-29 23:28:22 +0000 |
commit | 12b2adaafe3f962f756ee565475f47574dcc3026 (patch) | |
tree | 64274c028bfa00313f9bbd4dbeadf549dcac002a | |
parent | eeeb4b429da8fffc6e33c3c566c285f594d41e3f (diff) | |
download | chromium_src-12b2adaafe3f962f756ee565475f47574dcc3026.zip chromium_src-12b2adaafe3f962f756ee565475f47574dcc3026.tar.gz chromium_src-12b2adaafe3f962f756ee565475f47574dcc3026.tar.bz2 |
Initialize DOMUI handlers if the DOM itself is re-used
Back/forward causes a page navigation, triggering a new DOMUI to be created. Since the page is the same, however, WebKit doesn't actually do a navigation, and the DOM remains intact, so the onload handler doesn't fire and cause the newly-created DOMUI to be initialized.
This change notifies the DOMUI object when it has been bound to a RenderView that may have an existing DOM on the HTML/JS side, so that it can tell the page to re-trigger initialization if necessary.
BUG=60768
TEST=Open DOMUI prefs, go to another pref section, press the Back button, then try to change the search engines.
Review URL: http://codereview.chromium.org/5120005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67611 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/dom_ui/dom_ui.h | 11 | ||||
-rw-r--r-- | chrome/browser/dom_ui/options/options_ui.cc | 12 | ||||
-rw-r--r-- | chrome/browser/dom_ui/options/options_ui.h | 1 | ||||
-rw-r--r-- | chrome/browser/resources/options/options_page.js | 18 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_host_manager.cc | 2 |
5 files changed, 44 insertions, 0 deletions
diff --git a/chrome/browser/dom_ui/dom_ui.h b/chrome/browser/dom_ui/dom_ui.h index 5e76b7c..a74186d 100644 --- a/chrome/browser/dom_ui/dom_ui.h +++ b/chrome/browser/dom_ui/dom_ui.h @@ -42,6 +42,17 @@ class DOMUI { // page. virtual void RenderViewReused(RenderViewHost* render_view_host) {} + // Called when this becomes the active DOMUI instance for a re-used + // RenderView; this is the point at which this DOMUI instance will receive + // DOM messages instead of the previous DOMUI instance. + // + // If a DOMUI instance has code that is usually triggered from a JavaScript + // onload handler, this should be overridden to check to see if the web page's + // DOM is still intact (e.g., due to a back/forward navigation that remains + // within the same page), and if so trigger that code manually since onload + // won't be run in that case. + virtual void DidBecomeActiveForReusedRenderView() {} + // Called from TabContents. virtual void ProcessDOMUIMessage(const ViewHostMsg_DomMessage_Params& params); diff --git a/chrome/browser/dom_ui/options/options_ui.cc b/chrome/browser/dom_ui/options/options_ui.cc index 44d3b5d..2b250e7 100644 --- a/chrome/browser/dom_ui/options/options_ui.cc +++ b/chrome/browser/dom_ui/options/options_ui.cc @@ -231,6 +231,18 @@ void OptionsUI::RenderViewCreated(RenderViewHost* render_view_host) { DOMUI::RenderViewCreated(render_view_host); } +void OptionsUI::DidBecomeActiveForReusedRenderView() { + // When the renderer is re-used (e.g., for back/forward navigation within + // options), the handlers are torn down and rebuilt, so are no longer + // initialized, but the web page's DOM may remain intact, in which case onload + // won't fire to initilize the handlers. To make sure initialization always + // happens, call reinitializeCore (which is a no-op unless the DOM was already + // initialized). + CallJavascriptFunction(L"OptionsPage.reinitializeCore"); + + DOMUI::DidBecomeActiveForReusedRenderView(); +} + // static RefCountedMemory* OptionsUI::GetFaviconResourceBytes() { return ResourceBundle::GetSharedInstance(). diff --git a/chrome/browser/dom_ui/options/options_ui.h b/chrome/browser/dom_ui/options/options_ui.h index fafe972..fbc55e6 100644 --- a/chrome/browser/dom_ui/options/options_ui.h +++ b/chrome/browser/dom_ui/options/options_ui.h @@ -82,6 +82,7 @@ class OptionsUI : public DOMUI { static RefCountedMemory* GetFaviconResourceBytes(); void RenderViewCreated(RenderViewHost* render_view_host); + void DidBecomeActiveForReusedRenderView(); void InitializeHandlers(); diff --git a/chrome/browser/resources/options/options_page.js b/chrome/browser/resources/options/options_page.js index af66889..18b700e 100644 --- a/chrome/browser/resources/options/options_page.js +++ b/chrome/browser/resources/options/options_page.js @@ -37,6 +37,11 @@ cr.define('options', function() { OptionsPage.registeredOverlayPages_ = {}; /** + * Whether or not |initialize| has been called. + */ + OptionsPage.initialized_ = false; + + /** * Shows a registered page. This handles both top-level pages and sub-pages. * @param {string} pageName Page name. */ @@ -207,6 +212,7 @@ cr.define('options', function() { */ OptionsPage.initialize = function() { chrome.send('coreOptionsInitialize'); + this.initialized_ = true; // Set up the overlay sheet. Clicks on the visible part of the parent page // should close the overlay, not fall through to the parent page. @@ -217,6 +223,18 @@ cr.define('options', function() { } }; + /** + * Re-initializes the C++ handlers if necessary. This is called if the + * handlers are torn down and recreated but the DOM may not have been (in + * which case |initialize| won't be called again). If |initialize| hasn't been + * called, this does nothing (since it will be later, once the DOM has + * finished loading). + */ + OptionsPage.reinitializeCore = function() { + if (this.initialized_) + chrome.send('coreOptionsInitialize'); + } + OptionsPage.prototype = { __proto__: cr.EventTarget.prototype, diff --git a/chrome/browser/tab_contents/render_view_host_manager.cc b/chrome/browser/tab_contents/render_view_host_manager.cc index 664b7f5..c9e6373 100644 --- a/chrome/browser/tab_contents/render_view_host_manager.cc +++ b/chrome/browser/tab_contents/render_view_host_manager.cc @@ -495,6 +495,8 @@ void RenderViewHostManager::CommitPending() { // Next commit the DOM UI, if any. dom_ui_.swap(pending_dom_ui_); + if (dom_ui_.get() && pending_dom_ui_.get() && !pending_render_view_host_) + dom_ui_->DidBecomeActiveForReusedRenderView(); pending_dom_ui_.reset(); // It's possible for the pending_render_view_host_ to be NULL when we aren't |