Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / webui / web_ui_data_source_impl.cc
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.
4
5 #include "content/browser/webui/web_ui_data_source_impl.h"
6
7 #include <string>
8
9 #include "base/bind.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"
17
18 namespace content {
19
20 // static
21 WebUIDataSource* WebUIDataSource::Create(const std::string& source_name) {
22   return new WebUIDataSourceImpl(source_name);
23 }
24
25 // static
26 WebUIDataSource* WebUIDataSource::AddMojoDataSource(
27     BrowserContext* browser_context) {
28   WebUIDataSource* mojo_source = Create("mojo");
29
30   static const struct {
31     const char* path;
32     int id;
33   } resources[] = {
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 },
38   };
39   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(resources); ++i)
40     mojo_source->AddResourcePath(resources[i].path, resources[i].id);
41
42   URLDataManager::AddWebUIDataSource(browser_context, mojo_source);
43   return mojo_source;
44 }
45
46 // static
47 void WebUIDataSource::Add(BrowserContext* browser_context,
48                           WebUIDataSource* source) {
49   URLDataManager::AddWebUIDataSource(browser_context, source);
50 }
51
52 // Internal class to hide the fact that WebUIDataSourceImpl implements
53 // URLDataSource.
54 class WebUIDataSourceImpl::InternalDataSource : public URLDataSource {
55  public:
56   InternalDataSource(WebUIDataSourceImpl* parent) : parent_(parent) {
57   }
58
59   virtual ~InternalDataSource() {
60   }
61
62   // URLDataSource implementation.
63   virtual std::string GetSource() const OVERRIDE {
64     return parent_->GetSource();
65   }
66   virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
67     return parent_->GetMimeType(path);
68   }
69   virtual void StartDataRequest(
70       const std::string& path,
71       int render_process_id,
72       int render_frame_id,
73       const URLDataSource::GotDataCallback& callback) OVERRIDE {
74     return parent_->StartDataRequest(path, render_process_id, render_frame_id,
75                                      callback);
76   }
77   virtual bool ShouldReplaceExistingSource() const OVERRIDE {
78     return parent_->replace_existing_source_;
79   }
80   virtual bool AllowCaching() const OVERRIDE {
81     return false;
82   }
83   virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
84     return parent_->add_csp_;
85   }
86   virtual std::string GetContentSecurityPolicyObjectSrc() const OVERRIDE {
87     if (parent_->object_src_set_)
88       return parent_->object_src_;
89     return URLDataSource::GetContentSecurityPolicyObjectSrc();
90   }
91   virtual std::string GetContentSecurityPolicyFrameSrc() const OVERRIDE {
92     if (parent_->frame_src_set_)
93       return parent_->frame_src_;
94     return URLDataSource::GetContentSecurityPolicyFrameSrc();
95   }
96   virtual bool ShouldDenyXFrameOptions() const OVERRIDE {
97     return parent_->deny_xframe_options_;
98   }
99
100  private:
101   WebUIDataSourceImpl* parent_;
102 };
103
104 WebUIDataSourceImpl::WebUIDataSourceImpl(const std::string& source_name)
105     : URLDataSourceImpl(
106           source_name,
107           new InternalDataSource(this)),
108       source_name_(source_name),
109       default_resource_(-1),
110       json_js_format_v2_(false),
111       add_csp_(true),
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) {
117 }
118
119 WebUIDataSourceImpl::~WebUIDataSourceImpl() {
120 }
121
122 void WebUIDataSourceImpl::AddString(const std::string& name,
123                                     const base::string16& value) {
124   localized_strings_.SetString(name, value);
125 }
126
127 void WebUIDataSourceImpl::AddString(const std::string& name,
128                                     const std::string& value) {
129   localized_strings_.SetString(name, value);
130 }
131
132 void WebUIDataSourceImpl::AddLocalizedString(const std::string& name,
133                                              int ids) {
134   localized_strings_.SetString(
135       name, GetContentClient()->GetLocalizedString(ids));
136 }
137
138 void WebUIDataSourceImpl::AddLocalizedStrings(
139     const base::DictionaryValue& localized_strings) {
140   localized_strings_.MergeDictionary(&localized_strings);
141 }
142
143 void WebUIDataSourceImpl::AddBoolean(const std::string& name, bool value) {
144   localized_strings_.SetBoolean(name, value);
145 }
146
147 void WebUIDataSourceImpl::SetJsonPath(const std::string& path) {
148   json_path_ = path;
149 }
150
151 void WebUIDataSourceImpl::SetUseJsonJSFormatV2() {
152   json_js_format_v2_ = true;
153 }
154
155 void WebUIDataSourceImpl::AddResourcePath(const std::string &path,
156                                           int resource_id) {
157   path_to_idr_map_[path] = resource_id;
158 }
159
160 void WebUIDataSourceImpl::SetDefaultResource(int resource_id) {
161   default_resource_ = resource_id;
162 }
163
164 void WebUIDataSourceImpl::SetRequestFilter(
165     const WebUIDataSource::HandleRequestCallback& callback) {
166   filter_callback_ = callback;
167 }
168
169 void WebUIDataSourceImpl::DisableReplaceExistingSource() {
170   replace_existing_source_ = false;
171 }
172
173 void WebUIDataSourceImpl::DisableContentSecurityPolicy() {
174   add_csp_ = false;
175 }
176
177 void WebUIDataSourceImpl::OverrideContentSecurityPolicyObjectSrc(
178     const std::string& data) {
179   object_src_set_ = true;
180   object_src_ = data;
181 }
182
183 void WebUIDataSourceImpl::OverrideContentSecurityPolicyFrameSrc(
184     const std::string& data) {
185   frame_src_set_ = true;
186   frame_src_ = data;
187 }
188
189 void WebUIDataSourceImpl::DisableDenyXFrameOptions() {
190   deny_xframe_options_ = false;
191 }
192
193 std::string WebUIDataSourceImpl::GetSource() const {
194   return source_name_;
195 }
196
197 std::string WebUIDataSourceImpl::GetMimeType(const std::string& path) const {
198   if (EndsWith(path, ".js", false))
199     return "application/javascript";
200
201   if (EndsWith(path, ".json", false))
202     return "application/json";
203
204   if (EndsWith(path, ".pdf", false))
205     return "application/pdf";
206
207   if (EndsWith(path, ".svg", false))
208     return "image/svg+xml";
209
210   return "text/html";
211 }
212
213 void WebUIDataSourceImpl::StartDataRequest(
214     const std::string& path,
215     int render_process_id,
216     int render_frame_id,
217     const URLDataSource::GotDataCallback& callback) {
218   if (!filter_callback_.is_null() &&
219       filter_callback_.Run(path, callback)) {
220     return;
221   }
222
223   if (!json_path_.empty() && path == json_path_) {
224     SendLocalizedStringsAsJSON(callback);
225     return;
226   }
227
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);
235 }
236
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_);
242
243   scoped_ptr<webui::UseVersion2> version2;
244   if (json_js_format_v2_)
245     version2.reset(new webui::UseVersion2);
246
247   webui::AppendJsonJS(&localized_strings_, &template_data);
248   callback.Run(base::RefCountedString::TakeString(&template_data));
249 }
250
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());
256 }
257
258 }  // namespace content