Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: chrome/browser/resources/file_manager/js/media/media_util.js

Issue 12316118: Enabled Mosaic view on each volume. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleaned up. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * Loads a thumbnail using provided url. In CANVAS mode, loaded images 6 * Loads a thumbnail using provided url. In CANVAS mode, loaded images
7 * are attached as <canvas> element, while in IMAGE mode as <img>. 7 * are attached as <canvas> element, while in IMAGE mode as <img>.
8 * <canvas> renders faster than <img>, however has bigger memory overhead. 8 * <canvas> renders faster than <img>, however has bigger memory overhead.
9 * 9 *
10 * @param {string} url File URL. 10 * @param {string} url File URL.
11 * @param {ThumbnailLoader.LoaderType=} opt_loaderType Canvas or Image loader, 11 * @param {ThumbnailLoader.LoaderType=} opt_loaderType Canvas or Image loader,
12 * default: IMAGE. 12 * default: IMAGE.
13 * @param {Object=} opt_metadata Metadata object. 13 * @param {Object=} opt_metadata Metadata object.
14 * @param {string=} opt_mediaType Media type. 14 * @param {string=} opt_mediaType Media type.
15 * @param {ThumbnailLoader.UseEmbedded=} opt_useEmbedded If to use embedded
16 * jpeg thumbnail if available. Default: USE_EMBEDDED.
15 * @constructor 17 * @constructor
16 */ 18 */
17 function ThumbnailLoader(url, opt_loaderType, opt_metadata, opt_mediaType) { 19 function ThumbnailLoader(
20 url, opt_loaderType, opt_metadata, opt_mediaType, opt_useEmbedded) {
21 opt_useEmbedded = opt_useEmbedded || ThumbnailLoader.UseEmbedded.USE_EMBEDDED;
22
18 this.mediaType_ = opt_mediaType || FileType.getMediaType(url); 23 this.mediaType_ = opt_mediaType || FileType.getMediaType(url);
19 this.loaderType_ = opt_loaderType || ThumbnailLoader.LoaderType.IMAGE; 24 this.loaderType_ = opt_loaderType || ThumbnailLoader.LoaderType.IMAGE;
20 25
21 if (!opt_metadata) { 26 if (!opt_metadata) {
22 this.thumbnailUrl_ = url; // Use the URL directly. 27 this.thumbnailUrl_ = url; // Use the URL directly.
23 return; 28 return;
24 } 29 }
25 30
26 this.fallbackUrl_ = null; 31 this.fallbackUrl_ = null;
27 this.thumbnailUrl_ = null; 32 this.thumbnailUrl_ = null;
28 if (opt_metadata.drive) { 33 if (opt_metadata.drive) {
29 var apps = opt_metadata.drive.driveApps; 34 var apps = opt_metadata.drive.driveApps;
30 for (var i = 0; i < apps.length; ++i) { 35 for (var i = 0; i < apps.length; ++i) {
31 if (apps[i].docIcon && apps[i].isPrimary) { 36 if (apps[i].docIcon && apps[i].isPrimary) {
32 this.fallbackUrl_ = apps[i].docIcon; 37 this.fallbackUrl_ = apps[i].docIcon;
33 break; 38 break;
34 } 39 }
35 } 40 }
36 } 41 }
37 42
38 if (opt_metadata.thumbnail && opt_metadata.thumbnail.url) { 43 if (opt_metadata.thumbnail && opt_metadata.thumbnail.url &&
44 opt_useEmbedded == ThumbnailLoader.UseEmbedded.USE_EMBEDDED) {
39 this.thumbnailUrl_ = opt_metadata.thumbnail.url; 45 this.thumbnailUrl_ = opt_metadata.thumbnail.url;
40 this.transform_ = opt_metadata.thumbnail.transform; 46 this.transform_ = opt_metadata.thumbnail.transform;
41 } else if (FileType.isImage(url)) { 47 } else if (FileType.isImage(url)) {
42 this.thumbnailUrl_ = url; 48 this.thumbnailUrl_ = url;
43 this.transform_ = opt_metadata.media && opt_metadata.media.imageTransform; 49 this.transform_ = opt_metadata.media && opt_metadata.media.imageTransform;
44 } else if (this.fallbackUrl_) { 50 } else if (this.fallbackUrl_) {
45 // Use fallback as the primary thumbnail. 51 // Use fallback as the primary thumbnail.
46 this.thumbnailUrl_ = this.fallbackUrl_; 52 this.thumbnailUrl_ = this.fallbackUrl_;
47 this.fallbackUrl_ = null; 53 this.fallbackUrl_ = null;
48 } // else the generic thumbnail based on the media type will be used. 54 } // else the generic thumbnail based on the media type will be used.
(...skipping 29 matching lines...) Expand all
78 /** 84 /**
79 * Type of element to store the image. 85 * Type of element to store the image.
80 * @enum 86 * @enum
81 */ 87 */
82 ThumbnailLoader.LoaderType = { 88 ThumbnailLoader.LoaderType = {
83 IMAGE: 0, 89 IMAGE: 0,
84 CANVAS: 1 90 CANVAS: 1
85 }; 91 };
86 92
87 /** 93 /**
94 * Whether to use the embedded thumbnail, or not. The embedded thumbnail may
95 * be small.
96 * @enum
yoshiki 2013/02/26 08:21:44 @enum {number} The @enum tag must be followed by
mtomasz 2013/02/26 08:39:20 We have to fix it in lots of places. Separate cl?
yoshiki 2013/02/26 08:50:27 Thanks. We need to fix the others as well in separ
mtomasz 2013/02/27 00:55:31 Done.
97 */
98 ThumbnailLoader.UseEmbedded = {
99 USE_EMBEDDED: 0,
100 NO_EMBEDDED: 1
101 };
102
103 /**
88 * Maximum thumbnail's width when generating from the full resolution image. 104 * Maximum thumbnail's width when generating from the full resolution image.
89 * @const 105 * @const
90 * @type {number} 106 * @type {number}
91 */ 107 */
92 ThumbnailLoader.THUMBNAIL_MAX_WIDTH = 500; 108 ThumbnailLoader.THUMBNAIL_MAX_WIDTH = 500;
93 109
94 /** 110 /**
95 * Maximum thumbnail's height when generating from the full resolution image. 111 * Maximum thumbnail's height when generating from the full resolution image.
96 * @const 112 * @const
97 * @type {number} 113 * @type {number}
(...skipping 17 matching lines...) Expand all
115 opt_optimizationMode = opt_optimizationMode || 131 opt_optimizationMode = opt_optimizationMode ||
116 ThumbnailLoader.OptimizationMode.NEVER_DISCARD; 132 ThumbnailLoader.OptimizationMode.NEVER_DISCARD;
117 133
118 if (!this.thumbnailUrl_) { 134 if (!this.thumbnailUrl_) {
119 // Relevant CSS rules are in file_types.css. 135 // Relevant CSS rules are in file_types.css.
120 box.setAttribute('generic-thumbnail', this.mediaType_); 136 box.setAttribute('generic-thumbnail', this.mediaType_);
121 if (opt_onGeneric) opt_onGeneric(); 137 if (opt_onGeneric) opt_onGeneric();
122 return; 138 return;
123 } 139 }
124 140
141 this.cancel();
125 this.canvasUpToDate_ = false; 142 this.canvasUpToDate_ = false;
126 this.image_ = new Image(); 143 this.image_ = new Image();
127 this.image_.onload = function() { 144 this.image_.onload = function() {
128 this.attachImage(box, fillMode); 145 this.attachImage(box, fillMode);
129 if (opt_onSuccess) 146 if (opt_onSuccess)
130 opt_onSuccess(this.image_, this.transform_); 147 opt_onSuccess(this.image_, this.transform_);
131 }.bind(this); 148 }.bind(this);
132 this.image_.onerror = function() { 149 this.image_.onerror = function() {
133 if (opt_onError) 150 if (opt_onError)
134 opt_onError(); 151 opt_onError();
135 if (this.fallbackUrl_) { 152 if (this.fallbackUrl_) {
136 new ThumbnailLoader(this.fallbackUrl_, 153 new ThumbnailLoader(this.fallbackUrl_,
137 this.loaderType_, 154 this.loaderType_,
138 null, 155 null,
139 this.mediaType_). 156 this.mediaType_).
140 load(box, fillMode, opt_onSuccess); 157 load(box, fillMode, opt_onSuccess);
141 } else { 158 } else {
142 box.setAttribute('generic-thumbnail', this.mediaType_); 159 box.setAttribute('generic-thumbnail', this.mediaType_);
143 } 160 }
144 }.bind(this); 161 }.bind(this);
145 162
146 if (this.image_.src) { 163 if (this.image_.src) {
147 console.warn('Thumbnail already loaded: ' + this.thumbnailUrl_); 164 console.warn('Thumbnail already loaded: ' + this.thumbnailUrl_);
148 return; 165 return;
149 } 166 }
150 167
151 // TODO(mtomasz): Smarter calculation of the requested size. 168 // TODO(mtomasz): Smarter calculation of the requested size.
152 var wasAttached = box.ownerDocument.contains(box); 169 var wasAttached = box.ownerDocument.contains(box);
153 var taskId = util.loadImage( 170 this.taskId_ = util.loadImage(
154 this.image_, 171 this.image_,
155 this.thumbnailUrl_, 172 this.thumbnailUrl_,
156 { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH, 173 { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH,
157 maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT, 174 maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT,
158 cache: true }, 175 cache: true },
159 function() { 176 function() {
160 if (opt_optimizationMode == 177 if (opt_optimizationMode ==
161 ThumbnailLoader.OptimizationMode.DISCARD_DETACHED && 178 ThumbnailLoader.OptimizationMode.DISCARD_DETACHED &&
162 !box.ownerDocument.contains(box)) { 179 !box.ownerDocument.contains(box)) {
163 // If the container is not attached, then invalidate the download. 180 // If the container is not attached, then invalidate the download.
164 return false; 181 return false;
165 } 182 }
166 return true; 183 return true;
167 }); 184 });
168 185
169 if (!taskId) 186 if (!this.taskId_)
170 this.image_.classList.add('cached'); 187 this.image_.classList.add('cached');
171 }; 188 };
172 189
173 /** 190 /**
191 * Cancels loading the current image.
192 */
193 ThumbnailLoader.prototype.cancel = function() {
194 if (this.taskId_) {
195 this.image_.onload = function() {};
196 this.image_.onerror = function() {};
197 util.cancelLoadImage(this.taskId_);
198 }
199 };
200
201 /**
174 * @return {boolean} True if a valid image is loaded. 202 * @return {boolean} True if a valid image is loaded.
175 */ 203 */
176 ThumbnailLoader.prototype.hasValidImage = function() { 204 ThumbnailLoader.prototype.hasValidImage = function() {
177 return !!(this.image_ && this.image_.width && this.image_.height); 205 return !!(this.image_ && this.image_.width && this.image_.height);
178 }; 206 };
179 207
180 /** 208 /**
181 * @return {boolean} True if the image is rotated 90 degrees left or right. 209 * @return {boolean} True if the image is rotated 90 degrees left or right.
182 * @private 210 * @private
183 */ 211 */
(...skipping 20 matching lines...) Expand all
204 * 232 *
205 * @param {function(boolean)} callback Callback, parameter is true if the image 233 * @param {function(boolean)} callback Callback, parameter is true if the image
206 * has loaded successfully or a stock icon has been used. 234 * has loaded successfully or a stock icon has been used.
207 */ 235 */
208 ThumbnailLoader.prototype.loadDetachedImage = function(callback) { 236 ThumbnailLoader.prototype.loadDetachedImage = function(callback) {
209 if (!this.thumbnailUrl_) { 237 if (!this.thumbnailUrl_) {
210 callback(true); 238 callback(true);
211 return; 239 return;
212 } 240 }
213 241
242 this.cancel();
214 this.canvasUpToDate_ = false; 243 this.canvasUpToDate_ = false;
215 this.image_ = new Image(); 244 this.image_ = new Image();
216 this.image_.onload = callback.bind(null, true); 245 this.image_.onload = callback.bind(null, true);
217 this.image_.onerror = callback.bind(null, false); 246 this.image_.onerror = callback.bind(null, false);
218 247
219 // TODO(mtomasz): Smarter calculation of the requested size. 248 // TODO(mtomasz): Smarter calculation of the requested size.
220 var taskId = util.loadImage( 249 this.taskId_ = util.loadImage(
221 this.image_, 250 this.image_,
222 this.thumbnailUrl_, 251 this.thumbnailUrl_,
223 { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH, 252 { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH,
224 maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT, 253 maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT,
225 cache: true }); 254 cache: true });
226 255
227 if (!taskId) 256 if (!this.taskId_)
228 this.image_.classList.add('cached'); 257 this.image_.classList.add('cached');
229 }; 258 };
230 259
231 /** 260 /**
232 * Attach the image to a given element. 261 * Attach the image to a given element.
233 * @param {Element} container Parent element. 262 * @param {Element} container Parent element.
234 * @param {ThumbnailLoader.FillMode} fillMode Fill mode. 263 * @param {ThumbnailLoader.FillMode} fillMode Fill mode.
235 */ 264 */
236 ThumbnailLoader.prototype.attachImage = function(container, fillMode) { 265 ThumbnailLoader.prototype.attachImage = function(container, fillMode) {
237 if (!this.hasValidImage()) { 266 if (!this.hasValidImage()) {
(...skipping 18 matching lines...) Expand all
256 // Canvas will be attached. 285 // Canvas will be attached.
257 attachableMedia = this.canvas_; 286 attachableMedia = this.canvas_;
258 } else { 287 } else {
259 // Image will be attached. 288 // Image will be attached.
260 attachableMedia = this.image_; 289 attachableMedia = this.image_;
261 } 290 }
262 291
263 util.applyTransform(container, this.transform_); 292 util.applyTransform(container, this.transform_);
264 ThumbnailLoader.centerImage_( 293 ThumbnailLoader.centerImage_(
265 container, attachableMedia, fillMode, this.isRotated_()); 294 container, attachableMedia, fillMode, this.isRotated_());
266 if (this.image_.parentNode != container) { 295 if (attachableMedia.parentNode != container) {
267 container.textContent = ''; 296 container.textContent = '';
268 container.appendChild(attachableMedia); 297 container.appendChild(attachableMedia);
269 } 298 }
270 }; 299 };
271 300
272 /** 301 /**
273 * Update the image style to fit/fill the container. 302 * Update the image style to fit/fill the container.
274 * 303 *
275 * Using webkit center packing does not align the image properly, so we need 304 * Using webkit center packing does not align the image properly, so we need
276 * to wait until the image loads and its dimensions are known, then manually 305 * to wait until the image loads and its dimensions are known, then manually
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 369
341 function percent(fraction) { 370 function percent(fraction) {
342 return (fraction * 100).toFixed(2) + '%'; 371 return (fraction * 100).toFixed(2) + '%';
343 } 372 }
344 373
345 img.style.width = percent(fractionX); 374 img.style.width = percent(fractionX);
346 img.style.height = percent(fractionY); 375 img.style.height = percent(fractionY);
347 img.style.left = percent((1 - fractionX) / 2); 376 img.style.left = percent((1 - fractionX) / 2);
348 img.style.top = percent((1 - fractionY) / 2); 377 img.style.top = percent((1 - fractionY) / 2);
349 }; 378 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698