Commit 3d4f3ff1 authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Commit Bot

[Files app] Convert file_selection.js to es6 classes

Used lebab to convert to ES6 class with the following command:
lebab --replace \
 ui/file_manager/file_manager/foreground/js/file_selection.js \
 --transform class

Manual fixes:
- Fix closure markup to go to constructor() instead of class
definition.
- Fix Mock class to be ES6 class too, since closure doesn't allow
old style classes to extends from ES6 classes.
- Rename MockFileSelectionHandler to FakeSelectionHandler. This fake
lies to closure by saying that it extends FileSelectionHandler to allow
it to be passed as FileSelectionHandler in closure compilation.
- Add addEventListener() method to FakeFileSelectionHandler to fix
tests that use this method.

Bug: 778674
Change-Id: I39fb5ef7d7d8ef9c7fbc2b64244a26b9ebe23584
Reviewed-on: https://chromium-review.googlesource.com/c/1457700Reviewed-by: default avatarJoel Hockey <joelhockey@chromium.org>
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629911}
parent c471f24e
...@@ -4,12 +4,13 @@ ...@@ -4,12 +4,13 @@
/** /**
* The current selection object. * The current selection object.
*/
class FileSelection {
/**
* @param {!Array<number>} indexes * @param {!Array<number>} indexes
* @param {!Array<Entry>} entries * @param {!Array<Entry>} entries
* @constructor
* @struct
*/ */
function FileSelection(indexes, entries) { constructor(indexes, entries) {
/** /**
* @public {!Array<number>} * @public {!Array<number>}
* @const * @const
...@@ -79,9 +80,9 @@ function FileSelection(indexes, entries) { ...@@ -79,9 +80,9 @@ function FileSelection(indexes, entries) {
} }
this.totalCount++; this.totalCount++;
}); });
} }
FileSelection.prototype.computeAdditional = function(metadataModel) { computeAdditional(metadataModel) {
if (!this.additionalPromise_) { if (!this.additionalPromise_) {
this.additionalPromise_ = this.additionalPromise_ =
metadataModel metadataModel
...@@ -90,7 +91,8 @@ FileSelection.prototype.computeAdditional = function(metadataModel) { ...@@ -90,7 +91,8 @@ FileSelection.prototype.computeAdditional = function(metadataModel) {
constants.FILE_SELECTION_METADATA_PREFETCH_PROPERTY_NAMES) constants.FILE_SELECTION_METADATA_PREFETCH_PROPERTY_NAMES)
.then(props => { .then(props => {
const present = props.filter(p => { const present = props.filter(p => {
// If no availableOffline property, then assume it's available. // If no availableOffline property, then assume it's
// available.
return !('availableOffline' in p) || p.availableOffline; return !('availableOffline' in p) || p.availableOffline;
}); });
const hosted = props.filter(p => { const hosted = props.filter(p => {
...@@ -105,25 +107,26 @@ FileSelection.prototype.computeAdditional = function(metadataModel) { ...@@ -105,25 +107,26 @@ FileSelection.prototype.computeAdditional = function(metadataModel) {
}); });
} }
return this.additionalPromise_; return this.additionalPromise_;
}; }
}
/** /**
* This object encapsulates everything related to current selection. * This object encapsulates everything related to current selection.
* */
class FileSelectionHandler extends cr.EventTarget {
/**
* @param {!DirectoryModel} directoryModel * @param {!DirectoryModel} directoryModel
* @param {!FileOperationManager} fileOperationManager * @param {!FileOperationManager} fileOperationManager
* @param {!ListContainer} listContainer * @param {!ListContainer} listContainer
* @param {!MetadataModel} metadataModel * @param {!MetadataModel} metadataModel
* @param {!VolumeManager} volumeManager * @param {!VolumeManager} volumeManager
* @param {!AllowedPaths} allowedPaths * @param {!AllowedPaths} allowedPaths
* @extends {cr.EventTarget}
* @constructor
* @struct * @struct
*/ */
function FileSelectionHandler( constructor(
directoryModel, fileOperationManager, listContainer, metadataModel, directoryModel, fileOperationManager, listContainer, metadataModel,
volumeManager, allowedPaths) { volumeManager, allowedPaths) {
cr.EventTarget.call(this); super();
/** /**
* @private {DirectoryModel} * @private {DirectoryModel}
...@@ -176,50 +179,12 @@ function FileSelectionHandler( ...@@ -176,50 +179,12 @@ function FileSelectionHandler(
// Register evnets to update file selections. // Register evnets to update file selections.
directoryModel.addEventListener( directoryModel.addEventListener(
'directory-changed', this.onFileSelectionChanged.bind(this)); 'directory-changed', this.onFileSelectionChanged.bind(this));
} }
/**
* @enum {string}
*/
FileSelectionHandler.EventType = {
/**
* Dispatched every time when selection is changed.
*/
CHANGE: 'change',
/** /**
* Dispatched |UPDATE_DELAY| ms after the selecton is changed.
* If multiple changes are happened during the term, only one CHANGE_THROTTLED
* event is dispatched.
*/
CHANGE_THROTTLED: 'changethrottled'
};
/**
* Delay in milliseconds before recalculating the selection in case the
* selection is changed fast, or there are many items. Used to avoid freezing
* the UI.
* @const {number}
*/
FileSelectionHandler.UPDATE_DELAY = 200;
/**
* Number of items in the selection which triggers the update delay. Used to
* let the Material Design animations complete before performing a heavy task
* which would cause the UI freezing.
* @const {number}
*/
FileSelectionHandler.NUMBER_OF_ITEMS_HEAVY_TO_COMPUTE = 100;
/**
* FileSelectionHandler extends cr.EventTarget.
*/
FileSelectionHandler.prototype.__proto__ = cr.EventTarget.prototype;
/**
* Update the UI when the selection model changes. * Update the UI when the selection model changes.
*/ */
FileSelectionHandler.prototype.onFileSelectionChanged = function() { onFileSelectionChanged() {
const indexes = this.listContainer_.selectionModel.selectedIndexes; const indexes = this.listContainer_.selectionModel.selectedIndexes;
const entries = indexes.map(index => { const entries = indexes.map(index => {
return /** @type {!Entry} */ ( return /** @type {!Entry} */ (
...@@ -240,7 +205,8 @@ FileSelectionHandler.prototype.onFileSelectionChanged = function() { ...@@ -240,7 +205,8 @@ FileSelectionHandler.prototype.onFileSelectionChanged = function() {
const now = Date.now(); const now = Date.now();
if (now > (this.lastFileSelectionTime_ || 0) + updateDelay && if (now > (this.lastFileSelectionTime_ || 0) + updateDelay &&
indexes.length < FileSelectionHandler.NUMBER_OF_ITEMS_HEAVY_TO_COMPUTE) { indexes.length <
FileSelectionHandler.NUMBER_OF_ITEMS_HEAVY_TO_COMPUTE) {
// The previous selection change happened a while ago and there is few // The previous selection change happened a while ago and there is few
// selected items, so computation is lightweight. Update the UI without // selected items, so computation is lightweight. Update the UI without
// delay. // delay.
...@@ -257,15 +223,15 @@ FileSelectionHandler.prototype.onFileSelectionChanged = function() { ...@@ -257,15 +223,15 @@ FileSelectionHandler.prototype.onFileSelectionChanged = function() {
}, updateDelay); }, updateDelay);
cr.dispatchSimpleEvent(this, FileSelectionHandler.EventType.CHANGE); cr.dispatchSimpleEvent(this, FileSelectionHandler.EventType.CHANGE);
}; }
/** /**
* Calculates async selection stats and updates secondary UI elements. * Calculates async selection stats and updates secondary UI elements.
* *
* @param {FileSelection} selection The selection object. * @param {FileSelection} selection The selection object.
* @private * @private
*/ */
FileSelectionHandler.prototype.updateFileSelectionAsync_ = function(selection) { updateFileSelectionAsync_(selection) {
if (this.selection !== selection) { if (this.selection !== selection) {
return; return;
} }
...@@ -279,13 +245,13 @@ FileSelectionHandler.prototype.updateFileSelectionAsync_ = function(selection) { ...@@ -279,13 +245,13 @@ FileSelectionHandler.prototype.updateFileSelectionAsync_ = function(selection) {
cr.dispatchSimpleEvent( cr.dispatchSimpleEvent(
this, FileSelectionHandler.EventType.CHANGE_THROTTLED); this, FileSelectionHandler.EventType.CHANGE_THROTTLED);
}); });
}; }
/** /**
* Returns true if all files in the selection files are selectable. * Returns true if all files in the selection files are selectable.
* @return {boolean} * @return {boolean}
*/ */
FileSelectionHandler.prototype.isAvailable = function() { isAvailable() {
if (!this.directoryModel_.isOnDrive()) { if (!this.directoryModel_.isOnDrive()) {
return true; return true;
} }
...@@ -293,28 +259,61 @@ FileSelectionHandler.prototype.isAvailable = function() { ...@@ -293,28 +259,61 @@ FileSelectionHandler.prototype.isAvailable = function() {
return !( return !(
this.isOfflineWithUncachedFilesSelected_() || this.isOfflineWithUncachedFilesSelected_() ||
this.isDialogWithHostedFilesSelected_()); this.isDialogWithHostedFilesSelected_());
}; }
/** /**
* Returns true if we're offline with any selected files absent from the cache. * Returns true if we're offline with any selected files absent from the
* cache.
* @return {boolean} * @return {boolean}
* @private * @private
*/ */
FileSelectionHandler.prototype.isOfflineWithUncachedFilesSelected_ = isOfflineWithUncachedFilesSelected_() {
function() {
return this.volumeManager_.getDriveConnectionState().type === return this.volumeManager_.getDriveConnectionState().type ===
VolumeManagerCommon.DriveConnectionType.OFFLINE && VolumeManagerCommon.DriveConnectionType.OFFLINE &&
this.selection.anyFilesNotInCache; this.selection.anyFilesNotInCache;
}; }
/** /**
* Returns true if we're a dialog requiring real files with hosted files * Returns true if we're a dialog requiring real files with hosted files
* selected. * selected.
* @return {boolean} * @return {boolean}
* @private * @private
*/ */
FileSelectionHandler.prototype.isDialogWithHostedFilesSelected_ = function() { isDialogWithHostedFilesSelected_() {
return this.allowedPaths_ !== AllowedPaths.ANY_PATH_OR_URL && return this.allowedPaths_ !== AllowedPaths.ANY_PATH_OR_URL &&
this.selection.anyFilesHosted; this.selection.anyFilesHosted;
}
}
/**
* @enum {string}
*/
FileSelectionHandler.EventType = {
/**
* Dispatched every time when selection is changed.
*/
CHANGE: 'change',
/**
* Dispatched |UPDATE_DELAY| ms after the selecton is changed.
* If multiple changes are happened during the term, only one CHANGE_THROTTLED
* event is dispatched.
*/
CHANGE_THROTTLED: 'changethrottled'
}; };
/**
* Delay in milliseconds before recalculating the selection in case the
* selection is changed fast, or there are many items. Used to avoid freezing
* the UI.
* @const {number}
*/
FileSelectionHandler.UPDATE_DELAY = 200;
/**
* Number of items in the selection which triggers the update delay. Used to
* let the Material Design animations complete before performing a heavy task
* which would cause the UI freezing.
* @const {number}
*/
FileSelectionHandler.NUMBER_OF_ITEMS_HEAVY_TO_COMPUTE = 100;
...@@ -108,21 +108,16 @@ function createTaskController(fileSelectionHandler) { ...@@ -108,21 +108,16 @@ function createTaskController(fileSelectionHandler) {
/** /**
* Mock FileSelectionHandler. * Mock FileSelectionHandler.
* @constructor
* @extends {FileSelectionHandler} * @extends {FileSelectionHandler}
*/ */
function MockFileSelectionHandler() { class FakeFileSelectionHandler {
this.computeAdditionalCallback = function() {}; constructor() {
this.selection = /** @type {!FileSelection} */ ({}); this.selection = /** @type {!FileSelection} */ ({});
this.updateSelection([], []); this.updateSelection([], []);
} this.eventTarget_ = new cr.EventTarget();
}
MockFileSelectionHandler.prototype = /** @struct */ { computeAdditionalCallback() {}
__proto__: cr.EventTarget.prototype, updateSelection(entries, mimeTypes) {
};
MockFileSelectionHandler.prototype.updateSelection = function(
entries, mimeTypes) {
this.selection = /** @type {!FileSelection} */ ({ this.selection = /** @type {!FileSelection} */ ({
entries: entries, entries: entries,
mimeTypes: mimeTypes, mimeTypes: mimeTypes,
...@@ -133,7 +128,12 @@ MockFileSelectionHandler.prototype.updateSelection = function( ...@@ -133,7 +128,12 @@ MockFileSelectionHandler.prototype.updateSelection = function(
}); });
}, },
}); });
}; }
addEventListener(...args) {
return this.eventTarget_.addEventListener(...args);
}
}
/** /**
* Setup test case fileManagerPrivate. * Setup test case fileManagerPrivate.
...@@ -165,7 +165,7 @@ function setupFileManagerPrivate() { ...@@ -165,7 +165,7 @@ function setupFileManagerPrivate() {
* Tests that executeEntryTask() runs the expected task. * Tests that executeEntryTask() runs the expected task.
*/ */
function testExecuteEntryTask(callback) { function testExecuteEntryTask(callback) {
var selectionHandler = new MockFileSelectionHandler(); var selectionHandler = new FakeFileSelectionHandler();
var fileSystem = new MockFileSystem('volumeId'); var fileSystem = new MockFileSystem('volumeId');
fileSystem.entries['/test.png'] = new MockFileEntry(fileSystem, '/test.png'); fileSystem.entries['/test.png'] = new MockFileEntry(fileSystem, '/test.png');
...@@ -188,7 +188,7 @@ function testExecuteEntryTask(callback) { ...@@ -188,7 +188,7 @@ function testExecuteEntryTask(callback) {
* multiple times when the selected entries are not changed. * multiple times when the selected entries are not changed.
*/ */
function testGetFileTasksShouldNotBeCalledMultipleTimes(callback) { function testGetFileTasksShouldNotBeCalledMultipleTimes(callback) {
var selectionHandler = new MockFileSelectionHandler(); var selectionHandler = new FakeFileSelectionHandler();
var fileSystem = new MockFileSystem('volumeId'); var fileSystem = new MockFileSystem('volumeId');
selectionHandler.updateSelection( selectionHandler.updateSelection(
...@@ -225,7 +225,7 @@ function testGetFileTasksShouldNotBeCalledMultipleTimes(callback) { ...@@ -225,7 +225,7 @@ function testGetFileTasksShouldNotBeCalledMultipleTimes(callback) {
* called. * called.
*/ */
function testGetFileTasksShouldNotReturnObsoletePromise(callback) { function testGetFileTasksShouldNotReturnObsoletePromise(callback) {
var selectionHandler = new MockFileSelectionHandler(); var selectionHandler = new FakeFileSelectionHandler();
var fileSystem = new MockFileSystem('volumeId'); var fileSystem = new MockFileSystem('volumeId');
selectionHandler.updateSelection( selectionHandler.updateSelection(
...@@ -256,7 +256,7 @@ function testGetFileTasksShouldNotReturnObsoletePromise(callback) { ...@@ -256,7 +256,7 @@ function testGetFileTasksShouldNotReturnObsoletePromise(callback) {
* the getFileTasks() promise to reject. * the getFileTasks() promise to reject.
*/ */
function testGetFileTasksShouldNotCacheRejectedPromise(callback) { function testGetFileTasksShouldNotCacheRejectedPromise(callback) {
var selectionHandler = new MockFileSelectionHandler(); var selectionHandler = new FakeFileSelectionHandler();
var fileSystem = new MockFileSystem('volumeId'); var fileSystem = new MockFileSystem('volumeId');
selectionHandler.updateSelection( selectionHandler.updateSelection(
......
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