summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/automation/automation_provider.cc3
-rw-r--r--chrome/browser/browser.cc2
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm2
-rw-r--r--chrome/browser/cocoa/repost_form_warning_mac.h17
-rw-r--r--chrome/browser/cocoa/repost_form_warning_mac.mm68
-rw-r--r--chrome/browser/cocoa/toolbar_controller.mm3
-rw-r--r--chrome/browser/repost_form_warning_uitest.cc78
-rw-r--r--chrome/browser/tab_contents/navigation_controller.cc38
-rw-r--r--chrome/browser/tab_contents/navigation_controller.h9
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/notification_type.h4
-rw-r--r--chrome/test/data/form.html8
12 files changed, 190 insertions, 43 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 8ae593b..25f9d87 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -2299,7 +2299,8 @@ void AutomationProvider::ReloadAsync(int tab_handle) {
return;
}
- tab->Reload(false);
+ const bool check_for_repost = true;
+ tab->Reload(check_for_repost);
}
}
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index af98839..3dc499b 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -2787,7 +2787,7 @@ void Browser::UpdateCommandsForTabState() {
!(type() & TYPE_APP) && tab_count() > 1);
// Current navigation entry, may be NULL.
- NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
+ NavigationEntry* active_entry = nc.GetActiveEntry();
// Page-related commands
window_->SetStarredState(current_tab->is_starred());
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index 8380256..01d592e 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -333,7 +333,7 @@ void BrowserWindowCocoa::ShowNewProfileDialog() {
void BrowserWindowCocoa::ShowRepostFormWarningDialog(
TabContents* tab_contents) {
- new RepostFormWarningMac(GetNativeHandle(), &tab_contents->controller());
+ new RepostFormWarningMac(GetNativeHandle(), tab_contents);
}
void BrowserWindowCocoa::ShowContentSettingsWindow(
diff --git a/chrome/browser/cocoa/repost_form_warning_mac.h b/chrome/browser/cocoa/repost_form_warning_mac.h
index 91586cf..a9c480a 100644
--- a/chrome/browser/cocoa/repost_form_warning_mac.h
+++ b/chrome/browser/cocoa/repost_form_warning_mac.h
@@ -8,6 +8,8 @@
#import <Cocoa/Cocoa.h>
#include "base/scoped_nsobject.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/cocoa/constrained_window_mac.h"
#include "chrome/common/notification_registrar.h"
class NavigationController;
@@ -18,12 +20,15 @@ class RepostFormWarningMac;
// To display the dialog, allocate this object on the heap. It will open the
// dialog from its constructor and then delete itself when the user dismisses
// the dialog.
-class RepostFormWarningMac : public NotificationObserver {
+class RepostFormWarningMac : public NotificationObserver,
+ public ConstrainedWindowMacDelegateSystemSheet {
public:
RepostFormWarningMac(NSWindow* parent,
- NavigationController* navigation_controller);
+ TabContents* tab_contents);
virtual ~RepostFormWarningMac();
+ virtual void DeleteDelegate();
+
void Confirm();
void Cancel();
@@ -34,7 +39,9 @@ class RepostFormWarningMac : public NotificationObserver {
const NotificationSource& source,
const NotificationDetails& details);
- // Close the sheet. This will only be done once, even if Destroy is called
+ // Close the sheet.
+ void Dismiss();
+ // Clean up. This will only be done once, even if Destroy is called
// multiple times (eg, from both Confirm and Observe.)
void Destroy();
@@ -43,9 +50,7 @@ class RepostFormWarningMac : public NotificationObserver {
// Navigation controller, used to continue the reload.
NavigationController* navigation_controller_;
- scoped_nsobject<NSAlert> alert_;
-
- scoped_nsobject<RepostDelegate> delegate_;
+ ConstrainedWindow* window_;
DISALLOW_COPY_AND_ASSIGN(RepostFormWarningMac);
};
diff --git a/chrome/browser/cocoa/repost_form_warning_mac.mm b/chrome/browser/cocoa/repost_form_warning_mac.mm
index 2ca64d8..31292c0 100644
--- a/chrome/browser/cocoa/repost_form_warning_mac.mm
+++ b/chrome/browser/cocoa/repost_form_warning_mac.mm
@@ -41,64 +41,84 @@
RepostFormWarningMac::RepostFormWarningMac(
NSWindow* parent,
- NavigationController* navigation_controller)
- : navigation_controller_(navigation_controller),
- alert_([[NSAlert alloc] init]),
- delegate_([[RepostDelegate alloc] initWithWarning:this]) {
- [alert_ setMessageText:
+ TabContents* tab_contents)
+ : ConstrainedWindowMacDelegateSystemSheet(
+ [[[RepostDelegate alloc] initWithWarning:this] autorelease],
+ @selector(alertDidEnd:returnCode:contextInfo:)),
+ navigation_controller_(&tab_contents->controller()) {
+ scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
+ [alert setMessageText:
l10n_util::GetNSStringWithFixup(IDS_HTTP_POST_WARNING_TITLE)];
- [alert_ setInformativeText:
+ [alert setInformativeText:
l10n_util::GetNSStringWithFixup(IDS_HTTP_POST_WARNING)];
- [alert_ addButtonWithTitle:
+ [alert addButtonWithTitle:
l10n_util::GetNSStringWithFixup(IDS_HTTP_POST_WARNING_RESEND)];
- [alert_ addButtonWithTitle:
+ [alert addButtonWithTitle:
l10n_util::GetNSStringWithFixup(IDS_CANCEL)];
- [alert_ beginSheetModalForWindow:parent
- modalDelegate:delegate_.get()
- didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
- contextInfo:nil];
+ set_sheet(alert);
registrar_.Add(this, NotificationType::LOAD_START,
Source<NavigationController>(navigation_controller_));
registrar_.Add(this, NotificationType::TAB_CLOSING,
Source<NavigationController>(navigation_controller_));
+ registrar_.Add(this, NotificationType::RELOADING,
+ Source<NavigationController>(navigation_controller_));
+ window_ = tab_contents->CreateConstrainedDialog(this);
}
RepostFormWarningMac::~RepostFormWarningMac() {
}
+void RepostFormWarningMac::DeleteDelegate() {
+ window_ = NULL;
+ Dismiss();
+ delete this;
+}
+
void RepostFormWarningMac::Confirm() {
+ if (navigation_controller_) {
+ navigation_controller_->ContinuePendingReload();
+ }
Destroy();
- if (navigation_controller_)
- navigation_controller_->Reload(false);
}
void RepostFormWarningMac::Cancel() {
+ if (navigation_controller_) {
+ navigation_controller_->CancelPendingReload();
+ }
Destroy();
}
+void RepostFormWarningMac::Dismiss() {
+ if (sheet() && is_sheet_open()) {
+ // This will call |Cancel()|.
+ [NSApp endSheet:[(NSAlert*)sheet() window]
+ returnCode:NSAlertSecondButtonReturn];
+ }
+}
+
void RepostFormWarningMac::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
// Close the dialog if we load a page (because reloading might not apply to
// the same page anymore) or if the tab is closed, because then we won't have
// a navigation controller anymore.
- if (alert_ && navigation_controller_ &&
- (type == NotificationType::LOAD_START ||
- type == NotificationType::TAB_CLOSING)) {
+ if ((type == NotificationType::LOAD_START ||
+ type == NotificationType::TAB_CLOSING ||
+ type == NotificationType::RELOADING)) {
DCHECK_EQ(Source<NavigationController>(source).ptr(),
navigation_controller_);
- navigation_controller_ = NULL;
-
- // This will call |Cancel()|.
- [NSApp endSheet:[alert_ window] returnCode:NSAlertSecondButtonReturn];
+ Dismiss();
}
}
void RepostFormWarningMac::Destroy() {
- if (alert_) {
- alert_.reset(NULL);
- MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+ navigation_controller_ = NULL;
+ if (sheet()) {
+ set_sheet(nil);
+ }
+ if (window_) {
+ window_->CloseConstrainedWindow();
}
}
diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm
index bf32934..431932b 100644
--- a/chrome/browser/cocoa/toolbar_controller.mm
+++ b/chrome/browser/cocoa/toolbar_controller.mm
@@ -384,6 +384,9 @@ class PrefObserverBridge : public NotificationObserver {
case IDC_FORWARD:
button = forwardButton_;
break;
+ case IDC_RELOAD:
+ button = reloadButton_;
+ break;
case IDC_HOME:
button = homeButton_;
break;
diff --git a/chrome/browser/repost_form_warning_uitest.cc b/chrome/browser/repost_form_warning_uitest.cc
new file mode 100644
index 0000000..755ae85
--- /dev/null
+++ b/chrome/browser/repost_form_warning_uitest.cc
@@ -0,0 +1,78 @@
+// 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 <string>
+
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/net/url_fixer_upper.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/automation/tab_proxy.h"
+#include "chrome/test/automation/browser_proxy.h"
+#include "chrome/test/ui/ui_test.h"
+#include "net/url_request/url_request_unittest.h"
+
+using std::wstring;
+
+namespace {
+
+const wchar_t kDocRoot[] = L"chrome/test/data";
+
+} // namespace
+
+class RepostFormWarningTest : public UITest {
+};
+
+
+TEST_F(RepostFormWarningTest, TestDoubleReload) {
+ scoped_refptr<HTTPTestServer> server =
+ HTTPTestServer::CreateServer(kDocRoot, NULL);
+ ASSERT_TRUE(NULL != server.get());
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ EXPECT_TRUE(browser.get());
+
+ scoped_refptr<TabProxy> tab(browser->GetTab(0));
+
+ // Load a form.
+ ASSERT_TRUE(tab->NavigateToURL(server->TestServerPageW(L"files/form.html")));
+ // Submit it.
+ ASSERT_TRUE(tab->NavigateToURL(GURL(
+ "javascript:document.getElementById('form').submit()")));
+
+ // Try to reload it twice, checking for repost.
+ tab->ReloadAsync();
+ tab->ReloadAsync();
+
+ // Navigate away from the page (this is when the test usually crashes).
+ ASSERT_TRUE(tab->NavigateToURL(server->TestServerPageW(L"bar")));
+}
+
+TEST_F(RepostFormWarningTest, TestLoginAfterRepost) {
+ scoped_refptr<HTTPTestServer> server =
+ HTTPTestServer::CreateServer(kDocRoot, NULL);
+ ASSERT_TRUE(NULL != server.get());
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(browser.get());
+
+ scoped_refptr<TabProxy> tab(browser->GetTab(0));
+
+ // Load a form.
+ ASSERT_TRUE(tab->NavigateToURL(server->TestServerPageW(L"files/form.html")));
+ // Submit it.
+ ASSERT_TRUE(tab->NavigateToURL(GURL(
+ "javascript:document.getElementById('form').submit()")));
+
+ // Try to reload it, checking for repost.
+ tab->ReloadAsync();
+
+ // Navigate to a page that requires authentication, bringing up another
+ // tab-modal sheet.
+ ASSERT_TRUE(tab->NavigateToURL(server->TestServerPageW(L"auth-basic")));
+
+ // Try to reload it again.
+ tab->ReloadAsync();
+
+ // Navigate away from the page.
+ ASSERT_TRUE(tab->NavigateToURL(server->TestServerPageW(L"bar")));
+}
diff --git a/chrome/browser/tab_contents/navigation_controller.cc b/chrome/browser/tab_contents/navigation_controller.cc
index 96e5fa9..bdcc811 100644
--- a/chrome/browser/tab_contents/navigation_controller.cc
+++ b/chrome/browser/tab_contents/navigation_controller.cc
@@ -146,7 +146,8 @@ NavigationController::NavigationController(TabContents* contents,
needs_reload_(false),
user_gesture_observed_(false),
session_storage_namespace_id_(profile->GetWebKitContext()->
- dom_storage_context()->AllocateSessionStorageNamespaceId()) {
+ dom_storage_context()->AllocateSessionStorageNamespaceId()),
+ pending_reload_(NO_RELOAD) {
DCHECK(profile_);
}
@@ -195,22 +196,25 @@ void NavigationController::ReloadInternal(bool check_for_repost,
DiscardNonCommittedEntriesInternal();
int current_index = GetCurrentEntryIndex();
- if (check_for_repost_ && check_for_repost && current_index != -1 &&
+ // If we are no where, then we can't reload. TODO(darin): We should add a
+ // CanReload method.
+ if (current_index == -1) {
+ return;
+ }
+
+ NotificationService::current()->Notify(NotificationType::RELOADING,
+ Source<NavigationController>(this),
+ NotificationService::NoDetails());
+
+ if (check_for_repost_ && check_for_repost &&
GetEntryAtIndex(current_index)->has_post_data()) {
// The user is asking to reload a page with POST data. Prompt to make sure
// they really want to do this. If they do, the dialog will call us back
// with check_for_repost = false.
+ pending_reload_ = reload_type;
tab_contents_->Activate();
tab_contents_->delegate()->ShowRepostFormWarningDialog(tab_contents_);
} else {
- // Base the navigation on where we are now...
- int current_index = GetCurrentEntryIndex();
-
- // If we are no where, then we can't reload. TODO(darin): We should add a
- // CanReload method.
- if (current_index == -1)
- return;
-
DiscardNonCommittedEntriesInternal();
pending_entry_index_ = current_index;
@@ -219,6 +223,20 @@ void NavigationController::ReloadInternal(bool check_for_repost,
}
}
+void NavigationController::CancelPendingReload() {
+ DCHECK(pending_reload_ != NO_RELOAD);
+ pending_reload_ = NO_RELOAD;
+}
+
+void NavigationController::ContinuePendingReload() {
+ if (pending_reload_ == NO_RELOAD) {
+ NOTREACHED();
+ } else {
+ ReloadInternal(false, pending_reload_);
+ CancelPendingReload();
+ }
+}
+
NavigationEntry* NavigationController::GetEntryWithPageID(
SiteInstance* instance, int32 page_id) const {
int index = GetEntryIndexWithPageID(instance, page_id);
diff --git a/chrome/browser/tab_contents/navigation_controller.h b/chrome/browser/tab_contents/navigation_controller.h
index 1efdc3d..c2dae3f 100644
--- a/chrome/browser/tab_contents/navigation_controller.h
+++ b/chrome/browser/tab_contents/navigation_controller.h
@@ -400,6 +400,11 @@ class NavigationController {
}
static size_t max_entry_count() { return max_entry_count_; }
+ // Cancels a repost that brought up a warning.
+ void CancelPendingReload();
+ // Continues a repost that brought up a warning.
+ void ContinuePendingReload();
+
private:
class RestoreHelper;
friend class RestoreHelper;
@@ -557,6 +562,10 @@ class NavigationController {
// The maximum number of entries that a navigation controller can store.
static size_t max_entry_count_;
+ // If a repost is pending, its type (RELOAD or RELOAD_IGNORING_CACHE),
+ // NO_RELOAD otherwise.
+ ReloadType pending_reload_;
+
DISALLOW_COPY_AND_ASSIGN(NavigationController);
};
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 0034769..368cb2a 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -297,6 +297,7 @@
'browser/process_singleton_linux_uitest.cc',
'browser/process_singleton_win_uitest.cc',
'browser/renderer_host/resource_dispatcher_host_uitest.cc',
+ 'browser/repost_form_warning_uitest.cc',
'browser/sanity_uitest.cc',
'browser/session_history_uitest.cc',
'browser/sessions/session_restore_uitest.cc',
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 40211d5..b379f8a 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -885,6 +885,10 @@ class NotificationType {
LOGIN_AUTHENTICATION,
#endif
+ // Sent before a page is reloaded or the repost form warning is brought up.
+ // The source is a NavigationController.
+ RELOADING,
+
// Count (must be last) ----------------------------------------------------
// Used to determine the number of notification types. Not valid as
// a type parameter when registering for or posting notifications.
diff --git a/chrome/test/data/form.html b/chrome/test/data/form.html
new file mode 100644
index 0000000..5e98542
--- /dev/null
+++ b/chrome/test/data/form.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+</head>
+<body>
+<!-- A form leading to an empty page. The form is submitted via javascript, so
+ we don't need a submit button. -->
+<form id="form" action="/moose" method="post"></form>
+</body> \ No newline at end of file