| Index: ui/file_manager/file_manager/foreground/js/import_controller.js
|
| diff --git a/ui/file_manager/file_manager/foreground/js/import_controller.js b/ui/file_manager/file_manager/foreground/js/import_controller.js
|
| index 058e2dd4e14c5a244ff58fd9b81aeb9a708e4e5e..93f18dfb58695ae2ddcd1642f5cb28186e72d75d 100644
|
| --- a/ui/file_manager/file_manager/foreground/js/import_controller.js
|
| +++ b/ui/file_manager/file_manager/foreground/js/import_controller.js
|
| @@ -80,6 +80,9 @@ importer.ImportController =
|
| this.scanner_.removeObserver(listener);
|
| }.bind(this));
|
|
|
| + this.environment_.addWindowCloseListener(
|
| + this.onWindowClosing_.bind(this));
|
| +
|
| this.environment_.addVolumeUnmountListener(
|
| this.onVolumeUnmounted_.bind(this));
|
|
|
| @@ -128,7 +131,7 @@ importer.ImportController.prototype.onScanEvent_ = function(event, scan) {
|
|
|
| switch (event) {
|
| case importer.ScanEvent.INVALIDATED:
|
| - this.scanManager_.reset();
|
| + this.onScanInvalidated_();
|
| case importer.ScanEvent.FINALIZED:
|
| case importer.ScanEvent.UPDATED:
|
| this.checkState_(scan);
|
| @@ -136,6 +139,11 @@ importer.ImportController.prototype.onScanEvent_ = function(event, scan) {
|
| }
|
| };
|
|
|
| +/** @private */
|
| +importer.ImportController.prototype.onWindowClosing_ = function() {
|
| + this.scanManager_.reset(); // Will cancel any active scans.
|
| +};
|
| +
|
| /**
|
| * @param {string} volumeId
|
| * @private
|
| @@ -160,10 +168,11 @@ importer.ImportController.prototype.onDirectoryChanged_ = function(event) {
|
| importer.isMediaDirectory(event.newDirEntry, this.environment_)) {
|
| this.commandWidget_.setDetailsVisible(true);
|
| }
|
| - this.scanManager_.clearSelectionScan();
|
| +
|
| + this.scanManager_.reset();
|
| if (this.isCurrentDirectoryScannable_()) {
|
| this.checkState_(
|
| - this.scanManager_.getCurrentDirectoryScan());
|
| + this.scanManager_.getDirectoryScan());
|
| } else {
|
| this.checkState_();
|
| }
|
| @@ -171,6 +180,15 @@ importer.ImportController.prototype.onDirectoryChanged_ = function(event) {
|
|
|
| /** @private */
|
| importer.ImportController.prototype.onSelectionChanged_ = function() {
|
| + // NOTE: Empty selection changed events can and will fire for a directory
|
| + // before we receive the the corresponding directory changed event
|
| + // and when the selection is empty. These are spurios events
|
| + // and we ignore them.
|
| + if (!this.scanManager_.hasSelectionScan() &&
|
| + this.environment_.getSelection().length === 0) {
|
| + return;
|
| + }
|
| +
|
| // NOTE: We clear the scan here, but don't immediately initiate
|
| // a new scan. checkState will attempt to initialize the scan
|
| // during normal processing.
|
| @@ -181,7 +199,7 @@ importer.ImportController.prototype.onSelectionChanged_ = function() {
|
| if (this.environment_.getSelection().length === 0 &&
|
| this.isCurrentDirectoryScannable_()) {
|
| this.checkState_(
|
| - this.scanManager_.getCurrentDirectoryScan());
|
| + this.scanManager_.getDirectoryScan());
|
| } else {
|
| this.checkState_();
|
| }
|
| @@ -199,6 +217,18 @@ importer.ImportController.prototype.onImportFinished_ = function(task) {
|
| this.checkState_();
|
| };
|
|
|
| +/** @private */
|
| +importer.ImportController.prototype.onScanInvalidated_ = function() {
|
| + this.scanManager_.reset();
|
| + if (this.environment_.getSelection().length === 0 &&
|
| + this.isCurrentDirectoryScannable_()) {
|
| + this.checkState_(
|
| + this.scanManager_.getDirectoryScan());
|
| + } else {
|
| + this.checkState_();
|
| + }
|
| +};
|
| +
|
| /**
|
| * Does book keeping necessary to finalize the active task.
|
| * @private
|
| @@ -282,9 +312,11 @@ importer.ImportController.prototype.execute_ = function() {
|
| * @private
|
| */
|
| importer.ImportController.prototype.cancel_ = function() {
|
| - this.activeImport_.task.requestCancel();
|
| - this.finalizeActiveImport_();
|
| - this.tracker_.send(metrics.ImportEvents.IMPORT_CANCELLED);
|
| + if (this.activeImport_) {
|
| + this.activeImport_.task.requestCancel();
|
| + this.finalizeActiveImport_();
|
| + this.tracker_.send(metrics.ImportEvents.IMPORT_CANCELLED);
|
| + }
|
|
|
| this.scanManager_.reset();
|
| this.checkState_();
|
| @@ -411,14 +443,13 @@ importer.ImportController.prototype.fitsInAvailableSpace_ =
|
| */
|
| importer.ImportController.prototype.tryScan_ = function() {
|
| var entries = this.environment_.getSelection();
|
| -
|
| if (entries.length) {
|
| if (entries.every(
|
| importer.isEligibleEntry.bind(null, this.environment_))) {
|
| return this.scanManager_.getSelectionScan(entries);
|
| }
|
| } else if (this.isCurrentDirectoryScannable_()) {
|
| - return this.scanManager_.getCurrentDirectoryScan();
|
| + return this.scanManager_.getDirectoryScan();
|
| }
|
|
|
| return null;
|
| @@ -802,40 +833,53 @@ importer.ScanManager = function(environment, scanner) {
|
| this.scanner_ = scanner;
|
|
|
| /**
|
| - * A cache of selection scans by directory (url).
|
| + * The active files scan, if any.
|
| *
|
| * @private {importer.ScanResult}
|
| */
|
| this.selectionScan_ = null;
|
|
|
| /**
|
| - * A cache of scans by directory (url).
|
| + * The active directory scan, if any.
|
| *
|
| - * @private {!Object.<string, !importer.ScanResult>}
|
| + * @private {importer.ScanResult}
|
| */
|
| - this.directoryScans_ = {};
|
| + this.directoryScan_ = null;
|
| };
|
|
|
| /**
|
| - * Forgets all scans.
|
| + * Cancels and forgets all scans.
|
| */
|
| importer.ScanManager.prototype.reset = function() {
|
| this.clearSelectionScan();
|
| - this.clearDirectoryScans();
|
| + this.clearDirectoryScan();
|
| };
|
|
|
| /**
|
| - * Forgets the selection scans for the current directory.
|
| + * @return {boolean} True if we have an existing selection scan.
|
| + */
|
| +importer.ScanManager.prototype.hasSelectionScan = function() {
|
| + return !!this.selectionScan_;
|
| +};
|
| +
|
| +/**
|
| + * Cancels and forgets the current selection scan, if any.
|
| */
|
| importer.ScanManager.prototype.clearSelectionScan = function() {
|
| + if (this.selectionScan_) {
|
| + this.selectionScan_.cancel();
|
| + }
|
| this.selectionScan_ = null;
|
| };
|
|
|
| /**
|
| - * Forgets directory scans.
|
| + * Cancels and forgets the current directory scan, if any.
|
| */
|
| -importer.ScanManager.prototype.clearDirectoryScans = function() {
|
| - this.directoryScans_ = {};
|
| +importer.ScanManager.prototype.clearDirectoryScan = function() {
|
| + if (this.directoryScan_) {
|
| + this.directoryScan_.cancel();
|
| + }
|
| + this.directoryScan_ = null;
|
| };
|
|
|
| /**
|
| @@ -843,14 +887,7 @@ importer.ScanManager.prototype.clearDirectoryScans = function() {
|
| * if none.
|
| */
|
| importer.ScanManager.prototype.getActiveScan = function() {
|
| - if (!!this.selectionScan_) {
|
| - return this.selectionScan_;
|
| - }
|
| - var directory = this.environment_.getCurrentDirectory();
|
| - if (directory) {
|
| - return this.directoryScans_[directory.toURL()];
|
| - }
|
| - return null;
|
| + return this.selectionScan_ || this.directoryScan_;
|
| };
|
|
|
| /**
|
| @@ -859,13 +896,7 @@ importer.ScanManager.prototype.getActiveScan = function() {
|
| * selection scan or the scan for the current directory.
|
| */
|
| importer.ScanManager.prototype.isActiveScan = function(scan) {
|
| - if (scan === this.selectionScan_) {
|
| - return true;
|
| - }
|
| -
|
| - var directory = this.environment_.getCurrentDirectory();
|
| - return !!directory &&
|
| - scan === this.directoryScans_[directory.toURL()];
|
| + return scan === this.selectionScan_ || scan === this.directoryScan_;
|
| };
|
|
|
| /**
|
| @@ -888,21 +919,15 @@ importer.ScanManager.prototype.getSelectionScan = function(entries) {
|
| *
|
| * @return {importer.ScanResult}
|
| */
|
| -importer.ScanManager.prototype.getCurrentDirectoryScan = function() {
|
| - var directory = this.environment_.getCurrentDirectory();
|
| - if (!directory) {
|
| - return null;
|
| - }
|
| -
|
| - var url = directory.toURL();
|
| - var scan = this.directoryScans_[url];
|
| - if (!scan) {
|
| - scan = this.scanner_.scanDirectory(
|
| - /** @type {!DirectoryEntry} */ (directory));
|
| - this.directoryScans_[url] = scan;
|
| +importer.ScanManager.prototype.getDirectoryScan = function() {
|
| + if (!this.directoryScan_) {
|
| + var directory = this.environment_.getCurrentDirectory();
|
| + if (directory) {
|
| + this.directoryScan_ = this.scanner_.scanDirectory(
|
| + /** @type {!DirectoryEntry} */ (directory));
|
| + }
|
| }
|
| -
|
| - return scan;
|
| + return this.directoryScan_;
|
| };
|
|
|
| /**
|
| @@ -945,6 +970,14 @@ importer.ControllerEnvironment.prototype.isGoogleDriveMounted;
|
| importer.ControllerEnvironment.prototype.getFreeStorageSpace;
|
|
|
| /**
|
| + * Installs a 'window closed' listener. Listener is called just
|
| + * just before the window is closed. Any business must be
|
| + * done synchronously.
|
| + * @param {function()} listener
|
| + */
|
| +importer.ControllerEnvironment.prototype.addWindowCloseListener;
|
| +
|
| +/**
|
| * Installs an 'unmount' listener. Listener is called with
|
| * the corresponding volume id when a volume is unmounted.
|
| * @param {function(string)} listener
|
| @@ -1049,22 +1082,6 @@ importer.RuntimeControllerEnvironment.prototype.isGoogleDriveMounted =
|
| };
|
|
|
| /** @override */
|
| -importer.RuntimeControllerEnvironment.prototype.addVolumeUnmountListener =
|
| - function(listener) {
|
| - // TODO(smckay): remove listeners when the page is torn down.
|
| - chrome.fileManagerPrivate.onMountCompleted.addListener(
|
| - /**
|
| - * @param {!MountCompletedEvent} event
|
| - * @this {importer.RuntimeControllerEnvironment}
|
| - */
|
| - function(event) {
|
| - if (event.eventType === 'unmount') {
|
| - listener(event.volumeMetadata.volumeId);
|
| - }
|
| - });
|
| -};
|
| -
|
| -/** @override */
|
| importer.RuntimeControllerEnvironment.prototype.getFreeStorageSpace =
|
| function() {
|
| // Checking DOWNLOADS returns the amount of available local storage space.
|
| @@ -1089,6 +1106,28 @@ importer.RuntimeControllerEnvironment.prototype.getFreeStorageSpace =
|
| };
|
|
|
| /** @override */
|
| +importer.RuntimeControllerEnvironment.prototype.addWindowCloseListener =
|
| + function(listener) {
|
| + window.addEventListener('pagehide', listener);
|
| +};
|
| +
|
| +/** @override */
|
| +importer.RuntimeControllerEnvironment.prototype.addVolumeUnmountListener =
|
| + function(listener) {
|
| + // TODO(smckay): remove listeners when the page is torn down.
|
| + chrome.fileManagerPrivate.onMountCompleted.addListener(
|
| + /**
|
| + * @param {!MountCompletedEvent} event
|
| + * @this {importer.RuntimeControllerEnvironment}
|
| + */
|
| + function(event) {
|
| + if (event.eventType === 'unmount') {
|
| + listener(event.volumeMetadata.volumeId);
|
| + }
|
| + });
|
| +};
|
| +
|
| +/** @override */
|
| importer.RuntimeControllerEnvironment.prototype.addDirectoryChangedListener =
|
| function(listener) {
|
| // TODO(smckay): remove listeners when the page is torn down.
|
|
|