forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
web_dialog_ui.cc
143 lines (115 loc) · 4.98 KB
/
web_dialog_ui.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Copyright (c) 2012 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 "ui/web_dialogs/web_dialog_ui.h"
#include "base/bind.h"
#include "base/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_; // unowned
};
} // namespace
// static
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) {}
// Don't unregister our user data. During the teardown of the WebContents, this
// will be deleted, but the WebContents will already be destroyed.
//
// This object is owned indirectly by the WebContents. WebUIs can change, so
// it's scary if this WebUI is changed out and replaced with something else,
// since the user data will still point to the old delegate. But the delegate is
// itself the owner of the WebContents for a dialog so will be in scope, and the
// HTML dialogs won't swap WebUIs anyway since they don't navigate.
WebDialogUIBase::~WebDialogUIBase() = default;
void WebDialogUIBase::CloseDialog(const base::ListValue* 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) {
// Hook up the javascript function calls, also known as chrome.send("foo")
// calls in the HTML, to the actual C++ functions.
web_ui_->RegisterDeprecatedMessageCallback(
"dialogClose", base::BindRepeating(&WebDialogUIBase::OnDialogClosed,
base::Unretained(this)));
// Pass the arguments to the renderer supplied by the delegate.
std::string dialog_args;
std::vector<WebUIMessageHandler*> handlers;
WebDialogDelegate* delegate = GetDelegate(web_ui_->GetWebContents());
if (delegate) {
dialog_args = delegate->GetDialogArgs();
delegate->GetWebUIMessageHandlers(&handlers);
}
if (content::BINDINGS_POLICY_NONE !=
(web_ui_->GetBindings() & content::BINDINGS_POLICY_WEB_UI)) {
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::ListValue* args) {
WebDialogDelegate* delegate = GetDelegate(web_ui_->GetWebContents());
if (delegate) {
std::string json_retval;
if (args && !args->GetList().empty()) {
if (args->GetList()[0].is_string())
json_retval = args->GetList()[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) {
HandleRenderFrameCreated(render_frame_host);
}
// Note: chrome.send() must always be enabled for dialogs, since dialogs rely on
// chrome.send() to notify their handlers that the dialog should be closed. See
// the "dialogClose" message handler above in
// WebDialogUIBase::HandleRenderFrameCreated().
MojoWebDialogUI::MojoWebDialogUI(content::WebUI* web_ui)
: WebDialogUIBase(web_ui),
MojoWebUIController(web_ui, /*enable_chrome_send=*/true) {}
MojoWebDialogUI::~MojoWebDialogUI() = default;
void MojoWebDialogUI::WebUIRenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
content::WebUIController::WebUIRenderFrameCreated(render_frame_host);
HandleRenderFrameCreated(render_frame_host);
}
} // namespace ui