1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/webui/web_ui_impl.h"
7 #include "base/json/json_writer.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "content/browser/child_process_security_policy_impl.h"
11 #include "content/browser/renderer_host/dip_util.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/web_contents/web_contents_impl.h"
15 #include "content/browser/webui/web_ui_controller_factory_registry.h"
16 #include "content/common/view_messages.h"
17 #include "content/public/browser/content_browser_client.h"
18 #include "content/public/browser/web_contents_delegate.h"
19 #include "content/public/browser/web_contents_view.h"
20 #include "content/public/browser/web_ui_controller.h"
21 #include "content/public/browser/web_ui_message_handler.h"
22 #include "content/public/common/bindings_policy.h"
23 #include "content/public/common/content_client.h"
27 const WebUI::TypeID
WebUI::kNoWebUI
= NULL
;
30 base::string16
WebUI::GetJavascriptCall(
31 const std::string
& function_name
,
32 const std::vector
<const base::Value
*>& arg_list
) {
33 base::string16 parameters
;
35 for (size_t i
= 0; i
< arg_list
.size(); ++i
) {
37 parameters
+= base::char16(',');
39 base::JSONWriter::Write(arg_list
[i
], &json
);
40 parameters
+= base::UTF8ToUTF16(json
);
42 return base::ASCIIToUTF16(function_name
) +
43 base::char16('(') + parameters
+ base::char16(')') + base::char16(';');
46 WebUIImpl::WebUIImpl(WebContents
* contents
)
47 : link_transition_type_(PAGE_TRANSITION_LINK
),
48 bindings_(BINDINGS_POLICY_WEB_UI
),
49 web_contents_(contents
) {
53 WebUIImpl::~WebUIImpl() {
54 // Delete the controller first, since it may also be keeping a pointer to some
55 // of the handlers and can call them at destruction.
59 // WebUIImpl, public: ----------------------------------------------------------
61 bool WebUIImpl::OnMessageReceived(const IPC::Message
& message
) {
63 IPC_BEGIN_MESSAGE_MAP(WebUIImpl
, message
)
64 IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend
, OnWebUISend
)
65 IPC_MESSAGE_UNHANDLED(handled
= false)
70 void WebUIImpl::OnWebUISend(const GURL
& source_url
,
71 const std::string
& message
,
72 const base::ListValue
& args
) {
73 WebContentsDelegate
* delegate
= web_contents_
->GetDelegate();
74 bool data_urls_allowed
= delegate
&& delegate
->CanLoadDataURLsInWebUI();
75 if (!ChildProcessSecurityPolicyImpl::GetInstance()->
76 HasWebUIBindings(web_contents_
->GetRenderProcessHost()->GetID()) ||
77 !WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
78 web_contents_
->GetBrowserContext(), source_url
, data_urls_allowed
)) {
79 NOTREACHED() << "Blocked unauthorized use of WebUIBindings.";
83 ProcessWebUIMessage(source_url
, message
, args
);
86 void WebUIImpl::RenderViewCreated(RenderViewHost
* render_view_host
) {
87 controller_
->RenderViewCreated(render_view_host
);
89 // Do not attempt to set the toolkit property if WebUI is not enabled, e.g.,
90 // the bookmarks manager page.
91 if (!(bindings_
& BINDINGS_POLICY_WEB_UI
))
94 #if defined(TOOLKIT_VIEWS)
95 render_view_host
->SetWebUIProperty("toolkit", "views");
96 #elif defined(TOOLKIT_GTK)
97 render_view_host
->SetWebUIProperty("toolkit", "GTK");
98 #endif // defined(TOOLKIT_VIEWS)
101 WebContents
* WebUIImpl::GetWebContents() const {
102 return web_contents_
;
105 ui::ScaleFactor
WebUIImpl::GetDeviceScaleFactor() const {
106 return GetScaleFactorForView(web_contents_
->GetRenderWidgetHostView());
109 const base::string16
& WebUIImpl::GetOverriddenTitle() const {
110 return overridden_title_
;
113 void WebUIImpl::OverrideTitle(const base::string16
& title
) {
114 overridden_title_
= title
;
117 PageTransition
WebUIImpl::GetLinkTransitionType() const {
118 return link_transition_type_
;
121 void WebUIImpl::SetLinkTransitionType(PageTransition type
) {
122 link_transition_type_
= type
;
125 int WebUIImpl::GetBindings() const {
129 void WebUIImpl::SetBindings(int bindings
) {
130 bindings_
= bindings
;
133 void WebUIImpl::SetFrameXPath(const std::string
& xpath
) {
134 frame_xpath_
= xpath
;
137 WebUIController
* WebUIImpl::GetController() const {
138 return controller_
.get();
141 void WebUIImpl::SetController(WebUIController
* controller
) {
142 controller_
.reset(controller
);
145 void WebUIImpl::CallJavascriptFunction(const std::string
& function_name
) {
146 DCHECK(IsStringASCII(function_name
));
147 base::string16 javascript
= base::ASCIIToUTF16(function_name
+ "();");
148 ExecuteJavascript(javascript
);
151 void WebUIImpl::CallJavascriptFunction(const std::string
& function_name
,
152 const base::Value
& arg
) {
153 DCHECK(IsStringASCII(function_name
));
154 std::vector
<const base::Value
*> args
;
155 args
.push_back(&arg
);
156 ExecuteJavascript(GetJavascriptCall(function_name
, args
));
159 void WebUIImpl::CallJavascriptFunction(
160 const std::string
& function_name
,
161 const base::Value
& arg1
, const base::Value
& arg2
) {
162 DCHECK(IsStringASCII(function_name
));
163 std::vector
<const base::Value
*> args
;
164 args
.push_back(&arg1
);
165 args
.push_back(&arg2
);
166 ExecuteJavascript(GetJavascriptCall(function_name
, args
));
169 void WebUIImpl::CallJavascriptFunction(
170 const std::string
& function_name
,
171 const base::Value
& arg1
, const base::Value
& arg2
, const base::Value
& arg3
) {
172 DCHECK(IsStringASCII(function_name
));
173 std::vector
<const base::Value
*> args
;
174 args
.push_back(&arg1
);
175 args
.push_back(&arg2
);
176 args
.push_back(&arg3
);
177 ExecuteJavascript(GetJavascriptCall(function_name
, args
));
180 void WebUIImpl::CallJavascriptFunction(
181 const std::string
& function_name
,
182 const base::Value
& arg1
,
183 const base::Value
& arg2
,
184 const base::Value
& arg3
,
185 const base::Value
& arg4
) {
186 DCHECK(IsStringASCII(function_name
));
187 std::vector
<const base::Value
*> args
;
188 args
.push_back(&arg1
);
189 args
.push_back(&arg2
);
190 args
.push_back(&arg3
);
191 args
.push_back(&arg4
);
192 ExecuteJavascript(GetJavascriptCall(function_name
, args
));
195 void WebUIImpl::CallJavascriptFunction(
196 const std::string
& function_name
,
197 const std::vector
<const base::Value
*>& args
) {
198 DCHECK(IsStringASCII(function_name
));
199 ExecuteJavascript(GetJavascriptCall(function_name
, args
));
202 void WebUIImpl::RegisterMessageCallback(const std::string
&message
,
203 const MessageCallback
& callback
) {
204 message_callbacks_
.insert(std::make_pair(message
, callback
));
207 void WebUIImpl::ProcessWebUIMessage(const GURL
& source_url
,
208 const std::string
& message
,
209 const base::ListValue
& args
) {
210 if (controller_
->OverrideHandleWebUIMessage(source_url
, message
, args
))
213 // Look up the callback for this message.
214 MessageCallbackMap::const_iterator callback
=
215 message_callbacks_
.find(message
);
216 if (callback
!= message_callbacks_
.end()) {
217 // Forward this message and content on.
218 callback
->second
.Run(&args
);
220 NOTREACHED() << "Unhandled chrome.send(\"" << message
<< "\");";
224 // WebUIImpl, protected: -------------------------------------------------------
226 void WebUIImpl::AddMessageHandler(WebUIMessageHandler
* handler
) {
227 DCHECK(!handler
->web_ui());
228 handler
->set_web_ui(this);
229 handler
->RegisterMessages();
230 handlers_
.push_back(handler
);
233 void WebUIImpl::ExecuteJavascript(const base::string16
& javascript
) {
234 static_cast<RenderViewHostImpl
*>(
235 web_contents_
->GetRenderViewHost())->ExecuteJavascriptInWebFrame(
236 base::ASCIIToUTF16(frame_xpath_
), javascript
);
239 } // namespace content