Index: ui/file_manager/file_manager/foreground/js/file_selection.js |
diff --git a/ui/file_manager/file_manager/foreground/js/file_selection.js b/ui/file_manager/file_manager/foreground/js/file_selection.js |
index f1655ef4230cd4607ad552301eb3d15ec36e2fd3..e582294f7c523fbdc4506992ef9437a8f4313b82 100644 |
--- a/ui/file_manager/file_manager/foreground/js/file_selection.js |
+++ b/ui/file_manager/file_manager/foreground/js/file_selection.js |
@@ -5,26 +5,99 @@ |
/** |
* The current selection object. |
* |
- * @param {FileManager} fileManager FileManager instance. |
- * @param {Array.<number>} indexes Selected indexes. |
+ * @param {!FileManager} fileManager FileManager instance. |
+ * @param {!Array.<number>} indexes Selected indexes. |
* @constructor |
+ * @struct |
*/ |
function FileSelection(fileManager, indexes) { |
+ /** |
+ * @type {!FileManager} |
+ * @private |
+ * @const |
+ */ |
this.fileManager_ = fileManager; |
+ |
+ /** |
+ * @type {number} |
+ * @private |
+ */ |
this.computeBytesSequence_ = 0; |
+ |
+ /** |
+ * @type {!Array.<number>} |
+ * @const |
+ */ |
this.indexes = indexes; |
+ |
+ /** |
+ * @type {!Array.<!Entry>} |
+ * @const |
+ */ |
this.entries = []; |
+ |
+ /** |
+ * @type {number} |
+ */ |
this.totalCount = 0; |
+ |
+ /** |
+ * @type {number} |
+ */ |
this.fileCount = 0; |
+ |
+ /** |
+ * @type {number} |
+ */ |
this.directoryCount = 0; |
+ |
+ /** |
+ * @type {number} |
+ */ |
this.bytes = 0; |
+ |
+ /** |
+ * @type {boolean} |
+ */ |
this.showBytes = false; |
- this.allDriveFilesPresent = false, |
+ |
+ /** |
+ * @type {boolean} |
+ */ |
+ this.allDriveFilesPresent = false; |
+ |
+ /** |
+ * @type {?string} |
+ */ |
this.iconType = null; |
+ |
+ /** |
+ * @type {boolean} |
+ */ |
this.bytesKnown = false; |
+ |
+ /** |
+ * @type {boolean} |
+ * @private |
+ */ |
this.mustBeHidden_ = false; |
+ |
+ /** |
+ * @type {Array.<string>} |
+ */ |
this.mimeTypes = null; |
+ /** |
+ * @type {!FileTasks} |
+ */ |
+ this.tasks = new FileTasks(this.fileManager_); |
+ |
+ /** |
+ * @type {Promise} |
+ * @private |
+ */ |
+ this.asyncInitPromise_ = null; |
+ |
// Synchronously compute what we can. |
for (var i = 0; i < this.indexes.length; i++) { |
var entry = /** @type {!Entry} */ |
@@ -49,39 +122,36 @@ function FileSelection(fileManager, indexes) { |
} |
this.totalCount++; |
} |
- |
- this.tasks = new FileTasks(this.fileManager_); |
- |
- Object.seal(this); |
} |
/** |
* Computes data required to get file tasks and requests the tasks. |
- * |
- * @param {function()} callback The callback. |
+ * @return {!Promise} |
*/ |
-FileSelection.prototype.createTasks = function(callback) { |
- if (!this.fileManager_.isOnDrive()) { |
- this.tasks.init(this.entries); |
- callback(); |
- return; |
- } |
- |
- this.fileManager_.metadataCache_.get( |
- this.entries, 'external', function(props) { |
+FileSelection.prototype.completeInit = function() { |
+ if (!this.asyncInitPromise_) { |
+ if (!this.fileManager_.isOnDrive()) { |
+ this.asyncInitPromise_ = Promise.resolve(); |
+ this.tasks.init(this.entries); |
+ this.allDriveFilesPresent = true; |
+ } else { |
+ this.asyncInitPromise_ = new Promise(function(fulfill) { |
+ this.fileManager_.metadataCache.get(this.entries, 'external', fulfill); |
+ }.bind(this)).then(function(props) { |
var present = props.filter(function(p) { |
return p && p.availableOffline; |
}); |
this.allDriveFilesPresent = present.length == props.length; |
- |
- // Collect all of the mime types and push that info into the selection. |
+ // Collect all of the mime types and push that info into the |
+ // selection. |
this.mimeTypes = props.map(function(value) { |
return (value && value.contentMimeType) || ''; |
}); |
- |
this.tasks.init(this.entries, this.mimeTypes); |
- callback(); |
}.bind(this)); |
+ } |
+ } |
+ return this.asyncInitPromise_; |
}; |
/** |
@@ -150,7 +220,7 @@ FileSelection.prototype.cancelComputing_ = function() { |
/** |
* This object encapsulates everything related to current selection. |
* |
- * @param {FileManager} fileManager File manager instance. |
+ * @param {!FileManager} fileManager File manager instance. |
* @extends {cr.EventTarget} |
* @constructor |
* @struct |
@@ -179,6 +249,23 @@ function FileSelectionHandler(fileManager) { |
} |
/** |
+ * @enum {string} |
+ */ |
+FileSelectionHandler.EventType = { |
+ /** |
+ * Dispatched every time when selection is changed. |
+ */ |
+ CHANGE: 'change', |
+ |
+ /** |
+ * Dispatched 200ms later after the selecton is changed. |
+ * If multiple changes are happened during the term, only one CHANGE_THROTTLED |
+ * event is dispatched. |
+ */ |
+ CHANGE_THROTTLED: 'changethrottled' |
+}; |
+ |
+/** |
* Create the temporary disabled action item. |
* @return {Object} Created disabled item. |
* @private |
@@ -267,25 +354,27 @@ FileSelectionHandler.prototype.onFileSelectionChanged = function() { |
this.selectionUpdateTimer_ = setTimeout(function() { |
this.selectionUpdateTimer_ = null; |
if (this.selection == selection) |
- this.updateFileSelectionAsync(selection); |
+ this.updateFileSelectionAsync_(selection); |
}.bind(this), updateDelay); |
- cr.dispatchSimpleEvent(this, 'change'); |
+ cr.dispatchSimpleEvent(this, FileSelectionHandler.EventType.CHANGE); |
}; |
/** |
* Calculates async selection stats and updates secondary UI elements. |
* |
* @param {FileSelection} selection The selection object. |
+ * @private |
*/ |
-FileSelectionHandler.prototype.updateFileSelectionAsync = function(selection) { |
- if (this.selection != selection) return; |
+FileSelectionHandler.prototype.updateFileSelectionAsync_ = function(selection) { |
+ if (this.selection !== selection) |
+ return; |
// Update the file tasks. |
if (this.fileManager_.dialogType === DialogType.FULL_PAGE && |
selection.directoryCount === 0 && selection.fileCount > 0) { |
- selection.createTasks(function() { |
- if (this.selection != selection) |
+ selection.completeInit().then(function() { |
+ if (this.selection !== selection) |
return; |
selection.tasks.display(this.taskMenuButton_); |
selection.tasks.updateMenuItem(); |
@@ -308,7 +397,17 @@ FileSelectionHandler.prototype.updateFileSelectionAsync = function(selection) { |
if (this.fileManager_.commandHandler) |
this.fileManager_.commandHandler.updateAvailability(); |
- // Inform tests it's OK to click buttons now. |
- if (selection.totalCount > 0) |
- util.testSendMessage('selection-change-complete'); |
+ cr.dispatchSimpleEvent(this, FileSelectionHandler.EventType.CHANGE_THROTTLED); |
+}; |
+ |
+/** |
+ * Returns whether all the selected files are available currently or not. |
+ * Should be called after the selection initialized. |
+ * @return {boolean} |
+ */ |
+FileSelectionHandler.prototype.isAvailable = function() { |
+ return !this.fileManager_.isOnDrive() || |
+ this.fileManager_.volumeManager.getDriveConnectionState().type !== |
+ VolumeManagerCommon.DriveConnectionType.OFFLINE || |
+ this.selection.allDriveFilesPresent; |
}; |