| Index: chrome/browser/prerender/prerender_browsertest.cc
|
| diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
|
| index af8e09ed433e94793eb371b79ce30424c3a2e5a5..0ca3679326fcd6906921a9787e3d0217855ba56e 100644
|
| --- a/chrome/browser/prerender/prerender_browsertest.cc
|
| +++ b/chrome/browser/prerender/prerender_browsertest.cc
|
| @@ -46,6 +46,7 @@
|
| #include "chrome/browser/ui/browser_commands.h"
|
| #include "chrome/browser/ui/browser_finder.h"
|
| #include "chrome/browser/ui/browser_navigator.h"
|
| +#include "chrome/browser/ui/browser_tabstrip.h"
|
| #include "chrome/browser/ui/browser_window.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
|
| @@ -322,12 +323,17 @@ class NewTabNavigationOrSwapObserver {
|
| : new_tab_observer_(
|
| chrome::NOTIFICATION_TAB_ADDED,
|
| base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded,
|
| - base::Unretained(this))) {
|
| + base::Unretained(this))),
|
| + new_tab_(NULL) {
|
| // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the
|
| // NavigationOrSwapObserver can be attached synchronously and no events are
|
| // missed.
|
| }
|
|
|
| + WebContents* new_tab() const {
|
| + return new_tab_;
|
| + }
|
| +
|
| void Wait() {
|
| new_tab_observer_.Wait();
|
| swap_observer_->Wait();
|
| @@ -337,17 +343,18 @@ class NewTabNavigationOrSwapObserver {
|
| const content::NotificationDetails& details) {
|
| if (swap_observer_)
|
| return true;
|
| - WebContents* new_tab = content::Details<WebContents>(details).ptr();
|
| + new_tab_ = content::Details<WebContents>(details).ptr();
|
| // Get the TabStripModel. Assume this is attached to a Browser.
|
| TabStripModel* tab_strip_model =
|
| - static_cast<Browser*>(new_tab->GetDelegate())->tab_strip_model();
|
| + static_cast<Browser*>(new_tab_->GetDelegate())->tab_strip_model();
|
| swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model,
|
| - new_tab));
|
| + new_tab_));
|
| return true;
|
| }
|
|
|
| private:
|
| content::WindowedNotificationObserver new_tab_observer_;
|
| + WebContents* new_tab_;
|
| scoped_ptr<NavigationOrSwapObserver> swap_observer_;
|
| };
|
|
|
| @@ -1155,36 +1162,40 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
|
| OpenURLWithJSImpl("Click", url, GURL(), false);
|
| }
|
|
|
| - void OpenDestURLViaClickTarget() const {
|
| - OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true);
|
| + WebContents* OpenDestURLViaClickTarget() const {
|
| + return OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true);
|
| }
|
|
|
| void OpenDestURLViaClickPing(const GURL& ping_url) const {
|
| OpenURLWithJSImpl("ClickPing", dest_url_, ping_url, false);
|
| }
|
|
|
| - void OpenDestURLViaClickNewWindow() const {
|
| - OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true);
|
| + WebContents* OpenDestURLViaClickNewWindow() const {
|
| + return OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true);
|
| }
|
|
|
| - void OpenDestURLViaClickNewForegroundTab() const {
|
| + WebContents* OpenDestURLViaClickNewForegroundTab() const {
|
| #if defined(OS_MACOSX)
|
| - OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true);
|
| + return OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true);
|
| #else
|
| - OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true);
|
| + return OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true);
|
| #endif
|
| }
|
|
|
| - void OpenDestURLViaClickNewBackgroundTab() const {
|
| + WebContents* OpenDestURLViaClickNewBackgroundTab() const {
|
| #if defined(OS_MACOSX)
|
| - OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true);
|
| + return OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true);
|
| #else
|
| - OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true);
|
| + return OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true);
|
| #endif
|
| }
|
|
|
| - void OpenDestURLViaWindowOpen() const {
|
| - OpenURLWithJSImpl("WindowOpen", dest_url_, GURL(), true);
|
| + WebContents* OpenDestURLViaWindowOpen() const {
|
| + return OpenURLViaWindowOpen(dest_url_);
|
| + }
|
| +
|
| + WebContents* OpenURLViaWindowOpen(const GURL& url) const {
|
| + return OpenURLWithJSImpl("WindowOpen", url, GURL(), true);
|
| }
|
|
|
| void RemoveLinkElement(int i) const {
|
| @@ -1580,12 +1591,12 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
|
|
|
| // Opens the prerendered page using javascript functions in the loader
|
| // page. |javascript_function_name| should be a 0 argument function which is
|
| - // invoked. |new_web_contents| is true if the navigation is expected to
|
| - // happen in a new WebContents via OpenURL.
|
| - void OpenURLWithJSImpl(const std::string& javascript_function_name,
|
| - const GURL& url,
|
| - const GURL& ping_url,
|
| - bool new_web_contents) const {
|
| + // invoked. |new_web_contents| is true if the navigation is expected to happen
|
| + // in a new WebContents via OpenURL and the new WebContents is returned.
|
| + WebContents* OpenURLWithJSImpl(const std::string& javascript_function_name,
|
| + const GURL& url,
|
| + const GURL& ping_url,
|
| + bool new_web_contents) const {
|
| WebContents* web_contents = GetActiveWebContents();
|
| RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
|
| // Extra arguments in JS are ignored.
|
| @@ -1597,11 +1608,13 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
|
| NewTabNavigationOrSwapObserver observer;
|
| render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript));
|
| observer.Wait();
|
| + return observer.new_tab();
|
| } else {
|
| NavigationOrSwapObserver observer(current_browser()->tab_strip_model(),
|
| web_contents);
|
| render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript));
|
| observer.Wait();
|
| + return NULL;
|
| }
|
| }
|
|
|
| @@ -2869,6 +2882,37 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
|
| OpenDestURLViaClickTarget();
|
| }
|
|
|
| +// Checks that, if a popup's opener is closed, it still will not accept
|
| +// prerender swaps. This is relevant in determining whether window.close() may
|
| +// be called.
|
| +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderOpenerClosed) {
|
| + // Bump the abandon timeout to ensure the prerender survives its referrer
|
| + // closing.
|
| + GetPrerenderManager()->mutable_config().abandon_time_to_live =
|
| + base::TimeDelta::FromMinutes(5);
|
| +
|
| + PrerenderTestURL("files/prerender/prerender_page.html",
|
| + FINAL_STATUS_WINDOW_OPENER,
|
| + 1);
|
| +
|
| + // Open a popup with the referring page as opener.
|
| + WebContents* opener = GetActiveWebContents();
|
| + WebContents* popup = OpenURLViaWindowOpen(GURL(content::kAboutBlankURL));
|
| +
|
| + // Close the opener. The opener is gone, but WasOpenedByDOM() remains true.
|
| + EXPECT_TRUE(popup->HasOpener());
|
| + EXPECT_TRUE(popup->CreatedWithOpener());
|
| + chrome::CloseWebContents(browser(), opener, false);
|
| + EXPECT_FALSE(popup->HasOpener());
|
| + EXPECT_TRUE(popup->CreatedWithOpener());
|
| +
|
| + // Assume the popup is attached to a Browser.
|
| + set_browser(static_cast<Browser*>(popup->GetDelegate()));
|
| +
|
| + // The prerender should not swap.
|
| + NavigateToURLWithDisposition(dest_url(), CURRENT_TAB, false);
|
| +}
|
| +
|
| class TestClientCertStore : public net::ClientCertStore {
|
| public:
|
| TestClientCertStore() {}
|
|
|