Commit 9522fad4 authored by hirono@chromium.org's avatar hirono@chromium.org

Files.app: Make the sort for the search result stable.

In search result, the entries have same names and it causes unstability of the
sort. The CL let the compare function to see URL when the names are same.

The CL also moves the sort functions from the UI class to the model class.

BUG=397386
TEST=manually

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285537 0039d316-1c4b-4281-b951-d872f2087c98
parent 4115037d
......@@ -400,6 +400,109 @@ FileFilter.prototype.filter = function(entry) {
return true;
};
/**
* File list.
* @param {MetadataCache} metadataCache Metadata cache.
* @constructor
* @extends {cr.ui.ArrayDataModel}
*/
function FileListModel(metadataCache) {
cr.ui.ArrayDataModel.call(this, []);
/**
* Metadata cache.
* @type {MetadataCache}
*/
this.metadataCache_ = metadataCache;
/**
* Collator for sorting.
* @type {Intl.Collator}
*/
this.collator_ = new Intl.Collator([], {numeric: true, sensitivity: 'base'});
// Initialize compare functions.
this.setCompareFunction('name', this.compareName_.bind(this));
this.setCompareFunction('modificationTime', this.compareMtime_.bind(this));
this.setCompareFunction('size', this.compareSize_.bind(this));
this.setCompareFunction('type', this.compareType_.bind(this));
}
FileListModel.prototype = {
__proto__: cr.ui.ArrayDataModel.prototype
};
/**
* Compare by mtime first, then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileListModel.prototype.compareName_ = function(a, b) {
var result = this.collator_.compare(a.name, b.name);
return result !== 0 ? result : a.toURL().localeCompare(b.toURL());
};
/**
* Compare by mtime first, then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileListModel.prototype.compareMtime_ = function(a, b) {
var aCachedFilesystem = this.metadataCache_.getCached(a, 'filesystem');
var aTime = aCachedFilesystem ? aCachedFilesystem.modificationTime : 0;
var bCachedFilesystem = this.metadataCache_.getCached(b, 'filesystem');
var bTime = bCachedFilesystem ? bCachedFilesystem.modificationTime : 0;
if (aTime > bTime)
return 1;
if (aTime < bTime)
return -1;
return this.compareName_(a, b);
};
/**
* Compare by size first, then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileListModel.prototype.compareSize_ = function(a, b) {
var aCachedFilesystem = this.metadataCache_.getCached(a, 'filesystem');
var aSize = aCachedFilesystem ? aCachedFilesystem.size : 0;
var bCachedFilesystem = this.metadataCache_.getCached(b, 'filesystem');
var bSize = bCachedFilesystem ? bCachedFilesystem.size : 0;
return aSize !== bSize ? aSize - bSize : this.compareName_(a, b);
};
/**
* Compare by type first, then by subtype and then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileListModel.prototype.compareType_ = function(a, b) {
// Directories precede files.
if (a.isDirectory !== b.isDirectory)
return Number(b.isDirectory) - Number(a.isDirectory);
var aType = FileType.typeToString(FileType.getType(a));
var bType = FileType.typeToString(FileType.getType(b));
var result = this.collator_.compare(aType, bType);
return result !== 0 ? result : this.compareName_(a, b);
};
/**
* A context of DirectoryContents.
* TODO(yoshiki): remove this. crbug.com/224869.
......@@ -410,9 +513,9 @@ FileFilter.prototype.filter = function(entry) {
*/
function FileListContext(fileFilter, metadataCache) {
/**
* @type {cr.ui.ArrayDataModel}
* @type {FileListModel}
*/
this.fileList = new cr.ui.ArrayDataModel([]);
this.fileList = new FileListModel(metadataCache);
/**
* @type {MetadataCache}
......
......@@ -1004,9 +1004,6 @@ var BOTTOM_MARGIN_FOR_PREVIEW_PANEL_PX = 52;
this.selectionHandler_ = new FileSelectionHandler(this);
var dataModel = this.directoryModel_.getFileList();
this.table_.setupCompareFunctions(dataModel);
dataModel.addEventListener('permuted',
this.updateStartupPrefs_.bind(this));
......
......@@ -219,7 +219,6 @@ FileTable.decorate = function(self, metadataCache, volumeManager, fullPage) {
self.__proto__ = FileTable.prototype;
self.metadataCache_ = metadataCache;
self.volumeManager_ = volumeManager;
self.collator_ = Intl.Collator([], {numeric: true, sensitivity: 'base'});
var columns = [
new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'),
......@@ -423,21 +422,6 @@ FileTable.prototype.shouldStartDragSelection_ = function(event) {
}
};
/**
* Prepares the data model to be sorted by columns.
* @param {cr.ui.ArrayDataModel} dataModel Data model to prepare.
*/
FileTable.prototype.setupCompareFunctions = function(dataModel) {
dataModel.setCompareFunction('name',
this.compareName_.bind(this));
dataModel.setCompareFunction('modificationTime',
this.compareMtime_.bind(this));
dataModel.setCompareFunction('size',
this.compareSize_.bind(this));
dataModel.setCompareFunction('type',
this.compareType_.bind(this));
};
/**
* Render the Name column of the detail table.
*
......@@ -627,80 +611,6 @@ FileTable.prototype.updateListItemsMetadata = function(type, entries) {
}
};
/**
* Compare by mtime first, then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileTable.prototype.compareName_ = function(a, b) {
return this.collator_.compare(a.name, b.name);
};
/**
* Compare by mtime first, then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileTable.prototype.compareMtime_ = function(a, b) {
var aCachedFilesystem = this.metadataCache_.getCached(a, 'filesystem');
var aTime = aCachedFilesystem ? aCachedFilesystem.modificationTime : 0;
var bCachedFilesystem = this.metadataCache_.getCached(b, 'filesystem');
var bTime = bCachedFilesystem ? bCachedFilesystem.modificationTime : 0;
if (aTime > bTime)
return 1;
if (aTime < bTime)
return -1;
return this.collator_.compare(a.name, b.name);
};
/**
* Compare by size first, then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileTable.prototype.compareSize_ = function(a, b) {
var aCachedFilesystem = this.metadataCache_.getCached(a, 'filesystem');
var aSize = aCachedFilesystem ? aCachedFilesystem.size : 0;
var bCachedFilesystem = this.metadataCache_.getCached(b, 'filesystem');
var bSize = bCachedFilesystem ? bCachedFilesystem.size : 0;
if (aSize !== bSize) return aSize - bSize;
return this.collator_.compare(a.name, b.name);
};
/**
* Compare by type first, then by subtype and then by name.
* @param {Entry} a First entry.
* @param {Entry} b Second entry.
* @return {number} Compare result.
* @private
*/
FileTable.prototype.compareType_ = function(a, b) {
// Directories precede files.
if (a.isDirectory !== b.isDirectory)
return Number(b.isDirectory) - Number(a.isDirectory);
var aType = FileType.typeToString(FileType.getType(a));
var bType = FileType.typeToString(FileType.getType(b));
var result = this.collator_.compare(aType, bType);
if (result !== 0)
return result;
return this.collator_.compare(a.name, b.name);
};
/**
* Renders table row.
* @param {function(Entry, cr.ui.Table)} baseRenderFunction Base renderer.
......
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