summaryrefslogtreecommitdiffstats
path: root/chrome/browser/instant
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/instant')
-rw-r--r--chrome/browser/instant/instant_browsertest.cc1
-rw-r--r--chrome/browser/instant/instant_unload_handler.cc135
-rw-r--r--chrome/browser/instant/instant_unload_handler.h48
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(&params);
+}
+
+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_