Chromium Code Reviews| 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_)); |
| }; |
| /** |