summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/file_manager/gallery/js/gallery.js24
-rw-r--r--ui/file_manager/gallery/js/gallery_item.js59
-rw-r--r--ui/file_manager/gallery/js/gallery_item_unittest.html23
-rw-r--r--ui/file_manager/gallery/js/gallery_item_unittest.js79
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);
+}