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/common/content_client.h"
14 #include "mojo/public/js/bindings/constants.h"
15 #include "ui/base/webui/jstemplate_builder.h"
16 #include "ui/base/webui/web_ui_util.h"
21 WebUIDataSource
* WebUIDataSource::Create(const std::string
& source_name
) {
22 return new WebUIDataSourceImpl(source_name
);
26 WebUIDataSource
* WebUIDataSource::AddMojoDataSource(
27 BrowserContext
* browser_context
) {
28 WebUIDataSource
* mojo_source
= Create("mojo");
34 { mojo::kBufferModuleName
, IDR_MOJO_BUFFER_JS
},
35 { mojo::kCodecModuleName
, IDR_MOJO_CODEC_JS
},
36 { mojo::kConnectionModuleName
, IDR_MOJO_CONNECTION_JS
},
37 { mojo::kConnectorModuleName
, IDR_MOJO_CONNECTOR_JS
},
38 { mojo::kRouterModuleName
, IDR_MOJO_ROUTER_JS
},
39 { mojo::kUnicodeModuleName
, IDR_MOJO_UNICODE_JS
},
40 { mojo::kValidatorModuleName
, IDR_MOJO_VALIDATOR_JS
},
42 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(resources
); ++i
)
43 mojo_source
->AddResourcePath(resources
[i
].path
, resources
[i
].id
);
45 URLDataManager::AddWebUIDataSource(browser_context
, mojo_source
);
50 void WebUIDataSource::Add(BrowserContext
* browser_context
,
51 WebUIDataSource
* source
) {
52 URLDataManager::AddWebUIDataSource(browser_context
, source
);
55 // Internal class to hide the fact that WebUIDataSourceImpl implements
57 class WebUIDataSourceImpl::InternalDataSource
: public URLDataSource
{
59 InternalDataSource(WebUIDataSourceImpl
* parent
) : parent_(parent
) {
62 virtual ~InternalDataSource() {
65 // URLDataSource implementation.
66 virtual std::string
GetSource() const OVERRIDE
{
67 return parent_
->GetSource();
69 virtual std::string
GetMimeType(const std::string
& path
) const OVERRIDE
{
70 return parent_
->GetMimeType(path
);
72 virtual void StartDataRequest(
73 const std::string
& path
,
74 int render_process_id
,
76 const URLDataSource::GotDataCallback
& callback
) OVERRIDE
{
77 return parent_
->StartDataRequest(path
, render_process_id
, render_frame_id
,
80 virtual bool ShouldReplaceExistingSource() const OVERRIDE
{
81 return parent_
->replace_existing_source_
;
83 virtual bool AllowCaching() const OVERRIDE
{
86 virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE
{
87 return parent_
->add_csp_
;
89 virtual std::string
GetContentSecurityPolicyObjectSrc() const OVERRIDE
{
90 if (parent_
->object_src_set_
)
91 return parent_
->object_src_
;
92 return URLDataSource::GetContentSecurityPolicyObjectSrc();
94 virtual std::string
GetContentSecurityPolicyFrameSrc() const OVERRIDE
{
95 if (parent_
->frame_src_set_
)
96 return parent_
->frame_src_
;
97 return URLDataSource::GetContentSecurityPolicyFrameSrc();
99 virtual bool ShouldDenyXFrameOptions() const OVERRIDE
{
100 return parent_
->deny_xframe_options_
;
104 WebUIDataSourceImpl
* parent_
;
107 WebUIDataSourceImpl::WebUIDataSourceImpl(const std::string
& source_name
)
110 new InternalDataSource(this)),
111 source_name_(source_name
),
112 default_resource_(-1),
113 json_js_format_v2_(false),
115 object_src_set_(false),
116 frame_src_set_(false),
117 deny_xframe_options_(true),
118 disable_set_font_strings_(false),
119 replace_existing_source_(true) {
122 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
125 void WebUIDataSourceImpl::AddString(const std::string
& name
,
126 const base::string16
& value
) {
127 localized_strings_
.SetString(name
, value
);
130 void WebUIDataSourceImpl::AddString(const std::string
& name
,
131 const std::string
& value
) {
132 localized_strings_
.SetString(name
, value
);
135 void WebUIDataSourceImpl::AddLocalizedString(const std::string
& name
,
137 localized_strings_
.SetString(
138 name
, GetContentClient()->GetLocalizedString(ids
));
141 void WebUIDataSourceImpl::AddLocalizedStrings(
142 const base::DictionaryValue
& localized_strings
) {
143 localized_strings_
.MergeDictionary(&localized_strings
);
146 void WebUIDataSourceImpl::AddBoolean(const std::string
& name
, bool value
) {
147 localized_strings_
.SetBoolean(name
, value
);
150 void WebUIDataSourceImpl::SetJsonPath(const std::string
& path
) {
154 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() {
155 json_js_format_v2_
= true;
158 void WebUIDataSourceImpl::AddResourcePath(const std::string
&path
,
160 path_to_idr_map_
[path
] = resource_id
;
163 void WebUIDataSourceImpl::SetDefaultResource(int resource_id
) {
164 default_resource_
= resource_id
;
167 void WebUIDataSourceImpl::SetRequestFilter(
168 const WebUIDataSource::HandleRequestCallback
& callback
) {
169 filter_callback_
= callback
;
172 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
173 replace_existing_source_
= false;
176 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
180 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
181 const std::string
& data
) {
182 object_src_set_
= true;
186 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
187 const std::string
& data
) {
188 frame_src_set_
= true;
192 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
193 deny_xframe_options_
= false;
196 std::string
WebUIDataSourceImpl::GetSource() const {
200 std::string
WebUIDataSourceImpl::GetMimeType(const std::string
& path
) const {
201 if (EndsWith(path
, ".js", false))
202 return "application/javascript";
204 if (EndsWith(path
, ".json", false))
205 return "application/json";
207 if (EndsWith(path
, ".pdf", false))
208 return "application/pdf";
210 if (EndsWith(path
, ".svg", false))
211 return "image/svg+xml";
216 void WebUIDataSourceImpl::StartDataRequest(
217 const std::string
& path
,
218 int render_process_id
,
220 const URLDataSource::GotDataCallback
& callback
) {
221 if (!filter_callback_
.is_null() &&
222 filter_callback_
.Run(path
, callback
)) {
226 if (!json_path_
.empty() && path
== json_path_
) {
227 SendLocalizedStringsAsJSON(callback
);
231 int resource_id
= default_resource_
;
232 std::map
<std::string
, int>::iterator result
;
233 result
= path_to_idr_map_
.find(path
);
234 if (result
!= path_to_idr_map_
.end())
235 resource_id
= result
->second
;
236 DCHECK_NE(resource_id
, -1);
237 SendFromResourceBundle(callback
, resource_id
);
240 void WebUIDataSourceImpl::SendLocalizedStringsAsJSON(
241 const URLDataSource::GotDataCallback
& callback
) {
242 std::string template_data
;
243 if (!disable_set_font_strings_
)
244 webui::SetFontAndTextDirection(&localized_strings_
);
246 scoped_ptr
<webui::UseVersion2
> version2
;
247 if (json_js_format_v2_
)
248 version2
.reset(new webui::UseVersion2
);
250 webui::AppendJsonJS(&localized_strings_
, &template_data
);
251 callback
.Run(base::RefCountedString::TakeString(&template_data
));
254 void WebUIDataSourceImpl::SendFromResourceBundle(
255 const URLDataSource::GotDataCallback
& callback
, int idr
) {
256 scoped_refptr
<base::RefCountedStaticMemory
> response(
257 GetContentClient()->GetDataResourceBytes(idr
));
258 callback
.Run(response
.get());
261 } // namespace content