diff options
Diffstat (limited to 'chrome/browser/instant')
-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 |
3 files changed, 183 insertions, 1 deletions
diff --git a/chrome/browser/instant/instant_browsertest.cc b/chrome/browser/instant/instant_browsertest.cc index 18fc6b5..b5c1215 100644 --- a/chrome/browser/instant/instant_browsertest.cc +++ b/chrome/browser/instant/instant_browsertest.cc @@ -21,7 +21,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_ |