blob: 96b6cc8f0c4e04132e8d1cb81ff0853b7e2b2d69 [file]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/javascript_dialogs/app_modal_dialog_queue.h"
#include "base/no_destructor.h"
#include "components/javascript_dialogs/app_modal_dialog_controller.h"
namespace javascript_dialogs {
// static
AppModalDialogQueue* AppModalDialogQueue::GetInstance() {
static base::NoDestructor<AppModalDialogQueue> instance;
return instance.get();
}
void AppModalDialogQueue::CancelAllDialogs() {
shutting_down_ = true;
InvalidateAndClearQueuedDialogs();
}
void AppModalDialogQueue::ResetForTesting() {
active_dialog_ = nullptr;
shutting_down_ = false;
InvalidateAndClearQueuedDialogs();
}
void AppModalDialogQueue::InvalidateAndClearQueuedDialogs() {
while (!app_modal_dialog_queue_.empty()) {
app_modal_dialog_queue_.front()->Invalidate();
app_modal_dialog_queue_.pop_front();
}
}
void AppModalDialogQueue::AddDialog(
std::unique_ptr<AppModalDialogController> dialog) {
if (shutting_down_) {
dialog->Invalidate();
return;
}
if (!active_dialog_) {
ShowModalDialog(std::move(dialog));
return;
}
app_modal_dialog_queue_.push_back(std::move(dialog));
}
void AppModalDialogQueue::ShowNextDialog() {
if (shutting_down_) {
active_dialog_ = nullptr;
InvalidateAndClearQueuedDialogs();
return;
}
std::unique_ptr<AppModalDialogController> dialog = GetNextDialog();
if (dialog) {
ShowModalDialog(std::move(dialog));
} else {
active_dialog_ = nullptr;
}
}
void AppModalDialogQueue::ActivateModalDialog() {
if (showing_modal_dialog_) {
// As part of showing a modal dialog we may end up back in this method
// (showing a dialog activates the WebContents, which can trigger a call
// to ActivateModalDialog). We ignore such a request as after the call to
// activate the tab contents the dialog is shown.
return;
}
if (active_dialog_) {
active_dialog_->ActivateModalDialog();
}
}
bool AppModalDialogQueue::HasActiveDialog() const {
return !!active_dialog_;
}
AppModalDialogQueue::AppModalDialogQueue() = default;
AppModalDialogQueue::~AppModalDialogQueue() = default;
void AppModalDialogQueue::ShowModalDialog(
std::unique_ptr<AppModalDialogController> dialog) {
// Be sure and set the active_dialog_ field first, otherwise if
// ShowModalDialog triggers a call back to the queue they'll get the old
// dialog. Also, if the dialog calls `ShowNextDialog()` before returning, that
// would write nullptr into `active_dialog_` and this function would then undo
// that.
active_dialog_ = dialog.get();
showing_modal_dialog_ = true;
active_dialog_->ShowModalDialog(std::move(dialog));
showing_modal_dialog_ = false;
}
std::unique_ptr<AppModalDialogController> AppModalDialogQueue::GetNextDialog() {
while (!app_modal_dialog_queue_.empty()) {
std::unique_ptr<AppModalDialogController> dialog =
std::move(app_modal_dialog_queue_.front());
app_modal_dialog_queue_.pop_front();
if (dialog->IsValid()) {
return dialog;
}
}
return nullptr;
}
} // namespace javascript_dialogs