OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 "chrome/browser/ui/webui/slideshow_ui.h" | |
6 | |
7 #include "base/callback.h" | |
8 #include "base/memory/singleton.h" | |
9 #include "base/memory/weak_ptr.h" | |
10 #include "base/message_loop.h" | |
11 #include "base/path_service.h" | |
12 #include "base/string_piece.h" | |
13 #include "base/string_util.h" | |
14 #include "base/threading/thread.h" | |
15 #include "base/time.h" | |
16 #include "base/utf_string_conversions.h" | |
17 #include "base/values.h" | |
18 #include "chrome/browser/history/history_types.h" | |
19 #include "chrome/browser/metrics/user_metrics.h" | |
20 #include "chrome/browser/profiles/profile.h" | |
21 #include "chrome/browser/ui/webui/favicon_source.h" | |
22 #include "chrome/common/chrome_paths.h" | |
23 #include "chrome/common/jstemplate_builder.h" | |
24 #include "chrome/common/url_constants.h" | |
25 #include "content/browser/browser_thread.h" | |
26 #include "content/browser/tab_contents/tab_contents.h" | |
27 #include "grit/browser_resources.h" | |
28 #include "grit/chromium_strings.h" | |
29 #include "grit/generated_resources.h" | |
30 #include "grit/locale_settings.h" | |
31 #include "net/base/directory_lister.h" | |
32 #include "net/base/escape.h" | |
33 #include "ui/base/resource/resource_bundle.h" | |
34 | |
35 static const char kPropertyPath[] = "path"; | |
36 static const char kPropertyTitle[] = "title"; | |
37 static const char kPropertyOffset[] = "currentOffset"; | |
38 static const char kPropertyDirectory[] = "isDirectory"; | |
39 | |
40 class SlideshowUIHTMLSource : public ChromeURLDataManager::DataSource { | |
41 public: | |
42 SlideshowUIHTMLSource(); | |
43 | |
44 // Called when the network layer has requested a resource underneath | |
45 // the path we registered. | |
46 virtual void StartDataRequest(const std::string& path, | |
47 bool is_incognito, | |
48 int request_id); | |
49 virtual std::string GetMimeType(const std::string&) const { | |
50 return "text/html"; | |
51 } | |
52 | |
53 private: | |
54 ~SlideshowUIHTMLSource() {} | |
55 | |
56 DISALLOW_COPY_AND_ASSIGN(SlideshowUIHTMLSource); | |
57 }; | |
58 | |
59 // The handler for Javascript messages related to the "slideshow" view. | |
60 class SlideshowHandler : public net::DirectoryLister::DirectoryListerDelegate, | |
61 public WebUIMessageHandler, | |
62 public base::SupportsWeakPtr<SlideshowHandler> { | |
63 public: | |
64 SlideshowHandler(); | |
65 virtual ~SlideshowHandler(); | |
66 | |
67 // Init work after Attach. | |
68 void Init(); | |
69 | |
70 // DirectoryLister::DirectoryListerDelegate methods: | |
71 virtual void OnListFile( | |
72 const net::DirectoryLister::DirectoryListerData& data); | |
73 virtual void OnListDone(int error); | |
74 | |
75 // WebUIMessageHandler implementation. | |
76 virtual WebUIMessageHandler* Attach(WebUI* web_ui); | |
77 virtual void RegisterMessages(); | |
78 | |
79 void GetChildrenForPath(const FilePath& path, bool is_refresh); | |
80 | |
81 // Callback for the "getChildren" message. | |
82 void HandleGetChildren(const ListValue* args); | |
83 | |
84 void HandleRefreshDirectory(const ListValue* args); | |
85 | |
86 private: | |
87 bool PathIsImageFile(const char* filename); | |
88 | |
89 scoped_ptr<ListValue> filelist_value_; | |
90 FilePath currentpath_; | |
91 FilePath originalpath_; | |
92 Profile* profile_; | |
93 int counter_; | |
94 int currentOffset_; | |
95 scoped_refptr<net::DirectoryLister> lister_; | |
96 bool is_refresh_; | |
97 | |
98 DISALLOW_COPY_AND_ASSIGN(SlideshowHandler); | |
99 }; | |
100 | |
101 //////////////////////////////////////////////////////////////////////////////// | |
102 // | |
103 // SlideshowHTMLSource | |
104 // | |
105 //////////////////////////////////////////////////////////////////////////////// | |
106 | |
107 SlideshowUIHTMLSource::SlideshowUIHTMLSource() | |
108 : DataSource(chrome::kChromeUISlideshowHost, MessageLoop::current()) { | |
109 } | |
110 | |
111 void SlideshowUIHTMLSource::StartDataRequest(const std::string& path, | |
112 bool is_incognito, | |
113 int request_id) { | |
114 DictionaryValue localized_strings; | |
115 // TODO(dhg): Add stirings to localized strings, also add more strings | |
116 // that are currently hardcoded. | |
117 SetFontAndTextDirection(&localized_strings); | |
118 | |
119 static const base::StringPiece slideshow_html( | |
120 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
121 IDR_SLIDESHOW_HTML)); | |
122 const std::string full_html = jstemplate_builder::GetI18nTemplateHtml( | |
123 slideshow_html, &localized_strings); | |
124 | |
125 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); | |
126 html_bytes->data.resize(full_html.size()); | |
127 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); | |
128 | |
129 SendResponse(request_id, html_bytes); | |
130 } | |
131 | |
132 //////////////////////////////////////////////////////////////////////////////// | |
133 // | |
134 // SlideshowHandler | |
135 // | |
136 //////////////////////////////////////////////////////////////////////////////// | |
137 SlideshowHandler::SlideshowHandler() | |
138 : profile_(NULL), | |
139 is_refresh_(false) { | |
140 lister_ = NULL; | |
141 } | |
142 | |
143 SlideshowHandler::~SlideshowHandler() { | |
144 if (lister_.get()) { | |
145 lister_->Cancel(); | |
146 lister_->set_delegate(NULL); | |
147 } | |
148 } | |
149 | |
150 WebUIMessageHandler* SlideshowHandler::Attach(WebUI* web_ui) { | |
151 profile_ = web_ui->GetProfile(); | |
152 // Create our favicon data source. | |
153 profile_->GetChromeURLDataManager()->AddDataSource( | |
154 new FaviconSource(profile_, FaviconSource::FAVICON)); | |
155 return WebUIMessageHandler::Attach(web_ui); | |
156 } | |
157 | |
158 void SlideshowHandler::Init() { | |
159 } | |
160 | |
161 void SlideshowHandler::RegisterMessages() { | |
162 web_ui_->RegisterMessageCallback("getChildren", | |
163 NewCallback(this, &SlideshowHandler::HandleGetChildren)); | |
164 web_ui_->RegisterMessageCallback("refreshDirectory", | |
165 NewCallback(this, &SlideshowHandler::HandleRefreshDirectory)); | |
166 } | |
167 | |
168 void SlideshowHandler::HandleRefreshDirectory(const ListValue* args) { | |
169 #if defined(OS_CHROMEOS) | |
170 std::string path = UTF16ToUTF8(ExtractStringValue(args)); | |
171 GetChildrenForPath(FilePath(path), true); | |
172 #endif | |
173 } | |
174 | |
175 void SlideshowHandler::GetChildrenForPath(const FilePath& path, | |
176 bool is_refresh) { | |
177 filelist_value_.reset(new ListValue()); | |
178 currentpath_ = path; | |
179 | |
180 if (lister_.get()) { | |
181 lister_->Cancel(); | |
182 lister_->set_delegate(NULL); | |
183 lister_ = NULL; | |
184 } | |
185 | |
186 is_refresh_ = is_refresh; | |
187 if (file_util::EnsureEndsWithSeparator(¤tpath_) && | |
188 currentpath_.IsAbsolute()) { | |
189 lister_ = new net::DirectoryLister(currentpath_, this); | |
190 } else { | |
191 originalpath_ = currentpath_; | |
192 currentpath_ = currentpath_.DirName(); | |
193 lister_ = new net::DirectoryLister(currentpath_, this); | |
194 } | |
195 counter_ = 0; | |
196 currentOffset_ = -1; | |
197 lister_->Start(); | |
198 } | |
199 | |
200 void SlideshowHandler::HandleGetChildren(const ListValue* args) { | |
201 #if defined(OS_CHROMEOS) | |
202 filelist_value_.reset(new ListValue()); | |
203 std::string path = UTF16ToUTF8(ExtractStringValue(args)); | |
204 GetChildrenForPath(FilePath(path), false); | |
205 #endif | |
206 } | |
207 | |
208 bool SlideshowHandler::PathIsImageFile(const char* filename) { | |
209 #if defined(OS_CHROMEOS) | |
210 FilePath file = FilePath(filename); | |
211 std::string ext = file.Extension(); | |
212 ext = StringToLowerASCII(ext); | |
213 if (ext == ".jpg" || | |
214 ext == ".jpeg" || | |
215 ext == ".png" || | |
216 ext == ".gif") { | |
217 return true; | |
218 } else { | |
219 return false; | |
220 } | |
221 #else | |
222 return false; | |
223 #endif | |
224 } | |
225 | |
226 void SlideshowHandler::OnListFile( | |
227 const net::DirectoryLister::DirectoryListerData& data) { | |
228 #if defined(OS_CHROMEOS) | |
229 if (data.info.filename[0] == '.') { | |
230 return; | |
231 } | |
232 if (!PathIsImageFile(data.info.filename.c_str())) { | |
233 return; | |
234 } | |
235 | |
236 DictionaryValue* file_value = new DictionaryValue(); | |
237 | |
238 file_value->SetString(kPropertyTitle, data.info.filename); | |
239 file_value->SetString(kPropertyPath, | |
240 currentpath_.Append(data.info.filename).value()); | |
241 file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.info.stat.st_mode)); | |
242 filelist_value_->Append(file_value); | |
243 std::string val; | |
244 file_value->GetString(kPropertyTitle, &val); | |
245 if (val == originalpath_.BaseName().value()) { | |
246 currentOffset_ = counter_; | |
247 } | |
248 counter_++; | |
249 #endif | |
250 } | |
251 | |
252 void SlideshowHandler::OnListDone(int error) { | |
253 DictionaryValue info_value; | |
254 counter_ = 0; | |
255 if (!(file_util::EnsureEndsWithSeparator(&originalpath_) && | |
256 originalpath_.IsAbsolute()) && | |
257 currentOffset_ != -1) { | |
258 info_value.SetInteger(kPropertyOffset, currentOffset_); | |
259 } | |
260 if (is_refresh_) { | |
261 info_value.SetString("functionCall", "refresh"); | |
262 } else { | |
263 info_value.SetString("functionCall", "getChildren"); | |
264 } | |
265 info_value.SetString(kPropertyPath, currentpath_.value()); | |
266 web_ui_->CallJavascriptFunction("browseFileResult", | |
267 info_value, *(filelist_value_.get())); | |
268 } | |
269 | |
270 //////////////////////////////////////////////////////////////////////////////// | |
271 // | |
272 // SlideshowUI | |
273 // | |
274 //////////////////////////////////////////////////////////////////////////////// | |
275 | |
276 SlideshowUI::SlideshowUI(TabContents* contents) : WebUI(contents) { | |
277 SlideshowHandler* handler = new SlideshowHandler(); | |
278 AddMessageHandler((handler)->Attach(this)); | |
279 handler->Init(); | |
280 SlideshowUIHTMLSource* html_source = new SlideshowUIHTMLSource(); | |
281 | |
282 // Set up the chrome://slideshow/ source. | |
283 contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); | |
284 } | |
OLD | NEW |