OLD | NEW |
---|---|
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 * FileManager constructor. | 6 * FileManager constructor. |
7 * | 7 * |
8 * FileManager objects encapsulate the functionality of the file selector | 8 * FileManager objects encapsulate the functionality of the file selector |
9 * dialogs, as well as the full screen file manager application (though the | 9 * dialogs, as well as the full screen file manager application (though the |
10 * latter is not yet implemented). | 10 * latter is not yet implemented). |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 | 48 |
49 // TODO(dgozman): This will be changed to LocaleInfo. | 49 // TODO(dgozman): This will be changed to LocaleInfo. |
50 this.locale_ = new v8Locale(navigator.language); | 50 this.locale_ = new v8Locale(navigator.language); |
51 | 51 |
52 this.initFileSystem_(); | 52 this.initFileSystem_(); |
53 this.initDom_(); | 53 this.initDom_(); |
54 this.initDialogType_(); | 54 this.initDialogType_(); |
55 this.dialogDom_.style.opacity = '1'; | 55 this.dialogDom_.style.opacity = '1'; |
56 } | 56 } |
57 | 57 |
58 /** | |
59 * Maximum delay in milliseconds for updating thumbnails in the bottom panel | |
60 * to mitigate flickering. If images load faster then the delay they replace | |
61 * old images smoothly. On the other hand we don't want to keep old images | |
62 * too long. | |
63 */ | |
64 FileManager.THUMBNAIL_SHOW_DELAY = 100; | |
65 | |
58 FileManager.prototype = { | 66 FileManager.prototype = { |
59 __proto__: cr.EventTarget.prototype | 67 __proto__: cr.EventTarget.prototype |
60 }; | 68 }; |
61 | 69 |
62 // Anonymous "namespace". | 70 // Anonymous "namespace". |
63 (function() { | 71 (function() { |
64 | 72 |
65 // Private variables and helper functions. | 73 // Private variables and helper functions. |
66 | 74 |
67 /** | 75 /** |
(...skipping 2020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2088 }; | 2096 }; |
2089 | 2097 |
2090 if (!selection.indexes.length) { | 2098 if (!selection.indexes.length) { |
2091 this.updateCommonActionButtons_(); | 2099 this.updateCommonActionButtons_(); |
2092 this.updatePreviewPanelVisibility_(); | 2100 this.updatePreviewPanelVisibility_(); |
2093 cr.dispatchSimpleEvent(this, 'selection-summarized'); | 2101 cr.dispatchSimpleEvent(this, 'selection-summarized'); |
2094 return; | 2102 return; |
2095 } | 2103 } |
2096 | 2104 |
2097 this.previewSummary_.textContent = str('COMPUTING_SELECTION'); | 2105 this.previewSummary_.textContent = str('COMPUTING_SELECTION'); |
2098 var thumbnails = this.document_.createDocumentFragment(); | 2106 var thumbnails = []; |
2099 | 2107 |
2100 var pendingFiles = []; | 2108 var pendingFiles = []; |
2101 var thumbnailCount = 0; | 2109 var thumbnailCount = 0; |
2102 var thumbnailLoaded = -1; | 2110 var thumbnailLoaded = -1; |
2103 var forcedShowTimeout = null; | 2111 var forcedShowTimeout = null; |
2104 var self = this; | 2112 var self = this; |
2105 | 2113 |
2106 function showThumbnails() { | 2114 function showThumbnails() { |
2107 if (forcedShowTimeout === null) | 2115 if (forcedShowTimeout === null) |
2108 return; | 2116 return; |
2109 clearTimeout(forcedShowTimeout); | 2117 clearTimeout(forcedShowTimeout); |
2110 forcedShowTimeout = null; | 2118 forcedShowTimeout = null; |
2111 | 2119 |
2112 // Selection could change while images are loading. | 2120 // Selection could change while images are loading. |
2113 if (self.selection == selection) { | 2121 if (self.selection == selection) { |
2114 removeChildren(self.previewThumbnails_); | 2122 removeChildren(self.previewThumbnails_); |
2115 self.previewThumbnails_.appendChild(thumbnails); | 2123 for (var i = 0; i < thumbnails.length; i++) |
2124 self.previewThumbnails_.appendChild(thumbnails[i]); | |
2116 } | 2125 } |
2117 } | 2126 } |
2118 | 2127 |
2119 function onThumbnailLoaded() { | 2128 function onThumbnailLoaded() { |
2120 thumbnailLoaded++; | 2129 thumbnailLoaded++; |
2121 if (thumbnailLoaded == thumbnailCount) | 2130 if (thumbnailLoaded == thumbnailCount) |
2122 showThumbnails(); | 2131 showThumbnails(); |
2123 } | 2132 } |
2124 | 2133 |
2125 for (var i = 0; i < selection.indexes.length; i++) { | 2134 for (var i = 0; i < selection.indexes.length; i++) { |
2126 var entry = this.directoryModel_.getFileList().item(selection.indexes[i]); | 2135 var entry = this.directoryModel_.getFileList().item(selection.indexes[i]); |
2127 if (!entry) | 2136 if (!entry) |
2128 continue; | 2137 continue; |
2129 | 2138 |
2130 selection.entries.push(entry); | 2139 selection.entries.push(entry); |
2131 selection.urls.push(entry.toURL()); | 2140 selection.urls.push(entry.toURL()); |
2132 | 2141 |
2133 if (thumbnailCount < MAX_PREVIEW_THUMBAIL_COUNT) { | 2142 if (thumbnailCount < MAX_PREVIEW_THUMBAIL_COUNT) { |
2134 var box = this.document_.createElement('div'); | 2143 var box = this.document_.createElement('div'); |
2135 box.className = 'thumbnail'; | 2144 box.className = 'thumbnail'; |
2136 function imageLoadCalback(index, box, img, transform) { | 2145 if (thumbnailCount == 0) { |
2137 if (index == 0) | 2146 var zoomed = this.document_.createElement('div'); |
2138 thumbnails.insertBefore(self.renderThumbnailZoom_(img, transform), | 2147 zoomed.hidden = true; |
2139 thumbnails.firstChild); | 2148 thumbnails.push(zoomed); |
2140 onThumbnailLoaded(); | 2149 function onFirstThumbnailLoaded(img, transform) { |
2150 self.decorateThumbnailZoom_(zoomed, img, transform); | |
2151 zoomed.hidden = false; | |
2152 onThumbnailLoaded(); | |
2153 } | |
2154 var thumbnail = this.renderThumbnailBox_(entry, true, | |
2155 onFirstThumbnailLoaded); | |
2156 } else { | |
2157 var thumbnail = this.renderThumbnailBox_(entry, true, | |
2158 onThumbnailLoaded); | |
2141 } | 2159 } |
2142 var thumbnail = this.renderThumbnailBox_(entry, true, | |
2143 imageLoadCalback.bind(null, thumbnailCount, box)); | |
2144 thumbnailCount++; | 2160 thumbnailCount++; |
2145 box.appendChild(thumbnail); | 2161 box.appendChild(thumbnail); |
2146 box.style.zIndex = MAX_PREVIEW_THUMBAIL_COUNT + 1 - i; | 2162 box.style.zIndex = MAX_PREVIEW_THUMBAIL_COUNT + 1 - i; |
2147 box.addEventListener('click', | 2163 box.addEventListener('click', |
2148 this.dispatchDefaultTask_.bind(this, selection)); | 2164 this.dispatchDefaultTask_.bind(this, selection)); |
2149 | 2165 |
2150 thumbnails.appendChild(box); | 2166 thumbnails.push(box); |
2151 } | 2167 } |
2152 | 2168 |
2153 if (selection.iconType == null) { | 2169 if (selection.iconType == null) { |
2154 selection.iconType = FileType.getIcon(entry); | 2170 selection.iconType = FileType.getIcon(entry); |
2155 } else if (selection.iconType != 'unknown') { | 2171 } else if (selection.iconType != 'unknown') { |
2156 var iconType = FileType.getIcon(entry); | 2172 var iconType = FileType.getIcon(entry); |
2157 if (selection.iconType != iconType) | 2173 if (selection.iconType != iconType) |
2158 selection.iconType = 'unknown'; | 2174 selection.iconType = 'unknown'; |
2159 } | 2175 } |
2160 | 2176 |
2161 if (entry.isFile) { | 2177 if (entry.isFile) { |
2162 selection.fileCount += 1; | 2178 selection.fileCount += 1; |
2163 selection.showBytes |= !FileType.isHosted(entry); | 2179 selection.showBytes |= !FileType.isHosted(entry); |
2164 } else { | 2180 } else { |
2165 selection.directoryCount += 1; | 2181 selection.directoryCount += 1; |
2166 } | 2182 } |
2167 selection.totalCount++; | 2183 selection.totalCount++; |
2168 } | 2184 } |
2169 | 2185 |
2170 // Now this.selection is complete. Update buttons. | 2186 // Now this.selection is complete. Update buttons. |
2171 this.updateCommonActionButtons_(); | 2187 this.updateCommonActionButtons_(); |
2172 this.updatePreviewPanelVisibility_(); | 2188 this.updatePreviewPanelVisibility_(); |
2173 forcedShowTimeout = setTimeout(showThumbnails, 100); | 2189 forcedShowTimeout = setTimeout(showThumbnails, |
2190 FileManager.THUMBNAIL_SHOW_DELAY); | |
2174 onThumbnailLoaded(); | 2191 onThumbnailLoaded(); |
2175 | 2192 |
2176 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { | 2193 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { |
2177 // Some internal tasks cannot be defined in terms of file patterns, | 2194 // Some internal tasks cannot be defined in terms of file patterns, |
2178 // so we pass selection to check for them manually. | 2195 // so we pass selection to check for them manually. |
2179 if (selection.directoryCount == 0 && selection.fileCount > 0) { | 2196 if (selection.directoryCount == 0 && selection.fileCount > 0) { |
2180 // Only files, not directories, are supported for external tasks. | 2197 // Only files, not directories, are supported for external tasks. |
2181 chrome.fileBrowserPrivate.getFileTasks( | 2198 chrome.fileBrowserPrivate.getFileTasks( |
2182 selection.urls, | 2199 selection.urls, |
2183 this.onTasksFound_.bind(this, selection)); | 2200 this.onTasksFound_.bind(this, selection)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2218 FileManager.prototype.isSelectionAvailable = function() { | 2235 FileManager.prototype.isSelectionAvailable = function() { |
2219 return !this.isOnGData() || | 2236 return !this.isOnGData() || |
2220 !this.isOffline() || | 2237 !this.isOffline() || |
2221 this.selection.allGDataFilesPresent; | 2238 this.selection.allGDataFilesPresent; |
2222 }; | 2239 }; |
2223 | 2240 |
2224 /** | 2241 /** |
2225 * Creates enlarged image for a bottom pannel thumbnail. | 2242 * Creates enlarged image for a bottom pannel thumbnail. |
2226 * Image's assumed to be just loaded and not inserted into the DOM. | 2243 * Image's assumed to be just loaded and not inserted into the DOM. |
2227 * | 2244 * |
2245 * @param {HTMLElement} largeImageBox DIV element to decorate. | |
2228 * @param {HTMLElement} img Loaded image. | 2246 * @param {HTMLElement} img Loaded image. |
2229 * @param {Object} transform Image transformation description. | 2247 * @param {Object} transform Image transformation description. |
2230 * @return {Element} Created element. | |
2231 */ | 2248 */ |
2232 FileManager.prototype.renderThumbnailZoom_ = function(img, transform) { | 2249 FileManager.prototype.decorateThumbnailZoom_ = function(largeImageBox, |
2250 img, transform) { | |
2233 var width = img.width; | 2251 var width = img.width; |
2234 var height = img.height; | 2252 var height = img.height; |
2235 var THUMBNAIL_SIZE = 45; | 2253 var THUMBNAIL_SIZE = 45; |
2236 | 2254 |
2237 if (width < THUMBNAIL_SIZE * 2 && height < THUMBNAIL_SIZE * 2) | 2255 if (width < THUMBNAIL_SIZE * 2 && height < THUMBNAIL_SIZE * 2) |
2238 return; | 2256 return; |
Vladislav Kaznacheev
2012/05/18 06:58:57
if we return here the the DIV will be empty. Will
SeRya
2012/05/18 09:19:37
It doesn't show up. However thumbnails used to hid
| |
2239 | 2257 |
2240 var scale = Math.min(1, | 2258 var scale = Math.min(1, |
2241 IMAGE_HOVER_PREVIEW_SIZE / Math.max(width, height)); | 2259 IMAGE_HOVER_PREVIEW_SIZE / Math.max(width, height)); |
2242 | 2260 |
2243 var imageWidth = Math.round(width * scale); | 2261 var imageWidth = Math.round(width * scale); |
2244 var imageHeight = Math.round(height * scale); | 2262 var imageHeight = Math.round(height * scale); |
2245 | 2263 |
2246 var largeImage = this.document_.createElement('img'); | 2264 var largeImage = this.document_.createElement('img'); |
2247 if (scale < 0.3) { | 2265 if (scale < 0.3) { |
2248 // Scaling large images kills animation. Downscale it in advance. | 2266 // Scaling large images kills animation. Downscale it in advance. |
2249 | 2267 |
2250 // Canvas scales images with liner interpolation. Make a larger | 2268 // Canvas scales images with liner interpolation. Make a larger |
2251 // image (but small enough to not kill animation) and let IMG | 2269 // image (but small enough to not kill animation) and let IMG |
2252 // scale it smoothly. | 2270 // scale it smoothly. |
2253 var INTERMEDIATE_SCALE = 3; | 2271 var INTERMEDIATE_SCALE = 3; |
2254 var canvas = this.document_.createElement('canvas'); | 2272 var canvas = this.document_.createElement('canvas'); |
2255 canvas.width = imageWidth * INTERMEDIATE_SCALE; | 2273 canvas.width = imageWidth * INTERMEDIATE_SCALE; |
2256 canvas.height = imageHeight * INTERMEDIATE_SCALE; | 2274 canvas.height = imageHeight * INTERMEDIATE_SCALE; |
2257 var ctx = canvas.getContext('2d'); | 2275 var ctx = canvas.getContext('2d'); |
2258 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | 2276 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); |
2259 // Using bigger than default compression reduces image size by | 2277 // Using bigger than default compression reduces image size by |
2260 // several times. Quality degradation compensated by greater resolution. | 2278 // several times. Quality degradation compensated by greater resolution. |
2261 largeImage.src = canvas.toDataURL('image/jpeg', 0.6); | 2279 largeImage.src = canvas.toDataURL('image/jpeg', 0.6); |
2262 } else { | 2280 } else { |
2263 largeImage.src = img.src; | 2281 largeImage.src = img.src; |
2264 } | 2282 } |
2265 var largeImageBox = this.document_.createElement('div'); | |
2266 largeImageBox.className = 'popup'; | 2283 largeImageBox.className = 'popup'; |
2267 | 2284 |
2268 var boxWidth = Math.max(THUMBNAIL_SIZE, imageWidth); | 2285 var boxWidth = Math.max(THUMBNAIL_SIZE, imageWidth); |
2269 var boxHeight = Math.max(THUMBNAIL_SIZE, imageHeight); | 2286 var boxHeight = Math.max(THUMBNAIL_SIZE, imageHeight); |
2270 | 2287 |
2271 if (transform && transform.rotate90 % 2 == 1) { | 2288 if (transform && transform.rotate90 % 2 == 1) { |
2272 var t = boxWidth; | 2289 var t = boxWidth; |
2273 boxWidth = boxHeight; | 2290 boxWidth = boxHeight; |
2274 boxHeight = t; | 2291 boxHeight = t; |
2275 } | 2292 } |
2276 | 2293 |
2277 var style = largeImageBox.style; | 2294 var style = largeImageBox.style; |
2278 style.width = boxWidth + 'px'; | 2295 style.width = boxWidth + 'px'; |
2279 style.height = boxHeight + 'px'; | 2296 style.height = boxHeight + 'px'; |
2280 style.top = (-boxHeight + THUMBNAIL_SIZE) + 'px'; | 2297 style.top = (-boxHeight + THUMBNAIL_SIZE) + 'px'; |
2281 | 2298 |
2282 var style = largeImage.style; | 2299 var style = largeImage.style; |
2283 style.width = imageWidth + 'px'; | 2300 style.width = imageWidth + 'px'; |
2284 style.height = imageHeight + 'px'; | 2301 style.height = imageHeight + 'px'; |
2285 style.left = (boxWidth - imageWidth) / 2 + 'px'; | 2302 style.left = (boxWidth - imageWidth) / 2 + 'px'; |
2286 style.top = (boxHeight - imageHeight) / 2 + 'px'; | 2303 style.top = (boxHeight - imageHeight) / 2 + 'px'; |
2287 style.position = 'relative'; | 2304 style.position = 'relative'; |
2288 | 2305 |
2289 util.applyTransform(largeImage, transform); | 2306 util.applyTransform(largeImage, transform); |
2290 | 2307 |
2291 largeImageBox.appendChild(largeImage); | 2308 largeImageBox.appendChild(largeImage); |
2292 largeImageBox.style.zIndex = 1000; | 2309 largeImageBox.style.zIndex = 1000; |
2293 return largeImageBox; | 2310 return largeImageBox; |
Vladislav Kaznacheev
2012/05/18 06:59:35
return is not required anymore
SeRya
2012/05/18 09:19:37
Done.
| |
2294 }; | 2311 }; |
2295 | 2312 |
2296 FileManager.prototype.updatePreviewPanelVisibility_ = function() { | 2313 FileManager.prototype.updatePreviewPanelVisibility_ = function() { |
2297 var panel = this.previewPanel_; | 2314 var panel = this.previewPanel_; |
2298 var state = panel.getAttribute('visibility'); | 2315 var state = panel.getAttribute('visibility'); |
2299 var mustBeVisible = (this.selection.totalCount > 0); | 2316 var mustBeVisible = (this.selection.totalCount > 0); |
2300 var self = this; | 2317 var self = this; |
2301 | 2318 |
2302 switch (state) { | 2319 switch (state) { |
2303 case 'visible': | 2320 case 'visible': |
(...skipping 2322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4626 | 4643 |
4627 function closeBanner() { | 4644 function closeBanner() { |
4628 self.cleanupGDataWelcome_(); | 4645 self.cleanupGDataWelcome_(); |
4629 // Stop showing the welcome banner. | 4646 // Stop showing the welcome banner. |
4630 localStorage[WELCOME_HEADER_COUNTER_KEY] = WELCOME_HEADER_COUNTER_LIMIT; | 4647 localStorage[WELCOME_HEADER_COUNTER_KEY] = WELCOME_HEADER_COUNTER_LIMIT; |
4631 } | 4648 } |
4632 | 4649 |
4633 return maybeShowBanner; | 4650 return maybeShowBanner; |
4634 }; | 4651 }; |
4635 })(); | 4652 })(); |
OLD | NEW |