diff options
-rw-r--r-- | chrome/browser/instant/instant_browsertest.cc | 71 | ||||
-rw-r--r-- | chrome/browser/instant/instant_controller.cc | 4 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader.cc | 16 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader.h | 7 | ||||
-rw-r--r-- | chrome/test/data/instant/download.zip | 1 | ||||
-rw-r--r-- | chrome/test/data/instant/download.zip.mock-http-headers | 5 |
6 files changed, 102 insertions, 2 deletions
diff --git a/chrome/browser/instant/instant_browsertest.cc b/chrome/browser/instant/instant_browsertest.cc index 26d4006..d0915d4 100644 --- a/chrome/browser/instant/instant_browsertest.cc +++ b/chrome/browser/instant/instant_browsertest.cc @@ -29,6 +29,45 @@ #define EXPECT_STR_EQ(ascii, utf16) \ EXPECT_EQ(ASCIIToWide(ascii), UTF16ToWide(utf16)) +namespace { + +// Wait for DOWNLOAD_INITIATED. +class DownloadNotificationObserver : public NotificationObserver { + public: + DownloadNotificationObserver() : running_(false), fired_(false) { + registrar_.Add(this, NotificationType::DOWNLOAD_INITIATED, + NotificationService::AllSources()); + } + + void Run() { + if (fired_) + return; + + running_ = true; + ui_test_utils::RunMessageLoop(); + running_ = false; + } + + bool fired() const { return fired_; } + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) OVERRIDE { + fired_ = true; + if (running_) + MessageLoopForUI::current()->Quit(); + } + + private: + bool running_; + bool fired_; + NotificationRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(DownloadNotificationObserver); +}; + +} // namespace + class InstantTest : public InProcessBrowserTest { public: InstantTest() @@ -740,3 +779,35 @@ IN_PROC_BROWSER_TEST_F(InstantTest, DontCrashOnBlockedJS) { NotificationType::INSTANT_SUPPORT_DETERMINED); // As long as we get the notification we're good (the renderer didn't crash). } + +IN_PROC_BROWSER_TEST_F(InstantTest, DownloadOnEnter) { + ASSERT_TRUE(test_server()->Start()); + EnableInstant(); + ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html")); + ASSERT_NO_FATAL_FAILURE(FindLocationBar()); + GURL url(test_server()->GetURL("files/instant/empty.html")); + location_bar_->location_entry()->SetUserText(UTF8ToUTF16(url.spec())); + ASSERT_NO_FATAL_FAILURE(WaitForPreviewToNavigate(true)); + url = test_server()->GetURL("files/instant/download.zip"); + location_bar_->location_entry()->SetUserText(UTF8ToUTF16(url.spec())); + // Wait for the load to fail (because instant disables downloads). + ui_test_utils::WaitForNotification( + NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR); + + DownloadNotificationObserver download_observer; + ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN)); + download_observer.Run(); + // Pressing enter should initiate a download. + EXPECT_TRUE(download_observer.fired()); + + // And we should end up at about:blank. + TabContents* contents = browser()->GetSelectedTabContents(); + ASSERT_TRUE(contents); + EXPECT_EQ("about:blank", + contents->controller().GetLastCommittedEntry()->url().spec()); + if (contents->controller().pending_entry()) { + // If there is a pending entry, the url should correspond to the download. + EXPECT_EQ(url.spec(), + contents->controller().pending_entry()->url().spec()); + } +} diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc index 4949783..75686a0 100644 --- a/chrome/browser/instant/instant_controller.cc +++ b/chrome/browser/instant/instant_controller.cc @@ -228,7 +228,9 @@ void InstantController::DestroyPreviewContentsAndLeaveActive() { bool InstantController::IsCurrent() { return loader_manager_.get() && loader_manager_->active_loader() && - loader_manager_->active_loader()->ready() && !update_timer_.IsRunning(); + loader_manager_->active_loader()->ready() && + !loader_manager_->active_loader()->needs_reload() && + !update_timer_.IsRunning(); } void InstantController::CommitCurrentPreview(InstantCommitType type) { diff --git a/chrome/browser/instant/instant_loader.cc b/chrome/browser/instant/instant_loader.cc index 167a84f..6eda28f 100644 --- a/chrome/browser/instant/instant_loader.cc +++ b/chrome/browser/instant/instant_loader.cc @@ -27,6 +27,7 @@ #include "content/browser/renderer_host/render_widget_host_view.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/navigation_entry.h" +#include "content/browser/tab_contents/provisional_load_details.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/tab_contents_delegate.h" #include "content/browser/tab_contents/tab_contents_view.h" @@ -262,6 +263,8 @@ InstantLoader::TabContentsDelegateImpl::TabContentsDelegateImpl( DCHECK(loader->preview_contents()); registrar_.Add(this, NotificationType::INTERSTITIAL_ATTACHED, Source<TabContents>(loader->preview_contents()->tab_contents())); + registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR, + Source<NavigationController>(&loader->preview_contents()->controller())); } void InstantLoader::TabContentsDelegateImpl::PrepareForNewLoad() { @@ -364,6 +367,14 @@ void InstantLoader::TabContentsDelegateImpl::Observe( const NotificationSource& source, const NotificationDetails& details) { switch (type.value) { + case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR: + if (Details<ProvisionalLoadDetails>(details)->url() == loader_->url_) { + // This typically happens with downloads (which are disabled with + // instant active). To ensure the download happens when the user presses + // enter we set needs_reload_ to true, which triggers a reload. + loader_->needs_reload_ = true; + } + break; case NotificationType::RENDER_WIDGET_HOST_DID_PAINT: UnregisterForPaintNotifications(); PreviewPainted(); @@ -495,6 +506,7 @@ void InstantLoader::TabContentsDelegateImpl::DragEnded() { } bool InstantLoader::TabContentsDelegateImpl::CanDownload(int request_id) { + // Downloads are disabled. return false; } @@ -580,7 +592,8 @@ InstantLoader::InstantLoader(InstantLoaderDelegate* delegate, TemplateURLID id) template_url_id_(id), ready_(false), last_transition_type_(PageTransition::LINK), - verbatim_(false) { + verbatim_(false), + needs_reload_(false) { } InstantLoader::~InstantLoader() { @@ -632,6 +645,7 @@ void InstantLoader::Update(TabContentsWrapper* tab_contents, user_text_ = new_user_text; verbatim_ = verbatim; last_suggestion_.clear(); + needs_reload_ = false; bool created_preview_contents = preview_contents_.get() == NULL; if (created_preview_contents) diff --git a/chrome/browser/instant/instant_loader.h b/chrome/browser/instant/instant_loader.h index d6d9796..e0ea0fe 100644 --- a/chrome/browser/instant/instant_loader.h +++ b/chrome/browser/instant/instant_loader.h @@ -81,6 +81,10 @@ class InstantLoader : public NotificationObserver { // Returns true if the preview TabContents is ready to be shown. bool ready() const { return ready_; } + // Returns true if the url needs to be reloaded. This is set to true for + // downloads. + bool needs_reload() const { return needs_reload_; } + const GURL& url() const { return url_; } bool verbatim() const { return verbatim_; } @@ -190,6 +194,9 @@ class InstantLoader : public NotificationObserver { // Last value of verbatim passed to |Update|. bool verbatim_; + // True if the page needs to be reloaded. + bool needs_reload_; + DISALLOW_COPY_AND_ASSIGN(InstantLoader); }; diff --git a/chrome/test/data/instant/download.zip b/chrome/test/data/instant/download.zip new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/chrome/test/data/instant/download.zip @@ -0,0 +1 @@ + diff --git a/chrome/test/data/instant/download.zip.mock-http-headers b/chrome/test/data/instant/download.zip.mock-http-headers new file mode 100644 index 0000000..ef07401 --- /dev/null +++ b/chrome/test/data/instant/download.zip.mock-http-headers @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Content-Type: application/zip +Content-Length: 0 +Date: Mon, 13 Nov 2006 21:38:09 GMT +Expires: Tue, 14 Nov 2006 19:23:58 GMT |