Chromium Code Reviews| 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 * Removes the oldest custom wallpaper. If the oldest one is set as current | |
| 421 * wallpaper, removes the second oldest one to free some space. This should | |
| 422 * only be called when exceeding wallpaper quota. | |
| 316 */ | 423 */ |
| 317 WallpaperManager.prototype.onThumbnailClicked_ = function() { | 424 WallpaperManager.prototype.removeOldestWallpaper_ = function() { |
| 425 // Custom wallpapers should already sorted when put to the data model. The | |
| 426 // last element is the add new button, need to exclude it as well. | |
| 427 var oldestIndex = this.wallpaperGrid_.dataModel.length - 2; | |
| 428 var item = this.wallpaperGrid_.dataModel.item(oldestIndex); | |
| 429 if (!item || item.source != wallpapers.WallpaperSourceEnum.Custom) | |
| 430 return; | |
| 431 console.error(item.baseURL); | |
| 432 if (item.baseURL == this.currentWallpaper_) | |
| 433 item = this.wallpaperGrid_.dataModel.item(--oldestIndex); | |
| 434 if (item) { | |
| 435 this.removeCustomWallpaper(item.baseURL); | |
| 436 this.wallpaperGrid_.dataModel.splice(oldestIndex, 1); | |
| 437 } | |
| 438 }; | |
| 439 | |
| 440 /* | |
| 441 * Shows an error message to user and log the failed reason in console. | |
| 442 */ | |
| 443 WallpaperManager.prototype.onFileSystemError_ = function(e) { | |
| 444 var msg = ''; | |
| 445 switch (e.code) { | |
| 446 case FileError.QUOTA_EXCEEDED_ERR: | |
| 447 msg = 'QUOTA_EXCEEDED_ERR'; | |
| 448 this.removeOldestWallpaper_(); | |
|
flackr
2013/03/07 14:46:47
This won't retry saving the wallpaper though right
bshe
2013/03/07 16:13:05
Right. If we retry to save wallpaper here, it may
flackr
2013/03/07 18:03:17
Thanks. Please add TODO referencing bug.
On 2013/
| |
| 449 break; | |
| 450 case FileError.NOT_FOUND_ERR: | |
| 451 msg = 'NOT_FOUND_ERR'; | |
| 452 break; | |
| 453 case FileError.SECURITY_ERR: | |
| 454 msg = 'SECURITY_ERR'; | |
| 455 break; | |
| 456 case FileError.INVALID_MODIFICATION_ERR: | |
| 457 msg = 'INVALID_MODIFICATION_ERR'; | |
| 458 break; | |
| 459 case FileError.INVALID_STATE_ERR: | |
| 460 msg = 'INVALID_STATE_ERR'; | |
| 461 break; | |
| 462 default: | |
| 463 msg = 'Unknown Error'; | |
| 464 break; | |
| 465 } | |
| 466 console.error('Error: ' + msg); | |
| 467 this.showError_(str('accessFileFailure')); | |
| 468 }; | |
| 469 | |
| 470 /** | |
| 471 * Handles click on a different thumbnail in wallpaper grid. | |
| 472 */ | |
| 473 WallpaperManager.prototype.onThumbnailSelectionChanged_ = function() { | |
| 318 var selectedItem = this.wallpaperGrid_.selectedItem; | 474 var selectedItem = this.wallpaperGrid_.selectedItem; |
| 319 if (selectedItem && selectedItem.dynamicURL && | 475 if (selectedItem && selectedItem.source == 'ADDNEW') |
| 476 return; | |
| 477 | |
| 478 if (selectedItem && selectedItem.baseURL && | |
| 320 !this.wallpaperGrid_.inProgramSelection) { | 479 !this.wallpaperGrid_.inProgramSelection) { |
| 321 var wallpaperURL = selectedItem.baseURL + HighResolutionSuffix; | 480 if (selectedItem.source == wallpapers.WallpaperSourceEnum.Custom) { |
| 322 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem); | 481 var items = {}; |
| 323 var self = this; | 482 var key = selectedItem.baseURL; |
| 324 | 483 var self = this; |
| 325 chrome.wallpaperPrivate.setWallpaperIfExist(wallpaperURL, | 484 this.storage_.get(key, function(items) { |
| 326 selectedItem.layout, | 485 selectedItem.layout = items[key] ? items[key] : 'CENTER_CROPPED'; |
| 327 'ONLINE', | 486 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 }); | 487 }); |
| 359 self.wallpaperRequest_.addEventListener('error', function() { | 488 } else { |
| 360 self.showError_(str('downloadFailed')); | 489 this.setSelectedWallpaper_(selectedItem); |
| 361 }); | 490 } |
| 362 }); | |
| 363 } | 491 } |
| 364 this.setWallpaperAttribution_(selectedItem); | 492 this.setWallpaperAttribution_(selectedItem); |
| 365 }; | 493 }; |
| 366 | 494 |
| 367 /** | 495 /** |
| 368 * Set attributions of wallpaper with given URL. If URL is not valid, clear | 496 * Set attributions of wallpaper with given URL. If URL is not valid, clear |
| 369 * the attributions. | 497 * the attributions. |
| 370 * @param {{baseURL: string, dynamicURL: string, layout: string, | 498 * @param {{baseURL: string, dynamicURL: string, layout: string, |
| 371 * author: string, authorWebsite: string, availableOffline: boolean}} | 499 * author: string, authorWebsite: string, availableOffline: boolean}} |
| 372 * selectedItem selected wallpaper item in grid. | 500 * selectedItem selected wallpaper item in grid. |
| 373 * @private | 501 * @private |
| 374 */ | 502 */ |
| 375 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { | 503 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { |
| 376 if (selectedItem) { | 504 if (selectedItem) { |
| 377 $('author-name').textContent = selectedItem.author; | 505 $('author-name').textContent = selectedItem.author; |
| 378 $('author-website').textContent = $('author-website').href = | 506 $('author-website').textContent = $('author-website').href = |
| 379 selectedItem.authorWebsite; | 507 selectedItem.authorWebsite; |
| 380 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL, | 508 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL, |
| 509 selectedItem.source, | |
| 381 function(data) { | 510 function(data) { |
| 382 var img = $('attribute-image'); | 511 var img = $('attribute-image'); |
| 383 if (data) { | 512 if (data) { |
| 384 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'}); | 513 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'}); |
| 385 img.src = window.URL.createObjectURL(blob); | 514 img.src = window.URL.createObjectURL(blob); |
| 386 img.addEventListener('load', function(e) { | 515 img.addEventListener('load', function(e) { |
| 387 window.URL.revokeObjectURL(this.src); | 516 window.URL.revokeObjectURL(this.src); |
| 388 }); | 517 }); |
| 389 } else { | 518 } else { |
| 390 img.src = ''; | 519 img.src = ''; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 }; | 588 }; |
| 460 | 589 |
| 461 /** | 590 /** |
| 462 * Handles the custom wallpaper which user selected from file manager. Called | 591 * Handles the custom wallpaper which user selected from file manager. Called |
| 463 * when users select a file. | 592 * when users select a file. |
| 464 */ | 593 */ |
| 465 WallpaperManager.prototype.onFileSelectorChanged_ = function() { | 594 WallpaperManager.prototype.onFileSelectorChanged_ = function() { |
| 466 var files = $('file-selector').files; | 595 var files = $('file-selector').files; |
| 467 if (files.length != 1) | 596 if (files.length != 1) |
| 468 console.error('More than one files are selected or no file selected'); | 597 console.error('More than one files are selected or no file selected'); |
| 469 var file = files[0]; | 598 if (!files[0].type.match('image/jpeg')) { |
| 470 if (!file.type.match('image/jpeg')) { | |
| 471 this.showError_(str('invalidWallpaper')); | 599 this.showError_(str('invalidWallpaper')); |
| 472 return; | 600 return; |
| 473 } | 601 } |
| 474 var reader = new FileReader(); | 602 var layout = getSelectedLayout(); |
| 475 reader.readAsArrayBuffer(files[0]); | |
| 476 var self = this; | 603 var self = this; |
| 477 reader.addEventListener('error', function(e) { | 604 var errorHandler = this.onFileSystemError_.bind(this); |
| 478 self.showError_(str('accessFileFailure')); | 605 var setSelectedFile = function(file, layout, fileName) { |
| 479 }); | 606 var saveThumbnail = function(thumbnail) { |
| 480 reader.addEventListener('load', function(e) { | 607 var success = function(dirEntry) { |
| 481 self.customWallpaperData_ = e.target.result; | 608 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { |
| 482 self.refreshWallpaper_(self.customWallpaperData_); | 609 fileEntry.createWriter(function(fileWriter) { |
| 483 }); | 610 fileWriter.onwriteend = function(e) { |
| 484 this.generateThumbnail_(files[0]); | 611 $('set-wallpaper-layout').disabled = false; |
| 612 var wallpaperInfo = { | |
| 613 baseURL: fileName, | |
| 614 layout: layout, | |
| 615 source: wallpapers.WallpaperSourceEnum.Custom, | |
| 616 availableOffline: true | |
| 617 }; | |
| 618 self.currentWallpaper_ = fileName; | |
| 619 var items = {}; | |
| 620 items[self.currentWallpaper_] = layout; | |
| 621 self.storage_.set(items, function() {}); | |
| 622 self.wallpaperGrid_.dataModel.splice(0, 0, wallpaperInfo); | |
| 623 self.wallpaperGrid_.selectedItem = wallpaperInfo; | |
| 624 self.wallpaperGrid_.activeItem = wallpaperInfo; | |
| 625 }; | |
| 626 | |
| 627 fileWriter.onerror = errorHandler; | |
| 628 | |
| 629 var blob = new Blob([new Int8Array(thumbnail)], | |
| 630 {'type' : 'image\/jpeg'}); | |
| 631 fileWriter.write(blob); | |
| 632 }, errorHandler); | |
| 633 }, errorHandler); | |
| 634 }; | |
| 635 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL, | |
| 636 success, errorHandler); | |
| 637 }; | |
| 638 | |
| 639 var success = function(dirEntry) { | |
| 640 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { | |
| 641 fileEntry.createWriter(function(fileWriter) { | |
| 642 fileWriter.addEventListener('writeend', function(e) { | |
| 643 var reader = new FileReader(); | |
| 644 reader.readAsArrayBuffer(file); | |
| 645 reader.addEventListener('error', errorHandler); | |
| 646 reader.addEventListener('load', function(e) { | |
| 647 self.setCustomWallpaper(e.target.result, layout, true, fileName, | |
| 648 saveThumbnail, function() { | |
| 649 self.removeCustomWallpaper(fileName); | |
| 650 errorHandler(); | |
| 651 }); | |
| 652 }); | |
| 653 }); | |
| 654 | |
| 655 fileWriter.addEventListener('error', errorHandler); | |
| 656 fileWriter.write(file); | |
| 657 }, errorHandler); | |
| 658 }, errorHandler); | |
| 659 }; | |
| 660 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success, | |
| 661 errorHandler); | |
| 662 }; | |
| 663 setSelectedFile(files[0], layout, new Date().getTime().toString()); | |
| 485 }; | 664 }; |
| 486 | 665 |
| 487 /** | 666 /** |
| 488 * Refreshes the custom wallpaper with the current selected layout. | 667 * Removes wallpaper and thumbnail with fileName from FileSystem. |
| 489 * @param {ArrayBuffer} customWallpaper The raw wallpaper file data. | 668 * @param {string} fileName The file name of wallpaper and thumbnail to be |
| 669 * removed. | |
| 490 */ | 670 */ |
| 491 WallpaperManager.prototype.refreshWallpaper_ = function(customWallpaper) { | 671 WallpaperManager.prototype.removeCustomWallpaper = function(fileName) { |
| 492 var setWallpaperLayout = $('set-wallpaper-layout'); | 672 var errorHandler = this.onFileSystemError_.bind(this); |
| 493 var layout = | 673 var self = this; |
| 494 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; | 674 var removeFile = function(fileName) { |
| 495 chrome.wallpaperPrivate.setCustomWallpaper(customWallpaper, | 675 var success = function(dirEntry) { |
| 496 layout, | 676 dirEntry.getFile(fileName, {create: false}, function(fileEntry) { |
| 497 this.onFinished_.bind(this)); | 677 fileEntry.remove(function() { |
| 498 this.currentWallpaper_ = 'CUSTOM'; | 678 }, errorHandler); |
| 679 }, errorHandler); | |
| 680 } | |
| 681 | |
| 682 // Removes copy of original. | |
| 683 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, success, | |
| 684 errorHandler); | |
| 685 | |
| 686 // Removes generated thumbnail. | |
| 687 self.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.THUMBNAIL, success, | |
| 688 errorHandler); | |
| 689 }; | |
| 690 removeFile(fileName); | |
| 499 }; | 691 }; |
| 500 | 692 |
| 501 /** | 693 /** |
| 502 * Sets wallpaper finished. Displays error message in butter bar if any. | 694 * Sets current wallpaper and generate thumbnail if generateThumbnail is true. |
| 695 * @param {ArrayBuffer} wallpaper The binary representation of wallpaper. | |
| 696 * @param {string} layout The user selected wallpaper layout. | |
| 697 * @param {boolean} generateThumbnail True if need to generate thumbnail. | |
| 698 * @param {string} fileName The unique file name of wallpaper. | |
| 699 * @param {function(thumbnail):void} success Success callback. If | |
| 700 * generateThumbnail is true, the callback parameter should have the | |
| 701 * generated thumbnail. | |
| 702 * @param {function(e):void} failure Failure callback. Called when there is an | |
| 703 * error from FileSystem. | |
| 704 */ | |
| 705 WallpaperManager.prototype.setCustomWallpaper = function(wallpaper, | |
| 706 layout, | |
| 707 generateThumbnail, | |
| 708 fileName, | |
| 709 success, | |
| 710 failure) { | |
| 711 var self = this; | |
| 712 var onFinished = function(opt_thumbnail) { | |
| 713 if (chrome.runtime.lastError != undefined) { | |
| 714 self.showError_(chrome.runtime.lastError.message); | |
| 715 $('set-wallpaper-layout').disabled = true; | |
| 716 } else { | |
| 717 success(opt_thumbnail); | |
| 718 } | |
| 719 }; | |
| 720 | |
| 721 chrome.wallpaperPrivate.setCustomWallpaper(wallpaper, layout, | |
| 722 generateThumbnail, | |
| 723 fileName, onFinished); | |
| 724 }; | |
| 725 | |
| 726 /** | |
| 727 * Sets wallpaper finished. Displays error message if any. | |
| 503 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper | 728 * @param {WallpaperThumbnailsGridItem=} opt_selectedGridItem The wallpaper |
| 504 * thumbnail grid item. It extends from cr.ui.ListItem. | 729 * thumbnail grid item. It extends from cr.ui.ListItem. |
| 505 * @param {{baseURL: string, dynamicURL: string, layout: string, | 730 * @param {{baseURL: string, layout: string, source: string, |
| 506 * author: string, authorWebsite: string, | 731 * availableOffline: boolean, opt_dynamicURL: string, |
| 507 * availableOffline: boolean}=} | 732 * opt_author: string, opt_authorWebsite: string}=} |
| 508 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data | 733 * opt_selectedItem the selected item in WallpaperThumbnailsGrid's data |
| 509 * model. | 734 * model. |
| 510 */ | 735 */ |
| 511 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem, | 736 WallpaperManager.prototype.onFinished_ = function(opt_selectedGridItem, |
| 512 opt_selectedItem) { | 737 opt_selectedItem) { |
| 513 if (opt_selectedGridItem) | 738 if (opt_selectedGridItem) |
| 514 this.progressManager_.hideProgressBar(opt_selectedGridItem); | 739 this.progressManager_.hideProgressBar(opt_selectedGridItem); |
| 515 | 740 |
| 516 if (chrome.runtime.lastError != undefined) { | 741 if (chrome.runtime.lastError != undefined) { |
| 517 this.showError_(chrome.runtime.lastError.message); | 742 this.showError_(chrome.runtime.lastError.message); |
| 518 } else if (opt_selectedItem) { | 743 } else if (opt_selectedItem) { |
| 519 this.wallpaperGrid_.activeItem = opt_selectedItem; | 744 this.wallpaperGrid_.activeItem = opt_selectedItem; |
| 520 } | 745 } |
| 521 }; | 746 }; |
| 522 | 747 |
| 523 /** | 748 /** |
| 524 * Handles the layout setting change of custom wallpaper. | 749 * Handles the layout setting change of custom wallpaper. |
| 525 */ | 750 */ |
| 526 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { | 751 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { |
| 527 var setWallpaperLayout = $('set-wallpaper-layout'); | 752 var layout = getSelectedLayout(); |
| 528 var layout = | 753 var self = this; |
| 529 setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; | 754 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, function() { |
| 530 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, | 755 if (chrome.runtime.lastError != undefined) { |
| 531 this.onFinished_.bind(this)); | 756 self.showError_(chrome.runtime.lastError.message); |
| 757 self.removeCustomWallpaper(fileName); | |
| 758 $('set-wallpaper-layout').disabled = true; | |
| 759 } else { | |
| 760 var items = {}; | |
| 761 items[self.currentWallpaper_] = layout; | |
| 762 self.storage_.set(items, function() {}); | |
| 763 } | |
| 764 }); | |
| 532 }; | 765 }; |
| 533 | 766 |
| 534 /** | 767 /** |
| 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. | 768 * Handles user clicking on a different category. |
| 560 */ | 769 */ |
| 561 WallpaperManager.prototype.onCategoriesChange_ = function() { | 770 WallpaperManager.prototype.onCategoriesChange_ = function() { |
| 562 var categoriesList = this.categoriesList_; | 771 var categoriesList = this.categoriesList_; |
| 563 var selectedIndex = categoriesList.selectionModel.selectedIndex; | 772 var selectedIndex = categoriesList.selectionModel.selectedIndex; |
| 564 if (selectedIndex == -1) | 773 if (selectedIndex == -1) |
| 565 return; | 774 return; |
| 566 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); | 775 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); |
| 567 var bar = $('bar'); | 776 var bar = $('bar'); |
| 568 bar.style.left = selectedListItem.offsetLeft + 'px'; | 777 bar.style.left = selectedListItem.offsetLeft + 'px'; |
| 569 bar.style.width = selectedListItem.offsetWidth + 'px'; | 778 bar.style.width = selectedListItem.offsetWidth + 'px'; |
| 570 | 779 |
| 780 var wallpapersDataModel = new cr.ui.ArrayDataModel([]); | |
| 781 var selectedItem; | |
| 571 if (selectedListItem.custom) { | 782 if (selectedListItem.custom) { |
| 572 this.showCustomContainer_(true); | 783 $('online-wallpaper-attribute').hidden = true; |
| 784 var errorHandler = this.onFileSystemError_.bind(this); | |
| 785 var toArray = function(list) { | |
| 786 return Array.prototype.slice.call(list || [], 0); | |
| 787 } | |
| 788 | |
| 789 var self = this; | |
| 790 var processResults = function(entries) { | |
| 791 for (var i = 0; i < entries.length; i++) { | |
| 792 var entry = entries[i]; | |
| 793 var wallpaperInfo = { | |
| 794 baseURL: entry.name, | |
| 795 // The layout will be replaced by the actual value saved in | |
| 796 // local storage when requested later. Layout is not important | |
| 797 // for constructing thumbnails grid, we use CENTER_CROPPED here | |
| 798 // to speed up the process of constructing. So we do not need to | |
| 799 // wait for fetching correct layout. | |
| 800 layout: 'CENTER_CROPPED', | |
| 801 source: wallpapers.WallpaperSourceEnum.Custom, | |
| 802 availableOffline: true | |
| 803 }; | |
| 804 if (self.currentWallpaper_ == entry.name) | |
| 805 selectedItem = wallpaperInfo; | |
| 806 wallpapersDataModel.push(wallpaperInfo); | |
| 807 } | |
| 808 var lastElement = { | |
| 809 baseURL: '', | |
| 810 layout: '', | |
| 811 source: 'ADDNEW', | |
| 812 availableOffline: true | |
| 813 }; | |
| 814 wallpapersDataModel.push(lastElement); | |
| 815 self.wallpaperGrid_.dataModel = wallpapersDataModel; | |
| 816 self.wallpaperGrid_.selectedItem = selectedItem; | |
| 817 self.wallpaperGrid_.activeItem = selectedItem; | |
| 818 } | |
| 819 | |
| 820 var success = function(dirEntry) { | |
| 821 var dirReader = dirEntry.createReader(); | |
| 822 var entries = []; | |
| 823 // All of a directory's entries are not guaranteed to return in a single | |
| 824 // call. | |
| 825 var readEntries = function() { | |
| 826 dirReader.readEntries(function(results) { | |
| 827 if (!results.length) { | |
| 828 processResults(entries.sort()); | |
| 829 } else { | |
| 830 entries = entries.concat(toArray(results)); | |
| 831 readEntries(); | |
| 832 } | |
| 833 }, errorHandler); | |
| 834 }; | |
| 835 readEntries(); // Start reading dirs. | |
| 836 } | |
| 837 this.wallpaperDirs_.getDirectory(WallpaperDirNameEnum.ORIGINAL, | |
| 838 success, errorHandler); | |
| 573 } else { | 839 } else { |
| 574 this.showCustomContainer_(false); | 840 $('online-wallpaper-attribute').hidden = false; |
| 575 var selectedItem; | |
| 576 var wallpapersDataModel = new cr.ui.ArrayDataModel([]); | |
| 577 for (var key in this.manifest_.wallpaper_list) { | 841 for (var key in this.manifest_.wallpaper_list) { |
| 578 if (selectedIndex == AllCategoryIndex || | 842 if (selectedIndex == AllCategoryIndex || |
| 579 this.manifest_.wallpaper_list[key].categories.indexOf( | 843 this.manifest_.wallpaper_list[key].categories.indexOf( |
| 580 selectedIndex - OnlineCategoriesOffset) != -1) { | 844 selectedIndex - OnlineCategoriesOffset) != -1) { |
| 581 var wallpaperInfo = { | 845 var wallpaperInfo = { |
| 582 baseURL: this.manifest_.wallpaper_list[key].base_url, | 846 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, | 847 layout: this.manifest_.wallpaper_list[key].default_layout, |
| 848 source: wallpapers.WallpaperSourceEnum.Online, | |
| 849 availableOffline: false, | |
| 585 author: this.manifest_.wallpaper_list[key].author, | 850 author: this.manifest_.wallpaper_list[key].author, |
| 586 authorWebsite: this.manifest_.wallpaper_list[key].author_website, | 851 authorWebsite: this.manifest_.wallpaper_list[key].author_website, |
| 587 availableOffline: false | 852 dynamicURL: this.manifest_.wallpaper_list[key].dynamic_url |
| 588 }; | 853 }; |
| 589 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1; | 854 var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1; |
| 590 var fileName = wallpaperInfo.baseURL.substring(startIndex) + | 855 var fileName = wallpaperInfo.baseURL.substring(startIndex) + |
| 591 HighResolutionSuffix; | 856 HighResolutionSuffix; |
| 592 if (this.downloadedListMap_ && | 857 if (this.downloadedListMap_ && |
| 593 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { | 858 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { |
| 594 wallpaperInfo.availableOffline = true; | 859 wallpaperInfo.availableOffline = true; |
| 595 } | 860 } |
| 596 wallpapersDataModel.push(wallpaperInfo); | 861 wallpapersDataModel.push(wallpaperInfo); |
| 597 var url = this.manifest_.wallpaper_list[key].base_url + | 862 var url = this.manifest_.wallpaper_list[key].base_url + |
| 598 HighResolutionSuffix; | 863 HighResolutionSuffix; |
| 599 if (url == this.currentWallpaper_) { | 864 if (url == this.currentWallpaper_) { |
| 600 selectedItem = wallpaperInfo; | 865 selectedItem = wallpaperInfo; |
| 601 } | 866 } |
| 602 } | 867 } |
| 603 } | 868 } |
| 604 this.wallpaperGrid_.dataModel = wallpapersDataModel; | 869 this.wallpaperGrid_.dataModel = wallpapersDataModel; |
| 605 this.wallpaperGrid_.selectedItem = selectedItem; | 870 this.wallpaperGrid_.selectedItem = selectedItem; |
| 606 this.wallpaperGrid_.activeItem = selectedItem; | 871 this.wallpaperGrid_.activeItem = selectedItem; |
| 607 } | 872 } |
| 608 }; | 873 }; |
| 609 | 874 |
| 610 })(); | 875 })(); |
| OLD | NEW |