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