diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-08 22:57:50 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-08 22:57:50 +0000 |
commit | ccdaf3daedf362860baf698902f18d1e6f0089b7 (patch) | |
tree | 2be41f7cf39d63d49375bef762fb9b11a4e57002 | |
parent | a4df4160d29cbaee030d87fce1edaf9c9ba0f2e7 (diff) | |
download | chromium_src-ccdaf3daedf362860baf698902f18d1e6f0089b7.zip chromium_src-ccdaf3daedf362860baf698902f18d1e6f0089b7.tar.gz chromium_src-ccdaf3daedf362860baf698902f18d1e6f0089b7.tar.bz2 |
Merge 68646 - Makes instant run before unload listeners.
BUG=64694
TEST=none
Review URL: http://codereview.chromium.org/5610005
TBR=sky@chromium.org
Review URL: http://codereview.chromium.org/5581010
git-svn-id: svn://svn.chromium.org/chrome/branches/597/src@68657 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/instant/instant_browsertest.cc | 1 | ||||
-rw-r--r-- | chrome/browser/instant/instant_unload_handler.cc | 135 | ||||
-rw-r--r-- | chrome/browser/instant/instant_unload_handler.h | 48 | ||||
-rw-r--r-- | chrome/browser/sessions/session_id.h | 3 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_controller.cc | 6 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_controller.h | 2 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_controller_unittest.cc | 12 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 9 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.h | 6 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_delegate.cc | 3 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_delegate.h | 3 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.cc | 12 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.h | 8 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model_unittest.cc | 4 | ||||
-rw-r--r-- | chrome/browser/ui/browser.cc | 25 | ||||
-rw-r--r-- | chrome/browser/ui/browser.h | 2 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
17 files changed, 244 insertions, 37 deletions
diff --git a/chrome/browser/instant/instant_browsertest.cc b/chrome/browser/instant/instant_browsertest.cc index 02d25ad..f9a0d7e 100644 --- a/chrome/browser/instant/instant_browsertest.cc +++ b/chrome/browser/instant/instant_browsertest.cc @@ -22,7 +22,6 @@ #include "chrome/test/in_process_browser_test.h" #include "chrome/test/ui_test_utils.h" - class InstantTest : public InProcessBrowserTest { public: InstantTest() diff --git a/chrome/browser/instant/instant_unload_handler.cc b/chrome/browser/instant/instant_unload_handler.cc new file mode 100644 index 0000000..811bde2 --- /dev/null +++ b/chrome/browser/instant/instant_unload_handler.cc @@ -0,0 +1,135 @@ +// Copyright (c) 2010 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/browser/instant/instant_unload_handler.h" + +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_delegate.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" + +// TabContentsDelegate implementation. This owns the TabContents supplied to the +// constructor. +class InstantUnloadHandler::TabContentsDelegateImpl + : public TabContentsDelegate { + public: + TabContentsDelegateImpl(InstantUnloadHandler* handler, + TabContentsWrapper* tab_contents, + int index) + : handler_(handler), + tab_contents_(tab_contents), + index_(index) { + tab_contents->tab_contents()->set_delegate(this); + } + + ~TabContentsDelegateImpl() { + } + + // Releases ownership of the TabContentsWrapper to the caller. + TabContentsWrapper* ReleaseTab() { + TabContentsWrapper* tab = tab_contents_.release(); + tab->tab_contents()->set_delegate(NULL); + return tab; + } + + // See description above field. + int index() const { return index_; } + + // TabContentsDelegate overrides: + virtual void WillRunBeforeUnloadConfirm() { + handler_->Activate(this); + } + + virtual bool ShouldSuppressDialogs() { + return true; // Return true so dialogs are suppressed. + } + + virtual void CloseContents(TabContents* source) { + handler_->Destroy(this); + } + + // All of the following are overriden to do nothing (they are pure + // virtual). When we're attemping to close the tab, none of this matters. + virtual void OpenURLFromTab(TabContents* source, + const GURL& url, const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition) {} + virtual void NavigationStateChanged(const TabContents* source, + unsigned changed_flags) {} + virtual void AddNewContents(TabContents* source, + TabContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) {} + virtual void ActivateContents(TabContents* contents) {} + virtual void DeactivateContents(TabContents* contents) {} + virtual void LoadingStateChanged(TabContents* source) {} + virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {} + virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {} + virtual void URLStarredChanged(TabContents* source, bool starred) {} + virtual void UpdateTargetURL(TabContents* source, const GURL& url) {} + + private: + InstantUnloadHandler* handler_; + scoped_ptr<TabContentsWrapper> tab_contents_; + + // The index |tab_contents_| was originally at. If we add the tab back we add + // it at this index. + const int index_; + + DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl); +}; + +InstantUnloadHandler::InstantUnloadHandler(Browser* browser) + : browser_(browser) { +} + +InstantUnloadHandler::~InstantUnloadHandler() { +} + +void InstantUnloadHandler::RunUnloadListenersOrDestroy(TabContentsWrapper* tab, + int index) { + if (!tab->tab_contents()->NeedToFireBeforeUnload()) { + // Tab doesn't have any before unload listeners and can be safely deleted. + delete tab; + return; + } + + // Tab has before unload listener. Install a delegate and fire the before + // unload listener. + TabContentsDelegateImpl* delegate = + new TabContentsDelegateImpl(this, tab, index); + delegates_.push_back(delegate); + // TODO: decide if we really want false here. false is used for tab closes, + // and is needed so that the tab correctly closes but it doesn't really match + // what's logically happening. + tab->tab_contents()->render_view_host()->FirePageBeforeUnload(false); +} + +void InstantUnloadHandler::Activate(TabContentsDelegateImpl* delegate) { + // Take ownership of the TabContents from the delegate. + TabContentsWrapper* tab = delegate->ReleaseTab(); + browser::NavigateParams params(browser_, tab); + params.disposition = NEW_FOREGROUND_TAB; + params.tabstrip_index = delegate->index(); + + // Remove (and delete) the delegate. + ScopedVector<TabContentsDelegateImpl>::iterator i = + std::find(delegates_.begin(), delegates_.end(), delegate); + DCHECK(i != delegates_.end()); + delegates_.erase(i); + delegate = NULL; + + // Add the tab back in. + browser::Navigate(¶ms); +} + +void InstantUnloadHandler::Destroy(TabContentsDelegateImpl* delegate) { + ScopedVector<TabContentsDelegateImpl>::iterator i = + std::find(delegates_.begin(), delegates_.end(), delegate); + DCHECK(i != delegates_.end()); + delegates_.erase(i); +} diff --git a/chrome/browser/instant/instant_unload_handler.h b/chrome/browser/instant/instant_unload_handler.h new file mode 100644 index 0000000..21800d0 --- /dev/null +++ b/chrome/browser/instant/instant_unload_handler.h @@ -0,0 +1,48 @@ +// Copyright (c) 2010 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_BROWSER_INSTANT_INSTANT_UNLOAD_HANDLER_H_ +#define CHROME_BROWSER_INSTANT_INSTANT_UNLOAD_HANDLER_H_ +#pragma once + +#include "base/scoped_vector.h" + +class Browser; +class TabContentsWrapper; + +// InstantUnloadHandler makes sure the before unload and unload handler is run +// when using instant. When the user commits the instant preview the existing +// TabContentsWrapper is passed to |RunUnloadListenersOrDestroy|. If the tab has +// no before unload or unload listener the tab is deleted, otherwise the before +// unload and unload listener is executed. If the before unload listener shows a +// dialog the tab is added back to the tabstrip at its original location next to +// the instant page. +class InstantUnloadHandler { + public: + explicit InstantUnloadHandler(Browser* browser); + ~InstantUnloadHandler(); + + // See class description for details on what this does. + void RunUnloadListenersOrDestroy(TabContentsWrapper* tab_contents, int index); + + private: + class TabContentsDelegateImpl; + + // Invoked if the tab is to be shown. This happens if the before unload + // listener returns a string. + void Activate(TabContentsDelegateImpl* delegate); + + // Destroys the old tab. This is invoked if script tries to close the page. + void Destroy(TabContentsDelegateImpl* delegate); + + // TODO(sky): browser really needs to wait to close until there are no more + // tabs managed by InstantUnloadHandler. + Browser* browser_; + + ScopedVector<TabContentsDelegateImpl> delegates_; + + DISALLOW_COPY_AND_ASSIGN(InstantUnloadHandler); +}; + +#endif // CHROME_BROWSER_INSTANT_INSTANT_UNLOAD_HANDLER_H_ diff --git a/chrome/browser/sessions/session_id.h b/chrome/browser/sessions/session_id.h index 3036386..91f6d6f 100644 --- a/chrome/browser/sessions/session_id.h +++ b/chrome/browser/sessions/session_id.h @@ -28,9 +28,6 @@ class SessionID { explicit SessionID(id_type id) : id_(id) {} - // Resets the ID to 0. - void clear() { id_ = 0; } - // Resets the id. This is used when restoring a session void set_id(id_type id) { id_ = id; } diff --git a/chrome/browser/tab_contents/navigation_controller.cc b/chrome/browser/tab_contents/navigation_controller.cc index 918a9b4..fac26a3 100644 --- a/chrome/browser/tab_contents/navigation_controller.cc +++ b/chrome/browser/tab_contents/navigation_controller.cc @@ -980,8 +980,10 @@ void NavigationController::CopyStateFromAndPrune(NavigationController* source) { // Take over the session id from source. session_id_ = source->session_id_; - // Reset source's session id as we're taking it over. - source->session_id_.clear(); + // Reset source's session id as we're taking it over. We give it a new id in + // case source is added later on, which can happen with instant enabled if the + // tab has a before unload handler. + source->session_id_ = SessionID(); } void NavigationController::PruneAllButActive() { diff --git a/chrome/browser/tab_contents/navigation_controller.h b/chrome/browser/tab_contents/navigation_controller.h index f9c284e..d86b587 100644 --- a/chrome/browser/tab_contents/navigation_controller.h +++ b/chrome/browser/tab_contents/navigation_controller.h @@ -372,8 +372,6 @@ class NavigationController { // this: E F *G* (last must be active or pending) // result: A B *G* // This ignores the transient index of the source and honors that of 'this'. - // This should only be used when you are going to destroy |source| right after - // invoking this. void CopyStateFromAndPrune(NavigationController* source); // Removes all the entries except the active entry. If there is a new pending diff --git a/chrome/browser/tab_contents/navigation_controller_unittest.cc b/chrome/browser/tab_contents/navigation_controller_unittest.cc index 81010a9..b8cfcb5 100644 --- a/chrome/browser/tab_contents/navigation_controller_unittest.cc +++ b/chrome/browser/tab_contents/navigation_controller_unittest.cc @@ -1740,9 +1740,9 @@ TEST_F(NavigationControllerTest, CopyStateFromAndPrune) { EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->url()); // The session id of the new tab should be that of the old, and the old should - // be set to 0. + // get a new id. EXPECT_EQ(id.id(), other_controller.session_id().id()); - EXPECT_EQ(0, controller().session_id().id()); + EXPECT_NE(id.id(), controller().session_id().id()); } // Test CopyStateFromAndPrune with 2 urls, the first selected and nothing in @@ -1770,9 +1770,9 @@ TEST_F(NavigationControllerTest, CopyStateFromAndPrune2) { EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->url()); // The session id of the new tab should be that of the old, and the old should - // be set to 0. + // get a new id. EXPECT_EQ(id.id(), other_controller.session_id().id()); - EXPECT_EQ(0, controller().session_id().id()); + EXPECT_NE(id.id(), controller().session_id().id()); } // Test CopyStateFromAndPrune with 2 urls, the first selected and nothing in @@ -1807,9 +1807,9 @@ TEST_F(NavigationControllerTest, CopyStateFromAndPrune3) { EXPECT_EQ(url3, other_controller.pending_entry()->url()); // The session id of the new tab should be that of the old, and the old should - // be set to 0. + // be get a new id. EXPECT_EQ(id.id(), other_controller.session_id().id()); - EXPECT_EQ(0, controller().session_id().id()); + EXPECT_NE(id.id(), controller().session_id().id()); } // Tests that navigations initiated from the page (with the history object) diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 816c56d..53e295f 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -849,6 +849,13 @@ void TabContents::HideContents() { WasHidden(); } +bool TabContents::NeedToFireBeforeUnload() { + // TODO(creis): Should we fire even for interstitial pages? + return notify_disconnection() && + !showing_interstitial_page() && + !render_view_host()->SuddenTerminationAllowed(); +} + void TabContents::OpenURL(const GURL& url, const GURL& referrer, WindowOpenDisposition disposition, PageTransition::Type transition) { @@ -2792,6 +2799,8 @@ void TabContents::RunJavaScriptMessage( void TabContents::RunBeforeUnloadConfirm(const std::wstring& message, IPC::Message* reply_msg) { + if (delegate()) + delegate()->WillRunBeforeUnloadConfirm(); if (delegate() && delegate()->ShouldSuppressDialogs()) { render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true, std::wstring()); diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index e213cac..345bca2 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -345,6 +345,12 @@ class TabContents : public PageNavigator, virtual void ShowContents(); virtual void HideContents(); + // Returns true if the before unload and unload listeners need to be + // fired. The value of this changes over time. For example, if true and the + // before unload listener is executed and allows the user to exit, then this + // returns false. + bool NeedToFireBeforeUnload(); + #ifdef UNIT_TEST // Expose the render manager for testing. RenderViewHostManager* render_manager() { return &render_manager_; } diff --git a/chrome/browser/tab_contents/tab_contents_delegate.cc b/chrome/browser/tab_contents/tab_contents_delegate.cc index 4b0e54b..21c13ff 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.cc +++ b/chrome/browser/tab_contents/tab_contents_delegate.cc @@ -49,6 +49,9 @@ void TabContentsDelegate::ShowHtmlDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window) { } +void TabContentsDelegate::WillRunBeforeUnloadConfirm() { +} + bool TabContentsDelegate::ShouldSuppressDialogs() { return false; } diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index b3cbf72..6a59741 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -158,6 +158,9 @@ class TabContentsDelegate : public AutomationResourceRoutingDelegate { virtual void ShowHtmlDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window); + // Invoked prior to showing before unload handler confirmation dialog. + virtual void WillRunBeforeUnloadConfirm(); + // Returns true if javascript dialogs and unload alerts are suppressed. // Default is false. virtual bool ShouldSuppressDialogs(); diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 1a9ac8f..98316e9 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -165,26 +165,28 @@ void TabStripModel::InsertTabContentsAt(int index, ChangeSelectedContentsFrom(selected_contents, index, false); } -void TabStripModel::ReplaceTabContentsAt(int index, - TabContentsWrapper* new_contents) { +TabContentsWrapper* TabStripModel::ReplaceTabContentsAt( + int index, + TabContentsWrapper* new_contents) { // TODO: this should reset group/opener of any tabs that point at // old_contents. DCHECK(ContainsIndex(index)); - scoped_ptr<TabContentsWrapper> old_contents(GetContentsAt(index)); + TabContentsWrapper* old_contents = GetContentsAt(index); contents_data_[index]->contents = new_contents; FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabReplacedAt(old_contents.get(), new_contents, index)); + TabReplacedAt(old_contents, new_contents, index)); // When the selected tab contents is replaced send out selected notification // too. We do this as nearly all observers need to treat a replace of the // selected contents as selection changing. if (selected_index_ == index) { FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabSelectedAt(old_contents.get(), new_contents, + TabSelectedAt(old_contents, new_contents, selected_index_, false)); } + return old_contents; } void TabStripModel::ReplaceNavigationControllerAt( diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h index 2aae16e..7a3c8d9 100644 --- a/chrome/browser/tabs/tab_strip_model.h +++ b/chrome/browser/tabs/tab_strip_model.h @@ -195,9 +195,11 @@ class TabStripModel : public NotificationObserver { void ReplaceNavigationControllerAt(int index, TabContentsWrapper* contents); - // Replaces the tab contents at |index| with |new_contents|. This deletes the - // TabContents currently at |index|. - void ReplaceTabContentsAt(int index, TabContentsWrapper* new_contents); + // Replaces the tab contents at |index| with |new_contents|. The + // TabContentsWrapper that was at |index| is returned and ownership returns + // to the caller. + TabContentsWrapper* ReplaceTabContentsAt(int index, + TabContentsWrapper* new_contents); // Detaches the TabContents at the specified index from this strip. The // TabContents is not destroyed, just removed from display. The caller is diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc index 576085d..ff461f6 100644 --- a/chrome/browser/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/tabs/tab_strip_model_unittest.cc @@ -1846,7 +1846,7 @@ TEST_F(TabStripModelTest, ReplaceSendsSelected) { strip.AddObserver(&tabstrip_observer); TabContentsWrapper* new_contents = CreateTabContents(); - strip.ReplaceTabContentsAt(0, new_contents); + delete strip.ReplaceTabContentsAt(0, new_contents); ASSERT_EQ(2, tabstrip_observer.GetStateCount()); @@ -1870,7 +1870,7 @@ TEST_F(TabStripModelTest, ReplaceSendsSelected) { // And replace it. new_contents = CreateTabContents(); - strip.ReplaceTabContentsAt(1, new_contents); + delete strip.ReplaceTabContentsAt(1, new_contents); ASSERT_EQ(1, tabstrip_observer.GetStateCount()); diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index e91f4c7..e0d9e1d 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -60,6 +60,7 @@ #include "chrome/browser/google/google_util.h" #include "chrome/browser/host_zoom_map.h" #include "chrome/browser/instant/instant_controller.h" +#include "chrome/browser/instant/instant_unload_handler.h" #include "chrome/browser/location_bar.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/net/browser_url_util.h" @@ -183,13 +184,6 @@ const float kPopupMaxWidthFactor = 0.5; const float kPopupMaxHeightFactor = 0.6; #endif -// Returns true if the specified TabContents has unload listeners registered. -bool TabHasUnloadListener(TabContents* contents) { - return contents->notify_disconnection() && - !contents->showing_interstitial_page() && - !contents->render_view_host()->SuddenTerminationAllowed(); -} - } // namespace extern bool g_log_bug53991; @@ -820,7 +814,7 @@ bool Browser::ShouldCloseWindow() { for (int i = 0; i < tab_count(); ++i) { TabContents* contents = GetTabContentsAt(i); - if (TabHasUnloadListener(contents)) + if (contents->NeedToFireBeforeUnload()) tabs_needing_before_unload_fired_.insert(contents); } @@ -2034,11 +2028,11 @@ bool Browser::RunUnloadEventsHelper(TabContents* contents) { // handler we can fire even if the TabContents has an unload listener. // One case where we hit this is in a tab that has an infinite loop // before load. - if (TabHasUnloadListener(contents)) { + if (contents->NeedToFireBeforeUnload()) { // If the page has unload listeners, then we tell the renderer to fire // them. Once they have fired, we'll get a message back saying whether // to proceed closing the page or not, which sends us back to this method - // with the HasUnloadListener bit cleared. + // with the NeedToFireBeforeUnload bit cleared. contents->render_view_host()->FirePageBeforeUnload(false); return true; } @@ -3313,7 +3307,8 @@ void Browser::Observe(NotificationType type, if (!InstantController::IsEnabled(profile())) { if (instant()) { instant()->DestroyPreviewContents(); - instant_.reset(NULL); + instant_.reset(); + instant_unload_handler_.reset(); } } else { CreateInstantIfNecessary(); @@ -3373,8 +3368,11 @@ void Browser::CommitInstant(TabContentsWrapper* preview_contents) { preview_contents->controller().CopyStateFromAndPrune( &tab_contents->controller()); // TabStripModel takes ownership of preview_contents. - tab_handler_->GetTabStripModel()->ReplaceTabContentsAt( - index, preview_contents); + TabContentsWrapper* old_contents = + tab_handler_->GetTabStripModel()->ReplaceTabContentsAt( + index, preview_contents); + // InstantUnloadHandler takes ownership of old_contents. + instant_unload_handler_->RunUnloadListenersOrDestroy(old_contents, index); } void Browser::SetSuggestedText(const string16& text) { @@ -4141,5 +4139,6 @@ void Browser::CreateInstantIfNecessary() { if (type() == TYPE_NORMAL && InstantController::IsEnabled(profile()) && !profile()->IsOffTheRecord()) { instant_.reset(new InstantController(profile_, this)); + instant_unload_handler_.reset(new InstantUnloadHandler(this)); } } diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index faa316c..8dcc28f 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -40,6 +40,7 @@ class BrowserWindow; class Extension; class FindBarController; class InstantController; +class InstantUnloadHandler; class PrefService; class Profile; class SessionStorageNamespace; @@ -1109,6 +1110,7 @@ class Browser : public TabHandlerDelegate, TabRestoreService* tab_restore_service_; scoped_ptr<InstantController> instant_; + scoped_ptr<InstantUnloadHandler> instant_unload_handler_; DISALLOW_COPY_AND_ASSIGN(Browser); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 8b40050..550367e 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2161,6 +2161,8 @@ 'browser/instant/instant_loader_delegate.h', 'browser/instant/instant_loader_manager.cc', 'browser/instant/instant_loader_manager.h', + 'browser/instant/instant_unload_handler.cc', + 'browser/instant/instant_unload_handler.h', 'browser/instant/promo_counter.cc', 'browser/instant/promo_counter.h', 'browser/intranet_redirect_detector.cc', |