summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-29 23:28:22 +0000
committerstuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-29 23:28:22 +0000
commit12b2adaafe3f962f756ee565475f47574dcc3026 (patch)
tree64274c028bfa00313f9bbd4dbeadf549dcac002a
parenteeeb4b429da8fffc6e33c3c566c285f594d41e3f (diff)
downloadchromium_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.h11
-rw-r--r--chrome/browser/dom_ui/options/options_ui.cc12
-rw-r--r--chrome/browser/dom_ui/options/options_ui.h1
-rw-r--r--chrome/browser/resources/options/options_page.js18
-rw-r--r--chrome/browser/tab_contents/render_view_host_manager.cc2
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