OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * WallpaperManager constructor. | 6 * WallpaperManager constructor. |
7 * | 7 * |
8 * WallpaperManager objects encapsulate the functionality of the wallpaper | 8 * WallpaperManager objects encapsulate the functionality of the wallpaper |
9 * manager extension. | 9 * manager extension. |
10 * | 10 * |
11 * @constructor | 11 * @constructor |
12 * @param {HTMLElement} dialogDom The DOM node containing the prototypical | 12 * @param {HTMLElement} dialogDom The DOM node containing the prototypical |
13 * extension UI. | 13 * extension UI. |
14 */ | 14 */ |
15 | 15 |
16 function WallpaperManager(dialogDom) { | 16 function WallpaperManager(dialogDom) { |
17 this.dialogDom_ = dialogDom; | 17 this.dialogDom_ = dialogDom; |
18 this.storage_ = chrome.storage.local; | 18 this.storage_ = chrome.storage.local; |
19 this.document_ = dialogDom.ownerDocument; | 19 this.document_ = dialogDom.ownerDocument; |
20 this.selectedCategory = null; | 20 this.selectedCategory = null; |
21 this.progressManager_ = new ProgressManager(); | 21 this.progressManager_ = new ProgressManager(); |
22 this.customWallpaperData_ = null; | 22 this.customWallpaperData_ = null; |
23 this.currentWallpaper_ = null; | 23 this.currentWallpaper_ = null; |
24 this.wallpaperRequest_ = null; | 24 this.wallpaperRequest_ = null; |
25 this.wallpaperDirs_ = WallpaperDirectories.getInstance(); | |
25 this.fetchManifest_(); | 26 this.fetchManifest_(); |
26 } | 27 } |
27 | 28 |
28 // Anonymous 'namespace'. | 29 // Anonymous 'namespace'. |
29 // TODO(bshe): Get rid of anonymous namespace. | 30 // TODO(bshe): Get rid of anonymous namespace. |
30 (function() { | 31 (function() { |
31 | 32 |
32 /** | 33 /** |
33 * Base URL of the manifest file. | 34 * Base URL of the manifest file. |
34 */ | 35 */ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 * Equivilant to localStrings.getString(id). | 71 * Equivilant to localStrings.getString(id). |
71 * | 72 * |
72 * @param {string} id The id of the string to return. | 73 * @param {string} id The id of the string to return. |
73 * @return {string} The translated string. | 74 * @return {string} The translated string. |
74 */ | 75 */ |
75 function str(id) { | 76 function str(id) { |
76 return loadTimeData.getString(id); | 77 return loadTimeData.getString(id); |
77 } | 78 } |
78 | 79 |
79 /** | 80 /** |
81 * Retruns the current selected layout. | |
82 * @return {string} The selected layout. | |
83 */ | |
84 function getSelectedLayout() { | |
85 var setWallpaperLayout = $('set-wallpaper-layout'); | |
86 return setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; | |
87 } | |
88 | |
89 /** | |
80 * Loads translated strings. | 90 * Loads translated strings. |
81 */ | 91 */ |
82 WallpaperManager.initStrings = function(callback) { | 92 WallpaperManager.initStrings = function(callback) { |
83 chrome.wallpaperPrivate.getStrings(function(strings) { | 93 chrome.wallpaperPrivate.getStrings(function(strings) { |
84 loadTimeData.data = strings; | 94 loadTimeData.data = strings; |
85 if (callback) | 95 if (callback) |
86 callback(); | 96 callback(); |
87 }); | 97 }); |
88 }; | 98 }; |
89 | 99 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 this.initCategoriesList_(); | 208 this.initCategoriesList_(); |
199 this.initThumbnailsGrid_(); | 209 this.initThumbnailsGrid_(); |
200 this.presetCategory_(); | 210 this.presetCategory_(); |
201 | 211 |
202 $('file-selector').addEventListener( | 212 $('file-selector').addEventListener( |
203 'change', this.onFileSelectorChanged_.bind(this)); | 213 'change', this.onFileSelectorChanged_.bind(this)); |
204 $('set-wallpaper-layout').addEventListener( | 214 $('set-wallpaper-layout').addEventListener( |
205 'change', this.onWallpaperLayoutChanged_.bind(this)); | 215 'change', this.onWallpaperLayoutChanged_.bind(this)); |
206 var self = this; | 216 var self = this; |
207 window.addEventListener('offline', function() { | 217 window.addEventListener('offline', function() { |
208 chrome.wallpaperPrivate.getOfflineWallpaperList('ONLINE', | 218 chrome.wallpaperPrivate.getOfflineWallpaperList( |
209 function(lists) { | 219 wallpapers.WallpaperSourceEnum.Online, function(lists) { |
210 if (!self.downloadedListMap_) | 220 if (!self.downloadedListMap_) |
211 self.downloadedListMap_ = {}; | 221 self.downloadedListMap_ = {}; |
212 for (var i = 0; i < lists.length; i++) | 222 for (var i = 0; i < lists.length; i++) |
213 self.downloadedListMap_[lists[i]] = true; | 223 self.downloadedListMap_[lists[i]] = true; |
214 var thumbnails = self.document_.querySelectorAll('.thumbnail'); | 224 var thumbnails = self.document_.querySelectorAll('.thumbnail'); |
215 for (var i = 0; i < thumbnails.length; i++) { | 225 for (var i = 0; i < thumbnails.length; i++) { |
216 var thumbnail = thumbnails[i]; | 226 var thumbnail = thumbnails[i]; |
217 var url = self.wallpaperGrid_.dataModel.item(i).baseURL; | 227 var url = self.wallpaperGrid_.dataModel.item(i).baseURL; |
218 var fileName = url.substring(url.lastIndexOf('/') + 1) + | 228 var fileName = url.substring(url.lastIndexOf('/') + 1) + |
219 HighResolutionSuffix; | 229 HighResolutionSuffix; |
220 if (self.downloadedListMap_ && | 230 if (self.downloadedListMap_ && |
221 self.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { | 231 self.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { |
222 thumbnail.offline = true; | 232 thumbnail.offline = true; |
223 } | 233 } |
224 } | 234 } |
225 }); | 235 }); |
226 $('wallpaper-grid').classList.add('image-picker-offline'); | 236 $('wallpaper-grid').classList.add('image-picker-offline'); |
227 }); | 237 }); |
228 window.addEventListener('online', function() { | 238 window.addEventListener('online', function() { |
229 self.downloadedListMap_ = null; | 239 self.downloadedListMap_ = null; |
230 $('wallpaper-grid').classList.remove('image-picker-offline'); | 240 $('wallpaper-grid').classList.remove('image-picker-offline'); |
231 }); | 241 }); |
232 $('close').addEventListener('click', function() {window.close()}); | 242 $('close').addEventListener('click', function() {window.close()}); |
233 this.document_.defaultView.addEventListener( | 243 this.document_.defaultView.addEventListener( |
234 'resize', this.onResize_.bind(this)); | 244 'resize', this.onResize_.bind(this)); |
235 $('learn-more').href = LearnMoreURL; | 245 $('learn-more').href = LearnMoreURL; |
236 $('close-error').addEventListener('click', function() { | 246 $('close-error').addEventListener('click', function() { |
237 $('error-container').hidden = true; | 247 $('error-container').hidden = true; |
238 }); | 248 }); |
249 $('close-wallpaper-selection').addEventListener('click', function() { | |
250 $('wallpaper-selection-container').hidden = true; | |
251 $('set-wallpaper-layout').disabled = true; | |
252 }); | |
239 | 253 |
240 this.onResize_(); | 254 this.onResize_(); |
241 }; | 255 }; |
242 | 256 |
243 /** | 257 /** |
244 * Preset to the category which contains current wallpaper. | 258 * Preset to the category which contains current wallpaper. |
245 */ | 259 */ |
246 WallpaperManager.prototype.presetCategory_ = function() { | 260 WallpaperManager.prototype.presetCategory_ = function() { |
247 this.currentWallpaper_ = str('currentWallpaper'); | 261 this.currentWallpaper_ = str('currentWallpaper'); |
248 if (this.currentWallpaper_ && this.currentWallpaper_ == 'CUSTOM') { | 262 // The currentWallpaper_ is either a url contains HightResolutionSuffix or a |
263 // custom wallpaper file name converted from an integer value represent | |
264 // time (e.g., 13006377367586070). | |
265 if (this.currentWallpaper_ && | |
266 this.currentWallpaper_.indexOf(HighResolutionSuffix) == -1) { | |
249 // Custom is the last one in the categories list. | 267 // Custom is the last one in the categories list. |
250 this.categoriesList_.selectionModel.selectedIndex = | 268 this.categoriesList_.selectionModel.selectedIndex = |
251 this.categoriesList_.dataModel.length - 1; | 269 this.categoriesList_.dataModel.length - 1; |
252 return; | 270 return; |
253 } | 271 } |
254 var self = this; | 272 var self = this; |
255 var presetCategoryInner_ = function() { | 273 var presetCategoryInner_ = function() { |
256 // Selects the first category in the categories list of current | 274 // Selects the first category in the categories list of current |
257 // wallpaper as the default selected category when showing wallpaper | 275 // wallpaper as the default selected category when showing wallpaper |
258 // picker UI. | 276 // picker UI. |
259 var presetCategory = AllCategoryIndex; | 277 var presetCategory = AllCategoryIndex; |
260 for (var key in self.manifest_.wallpaper_list) { | 278 if (self.currentWallpaper_) { |
261 var url = self.manifest_.wallpaper_list[key].base_url + | 279 for (var key in self.manifest_.wallpaper_list) { |
262 HighResolutionSuffix; | 280 var url = self.manifest_.wallpaper_list[key].base_url + |
263 if (url.indexOf(self.currentWallpaper_) != -1 && | 281 HighResolutionSuffix; |
264 self.manifest_.wallpaper_list[key].categories.length > 0) { | 282 if (url.indexOf(self.currentWallpaper_) != -1 && |
265 presetCategory = self.manifest_.wallpaper_list[key].categories[0] + | 283 self.manifest_.wallpaper_list[key].categories.length > 0) { |
266 OnlineCategoriesOffset; | 284 presetCategory = self.manifest_.wallpaper_list[key].categories[0] + |
285 OnlineCategoriesOffset; | |
286 break; | |
287 } | |
267 } | 288 } |
268 } | 289 } |
269 self.categoriesList_.selectionModel.selectedIndex = presetCategory; | 290 self.categoriesList_.selectionModel.selectedIndex = presetCategory; |
270 }; | 291 }; |
271 if (navigator.onLine) { | 292 if (navigator.onLine) { |
272 presetCategoryInner_(); | 293 presetCategoryInner_(); |
273 } else { | 294 } else { |
274 // If device is offline, gets the available offline wallpaper list first. | 295 // If device is offline, gets the available offline wallpaper list first. |
275 // Wallpapers which are not in the list will display a grayscaled | 296 // Wallpapers which are not in the list will display a grayscaled |
276 // thumbnail. | 297 // thumbnail. |
277 chrome.wallpaperPrivate.getOfflineWallpaperList('ONLINE', | 298 chrome.wallpaperPrivate.getOfflineWallpaperList( |
278 function(lists) { | 299 wallpapers.WallpaperSourceEnum.Online, function(lists) { |
279 if (!self.downloadedListMap_) | 300 if (!self.downloadedListMap_) |
280 self.downloadedListMap_ = {}; | 301 self.downloadedListMap_ = {}; |
281 for (var i = 0; i < lists.length; i++) | 302 for (var i = 0; i < lists.length; i++) |
282 self.downloadedListMap_[lists[i]] = true; | 303 self.downloadedListMap_[lists[i]] = true; |
283 presetCategoryInner_(); | 304 presetCategoryInner_(); |
284 }); | 305 }); |
285 } | 306 } |
286 }; | 307 }; |
287 | 308 |
288 /** | 309 /** |
289 * Constructs the thumbnails grid. | 310 * Constructs the thumbnails grid. |
290 */ | 311 */ |
291 WallpaperManager.prototype.initThumbnailsGrid_ = function() { | 312 WallpaperManager.prototype.initThumbnailsGrid_ = function() { |
292 this.wallpaperGrid_ = $('wallpaper-grid'); | 313 this.wallpaperGrid_ = $('wallpaper-grid'); |
293 wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_); | 314 wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_); |
294 | 315 |
295 this.wallpaperGrid_.addEventListener('change', | 316 this.wallpaperGrid_.addEventListener('change', |
296 this.onThumbnailClicked_.bind(this)); | 317 this.onThumbnailSelectionChanged_.bind(this)); |
297 this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this)); | 318 this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this)); |
298 }; | 319 }; |
299 | 320 |
300 /** | 321 /** |
301 * Closes window if no pending wallpaper request. | 322 * Closes window if no pending wallpaper request. |
302 */ | 323 */ |
303 WallpaperManager.prototype.onClose_ = function() { | 324 WallpaperManager.prototype.onClose_ = function() { |
304 if (this.wallpaperRequest_) { | 325 if (this.wallpaperRequest_) { |
305 this.wallpaperRequest_.addEventListener('loadend', function() { | 326 this.wallpaperRequest_.addEventListener('loadend', function() { |
306 // Close window on wallpaper loading finished. | 327 // Close window on wallpaper loading finished. |
307 window.close(); | 328 window.close(); |
308 }); | 329 }); |
309 } else { | 330 } else { |
310 window.close(); | 331 window.close(); |
311 } | 332 } |
312 }; | 333 }; |
313 | 334 |
314 /** | 335 /** |
315 * Sets wallpaper to the corresponding wallpaper of selected thumbnail. | 336 * Sets wallpaper to the corresponding wallpaper of selected thumbnail. |
337 * @param {{baseURL: string, layout: string, source: string, | |
338 * availableOffline: boolean, opt_dynamicURL: string, | |
339 * opt_author: string, opt_authorWebsite: string}} | |
340 * selectedItem the selected item in WallpaperThumbnailsGrid's data | |
341 * model. | |
342 */ | |
343 WallpaperManager.prototype.setSelectedWallpaper_ = function(selectedItem) { | |
344 var self = this; | |
345 switch (selectedItem.source) { | |
346 case wallpapers.WallpaperSourceEnum.Custom: | |
347 var errorHandler = this.onFileSystemError_.bind(this); | |
348 var setActive = function() { | |
349 self.wallpaperGrid_.activeItem = selectedItem; | |
350 self.currentWallpaper_ = selectedItem.baseURL; | |
351 }; | |
352 var success = function(dirEntry) { | |
353 dirEntry.getFile(selectedItem.baseURL, {create: false}, | |
354 function(fileEntry) { | |
355 fileEntry.file(function(file) { | |
356 var reader = new FileReader(); | |
357 reader.readAsArrayBuffer(file); | |
358 reader.addEventListener('error', errorHandler); | |
359 reader.addEventListener('load', function(e) { | |
360 self.setCustomWallpaper(e.target.result, | |
361 selectedItem.layout, | |
362 false, selectedItem.baseURL, | |
363 setActive, errorHandler); | |
364 }); | |
365 }, errorHandler); | |
366 }, errorHandler); | |
367 } | |
368 this.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, | |
369 success, errorHandler); | |
370 break; | |
371 case wallpapers.WallpaperSourceEnum.Online: | |
372 var wallpaperURL = selectedItem.baseURL + HighResolutionSuffix; | |
373 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem); | |
374 | |
375 chrome.wallpaperPrivate.setWallpaperIfExist(wallpaperURL, | |
376 selectedItem.layout, | |
377 selectedItem.source, | |
378 function() { | |
379 if (chrome.runtime.lastError == undefined) { | |
380 self.currentWallpaper_ = wallpaperURL; | |
381 self.wallpaperGrid_.activeItem = selectedItem; | |
382 return; | |
383 } | |
384 | |
385 // Falls back to request wallpaper from server. | |
386 if (self.wallpaperRequest_) | |
387 self.wallpaperRequest_.abort(); | |
388 | |
389 self.wallpaperRequest_ = new XMLHttpRequest(); | |
390 self.wallpaperRequest_.open('GET', wallpaperURL, true); | |
391 self.wallpaperRequest_.responseType = 'arraybuffer'; | |
392 self.progressManager_.reset(self.wallpaperRequest_, selectedGridItem); | |
393 self.wallpaperRequest_.send(null); | |
394 self.wallpaperRequest_.addEventListener('load', function(e) { | |
395 if (self.wallpaperRequest_.status === 200) { | |
396 var image = self.wallpaperRequest_.response; | |
397 chrome.wallpaperPrivate.setWallpaper( | |
398 image, | |
399 selectedItem.layout, | |
400 wallpaperURL, | |
401 self.onFinished_.bind(self, selectedGridItem, selectedItem)); | |
402 self.currentWallpaper_ = wallpaperURL; | |
403 } else { | |
404 self.progressManager_.hideProgressBar(selectedGridItem); | |
405 self.showError_(str('downloadFailed')); | |
406 } | |
407 self.wallpaperRequest_ = null; | |
408 }); | |
409 self.wallpaperRequest_.addEventListener('error', function() { | |
410 self.showError_(str('downloadFailed')); | |
411 }); | |
412 }); | |
413 break; | |
414 default: | |
415 console.error('Unsupported wallpaper source.'); | |
416 } | |
417 }; | |
418 | |
419 /* | |
420 * Shows an error message to user and log the failed reason in console. | |
316 */ | 421 */ |
317 WallpaperManager.prototype.onThumbnailClicked_ = function() { | 422 WallpaperManager.prototype.onFileSystemError_ = function(e) { |
423 var msg = ''; | |
424 switch (e.code) { | |
425 case FileError.QUOTA_EXCEEDED_ERR: | |
426 msg = 'QUOTA_EXCEEDED_ERR'; | |
427 break; | |
428 case FileError.NOT_FOUND_ERR: | |
429 msg = 'NOT_FOUND_ERR'; | |
430 break; | |
431 case FileError.SECURITY_ERR: | |
432 msg = 'SECURITY_ERR'; | |
433 break; | |
434 case FileError.INVALID_MODIFICATION_ERR: | |
435 msg = 'INVALID_MODIFICATION_ERR'; | |
436 break; | |
437 case FileError.INVALID_STATE_ERR: | |
438 msg = 'INVALID_STATE_ERR'; | |
439 break; | |
440 default: | |
441 msg = 'Unknown Error'; | |
442 break; | |
443 } | |
444 console.error('Error: ' + msg); | |
445 this.showError_(str('accessFileFailure')); | |
446 }; | |
447 | |
448 /** | |
449 * Handles click on a different thumbnail in wallpaper grid. | |
450 */ | |
451 WallpaperManager.prototype.onThumbnailSelectionChanged_ = function() { | |
318 var selectedItem = this.wallpaperGrid_.selectedItem; | 452 var selectedItem = this.wallpaperGrid_.selectedItem; |
319 if (selectedItem && selectedItem.dynamicURL && | 453 if (selectedItem && selectedItem.source == 'ADDNEW') |
454 return; | |
455 | |
456 if (selectedItem && selectedItem.baseURL && | |
320 !this.wallpaperGrid_.inProgramSelection) { | 457 !this.wallpaperGrid_.inProgramSelection) { |
321 var wallpaperURL = selectedItem.baseURL + HighResolutionSuffix; | 458 if (selectedItem.source == wallpapers.WallpaperSourceEnum.Custom) { |
322 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem); | 459 var items = {}; |
323 var self = this; | 460 var key = selectedItem.baseURL; |
324 | 461 var self = this; |
325 chrome.wallpaperPrivate.setWallpaperIfExist(wallpaperURL, | 462 this.storage_.get(key, function(items) { |
326 selectedItem.layout, | 463 selectedItem.layout = items[key] ? items[key] : 'CENTER_CROPPED'; |
327 'ONLINE', | 464 self.setSelectedWallpaper_(selectedItem); |
328 function() { | |
329 if (chrome.runtime.lastError == undefined) { | |
330 self.currentWallpaper_ = wallpaperURL; | |
331 self.wallpaperGrid_.activeItem = selectedItem; | |
332 return; | |
333 } | |
334 | |
335 // Falls back to request wallpaper from server. | |
336 if (self.wallpaperRequest_) | |
337 self.wallpaperRequest_.abort(); | |
338 | |
339 self.wallpaperRequest_ = new XMLHttpRequest(); | |
340 self.wallpaperRequest_.open('GET', wallpaperURL, true); | |
341 self.wallpaperRequest_.responseType = 'arraybuffer'; | |
342 self.progressManager_.reset(self.wallpaperRequest_, selectedGridItem); | |
343 self.wallpaperRequest_.send(null); | |
344 self.wallpaperRequest_.addEventListener('load', function(e) { | |
345 if (self.wallpaperRequest_.status === 200) { | |
346 var image = self.wallpaperRequest_.response; | |
347 chrome.wallpaperPrivate.setWallpaper( | |
348 image, | |
349 selectedItem.layout, | |
350 wallpaperURL, | |
351 self.onFinished_.bind(self, selectedGridItem, selectedItem)); | |
352 self.currentWallpaper_ = wallpaperURL; | |
353 } else { | |
354 self.progressManager_.hideProgressBar(selectedGridItem); | |
355 self.showError_(str('downloadFailed')); | |
356 } | |
357 self.wallpaperRequest_ = null; | |
358 }); | 465 }); |
359 self.wallpaperRequest_.addEventListener('error', function() { | 466 } else { |
360 self.showError_(str('downloadFailed')); | 467 this.setSelectedWallpaper_(selectedItem); |
361 }); | 468 } |
362 }); | |
363 } | 469 } |
364 this.setWallpaperAttribution_(selectedItem); | 470 this.setWallpaperAttribution_(selectedItem); |
365 }; | 471 }; |
366 | 472 |
367 /** | 473 /** |
368 * Set attributions of wallpaper with given URL. If URL is not valid, clear | 474 * Set attributions of wallpaper with given URL. If URL is not valid, clear |
369 * the attributions. | 475 * the attributions. |
370 * @param {{baseURL: string, dynamicURL: string, layout: string, | 476 * @param {{baseURL: string, dynamicURL: string, layout: string, |
371 * author: string, authorWebsite: string, availableOffline: boolean}} | 477 * author: string, authorWebsite: string, availableOffline: boolean}} |
372 * selectedItem selected wallpaper item in grid. | 478 * selectedItem selected wallpaper item in grid. |
373 * @private | 479 * @private |
374 */ | 480 */ |
375 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { | 481 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { |
376 if (selectedItem) { | 482 if (selectedItem) { |
377 $('author-name').textContent = selectedItem.author; | 483 $('author-name').textContent = selectedItem.author; |
378 $('author-website').textContent = $('author-website').href = | 484 $('author-website').textContent = $('author-website').href = |
379 selectedItem.authorWebsite; | 485 selectedItem.authorWebsite; |
380 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL, | 486 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL, |
487 selectedItem.source, | |
381 function(data) { | 488 function(data) { |
382 var img = $('attribute-image'); | 489 var img = $('attribute-image'); |
383 if (data) { | 490 if (data) { |
384 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'}); | 491 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'}); |
385 img.src = window.URL.createObjectURL(blob); | 492 img.src = window.URL.createObjectURL(blob); |
386 img.addEventListener('load', function(e) { | 493 img.addEventListener('load', function(e) { |
387 window.URL.revokeObjectURL(this.src); | 494 window.URL.revokeObjectURL(this.src); |
388 }); | 495 }); |
389 } else { | 496 } else { |
390 img.src = ''; | 497 img.src = ''; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 }; | 566 }; |
460 | 567 |
461 /** | 568 /** |
462 * Handles the custom wallpaper which user selected from file manager. Called | 569 * Handles the custom wallpaper which user selected from file manager. Called |
463 * when users select a file. | 570 * when users select a file. |
464 */ | 571 */ |
465 WallpaperManager.prototype.onFileSelectorChanged_ = function() { | 572 WallpaperManager.prototype.onFileSelectorChanged_ = function() { |
466 var files = $('file-selector').files; | 573 var files = $('file-selector').files; |
467 if (files.length != 1) | 574 if (files.length != 1) |
468 console.error('More than one files are selected or no file selected'); | 575 console.error('More than one files are selected or no file selected'); |
469 var file = files[0]; | 576 if (!files[0].type.match('image/jpeg')) { |
470 if (!file.type.match('image/jpeg')) { | |
471 this.showError_(str('invalidWallpaper')); | 577 this.showError_(str('invalidWallpaper')); |
472 return; | 578 return; |
473 } | 579 } |
474 var reader = new FileReader(); | 580 var layout = getSelectedLayout(); |
475 reader.readAsArrayBuffer(files[0]); | |
476 var self = this; | 581 var self = this; |
477 reader.addEventListener('error', function(e) { | 582 var errorHandler = this.onFileSystemError_.bind(this); |
478 self.showError_(str('accessFileFailure')); | 583 var setSelectedFile = function(file, layout, fileName) { |
479 }); | 584 var saveThumbnail = function(thumbnail) { |
480 reader.addEventListener('load', function(e) { | 585 var success = function(dirEntry) { |
481 self.customWallpaperData_ = e.target.result; | 586 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { |
482 self.refreshWallpaper_(self.customWallpaperData_); | 587 fileEntry.createWriter(function(fileWriter) { |
483 }); | 588 fileWriter.onwriteend = function(e) { |
484 this.generateThumbnail_(files[0]); | 589 $('set-wallpaper-layout').disabled = false; |
590 var wallpaperInfo = { | |
591 baseURL: fileName, | |
592 layout: layout, | |
593 source: wallpapers.WallpaperSourceEnum.Custom, | |
594 availableOffline: true | |
595 }; | |
596 self.currentWallpaper_ = fileName; | |
597 var items = {}; | |
598 items[self.currentWallpaper_] = layout; | |
599 self.storage_.set(items, function() {}); | |
600 self.wallpaperGrid_.dataModel.splice(0, 0, wallpaperInfo); | |
601 self.wallpaperGrid_.selectedItem = wallpaperInfo; | |
602 self.wallpaperGrid_.activeItem = wallpaperInfo; | |
603 }; | |
604 | |
605 fileWriter.onerror = errorHandler; | |
606 | |
607 var blob = new Blob([new Int8Array(thumbnail)], | |
608 {'type' : 'image\/jpeg'}); | |
609 fileWriter.write(blob); | |
flackr
2013/03/06 16:22:11
What happens when we run out of quota? We should b
bshe
2013/03/07 05:34:35
Added a simple function to remove the oldest file
| |
610 }, errorHandler); | |
611 }, errorHandler); | |
612 }; | |
613 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL, | |
614 success, errorHandler); | |
615 }; | |
616 | |
617 var success = function(dirEntry) { | |
618 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { | |
619 fileEntry.createWriter(function(fileWriter) { | |
620 fileWriter.addEventListener('writeend', function(e) { | |
621 var reader = new FileReader(); | |
622 reader.readAsArrayBuffer(file); | |
623 reader.addEventListener('error', errorHandler); | |
624 reader.addEventListener('load', function(e) { | |
625 self.setCustomWallpaper(e.target.result, layout, true, fileName, | |
626 saveThumbnail, function() { | |
627 self.removeCustomWallpaper(fileName); | |
628 errorHandler(); | |
629 }); | |
630 }); | |
631 }); | |
632 | |
633 fileWriter.addEventListener('error', errorHandler); | |
634 fileWriter.write(file); | |
bshe
2013/03/06 15:44:33
duplicate the selected file before we try to set i
| |
635 }, errorHandler); | |
636 }, errorHandler); | |
637 }; | |
638 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success, | |
639 errorHandler); | |
640 }; | |
641 setSelectedFile(files[0], layout, new Date().getTime().toString()); | |
485 }; | 642 }; |
486 | 643 |
487 /** | 644 /** |
488 * Refreshes the custom wallpaper with the current selected layout. | 645 * Removes wallpaper and thumbnail with fileName from FileSystem. |
489 * @param {ArrayBuffer} customWallpaper The raw wallpaper file data. | 646 * @param {string} fileName The file name of wallpaper and thumbnail to be |
647 * removed. | |
490 */ | 648 */ |
491 WallpaperManager.prototype.refreshWallpaper_ = function(customWallpaper) { | 649 WallpaperManager.prototype.removeCustomWallpaper = function(fileName) { |
492 var setWallpaperLayout = $('set-wallpaper-layout'); | 650 var errorHandler = this.onFileSystemError_.bind(this); |
493 var layout = | 651 var self = this; |
494 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; | 652 var removeFile = function(fileName) { |
495 chrome.wallpaperPrivate.setCustomWallpaper(customWallpaper, | 653 var success = function(dirEntry) { |
496 layout, | 654 dirEntry.getFile(fileName, {create: false}, function(fileEntry) { |
497 this.onFinished_.bind(this)); | 655 fileEntry.remove(function() { |
498 this.currentWallpaper_ = 'CUSTOM'; | 656 }, errorHandler); |
657 }, errorHandler); | |
658 } | |
659 | |
660 // Removes copy of original. | |
661 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success, | |
662 errorHandler); | |
663 | |
664 // Removes generated thumbnail. | |
665 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL, success, | |
666 errorHandler); | |
667 }; | |
668 removeFile(fileName); | |
499 }; | 669 }; |
500 | 670 |
501 /** | 671 /** |
502 * Sets wallpaper finished. Displays error message in butter bar if any. | 672 * Sets current wallpaper and generate thumbnail if generateThumbnail is true. |
673 * @param {ArrayBuffer} wallpaper The binary representation of wallpaper. | |
674 * @param {string} layout The user selected wallpaper layout. | |
675 * @param {boolean} generateThumbnail True if need to generate thumbnail. | |
676 * @param {string} fileName The unique file name of wallpaper. | |
677 * @param {function(thumbnail):void} success Success callback. If | |
678 * generateThumbnail is true, the callback parameter should have the | |
679 * generated thumbnail. | |
680 * @param {function(e):void} failure Failure callback. Called when there is an | |
681 * error from FileSystem. | |
682 */ | |
683 WallpaperManager.prototype.setCustomWallpaper = function(wallpaper, | |
684 layout, | |
685 generateThumbnail, | |
686 fileName, | |
687 success, | |
688 failure) { | |
689 var self = this; | |
690 var onFinished = function(opt_thumbnail) { | |
691 if (chrome.runtime.lastError != undefined) { | |
692 self.showError_(chrome.runtime.lastError.message); | |
693 $('set-wallpaper-layout').disabled = true; | |
694 } else { | |
695 success(opt_thumbnail); | |
696 } | |
697 }; | |
698 | |
699 chrome.wallpaperPrivate.setCustomWallpaper(wallpaper, layout, | |
700 generateThumbnail, | |
701 fileName, onFinished); | |
702 }; | |
703 | |
704 /** | |
705 * Sets wallpaper finished. Displays error message if any. | |
503 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper | 706 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper |
504 * thumbnail grid item. It extends from cr.ui.ListItem. | 707 * thumbnail grid item. It extends from cr.ui.ListItem. |
505 * @param {{baseURL: string, dynamicURL: string, layout: string, | 708 * @param {{baseURL: string, layout: string, source: string, |
506 * author: string, authorWebsite: string, | 709 * availableOffline: boolean, opt_dynamicURL: string, |
507 * availableOffline: boolean}=} | 710 * opt_author: string, opt_authorWebsite: string}=} |
508 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data | 711 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data |
509 * model. | 712 * model. |
510 */ | 713 */ |
511 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem, | 714 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem, |
512 opt_selectedItem) { | 715 opt_selectedItem) { |
513 if (opt_selectedGridItem) | 716 if (opt_selectedGridItem) |
514 this.progressManager_.hideProgressBar(opt_selectedGridItem); | 717 this.progressManager_.hideProgressBar(opt_selectedGridItem); |
515 | 718 |
516 if (chrome.runtime.lastError != undefined) { | 719 if (chrome.runtime.lastError != undefined) { |
517 this.showError_(chrome.runtime.lastError.message); | 720 this.showError_(chrome.runtime.lastError.message); |
518 } else if (opt_selectedItem) { | 721 } else if (opt_selectedItem) { |
519 this.wallpaperGrid_.activeItem = opt_selectedItem; | 722 this.wallpaperGrid_.activeItem = opt_selectedItem; |
520 } | 723 } |
521 }; | 724 }; |
522 | 725 |
523 /** | 726 /** |
524 * Handles the layout setting change of custom wallpaper. | 727 * Handles the layout setting change of custom wallpaper. |
525 */ | 728 */ |
526 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { | 729 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { |
527 var setWallpaperLayout = $('set-wallpaper-layout'); | 730 var layout = getSelectedLayout(); |
528 var layout = | 731 var self = this; |
529 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; | 732 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, function() { |
530 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, | 733 if (chrome.runtime.lastError != undefined) { |
531 this.onFinished_.bind(this)); | 734 self.showError_(chrome.runtime.lastError.message); |
735 self.removeCustomWallpaper(fileName); | |
736 $('set-wallpaper-layout').disabled = true; | |
737 } else { | |
738 var items = {}; | |
739 items[self.currentWallpaper_] = layout; | |
740 self.storage_.set(items, function() {}); | |
741 } | |
742 }); | |
532 }; | 743 }; |
533 | 744 |
534 /** | 745 /** |
535 * Generates a thumbnail of user selected image file. | |
536 * @param {Object} file The file user selected from file manager. | |
537 */ | |
538 WallpaperManager.prototype.generateThumbnail_ = function(file) { | |
539 var img = $('preview'); | |
540 img.file = file; | |
541 var reader = new FileReader(); | |
542 reader.addEventListener('load', function(e) { | |
543 img.src = e.target.result; | |
544 }); | |
545 reader.readAsDataURL(file); | |
546 }; | |
547 | |
548 /** | |
549 * Toggle visibility of custom container and category container. | |
550 * @param {boolean} showCustom True if display custom container and hide | |
551 * category container. | |
552 */ | |
553 WallpaperManager.prototype.showCustomContainer_ = function(showCustom) { | |
554 $('category-container').hidden = showCustom; | |
555 $('custom-container').hidden = !showCustom; | |
556 }; | |
557 | |
558 /** | |
559 * Handles user clicking on a different category. | 746 * Handles user clicking on a different category. |
560 */ | 747 */ |
561 WallpaperManager.prototype.onCategoriesChange_ = function() { | 748 WallpaperManager.prototype.onCategoriesChange_ = function() { |
562 var categoriesList = this.categoriesList_; | 749 var categoriesList = this.categoriesList_; |
563 var selectedIndex = categoriesList.selectionModel.selectedIndex; | 750 var selectedIndex = categoriesList.selectionModel.selectedIndex; |
564 if (selectedIndex == -1) | 751 if (selectedIndex == -1) |
565 return; | 752 return; |
566 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); | 753 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); |
567 var bar = $('bar'); | 754 var bar = $('bar'); |
568 bar.style.left = selectedListItem.offsetLeft + 'px'; | 755 bar.style.left = selectedListItem.offsetLeft + 'px'; |
569 bar.style.width = selectedListItem.offsetWidth + 'px'; | 756 bar.style.width = selectedListItem.offsetWidth + 'px'; |
570 | 757 |
758 var wallpapersDataModel = new cr.ui.ArrayDataModel([]); | |
759 var selectedItem; | |
571 if (selectedListItem.custom) { | 760 if (selectedListItem.custom) { |
572 this.showCustomContainer_(true); | 761 $('online-wallpaper-attribute').hidden = true; |
762 var errorHandler = this.onFileSystemError_.bind(this); | |
763 var toArray = function(list) { | |
764 return Array.prototype.slice.call(list || [], 0); | |
765 } | |
766 | |
767 var self = this; | |
768 var processResults = function(entries) { | |
769 for (var i = 0; i < entries.length; i++) { | |
770 var entry = entries[i]; | |
771 var wallpaperInfo = { | |
772 baseURL: entry.name, | |
773 // The layout will be replaced by the actual value saved in | |
774 // local storage when requested later. Layout is not important | |
775 // for constructing thumbnails grid, we use CENTER_CROPPED here | |
776 // to speed up the process of constructing. So we do not need to | |
777 // wait for fetching correct layout. | |
778 layout: 'CENTER_CROPPED', | |
779 source: wallpapers.WallpaperSourceEnum.Custom, | |
780 availableOffline: true | |
781 }; | |
782 if (self.currentWallpaper_ == entry.name) | |
783 selectedItem = wallpaperInfo; | |
784 wallpapersDataModel.push(wallpaperInfo); | |
785 } | |
786 var lastElement = { | |
787 baseURL: '', | |
788 layout: '', | |
789 source: 'ADDNEW', | |
790 availableOffline: true | |
791 }; | |
792 wallpapersDataModel.push(lastElement); | |
793 self.wallpaperGrid_.dataModel = wallpapersDataModel; | |
794 self.wallpaperGrid_.selectedItem = selectedItem; | |
795 self.wallpaperGrid_.activeItem = selectedItem; | |
796 } | |
797 | |
798 var success = function(dirEntry) { | |
799 var dirReader = dirEntry.createReader(); | |
800 var entries = []; | |
801 // All of a directory's entries are not guaranteed to return in a single | |
802 // call. | |
803 var readEntries = function() { | |
804 dirReader.readEntries(function(results) { | |
805 if (!results.length) { | |
806 processResults(entries.sort()); | |
807 } else { | |
808 entries = entries.concat(toArray(results)); | |
809 readEntries(); | |
810 } | |
811 }, errorHandler); | |
812 }; | |
813 readEntries(); // Start reading dirs. | |
814 } | |
815 this.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, | |
816 success, errorHandler); | |
573 } else { | 817 } else { |
574 this.showCustomContainer_(false); | 818 $('online-wallpaper-attribute').hidden = false; |
575 var selectedItem; | |
576 var wallpapersDataModel = new cr.ui.ArrayDataModel([]); | |
577 for (var key in this.manifest_.wallpaper_list) { | 819 for (var key in this.manifest_.wallpaper_list) { |
578 if (selectedIndex == AllCategoryIndex || | 820 if (selectedIndex == AllCategoryIndex || |
579 this.manifest_.wallpaper_list[key].categories.indexOf( | 821 this.manifest_.wallpaper_list[key].categories.indexOf( |
580 selectedIndex - OnlineCategoriesOffset) != -1) { | 822 selectedIndex - OnlineCategoriesOffset) != -1) { |
581 var wallpaperInfo = { | 823 var wallpaperInfo = { |
582 baseURL: this.manifest_.wallpaper_list[key].base_url, | 824 baseURL: this.manifest_.wallpaper_list[key].base_url, |
583 dynamicURL: this.manifest_.wallpaper_list[key].dynamic_url, | |
584 layout: this.manifest_.wallpaper_list[key].default_layout, | 825 layout: this.manifest_.wallpaper_list[key].default_layout, |
826 source: wallpapers.WallpaperSourceEnum.Online, | |
827 availableOffline: false, | |
585 author: this.manifest_.wallpaper_list[key].author, | 828 author: this.manifest_.wallpaper_list[key].author, |
586 authorWebsite: this.manifest_.wallpaper_list[key].author_website, | 829 authorWebsite: this.manifest_.wallpaper_list[key].author_website, |
587 availableOffline: false | 830 dynamicURL: this.manifest_.wallpaper_list[key].dynamic_url |
588 }; | 831 }; |
589 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1; | 832 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1; |
590 var fileName = wallpaperInfo.baseURL.substring(startIndex) + | 833 var fileName = wallpaperInfo.baseURL.substring(startIndex) + |
591 HighResolutionSuffix; | 834 HighResolutionSuffix; |
592 if (this.downloadedListMap_ && | 835 if (this.downloadedListMap_ && |
593 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { | 836 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { |
594 wallpaperInfo.availableOffline = true; | 837 wallpaperInfo.availableOffline = true; |
595 } | 838 } |
596 wallpapersDataModel.push(wallpaperInfo); | 839 wallpapersDataModel.push(wallpaperInfo); |
597 var url = this.manifest_.wallpaper_list[key].base_url + | 840 var url = this.manifest_.wallpaper_list[key].base_url + |
598 HighResolutionSuffix; | 841 HighResolutionSuffix; |
599 if (url == this.currentWallpaper_) { | 842 if (url == this.currentWallpaper_) { |
600 selectedItem = wallpaperInfo; | 843 selectedItem = wallpaperInfo; |
601 } | 844 } |
602 } | 845 } |
603 } | 846 } |
604 this.wallpaperGrid_.dataModel = wallpapersDataModel; | 847 this.wallpaperGrid_.dataModel = wallpapersDataModel; |
605 this.wallpaperGrid_.selectedItem = selectedItem; | 848 this.wallpaperGrid_.selectedItem = selectedItem; |
606 this.wallpaperGrid_.activeItem = selectedItem; | 849 this.wallpaperGrid_.activeItem = selectedItem; |
607 } | 850 } |
608 }; | 851 }; |
609 | 852 |
610 })(); | 853 })(); |
OLD | NEW |