Index: chrome/browser/resources/file_manager/js/media/media_util.js |
diff --git a/chrome/browser/resources/file_manager/js/media/media_util.js b/chrome/browser/resources/file_manager/js/media/media_util.js |
deleted file mode 100644 |
index a4c28348048d77bb57920a3e5f50db4611468918..0000000000000000000000000000000000000000 |
--- a/chrome/browser/resources/file_manager/js/media/media_util.js |
+++ /dev/null |
@@ -1,421 +0,0 @@ |
-// Copyright (c) 2012 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. |
- |
-'use strict'; |
- |
-/** |
- * Loads a thumbnail using provided url. In CANVAS mode, loaded images |
- * are attached as <canvas> element, while in IMAGE mode as <img>. |
- * <canvas> renders faster than <img>, however has bigger memory overhead. |
- * |
- * @param {string} url File URL. |
- * @param {ThumbnailLoader.LoaderType=} opt_loaderType Canvas or Image loader, |
- * default: IMAGE. |
- * @param {Object=} opt_metadata Metadata object. |
- * @param {string=} opt_mediaType Media type. |
- * @param {ThumbnailLoader.UseEmbedded=} opt_useEmbedded If to use embedded |
- * jpeg thumbnail if available. Default: USE_EMBEDDED. |
- * @param {number=} opt_priority Priority, the highest is 0. default: 2. |
- * @constructor |
- */ |
-function ThumbnailLoader(url, opt_loaderType, opt_metadata, opt_mediaType, |
- opt_useEmbedded, opt_priority) { |
- opt_useEmbedded = opt_useEmbedded || ThumbnailLoader.UseEmbedded.USE_EMBEDDED; |
- |
- this.mediaType_ = opt_mediaType || FileType.getMediaType(url); |
- this.loaderType_ = opt_loaderType || ThumbnailLoader.LoaderType.IMAGE; |
- this.metadata_ = opt_metadata; |
- this.priority_ = (opt_priority !== undefined) ? opt_priority : 2; |
- this.transform_ = null; |
- |
- if (!opt_metadata) { |
- this.thumbnailUrl_ = url; // Use the URL directly. |
- return; |
- } |
- |
- this.fallbackUrl_ = null; |
- this.thumbnailUrl_ = null; |
- if (opt_metadata.drive && opt_metadata.drive.customIconUrl) |
- this.fallbackUrl_ = opt_metadata.drive.customIconUrl; |
- |
- // Fetch the rotation from the Drive metadata (if available). |
- var driveTransform; |
- if (opt_metadata.drive && opt_metadata.drive.imageRotation !== undefined) { |
- driveTransform = { |
- scaleX: 1, |
- scaleY: 1, |
- rotate90: opt_metadata.drive.imageRotation / 90 |
- }; |
- } |
- |
- if (opt_metadata.thumbnail && opt_metadata.thumbnail.url && |
- opt_useEmbedded == ThumbnailLoader.UseEmbedded.USE_EMBEDDED) { |
- this.thumbnailUrl_ = opt_metadata.thumbnail.url; |
- this.transform_ = driveTransform !== undefined ? driveTransform : |
- opt_metadata.thumbnail.transform; |
- } else if (FileType.isImage(url)) { |
- this.thumbnailUrl_ = url; |
- this.transform_ = driveTransform !== undefined ? driveTransform : |
- opt_metadata.media && opt_metadata.media.imageTransform; |
- } else if (this.fallbackUrl_) { |
- // Use fallback as the primary thumbnail. |
- this.thumbnailUrl_ = this.fallbackUrl_; |
- this.fallbackUrl_ = null; |
- } // else the generic thumbnail based on the media type will be used. |
-} |
- |
-/** |
- * In percents (0.0 - 1.0), how much area can be cropped to fill an image |
- * in a container, when loading a thumbnail in FillMode.AUTO mode. |
- * The specified 30% value allows to fill 16:9, 3:2 pictures in 4:3 element. |
- * @type {number} |
- */ |
-ThumbnailLoader.AUTO_FILL_THRESHOLD = 0.3; |
- |
-/** |
- * Type of displaying a thumbnail within a box. |
- * @enum {number} |
- */ |
-ThumbnailLoader.FillMode = { |
- FILL: 0, // Fill whole box. Image may be cropped. |
- FIT: 1, // Keep aspect ratio, do not crop. |
- OVER_FILL: 2, // Fill whole box with possible stretching. |
- AUTO: 3 // Try to fill, but if incompatible aspect ratio, then fit. |
-}; |
- |
-/** |
- * Optimization mode for downloading thumbnails. |
- * @enum {number} |
- */ |
-ThumbnailLoader.OptimizationMode = { |
- NEVER_DISCARD: 0, // Never discards downloading. No optimization. |
- DISCARD_DETACHED: 1 // Canceled if the container is not attached anymore. |
-}; |
- |
-/** |
- * Type of element to store the image. |
- * @enum {number} |
- */ |
-ThumbnailLoader.LoaderType = { |
- IMAGE: 0, |
- CANVAS: 1 |
-}; |
- |
-/** |
- * Whether to use the embedded thumbnail, or not. The embedded thumbnail may |
- * be small. |
- * @enum {number} |
- */ |
-ThumbnailLoader.UseEmbedded = { |
- USE_EMBEDDED: 0, |
- NO_EMBEDDED: 1 |
-}; |
- |
-/** |
- * Maximum thumbnail's width when generating from the full resolution image. |
- * @const |
- * @type {number} |
- */ |
-ThumbnailLoader.THUMBNAIL_MAX_WIDTH = 500; |
- |
-/** |
- * Maximum thumbnail's height when generating from the full resolution image. |
- * @const |
- * @type {number} |
- */ |
-ThumbnailLoader.THUMBNAIL_MAX_HEIGHT = 500; |
- |
-/** |
- * Loads and attaches an image. |
- * |
- * @param {HTMLElement} box Container element. |
- * @param {ThumbnailLoader.FillMode} fillMode Fill mode. |
- * @param {ThumbnailLoader.OptimizationMode=} opt_optimizationMode Optimization |
- * for downloading thumbnails. By default optimizations are disabled. |
- * @param {function(Image, Object)} opt_onSuccess Success callback, |
- * accepts the image and the transform. |
- * @param {function} opt_onError Error callback. |
- * @param {function} opt_onGeneric Callback for generic image used. |
- */ |
-ThumbnailLoader.prototype.load = function(box, fillMode, opt_optimizationMode, |
- opt_onSuccess, opt_onError, opt_onGeneric) { |
- opt_optimizationMode = opt_optimizationMode || |
- ThumbnailLoader.OptimizationMode.NEVER_DISCARD; |
- |
- if (!this.thumbnailUrl_) { |
- // Relevant CSS rules are in file_types.css. |
- box.setAttribute('generic-thumbnail', this.mediaType_); |
- if (opt_onGeneric) opt_onGeneric(); |
- return; |
- } |
- |
- this.cancel(); |
- this.canvasUpToDate_ = false; |
- this.image_ = new Image(); |
- this.image_.onload = function() { |
- this.attachImage(box, fillMode); |
- if (opt_onSuccess) |
- opt_onSuccess(this.image_, this.transform_); |
- }.bind(this); |
- this.image_.onerror = function() { |
- if (opt_onError) |
- opt_onError(); |
- if (this.fallbackUrl_) { |
- new ThumbnailLoader(this.fallbackUrl_, |
- this.loaderType_, |
- null, // No metadata. |
- this.mediaType_, |
- undefined, // Default value for use-embedded. |
- this.priority_). |
- load(box, fillMode, opt_optimizationMode, opt_onSuccess); |
- } else { |
- box.setAttribute('generic-thumbnail', this.mediaType_); |
- } |
- }.bind(this); |
- |
- if (this.image_.src) { |
- console.warn('Thumbnail already loaded: ' + this.thumbnailUrl_); |
- return; |
- } |
- |
- // TODO(mtomasz): Smarter calculation of the requested size. |
- var wasAttached = box.ownerDocument.contains(box); |
- var modificationTime = this.metadata_ && |
- this.metadata_.filesystem && |
- this.metadata_.filesystem.modificationTime && |
- this.metadata_.filesystem.modificationTime.getTime(); |
- this.taskId_ = util.loadImage( |
- this.image_, |
- this.thumbnailUrl_, |
- { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH, |
- maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT, |
- cache: true, |
- priority: this.priority_, |
- timestamp: modificationTime }, |
- function() { |
- if (opt_optimizationMode == |
- ThumbnailLoader.OptimizationMode.DISCARD_DETACHED && |
- !box.ownerDocument.contains(box)) { |
- // If the container is not attached, then invalidate the download. |
- return false; |
- } |
- return true; |
- }); |
-}; |
- |
-/** |
- * Cancels loading the current image. |
- */ |
-ThumbnailLoader.prototype.cancel = function() { |
- if (this.taskId_) { |
- this.image_.onload = function() {}; |
- this.image_.onerror = function() {}; |
- util.cancelLoadImage(this.taskId_); |
- this.taskId_ = null; |
- } |
-}; |
- |
-/** |
- * @return {boolean} True if a valid image is loaded. |
- */ |
-ThumbnailLoader.prototype.hasValidImage = function() { |
- return !!(this.image_ && this.image_.width && this.image_.height); |
-}; |
- |
-/** |
- * @return {boolean} True if the image is rotated 90 degrees left or right. |
- * @private |
- */ |
-ThumbnailLoader.prototype.isRotated_ = function() { |
- return this.transform_ && (this.transform_.rotate90 % 2 == 1); |
-}; |
- |
-/** |
- * @return {number} Image width (corrected for rotation). |
- */ |
-ThumbnailLoader.prototype.getWidth = function() { |
- return this.isRotated_() ? this.image_.height : this.image_.width; |
-}; |
- |
-/** |
- * @return {number} Image height (corrected for rotation). |
- */ |
-ThumbnailLoader.prototype.getHeight = function() { |
- return this.isRotated_() ? this.image_.width : this.image_.height; |
-}; |
- |
-/** |
- * Load an image but do not attach it. |
- * |
- * @param {function(boolean)} callback Callback, parameter is true if the image |
- * has loaded successfully or a stock icon has been used. |
- */ |
-ThumbnailLoader.prototype.loadDetachedImage = function(callback) { |
- if (!this.thumbnailUrl_) { |
- callback(true); |
- return; |
- } |
- |
- this.cancel(); |
- this.canvasUpToDate_ = false; |
- this.image_ = new Image(); |
- this.image_.onload = callback.bind(null, true); |
- this.image_.onerror = callback.bind(null, false); |
- |
- // TODO(mtomasz): Smarter calculation of the requested size. |
- var modificationTime = this.metadata_ && |
- this.metadata_.filesystem && |
- this.metadata_.filesystem.modificationTime && |
- this.metadata_.filesystem.modificationTime.getTime(); |
- this.taskId_ = util.loadImage( |
- this.image_, |
- this.thumbnailUrl_, |
- { maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH, |
- maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT, |
- cache: true, |
- priority: this.priority_, |
- timestamp: modificationTime }); |
-}; |
- |
-/** |
- * Renders the thumbnail into either canvas or an image element. |
- * @private |
- */ |
-ThumbnailLoader.prototype.renderMedia_ = function() { |
- if (this.loaderType_ != ThumbnailLoader.LoaderType.CANVAS) |
- return; |
- |
- if (!this.canvas_) |
- this.canvas_ = document.createElement('canvas'); |
- |
- // Copy the image to a canvas if the canvas is outdated. |
- if (!this.canvasUpToDate_) { |
- this.canvas_.width = this.image_.width; |
- this.canvas_.height = this.image_.height; |
- var context = this.canvas_.getContext('2d'); |
- context.drawImage(this.image_, 0, 0); |
- this.canvasUpToDate_ = true; |
- } |
-}; |
- |
-/** |
- * Attach the image to a given element. |
- * @param {Element} container Parent element. |
- * @param {ThumbnailLoader.FillMode} fillMode Fill mode. |
- */ |
-ThumbnailLoader.prototype.attachImage = function(container, fillMode) { |
- if (!this.hasValidImage()) { |
- container.setAttribute('generic-thumbnail', this.mediaType_); |
- return; |
- } |
- |
- this.renderMedia_(); |
- util.applyTransform(container, this.transform_); |
- var attachableMedia = this.loaderType_ == ThumbnailLoader.LoaderType.CANVAS ? |
- this.canvas_ : this.image_; |
- |
- ThumbnailLoader.centerImage_( |
- container, attachableMedia, fillMode, this.isRotated_()); |
- |
- if (attachableMedia.parentNode != container) { |
- container.textContent = ''; |
- container.appendChild(attachableMedia); |
- } |
- |
- if (!this.taskId_) |
- attachableMedia.classList.add('cached'); |
-}; |
- |
-/** |
- * Gets the loaded image. |
- * TODO(mtomasz): Apply transformations. |
- * |
- * @return {Image|HTMLCanvasElement} Either image or a canvas object. |
- */ |
-ThumbnailLoader.prototype.getImage = function() { |
- this.renderMedia_(); |
- return this.loaderType_ == ThumbnailLoader.LoaderType.CANVAS ? this.canvas_ : |
- this.image_; |
-}; |
- |
-/** |
- * Update the image style to fit/fill the container. |
- * |
- * Using webkit center packing does not align the image properly, so we need |
- * to wait until the image loads and its dimensions are known, then manually |
- * position it at the center. |
- * |
- * @param {HTMLElement} box Containing element. |
- * @param {Image|HTMLCanvasElement} img Element containing an image. |
- * @param {ThumbnailLoader.FillMode} fillMode Fill mode. |
- * @param {boolean} rotate True if the image should be rotated 90 degrees. |
- * @private |
- */ |
-ThumbnailLoader.centerImage_ = function(box, img, fillMode, rotate) { |
- var imageWidth = img.width; |
- var imageHeight = img.height; |
- |
- var fractionX; |
- var fractionY; |
- |
- var boxWidth = box.clientWidth; |
- var boxHeight = box.clientHeight; |
- |
- var fill; |
- switch (fillMode) { |
- case ThumbnailLoader.FillMode.FILL: |
- case ThumbnailLoader.FillMode.OVER_FILL: |
- fill = true; |
- break; |
- case ThumbnailLoader.FillMode.FIT: |
- fill = false; |
- break; |
- case ThumbnailLoader.FillMode.AUTO: |
- var imageRatio = imageWidth / imageHeight; |
- var boxRatio = 1.0; |
- if (boxWidth && boxHeight) |
- boxRatio = boxWidth / boxHeight; |
- // Cropped area in percents. |
- var ratioFactor = boxRatio / imageRatio; |
- fill = (ratioFactor >= 1.0 - ThumbnailLoader.AUTO_FILL_THRESHOLD) && |
- (ratioFactor <= 1.0 + ThumbnailLoader.AUTO_FILL_THRESHOLD); |
- break; |
- } |
- |
- if (boxWidth && boxHeight) { |
- // When we know the box size we can position the image correctly even |
- // in a non-square box. |
- var fitScaleX = (rotate ? boxHeight : boxWidth) / imageWidth; |
- var fitScaleY = (rotate ? boxWidth : boxHeight) / imageHeight; |
- |
- var scale = fill ? |
- Math.max(fitScaleX, fitScaleY) : |
- Math.min(fitScaleX, fitScaleY); |
- |
- if (fillMode != ThumbnailLoader.FillMode.OVER_FILL) |
- scale = Math.min(scale, 1); // Never overscale. |
- |
- fractionX = imageWidth * scale / boxWidth; |
- fractionY = imageHeight * scale / boxHeight; |
- } else { |
- // We do not know the box size so we assume it is square. |
- // Compute the image position based only on the image dimensions. |
- // First try vertical fit or horizontal fill. |
- fractionX = imageWidth / imageHeight; |
- fractionY = 1; |
- if ((fractionX < 1) == !!fill) { // Vertical fill or horizontal fit. |
- fractionY = 1 / fractionX; |
- fractionX = 1; |
- } |
- } |
- |
- function percent(fraction) { |
- return (fraction * 100).toFixed(2) + '%'; |
- } |
- |
- img.style.width = percent(fractionX); |
- img.style.height = percent(fractionY); |
- img.style.left = percent((1 - fractionX) / 2); |
- img.style.top = percent((1 - fractionY) / 2); |
-}; |