| 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 * |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 this.wallpaperRequest_ = null; | 24 this.wallpaperRequest_ = null; |
| 25 this.wallpaperDirs_ = WallpaperDirectories.getInstance(); | 25 this.wallpaperDirs_ = WallpaperDirectories.getInstance(); |
| 26 this.preManifestDomInit_(); | 26 this.preManifestDomInit_(); |
| 27 this.fetchManifest_(); | 27 this.fetchManifest_(); |
| 28 } | 28 } |
| 29 | 29 |
| 30 // Anonymous 'namespace'. | 30 // Anonymous 'namespace'. |
| 31 // TODO(bshe): Get rid of anonymous namespace. | 31 // TODO(bshe): Get rid of anonymous namespace. |
| 32 (function() { | 32 (function() { |
| 33 | 33 |
| 34 /** | 34 /** |
| 35 * URL of the learn more page for wallpaper picker. | 35 * URL of the learn more page for wallpaper picker. |
| 36 */ | 36 */ |
| 37 /** @const */ var LearnMoreURL = | 37 /** @const */ var LearnMoreURL = |
| 38 'https://support.google.com/chromebook/?p=wallpaper_fileerror&hl=' + | 38 'https://support.google.com/chromebook/?p=wallpaper_fileerror&hl=' + |
| 39 navigator.language; | 39 navigator.language; |
| 40 | 40 |
| 41 /** | 41 /** |
| 42 * Index of the All category. It is the first category in wallpaper picker. | 42 * Index of the All category. It is the first category in wallpaper picker. |
| 43 */ | 43 */ |
| 44 /** @const */ var AllCategoryIndex = 0; | 44 /** @const */ var AllCategoryIndex = 0; |
| 45 | 45 |
| 46 /** | 46 /** |
| 47 * Index offset of categories parsed from manifest. The All category is added | 47 * Index offset of categories parsed from manifest. The All category is added |
| 48 * before them. So the offset is 1. | 48 * before them. So the offset is 1. |
| 49 */ | 49 */ |
| 50 /** @const */ var OnlineCategoriesOffset = 1; | 50 /** @const */ var OnlineCategoriesOffset = 1; |
| 51 | 51 |
| 52 /** | 52 /** |
| 53 * Returns a translated string. | 53 * Returns a translated string. |
| 54 * | 54 * |
| 55 * Wrapper function to make dealing with translated strings more concise. | 55 * Wrapper function to make dealing with translated strings more concise. |
| 56 * | 56 * |
| 57 * @param {string} id The id of the string to return. | 57 * @param {string} id The id of the string to return. |
| 58 * @return {string} The translated string. | 58 * @return {string} The translated string. |
| 59 */ | 59 */ |
| 60 function str(id) { | 60 function str(id) { |
| 61 return loadTimeData.getString(id); | 61 return loadTimeData.getString(id); |
| 62 } | 62 } |
| 63 | 63 |
| 64 /** | 64 /** |
| 65 * Returns the base name for |file_path|. | 65 * Returns the base name for |file_path|. |
| 66 * @param {string} file_path The path of the file. | 66 * @param {string} file_path The path of the file. |
| 67 * @return {string} The base name of the file. | 67 * @return {string} The base name of the file. |
| 68 */ | 68 */ |
| 69 function getBaseName(file_path) { | 69 function getBaseName(file_path) { |
| 70 return file_path.substring(file_path.lastIndexOf('/') + 1); | 70 return file_path.substring(file_path.lastIndexOf('/') + 1); |
| 71 } | 71 } |
| 72 | 72 |
| 73 /** | 73 /** |
| 74 * Retruns the current selected layout. | 74 * Retruns the current selected layout. |
| 75 * @return {string} The selected layout. | 75 * @return {string} The selected layout. |
| 76 */ | 76 */ |
| 77 function getSelectedLayout() { | 77 function getSelectedLayout() { |
| 78 var setWallpaperLayout = $('set-wallpaper-layout'); | 78 var setWallpaperLayout = $('set-wallpaper-layout'); |
| 79 return setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; | 79 return setWallpaperLayout.options[setWallpaperLayout.selectedIndex].value; |
| 80 } | 80 } |
| 81 | 81 |
| 82 /** | 82 /** |
| 83 * Loads translated strings. | 83 * Loads translated strings. |
| 84 */ | 84 */ |
| 85 WallpaperManager.initStrings = function(callback) { | 85 WallpaperManager.initStrings = function(callback) { |
| 86 chrome.wallpaperPrivate.getStrings(function(strings) { | 86 chrome.wallpaperPrivate.getStrings(function(strings) { |
| 87 loadTimeData.data = strings; | 87 loadTimeData.data = strings; |
| 88 if (callback) | 88 if (callback) |
| 89 callback(); | 89 callback(); |
| 90 }); | 90 }); |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 /** | 93 /** |
| 94 * Requests wallpaper manifest file from server. | 94 * Requests wallpaper manifest file from server. |
| 95 */ | 95 */ |
| 96 WallpaperManager.prototype.fetchManifest_ = function() { | 96 WallpaperManager.prototype.fetchManifest_ = function() { |
| 97 var locale = navigator.language; | 97 var locale = navigator.language; |
| 98 if (!this.enableOnlineWallpaper_) { | 98 if (!this.enableOnlineWallpaper_) { |
| 99 this.postManifestDomInit_(); | 99 this.postManifestDomInit_(); |
| 100 return; | 100 return; |
| 101 } | 101 } |
| 102 | 102 |
| 103 var urls = [ | 103 var urls = [ |
| 104 str('manifestBaseURL') + locale + '.json', | 104 str('manifestBaseURL') + locale + '.json', |
| 105 // Fallback url. Use 'en' locale by default. | 105 // Fallback url. Use 'en' locale by default. |
| 106 str('manifestBaseURL') + 'en.json']; | 106 str('manifestBaseURL') + 'en.json' |
| 107 | 107 ]; |
| 108 var asyncFetchManifestFromUrls = function(urls, func, successCallback, | 108 |
| 109 failureCallback) { | 109 var asyncFetchManifestFromUrls = function( |
| 110 var index = 0; | 110 urls, func, successCallback, failureCallback) { |
| 111 var loop = { | 111 var index = 0; |
| 112 next: function() { | 112 var loop = { |
| 113 if (index < urls.length) { | 113 next: function() { |
| 114 func(loop, urls[index]); | 114 if (index < urls.length) { |
| 115 index++; | 115 func(loop, urls[index]); |
| 116 } else { | 116 index++; |
| 117 failureCallback(); | 117 } else { |
| 118 } | |
| 119 }, | |
| 120 | |
| 121 success: function(response) { | |
| 122 successCallback(response); | |
| 123 }, | |
| 124 | |
| 125 failure: function() { | |
| 126 failureCallback(); | 118 failureCallback(); |
| 127 } | 119 } |
| 128 }; | 120 }, |
| 129 loop.next(); | 121 |
| 130 }; | 122 success: function(response) { |
| 131 | 123 successCallback(response); |
| 132 var fetchManifestAsync = function(loop, url) { | 124 }, |
| 133 var xhr = new XMLHttpRequest(); | 125 |
| 134 try { | 126 failure: function() { |
| 135 xhr.addEventListener('loadend', function(e) { | 127 failureCallback(); |
| 136 if (this.status == 200 && this.responseText != null) { | |
| 137 try { | |
| 138 var manifest = JSON.parse(this.responseText); | |
| 139 loop.success(manifest); | |
| 140 } catch (e) { | |
| 141 loop.failure(); | |
| 142 } | |
| 143 } else { | |
| 144 loop.next(); | |
| 145 } | |
| 146 }); | |
| 147 xhr.open('GET', url, true); | |
| 148 xhr.send(null); | |
| 149 } catch (e) { | |
| 150 loop.failure(); | |
| 151 } | 128 } |
| 152 }; | 129 }; |
| 153 | 130 loop.next(); |
| 154 if (navigator.onLine) { | 131 }; |
| 155 asyncFetchManifestFromUrls(urls, fetchManifestAsync, | 132 |
| 156 this.onLoadManifestSuccess_.bind(this), | 133 var fetchManifestAsync = function(loop, url) { |
| 157 this.onLoadManifestFailed_.bind(this)); | 134 var xhr = new XMLHttpRequest(); |
| 158 } else { | 135 try { |
| 159 // If device is offline, fetches manifest from local storage. | 136 xhr.addEventListener('loadend', function(e) { |
| 160 // TODO(bshe): Always loading the offline manifest first and replacing | 137 if (this.status == 200 && this.responseText != null) { |
| 161 // with the online one when available. | 138 try { |
| 162 this.onLoadManifestFailed_(); | 139 var manifest = JSON.parse(this.responseText); |
| 140 loop.success(manifest); |
| 141 } catch (e) { |
| 142 loop.failure(); |
| 143 } |
| 144 } else { |
| 145 loop.next(); |
| 146 } |
| 147 }); |
| 148 xhr.open('GET', url, true); |
| 149 xhr.send(null); |
| 150 } catch (e) { |
| 151 loop.failure(); |
| 163 } | 152 } |
| 164 }; | 153 }; |
| 165 | 154 |
| 166 /** | 155 if (navigator.onLine) { |
| 167 * Shows error message in a centered dialog. | 156 asyncFetchManifestFromUrls( |
| 168 * @private | 157 urls, fetchManifestAsync, this.onLoadManifestSuccess_.bind(this), |
| 169 * @param {string} errroMessage The string to show in the error dialog. | 158 this.onLoadManifestFailed_.bind(this)); |
| 170 */ | 159 } else { |
| 171 WallpaperManager.prototype.showError_ = function(errorMessage) { | 160 // If device is offline, fetches manifest from local storage. |
| 172 document.querySelector('.error-message').textContent = errorMessage; | 161 // TODO(bshe): Always loading the offline manifest first and replacing |
| 173 $('error-container').hidden = false; | 162 // with the online one when available. |
| 163 this.onLoadManifestFailed_(); |
| 164 } |
| 165 }; |
| 166 |
| 167 /** |
| 168 * Shows error message in a centered dialog. |
| 169 * @private |
| 170 * @param {string} errroMessage The string to show in the error dialog. |
| 171 */ |
| 172 WallpaperManager.prototype.showError_ = function(errorMessage) { |
| 173 document.querySelector('.error-message').textContent = errorMessage; |
| 174 $('error-container').hidden = false; |
| 175 }; |
| 176 |
| 177 /** |
| 178 * Sets manifest loaded from server. Called after manifest is successfully |
| 179 * loaded. |
| 180 * @param {object} manifest The parsed manifest file. |
| 181 */ |
| 182 WallpaperManager.prototype.onLoadManifestSuccess_ = function(manifest) { |
| 183 this.manifest_ = manifest; |
| 184 WallpaperUtil.saveToLocalStorage(Constants.AccessLocalManifestKey, manifest); |
| 185 this.postManifestDomInit_(); |
| 186 }; |
| 187 |
| 188 // Sets manifest to previously saved object if any and shows connection error. |
| 189 // Called after manifest failed to load. |
| 190 WallpaperManager.prototype.onLoadManifestFailed_ = function() { |
| 191 var accessManifestKey = Constants.AccessLocalManifestKey; |
| 192 var self = this; |
| 193 Constants.WallpaperLocalStorage.get(accessManifestKey, function(items) { |
| 194 self.manifest_ = items[accessManifestKey] ? items[accessManifestKey] : null; |
| 195 self.showError_(str('connectionFailed')); |
| 196 self.postManifestDomInit_(); |
| 197 $('wallpaper-grid').classList.add('image-picker-offline'); |
| 198 }); |
| 199 }; |
| 200 |
| 201 /** |
| 202 * Toggle surprise me feature of wallpaper picker. It fires an storage |
| 203 * onChanged event. Event handler for that event is in event_page.js. |
| 204 * @private |
| 205 */ |
| 206 WallpaperManager.prototype.toggleSurpriseMe_ = function() { |
| 207 var self = this; |
| 208 var checkbox = $('surprise-me').querySelector('#checkbox'); |
| 209 var shouldEnable = !checkbox.classList.contains('checked'); |
| 210 var onSuccess = function() { |
| 211 if (chrome.runtime.lastError == null) { |
| 212 if (shouldEnable) { |
| 213 self.document_.body.removeAttribute('surprise-me-disabled'); |
| 214 checkbox.classList.add('checked'); |
| 215 // Hides the wallpaper set by message if there is any. |
| 216 $('wallpaper-set-by-message').textContent = ''; |
| 217 } else { |
| 218 // Unchecking the "Surprise me" checkbox falls back to the previous |
| 219 // wallpaper before "Surprise me" was turned on. |
| 220 if (self.wallpaperGrid_.activeItem) { |
| 221 self.setSelectedWallpaper_(self.wallpaperGrid_.activeItem); |
| 222 self.onWallpaperChanged_( |
| 223 self.wallpaperGrid_.activeItem, self.currentWallpaper_); |
| 224 } |
| 225 checkbox.classList.remove('checked'); |
| 226 self.document_.body.setAttribute('surprise-me-disabled', ''); |
| 227 } |
| 228 $('categories-list').disabled = shouldEnable; |
| 229 $('wallpaper-grid').disabled = shouldEnable; |
| 230 } else { |
| 231 // TODO(bshe): show error message to user. |
| 232 console.error('Failed to save surprise me option to chrome storage.'); |
| 233 } |
| 174 }; | 234 }; |
| 175 | 235 |
| 176 /** | 236 // To prevent the onChanged event being fired twice, we only save the value |
| 177 * Sets manifest loaded from server. Called after manifest is successfully | 237 // to sync storage if the sync theme is enabled, otherwise save it to local |
| 178 * loaded. | 238 // storage. |
| 179 * @param {object} manifest The parsed manifest file. | 239 WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) { |
| 180 */ | 240 if (syncEnabled) |
| 181 WallpaperManager.prototype.onLoadManifestSuccess_ = function(manifest) { | 241 WallpaperUtil.saveToSyncStorage( |
| 182 this.manifest_ = manifest; | 242 Constants.AccessSyncSurpriseMeEnabledKey, shouldEnable, onSuccess); |
| 183 WallpaperUtil.saveToLocalStorage(Constants.AccessLocalManifestKey, | 243 else |
| 184 manifest); | 244 WallpaperUtil.saveToLocalStorage( |
| 185 this.postManifestDomInit_(); | 245 Constants.AccessLocalSurpriseMeEnabledKey, shouldEnable, onSuccess); |
| 246 }); |
| 247 }; |
| 248 |
| 249 /** |
| 250 * One-time initialization of various DOM nodes. Fetching manifest may take a |
| 251 * long time due to slow connection. Dom nodes that do not depend on manifest |
| 252 * should be initialized here to unblock from manifest fetching. |
| 253 */ |
| 254 WallpaperManager.prototype.preManifestDomInit_ = function() { |
| 255 $('window-close-button').addEventListener('click', function() { |
| 256 window.close(); |
| 257 }); |
| 258 this.document_.defaultView.addEventListener( |
| 259 'resize', this.onResize_.bind(this)); |
| 260 this.document_.defaultView.addEventListener( |
| 261 'keydown', this.onKeyDown_.bind(this)); |
| 262 $('learn-more').href = LearnMoreURL; |
| 263 $('close-error').addEventListener('click', function() { |
| 264 $('error-container').hidden = true; |
| 265 }); |
| 266 $('close-wallpaper-selection').addEventListener('click', function() { |
| 267 $('wallpaper-selection-container').hidden = true; |
| 268 $('set-wallpaper-layout').disabled = true; |
| 269 }); |
| 270 }; |
| 271 |
| 272 /** |
| 273 * One-time initialization of various DOM nodes. Dom nodes that do depend on |
| 274 * manifest should be initialized here. |
| 275 */ |
| 276 WallpaperManager.prototype.postManifestDomInit_ = function() { |
| 277 i18nTemplate.process(this.document_, loadTimeData); |
| 278 this.initCategoriesList_(); |
| 279 this.initThumbnailsGrid_(); |
| 280 this.presetCategory_(); |
| 281 |
| 282 $('file-selector') |
| 283 .addEventListener('change', this.onFileSelectorChanged_.bind(this)); |
| 284 $('set-wallpaper-layout') |
| 285 .addEventListener('change', this.onWallpaperLayoutChanged_.bind(this)); |
| 286 |
| 287 // Always prefer the value from local filesystem to avoid the time window |
| 288 // of setting the third party app name and the third party wallpaper. |
| 289 var getThirdPartyAppName = function(callback) { |
| 290 Constants.WallpaperLocalStorage.get( |
| 291 Constants.AccessLocalWallpaperInfoKey, function(items) { |
| 292 var localInfo = items[Constants.AccessLocalWallpaperInfoKey]; |
| 293 if (localInfo && localInfo.hasOwnProperty('appName')) |
| 294 callback(localInfo.appName); |
| 295 else if (loadTimeData.valueExists('wallpaperAppName')) |
| 296 callback(str('wallpaperAppName')); |
| 297 else |
| 298 callback(''); |
| 299 }); |
| 186 }; | 300 }; |
| 187 | 301 |
| 188 // Sets manifest to previously saved object if any and shows connection error. | 302 getThirdPartyAppName(function(appName) { |
| 189 // Called after manifest failed to load. | 303 if (!!appName) { |
| 190 WallpaperManager.prototype.onLoadManifestFailed_ = function() { | 304 $('wallpaper-set-by-message').textContent = |
| 191 var accessManifestKey = Constants.AccessLocalManifestKey; | 305 loadTimeData.getStringF('currentWallpaperSetByMessage', appName); |
| 306 $('wallpaper-grid').classList.add('small'); |
| 307 } else { |
| 308 $('wallpaper-grid').classList.remove('small'); |
| 309 } |
| 310 }); |
| 311 |
| 312 if (this.enableOnlineWallpaper_) { |
| 192 var self = this; | 313 var self = this; |
| 193 Constants.WallpaperLocalStorage.get(accessManifestKey, function(items) { | 314 self.document_.body.setAttribute('surprise-me-disabled', ''); |
| 194 self.manifest_ = items[accessManifestKey] ? | 315 $('surprise-me').hidden = false; |
| 195 items[accessManifestKey] : null; | 316 $('surprise-me') |
| 196 self.showError_(str('connectionFailed')); | 317 .addEventListener('click', this.toggleSurpriseMe_.bind(this)); |
| 197 self.postManifestDomInit_(); | 318 var onSurpriseMeEnabled = function() { |
| 319 $('surprise-me').querySelector('#checkbox').classList.add('checked'); |
| 320 $('categories-list').disabled = true; |
| 321 $('wallpaper-grid').disabled = true; |
| 322 self.document_.body.removeAttribute('surprise-me-disabled'); |
| 323 }; |
| 324 |
| 325 WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) { |
| 326 // Surprise me has been moved from local to sync storage, prefer |
| 327 // values from sync, but if unset check local and update synced pref |
| 328 // if applicable. |
| 329 if (syncEnabled) { |
| 330 Constants.WallpaperSyncStorage.get( |
| 331 Constants.AccessSyncSurpriseMeEnabledKey, function(items) { |
| 332 if (items.hasOwnProperty( |
| 333 Constants.AccessSyncSurpriseMeEnabledKey)) { |
| 334 if (items[Constants.AccessSyncSurpriseMeEnabledKey]) { |
| 335 onSurpriseMeEnabled(); |
| 336 } |
| 337 } else { |
| 338 Constants.WallpaperLocalStorage.get( |
| 339 Constants.AccessLocalSurpriseMeEnabledKey, function(items) { |
| 340 if (items.hasOwnProperty( |
| 341 Constants.AccessLocalSurpriseMeEnabledKey)) { |
| 342 WallpaperUtil.saveToSyncStorage( |
| 343 Constants.AccessSyncSurpriseMeEnabledKey, |
| 344 items[Constants.AccessLocalSurpriseMeEnabledKey]); |
| 345 if (items[Constants.AccessLocalSurpriseMeEnabledKey]) { |
| 346 onSurpriseMeEnabled(); |
| 347 } |
| 348 } |
| 349 }); |
| 350 } |
| 351 }); |
| 352 } else { |
| 353 Constants.WallpaperLocalStorage.get( |
| 354 Constants.AccessLocalSurpriseMeEnabledKey, function(items) { |
| 355 if (items.hasOwnProperty( |
| 356 Constants.AccessLocalSurpriseMeEnabledKey)) { |
| 357 if (items[Constants.AccessLocalSurpriseMeEnabledKey]) { |
| 358 onSurpriseMeEnabled(); |
| 359 } |
| 360 } |
| 361 }); |
| 362 } |
| 363 }); |
| 364 |
| 365 window.addEventListener('offline', function() { |
| 366 chrome.wallpaperPrivate.getOfflineWallpaperList(function(lists) { |
| 367 if (!self.downloadedListMap_) |
| 368 self.downloadedListMap_ = {}; |
| 369 for (var i = 0; i < lists.length; i++) { |
| 370 self.downloadedListMap_[lists[i]] = true; |
| 371 } |
| 372 var thumbnails = self.document_.querySelectorAll('.thumbnail'); |
| 373 for (var i = 0; i < thumbnails.length; i++) { |
| 374 var thumbnail = thumbnails[i]; |
| 375 var url = self.wallpaperGrid_.dataModel.item(i).baseURL; |
| 376 var fileName = getBaseName(url) + Constants.HighResolutionSuffix; |
| 377 if (self.downloadedListMap_ && |
| 378 self.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { |
| 379 thumbnail.offline = true; |
| 380 } |
| 381 } |
| 382 }); |
| 198 $('wallpaper-grid').classList.add('image-picker-offline'); | 383 $('wallpaper-grid').classList.add('image-picker-offline'); |
| 199 }); | 384 }); |
| 200 }; | 385 window.addEventListener('online', function() { |
| 201 | 386 self.downloadedListMap_ = null; |
| 202 /** | 387 $('wallpaper-grid').classList.remove('image-picker-offline'); |
| 203 * Toggle surprise me feature of wallpaper picker. It fires an storage | |
| 204 * onChanged event. Event handler for that event is in event_page.js. | |
| 205 * @private | |
| 206 */ | |
| 207 WallpaperManager.prototype.toggleSurpriseMe_ = function() { | |
| 208 var self = this; | |
| 209 var checkbox = $('surprise-me').querySelector('#checkbox'); | |
| 210 var shouldEnable = !checkbox.classList.contains('checked'); | |
| 211 var onSuccess = function() { | |
| 212 if (chrome.runtime.lastError == null) { | |
| 213 if (shouldEnable) { | |
| 214 self.document_.body.removeAttribute('surprise-me-disabled'); | |
| 215 checkbox.classList.add('checked'); | |
| 216 // Hides the wallpaper set by message if there is any. | |
| 217 $('wallpaper-set-by-message').textContent = ''; | |
| 218 } else { | |
| 219 // Unchecking the "Surprise me" checkbox falls back to the previous | |
| 220 // wallpaper before "Surprise me" was turned on. | |
| 221 if (self.wallpaperGrid_.activeItem) { | |
| 222 self.setSelectedWallpaper_(self.wallpaperGrid_.activeItem); | |
| 223 self.onWallpaperChanged_(self.wallpaperGrid_.activeItem, | |
| 224 self.currentWallpaper_); | |
| 225 } | |
| 226 checkbox.classList.remove('checked'); | |
| 227 self.document_.body.setAttribute('surprise-me-disabled', ''); | |
| 228 } | |
| 229 $('categories-list').disabled = shouldEnable; | |
| 230 $('wallpaper-grid').disabled = shouldEnable; | |
| 231 } else { | |
| 232 // TODO(bshe): show error message to user. | |
| 233 console.error('Failed to save surprise me option to chrome storage.'); | |
| 234 } | |
| 235 }; | |
| 236 | |
| 237 // To prevent the onChanged event being fired twice, we only save the value | |
| 238 // to sync storage if the sync theme is enabled, otherwise save it to local | |
| 239 // storage. | |
| 240 WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) { | |
| 241 if (syncEnabled) | |
| 242 WallpaperUtil.saveToSyncStorage( | |
| 243 Constants.AccessSyncSurpriseMeEnabledKey, shouldEnable, onSuccess); | |
| 244 else | |
| 245 WallpaperUtil.saveToLocalStorage( | |
| 246 Constants.AccessLocalSurpriseMeEnabledKey, shouldEnable, onSuccess); | |
| 247 }); | 388 }); |
| 248 }; | 389 } |
| 249 | 390 |
| 250 /** | 391 this.onResize_(); |
| 251 * One-time initialization of various DOM nodes. Fetching manifest may take a | 392 this.initContextMenuAndCommand_(); |
| 252 * long time due to slow connection. Dom nodes that do not depend on manifest | 393 WallpaperUtil.testSendMessage('launched'); |
| 253 * should be initialized here to unblock from manifest fetching. | 394 }; |
| 254 */ | 395 |
| 255 WallpaperManager.prototype.preManifestDomInit_ = function() { | 396 /** |
| 256 $('window-close-button').addEventListener('click', function() { | 397 * One-time initialization of context menu and command. |
| 257 window.close(); | 398 */ |
| 258 }); | 399 WallpaperManager.prototype.initContextMenuAndCommand_ = function() { |
| 259 this.document_.defaultView.addEventListener( | 400 this.wallpaperContextMenu_ = $('wallpaper-context-menu'); |
| 260 'resize', this.onResize_.bind(this)); | 401 cr.ui.Menu.decorate(this.wallpaperContextMenu_); |
| 261 this.document_.defaultView.addEventListener( | 402 cr.ui.contextMenuHandler.setContextMenu( |
| 262 'keydown', this.onKeyDown_.bind(this)); | 403 this.wallpaperGrid_, this.wallpaperContextMenu_); |
| 263 $('learn-more').href = LearnMoreURL; | 404 var commands = this.dialogDom_.querySelectorAll('command'); |
| 264 $('close-error').addEventListener('click', function() { | 405 for (var i = 0; i < commands.length; i++) |
| 265 $('error-container').hidden = true; | 406 cr.ui.Command.decorate(commands[i]); |
| 266 }); | 407 |
| 267 $('close-wallpaper-selection').addEventListener('click', function() { | 408 var doc = this.document_; |
| 268 $('wallpaper-selection-container').hidden = true; | 409 doc.addEventListener('command', this.onCommand_.bind(this)); |
| 269 $('set-wallpaper-layout').disabled = true; | 410 doc.addEventListener('canExecute', this.onCommandCanExecute_.bind(this)); |
| 270 }); | 411 }; |
| 271 }; | 412 |
| 272 | 413 /** |
| 273 /** | 414 * Handles a command being executed. |
| 274 * One-time initialization of various DOM nodes. Dom nodes that do depend on | 415 * @param {Event} event A command event. |
| 275 * manifest should be initialized here. | 416 */ |
| 276 */ | 417 WallpaperManager.prototype.onCommand_ = function(event) { |
| 277 WallpaperManager.prototype.postManifestDomInit_ = function() { | 418 if (event.command.id == 'delete') { |
| 278 i18nTemplate.process(this.document_, loadTimeData); | 419 var wallpaperGrid = this.wallpaperGrid_; |
| 279 this.initCategoriesList_(); | 420 var selectedIndex = wallpaperGrid.selectionModel.selectedIndex; |
| 280 this.initThumbnailsGrid_(); | 421 var item = wallpaperGrid.dataModel.item(selectedIndex); |
| 281 this.presetCategory_(); | 422 if (!item || item.source != Constants.WallpaperSourceEnum.Custom) |
| 282 | 423 return; |
| 283 $('file-selector').addEventListener( | 424 this.removeCustomWallpaper(item.baseURL); |
| 284 'change', this.onFileSelectorChanged_.bind(this)); | 425 wallpaperGrid.dataModel.splice(selectedIndex, 1); |
| 285 $('set-wallpaper-layout').addEventListener( | 426 // Calculate the number of remaining custom wallpapers. The add new button |
| 286 'change', this.onWallpaperLayoutChanged_.bind(this)); | 427 // in data model needs to be excluded. |
| 287 | 428 var customWallpaperCount = wallpaperGrid.dataModel.length - 1; |
| 288 // Always prefer the value from local filesystem to avoid the time window | 429 if (customWallpaperCount == 0) { |
| 289 // of setting the third party app name and the third party wallpaper. | 430 // Active custom wallpaper is also copied in chronos data dir. It needs |
| 290 var getThirdPartyAppName = function(callback) { | 431 // to be deleted. |
| 291 Constants.WallpaperLocalStorage.get( | 432 chrome.wallpaperPrivate.resetWallpaper(); |
| 292 Constants.AccessLocalWallpaperInfoKey, function(items) { | 433 this.onWallpaperChanged_(null, null); |
| 293 var localInfo = items[Constants.AccessLocalWallpaperInfoKey]; | 434 } else { |
| 294 if (localInfo && localInfo.hasOwnProperty('appName')) | 435 selectedIndex = Math.min(selectedIndex, customWallpaperCount - 1); |
| 295 callback(localInfo.appName); | 436 wallpaperGrid.selectionModel.selectedIndex = selectedIndex; |
| 296 else if (loadTimeData.valueExists('wallpaperAppName')) | |
| 297 callback(str('wallpaperAppName')); | |
| 298 else | |
| 299 callback(''); | |
| 300 }); | |
| 301 }; | |
| 302 | |
| 303 getThirdPartyAppName(function(appName) { | |
| 304 if (!!appName) { | |
| 305 $('wallpaper-set-by-message').textContent = loadTimeData.getStringF( | |
| 306 'currentWallpaperSetByMessage', appName); | |
| 307 $('wallpaper-grid').classList.add('small'); | |
| 308 } else { | |
| 309 $('wallpaper-grid').classList.remove('small'); | |
| 310 } | |
| 311 }); | |
| 312 | |
| 313 if (this.enableOnlineWallpaper_) { | |
| 314 var self = this; | |
| 315 self.document_.body.setAttribute('surprise-me-disabled', ''); | |
| 316 $('surprise-me').hidden = false; | |
| 317 $('surprise-me').addEventListener('click', | |
| 318 this.toggleSurpriseMe_.bind(this)); | |
| 319 var onSurpriseMeEnabled = function() { | |
| 320 $('surprise-me').querySelector('#checkbox').classList.add('checked'); | |
| 321 $('categories-list').disabled = true; | |
| 322 $('wallpaper-grid').disabled = true; | |
| 323 self.document_.body.removeAttribute('surprise-me-disabled'); | |
| 324 }; | |
| 325 | |
| 326 WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) { | |
| 327 // Surprise me has been moved from local to sync storage, prefer | |
| 328 // values from sync, but if unset check local and update synced pref | |
| 329 // if applicable. | |
| 330 if (syncEnabled) { | |
| 331 Constants.WallpaperSyncStorage.get( | |
| 332 Constants.AccessSyncSurpriseMeEnabledKey, function(items) { | |
| 333 if (items.hasOwnProperty( | |
| 334 Constants.AccessSyncSurpriseMeEnabledKey)) { | |
| 335 if (items[Constants.AccessSyncSurpriseMeEnabledKey]) { | |
| 336 onSurpriseMeEnabled(); | |
| 337 } | |
| 338 } else { | |
| 339 Constants.WallpaperLocalStorage.get( | |
| 340 Constants.AccessLocalSurpriseMeEnabledKey, function(items) { | |
| 341 if (items.hasOwnProperty( | |
| 342 Constants.AccessLocalSurpriseMeEnabledKey)) { | |
| 343 WallpaperUtil.saveToSyncStorage( | |
| 344 Constants.AccessSyncSurpriseMeEnabledKey, | |
| 345 items[Constants.AccessLocalSurpriseMeEnabledKey]); | |
| 346 if (items[Constants.AccessLocalSurpriseMeEnabledKey]) { | |
| 347 onSurpriseMeEnabled(); | |
| 348 } | |
| 349 } | |
| 350 }); | |
| 351 } | |
| 352 }); | |
| 353 } else { | |
| 354 Constants.WallpaperLocalStorage.get( | |
| 355 Constants.AccessLocalSurpriseMeEnabledKey, function(items) { | |
| 356 if (items.hasOwnProperty( | |
| 357 Constants.AccessLocalSurpriseMeEnabledKey)) { | |
| 358 if (items[Constants.AccessLocalSurpriseMeEnabledKey]) { | |
| 359 onSurpriseMeEnabled(); | |
| 360 } | |
| 361 } | |
| 362 }); | |
| 363 } | |
| 364 }); | |
| 365 | |
| 366 window.addEventListener('offline', function() { | |
| 367 chrome.wallpaperPrivate.getOfflineWallpaperList(function(lists) { | |
| 368 if (!self.downloadedListMap_) | |
| 369 self.downloadedListMap_ = {}; | |
| 370 for (var i = 0; i < lists.length; i++) { | |
| 371 self.downloadedListMap_[lists[i]] = true; | |
| 372 } | |
| 373 var thumbnails = self.document_.querySelectorAll('.thumbnail'); | |
| 374 for (var i = 0; i < thumbnails.length; i++) { | |
| 375 var thumbnail = thumbnails[i]; | |
| 376 var url = self.wallpaperGrid_.dataModel.item(i).baseURL; | |
| 377 var fileName = getBaseName(url) + Constants.HighResolutionSuffix; | |
| 378 if (self.downloadedListMap_ && | |
| 379 self.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { | |
| 380 thumbnail.offline = true; | |
| 381 } | |
| 382 } | |
| 383 }); | |
| 384 $('wallpaper-grid').classList.add('image-picker-offline'); | |
| 385 }); | |
| 386 window.addEventListener('online', function() { | |
| 387 self.downloadedListMap_ = null; | |
| 388 $('wallpaper-grid').classList.remove('image-picker-offline'); | |
| 389 }); | |
| 390 } | 437 } |
| 391 | 438 event.cancelBubble = true; |
| 392 this.onResize_(); | 439 } |
| 393 this.initContextMenuAndCommand_(); | 440 }; |
| 394 WallpaperUtil.testSendMessage('launched'); | 441 |
| 395 }; | 442 /** |
| 396 | 443 * Decides if a command can be executed on current target. |
| 397 /** | 444 * @param {Event} event A command event. |
| 398 * One-time initialization of context menu and command. | 445 */ |
| 399 */ | 446 WallpaperManager.prototype.onCommandCanExecute_ = function(event) { |
| 400 WallpaperManager.prototype.initContextMenuAndCommand_ = function() { | 447 switch (event.command.id) { |
| 401 this.wallpaperContextMenu_ = $('wallpaper-context-menu'); | 448 case 'delete': |
| 402 cr.ui.Menu.decorate(this.wallpaperContextMenu_); | |
| 403 cr.ui.contextMenuHandler.setContextMenu(this.wallpaperGrid_, | |
| 404 this.wallpaperContextMenu_); | |
| 405 var commands = this.dialogDom_.querySelectorAll('command'); | |
| 406 for (var i = 0; i < commands.length; i++) | |
| 407 cr.ui.Command.decorate(commands[i]); | |
| 408 | |
| 409 var doc = this.document_; | |
| 410 doc.addEventListener('command', this.onCommand_.bind(this)); | |
| 411 doc.addEventListener('canExecute', this.onCommandCanExecute_.bind(this)); | |
| 412 }; | |
| 413 | |
| 414 /** | |
| 415 * Handles a command being executed. | |
| 416 * @param {Event} event A command event. | |
| 417 */ | |
| 418 WallpaperManager.prototype.onCommand_ = function(event) { | |
| 419 if (event.command.id == 'delete') { | |
| 420 var wallpaperGrid = this.wallpaperGrid_; | 449 var wallpaperGrid = this.wallpaperGrid_; |
| 421 var selectedIndex = wallpaperGrid.selectionModel.selectedIndex; | 450 var selectedIndex = wallpaperGrid.selectionModel.selectedIndex; |
| 422 var item = wallpaperGrid.dataModel.item(selectedIndex); | 451 var item = wallpaperGrid.dataModel.item(selectedIndex); |
| 423 if (!item || item.source != Constants.WallpaperSourceEnum.Custom) | 452 if (selectedIndex != this.wallpaperGrid_.dataModel.length - 1 && item && |
| 424 return; | 453 item.source == Constants.WallpaperSourceEnum.Custom) { |
| 425 this.removeCustomWallpaper(item.baseURL); | 454 event.canExecute = true; |
| 426 wallpaperGrid.dataModel.splice(selectedIndex, 1); | 455 break; |
| 427 // Calculate the number of remaining custom wallpapers. The add new button | |
| 428 // in data model needs to be excluded. | |
| 429 var customWallpaperCount = wallpaperGrid.dataModel.length - 1; | |
| 430 if (customWallpaperCount == 0) { | |
| 431 // Active custom wallpaper is also copied in chronos data dir. It needs | |
| 432 // to be deleted. | |
| 433 chrome.wallpaperPrivate.resetWallpaper(); | |
| 434 this.onWallpaperChanged_(null, null); | |
| 435 } else { | |
| 436 selectedIndex = Math.min(selectedIndex, customWallpaperCount - 1); | |
| 437 wallpaperGrid.selectionModel.selectedIndex = selectedIndex; | |
| 438 } | 456 } |
| 439 event.cancelBubble = true; | 457 default: |
| 440 } | 458 event.canExecute = false; |
| 441 }; | 459 } |
| 442 | 460 }; |
| 443 /** | 461 |
| 444 * Decides if a command can be executed on current target. | 462 /** |
| 445 * @param {Event} event A command event. | 463 * Preset to the category which contains current wallpaper. |
| 446 */ | 464 */ |
| 447 WallpaperManager.prototype.onCommandCanExecute_ = function(event) { | 465 WallpaperManager.prototype.presetCategory_ = function() { |
| 448 switch (event.command.id) { | 466 this.currentWallpaper_ = str('currentWallpaper'); |
| 449 case 'delete': | 467 // The currentWallpaper_ is either a url contains HightResolutionSuffix or a |
| 450 var wallpaperGrid = this.wallpaperGrid_; | 468 // custom wallpaper file name converted from an integer value represent |
| 451 var selectedIndex = wallpaperGrid.selectionModel.selectedIndex; | 469 // time (e.g., 13006377367586070). |
| 452 var item = wallpaperGrid.dataModel.item(selectedIndex); | 470 if (!this.enableOnlineWallpaper_ || |
| 453 if (selectedIndex != this.wallpaperGrid_.dataModel.length - 1 && | 471 (this.currentWallpaper_ && |
| 454 item && item.source == Constants.WallpaperSourceEnum.Custom) { | 472 this.currentWallpaper_.indexOf(Constants.HighResolutionSuffix) == -1)) { |
| 455 event.canExecute = true; | 473 // Custom is the last one in the categories list. |
| 474 this.categoriesList_.selectionModel.selectedIndex = |
| 475 this.categoriesList_.dataModel.length - 1; |
| 476 return; |
| 477 } |
| 478 var self = this; |
| 479 var presetCategoryInner = function() { |
| 480 // Selects the first category in the categories list of current |
| 481 // wallpaper as the default selected category when showing wallpaper |
| 482 // picker UI. |
| 483 var presetCategory = AllCategoryIndex; |
| 484 if (self.currentWallpaper_) { |
| 485 for (var key in self.manifest_.wallpaper_list) { |
| 486 var url = self.manifest_.wallpaper_list[key].base_url + |
| 487 Constants.HighResolutionSuffix; |
| 488 if (url.indexOf(self.currentWallpaper_) != -1 && |
| 489 self.manifest_.wallpaper_list[key].categories.length > 0) { |
| 490 presetCategory = self.manifest_.wallpaper_list[key].categories[0] + |
| 491 OnlineCategoriesOffset; |
| 456 break; | 492 break; |
| 457 } | 493 } |
| 458 default: | 494 } |
| 459 event.canExecute = false; | |
| 460 } | 495 } |
| 496 self.categoriesList_.selectionModel.selectedIndex = presetCategory; |
| 461 }; | 497 }; |
| 462 | 498 if (navigator.onLine) { |
| 463 /** | 499 presetCategoryInner(); |
| 464 * Preset to the category which contains current wallpaper. | 500 } else { |
| 465 */ | 501 // If device is offline, gets the available offline wallpaper list first. |
| 466 WallpaperManager.prototype.presetCategory_ = function() { | 502 // Wallpapers which are not in the list will display a grayscaled |
| 467 this.currentWallpaper_ = str('currentWallpaper'); | 503 // thumbnail. |
| 468 // The currentWallpaper_ is either a url contains HightResolutionSuffix or a | 504 chrome.wallpaperPrivate.getOfflineWallpaperList(function(lists) { |
| 469 // custom wallpaper file name converted from an integer value represent | 505 if (!self.downloadedListMap_) |
| 470 // time (e.g., 13006377367586070). | 506 self.downloadedListMap_ = {}; |
| 471 if (!this.enableOnlineWallpaper_ || (this.currentWallpaper_ && | 507 for (var i = 0; i < lists.length; i++) |
| 472 this.currentWallpaper_.indexOf(Constants.HighResolutionSuffix) == -1)) { | 508 self.downloadedListMap_[lists[i]] = true; |
| 473 // Custom is the last one in the categories list. | |
| 474 this.categoriesList_.selectionModel.selectedIndex = | |
| 475 this.categoriesList_.dataModel.length - 1; | |
| 476 return; | |
| 477 } | |
| 478 var self = this; | |
| 479 var presetCategoryInner = function() { | |
| 480 // Selects the first category in the categories list of current | |
| 481 // wallpaper as the default selected category when showing wallpaper | |
| 482 // picker UI. | |
| 483 var presetCategory = AllCategoryIndex; | |
| 484 if (self.currentWallpaper_) { | |
| 485 for (var key in self.manifest_.wallpaper_list) { | |
| 486 var url = self.manifest_.wallpaper_list[key].base_url + | |
| 487 Constants.HighResolutionSuffix; | |
| 488 if (url.indexOf(self.currentWallpaper_) != -1 && | |
| 489 self.manifest_.wallpaper_list[key].categories.length > 0) { | |
| 490 presetCategory = self.manifest_.wallpaper_list[key].categories[0] + | |
| 491 OnlineCategoriesOffset; | |
| 492 break; | |
| 493 } | |
| 494 } | |
| 495 } | |
| 496 self.categoriesList_.selectionModel.selectedIndex = presetCategory; | |
| 497 }; | |
| 498 if (navigator.onLine) { | |
| 499 presetCategoryInner(); | 509 presetCategoryInner(); |
| 500 } else { | 510 }); |
| 501 // If device is offline, gets the available offline wallpaper list first. | 511 } |
| 502 // Wallpapers which are not in the list will display a grayscaled | 512 }; |
| 503 // thumbnail. | 513 |
| 504 chrome.wallpaperPrivate.getOfflineWallpaperList(function(lists) { | 514 /** |
| 505 if (!self.downloadedListMap_) | 515 * Constructs the thumbnails grid. |
| 506 self.downloadedListMap_ = {}; | 516 */ |
| 507 for (var i = 0; i < lists.length; i++) | 517 WallpaperManager.prototype.initThumbnailsGrid_ = function() { |
| 508 self.downloadedListMap_[lists[i]] = true; | 518 this.wallpaperGrid_ = $('wallpaper-grid'); |
| 509 presetCategoryInner(); | 519 wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_); |
| 510 }); | 520 |
| 511 } | 521 this.wallpaperGrid_.addEventListener('change', this.onChange_.bind(this)); |
| 512 }; | 522 this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this)); |
| 513 | 523 }; |
| 514 /** | 524 |
| 515 * Constructs the thumbnails grid. | 525 /** |
| 516 */ | 526 * Handles change event dispatched by wallpaper grid. |
| 517 WallpaperManager.prototype.initThumbnailsGrid_ = function() { | 527 */ |
| 518 this.wallpaperGrid_ = $('wallpaper-grid'); | 528 WallpaperManager.prototype.onChange_ = function() { |
| 519 wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_); | 529 // splice may dispatch a change event because the position of selected |
| 520 | 530 // element changing. But the actual selected element may not change after |
| 521 this.wallpaperGrid_.addEventListener('change', this.onChange_.bind(this)); | 531 // splice. Check if the new selected element equals to the previous selected |
| 522 this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this)); | 532 // element before continuing. Otherwise, wallpaper may reset to previous one |
| 523 }; | 533 // as described in http://crbug.com/229036. |
| 524 | 534 if (this.selectedItem_ == this.wallpaperGrid_.selectedItem) |
| 525 /** | 535 return; |
| 526 * Handles change event dispatched by wallpaper grid. | 536 this.selectedItem_ = this.wallpaperGrid_.selectedItem; |
| 527 */ | 537 this.onSelectedItemChanged_(); |
| 528 WallpaperManager.prototype.onChange_ = function() { | 538 }; |
| 529 // splice may dispatch a change event because the position of selected | 539 |
| 530 // element changing. But the actual selected element may not change after | 540 /** |
| 531 // splice. Check if the new selected element equals to the previous selected | 541 * Closes window if no pending wallpaper request. |
| 532 // element before continuing. Otherwise, wallpaper may reset to previous one | 542 */ |
| 533 // as described in http://crbug.com/229036. | 543 WallpaperManager.prototype.onClose_ = function() { |
| 534 if (this.selectedItem_ == this.wallpaperGrid_.selectedItem) | 544 if (this.wallpaperRequest_) { |
| 535 return; | 545 this.wallpaperRequest_.addEventListener('loadend', function() { |
| 536 this.selectedItem_ = this.wallpaperGrid_.selectedItem; | 546 // Close window on wallpaper loading finished. |
| 537 this.onSelectedItemChanged_(); | 547 window.close(); |
| 538 }; | 548 }); |
| 539 | 549 } else { |
| 540 /** | 550 window.close(); |
| 541 * Closes window if no pending wallpaper request. | 551 } |
| 542 */ | 552 }; |
| 543 WallpaperManager.prototype.onClose_ = function() { | 553 |
| 544 if (this.wallpaperRequest_) { | 554 /** |
| 545 this.wallpaperRequest_.addEventListener('loadend', function() { | 555 * Moves the check mark to |activeItem| and hides the wallpaper set by third |
| 546 // Close window on wallpaper loading finished. | 556 * party message if any. And saves the wallpaper's information to local & sync |
| 547 window.close(); | 557 * storage. Called when wallpaper changed successfully. |
| 558 * @param {?Object} activeItem The active item in WallpaperThumbnailsGrid's |
| 559 * data model. |
| 560 * @param {?string} currentWallpaperURL The URL or filename of current |
| 561 * wallpaper. |
| 562 */ |
| 563 WallpaperManager.prototype.onWallpaperChanged_ = function( |
| 564 activeItem, currentWallpaperURL) { |
| 565 this.wallpaperGrid_.activeItem = activeItem; |
| 566 this.currentWallpaper_ = currentWallpaperURL; |
| 567 // Hides the wallpaper set by message. |
| 568 $('wallpaper-set-by-message').textContent = ''; |
| 569 $('wallpaper-grid').classList.remove('small'); |
| 570 |
| 571 if (activeItem) { |
| 572 WallpaperUtil.saveWallpaperInfo( |
| 573 currentWallpaperURL, activeItem.layout, activeItem.source, ''); |
| 574 } else { |
| 575 WallpaperUtil.saveWallpaperInfo( |
| 576 '', '', Constants.WallpaperSourceEnum.Default, ''); |
| 577 } |
| 578 }; |
| 579 |
| 580 /** |
| 581 * Sets wallpaper to the corresponding wallpaper of selected thumbnail. |
| 582 * @param {{baseURL: string, layout: string, source: string, |
| 583 * availableOffline: boolean, opt_dynamicURL: string, |
| 584 * opt_author: string, opt_authorWebsite: string}} |
| 585 * selectedItem the selected item in WallpaperThumbnailsGrid's data |
| 586 * model. |
| 587 */ |
| 588 WallpaperManager.prototype.setSelectedWallpaper_ = function(selectedItem) { |
| 589 var self = this; |
| 590 switch (selectedItem.source) { |
| 591 case Constants.WallpaperSourceEnum.Custom: |
| 592 var errorHandler = this.onFileSystemError_.bind(this); |
| 593 var success = function(dirEntry) { |
| 594 dirEntry.getFile( |
| 595 selectedItem.baseURL, {create: false}, function(fileEntry) { |
| 596 fileEntry.file(function(file) { |
| 597 var reader = new FileReader(); |
| 598 reader.readAsArrayBuffer(file); |
| 599 reader.addEventListener('error', errorHandler); |
| 600 reader.addEventListener('load', function(e) { |
| 601 self.setCustomWallpaper( |
| 602 e.target.result, selectedItem.layout, false, |
| 603 selectedItem.baseURL, function(thumbnailData) { |
| 604 self.onWallpaperChanged_( |
| 605 selectedItem, selectedItem.baseURL); |
| 606 WallpaperUtil.storeWallpaperToSyncFS( |
| 607 selectedItem.baseURL, e.target.result); |
| 608 WallpaperUtil.storeWallpaperToSyncFS( |
| 609 selectedItem.baseURL + |
| 610 Constants.CustomWallpaperThumbnailSuffix, |
| 611 thumbnailData); |
| 612 }, errorHandler); |
| 613 }); |
| 614 }, errorHandler); |
| 615 }, errorHandler); |
| 616 }; |
| 617 this.wallpaperDirs_.getDirectory( |
| 618 Constants.WallpaperDirNameEnum.ORIGINAL, success, errorHandler); |
| 619 break; |
| 620 case Constants.WallpaperSourceEnum.OEM: |
| 621 // Resets back to default wallpaper. |
| 622 chrome.wallpaperPrivate.resetWallpaper(); |
| 623 this.onWallpaperChanged_(selectedItem, selectedItem.baseURL); |
| 624 break; |
| 625 case Constants.WallpaperSourceEnum.Online: |
| 626 var wallpaperURL = selectedItem.baseURL + Constants.HighResolutionSuffix; |
| 627 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem); |
| 628 |
| 629 chrome.wallpaperPrivate.setWallpaperIfExists( |
| 630 wallpaperURL, selectedItem.layout, function(exists) { |
| 631 if (exists) { |
| 632 self.onWallpaperChanged_(selectedItem, wallpaperURL); |
| 633 return; |
| 634 } |
| 635 |
| 636 // Falls back to request wallpaper from server. |
| 637 if (self.wallpaperRequest_) |
| 638 self.wallpaperRequest_.abort(); |
| 639 |
| 640 self.wallpaperRequest_ = new XMLHttpRequest(); |
| 641 self.progressManager_.reset( |
| 642 self.wallpaperRequest_, selectedGridItem); |
| 643 |
| 644 var onSuccess = function(xhr) { |
| 645 var image = xhr.response; |
| 646 chrome.wallpaperPrivate.setWallpaper( |
| 647 image, selectedItem.layout, wallpaperURL, function() { |
| 648 self.progressManager_.hideProgressBar(selectedGridItem); |
| 649 |
| 650 if (chrome.runtime.lastError != undefined && |
| 651 chrome.runtime.lastError.message != |
| 652 str('canceledWallpaper')) { |
| 653 self.showError_(chrome.runtime.lastError.message); |
| 654 } else { |
| 655 self.onWallpaperChanged_(selectedItem, wallpaperURL); |
| 656 } |
| 657 }); |
| 658 self.wallpaperRequest_ = null; |
| 659 }; |
| 660 var onFailure = function(status) { |
| 661 self.progressManager_.hideProgressBar(selectedGridItem); |
| 662 self.showError_(str('downloadFailed')); |
| 663 self.wallpaperRequest_ = null; |
| 664 }; |
| 665 WallpaperUtil.fetchURL( |
| 666 wallpaperURL, 'arraybuffer', onSuccess, onFailure, |
| 667 self.wallpaperRequest_); |
| 668 }); |
| 669 break; |
| 670 case Constants.WallpaperSourceEnum.Daily: |
| 671 case Constants.WallpaperSourceEnum.ThirdParty: |
| 672 default: |
| 673 console.error('Unsupported wallpaper source.'); |
| 674 } |
| 675 }; |
| 676 |
| 677 /* |
| 678 * Removes the oldest custom wallpaper. If the oldest one is set as current |
| 679 * wallpaper, removes the second oldest one to free some space. This should |
| 680 * only be called when exceeding wallpaper quota. |
| 681 */ |
| 682 WallpaperManager.prototype.removeOldestWallpaper_ = function() { |
| 683 // Custom wallpapers should already sorted when put to the data model. The |
| 684 // last element is the add new button, need to exclude it as well. |
| 685 var oldestIndex = this.wallpaperGrid_.dataModel.length - 2; |
| 686 var item = this.wallpaperGrid_.dataModel.item(oldestIndex); |
| 687 if (!item || item.source != Constants.WallpaperSourceEnum.Custom) |
| 688 return; |
| 689 if (item.baseURL == this.currentWallpaper_) |
| 690 item = this.wallpaperGrid_.dataModel.item(--oldestIndex); |
| 691 if (item) { |
| 692 this.removeCustomWallpaper(item.baseURL); |
| 693 this.wallpaperGrid_.dataModel.splice(oldestIndex, 1); |
| 694 } |
| 695 }; |
| 696 |
| 697 /* |
| 698 * Shows an error message to user and log the failed reason in console. |
| 699 */ |
| 700 WallpaperManager.prototype.onFileSystemError_ = function(e) { |
| 701 var msg = ''; |
| 702 switch (e.code) { |
| 703 case FileError.QUOTA_EXCEEDED_ERR: |
| 704 msg = 'QUOTA_EXCEEDED_ERR'; |
| 705 // Instead of simply remove oldest wallpaper, we should consider a |
| 706 // better way to handle this situation. See crbug.com/180890. |
| 707 this.removeOldestWallpaper_(); |
| 708 break; |
| 709 case FileError.NOT_FOUND_ERR: |
| 710 msg = 'NOT_FOUND_ERR'; |
| 711 break; |
| 712 case FileError.SECURITY_ERR: |
| 713 msg = 'SECURITY_ERR'; |
| 714 break; |
| 715 case FileError.INVALID_MODIFICATION_ERR: |
| 716 msg = 'INVALID_MODIFICATION_ERR'; |
| 717 break; |
| 718 case FileError.INVALID_STATE_ERR: |
| 719 msg = 'INVALID_STATE_ERR'; |
| 720 break; |
| 721 default: |
| 722 msg = 'Unknown Error'; |
| 723 break; |
| 724 } |
| 725 console.error('Error: ' + msg); |
| 726 this.showError_(str('accessFileFailure')); |
| 727 }; |
| 728 |
| 729 /** |
| 730 * Handles changing of selectedItem in wallpaper manager. |
| 731 */ |
| 732 WallpaperManager.prototype.onSelectedItemChanged_ = function() { |
| 733 this.setWallpaperAttribution_(this.selectedItem_); |
| 734 |
| 735 if (!this.selectedItem_ || this.selectedItem_.source == 'ADDNEW') |
| 736 return; |
| 737 |
| 738 if (this.selectedItem_.baseURL && !this.wallpaperGrid_.inProgramSelection) { |
| 739 if (this.selectedItem_.source == Constants.WallpaperSourceEnum.Custom) { |
| 740 var items = {}; |
| 741 var key = this.selectedItem_.baseURL; |
| 742 var self = this; |
| 743 Constants.WallpaperLocalStorage.get(key, function(items) { |
| 744 self.selectedItem_.layout = items[key] ? items[key] : 'CENTER_CROPPED'; |
| 745 self.setSelectedWallpaper_(self.selectedItem_); |
| 548 }); | 746 }); |
| 549 } else { | 747 } else { |
| 550 window.close(); | 748 this.setSelectedWallpaper_(this.selectedItem_); |
| 551 } | 749 } |
| 552 }; | 750 } |
| 553 | 751 }; |
| 554 /** | 752 |
| 555 * Moves the check mark to |activeItem| and hides the wallpaper set by third | 753 /** |
| 556 * party message if any. And saves the wallpaper's information to local & sync | 754 * Set attributions of wallpaper with given URL. If URL is not valid, clear |
| 557 * storage. Called when wallpaper changed successfully. | 755 * the attributions. |
| 558 * @param {?Object} activeItem The active item in WallpaperThumbnailsGrid's | 756 * @param {{baseURL: string, dynamicURL: string, layout: string, |
| 559 * data model. | 757 * author: string, authorWebsite: string, availableOffline: boolean}} |
| 560 * @param {?string} currentWallpaperURL The URL or filename of current | 758 * selectedItem selected wallpaper item in grid. |
| 561 * wallpaper. | 759 * @private |
| 562 */ | 760 */ |
| 563 WallpaperManager.prototype.onWallpaperChanged_ = function( | 761 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { |
| 564 activeItem, currentWallpaperURL) { | 762 // Only online wallpapers have author and website attributes. All other type |
| 565 this.wallpaperGrid_.activeItem = activeItem; | 763 // of wallpapers should not show attributions. |
| 566 this.currentWallpaper_ = currentWallpaperURL; | 764 if (selectedItem && |
| 567 // Hides the wallpaper set by message. | 765 selectedItem.source == Constants.WallpaperSourceEnum.Online) { |
| 568 $('wallpaper-set-by-message').textContent = ''; | 766 $('author-name').textContent = selectedItem.author; |
| 569 $('wallpaper-grid').classList.remove('small'); | 767 $('author-website').textContent = $('author-website').href = |
| 570 | 768 selectedItem.authorWebsite; |
| 571 if (activeItem) { | 769 chrome.wallpaperPrivate.getThumbnail( |
| 572 WallpaperUtil.saveWallpaperInfo( | 770 selectedItem.baseURL, selectedItem.source, function(data) { |
| 573 currentWallpaperURL, activeItem.layout, activeItem.source, ''); | 771 var img = $('attribute-image'); |
| 772 if (data) { |
| 773 var blob = new Blob([new Int8Array(data)], {'type': 'image\/png'}); |
| 774 img.src = window.URL.createObjectURL(blob); |
| 775 img.addEventListener('load', function(e) { |
| 776 window.URL.revokeObjectURL(this.src); |
| 777 }); |
| 778 } else { |
| 779 img.src = ''; |
| 780 } |
| 781 }); |
| 782 $('wallpaper-attribute').hidden = false; |
| 783 $('attribute-image').hidden = false; |
| 784 return; |
| 785 } |
| 786 $('wallpaper-attribute').hidden = true; |
| 787 $('attribute-image').hidden = true; |
| 788 $('author-name').textContent = ''; |
| 789 $('author-website').textContent = $('author-website').href = ''; |
| 790 $('attribute-image').src = ''; |
| 791 }; |
| 792 |
| 793 /** |
| 794 * Resize thumbnails grid and categories list to fit the new window size. |
| 795 */ |
| 796 WallpaperManager.prototype.onResize_ = function() { |
| 797 this.wallpaperGrid_.redraw(); |
| 798 this.categoriesList_.redraw(); |
| 799 }; |
| 800 |
| 801 /** |
| 802 * Close the last opened overlay or app window on pressing the Escape key. |
| 803 * @param {Event} event A keydown event. |
| 804 */ |
| 805 WallpaperManager.prototype.onKeyDown_ = function(event) { |
| 806 if (event.keyCode == 27) { |
| 807 // The last opened overlay coincides with the first match of querySelector |
| 808 // because the Error Container is declared in the DOM before the Wallpaper |
| 809 // Selection Container. |
| 810 // TODO(bshe): Make the overlay selection not dependent on the DOM. |
| 811 var closeButtonSelector = '.overlay-container:not([hidden]) .close'; |
| 812 var closeButton = this.document_.querySelector(closeButtonSelector); |
| 813 if (closeButton) { |
| 814 closeButton.click(); |
| 815 event.preventDefault(); |
| 574 } else { | 816 } else { |
| 575 WallpaperUtil.saveWallpaperInfo( | 817 this.onClose_(); |
| 576 '', '', Constants.WallpaperSourceEnum.Default, ''); | |
| 577 } | 818 } |
| 578 }; | 819 } |
| 579 | 820 }; |
| 580 /** | 821 |
| 581 * Sets wallpaper to the corresponding wallpaper of selected thumbnail. | 822 /** |
| 582 * @param {{baseURL: string, layout: string, source: string, | 823 * Constructs the categories list. |
| 583 * availableOffline: boolean, opt_dynamicURL: string, | 824 */ |
| 584 * opt_author: string, opt_authorWebsite: string}} | 825 WallpaperManager.prototype.initCategoriesList_ = function() { |
| 585 * selectedItem the selected item in WallpaperThumbnailsGrid's data | 826 this.categoriesList_ = $('categories-list'); |
| 586 * model. | 827 wallpapers.WallpaperCategoriesList.decorate(this.categoriesList_); |
| 587 */ | 828 |
| 588 WallpaperManager.prototype.setSelectedWallpaper_ = function(selectedItem) { | 829 this.categoriesList_.selectionModel.addEventListener( |
| 589 var self = this; | 830 'change', this.onCategoriesChange_.bind(this)); |
| 590 switch (selectedItem.source) { | 831 |
| 591 case Constants.WallpaperSourceEnum.Custom: | 832 if (this.enableOnlineWallpaper_ && this.manifest_) { |
| 592 var errorHandler = this.onFileSystemError_.bind(this); | 833 // Adds all category as first category. |
| 593 var success = function(dirEntry) { | 834 this.categoriesList_.dataModel.push(str('allCategoryLabel')); |
| 594 dirEntry.getFile(selectedItem.baseURL, {create: false}, | 835 for (var key in this.manifest_.categories) { |
| 595 function(fileEntry) { | 836 this.categoriesList_.dataModel.push(this.manifest_.categories[key]); |
| 596 fileEntry.file(function(file) { | |
| 597 var reader = new FileReader(); | |
| 598 reader.readAsArrayBuffer(file); | |
| 599 reader.addEventListener('error', errorHandler); | |
| 600 reader.addEventListener('load', function(e) { | |
| 601 self.setCustomWallpaper(e.target.result, selectedItem.layout, | |
| 602 false, selectedItem.baseURL, | |
| 603 function(thumbnailData) { | |
| 604 self.onWallpaperChanged_(selectedItem, | |
| 605 selectedItem.baseURL); | |
| 606 WallpaperUtil.storeWallpaperToSyncFS( | |
| 607 selectedItem.baseURL, e.target.result); | |
| 608 WallpaperUtil.storeWallpaperToSyncFS( | |
| 609 selectedItem.baseURL + | |
| 610 Constants.CustomWallpaperThumbnailSuffix, | |
| 611 thumbnailData); | |
| 612 }, | |
| 613 errorHandler); | |
| 614 }); | |
| 615 }, errorHandler); | |
| 616 }, errorHandler); | |
| 617 }; | |
| 618 this.wallpaperDirs_.getDirectory( | |
| 619 Constants.WallpaperDirNameEnum.ORIGINAL, success, errorHandler); | |
| 620 break; | |
| 621 case Constants.WallpaperSourceEnum.OEM: | |
| 622 // Resets back to default wallpaper. | |
| 623 chrome.wallpaperPrivate.resetWallpaper(); | |
| 624 this.onWallpaperChanged_(selectedItem, selectedItem.baseURL); | |
| 625 break; | |
| 626 case Constants.WallpaperSourceEnum.Online: | |
| 627 var wallpaperURL = selectedItem.baseURL + | |
| 628 Constants.HighResolutionSuffix; | |
| 629 var selectedGridItem = this.wallpaperGrid_.getListItem(selectedItem); | |
| 630 | |
| 631 chrome.wallpaperPrivate.setWallpaperIfExists(wallpaperURL, | |
| 632 selectedItem.layout, | |
| 633 function(exists) { | |
| 634 if (exists) { | |
| 635 self.onWallpaperChanged_(selectedItem, wallpaperURL); | |
| 636 return; | |
| 637 } | |
| 638 | |
| 639 // Falls back to request wallpaper from server. | |
| 640 if (self.wallpaperRequest_) | |
| 641 self.wallpaperRequest_.abort(); | |
| 642 | |
| 643 self.wallpaperRequest_ = new XMLHttpRequest(); | |
| 644 self.progressManager_.reset(self.wallpaperRequest_, selectedGridItem); | |
| 645 | |
| 646 var onSuccess = function(xhr) { | |
| 647 var image = xhr.response; | |
| 648 chrome.wallpaperPrivate.setWallpaper(image, selectedItem.layout, | |
| 649 wallpaperURL, | |
| 650 function() { | |
| 651 self.progressManager_.hideProgressBar(selectedGridItem); | |
| 652 | |
| 653 if (chrome.runtime.lastError != undefined && | |
| 654 chrome.runtime.lastError.message != | |
| 655 str('canceledWallpaper')) { | |
| 656 self.showError_(chrome.runtime.lastError.message); | |
| 657 } else { | |
| 658 self.onWallpaperChanged_(selectedItem, wallpaperURL); | |
| 659 } | |
| 660 }); | |
| 661 self.wallpaperRequest_ = null; | |
| 662 }; | |
| 663 var onFailure = function(status) { | |
| 664 self.progressManager_.hideProgressBar(selectedGridItem); | |
| 665 self.showError_(str('downloadFailed')); | |
| 666 self.wallpaperRequest_ = null; | |
| 667 }; | |
| 668 WallpaperUtil.fetchURL(wallpaperURL, 'arraybuffer', onSuccess, | |
| 669 onFailure, self.wallpaperRequest_); | |
| 670 }); | |
| 671 break; | |
| 672 case Constants.WallpaperSourceEnum.Daily: | |
| 673 case Constants.WallpaperSourceEnum.ThirdParty: | |
| 674 default: | |
| 675 console.error('Unsupported wallpaper source.'); | |
| 676 } | 837 } |
| 677 }; | 838 } |
| 678 | 839 // Adds custom category as last category. |
| 679 /* | 840 this.categoriesList_.dataModel.push(str('customCategoryLabel')); |
| 680 * Removes the oldest custom wallpaper. If the oldest one is set as current | 841 }; |
| 681 * wallpaper, removes the second oldest one to free some space. This should | 842 |
| 682 * only be called when exceeding wallpaper quota. | 843 /** |
| 683 */ | 844 * Handles the custom wallpaper which user selected from file manager. Called |
| 684 WallpaperManager.prototype.removeOldestWallpaper_ = function() { | 845 * when users select a file. |
| 685 // Custom wallpapers should already sorted when put to the data model. The | 846 */ |
| 686 // last element is the add new button, need to exclude it as well. | 847 WallpaperManager.prototype.onFileSelectorChanged_ = function() { |
| 687 var oldestIndex = this.wallpaperGrid_.dataModel.length - 2; | 848 var files = $('file-selector').files; |
| 688 var item = this.wallpaperGrid_.dataModel.item(oldestIndex); | 849 if (files.length != 1) |
| 689 if (!item || item.source != Constants.WallpaperSourceEnum.Custom) | 850 console.error('More than one files are selected or no file selected'); |
| 690 return; | 851 if (!files[0].type.match('image/jpeg') && !files[0].type.match('image/png')) { |
| 691 if (item.baseURL == this.currentWallpaper_) | 852 this.showError_(str('invalidWallpaper')); |
| 692 item = this.wallpaperGrid_.dataModel.item(--oldestIndex); | 853 return; |
| 693 if (item) { | 854 } |
| 694 this.removeCustomWallpaper(item.baseURL); | 855 var layout = getSelectedLayout(); |
| 695 this.wallpaperGrid_.dataModel.splice(oldestIndex, 1); | 856 var self = this; |
| 696 } | 857 var errorHandler = this.onFileSystemError_.bind(this); |
| 697 }; | 858 var setSelectedFile = function(file, layout, fileName) { |
| 698 | 859 var saveThumbnail = function(thumbnail) { |
| 699 /* | |
| 700 * Shows an error message to user and log the failed reason in console. | |
| 701 */ | |
| 702 WallpaperManager.prototype.onFileSystemError_ = function(e) { | |
| 703 var msg = ''; | |
| 704 switch (e.code) { | |
| 705 case FileError.QUOTA_EXCEEDED_ERR: | |
| 706 msg = 'QUOTA_EXCEEDED_ERR'; | |
| 707 // Instead of simply remove oldest wallpaper, we should consider a | |
| 708 // better way to handle this situation. See crbug.com/180890. | |
| 709 this.removeOldestWallpaper_(); | |
| 710 break; | |
| 711 case FileError.NOT_FOUND_ERR: | |
| 712 msg = 'NOT_FOUND_ERR'; | |
| 713 break; | |
| 714 case FileError.SECURITY_ERR: | |
| 715 msg = 'SECURITY_ERR'; | |
| 716 break; | |
| 717 case FileError.INVALID_MODIFICATION_ERR: | |
| 718 msg = 'INVALID_MODIFICATION_ERR'; | |
| 719 break; | |
| 720 case FileError.INVALID_STATE_ERR: | |
| 721 msg = 'INVALID_STATE_ERR'; | |
| 722 break; | |
| 723 default: | |
| 724 msg = 'Unknown Error'; | |
| 725 break; | |
| 726 } | |
| 727 console.error('Error: ' + msg); | |
| 728 this.showError_(str('accessFileFailure')); | |
| 729 }; | |
| 730 | |
| 731 /** | |
| 732 * Handles changing of selectedItem in wallpaper manager. | |
| 733 */ | |
| 734 WallpaperManager.prototype.onSelectedItemChanged_ = function() { | |
| 735 this.setWallpaperAttribution_(this.selectedItem_); | |
| 736 | |
| 737 if (!this.selectedItem_ || this.selectedItem_.source == 'ADDNEW') | |
| 738 return; | |
| 739 | |
| 740 if (this.selectedItem_.baseURL && !this.wallpaperGrid_.inProgramSelection) { | |
| 741 if (this.selectedItem_.source == Constants.WallpaperSourceEnum.Custom) { | |
| 742 var items = {}; | |
| 743 var key = this.selectedItem_.baseURL; | |
| 744 var self = this; | |
| 745 Constants.WallpaperLocalStorage.get(key, function(items) { | |
| 746 self.selectedItem_.layout = | |
| 747 items[key] ? items[key] : 'CENTER_CROPPED'; | |
| 748 self.setSelectedWallpaper_(self.selectedItem_); | |
| 749 }); | |
| 750 } else { | |
| 751 this.setSelectedWallpaper_(this.selectedItem_); | |
| 752 } | |
| 753 } | |
| 754 }; | |
| 755 | |
| 756 /** | |
| 757 * Set attributions of wallpaper with given URL. If URL is not valid, clear | |
| 758 * the attributions. | |
| 759 * @param {{baseURL: string, dynamicURL: string, layout: string, | |
| 760 * author: string, authorWebsite: string, availableOffline: boolean}} | |
| 761 * selectedItem selected wallpaper item in grid. | |
| 762 * @private | |
| 763 */ | |
| 764 WallpaperManager.prototype.setWallpaperAttribution_ = function(selectedItem) { | |
| 765 // Only online wallpapers have author and website attributes. All other type | |
| 766 // of wallpapers should not show attributions. | |
| 767 if (selectedItem && | |
| 768 selectedItem.source == Constants.WallpaperSourceEnum.Online) { | |
| 769 $('author-name').textContent = selectedItem.author; | |
| 770 $('author-website').textContent = $('author-website').href = | |
| 771 selectedItem.authorWebsite; | |
| 772 chrome.wallpaperPrivate.getThumbnail(selectedItem.baseURL, | |
| 773 selectedItem.source, | |
| 774 function(data) { | |
| 775 var img = $('attribute-image'); | |
| 776 if (data) { | |
| 777 var blob = new Blob([new Int8Array(data)], {'type' : 'image\/png'}); | |
| 778 img.src = window.URL.createObjectURL(blob); | |
| 779 img.addEventListener('load', function(e) { | |
| 780 window.URL.revokeObjectURL(this.src); | |
| 781 }); | |
| 782 } else { | |
| 783 img.src = ''; | |
| 784 } | |
| 785 }); | |
| 786 $('wallpaper-attribute').hidden = false; | |
| 787 $('attribute-image').hidden = false; | |
| 788 return; | |
| 789 } | |
| 790 $('wallpaper-attribute').hidden = true; | |
| 791 $('attribute-image').hidden = true; | |
| 792 $('author-name').textContent = ''; | |
| 793 $('author-website').textContent = $('author-website').href = ''; | |
| 794 $('attribute-image').src = ''; | |
| 795 }; | |
| 796 | |
| 797 /** | |
| 798 * Resize thumbnails grid and categories list to fit the new window size. | |
| 799 */ | |
| 800 WallpaperManager.prototype.onResize_ = function() { | |
| 801 this.wallpaperGrid_.redraw(); | |
| 802 this.categoriesList_.redraw(); | |
| 803 }; | |
| 804 | |
| 805 /** | |
| 806 * Close the last opened overlay or app window on pressing the Escape key. | |
| 807 * @param {Event} event A keydown event. | |
| 808 */ | |
| 809 WallpaperManager.prototype.onKeyDown_ = function(event) { | |
| 810 if (event.keyCode == 27) { | |
| 811 // The last opened overlay coincides with the first match of querySelector | |
| 812 // because the Error Container is declared in the DOM before the Wallpaper | |
| 813 // Selection Container. | |
| 814 // TODO(bshe): Make the overlay selection not dependent on the DOM. | |
| 815 var closeButtonSelector = '.overlay-container:not([hidden]) .close'; | |
| 816 var closeButton = this.document_.querySelector(closeButtonSelector); | |
| 817 if (closeButton) { | |
| 818 closeButton.click(); | |
| 819 event.preventDefault(); | |
| 820 } else { | |
| 821 this.onClose_(); | |
| 822 } | |
| 823 } | |
| 824 }; | |
| 825 | |
| 826 /** | |
| 827 * Constructs the categories list. | |
| 828 */ | |
| 829 WallpaperManager.prototype.initCategoriesList_ = function() { | |
| 830 this.categoriesList_ = $('categories-list'); | |
| 831 wallpapers.WallpaperCategoriesList.decorate(this.categoriesList_); | |
| 832 | |
| 833 this.categoriesList_.selectionModel.addEventListener( | |
| 834 'change', this.onCategoriesChange_.bind(this)); | |
| 835 | |
| 836 if (this.enableOnlineWallpaper_ && this.manifest_) { | |
| 837 // Adds all category as first category. | |
| 838 this.categoriesList_.dataModel.push(str('allCategoryLabel')); | |
| 839 for (var key in this.manifest_.categories) { | |
| 840 this.categoriesList_.dataModel.push(this.manifest_.categories[key]); | |
| 841 } | |
| 842 } | |
| 843 // Adds custom category as last category. | |
| 844 this.categoriesList_.dataModel.push(str('customCategoryLabel')); | |
| 845 }; | |
| 846 | |
| 847 /** | |
| 848 * Handles the custom wallpaper which user selected from file manager. Called | |
| 849 * when users select a file. | |
| 850 */ | |
| 851 WallpaperManager.prototype.onFileSelectorChanged_ = function() { | |
| 852 var files = $('file-selector').files; | |
| 853 if (files.length != 1) | |
| 854 console.error('More than one files are selected or no file selected'); | |
| 855 if (!files[0].type.match('image/jpeg') && | |
| 856 !files[0].type.match('image/png')) { | |
| 857 this.showError_(str('invalidWallpaper')); | |
| 858 return; | |
| 859 } | |
| 860 var layout = getSelectedLayout(); | |
| 861 var self = this; | |
| 862 var errorHandler = this.onFileSystemError_.bind(this); | |
| 863 var setSelectedFile = function(file, layout, fileName) { | |
| 864 var saveThumbnail = function(thumbnail) { | |
| 865 var success = function(dirEntry) { | |
| 866 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { | |
| 867 fileEntry.createWriter(function(fileWriter) { | |
| 868 fileWriter.onwriteend = function(e) { | |
| 869 $('set-wallpaper-layout').disabled = false; | |
| 870 var wallpaperInfo = { | |
| 871 baseURL: fileName, | |
| 872 layout: layout, | |
| 873 source: Constants.WallpaperSourceEnum.Custom, | |
| 874 availableOffline: true | |
| 875 }; | |
| 876 self.wallpaperGrid_.dataModel.splice(0, 0, wallpaperInfo); | |
| 877 self.wallpaperGrid_.selectedItem = wallpaperInfo; | |
| 878 self.onWallpaperChanged_(wallpaperInfo, fileName); | |
| 879 WallpaperUtil.saveToLocalStorage(self.currentWallpaper_, | |
| 880 layout); | |
| 881 }; | |
| 882 | |
| 883 fileWriter.onerror = errorHandler; | |
| 884 | |
| 885 var blob = new Blob([new Int8Array(thumbnail)], | |
| 886 {'type' : 'image\/jpeg'}); | |
| 887 fileWriter.write(blob); | |
| 888 }, errorHandler); | |
| 889 }, errorHandler); | |
| 890 }; | |
| 891 self.wallpaperDirs_.getDirectory( | |
| 892 Constants.WallpaperDirNameEnum.THUMBNAIL, success, errorHandler); | |
| 893 }; | |
| 894 var onCustomWallpaperSuccess = function(thumbnailData, wallpaperData) { | |
| 895 WallpaperUtil.storeWallpaperToSyncFS(fileName, wallpaperData); | |
| 896 WallpaperUtil.storeWallpaperToSyncFS( | |
| 897 fileName + Constants.CustomWallpaperThumbnailSuffix, | |
| 898 thumbnailData); | |
| 899 saveThumbnail(thumbnailData); | |
| 900 }; | |
| 901 var success = function(dirEntry) { | 860 var success = function(dirEntry) { |
| 902 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { | 861 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { |
| 903 fileEntry.createWriter(function(fileWriter) { | 862 fileEntry.createWriter(function(fileWriter) { |
| 904 fileWriter.addEventListener('writeend', function(e) { | 863 fileWriter.onwriteend = function(e) { |
| 905 var reader = new FileReader(); | 864 $('set-wallpaper-layout').disabled = false; |
| 906 reader.readAsArrayBuffer(file); | 865 var wallpaperInfo = { |
| 907 reader.addEventListener('error', errorHandler); | 866 baseURL: fileName, |
| 908 reader.addEventListener('load', function(e) { | 867 layout: layout, |
| 909 self.setCustomWallpaper(e.target.result, layout, true, fileName, | 868 source: Constants.WallpaperSourceEnum.Custom, |
| 910 function(thumbnail) { | 869 availableOffline: true |
| 911 onCustomWallpaperSuccess(thumbnail, e.target.result); | 870 }; |
| 912 }, | 871 self.wallpaperGrid_.dataModel.splice(0, 0, wallpaperInfo); |
| 913 function() { | 872 self.wallpaperGrid_.selectedItem = wallpaperInfo; |
| 914 self.removeCustomWallpaper(fileName); | 873 self.onWallpaperChanged_(wallpaperInfo, fileName); |
| 915 errorHandler(); | 874 WallpaperUtil.saveToLocalStorage(self.currentWallpaper_, layout); |
| 916 }); | 875 }; |
| 917 }); | 876 |
| 918 }); | 877 fileWriter.onerror = errorHandler; |
| 919 fileWriter.addEventListener('error', errorHandler); | 878 |
| 920 fileWriter.write(file); | 879 var blob = |
| 880 new Blob([new Int8Array(thumbnail)], {'type': 'image\/jpeg'}); |
| 881 fileWriter.write(blob); |
| 921 }, errorHandler); | 882 }, errorHandler); |
| 922 }, errorHandler); | 883 }, errorHandler); |
| 923 }; | 884 }; |
| 924 self.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.ORIGINAL, | 885 self.wallpaperDirs_.getDirectory( |
| 925 success, | 886 Constants.WallpaperDirNameEnum.THUMBNAIL, success, errorHandler); |
| 926 errorHandler); | |
| 927 }; | 887 }; |
| 928 setSelectedFile(files[0], layout, new Date().getTime().toString()); | 888 var onCustomWallpaperSuccess = function(thumbnailData, wallpaperData) { |
| 889 WallpaperUtil.storeWallpaperToSyncFS(fileName, wallpaperData); |
| 890 WallpaperUtil.storeWallpaperToSyncFS( |
| 891 fileName + Constants.CustomWallpaperThumbnailSuffix, thumbnailData); |
| 892 saveThumbnail(thumbnailData); |
| 893 }; |
| 894 var success = function(dirEntry) { |
| 895 dirEntry.getFile(fileName, {create: true}, function(fileEntry) { |
| 896 fileEntry.createWriter(function(fileWriter) { |
| 897 fileWriter.addEventListener('writeend', function(e) { |
| 898 var reader = new FileReader(); |
| 899 reader.readAsArrayBuffer(file); |
| 900 reader.addEventListener('error', errorHandler); |
| 901 reader.addEventListener('load', function(e) { |
| 902 self.setCustomWallpaper( |
| 903 e.target.result, layout, true, fileName, |
| 904 function(thumbnail) { |
| 905 onCustomWallpaperSuccess(thumbnail, e.target.result); |
| 906 }, |
| 907 function() { |
| 908 self.removeCustomWallpaper(fileName); |
| 909 errorHandler(); |
| 910 }); |
| 911 }); |
| 912 }); |
| 913 fileWriter.addEventListener('error', errorHandler); |
| 914 fileWriter.write(file); |
| 915 }, errorHandler); |
| 916 }, errorHandler); |
| 917 }; |
| 918 self.wallpaperDirs_.getDirectory( |
| 919 Constants.WallpaperDirNameEnum.ORIGINAL, success, errorHandler); |
| 929 }; | 920 }; |
| 930 | 921 setSelectedFile(files[0], layout, new Date().getTime().toString()); |
| 931 /** | 922 }; |
| 932 * Removes wallpaper and thumbnail with fileName from FileSystem. | 923 |
| 933 * @param {string} fileName The file name of wallpaper and thumbnail to be | 924 /** |
| 934 * removed. | 925 * Removes wallpaper and thumbnail with fileName from FileSystem. |
| 935 */ | 926 * @param {string} fileName The file name of wallpaper and thumbnail to be |
| 936 WallpaperManager.prototype.removeCustomWallpaper = function(fileName) { | 927 * removed. |
| 928 */ |
| 929 WallpaperManager.prototype.removeCustomWallpaper = function(fileName) { |
| 930 var errorHandler = this.onFileSystemError_.bind(this); |
| 931 var self = this; |
| 932 var removeFile = function(fileName) { |
| 933 var success = function(dirEntry) { |
| 934 dirEntry.getFile(fileName, {create: false}, function(fileEntry) { |
| 935 fileEntry.remove(function() { |
| 936 WallpaperUtil.deleteWallpaperFromSyncFS(fileName); |
| 937 }, errorHandler); |
| 938 }, errorHandler); |
| 939 }; |
| 940 |
| 941 // Removes copy of original. |
| 942 self.wallpaperDirs_.getDirectory( |
| 943 Constants.WallpaperDirNameEnum.ORIGINAL, success, errorHandler); |
| 944 |
| 945 // Removes generated thumbnail. |
| 946 self.wallpaperDirs_.getDirectory( |
| 947 Constants.WallpaperDirNameEnum.THUMBNAIL, success, errorHandler); |
| 948 }; |
| 949 removeFile(fileName); |
| 950 }; |
| 951 |
| 952 /** |
| 953 * Sets current wallpaper and generate thumbnail if generateThumbnail is true. |
| 954 * @param {ArrayBuffer} wallpaper The binary representation of wallpaper. |
| 955 * @param {string} layout The user selected wallpaper layout. |
| 956 * @param {boolean} generateThumbnail True if need to generate thumbnail. |
| 957 * @param {string} fileName The unique file name of wallpaper. |
| 958 * @param {function(thumbnail):void} success Success callback. If |
| 959 * generateThumbnail is true, the callback parameter should have the |
| 960 * generated thumbnail. |
| 961 * @param {function(e):void} failure Failure callback. Called when there is an |
| 962 * error from FileSystem. |
| 963 */ |
| 964 WallpaperManager.prototype.setCustomWallpaper = function( |
| 965 wallpaper, layout, generateThumbnail, fileName, success, failure) { |
| 966 var self = this; |
| 967 var onFinished = function(opt_thumbnail) { |
| 968 if (chrome.runtime.lastError != undefined && |
| 969 chrome.runtime.lastError.message != str('canceledWallpaper')) { |
| 970 self.showError_(chrome.runtime.lastError.message); |
| 971 $('set-wallpaper-layout').disabled = true; |
| 972 failure(); |
| 973 } else { |
| 974 success(opt_thumbnail); |
| 975 } |
| 976 }; |
| 977 |
| 978 chrome.wallpaperPrivate.setCustomWallpaper( |
| 979 wallpaper, layout, generateThumbnail, fileName, onFinished); |
| 980 }; |
| 981 |
| 982 /** |
| 983 * Handles the layout setting change of custom wallpaper. |
| 984 */ |
| 985 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { |
| 986 var layout = getSelectedLayout(); |
| 987 var self = this; |
| 988 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, function() { |
| 989 if (chrome.runtime.lastError != undefined && |
| 990 chrome.runtime.lastError.message != str('canceledWallpaper')) { |
| 991 self.showError_(chrome.runtime.lastError.message); |
| 992 self.removeCustomWallpaper(fileName); |
| 993 $('set-wallpaper-layout').disabled = true; |
| 994 } else { |
| 995 WallpaperUtil.saveToLocalStorage(self.currentWallpaper_, layout); |
| 996 self.onWallpaperChanged_( |
| 997 self.wallpaperGrid_.activeItem, self.currentWallpaper_); |
| 998 } |
| 999 }); |
| 1000 }; |
| 1001 |
| 1002 /** |
| 1003 * Handles user clicking on a different category. |
| 1004 */ |
| 1005 WallpaperManager.prototype.onCategoriesChange_ = function() { |
| 1006 var categoriesList = this.categoriesList_; |
| 1007 var selectedIndex = categoriesList.selectionModel.selectedIndex; |
| 1008 if (selectedIndex == -1) |
| 1009 return; |
| 1010 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); |
| 1011 var bar = $('bar'); |
| 1012 bar.style.left = selectedListItem.offsetLeft + 'px'; |
| 1013 bar.style.width = selectedListItem.offsetWidth + 'px'; |
| 1014 |
| 1015 var wallpapersDataModel = new cr.ui.ArrayDataModel([]); |
| 1016 var selectedItem = null; |
| 1017 if (selectedListItem.custom) { |
| 1018 this.document_.body.setAttribute('custom', ''); |
| 937 var errorHandler = this.onFileSystemError_.bind(this); | 1019 var errorHandler = this.onFileSystemError_.bind(this); |
| 1020 var toArray = function(list) { |
| 1021 return Array.prototype.slice.call(list || [], 0); |
| 1022 }; |
| 1023 |
| 938 var self = this; | 1024 var self = this; |
| 939 var removeFile = function(fileName) { | 1025 var processResults = function(entries) { |
| 940 var success = function(dirEntry) { | 1026 for (var i = 0; i < entries.length; i++) { |
| 941 dirEntry.getFile(fileName, {create: false}, function(fileEntry) { | 1027 var entry = entries[i]; |
| 942 fileEntry.remove(function() { | 1028 var wallpaperInfo = { |
| 943 WallpaperUtil.deleteWallpaperFromSyncFS(fileName); | 1029 // Set wallpaperId to null to avoid duplicate thumbnail images, |
| 944 }, errorHandler); | 1030 // see crbug.com/506135 for details. |
| 1031 wallpaperId: null, |
| 1032 baseURL: entry.name, |
| 1033 // The layout will be replaced by the actual value saved in |
| 1034 // local storage when requested later. Layout is not important |
| 1035 // for constructing thumbnails grid, we use CENTER_CROPPED here |
| 1036 // to speed up the process of constructing. So we do not need to |
| 1037 // wait for fetching correct layout. |
| 1038 layout: 'CENTER_CROPPED', |
| 1039 source: Constants.WallpaperSourceEnum.Custom, |
| 1040 availableOffline: true |
| 1041 }; |
| 1042 wallpapersDataModel.push(wallpaperInfo); |
| 1043 } |
| 1044 if (loadTimeData.getBoolean('isOEMDefaultWallpaper')) { |
| 1045 var oemDefaultWallpaperElement = { |
| 1046 wallpaperId: null, |
| 1047 baseURL: 'OemDefaultWallpaper', |
| 1048 layout: 'CENTER_CROPPED', |
| 1049 source: Constants.WallpaperSourceEnum.OEM, |
| 1050 availableOffline: true |
| 1051 }; |
| 1052 wallpapersDataModel.push(oemDefaultWallpaperElement); |
| 1053 } |
| 1054 for (var i = 0; i < wallpapersDataModel.length; i++) { |
| 1055 // For custom wallpapers, the file name of |currentWallpaper_| |
| 1056 // includes the first directory level (corresponding to user id hash). |
| 1057 if (getBaseName(self.currentWallpaper_) == |
| 1058 wallpapersDataModel.item(i).baseURL) { |
| 1059 selectedItem = wallpapersDataModel.item(i); |
| 1060 } |
| 1061 } |
| 1062 var lastElement = { |
| 1063 baseURL: '', |
| 1064 layout: '', |
| 1065 source: Constants.WallpaperSourceEnum.AddNew, |
| 1066 availableOffline: true |
| 1067 }; |
| 1068 wallpapersDataModel.push(lastElement); |
| 1069 self.wallpaperGrid_.dataModel = wallpapersDataModel; |
| 1070 if (selectedItem) { |
| 1071 self.wallpaperGrid_.selectedItem = selectedItem; |
| 1072 self.wallpaperGrid_.activeItem = selectedItem; |
| 1073 } |
| 1074 }; |
| 1075 |
| 1076 var success = function(dirEntry) { |
| 1077 var dirReader = dirEntry.createReader(); |
| 1078 var entries = []; |
| 1079 // All of a directory's entries are not guaranteed to return in a single |
| 1080 // call. |
| 1081 var readEntries = function() { |
| 1082 dirReader.readEntries(function(results) { |
| 1083 if (!results.length) { |
| 1084 processResults(entries.sort()); |
| 1085 } else { |
| 1086 entries = entries.concat(toArray(results)); |
| 1087 readEntries(); |
| 1088 } |
| 945 }, errorHandler); | 1089 }, errorHandler); |
| 946 }; | 1090 }; |
| 947 | 1091 readEntries(); // Start reading dirs. |
| 948 // Removes copy of original. | |
| 949 self.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.ORIGINAL, | |
| 950 success, | |
| 951 errorHandler); | |
| 952 | |
| 953 // Removes generated thumbnail. | |
| 954 self.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.THUMBNAIL, | |
| 955 success, | |
| 956 errorHandler); | |
| 957 }; | 1092 }; |
| 958 removeFile(fileName); | 1093 this.wallpaperDirs_.getDirectory( |
| 959 }; | 1094 Constants.WallpaperDirNameEnum.ORIGINAL, success, errorHandler); |
| 960 | 1095 } else { |
| 961 /** | 1096 this.document_.body.removeAttribute('custom'); |
| 962 * Sets current wallpaper and generate thumbnail if generateThumbnail is true. | 1097 // Need this check for test purpose. |
| 963 * @param {ArrayBuffer} wallpaper The binary representation of wallpaper. | 1098 var numOnlineWallpaper = (this.enableOnlineWallpaper_ && this.manifest_) ? |
| 964 * @param {string} layout The user selected wallpaper layout. | 1099 this.manifest_.wallpaper_list.length : |
| 965 * @param {boolean} generateThumbnail True if need to generate thumbnail. | 1100 0; |
| 966 * @param {string} fileName The unique file name of wallpaper. | 1101 for (var i = 0; i < numOnlineWallpaper; i++) { |
| 967 * @param {function(thumbnail):void} success Success callback. If | 1102 if (selectedIndex == AllCategoryIndex || |
| 968 * generateThumbnail is true, the callback parameter should have the | 1103 this.manifest_.wallpaper_list[i].categories.indexOf( |
| 969 * generated thumbnail. | 1104 selectedIndex - OnlineCategoriesOffset) != -1) { |
| 970 * @param {function(e):void} failure Failure callback. Called when there is an | 1105 var wallpaperInfo = { |
| 971 * error from FileSystem. | 1106 wallpaperId: i, |
| 972 */ | 1107 baseURL: this.manifest_.wallpaper_list[i].base_url, |
| 973 WallpaperManager.prototype.setCustomWallpaper = function(wallpaper, | 1108 layout: this.manifest_.wallpaper_list[i].default_layout, |
| 974 layout, | 1109 source: Constants.WallpaperSourceEnum.Online, |
| 975 generateThumbnail, | 1110 availableOffline: false, |
| 976 fileName, | 1111 author: this.manifest_.wallpaper_list[i].author, |
| 977 success, | 1112 authorWebsite: this.manifest_.wallpaper_list[i].author_website, |
| 978 failure) { | 1113 dynamicURL: this.manifest_.wallpaper_list[i].dynamic_url |
| 979 var self = this; | 1114 }; |
| 980 var onFinished = function(opt_thumbnail) { | 1115 var fileName = |
| 981 if (chrome.runtime.lastError != undefined && | 1116 getBaseName(wallpaperInfo.baseURL) + Constants.HighResolutionSuffix; |
| 982 chrome.runtime.lastError.message != str('canceledWallpaper')) { | 1117 if (this.downloadedListMap_ && |
| 983 self.showError_(chrome.runtime.lastError.message); | 1118 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { |
| 984 $('set-wallpaper-layout').disabled = true; | 1119 wallpaperInfo.availableOffline = true; |
| 985 failure(); | |
| 986 } else { | |
| 987 success(opt_thumbnail); | |
| 988 } | |
| 989 }; | |
| 990 | |
| 991 chrome.wallpaperPrivate.setCustomWallpaper(wallpaper, layout, | |
| 992 generateThumbnail, | |
| 993 fileName, onFinished); | |
| 994 }; | |
| 995 | |
| 996 /** | |
| 997 * Handles the layout setting change of custom wallpaper. | |
| 998 */ | |
| 999 WallpaperManager.prototype.onWallpaperLayoutChanged_ = function() { | |
| 1000 var layout = getSelectedLayout(); | |
| 1001 var self = this; | |
| 1002 chrome.wallpaperPrivate.setCustomWallpaperLayout(layout, function() { | |
| 1003 if (chrome.runtime.lastError != undefined && | |
| 1004 chrome.runtime.lastError.message != str('canceledWallpaper')) { | |
| 1005 self.showError_(chrome.runtime.lastError.message); | |
| 1006 self.removeCustomWallpaper(fileName); | |
| 1007 $('set-wallpaper-layout').disabled = true; | |
| 1008 } else { | |
| 1009 WallpaperUtil.saveToLocalStorage(self.currentWallpaper_, layout); | |
| 1010 self.onWallpaperChanged_(self.wallpaperGrid_.activeItem, | |
| 1011 self.currentWallpaper_); | |
| 1012 } | |
| 1013 }); | |
| 1014 }; | |
| 1015 | |
| 1016 /** | |
| 1017 * Handles user clicking on a different category. | |
| 1018 */ | |
| 1019 WallpaperManager.prototype.onCategoriesChange_ = function() { | |
| 1020 var categoriesList = this.categoriesList_; | |
| 1021 var selectedIndex = categoriesList.selectionModel.selectedIndex; | |
| 1022 if (selectedIndex == -1) | |
| 1023 return; | |
| 1024 var selectedListItem = categoriesList.getListItemByIndex(selectedIndex); | |
| 1025 var bar = $('bar'); | |
| 1026 bar.style.left = selectedListItem.offsetLeft + 'px'; | |
| 1027 bar.style.width = selectedListItem.offsetWidth + 'px'; | |
| 1028 | |
| 1029 var wallpapersDataModel = new cr.ui.ArrayDataModel([]); | |
| 1030 var selectedItem = null; | |
| 1031 if (selectedListItem.custom) { | |
| 1032 this.document_.body.setAttribute('custom', ''); | |
| 1033 var errorHandler = this.onFileSystemError_.bind(this); | |
| 1034 var toArray = function(list) { | |
| 1035 return Array.prototype.slice.call(list || [], 0); | |
| 1036 }; | |
| 1037 | |
| 1038 var self = this; | |
| 1039 var processResults = function(entries) { | |
| 1040 for (var i = 0; i < entries.length; i++) { | |
| 1041 var entry = entries[i]; | |
| 1042 var wallpaperInfo = { | |
| 1043 // Set wallpaperId to null to avoid duplicate thumbnail images, | |
| 1044 // see crbug.com/506135 for details. | |
| 1045 wallpaperId: null, | |
| 1046 baseURL: entry.name, | |
| 1047 // The layout will be replaced by the actual value saved in | |
| 1048 // local storage when requested later. Layout is not important | |
| 1049 // for constructing thumbnails grid, we use CENTER_CROPPED here | |
| 1050 // to speed up the process of constructing. So we do not need to | |
| 1051 // wait for fetching correct layout. | |
| 1052 layout: 'CENTER_CROPPED', | |
| 1053 source: Constants.WallpaperSourceEnum.Custom, | |
| 1054 availableOffline: true | |
| 1055 }; | |
| 1056 wallpapersDataModel.push(wallpaperInfo); | |
| 1057 } | 1120 } |
| 1058 if (loadTimeData.getBoolean('isOEMDefaultWallpaper')) { | 1121 wallpapersDataModel.push(wallpaperInfo); |
| 1059 var oemDefaultWallpaperElement = { | 1122 var url = this.manifest_.wallpaper_list[i].base_url + |
| 1060 wallpaperId: null, | 1123 Constants.HighResolutionSuffix; |
| 1061 baseURL: 'OemDefaultWallpaper', | 1124 if (url == this.currentWallpaper_) { |
| 1062 layout: 'CENTER_CROPPED', | 1125 selectedItem = wallpaperInfo; |
| 1063 source: Constants.WallpaperSourceEnum.OEM, | |
| 1064 availableOffline: true | |
| 1065 }; | |
| 1066 wallpapersDataModel.push(oemDefaultWallpaperElement); | |
| 1067 } | |
| 1068 for (var i = 0; i < wallpapersDataModel.length; i++) { | |
| 1069 // For custom wallpapers, the file name of |currentWallpaper_| | |
| 1070 // includes the first directory level (corresponding to user id hash). | |
| 1071 if (getBaseName(self.currentWallpaper_) == | |
| 1072 wallpapersDataModel.item(i).baseURL) { | |
| 1073 selectedItem = wallpapersDataModel.item(i); | |
| 1074 } | |
| 1075 } | |
| 1076 var lastElement = { | |
| 1077 baseURL: '', | |
| 1078 layout: '', | |
| 1079 source: Constants.WallpaperSourceEnum.AddNew, | |
| 1080 availableOffline: true | |
| 1081 }; | |
| 1082 wallpapersDataModel.push(lastElement); | |
| 1083 self.wallpaperGrid_.dataModel = wallpapersDataModel; | |
| 1084 if (selectedItem) { | |
| 1085 self.wallpaperGrid_.selectedItem = selectedItem; | |
| 1086 self.wallpaperGrid_.activeItem = selectedItem; | |
| 1087 } | |
| 1088 }; | |
| 1089 | |
| 1090 var success = function(dirEntry) { | |
| 1091 var dirReader = dirEntry.createReader(); | |
| 1092 var entries = []; | |
| 1093 // All of a directory's entries are not guaranteed to return in a single | |
| 1094 // call. | |
| 1095 var readEntries = function() { | |
| 1096 dirReader.readEntries(function(results) { | |
| 1097 if (!results.length) { | |
| 1098 processResults(entries.sort()); | |
| 1099 } else { | |
| 1100 entries = entries.concat(toArray(results)); | |
| 1101 readEntries(); | |
| 1102 } | |
| 1103 }, errorHandler); | |
| 1104 }; | |
| 1105 readEntries(); // Start reading dirs. | |
| 1106 }; | |
| 1107 this.wallpaperDirs_.getDirectory(Constants.WallpaperDirNameEnum.ORIGINAL, | |
| 1108 success, errorHandler); | |
| 1109 } else { | |
| 1110 this.document_.body.removeAttribute('custom'); | |
| 1111 // Need this check for test purpose. | |
| 1112 var numOnlineWallpaper = (this.enableOnlineWallpaper_ && this.manifest_) ? | |
| 1113 this.manifest_.wallpaper_list.length : 0; | |
| 1114 for (var i = 0; i < numOnlineWallpaper; i++) { | |
| 1115 if (selectedIndex == AllCategoryIndex || | |
| 1116 this.manifest_.wallpaper_list[i].categories.indexOf( | |
| 1117 selectedIndex - OnlineCategoriesOffset) != -1) { | |
| 1118 var wallpaperInfo = { | |
| 1119 wallpaperId: i, | |
| 1120 baseURL: this.manifest_.wallpaper_list[i].base_url, | |
| 1121 layout: this.manifest_.wallpaper_list[i].default_layout, | |
| 1122 source: Constants.WallpaperSourceEnum.Online, | |
| 1123 availableOffline: false, | |
| 1124 author: this.manifest_.wallpaper_list[i].author, | |
| 1125 authorWebsite: this.manifest_.wallpaper_list[i].author_website, | |
| 1126 dynamicURL: this.manifest_.wallpaper_list[i].dynamic_url | |
| 1127 }; | |
| 1128 var fileName = getBaseName(wallpaperInfo.baseURL) + | |
| 1129 Constants.HighResolutionSuffix; | |
| 1130 if (this.downloadedListMap_ && | |
| 1131 this.downloadedListMap_.hasOwnProperty(encodeURI(fileName))) { | |
| 1132 wallpaperInfo.availableOffline = true; | |
| 1133 } | |
| 1134 wallpapersDataModel.push(wallpaperInfo); | |
| 1135 var url = this.manifest_.wallpaper_list[i].base_url + | |
| 1136 Constants.HighResolutionSuffix; | |
| 1137 if (url == this.currentWallpaper_) { | |
| 1138 selectedItem = wallpaperInfo; | |
| 1139 } | |
| 1140 } | 1126 } |
| 1141 } | 1127 } |
| 1142 this.wallpaperGrid_.dataModel = wallpapersDataModel; | |
| 1143 if (selectedItem) { | |
| 1144 this.wallpaperGrid_.selectedItem = selectedItem; | |
| 1145 this.wallpaperGrid_.activeItem = selectedItem; | |
| 1146 } | |
| 1147 } | 1128 } |
| 1148 }; | 1129 this.wallpaperGrid_.dataModel = wallpapersDataModel; |
| 1130 if (selectedItem) { |
| 1131 this.wallpaperGrid_.selectedItem = selectedItem; |
| 1132 this.wallpaperGrid_.activeItem = selectedItem; |
| 1133 } |
| 1134 } |
| 1135 }; |
| 1149 | 1136 |
| 1150 })(); | 1137 })(); |
| OLD | NEW |