Home | History | Annotate | Download | only in search
      1 // Copyright 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_UI_SEARCH_INSTANT_UNLOAD_HANDLER_H_
      6 #define CHROME_BROWSER_UI_SEARCH_INSTANT_UNLOAD_HANDLER_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/memory/scoped_vector.h"
     11 
     12 class Browser;
     13 
     14 namespace content {
     15 class WebContents;
     16 }
     17 
     18 // InstantUnloadHandler ensures that it runs the BeforeUnload/Unload Handlers
     19 // (BUH) of a page if the page is replaced by an Instant overlay.
     20 //
     21 // Why is this needed? Say the user is looking at a page P. They then try to
     22 // navigate to another page Q. Consider what happens with and without Instant:
     23 //
     24 // Without Instant: Before the navigation is committed, P's BUH are run. If P's
     25 // BUH return a string (instead of the default null), the user is prompted to
     26 // "Stay or Leave?". If the user clicks "Stay", the navigation is cancelled,
     27 // and the user remains on P.
     28 //
     29 // With Instant: The navigation to Q has already happened, since Q is being
     30 // shown as a preview (overlay). When the user "commits" the overlay, it's too
     31 // late to cancel Q based on P's BUH. So, Instant just replaces P with Q and
     32 // passes P to InstantUnloadHandler::RunUnloadListenersOrDestroy(). This class
     33 // runs P's BUH in the background. If the "Stay or Leave?" dialog needs to be
     34 // shown, it adds P back onto the tabstrip, next to Q. Otherwise, P is deleted.
     35 class InstantUnloadHandler {
     36  public:
     37   explicit InstantUnloadHandler(Browser* browser);
     38   ~InstantUnloadHandler();
     39 
     40   // See class description for details on what this does.
     41   void RunUnloadListenersOrDestroy(scoped_ptr<content::WebContents> contents,
     42                                    int index);
     43 
     44  private:
     45   class WebContentsDelegateImpl;
     46 
     47   // Invoked if the tab is to be shown, at |index| on the tab strip. This
     48   // happens if the beforeunload listener returns a string.
     49   void Activate(WebContentsDelegateImpl* delegate,
     50                 scoped_ptr<content::WebContents> contents,
     51                 int index);
     52 
     53   // Destroys the old tab. This is invoked if script tries to close the page.
     54   void Destroy(WebContentsDelegateImpl* delegate);
     55 
     56   // TODO(sky): Browser really needs to wait to close until there are no more
     57   // tabs managed by InstantUnloadHandler.
     58   Browser* const browser_;
     59 
     60   ScopedVector<WebContentsDelegateImpl> delegates_;
     61 
     62   DISALLOW_COPY_AND_ASSIGN(InstantUnloadHandler);
     63 };
     64 
     65 #endif  // CHROME_BROWSER_UI_SEARCH_INSTANT_UNLOAD_HANDLER_H_
     66