Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / ui / file_manager / gallery / js / gallery_data_model.js
blob5bab3da76873545c7bb5a1575b846c2cf5cb3c89
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 oldLocationInfo = item.getLocationInfo();
68   return new Promise(function(fulfill, reject) {
69     item.saveToFile(
70         volumeManager,
71         this.metadataModel_,
72         this.fallbackSaveDirectory,
73         overwrite,
74         canvas,
75         function(success) {
76           if (!success) {
77             reject('Failed to save the image.');
78             return;
79           }
81           // Current entry is updated.
82           // Dispatch an event.
83           var event = new Event('content');
84           event.item = item;
85           event.oldEntry = oldEntry;
86           event.thumbnailChanged = true;
87           this.dispatchEvent(event);
89           if (!util.isSameEntry(oldEntry, item.getEntry())) {
90             Promise.all([
91               this.metadataModel_.get(
92                   [oldEntry], Gallery.PREFETCH_PROPERTY_NAMES),
93               new ThumbnailModel(this.metadataModel_).get([oldEntry])
94             ]).then(function(itemLists) {
95               // New entry is added and the item now tracks it.
96               // Add another item for the old entry.
97               var anotherItem = new Gallery.Item(
98                   oldEntry,
99                   oldLocationInfo,
100                   itemLists[0][0],
101                   itemLists[1][0],
102                   item.isOriginal());
103               // The item must be added behind the existing item so that it does
104               // not change the index of the existing item.
105               // TODO(hirono): Update the item index of the selection model
106               // correctly.
107               this.splice(this.indexOf(item) + 1, 0, anotherItem);
108             }.bind(this)).then(fulfill, reject);
109           } else {
110             fulfill();
111           }
112         }.bind(this));
113   }.bind(this));
117  * Evicts image caches in the items.
118  */
119 GalleryDataModel.prototype.evictCache = function() {
120   // Sort the item by the last accessed date.
121   var sorted = this.slice().sort(function(a, b) {
122     return b.getLastAccessedDate() - a.getLastAccessedDate();
123   });
125   // Evict caches.
126   var contentCacheCount = 0;
127   var screenCacheCount = 0;
128   for (var i = 0; i < sorted.length; i++) {
129     if (sorted[i].contentImage) {
130       if (++contentCacheCount > GalleryDataModel.MAX_FULL_IMAGE_CACHE_) {
131         if (sorted[i].contentImage.parentNode) {
132           console.error('The content image has a parent node.');
133         } else {
134           // Force to free the buffer of the canvas by assigning zero size.
135           sorted[i].contentImage.width = 0;
136           sorted[i].contentImage.height = 0;
137           sorted[i].contentImage = null;
138         }
139       }
140     }
141     if (sorted[i].screenImage) {
142       if (++screenCacheCount > GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_) {
143         if (sorted[i].screenImage.parentNode) {
144           console.error('The screen image has a parent node.');
145         } else {
146           // Force to free the buffer of the canvas by assigning zero size.
147           sorted[i].screenImage.width = 0;
148           sorted[i].screenImage.height = 0;
149           sorted[i].screenImage = null;
150         }
151       }
152     }
153   }