diff options
Diffstat (limited to 'ui/file_manager')
-rw-r--r-- | ui/file_manager/gallery/js/gallery.js | 24 | ||||
-rw-r--r-- | ui/file_manager/gallery/js/gallery_item.js | 59 | ||||
-rw-r--r-- | ui/file_manager/gallery/js/gallery_item_unittest.html | 23 | ||||
-rw-r--r-- | ui/file_manager/gallery/js/gallery_item_unittest.js | 79 |
4 files changed, 136 insertions, 49 deletions
diff --git a/ui/file_manager/gallery/js/gallery.js b/ui/file_manager/gallery/js/gallery.js index a575e86..b0a12ceb 100644 --- a/ui/file_manager/gallery/js/gallery.js +++ b/ui/file_manager/gallery/js/gallery.js @@ -71,47 +71,27 @@ GalleryDataModel.prototype.saveItem = function( var oldEntry = item.getEntry(); var oldMetadata = item.getMetadata(); var oldLocationInfo = item.getLocationInfo(); - var metadataEncoder = ImageEncoder.encodeMetadata( - item.getMetadata(), canvas, 1 /* quality */); - var newMetadata = ContentProvider.ConvertContentMetadata( - metadataEncoder.getMetadata(), - MetadataCache.cloneMetadata(item.getMetadata())); - if (newMetadata.filesystem) - newMetadata.filesystem.modificationTime = new Date(); - if (newMetadata.external) - newMetadata.external.present = true; - return new Promise(function(fulfill, reject) { item.saveToFile( volumeManager, this.fallbackSaveDirectory, overwrite, canvas, - metadataEncoder, function(success) { if (!success) { reject('Failed to save the image.'); return; } - // The item's entry is updated to the latest entry. Update metadata. - item.setMetadata(newMetadata); - // Current entry is updated. // Dispatch an event. var event = new Event('content'); event.item = item; event.oldEntry = oldEntry; - event.metadata = newMetadata; + event.metadata = item.getMetadata(); this.dispatchEvent(event); - if (util.isSameEntry(oldEntry, item.getEntry())) { - // Need an update of metdataCache. - this.metadataCache_.set( - item.getEntry(), - Gallery.METADATA_TYPE, - newMetadata); - } else { + if (!util.isSameEntry(oldEntry, item.getEntry())) { // New entry is added and the item now tracks it. // Add another item for the old entry. var anotherItem = new Gallery.Item( diff --git a/ui/file_manager/gallery/js/gallery_item.js b/ui/file_manager/gallery/js/gallery_item.js index 7244bf5..227940a 100644 --- a/ui/file_manager/gallery/js/gallery_item.js +++ b/ui/file_manager/gallery/js/gallery_item.js @@ -112,14 +112,6 @@ Gallery.Item.prototype.getFetchedMedia = function() { }; /** - * Sets the metadata. - * @param {!Object} metadata New metadata. - */ -Gallery.Item.prototype.setMetadata = function(metadata) { - this.metadata_ = Object.preventExtensions(metadata); -}; - -/** * @return {string} File name. */ Gallery.Item.prototype.getFileName = function() { @@ -231,30 +223,45 @@ Gallery.Item.prototype.createCopyName_ = function(dirEntry, callback) { * Writes the new item content to either the existing or a new file. * * @param {!VolumeManager} volumeManager Volume manager instance. - * @param {string} fallbackDir Fallback directory in case the current directory - * is read only. + * @param {DirectoryEntry} fallbackDir Fallback directory in case the current + * directory is read only. * @param {boolean} overwrite Whether to overwrite the image to the item or not. * @param {!HTMLCanvasElement} canvas Source canvas. - * @param {!ImageEncoder.MetadataEncoder} metadataEncoder MetadataEncoder. * @param {function(boolean)=} opt_callback Callback accepting true for success. */ Gallery.Item.prototype.saveToFile = function( - volumeManager, fallbackDir, overwrite, canvas, metadataEncoder, - opt_callback) { + volumeManager, fallbackDir, overwrite, canvas, opt_callback) { ImageUtil.metrics.startInterval(ImageUtil.getMetricName('SaveTime')); var name = this.getFileName(); - var onSuccess = function(entry, locationInfo) { + var onSuccess = function(entry) { + var locationInfo = volumeManager.getLocationInfo(entry); + if (!locationInfo) { + // Reuse old location info if it fails to obtain location info. + locationInfo = this.locationInfo_; + } ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 1, 2); ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('SaveTime')); this.entry_ = entry; this.locationInfo_ = locationInfo; - this.metadataCache_.clear([this.entry_], 'fetchedMedia'); - if (opt_callback) - opt_callback(true); + // Updates the metadata. + this.metadataCache_.clear([this.entry_], '*'); + this.metadataCache_.getLatest( + [this.entry_], + Gallery.METADATA_TYPE, + function(metadataList) { + if (metadataList.length === 1) { + this.metadata_ = metadataList[0]; + if (opt_callback) + opt_callback(true); + } else { + if (opt_callback) + opt_callback(false); + } + }.bind(this)); }.bind(this); var onError = function(error) { @@ -266,15 +273,19 @@ Gallery.Item.prototype.saveToFile = function( var doSave = function(newFile, fileEntry) { fileEntry.createWriter(function(fileWriter) { - function writeContent() { + var writeContent = function() { fileWriter.onwriteend = onSuccess.bind(null, fileEntry); + // TODO(hirono): Remove the quality 1 for thumbanils. The code path is + // no longer used. + var metadataEncoder = ImageEncoder.encodeMetadata( + this.metadata_, canvas, 1 /* quality */); // Contrary to what one might think 1.0 is not a good default. Opening // and saving an typical photo taken with consumer camera increases its // file size by 50-100%. Experiments show that 0.9 is much better. It // shrinks some photos a bit, keeps others about the same size, but does // not visibly lower the quality. fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder, 0.9)); - } + }.bind(this); fileWriter.onerror = function(error) { onError(error); // Disable all callbacks on the first error. @@ -287,18 +298,12 @@ Gallery.Item.prototype.saveToFile = function( fileWriter.onwriteend = writeContent; fileWriter.truncate(0); } - }, onError); - }; + }.bind(this), onError); + }.bind(this); var getFile = function(dir, newFile) { dir.getFile(name, {create: newFile, exclusive: newFile}, function(fileEntry) { - var locationInfo = volumeManager.getLocationInfo(fileEntry); - // If the volume is gone, then abort the saving operation. - if (!locationInfo) { - onError('NotFound'); - return; - } doSave(newFile, fileEntry); }.bind(this), onError); }.bind(this); diff --git a/ui/file_manager/gallery/js/gallery_item_unittest.html b/ui/file_manager/gallery/js/gallery_item_unittest.html new file mode 100644 index 0000000..70ef7d0 --- /dev/null +++ b/ui/file_manager/gallery/js/gallery_item_unittest.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + -- Use of this source code is governed by a BSD-style license that can be + -- found in the LICENSE file. + --> +<script> +// Define mock Gallery class to define Gallery.Item class. +var Gallery = function() {}; +</script> +<!-- Should be loaded before volume_manager.js --> +<script src="../../file_manager/common/js/volume_manager_common.js"></script> +<!-- Others --> +<script src="../../../webui/resources/js/assert.js"></script> +<script src="../../../webui/resources/js/cr.js"></script> +<script src="../../../webui/resources/js/cr/event_target.js"></script> +<script src="../../../webui/resources/js/cr/ui/array_data_model.js"></script> +<script src="../../../webui/resources/js/load_time_data.js"></script> +<script src="../../file_manager/common/js/mock_entry.js"></script> +<script src="../../file_manager/common/js/unittest_util.js"></script> +<script src="../../file_manager/common/js/util.js"></script> +<script src="gallery_item.js"></script> + +<script src="gallery_item_unittest.js"></script> diff --git a/ui/file_manager/gallery/js/gallery_item_unittest.js b/ui/file_manager/gallery/js/gallery_item_unittest.js new file mode 100644 index 0000000..e3c545b --- /dev/null +++ b/ui/file_manager/gallery/js/gallery_item_unittest.js @@ -0,0 +1,79 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Mock of ImageUtil. + */ +var ImageUtil = { + getMetricName: function() {}, + metrics: { + recordEnum: function() {}, + recordInterval: function() {}, + startInterval: function() {} + } +}; + +/** + * Mock of ImageEncoder + */ +var ImageEncoder = { + encodeMetadata: function() {}, + getBlob: function() {} +}; + +/** + * Load time data. + */ +loadTimeData.data = { + DRIVE_DIRECTORY_LABEL: '', + DOWNLOADS_DIRECTORY_LABEL: '' +}; + +/** + * Tests for GalleryItem#saveToFile. + */ +function testSaveToFile(callback) { + var fileSystem = new MockFileSystem('volumeId'); + fileSystem.populate(['/test.jpg']); + var entry = fileSystem.entries['/test.jpg']; + entry.createWriter = function(callback) { + callback({ + write: function() { + Promise.resolve().then(function() { + this.onwriteend(); + }.bind(this)); + }, + truncate: function() { + this.write(); + } + }); + }; + var fetchedMediaCleared = false; + var metadataCache = { + getLatest: function(entries, type, callback) { + callback([{name: 'newMetadata'}]); + }, + clear: function(entries, type) { + fetchedMediaCleared = true; + } + }; + var item = new Gallery.Item( + entry, + {isReadOnly: false}, + {name: 'oldMetadata'}, + metadataCache, + /* original */ true); + assertEquals('oldMetadata', item.getMetadata().name); + assertFalse(fetchedMediaCleared); + reportPromise( + new Promise(item.saveToFile.bind( + item, + {getLocationInfo: function() { return {}; }}, + null, + true, + document.createElement('canvas'))).then(function() { + assertEquals('newMetadata', item.getMetadata().name); + assertTrue(fetchedMediaCleared); + }), callback); +} |