| Index: chrome/browser/instant/instant_unload_handler.cc
|
| diff --git a/chrome/browser/instant/instant_unload_handler.cc b/chrome/browser/instant/instant_unload_handler.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..811bde25e2e06d5dc43a96ee0ac211a4bcfff56f
|
| --- /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);
|
| +}
|
|
|