Index: ui/file_manager/file_manager/foreground/js/directory_model.js |
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js |
index 810a12706b2273bb31ef6388f71004d72f55ed50..0333336460dac8f8427464160ba106ba52f6a012 100644 |
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js |
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js |
@@ -32,6 +32,8 @@ function DirectoryModel(singleSelection, fileFilter, fileWatcher, |
this.scanFailures_ = 0; |
this.changeDirectorySequence_ = 0; |
+ this.directoryChangeQueue_ = new AsyncUtil.Queue(); |
+ |
this.fileFilter_ = fileFilter; |
this.fileFilter_.addEventListener('changed', |
this.onFilterChanged_.bind(this)); |
@@ -278,8 +280,15 @@ DirectoryModel.prototype.scheduleRescan = function(delay) { |
clearTimeout(this.rescanTimeoutId_); |
} |
+ var sequence = this.changeDirectorySequence_; |
+ |
this.rescanTime_ = Date.now() + delay; |
- this.rescanTimeoutId_ = setTimeout(this.rescan.bind(this), delay); |
+ this.rescanTimeoutId_ = setTimeout(function() { |
+ this.rescanTimeoutId_ = null; |
+ tracker.stop(); |
hirono
2014/06/02 11:52:07
Remaining line.
yoshiki
2014/06/04 13:46:41
Done.
|
+ if (sequence !== this.changeDirectorySequence_) |
+ this.rescan(); |
+ }.bind(this), delay); |
}; |
/** |
@@ -312,8 +321,11 @@ DirectoryModel.prototype.rescan = function() { |
var dirContents = this.currentDirContents_.clone(); |
dirContents.setFileList([]); |
+ var sequence = this.changeDirectorySequence_; |
+ |
var successCallback = (function() { |
- this.replaceDirectoryContents_(dirContents); |
+ if (sequence !== this.changeDirectorySequence_) |
+ this.replaceDirectoryContents_(dirContents); |
cr.dispatchSimpleEvent(this, 'rescan-completed'); |
}).bind(this); |
@@ -329,11 +341,12 @@ DirectoryModel.prototype.rescan = function() { |
* |
* @param {DirectoryContentes} newDirContents New DirectoryContents instance to |
* replace currentDirContents_. |
- * @param {function()=} opt_callback Called on success. |
+ * @param {function(boolean)} callback Callback with result. True if the scan |
+ * is completed successfully, false if the scan is failed. |
* @private |
*/ |
DirectoryModel.prototype.clearAndScan_ = function(newDirContents, |
- opt_callback) { |
+ callback) { |
if (this.currentDirContents_.isScanning()) |
this.currentDirContents_.cancelScan(); |
this.currentDirContents_ = newDirContents; |
@@ -348,22 +361,46 @@ DirectoryModel.prototype.clearAndScan_ = function(newDirContents, |
this.runningScan_ = null; |
} |
+ var sequence = this.changeDirectorySequence_; |
+ var cancelled = false; |
+ |
var onDone = function() { |
+ if (cancelled) |
+ return; |
+ |
cr.dispatchSimpleEvent(this, 'scan-completed'); |
- if (opt_callback) |
- opt_callback(); |
+ callback(true); |
}.bind(this); |
var onFailed = function() { |
+ if (cancelled) |
+ return; |
+ |
cr.dispatchSimpleEvent(this, 'scan-failed'); |
+ callback(false); |
}.bind(this); |
var onUpdated = function() { |
+ if (cancelled) |
+ return; |
+ |
+ if (this.changeDirectorySequence_ !== sequence) { |
+ cancelled = true; |
+ cr.dispatchSimpleEvent(this, 'scan-cancelled'); |
+ callback(false); |
+ return; |
+ } |
+ |
cr.dispatchSimpleEvent(this, 'scan-updated'); |
}.bind(this); |
var onCancelled = function() { |
+ if (cancelled) |
+ return; |
+ |
+ cancelled = true; |
cr.dispatchSimpleEvent(this, 'scan-cancelled'); |
+ callback(false); |
}.bind(this); |
// Clear the table, and start scanning. |
@@ -602,8 +639,7 @@ DirectoryModel.prototype.createDirectory = function(name, |
return; |
} |
- var tracker = this.createDirectoryChangeTracker(); |
- tracker.start(); |
+ var sequence = this.changeDirectorySequence_; |
new Promise(entry.getDirectory.bind( |
entry, name, {create: true, exclusive: true})). |
@@ -621,8 +657,7 @@ DirectoryModel.prototype.createDirectory = function(name, |
then(function(newEntry) { |
// Do not change anything or call the callback if current |
// directory changed. |
- tracker.stop(); |
- if (tracker.hasChanged) { |
+ if (this.changeDirectorySequence_ !== sequence) { |
abortCallback(); |
return; |
} |
@@ -668,26 +703,38 @@ DirectoryModel.prototype.changeDirectoryEntry = function( |
this.changeDirectorySequence_++; |
this.clearSearch_(); |
- var promise = new Promise( |
- function(onFulfilled, onRejected) { |
- this.fileWatcher_.changeWatchedDirectory(dirEntry, onFulfilled); |
- }.bind(this)). |
- |
- then(function(sequence) { |
- return new Promise(function(onFulfilled, onRejected) { |
- if (this.changeDirectorySequence_ !== sequence) |
+ this.directoryChangeQueue_.run(function(sequence, queueTaskCallback) { |
+ this.fileWatcher_.changeWatchedDirectory( |
+ dirEntry, |
+ function() { |
+ if (this.changeDirectorySequence_ !== sequence) { |
+ callback(); |
return; |
+ } |
var newDirectoryContents = this.createDirectoryContents_( |
this.currentFileListContext_, dirEntry, ''); |
- if (!newDirectoryContents) |
+ if (!newDirectoryContents) { |
+ callback(); |
return; |
+ } |
- var previousDirEntry = this.currentDirContents_.getDirectoryEntry(); |
- this.clearAndScan_(newDirectoryContents, opt_callback); |
- |
- // For tests that open the dialog to empty directories, everything is |
- // loaded at this point. |
+ var previousDirEntry = |
+ this.currentDirContents_.getDirectoryEntry(); |
+ this.clearAndScan_( |
+ newDirectoryContents, |
+ function(result) { |
+ // Calls the callback of the method when successful. |
+ if (result && opt_callback) |
+ opt_callback(); |
+ |
+ // Notify that the current task of this.directoryChangeQueue_ |
+ // is completed. |
+ setTimeout(queueTaskCallback); |
+ }); |
+ |
+ // For tests that open the dialog to empty directories, everything |
+ // is loaded at this point. |
util.testSendMessage('directory-change-complete'); |
var event = new Event('directory-changed'); |
@@ -695,7 +742,7 @@ DirectoryModel.prototype.changeDirectoryEntry = function( |
event.newDirEntry = dirEntry; |
this.dispatchEvent(event); |
}.bind(this)); |
- }.bind(this, this.changeDirectorySequence_)); |
+ }.bind(this, this.changeDirectorySequence_)); |
}; |
/** |
@@ -903,25 +950,41 @@ DirectoryModel.prototype.search = function(query, |
return; |
} |
- if (!(query || '').trimLeft()) { |
- if (this.isSearching()) { |
- var newDirContents = this.createDirectoryContents_( |
- this.currentFileListContext_, |
- currentDirEntry); |
- this.clearAndScan_(newDirContents); |
+ this.changeDirectorySequence_++; |
+ this.directoryChangeQueue_.run(function(sequence, callback) { |
+ if (this.changeDirectorySequence_ !== sequence) { |
+ callback(); |
+ return; |
+ } |
+ |
+ if (!(query || '').trimLeft()) { |
+ if (this.isSearching()) { |
+ var newDirContents = this.createDirectoryContents_( |
+ this.currentFileListContext_, |
+ currentDirEntry); |
+ this.clearAndScan_(newDirContents, |
+ sequence, |
+ callback); |
+ } else { |
+ callback(); |
+ } |
+ return; |
} |
- return; |
- } |
- var newDirContents = this.createDirectoryContents_( |
- this.currentFileListContext_, currentDirEntry, query); |
- if (!newDirContents) |
- return; |
+ var newDirContents = this.createDirectoryContents_( |
+ this.currentFileListContext_, currentDirEntry, query); |
+ if (!newDirContents) { |
+ callback(); |
+ return; |
+ } |
- this.onSearchCompleted_ = onSearchRescan; |
- this.onClearSearch_ = onClearSearch; |
- this.addEventListener('scan-completed', this.onSearchCompleted_); |
- this.clearAndScan_(newDirContents); |
+ this.onSearchCompleted_ = onSearchRescan; |
+ this.onClearSearch_ = onClearSearch; |
+ this.addEventListener('scan-completed', this.onSearchCompleted_); |
+ this.clearAndScan_(newDirContents, |
+ sequence, |
+ callback); |
+ }.bind(this, this.changeDirectorySequence_)); |
}; |
/** |