172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// found in the LICENSE file. 4201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 5201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/instant/instant_unload_handler.h" 6201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 7201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/ui/browser.h" 8201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/ui/browser_navigator.h" 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_delegate.h" 13201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 14201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// TabContentsDelegate implementation. This owns the TabContents supplied to the 15201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// constructor. 16201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass InstantUnloadHandler::TabContentsDelegateImpl 17201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : public TabContentsDelegate { 18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public: 19201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsDelegateImpl(InstantUnloadHandler* handler, 20201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* tab_contents, 21201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int index) 22201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : handler_(handler), 23201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_(tab_contents), 24201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch index_(index) { 25201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents->tab_contents()->set_delegate(this); 26201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 27201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 28201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ~TabContentsDelegateImpl() { 29201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 30201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 31201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Releases ownership of the TabContentsWrapper to the caller. 32201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* ReleaseTab() { 33201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* tab = tab_contents_.release(); 34201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab->tab_contents()->set_delegate(NULL); 35201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return tab; 36201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 37201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 38201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // See description above field. 39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int index() const { return index_; } 40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // TabContentsDelegate overrides: 42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void WillRunBeforeUnloadConfirm() { 43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch handler_->Activate(this); 44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 45201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 46201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual bool ShouldSuppressDialogs() { 47201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; // Return true so dialogs are suppressed. 48201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 49201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 50201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void CloseContents(TabContents* source) { 51201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch handler_->Destroy(this); 52201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 53201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // All of the following are overriden to do nothing (they are pure 55201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // virtual). When we're attemping to close the tab, none of this matters. 56201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void OpenURLFromTab(TabContents* source, 57201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const GURL& url, const GURL& referrer, 58201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch WindowOpenDisposition disposition, 59201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch PageTransition::Type transition) {} 60201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void NavigationStateChanged(const TabContents* source, 61201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch unsigned changed_flags) {} 62201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void AddNewContents(TabContents* source, 63201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContents* new_contents, 64201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch WindowOpenDisposition disposition, 65201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const gfx::Rect& initial_pos, 66201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool user_gesture) {} 67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void ActivateContents(TabContents* contents) {} 68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void DeactivateContents(TabContents* contents) {} 69201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void LoadingStateChanged(TabContents* source) {} 70201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {} 71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void UpdateTargetURL(TabContents* source, const GURL& url) {} 72201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 73201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private: 74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch InstantUnloadHandler* handler_; 75201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch scoped_ptr<TabContentsWrapper> tab_contents_; 76201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 77201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // The index |tab_contents_| was originally at. If we add the tab back we add 78201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // it at this index. 79201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const int index_; 80201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 81201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl); 82201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 83201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochInstantUnloadHandler::InstantUnloadHandler(Browser* browser) 85201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : browser_(browser) { 86201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 87201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 88201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochInstantUnloadHandler::~InstantUnloadHandler() { 89201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 90201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 91201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid InstantUnloadHandler::RunUnloadListenersOrDestroy(TabContentsWrapper* tab, 92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int index) { 93201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!tab->tab_contents()->NeedToFireBeforeUnload()) { 94201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Tab doesn't have any before unload listeners and can be safely deleted. 95201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch delete tab; 96201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 97201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 98201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 99201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Tab has before unload listener. Install a delegate and fire the before 100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // unload listener. 101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsDelegateImpl* delegate = 102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new TabContentsDelegateImpl(this, tab, index); 103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch delegates_.push_back(delegate); 104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // TODO: decide if we really want false here. false is used for tab closes, 105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // and is needed so that the tab correctly closes but it doesn't really match 106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // what's logically happening. 107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab->tab_contents()->render_view_host()->FirePageBeforeUnload(false); 108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid InstantUnloadHandler::Activate(TabContentsDelegateImpl* delegate) { 111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Take ownership of the TabContents from the delegate. 112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* tab = delegate->ReleaseTab(); 113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser::NavigateParams params(browser_, tab); 114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch params.disposition = NEW_FOREGROUND_TAB; 115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch params.tabstrip_index = delegate->index(); 116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Remove (and delete) the delegate. 118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ScopedVector<TabContentsDelegateImpl>::iterator i = 119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::find(delegates_.begin(), delegates_.end(), delegate); 120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(i != delegates_.end()); 121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch delegates_.erase(i); 122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch delegate = NULL; 123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Add the tab back in. 125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser::Navigate(¶ms); 126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid InstantUnloadHandler::Destroy(TabContentsDelegateImpl* delegate) { 129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ScopedVector<TabContentsDelegateImpl>::iterator i = 130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::find(delegates_.begin(), delegates_.end(), delegate); 131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(i != delegates_.end()); 132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch delegates_.erase(i); 133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 134