Chromium Code Reviews| Index: ui/file_manager/file_manager/background/js/import_history.js |
| diff --git a/ui/file_manager/file_manager/background/js/import_history.js b/ui/file_manager/file_manager/background/js/import_history.js |
| index 76bacb2847dcdb29f993b44348f2e4d66f5d730f..2a076cf8929feaeecf826f187808939809b59424 100644 |
| --- a/ui/file_manager/file_manager/background/js/import_history.js |
| +++ b/ui/file_manager/file_manager/background/js/import_history.js |
| @@ -212,115 +212,33 @@ importer.PersistentImportHistory = function(hashGenerator, storage) { |
| /** @private {!Array.<!importer.ImportHistory.Observer>} */ |
| this.observers_ = []; |
| + /** @private {!importer.Resolver.<!importer.PersistentImportHistory>} */ |
| + this.readyResolver_ = new importer.Resolver(); |
| + |
| /** @private {!Promise.<!importer.PersistentImportHistory>} */ |
| - this.whenReady_ = this.refresh_(); |
| + this.whenReady_ = this.readyResolver_.promise; |
| }; |
| /** |
| - * Loads history from storage and merges in any previously existing entries |
| - * that are not present in the newly loaded data. Should be called |
| - * when the storage is externally changed. |
| + * Reloads history from disk. Should be called when the file |
| + * is changed by an external source. |
| * |
| - * @return {!Promise.<!importer.PersistentImportHistory>} Resolves when history |
| - * has been refreshed. |
| - * @private |
| + * @return {!Promise.<!importer.PersistentImportHistory>} Resolves when |
| + * history has been refreshed. |
| */ |
| -importer.PersistentImportHistory.prototype.refresh_ = function() { |
| - var oldCopiedEntries = this.copiedEntries_; |
| - // NOTE: importDetailsIndex is built in relation to the copiedEntries_ |
| - // data, so we don't need to preserve the information in that field. |
| - var oldImportedEntries = this.importedEntries_; |
| - |
| - this.copiedEntries_ = {}; |
| - this.importedEntries_ = {}; |
| - |
| - return this.storage_.readAll() |
| +importer.PersistentImportHistory.prototype.load = function() { |
| + this.storage_.readAll() |
| .then(this.updateHistoryRecords_.bind(this)) |
| - .then(this.mergeCopiedEntries_.bind(this, oldCopiedEntries)) |
| - .then(this.mergeImportedEntries_.bind(this, oldImportedEntries)) |
| .then( |
| /** |
| * @return {!importer.PersistentImportHistory} |
| * @this {importer.PersistentImportHistory} |
| */ |
| function() { |
| - return this; |
| + this.readyResolver_.resolve(this); |
| }.bind(this)) |
| - .catch(importer.getLogger().catcher('import-history-refresh')); |
| -}; |
| - |
| -/** |
| - * Adds all copied entries into existing entries. |
| - * |
| - * @param {!Object.<string, !Object.<!importer.Destination, importer.Urls>>} |
| - * entries |
| - * @return {!Promise.<?>} Resolves once all updates are completed. |
| - * @private |
| - */ |
| -importer.PersistentImportHistory.prototype.mergeCopiedEntries_ = |
| - function(entries) { |
| - var promises = []; |
| - for (var key in entries) { |
| - for (var destination in entries[key]) { |
| - // This method is only called when data is reloaded from disk. |
| - // In such a situation we defend against loss of in-memory data |
| - // by copying it out of the way, reloading data from disk, then |
| - // merging that data back into the freshly loaded data. For that |
| - // reason we will write newly created entries back to disk. |
| - |
| - var urls = entries[key][destination]; |
| - if (this.updateInMemoryCopyRecord_( |
| - key, |
| - destination, |
| - urls.sourceUrl, |
| - urls.destinationUrl)) { |
| - promises.push(this.storage_.write([ |
| - importer.RecordType_.COPY, |
| - key, |
| - destination, |
| - urls.sourceUrl, |
| - urls.destinationUrl])); |
| - } |
| - } |
| - } |
| - return Promise.all(promises); |
| -}; |
| - |
| -/** |
| - * Adds all imported entries into existing entries. |
| - * |
| - * @param {!Object.<string, !Array.<!importer.Destination>>} entries |
| - * @return {!Promise.<?>} Resolves once all updates are completed. |
| - * @private |
| - */ |
| -importer.PersistentImportHistory.prototype.mergeImportedEntries_ = |
| - function(entries) { |
| - var promises = []; |
| - for (var key in entries) { |
| - entries[key].forEach( |
| - /** |
| - * @param {!importer.Destination} destination |
| - * @this {importer.PersistentImportHistory} |
| - */ |
| - function(destination) { |
| - if (this.updateInMemoryImportRecord_(key, destination)) { |
| - promises.push(this.storage_.write( |
| - [importer.RecordType_.IMPORT, key, destination])); |
| - } |
| - }.bind(this)); |
| - } |
| - return Promise.all(promises); |
| -}; |
| + .catch(importer.getLogger().catcher('import-history-load')); |
| -/** |
| - * Reloads history from disk. Should be called when the file |
| - * is changed by an external source. |
| - * |
| - * @return {!Promise.<!importer.PersistentImportHistory>} Resolves when |
| - * history has been refreshed. |
| - */ |
| -importer.PersistentImportHistory.prototype.refresh = function() { |
| - this.whenReady_ = this.refresh_(); |
| return this.whenReady_; |
| }; |
| @@ -342,6 +260,8 @@ importer.PersistentImportHistory.prototype.updateHistoryRecords_ = |
| }; |
| /** |
| + * Detects record type and expands records to appropriate arguments. |
| + * |
| * @param {!Array.<*>} record |
| * @this {importer.PersistentImportHistory} |
| */ |
| @@ -349,6 +269,12 @@ importer.PersistentImportHistory.prototype.updateInMemoryRecord_ = |
| function(record) { |
| switch (record[0]) { |
| case importer.RecordType_.COPY: |
| + if (record.length !== 5) { |
| + importer.getLogger().error( |
| + 'Skipping copy record with wrong number of fields: ' + |
| + record.length); |
| + break; |
| + } |
| this.updateInMemoryCopyRecord_( |
| /** @type {string} */ ( |
| record[1]), // key |
| @@ -360,6 +286,12 @@ importer.PersistentImportHistory.prototype.updateInMemoryRecord_ = |
| record[4])); // destinationUrl |
| return; |
| case importer.RecordType_.IMPORT: |
| + if (record.length !== 3) { |
| + importer.getLogger().error( |
| + 'Skipping import record with wrong number of fields: ' + |
| + record.length); |
| + break; |
| + } |
| this.updateInMemoryImportRecord_( |
| /** @type {string } */ ( |
| record[1]), // key |
| @@ -470,8 +402,8 @@ importer.PersistentImportHistory.prototype.markCopied = |
| importer.RecordType_.COPY, |
| key, |
| destination, |
| - entry.toURL(), |
| - destinationUrl]); |
| + importer.deflateAppUrl(entry.toURL()), |
| + importer.deflateAppUrl(destinationUrl)]); |
| }.bind(this)) |
| .then(this.notifyObservers_.bind( |
| this, |
| @@ -494,8 +426,9 @@ importer.PersistentImportHistory.prototype.listUnimportedUrls = |
| var imported = this.importedEntries_[key]; |
| for (var destination in this.copiedEntries_[key]) { |
| if (!imported || imported.indexOf(destination) === -1) { |
| - unimported.push( |
| + var url = importer.inflateAppUrl( |
|
mtomasz
2015/02/25 00:40:17
We're losing backward compatibility. What will hap
Steve McKay
2015/02/25 01:51:56
They'll still have the pictures, but they'll have
|
| this.copiedEntries_[key][destination].destinationUrl); |
| + unimported.push(url); |
| } |
| } |
| } |
| @@ -533,7 +466,8 @@ importer.PersistentImportHistory.prototype.markImported = |
| /** @override */ |
| importer.PersistentImportHistory.prototype.markImportedByUrl = |
| function(destinationUrl) { |
| - var key = this.copyKeyIndex_[destinationUrl]; |
| + var deflatedUrl = importer.deflateAppUrl(destinationUrl); |
| + var key = this.copyKeyIndex_[deflatedUrl]; |
| if (!!key) { |
| var copyData = this.copiedEntries_[key]; |
| @@ -541,16 +475,18 @@ importer.PersistentImportHistory.prototype.markImportedByUrl = |
| // unnecessary given the fact that there will almost always |
| // be just one destination for a file (assumption). |
| for (var destination in copyData) { |
| - if (copyData[destination].destinationUrl === destinationUrl) { |
| + if (copyData[destination].destinationUrl === deflatedUrl) { |
| return this.storeRecord_([ |
| importer.RecordType_.IMPORT, |
| key, |
| destination]).then( |
| function() { |
| + var sourceUrl = importer.inflateAppUrl( |
| + copyData[destination].sourceUrl); |
| // Here we try to create an Entry for the source URL. |
| // This will allow observers to update the UI if the |
| // source entry is in view. |
| - util.urlToEntry(copyData[destination].sourceUrl).then( |
| + util.urlToEntry(sourceUrl).then( |
| function(entry) { |
| if (entry.isFile) { |
| this.notifyObservers_( |
| @@ -558,7 +494,13 @@ importer.PersistentImportHistory.prototype.markImportedByUrl = |
| /** @type {!FileEntry} */ (entry), |
| destination); |
| } |
| - }.bind(this)); |
| + }.bind(this)) |
| + .catch( |
| + function(error) { |
| + console.log('Unable to lookup original entry for: ' + |
| + sourceUrl); |
| + return; |
| + }); |
| }.bind(this) |
| ) |
| .catch(importer.getLogger().catcher('mark-imported-by-url')); |
| @@ -686,8 +628,6 @@ importer.SynchronizedHistoryLoader = function(fileProvider) { |
| importer.SynchronizedHistoryLoader.prototype.getHistory = function() { |
| if (this.needsInitialization_) { |
| this.needsInitialization_ = false; |
| - this.fileProvider_.addSyncListener( |
| - this.onSyncedDataChanged_.bind(this)); |
| this.fileProvider_.getSyncFileEntry() |
| .then( |
| @@ -702,7 +642,7 @@ importer.SynchronizedHistoryLoader.prototype.getHistory = function() { |
| importer.createMetadataHashcode, |
| storage); |
| new importer.DriveSyncWatcher(history); |
| - history.refresh().then( |
| + history.load().then( |
| /** @this {importer.SynchronizedHistoryLoader} */ |
| function() { |
| this.historyResolver_.resolve(history); |
| @@ -721,22 +661,6 @@ importer.SynchronizedHistoryLoader.prototype.addHistoryLoadedListener = |
| }; |
| /** |
| - * Handles file sync events, by simply reloading history. The presumption |
| - * is that 99% of the time these events will basically be happening when |
| - * there is no active import process. |
| - * |
| - * @private |
| - */ |
| -importer.SynchronizedHistoryLoader.prototype.onSyncedDataChanged_ = |
| - function() { |
| - this.historyResolver_.promise.then( |
| - /** @param {!importer.ImportHistory} history */ |
| - function(history) { |
| - history.refresh(); |
| - }); |
| -}; |
| - |
| -/** |
| * An simple record storage mechanism. |
| * |
| * @interface |