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/public/common/content_client.h"
13 #include "grit/content_resources.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::kCodecModuleName
, IDR_MOJO_CODEC_JS
},
35 { mojo::kConnectionModuleName
, IDR_MOJO_CONNECTION_JS
},
36 { mojo::kConnectorModuleName
, IDR_MOJO_CONNECTOR_JS
},
37 { mojo::kRouterModuleName
, IDR_MOJO_ROUTER_JS
},
39 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(resources
); ++i
)
40 mojo_source
->AddResourcePath(resources
[i
].path
, resources
[i
].id
);
42 URLDataManager::AddWebUIDataSource(browser_context
, mojo_source
);
47 void WebUIDataSource::Add(BrowserContext
* browser_context
,
48 WebUIDataSource
* source
) {
49 URLDataManager::AddWebUIDataSource(browser_context
, source
);
52 // Internal class to hide the fact that WebUIDataSourceImpl implements
54 class WebUIDataSourceImpl::InternalDataSource
: public URLDataSource
{
56 InternalDataSource(WebUIDataSourceImpl
* parent
) : parent_(parent
) {
59 virtual ~InternalDataSource() {
62 // URLDataSource implementation.
63 virtual std::string
GetSource() const OVERRIDE
{
64 return parent_
->GetSource();
66 virtual std::string
GetMimeType(const std::string
& path
) const OVERRIDE
{
67 return parent_
->GetMimeType(path
);
69 virtual void StartDataRequest(
70 const std::string
& path
,
71 int render_process_id
,
73 const URLDataSource::GotDataCallback
& callback
) OVERRIDE
{
74 return parent_
->StartDataRequest(path
, render_process_id
, render_frame_id
,
77 virtual bool ShouldReplaceExistingSource() const OVERRIDE
{
78 return parent_
->replace_existing_source_
;
80 virtual bool AllowCaching() const OVERRIDE
{
83 virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE
{
84 return parent_
->add_csp_
;
86 virtual std::string
GetContentSecurityPolicyObjectSrc() const OVERRIDE
{
87 if (parent_
->object_src_set_
)
88 return parent_
->object_src_
;
89 return URLDataSource::GetContentSecurityPolicyObjectSrc();
91 virtual std::string
GetContentSecurityPolicyFrameSrc() const OVERRIDE
{
92 if (parent_
->frame_src_set_
)
93 return parent_
->frame_src_
;
94 return URLDataSource::GetContentSecurityPolicyFrameSrc();
96 virtual 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),
110 json_js_format_v2_(false),
112 object_src_set_(false),
113 frame_src_set_(false),
114 deny_xframe_options_(true),
115 disable_set_font_strings_(false),
116 replace_existing_source_(true) {
119 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
122 void WebUIDataSourceImpl::AddString(const std::string
& name
,
123 const base::string16
& value
) {
124 localized_strings_
.SetString(name
, value
);
127 void WebUIDataSourceImpl::AddString(const std::string
& name
,
128 const std::string
& value
) {
129 localized_strings_
.SetString(name
, value
);
132 void WebUIDataSourceImpl::AddLocalizedString(const std::string
& name
,
134 localized_strings_
.SetString(
135 name
, GetContentClient()->GetLocalizedString(ids
));
138 void WebUIDataSourceImpl::AddLocalizedStrings(
139 const base::DictionaryValue
& localized_strings
) {
140 localized_strings_
.MergeDictionary(&localized_strings
);
143 void WebUIDataSourceImpl::AddBoolean(const std::string
& name
, bool value
) {
144 localized_strings_
.SetBoolean(name
, value
);
147 void WebUIDataSourceImpl::SetJsonPath(const std::string
& path
) {
151 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() {
152 json_js_format_v2_
= true;
155 void WebUIDataSourceImpl::AddResourcePath(const std::string
&path
,
157 path_to_idr_map_
[path
] = resource_id
;
160 void WebUIDataSourceImpl::SetDefaultResource(int resource_id
) {
161 default_resource_
= resource_id
;
164 void WebUIDataSourceImpl::SetRequestFilter(
165 const WebUIDataSource::HandleRequestCallback
& callback
) {
166 filter_callback_
= callback
;
169 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
170 replace_existing_source_
= false;
173 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
177 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
178 const std::string
& data
) {
179 object_src_set_
= true;
183 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
184 const std::string
& data
) {
185 frame_src_set_
= true;
189 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
190 deny_xframe_options_
= false;
193 std::string
WebUIDataSourceImpl::GetSource() const {
197 std::string
WebUIDataSourceImpl::GetMimeType(const std::string
& path
) const {
198 if (EndsWith(path
, ".js", false))
199 return "application/javascript";
201 if (EndsWith(path
, ".json", false))
202 return "application/json";
204 if (EndsWith(path
, ".pdf", false))
205 return "application/pdf";
207 if (EndsWith(path
, ".svg", false))
208 return "image/svg+xml";
213 void WebUIDataSourceImpl::StartDataRequest(
214 const std::string
& path
,
215 int render_process_id
,
217 const URLDataSource::GotDataCallback
& callback
) {
218 if (!filter_callback_
.is_null() &&
219 filter_callback_
.Run(path
, callback
)) {
223 if (!json_path_
.empty() && path
== json_path_
) {
224 SendLocalizedStringsAsJSON(callback
);
228 int resource_id
= default_resource_
;
229 std::map
<std::string
, int>::iterator result
;
230 result
= path_to_idr_map_
.find(path
);
231 if (result
!= path_to_idr_map_
.end())
232 resource_id
= result
->second
;
233 DCHECK_NE(resource_id
, -1);
234 SendFromResourceBundle(callback
, resource_id
);
237 void WebUIDataSourceImpl::SendLocalizedStringsAsJSON(
238 const URLDataSource::GotDataCallback
& callback
) {
239 std::string template_data
;
240 if (!disable_set_font_strings_
)
241 webui::SetFontAndTextDirection(&localized_strings_
);
243 scoped_ptr
<webui::UseVersion2
> version2
;
244 if (json_js_format_v2_
)
245 version2
.reset(new webui::UseVersion2
);
247 webui::AppendJsonJS(&localized_strings_
, &template_data
);
248 callback
.Run(base::RefCountedString::TakeString(&template_data
));
251 void WebUIDataSourceImpl::SendFromResourceBundle(
252 const URLDataSource::GotDataCallback
& callback
, int idr
) {
253 scoped_refptr
<base::RefCountedStaticMemory
> response(
254 GetContentClient()->GetDataResourceBytes(idr
));
255 callback
.Run(response
.get());
258 } // namespace content