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_data_source_impl.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/strings/string_util.h"
12 #include "content/grit/content_resources.h"
13 #include "content/public/browser/content_browser_client.h"
14 #include "content/public/common/content_client.h"
15 #include "third_party/mojo/src/mojo/public/js/constants.h"
16 #include "ui/base/webui/jstemplate_builder.h"
17 #include "ui/base/webui/web_ui_util.h"
22 WebUIDataSource
* WebUIDataSource::Create(const std::string
& source_name
) {
23 return new WebUIDataSourceImpl(source_name
);
27 WebUIDataSource
* WebUIDataSource::AddMojoDataSource(
28 BrowserContext
* browser_context
) {
29 WebUIDataSource
* mojo_source
= Create("mojo");
35 { mojo::kBindingsModuleName
, IDR_MOJO_BINDINGS_JS
},
36 { mojo::kBufferModuleName
, IDR_MOJO_BUFFER_JS
},
37 { mojo::kCodecModuleName
, IDR_MOJO_CODEC_JS
},
38 { mojo::kConnectionModuleName
, IDR_MOJO_CONNECTION_JS
},
39 { mojo::kConnectorModuleName
, IDR_MOJO_CONNECTOR_JS
},
40 { mojo::kRouterModuleName
, IDR_MOJO_ROUTER_JS
},
41 { mojo::kUnicodeModuleName
, IDR_MOJO_UNICODE_JS
},
42 { mojo::kValidatorModuleName
, IDR_MOJO_VALIDATOR_JS
},
44 for (size_t i
= 0; i
< arraysize(resources
); ++i
)
45 mojo_source
->AddResourcePath(resources
[i
].path
, resources
[i
].id
);
47 URLDataManager::AddWebUIDataSource(browser_context
, mojo_source
);
52 void WebUIDataSource::Add(BrowserContext
* browser_context
,
53 WebUIDataSource
* source
) {
54 URLDataManager::AddWebUIDataSource(browser_context
, source
);
57 // Internal class to hide the fact that WebUIDataSourceImpl implements
59 class WebUIDataSourceImpl::InternalDataSource
: public URLDataSource
{
61 InternalDataSource(WebUIDataSourceImpl
* parent
) : parent_(parent
) {
64 ~InternalDataSource() override
{}
66 // URLDataSource implementation.
67 std::string
GetSource() const override
{ return parent_
->GetSource(); }
68 std::string
GetMimeType(const std::string
& path
) const override
{
69 return parent_
->GetMimeType(path
);
71 void StartDataRequest(
72 const std::string
& path
,
73 int render_process_id
,
75 const URLDataSource::GotDataCallback
& callback
) override
{
76 return parent_
->StartDataRequest(path
, render_process_id
, render_frame_id
,
79 bool ShouldReplaceExistingSource() const override
{
80 return parent_
->replace_existing_source_
;
82 bool AllowCaching() const override
{ return false; }
83 bool ShouldAddContentSecurityPolicy() const override
{
84 return parent_
->add_csp_
;
86 std::string
GetContentSecurityPolicyObjectSrc() const override
{
87 if (parent_
->object_src_set_
)
88 return parent_
->object_src_
;
89 return URLDataSource::GetContentSecurityPolicyObjectSrc();
91 std::string
GetContentSecurityPolicyFrameSrc() const override
{
92 if (parent_
->frame_src_set_
)
93 return parent_
->frame_src_
;
94 return URLDataSource::GetContentSecurityPolicyFrameSrc();
96 bool ShouldDenyXFrameOptions() const override
{
97 return parent_
->deny_xframe_options_
;
101 WebUIDataSourceImpl
* parent_
;
104 WebUIDataSourceImpl::WebUIDataSourceImpl(const std::string
& source_name
)
107 new InternalDataSource(this)),
108 source_name_(source_name
),
109 default_resource_(-1),
111 object_src_set_(false),
112 frame_src_set_(false),
113 deny_xframe_options_(true),
114 disable_set_font_strings_(false),
115 replace_existing_source_(true) {
118 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
121 void WebUIDataSourceImpl::AddString(const std::string
& name
,
122 const base::string16
& value
) {
123 localized_strings_
.SetString(name
, value
);
126 void WebUIDataSourceImpl::AddString(const std::string
& name
,
127 const std::string
& value
) {
128 localized_strings_
.SetString(name
, value
);
131 void WebUIDataSourceImpl::AddLocalizedString(const std::string
& name
,
133 localized_strings_
.SetString(
134 name
, GetContentClient()->GetLocalizedString(ids
));
137 void WebUIDataSourceImpl::AddLocalizedStrings(
138 const base::DictionaryValue
& localized_strings
) {
139 localized_strings_
.MergeDictionary(&localized_strings
);
142 void WebUIDataSourceImpl::AddBoolean(const std::string
& name
, bool value
) {
143 localized_strings_
.SetBoolean(name
, value
);
146 void WebUIDataSourceImpl::SetJsonPath(const std::string
& path
) {
150 void WebUIDataSourceImpl::AddResourcePath(const std::string
&path
,
152 path_to_idr_map_
[path
] = resource_id
;
155 void WebUIDataSourceImpl::SetDefaultResource(int resource_id
) {
156 default_resource_
= resource_id
;
159 void WebUIDataSourceImpl::SetRequestFilter(
160 const WebUIDataSource::HandleRequestCallback
& callback
) {
161 filter_callback_
= callback
;
164 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
165 replace_existing_source_
= false;
168 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
172 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
173 const std::string
& data
) {
174 object_src_set_
= true;
178 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
179 const std::string
& data
) {
180 frame_src_set_
= true;
184 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
185 deny_xframe_options_
= false;
188 std::string
WebUIDataSourceImpl::GetSource() const {
192 std::string
WebUIDataSourceImpl::GetMimeType(const std::string
& path
) const {
193 if (base::EndsWith(path
, ".css", base::CompareCase::INSENSITIVE_ASCII
))
196 if (base::EndsWith(path
, ".js", base::CompareCase::INSENSITIVE_ASCII
))
197 return "application/javascript";
199 if (base::EndsWith(path
, ".json", base::CompareCase::INSENSITIVE_ASCII
))
200 return "application/json";
202 if (base::EndsWith(path
, ".pdf", base::CompareCase::INSENSITIVE_ASCII
))
203 return "application/pdf";
205 if (base::EndsWith(path
, ".svg", base::CompareCase::INSENSITIVE_ASCII
))
206 return "image/svg+xml";
211 void WebUIDataSourceImpl::StartDataRequest(
212 const std::string
& path
,
213 int render_process_id
,
215 const URLDataSource::GotDataCallback
& callback
) {
216 if (!filter_callback_
.is_null() &&
217 filter_callback_
.Run(path
, callback
)) {
221 if (!json_path_
.empty() && path
== json_path_
) {
222 SendLocalizedStringsAsJSON(callback
);
226 int resource_id
= default_resource_
;
227 std::map
<std::string
, int>::iterator result
;
228 result
= path_to_idr_map_
.find(path
);
229 if (result
!= path_to_idr_map_
.end())
230 resource_id
= result
->second
;
231 DCHECK_NE(resource_id
, -1);
232 SendFromResourceBundle(callback
, resource_id
);
235 void WebUIDataSourceImpl::SendLocalizedStringsAsJSON(
236 const URLDataSource::GotDataCallback
& callback
) {
237 std::string template_data
;
238 if (!disable_set_font_strings_
) {
239 std::string locale
= GetContentClient()->browser()->GetApplicationLocale();
240 webui::SetLoadTimeDataDefaults(locale
, &localized_strings_
);
243 webui::AppendJsonJS(&localized_strings_
, &template_data
);
244 callback
.Run(base::RefCountedString::TakeString(&template_data
));
247 void WebUIDataSourceImpl::SendFromResourceBundle(
248 const URLDataSource::GotDataCallback
& callback
, int idr
) {
249 scoped_refptr
<base::RefCountedStaticMemory
> response(
250 GetContentClient()->GetDataResourceBytes(idr
));
251 callback
.Run(response
.get());
254 } // namespace content