Move action_runner.py out of actions folder prior to moving actions to internal.
[chromium-blink-merge.git] / ui / file_manager / gallery / js / gallery_data_model.js
blobcac6d65a9a791d2337beabaf8ae3520282e2e45d
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6  * Data model for gallery.
7  *
8  * @param {!MetadataModel} metadataModel
9  * @param {!EntryListWatcher=} opt_watcher Entry list watcher.
10  * @constructor
11  * @extends {cr.ui.ArrayDataModel}
12  */
13 function GalleryDataModel(metadataModel, opt_watcher) {
14   cr.ui.ArrayDataModel.call(this, []);
16   /**
17    * File system metadata.
18    * @private {!MetadataModel}
19    * @const
20    */
21   this.metadataModel_ = metadataModel;
23   /**
24    * Directory where the image is saved if the image is located in a read-only
25    * volume.
26    * @public {DirectoryEntry}
27    */
28   this.fallbackSaveDirectory = null;
30   // Start to watch file system entries.
31   var watcher = opt_watcher ? opt_watcher : new EntryListWatcher(this);
32   watcher.getEntry = function(item) { return item.getEntry(); };
35 /**
36  * Maximum number of full size image cache.
37  * @type {number}
38  * @const
39  * @private
40  */
41 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3;
43 /**
44  * Maximum number of screen size image cache.
45  * @type {number}
46  * @const
47  * @private
48  */
49 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5;
51 GalleryDataModel.prototype = {
52   __proto__: cr.ui.ArrayDataModel.prototype
55 /**
56  * Saves new image.
57  *
58  * @param {!VolumeManager} volumeManager Volume manager instance.
59  * @param {!Gallery.Item} item Original gallery item.
60  * @param {!HTMLCanvasElement} canvas Canvas containing new image.
61  * @param {boolean} overwrite Whether to overwrite the image to the item or not.
62  * @return {!Promise} Promise to be fulfilled with when the operation completes.
63  */
64 GalleryDataModel.prototype.saveItem = function(
65     volumeManager, item, canvas, overwrite) {
66   var oldEntry = item.getEntry();
67   var oldMetadataItem = item.getMetadataItem();
68   var oldThumbnailMetadataItem = item.getThumbnailMetadataItem();
69   var oldLocationInfo = item.getLocationInfo();
70   return new Promise(function(fulfill, reject) {
71     item.saveToFile(
72         volumeManager,
73         this.metadataModel_,
74         this.fallbackSaveDirectory,
75         overwrite,
76         canvas,
77         function(success) {
78           if (!success) {
79             reject('Failed to save the image.');
80             return;
81           }
83           // Current entry is updated.
84           // Dispatch an event.
85           var event = new Event('content');
86           event.item = item;
87           event.oldEntry = oldEntry;
88           event.thumbnailChanged = true;
89           this.dispatchEvent(event);
91           if (!util.isSameEntry(oldEntry, item.getEntry())) {
92             // New entry is added and the item now tracks it.
93             // Add another item for the old entry.
94             var anotherItem = new Gallery.Item(
95                 oldEntry,
96                 oldLocationInfo,
97                 oldMetadataItem,
98                 oldThumbnailMetadataItem,
99                 item.isOriginal());
100             // The item must be added behind the existing item so that it does
101             // not change the index of the existing item.
102             // TODO(hirono): Update the item index of the selection model
103             // correctly.
104             this.splice(this.indexOf(item) + 1, 0, anotherItem);
105           }
107           fulfill();
108         }.bind(this));
109   }.bind(this));
113  * Evicts image caches in the items.
114  */
115 GalleryDataModel.prototype.evictCache = function() {
116   // Sort the item by the last accessed date.
117   var sorted = this.slice().sort(function(a, b) {
118     return b.getLastAccessedDate() - a.getLastAccessedDate();
119   });
121   // Evict caches.
122   var contentCacheCount = 0;
123   var screenCacheCount = 0;
124   for (var i = 0; i < sorted.length; i++) {
125     if (sorted[i].contentImage) {
126       if (++contentCacheCount > GalleryDataModel.MAX_FULL_IMAGE_CACHE_) {
127         if (sorted[i].contentImage.parentNode) {
128           console.error('The content image has a parent node.');
129         } else {
130           // Force to free the buffer of the canvas by assigning zero size.
131           sorted[i].contentImage.width = 0;
132           sorted[i].contentImage.height = 0;
133           sorted[i].contentImage = null;
134         }
135       }
136     }
137     if (sorted[i].screenImage) {
138       if (++screenCacheCount > GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_) {
139         if (sorted[i].screenImage.parentNode) {
140           console.error('The screen image has a parent node.');
141         } else {
142           // Force to free the buffer of the canvas by assigning zero size.
143           sorted[i].screenImage.width = 0;
144           sorted[i].screenImage.height = 0;
145           sorted[i].screenImage = null;
146         }
147       }
148     }
149   }