Chromium Code Reviews| Index: chrome/browser/resources/file_manager/js/file_manager.js |
| diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js |
| index bc755bafa2ef3bb80fa6367d9bf6c1365b625851..2b6b76e1d98ca5a55ae9fead7de1daeb76367aeb 100644 |
| --- a/chrome/browser/resources/file_manager/js/file_manager.js |
| +++ b/chrome/browser/resources/file_manager/js/file_manager.js |
| @@ -11,6 +11,10 @@ var g_slideshow_data = null; |
| const IMAGE_EDITOR_ENABLED = false; |
| +// If directory files changes too often, don't rescan directory more than once |
| +// per specified interva; |
|
rginda
2011/08/31 00:32:58
typo: s/;/l./
Dmitry Zvorygin
2011/09/12 11:12:23
Done.
|
| +const SIMULTANEOUS_RESCAN_INTERVAL = 1000; |
| + |
| /** |
| * FileManager constructor. |
| * |
| @@ -52,6 +56,9 @@ function FileManager(dialogDom, filesystem, rootEntries, params) { |
| // True if we should filter out files that start with a dot. |
| this.filterFiles_ = true; |
| + this.subscribedOnDirectoryChanges_ = false; |
| + this.rescanPending_ = []; |
|
rginda
2011/08/31 00:32:58
rescanPending_ and rescanRunning_ are *very* simil
Dmitry Zvorygin
2011/09/12 11:12:23
We need both array and flag because we empty array
|
| + this.rescanRunning_ = false; |
| this.commands_ = {}; |
| @@ -108,6 +115,8 @@ function FileManager(dialogDom, filesystem, rootEntries, params) { |
| this.onCopyProgress_.bind(this)); |
| window.addEventListener('popstate', this.onPopState_.bind(this)); |
| + window.addEventListener('unload', this.onUnload_.bind(this)); |
| + |
| this.addEventListener('directory-changed', |
| this.onDirectoryChanged_.bind(this)); |
| this.addEventListener('selection-summarized', |
| @@ -119,6 +128,9 @@ function FileManager(dialogDom, filesystem, rootEntries, params) { |
| chrome.fileBrowserPrivate.onMountCompleted.addListener( |
| this.onMountCompleted_.bind(this)); |
| + chrome.fileBrowserPrivate.onFileChanged.addListener( |
| + this.onFileChanged_.bind(this)); |
| + |
| var self = this; |
| // The list of active mount points to distinct them from other directories. |
| @@ -2345,6 +2357,24 @@ FileManager.prototype = { |
| this.document_.title = this.currentDirEntry_.fullPath; |
| var self = this; |
| + |
| + if (this.subscribedOnDirectoryChanges_) { |
| + chrome.fileBrowserPrivate.removeFileWatch(event.previousDirEntry.toURL(), |
| + function(result) { |
| + if (!result) { |
| + console.log('Failed to remove file watch'); |
| + } |
| + }); |
| + } |
| + |
| + this.subscribedOnDirectoryChanges_ = true; |
| + chrome.fileBrowserPrivate.addFileWatch(event.newDirEntry.toURL(), |
| + function(result) { |
| + if (!result) { |
| + console.log('Failed to add file watch'); |
| + } |
| + }); |
| + |
| this.rescanDirectory_(function() { |
| if (event.selectedEntry) |
| self.selectEntry(event.selectedEntry); |
| @@ -2376,38 +2406,11 @@ FileManager.prototype = { |
| * |
|
rginda
2011/08/31 00:32:58
Please add some description of the new queuing nat
Dmitry Zvorygin
2011/09/12 11:12:23
Done.
|
| * @param {function()} opt_callback Optional function to invoke when the |
| * rescan is complete. |
| + * |
| + * @param {function()} opt_onError Optional function to invoke when the |
| + * rescan fails. |
| */ |
| - FileManager.prototype.rescanDirectory_ = function(opt_callback) { |
| - var self = this; |
| - var reader; |
| - |
| - function onReadSome(entries) { |
| - if (entries.length == 0) { |
| - if (opt_callback) |
| - opt_callback(); |
| - return; |
| - } |
| - |
| - // Splice takes the to-be-spliced-in array as individual parameters, |
| - // rather than as an array, so we need to perform some acrobatics... |
| - var spliceArgs = [].slice.call(entries); |
| - |
| - // Hide files that start with a dot ('.'). |
| - // TODO(rginda): User should be able to override this. Support for other |
| - // commonly hidden patterns might be nice too. |
| - if (self.filterFiles_) { |
| - spliceArgs = spliceArgs.filter(function(e) { |
| - return e.name.substr(0, 1) != '.'; |
| - }); |
| - } |
| - |
| - spliceArgs.unshift(0, 0); // index, deleteCount |
| - self.dataModel_.splice.apply(self.dataModel_, spliceArgs); |
| - |
| - // Keep reading until entries.length is 0. |
| - reader.readEntries(onReadSome); |
| - }; |
| - |
| + FileManager.prototype.rescanDirectory_ = function(opt_callback, opt_onError) { |
| // Updated when a user clicks on the label of a file, used to detect |
| // when a click is eligible to trigger a rename. Can be null, or |
| // an object with 'path' and 'date' properties. |
| @@ -2420,9 +2423,81 @@ FileManager.prototype = { |
| this.updateBreadcrumbs_(); |
| if (this.currentDirEntry_.fullPath != '/') { |
| + // Add current request to pending result list |
|
rginda
2011/08/31 00:32:58
rescanDirectory_ is getting pretty large, can this
Dmitry Zvorygin
2011/09/12 11:12:23
I think it's little useless because that function
|
| + this.rescanPending_.push({onSuccess:opt_callback, onError:opt_onError}); |
| + |
| + if (this.rescanRunning_) { |
|
rginda
2011/08/31 00:32:58
No braces necessary here.
Dmitry Zvorygin
2011/09/12 11:12:23
Done.
|
| + return; |
| + } |
| + |
| + this.rescanRunning_ = true; |
| + |
| + // Save list of items to notify locally in case we'll receive new requests |
|
rginda
2011/08/31 00:32:58
I don't think this comment is enough to describe w
Dmitry Zvorygin
2011/09/12 11:12:23
Done.
|
| + // to refresh while refreshing |
| + var callbacks = this.rescanPending_; |
| + |
| + this.rescanPending_ = []; |
| + |
| + var self = this; |
| + var reader; |
| + |
| + function onError() { |
| + |
| + for (var i= 0; i < callbacks.length; i++) { |
| + if (callbacks[i].onError) { |
|
rginda
2011/08/31 00:32:58
No braces.
Dmitry Zvorygin
2011/09/12 11:12:23
Done.
|
| + callbacks[i].onError(); |
|
rginda
2011/08/31 00:32:58
If any of these callbacks throw, rescanRunning wil
Dmitry Zvorygin
2011/09/12 11:12:23
Done.
|
| + } |
| + } |
| + |
| + if (self.rescanPending_.length > 0) { |
| + setTimeout(self.rescanDirectory_.bind(self), |
| + SIMULTANEOUS_RESCAN_INTERVAL); |
| + } |
| + |
| + self.rescanRunning_ = false; |
| + } |
| + |
| + function onReadSome(entries) { |
| + if (entries.length == 0) { |
| + |
| + for (var i= 0; i < callbacks.length; i++) { |
| + if (callbacks[i].onSuccess) { |
| + callbacks[i].onSuccess(); |
|
rginda
2011/08/31 00:32:58
Same issue with failed callbacks here. Also, unne
Dmitry Zvorygin
2011/09/12 11:12:23
Done.
|
| + } |
| + } |
| + |
| + if (self.rescanPending_.length > 0) { |
| + setTimeout(self.rescanDirectory_.bind(self), |
| + SIMULTANEOUS_RESCAN_INTERVAL); |
| + } |
| + |
| + self.rescanRunning_ = false; |
| + return; |
| + } |
| + |
| + // Splice takes the to-be-spliced-in array as individual parameters, |
| + // rather than as an array, so we need to perform some acrobatics... |
| + var spliceArgs = [].slice.call(entries); |
| + |
| + // Hide files that start with a dot ('.'). |
| + // TODO(rginda): User should be able to override this. Support for other |
| + // commonly hidden patterns might be nice too. |
| + if (self.filterFiles_) { |
| + spliceArgs = spliceArgs.filter(function(e) { |
| + return e.name.substr(0, 1) != '.'; |
| + }); |
| + } |
| + |
| + spliceArgs.unshift(0, 0); // index, deleteCount |
| + self.dataModel_.splice.apply(self.dataModel_, spliceArgs); |
| + |
| + // Keep reading until entries.length is 0. |
| + reader.readEntries(onReadSome, onError); |
| + }; |
| + |
| // If not the root directory, just read the contents. |
| reader = this.currentDirEntry_.createReader(); |
| - reader.readEntries(onReadSome); |
| + reader.readEntries(onReadSome, onError); |
| return; |
| } |
| @@ -2483,6 +2558,33 @@ FileManager.prototype = { |
| } |
| }; |
| + FileManager.prototype.onUnload_ = function(event) { |
| + if (this.subscribedOnDirectoryChanges_) { |
| + chrome.fileBrowserPrivate.removeFileWatch(event.previousDirEntry.toURL(), |
| + function(result) { |
| + if (!result) { |
| + console.log('Failed to remove file watch'); |
| + } |
| + }); |
| + } |
| + }; |
| + |
| + FileManager.prototype.onFileChanged_ = function(event) { |
| + // It might be massive change, so let's note somehow, that we need |
|
rginda
2011/08/31 00:32:58
How about just moving this code into a 'rescanDire
|
| + // rescanning and then wait some time |
| + |
| + if (this.rescanPending_.length == 0) { |
| + this.rescanPending_.push({onSuccess:undefined, onError:undefined}); |
| + |
| + // If rescan isn't going to run without |
| + // our interruption, then say that we need to run it |
| + if (!this.rescanRunning_) { |
| + setTimeout(this.rescanDirectory_.bind(this), |
| + SIMULTANEOUS_RESCAN_INTERVAL); |
| + } |
| + } |
| + }; |
| + |
| /** |
| * Determine whether or not a click should initiate a rename. |
| * |