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 "ui/base/webui/jstemplate_builder.h"
15 #include "ui/base/webui/web_ui_util.h"
18 #include "mojo/public/bindings/js/constants.h"
24 WebUIDataSource* WebUIDataSource::Create(const std::string& source_name) {
25 return new WebUIDataSourceImpl(source_name);
30 WebUIDataSource* WebUIDataSource::AddMojoDataSource(
31 BrowserContext* browser_context) {
32 WebUIDataSource* mojo_source = Create("mojo");
38 { mojo::kCodecModuleName, IDR_MOJO_CODEC_JS },
39 { mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS },
40 { mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS },
41 { mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS },
43 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(resources); ++i)
44 mojo_source->AddResourcePath(resources[i].path, resources[i].id);
46 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 virtual ~InternalDataSource() {
67 // URLDataSource implementation.
68 virtual std::string GetSource() const OVERRIDE {
69 return parent_->GetSource();
71 virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
72 return parent_->GetMimeType(path);
74 virtual void StartDataRequest(
75 const std::string& path,
76 int render_process_id,
78 const URLDataSource::GotDataCallback& callback) OVERRIDE {
79 return parent_->StartDataRequest(path, render_process_id, render_frame_id,
82 virtual bool ShouldReplaceExistingSource() const OVERRIDE {
83 return parent_->replace_existing_source_;
85 virtual bool AllowCaching() const OVERRIDE {
88 virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
89 return parent_->add_csp_;
91 virtual std::string GetContentSecurityPolicyObjectSrc() const OVERRIDE {
92 if (parent_->object_src_set_)
93 return parent_->object_src_;
94 return URLDataSource::GetContentSecurityPolicyObjectSrc();
96 virtual std::string GetContentSecurityPolicyFrameSrc() const OVERRIDE {
97 if (parent_->frame_src_set_)
98 return parent_->frame_src_;
99 return URLDataSource::GetContentSecurityPolicyFrameSrc();
101 virtual bool ShouldDenyXFrameOptions() const OVERRIDE {
102 return parent_->deny_xframe_options_;
106 WebUIDataSourceImpl* parent_;
109 WebUIDataSourceImpl::WebUIDataSourceImpl(const std::string& source_name)
112 new InternalDataSource(this)),
113 source_name_(source_name),
114 default_resource_(-1),
115 json_js_format_v2_(false),
117 object_src_set_(false),
118 frame_src_set_(false),
119 deny_xframe_options_(true),
120 disable_set_font_strings_(false),
121 replace_existing_source_(true) {
124 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
127 void WebUIDataSourceImpl::AddString(const std::string& name,
128 const base::string16& value) {
129 localized_strings_.SetString(name, value);
132 void WebUIDataSourceImpl::AddString(const std::string& name,
133 const std::string& value) {
134 localized_strings_.SetString(name, value);
137 void WebUIDataSourceImpl::AddLocalizedString(const std::string& name,
139 localized_strings_.SetString(
140 name, GetContentClient()->GetLocalizedString(ids));
143 void WebUIDataSourceImpl::AddLocalizedStrings(
144 const base::DictionaryValue& localized_strings) {
145 localized_strings_.MergeDictionary(&localized_strings);
148 void WebUIDataSourceImpl::AddBoolean(const std::string& name, bool value) {
149 localized_strings_.SetBoolean(name, value);
152 void WebUIDataSourceImpl::SetJsonPath(const std::string& path) {
156 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() {
157 json_js_format_v2_ = true;
160 void WebUIDataSourceImpl::AddResourcePath(const std::string &path,
162 path_to_idr_map_[path] = resource_id;
165 void WebUIDataSourceImpl::SetDefaultResource(int resource_id) {
166 default_resource_ = resource_id;
169 void WebUIDataSourceImpl::SetRequestFilter(
170 const WebUIDataSource::HandleRequestCallback& callback) {
171 filter_callback_ = callback;
174 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
175 replace_existing_source_ = false;
178 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
182 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
183 const std::string& data) {
184 object_src_set_ = true;
188 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
189 const std::string& data) {
190 frame_src_set_ = true;
194 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
195 deny_xframe_options_ = false;
198 std::string WebUIDataSourceImpl::GetSource() const {
202 std::string WebUIDataSourceImpl::GetMimeType(const std::string& path) const {
203 if (EndsWith(path, ".js", false))
204 return "application/javascript";
206 if (EndsWith(path, ".json", false))
207 return "application/json";
209 if (EndsWith(path, ".pdf", false))
210 return "application/pdf";
212 if (EndsWith(path, ".svg", false))
213 return "image/svg+xml";
218 void WebUIDataSourceImpl::StartDataRequest(
219 const std::string& path,
220 int render_process_id,
222 const URLDataSource::GotDataCallback& callback) {
223 if (!filter_callback_.is_null() &&
224 filter_callback_.Run(path, callback)) {
228 if (!json_path_.empty() && path == json_path_) {
229 SendLocalizedStringsAsJSON(callback);
233 int resource_id = default_resource_;
234 std::map<std::string, int>::iterator result;
235 result = path_to_idr_map_.find(path);
236 if (result != path_to_idr_map_.end())
237 resource_id = result->second;
238 DCHECK_NE(resource_id, -1);
239 SendFromResourceBundle(callback, resource_id);
242 void WebUIDataSourceImpl::SendLocalizedStringsAsJSON(
243 const URLDataSource::GotDataCallback& callback) {
244 std::string template_data;
245 if (!disable_set_font_strings_)
246 webui::SetFontAndTextDirection(&localized_strings_);
248 scoped_ptr<webui::UseVersion2> version2;
249 if (json_js_format_v2_)
250 version2.reset(new webui::UseVersion2);
252 webui::AppendJsonJS(&localized_strings_, &template_data);
253 callback.Run(base::RefCountedString::TakeString(&template_data));
256 void WebUIDataSourceImpl::SendFromResourceBundle(
257 const URLDataSource::GotDataCallback& callback, int idr) {
258 scoped_refptr<base::RefCountedStaticMemory> response(
259 GetContentClient()->GetDataResourceBytes(idr));
260 callback.Run(response.get());
263 } // namespace content