#include "ui/web_dialogs/web_dialog_ui.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/values.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "content/public/common/bindings_policy.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
using content::RenderFrameHost;
using content::WebUIMessageHandler;
namespace ui {
namespace {
const char kWebDialogDelegateUserDataKey[] = "WebDialogDelegateUserData";
class WebDialogDelegateUserData : public base::SupportsUserData::Data {
public:
explicit WebDialogDelegateUserData(WebDialogDelegate* delegate)
: delegate_(delegate) {}
~WebDialogDelegateUserData() override {}
WebDialogDelegate* delegate() { return delegate_; }
private:
raw_ptr<WebDialogDelegate> delegate_;
};
}
void WebDialogUIBase::SetDelegate(content::WebContents* web_contents,
WebDialogDelegate* delegate) {
web_contents->SetUserData(
&kWebDialogDelegateUserDataKey,
std::make_unique<WebDialogDelegateUserData>(delegate));
}
WebDialogUIBase::WebDialogUIBase(content::WebUI* web_ui) : web_ui_(web_ui) {}
WebDialogUIBase::~WebDialogUIBase() = default;
void WebDialogUIBase::CloseDialog(const base::Value::List& args) {
OnDialogClosed(args);
}
WebDialogDelegate* WebDialogUIBase::GetDelegate(
content::WebContents* web_contents) {
WebDialogDelegateUserData* user_data =
static_cast<WebDialogDelegateUserData*>(
web_contents->GetUserData(&kWebDialogDelegateUserDataKey));
return user_data ? user_data->delegate() : NULL;
}
void WebDialogUIBase::HandleRenderFrameCreated(
RenderFrameHost* render_frame_host) {
web_ui_->RegisterMessageCallback(
"dialogClose", base::BindRepeating(&WebDialogUIBase::OnDialogClosed,
base::Unretained(this)));
std::string dialog_args;
std::vector<WebUIMessageHandler*> handlers;
WebDialogDelegate* delegate = GetDelegate(web_ui_->GetWebContents());
if (delegate) {
dialog_args = delegate->GetDialogArgs();
delegate->GetWebUIMessageHandlers(&handlers);
}
if (web_ui_->GetBindings().Has(content::BindingsPolicyValue::kWebUi)) {
render_frame_host->SetWebUIProperty("dialogArguments", dialog_args);
}
for (WebUIMessageHandler* handler : handlers) {
web_ui_->AddMessageHandler(base::WrapUnique(handler));
}
if (delegate) {
delegate->OnDialogShown(web_ui_);
}
}
void WebDialogUIBase::OnDialogClosed(const base::Value::List& args) {
WebDialogDelegate* delegate = GetDelegate(web_ui_->GetWebContents());
if (delegate) {
std::string json_retval;
if (!args.empty()) {
if (args[0].is_string()) {
json_retval = args[0].GetString();
} else {
NOTREACHED() << "Could not read JSON argument";
}
}
delegate->OnDialogCloseFromWebUI(json_retval);
}
}
WebDialogUI::WebDialogUI(content::WebUI* web_ui)
: WebDialogUIBase(web_ui), content::WebUIController(web_ui) {}
WebDialogUI::~WebDialogUI() = default;
void WebDialogUI::WebUIRenderFrameCreated(RenderFrameHost* render_frame_host) {
content::WebUIController::WebUIRenderFrameCreated(render_frame_host);
HandleRenderFrameCreated(render_frame_host);
}
MojoWebDialogUI::MojoWebDialogUI(content::WebUI* web_ui)
: WebDialogUI(web_ui),
ui::EnableMojoWebUI(web_ui, true) {}
MojoWebDialogUI::~MojoWebDialogUI() = default;
void MojoWebDialogUI::WebUIRenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
WebDialogUI::WebUIRenderFrameCreated(render_frame_host);
}
}