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