Commit 2e5b90c3 authored by avi@chromium.org's avatar avi@chromium.org

Fix handling of tab contents disappearing out from underneath Javascript dialogs.

BUG=93094, 90196
TEST=as in bug 93094

Review URL: http://codereview.chromium.org/7661029

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97023 0039d316-1c4b-4281-b951-d872f2087c98
parent 3f0e79e9
......@@ -20,7 +20,7 @@ class AppModalDialogQueue {
// Returns the singleton instance.
static AppModalDialogQueue* GetInstance();
// Adds a modal dialog to the queue, if there are no other dialogs in the
// Adds a modal dialog to the queue. If there are no other dialogs in the
// queue, the dialog will be shown immediately. Once it is shown, the
// most recently active browser window (or whichever is currently active)
// will be app modal, meaning it will be activated if the user tries to
......@@ -56,7 +56,8 @@ class AppModalDialogQueue {
return active_dialog_;
}
// Iterators to walk the queue.
// Iterators to walk the queue. The queue does not include the currently
// active app modal dialog box.
typedef std::deque<AppModalDialog*>::iterator iterator;
iterator begin() {
return app_modal_dialog_queue_.begin();
......@@ -81,8 +82,8 @@ class AppModalDialogQueue {
// are not valid.
AppModalDialog* GetNextDialog();
// Contains all app modal dialogs which are waiting to be shown, with the
// currently modal dialog at the front of the queue.
// Contains all app modal dialogs which are waiting to be shown. The currently
// active modal dialog is not included.
std::deque<AppModalDialog*> app_modal_dialog_queue_;
// The currently active app-modal dialog box's delegate. NULL if there is no
......
......@@ -174,6 +174,9 @@ string16 ChromeJavaScriptDialogCreator::GetTitle(TitleType title_type,
void ChromeJavaScriptDialogCreator::CancelPendingDialogs(
content::DialogDelegate* delegate) {
AppModalDialogQueue* queue = AppModalDialogQueue::GetInstance();
AppModalDialog* active_dialog = queue->active_dialog();
if (active_dialog && active_dialog->delegate() == delegate)
active_dialog->Invalidate();
for (AppModalDialogQueue::iterator i = queue->begin();
i != queue->end(); ++i) {
if ((*i)->delegate() == delegate)
......
......@@ -184,6 +184,7 @@ TabContents::TabContents(content::BrowserContext* browser_context,
capturing_contents_(false),
is_being_destroyed_(false),
notify_disconnection_(false),
dialog_creator_(NULL),
#if defined(OS_WIN)
message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)),
#endif
......@@ -209,8 +210,8 @@ TabContents::~TabContents() {
is_being_destroyed_ = true;
// Clear out any JavaScript state.
if (delegate_)
delegate_->GetJavaScriptDialogCreator()->ResetJavaScriptState(this);
if (dialog_creator_)
dialog_creator_->ResetJavaScriptState(this);
NotifyDisconnected();
......@@ -1222,8 +1223,10 @@ void TabContents::DidNavigateAnyFramePostCommit(
// If we navigate, reset JavaScript state. This does nothing to prevent
// a malicious script from spamming messages, since the script could just
// reload the page to stop blocking.
if (delegate_)
delegate_->GetJavaScriptDialogCreator()->ResetJavaScriptState(this);
if (dialog_creator_) {
dialog_creator_->ResetJavaScriptState(this);
dialog_creator_ = NULL;
}
// Notify observers about navigation.
FOR_EACH_OBSERVER(TabContentsObserver, observers_,
......@@ -1690,15 +1693,15 @@ void TabContents::RunJavaScriptMessage(
content::GetContentClient()->browser()->GetAcceptLangs(this));
}
delegate_->GetJavaScriptDialogCreator()->RunJavaScriptDialog(
this,
title_type,
title,
flags,
message,
default_prompt,
reply_msg,
&suppress_this_message);
dialog_creator_ = delegate_->GetJavaScriptDialogCreator();
dialog_creator_->RunJavaScriptDialog(this,
title_type,
title,
flags,
message,
default_prompt,
reply_msg,
&suppress_this_message);
}
if (suppress_this_message) {
......@@ -1726,10 +1729,10 @@ void TabContents::RunBeforeUnloadConfirm(const RenderViewHost* rvh,
}
is_showing_before_unload_dialog_ = true;
delegate_->GetJavaScriptDialogCreator()->RunBeforeUnloadDialog(
this,
message,
reply_msg);
dialog_creator_ = delegate_->GetJavaScriptDialogCreator();
dialog_creator_->RunBeforeUnloadDialog(this,
message,
reply_msg);
}
WebPreferences TabContents::GetWebkitPrefs() {
......
......@@ -823,6 +823,10 @@ class TabContents : public PageNavigator,
// once.
bool notify_disconnection_;
// Pointer to the JavaScript dialog creator, lazily assigned. Used because the
// delegate of this TabContents is nulled before its destructor is called.
content::JavaScriptDialogCreator* dialog_creator_;
#if defined(OS_WIN)
// Handle to an event that's set when the page is showing a message box (or
// equivalent constrained window). Plugin processes check this to know if
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment