Commit 392f1214 authored by xdai's avatar xdai Committed by Commit bot

Reland of "Decrease the lag when switching between different categories in the...

Reland of "Decrease the lag when switching between different categories in the Cros wallpaper selector".

The original one (https://codereview.chromium.org/1028513003) caused failures in the cros_trunk official builder (see http://master.chrome.corp.google.com:8011/builders/cros%20trunk/builds/31816 for detail).

The issue should fix the broken tests.

BUG=454932

Review URL: https://codereview.chromium.org/1038543002

Cr-Commit-Position: refs/heads/master@{#322602}
parent d98dbc8d
...@@ -13,21 +13,28 @@ cr.define('wallpapers', function() { ...@@ -13,21 +13,28 @@ cr.define('wallpapers', function() {
/** /**
* Creates a new wallpaper thumbnails grid item. * Creates a new wallpaper thumbnails grid item.
* @param {{baseURL: string, layout: string, source: string, * @param {{wallpaperId: number, baseURL: string, layout: string,
* availableOffline: boolean, opt_dynamicURL: string, * source: string, availableOffline: boolean,
* opt_author: string, opt_authorWebsite: string}} * opt_dynamicURL: string, opt_author: string,
* opt_authorWebsite: string}}
* wallpaperInfo Wallpaper data item in WallpaperThumbnailsGrid's data * wallpaperInfo Wallpaper data item in WallpaperThumbnailsGrid's data
* model. * model.
* @param {number} dataModelId A unique ID that this item associated to. * @param {number} dataModelId A unique ID that this item associated to.
* @param {object} thumbnail The thumbnail image Object associated with this
* grid item.
* @param {function} callback The callback function when decoration finished. * @param {function} callback The callback function when decoration finished.
* @constructor * @constructor
* @extends {cr.ui.GridItem} * @extends {cr.ui.GridItem}
*/ */
function WallpaperThumbnailsGridItem(wallpaperInfo, dataModelId, callback) { function WallpaperThumbnailsGridItem(wallpaperInfo,
dataModelId,
thumbnail,
callback) {
var el = new GridItem(wallpaperInfo); var el = new GridItem(wallpaperInfo);
el.__proto__ = WallpaperThumbnailsGridItem.prototype; el.__proto__ = WallpaperThumbnailsGridItem.prototype;
el.dataModelId = dataModelId; el.dataModelId_ = dataModelId;
el.callback = callback; el.thumbnail_ = thumbnail;
el.callback_ = callback;
return el; return el;
} }
...@@ -38,7 +45,12 @@ cr.define('wallpapers', function() { ...@@ -38,7 +45,12 @@ cr.define('wallpapers', function() {
* The unique ID this thumbnail grid associated to. * The unique ID this thumbnail grid associated to.
* @type {number} * @type {number}
*/ */
dataModelId: null, dataModelId_: null,
/**
* The thumbnail image associated with the current grid item.
*/
thumbnail_: null,
/** /**
* Called when the WallpaperThumbnailsGridItem is decorated or failed to * Called when the WallpaperThumbnailsGridItem is decorated or failed to
...@@ -46,13 +58,20 @@ cr.define('wallpapers', function() { ...@@ -46,13 +58,20 @@ cr.define('wallpapers', function() {
* be called after image loaded. * be called after image loaded.
* @type {function} * @type {function}
*/ */
callback: null, callback_: null,
/** @override */ /** @override */
decorate: function() { decorate: function() {
GridItem.prototype.decorate.call(this); GridItem.prototype.decorate.call(this);
// Removes garbage created by GridItem. // Removes garbage created by GridItem.
this.innerText = ''; this.innerText = '';
if (this.thumbnail_) {
this.appendChild(this.thumbnail_);
this.callback_(this.dataModelId_);
return;
}
var imageEl = cr.doc.createElement('img'); var imageEl = cr.doc.createElement('img');
imageEl.classList.add('thumbnail'); imageEl.classList.add('thumbnail');
cr.defineProperty(imageEl, 'offline', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(imageEl, 'offline', cr.PropertyKind.BOOL_ATTR);
...@@ -70,18 +89,20 @@ cr.define('wallpapers', function() { ...@@ -70,18 +89,20 @@ cr.define('wallpapers', function() {
}); });
// Delay dispatching the completion callback until all items have // Delay dispatching the completion callback until all items have
// begun loading and are tracked. // begun loading and are tracked.
window.setTimeout(this.callback.bind(this, this.dataModelId), 0); window.setTimeout(this.callback_.bind(this, this.dataModelId_), 0);
break; break;
case Constants.WallpaperSourceEnum.Custom: case Constants.WallpaperSourceEnum.Custom:
var errorHandler = function(e) { var errorHandler = function(e) {
self.callback(self.dataModelId); self.callback_(self.dataModelId_);
console.error('Can not access file system.'); console.error('Can not access file system.');
}; };
var wallpaperDirectories = WallpaperDirectories.getInstance(); var wallpaperDirectories = WallpaperDirectories.getInstance();
var getThumbnail = function(fileName) { var getThumbnail = function(fileName) {
var setURL = function(fileEntry) { var setURL = function(fileEntry) {
imageEl.src = fileEntry.toURL(); imageEl.src = fileEntry.toURL();
self.callback(self.dataModelId); self.callback_(self.dataModelId_,
self.dataItem.wallpaperId,
imageEl);
}; };
var fallback = function() { var fallback = function() {
wallpaperDirectories.getDirectory( wallpaperDirectories.getDirectory(
...@@ -108,7 +129,9 @@ cr.define('wallpapers', function() { ...@@ -108,7 +129,9 @@ cr.define('wallpapers', function() {
{'type': 'image\/png'}); {'type': 'image\/png'});
imageEl.src = window.URL.createObjectURL(blob); imageEl.src = window.URL.createObjectURL(blob);
imageEl.addEventListener('load', function(e) { imageEl.addEventListener('load', function(e) {
self.callback(self.dataModelId); self.callback_(self.dataModelId_,
self.dataItem.wallpaperId,
imageEl);
window.URL.revokeObjectURL(this.src); window.URL.revokeObjectURL(this.src);
}); });
} else if (self.dataItem.source == } else if (self.dataItem.source ==
...@@ -128,11 +151,13 @@ cr.define('wallpapers', function() { ...@@ -128,11 +151,13 @@ cr.define('wallpapers', function() {
// thumbnail. Use a placeholder like "loading" image may // thumbnail. Use a placeholder like "loading" image may
// better. // better.
imageEl.addEventListener('load', function(e) { imageEl.addEventListener('load', function(e) {
self.callback(self.dataModelId); self.callback_(self.dataModelId_,
self.dataItem.wallpaperId,
this);
window.URL.revokeObjectURL(this.src); window.URL.revokeObjectURL(this.src);
}); });
} else { } else {
self.callback(self.dataModelId); self.callback_(self.dataModelId_);
} }
}); });
} }
...@@ -142,7 +167,7 @@ cr.define('wallpapers', function() { ...@@ -142,7 +167,7 @@ cr.define('wallpapers', function() {
console.error('Unsupported image source.'); console.error('Unsupported image source.');
// Delay dispatching the completion callback until all items have // Delay dispatching the completion callback until all items have
// begun loading and are tracked. // begun loading and are tracked.
window.setTimeout(this.callback.bind(this, this.dataModelId), 0); window.setTimeout(this.callback_.bind(this, this.dataModelId_), 0);
} }
}, },
}; };
...@@ -239,6 +264,12 @@ cr.define('wallpapers', function() { ...@@ -239,6 +264,12 @@ cr.define('wallpapers', function() {
*/ */
pendingItems_: 0, pendingItems_: 0,
/**
* Maintains all grid items' thumbnail images for quickly switching between
* different categories.
*/
thumbnailList_: undefined,
/** @override */ /** @override */
set dataModel(dataModel) { set dataModel(dataModel) {
if (this.dataModel_ == dataModel) if (this.dataModel_ == dataModel)
...@@ -282,11 +313,19 @@ cr.define('wallpapers', function() { ...@@ -282,11 +313,19 @@ cr.define('wallpapers', function() {
* it does not reduce the count on a previous |dataModelId|. * it does not reduce the count on a previous |dataModelId|.
* @param {number} dataModelId A unique ID that a thumbnail item is * @param {number} dataModelId A unique ID that a thumbnail item is
* associated to. * associated to.
* @param {number} opt_wallpaperId The unique wallpaper ID that associated
* with this thumbnail gird item.
* @param {object} opt_thumbnail The thumbnail image that associated with
* the opt_wallpaperId.
*/ */
pendingItemComplete: function(dataModelId) { pendingItemComplete: function(dataModelId,
opt_wallpaperId,
opt_thumbnail) {
if (dataModelId != this.dataModelId_) if (dataModelId != this.dataModelId_)
return; return;
this.pendingItems_--; this.pendingItems_--;
if (opt_wallpaperId != null)
this.thumbnailList_[opt_wallpaperId] = opt_thumbnail;
if (this.pendingItems_ == 0) { if (this.pendingItems_ == 0) {
this.style.visibility = 'visible'; this.style.visibility = 'visible';
window.clearTimeout(this.spinnerTimeout_); window.clearTimeout(this.spinnerTimeout_);
...@@ -304,11 +343,13 @@ cr.define('wallpapers', function() { ...@@ -304,11 +343,13 @@ cr.define('wallpapers', function() {
this.checkmark_ = cr.doc.createElement('div'); this.checkmark_ = cr.doc.createElement('div');
this.checkmark_.classList.add('check'); this.checkmark_.classList.add('check');
this.dataModel = new ArrayDataModel([]); this.dataModel = new ArrayDataModel([]);
this.thumbnailList_ = new ArrayDataModel([]);
var self = this; var self = this;
this.itemConstructor = function(value) { this.itemConstructor = function(value) {
var dataModelId = self.dataModelId_; var dataModelId = self.dataModelId_;
self.pendingItems_++; self.pendingItems_++;
return WallpaperThumbnailsGridItem(value, dataModelId, return WallpaperThumbnailsGridItem(value, dataModelId,
self.thumbnailList_[value.wallpaperId],
self.pendingItemComplete.bind(self)); self.pendingItemComplete.bind(self));
}; };
this.selectionModel = new ListSingleSelectionModel(); this.selectionModel = new ListSingleSelectionModel();
......
...@@ -17,7 +17,6 @@ function WallpaperManager(dialogDom) { ...@@ -17,7 +17,6 @@ function WallpaperManager(dialogDom) {
this.dialogDom_ = dialogDom; this.dialogDom_ = dialogDom;
this.document_ = dialogDom.ownerDocument; this.document_ = dialogDom.ownerDocument;
this.enableOnlineWallpaper_ = loadTimeData.valueExists('manifestBaseURL'); this.enableOnlineWallpaper_ = loadTimeData.valueExists('manifestBaseURL');
this.selectedCategory = null;
this.selectedItem_ = null; this.selectedItem_ = null;
this.progressManager_ = new ProgressManager(); this.progressManager_ = new ProgressManager();
this.customWallpaperData_ = null; this.customWallpaperData_ = null;
...@@ -182,7 +181,8 @@ function WallpaperManager(dialogDom) { ...@@ -182,7 +181,8 @@ function WallpaperManager(dialogDom) {
var accessManifestKey = Constants.AccessManifestKey; var accessManifestKey = Constants.AccessManifestKey;
var self = this; var self = this;
Constants.WallpaperLocalStorage.get(accessManifestKey, function(items) { Constants.WallpaperLocalStorage.get(accessManifestKey, function(items) {
self.manifest_ = items[accessManifestKey] ? items[accessManifestKey] : {}; self.manifest_ = items[accessManifestKey] ?
items[accessManifestKey] : null;
self.showError_(str('connectionFailed')); self.showError_(str('connectionFailed'));
self.postManifestDomInit_(); self.postManifestDomInit_();
$('wallpaper-grid').classList.add('image-picker-offline'); $('wallpaper-grid').classList.add('image-picker-offline');
...@@ -455,7 +455,6 @@ function WallpaperManager(dialogDom) { ...@@ -455,7 +455,6 @@ function WallpaperManager(dialogDom) {
WallpaperManager.prototype.initThumbnailsGrid_ = function() { WallpaperManager.prototype.initThumbnailsGrid_ = function() {
this.wallpaperGrid_ = $('wallpaper-grid'); this.wallpaperGrid_ = $('wallpaper-grid');
wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_); wallpapers.WallpaperThumbnailsGrid.decorate(this.wallpaperGrid_);
this.wallpaperGrid_.autoExpands = true;
this.wallpaperGrid_.addEventListener('change', this.onChange_.bind(this)); this.wallpaperGrid_.addEventListener('change', this.onChange_.bind(this));
this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this)); this.wallpaperGrid_.addEventListener('dblclick', this.onClose_.bind(this));
...@@ -1003,10 +1002,14 @@ function WallpaperManager(dialogDom) { ...@@ -1003,10 +1002,14 @@ function WallpaperManager(dialogDom) {
}; };
var self = this; var self = this;
// Need this check for test purpose.
var numOnlineWallpaper = (this.enableOnlineWallpaper_ && this.manifest_) ?
this.manifest_.wallpaper_list.length : 0;
var processResults = function(entries) { var processResults = function(entries) {
for (var i = 0; i < entries.length; i++) { for (var i = 0; i < entries.length; i++) {
var entry = entries[i]; var entry = entries[i];
var wallpaperInfo = { var wallpaperInfo = {
wallpaperId: numOnlineWallpaper + i,
baseURL: entry.name, baseURL: entry.name,
// The layout will be replaced by the actual value saved in // The layout will be replaced by the actual value saved in
// local storage when requested later. Layout is not important // local storage when requested later. Layout is not important
...@@ -1021,6 +1024,7 @@ function WallpaperManager(dialogDom) { ...@@ -1021,6 +1024,7 @@ function WallpaperManager(dialogDom) {
} }
if (loadTimeData.getBoolean('isOEMDefaultWallpaper')) { if (loadTimeData.getBoolean('isOEMDefaultWallpaper')) {
var oemDefaultWallpaperElement = { var oemDefaultWallpaperElement = {
wallpaperId: numOnlineWallpaper + entries.length,
baseURL: 'OemDefaultWallpaper', baseURL: 'OemDefaultWallpaper',
layout: 'CENTER_CROPPED', layout: 'CENTER_CROPPED',
source: Constants.WallpaperSourceEnum.OEM, source: Constants.WallpaperSourceEnum.OEM,
...@@ -1067,18 +1071,22 @@ function WallpaperManager(dialogDom) { ...@@ -1067,18 +1071,22 @@ function WallpaperManager(dialogDom) {
success, errorHandler); success, errorHandler);
} else { } else {
this.document_.body.removeAttribute('custom'); this.document_.body.removeAttribute('custom');
for (var key in this.manifest_.wallpaper_list) { // Need this check for test purpose.
var numOnlineWallpaper = (this.enableOnlineWallpaper_ && this.manifest_) ?
this.manifest_.wallpaper_list.length : 0;
for (var i = 0; i < numOnlineWallpaper; i++) {
if (selectedIndex == AllCategoryIndex || if (selectedIndex == AllCategoryIndex ||
this.manifest_.wallpaper_list[key].categories.indexOf( this.manifest_.wallpaper_list[i].categories.indexOf(
selectedIndex - OnlineCategoriesOffset) != -1) { selectedIndex - OnlineCategoriesOffset) != -1) {
var wallpaperInfo = { var wallpaperInfo = {
baseURL: this.manifest_.wallpaper_list[key].base_url, wallpaperId: i,
layout: this.manifest_.wallpaper_list[key].default_layout, baseURL: this.manifest_.wallpaper_list[i].base_url,
layout: this.manifest_.wallpaper_list[i].default_layout,
source: Constants.WallpaperSourceEnum.Online, source: Constants.WallpaperSourceEnum.Online,
availableOffline: false, availableOffline: false,
author: this.manifest_.wallpaper_list[key].author, author: this.manifest_.wallpaper_list[i].author,
authorWebsite: this.manifest_.wallpaper_list[key].author_website, authorWebsite: this.manifest_.wallpaper_list[i].author_website,
dynamicURL: this.manifest_.wallpaper_list[key].dynamic_url dynamicURL: this.manifest_.wallpaper_list[i].dynamic_url
}; };
var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1; var startIndex = wallpaperInfo.baseURL.lastIndexOf('/') + 1;
var fileName = wallpaperInfo.baseURL.substring(startIndex) + var fileName = wallpaperInfo.baseURL.substring(startIndex) +
...@@ -1088,7 +1096,7 @@ function WallpaperManager(dialogDom) { ...@@ -1088,7 +1096,7 @@ function WallpaperManager(dialogDom) {
wallpaperInfo.availableOffline = true; wallpaperInfo.availableOffline = true;
} }
wallpapersDataModel.push(wallpaperInfo); wallpapersDataModel.push(wallpaperInfo);
var url = this.manifest_.wallpaper_list[key].base_url + var url = this.manifest_.wallpaper_list[i].base_url +
Constants.HighResolutionSuffix; Constants.HighResolutionSuffix;
if (url == this.currentWallpaper_) { if (url == this.currentWallpaper_) {
selectedItem = wallpaperInfo; selectedItem = wallpaperInfo;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment