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 'use strict'; | 5 'use strict'; |
6 | 6 |
7 util.addPageLoadHandler(function() { | 7 util.addPageLoadHandler(function() { |
8 if (!location.hash) | 8 if (!location.hash) |
9 return; | 9 return; |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 * @param {boolean=} opt_exiting True if the app is exiting. | 28 * @param {boolean=} opt_exiting True if the app is exiting. |
29 */ | 29 */ |
30 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting) } | 30 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting) } |
31 | 31 |
32 /** | 32 /** |
33 * Gallery for viewing and editing image files. | 33 * Gallery for viewing and editing image files. |
34 * | 34 * |
35 * @param {Object} context Object containing the following: | 35 * @param {Object} context Object containing the following: |
36 * {function(string)} onNameChange Called every time a selected | 36 * {function(string)} onNameChange Called every time a selected |
37 * item name changes (on rename and on selection change). | 37 * item name changes (on rename and on selection change). |
38 * {function} onClose | 38 * {function(string)} onBack |
| 39 * {function()} onClose |
| 40 * {function()} onMaximize |
39 * {MetadataCache} metadataCache | 41 * {MetadataCache} metadataCache |
40 * {Array.<Object>} shareActions | 42 * {Array.<Object>} shareActions |
41 * {string} readonlyDirName Directory name for readonly warning or null. | 43 * {string} readonlyDirName Directory name for readonly warning or null. |
42 * {DirEntry} saveDirEntry Directory to save to. | 44 * {DirEntry} saveDirEntry Directory to save to. |
43 * {function(string)} displayStringFunction. | 45 * {function(string)} displayStringFunction. |
44 * @class | 46 * @class |
45 * @constructor | 47 * @constructor |
46 */ | 48 */ |
47 function Gallery(context) { | 49 function Gallery(context) { |
48 this.container_ = document.querySelector('.gallery'); | 50 this.container_ = document.querySelector('.gallery'); |
(...skipping 28 matching lines...) Expand all Loading... |
77 * @param {Array.<string>} urls Array of urls. | 79 * @param {Array.<string>} urls Array of urls. |
78 * @param {Array.<string>} selectedUrls Array of selected urls. | 80 * @param {Array.<string>} selectedUrls Array of selected urls. |
79 */ | 81 */ |
80 Gallery.open = function(context, urls, selectedUrls) { | 82 Gallery.open = function(context, urls, selectedUrls) { |
81 Gallery.instance = new Gallery(context); | 83 Gallery.instance = new Gallery(context); |
82 Gallery.instance.load(urls, selectedUrls); | 84 Gallery.instance.load(urls, selectedUrls); |
83 }; | 85 }; |
84 | 86 |
85 /** | 87 /** |
86 * Create a Gallery object in a tab. | 88 * Create a Gallery object in a tab. |
| 89 * TODO(mtomasz): Remove it after dropping support for Files.app V1. |
| 90 * |
87 * @param {string} path File system path to a selected file. | 91 * @param {string} path File system path to a selected file. |
88 * @param {Object} pageState Page state object. | 92 * @param {Object} pageState Page state object. |
89 * @param {function=} opt_callback Called when gallery object is constructed. | 93 * @param {function=} opt_callback Called when gallery object is constructed. |
90 */ | 94 */ |
91 Gallery.openStandalone = function(path, pageState, opt_callback) { | 95 Gallery.openStandalone = function(path, pageState, opt_callback) { |
92 ImageUtil.metrics = metrics; | 96 ImageUtil.metrics = metrics; |
93 | 97 |
94 var currentDir; | 98 var currentDir; |
95 var urls = []; | 99 var urls = []; |
96 var selectedUrls = []; | 100 var selectedUrls = []; |
97 | 101 |
98 Gallery.getFileBrowserPrivate().requestLocalFileSystem(function(filesystem) { | 102 Gallery.getFileBrowserPrivate().requestLocalFileSystem(function(filesystem) { |
99 // If the path points to the directory scan it. | 103 // If the path points to the directory scan it. |
100 filesystem.root.getDirectory(path, {create: false}, scanDirectory, | 104 filesystem.root.getDirectory(path, {create: false}, scanDirectory, |
101 function() { | 105 function() { |
102 // Try to scan the parent directory. | 106 // Try to scan the parent directory. |
103 var pathParts = path.split('/'); | 107 var pathParts = path.split('/'); |
104 pathParts.pop(); | 108 pathParts.pop(); |
105 var parentPath = pathParts.join('/'); | 109 var parentPath = pathParts.join('/'); |
106 filesystem.root.getDirectory(parentPath, {create: false}, | 110 filesystem.root.getDirectory(parentPath, {create: false}, |
107 scanDirectory, open /* no data, just display an error */); | 111 scanDirectory, open /* no data, just display an error */); |
108 }); | 112 }); |
109 }); | 113 }); |
110 | 114 |
111 function scanDirectory(dirEntry) { | 115 var scanDirectory = function(dirEntry) { |
112 currentDir = dirEntry; | 116 currentDir = dirEntry; |
113 util.forEachDirEntry(currentDir, function(entry) { | 117 util.forEachDirEntry(currentDir, function(entry) { |
114 if (entry == null) { | 118 if (entry == null) { |
115 open(); | 119 open(); |
116 } else if (FileType.isImageOrVideo(entry)) { | 120 } else if (FileType.isImageOrVideo(entry)) { |
117 var url = entry.toURL(); | 121 var url = entry.toURL(); |
118 urls.push(url); | 122 urls.push(url); |
119 if (entry.fullPath == path) | 123 if (entry.fullPath == path) |
120 selectedUrls = [url]; | 124 selectedUrls = [url]; |
121 } | 125 } |
122 }); | 126 }); |
123 } | 127 }; |
124 | 128 |
125 function onClose() { | 129 var onBack = function() { |
126 // Exiting to the Files app seems arbitrary. Consider closing the tab. | 130 // Exiting to the Files app seems arbitrary. Consider closing the tab. |
127 document.location = 'main.html?' + | 131 document.location = 'main.html?' + |
128 JSON.stringify({defaultPath: document.location.hash.substr(1)}); | 132 JSON.stringify({defaultPath: document.location.hash.substr(1)}); |
129 } | 133 }; |
| 134 |
| 135 var onClose = function() { |
| 136 window.close(); |
| 137 }; |
| 138 |
| 139 var onMaximize = function() { |
| 140 var appWindow = chrome.app.window.current(); |
| 141 if (appWindow.isMaximized()) |
| 142 appWindow.restore(); |
| 143 else |
| 144 appWindow.maximize(); |
| 145 }; |
130 | 146 |
131 function open() { | 147 function open() { |
132 urls.sort(); | 148 urls.sort(); |
133 Gallery.getFileBrowserPrivate().getStrings(function(strings) { | 149 Gallery.getFileBrowserPrivate().getStrings(function(strings) { |
134 loadTimeData.data = strings; | 150 loadTimeData.data = strings; |
135 var context = { | 151 var context = { |
136 readonlyDirName: null, | 152 readonlyDirName: null, |
137 curDirEntry: currentDir, | 153 curDirEntry: currentDir, |
138 saveDirEntry: null, | 154 saveDirEntry: null, |
139 metadataCache: MetadataCache.createFull(), | 155 metadataCache: MetadataCache.createFull(), |
140 pageState: pageState, | 156 pageState: pageState, |
| 157 onBack: onBack, |
141 onClose: onClose, | 158 onClose: onClose, |
| 159 onMaximize: onMaximize, |
142 displayStringFunction: strf | 160 displayStringFunction: strf |
143 }; | 161 }; |
144 Gallery.open(context, urls, selectedUrls); | 162 Gallery.open(context, urls, selectedUrls); |
145 if (opt_callback) opt_callback(); | 163 if (opt_callback) opt_callback(); |
146 }); | 164 }); |
147 } | 165 } |
148 }; | 166 }; |
149 | 167 |
150 /** | 168 /** |
151 * Tools fade-out timeout im milliseconds. | 169 * Tools fade-out timeout im milliseconds. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 | 226 |
209 /** | 227 /** |
210 * Closes gallery when a volume containing the selected item is unmounted. | 228 * Closes gallery when a volume containing the selected item is unmounted. |
211 * @param {Event} event The unmount event. | 229 * @param {Event} event The unmount event. |
212 * @private | 230 * @private |
213 */ | 231 */ |
214 Gallery.prototype.onExternallyUnmounted_ = function(event) { | 232 Gallery.prototype.onExternallyUnmounted_ = function(event) { |
215 if (!this.selectedItemFilesystemPath_) | 233 if (!this.selectedItemFilesystemPath_) |
216 return; | 234 return; |
217 if (this.selectedItemFilesystemPath_.indexOf(event.mountPath) == 0) | 235 if (this.selectedItemFilesystemPath_.indexOf(event.mountPath) == 0) |
218 this.onClose_(); | 236 this.onBack_(); |
219 }; | 237 }; |
220 | 238 |
221 /** | 239 /** |
222 * Beforeunload handler. | 240 * Beforeunload handler. |
223 * @return {string?} User-visible message on null if it is OK to close. | 241 * @return {string?} User-visible message on null if it is OK to close. |
224 */ | 242 */ |
225 Gallery.prototype.onBeforeUnload = function() { | 243 Gallery.prototype.onBeforeUnload = function() { |
226 return this.slideMode_.onBeforeUnload(); | 244 return this.slideMode_.onBeforeUnload(); |
227 }; | 245 }; |
228 | 246 |
229 /** | 247 /** |
230 * Unload the Gallery. | 248 * Unload the Gallery. |
231 * @param {boolean} exiting True if the app is exiting. | 249 * @param {boolean} exiting True if the app is exiting. |
232 */ | 250 */ |
233 Gallery.prototype.onUnload = function(exiting) { | 251 Gallery.prototype.onUnload = function(exiting) { |
234 if (!this.context_.searchResults) { | 252 if (!this.context_.searchResults) { |
235 this.metadataCache_.removeObserver(this.thumbnailObserverId_); | 253 this.metadataCache_.removeObserver(this.thumbnailObserverId_); |
236 } | 254 } |
237 this.slideMode_.onUnload(exiting); | 255 this.slideMode_.onUnload(exiting); |
238 }; | 256 }; |
239 | 257 |
240 /** | 258 /** |
241 * Initializes DOM UI | 259 * Initializes DOM UI |
242 * @private | 260 * @private |
243 */ | 261 */ |
244 Gallery.prototype.initDom_ = function() { | 262 Gallery.prototype.initDom_ = function() { |
245 var content = util.createChild(this.container_, 'content'); | 263 var content = util.createChild(this.container_, 'content'); |
246 content.addEventListener('click', this.onContentClick_.bind(this)); | 264 content.addEventListener('click', this.onContentClick_.bind(this)); |
247 | 265 |
248 var closeButton = util.createChild(this.container_, 'close tool dimmable'); | |
249 util.createChild(closeButton); | |
250 closeButton.addEventListener('click', this.onClose_.bind(this)); | |
251 | |
252 this.header_ = util.createChild(this.container_, 'header tool dimmable'); | 266 this.header_ = util.createChild(this.container_, 'header tool dimmable'); |
253 this.toolbar_ = util.createChild(this.container_, 'toolbar tool dimmable'); | 267 this.toolbar_ = util.createChild(this.container_, 'toolbar tool dimmable'); |
254 | 268 |
| 269 var backButton = util.createChild(this.container_, |
| 270 'back-button tool dimmable'); |
| 271 util.createChild(backButton); |
| 272 backButton.addEventListener('click', this.onBack_.bind(this)); |
| 273 |
| 274 if (util.platform.newUI()) { |
| 275 var maximizeButton = util.createChild(this.header_, |
| 276 'maximize-button tool dimmable', |
| 277 'button'); |
| 278 maximizeButton.addEventListener('click', this.onMaximize_.bind(this)); |
| 279 |
| 280 var closeButton = util.createChild(this.header_, |
| 281 'close-button tool dimmable', |
| 282 'button'); |
| 283 closeButton.addEventListener('click', this.onClose_.bind(this)); |
| 284 } |
| 285 |
255 this.filenameSpacer_ = util.createChild(this.toolbar_, 'filename-spacer'); | 286 this.filenameSpacer_ = util.createChild(this.toolbar_, 'filename-spacer'); |
256 | |
257 this.filenameEdit_ = util.createChild(this.filenameSpacer_, | 287 this.filenameEdit_ = util.createChild(this.filenameSpacer_, |
258 'namebox', 'input'); | 288 'namebox', 'input'); |
259 | 289 |
260 this.filenameEdit_.setAttribute('type', 'text'); | 290 this.filenameEdit_.setAttribute('type', 'text'); |
261 this.filenameEdit_.addEventListener('blur', | 291 this.filenameEdit_.addEventListener('blur', |
262 this.onFilenameEditBlur_.bind(this)); | 292 this.onFilenameEditBlur_.bind(this)); |
263 | 293 |
264 this.filenameEdit_.addEventListener('focus', | 294 this.filenameEdit_.addEventListener('focus', |
265 this.onFilenameFocus_.bind(this)); | 295 this.onFilenameFocus_.bind(this)); |
266 | 296 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 /* TODO: consider nice blow-up animation for the first image */ | 416 /* TODO: consider nice blow-up animation for the first image */ |
387 this.slideMode_.enter(null, function() { | 417 this.slideMode_.enter(null, function() { |
388 // Flash the toolbar briefly to show it is there. | 418 // Flash the toolbar briefly to show it is there. |
389 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT); | 419 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT); |
390 }.bind(this), | 420 }.bind(this), |
391 maybeLoadMosaic); | 421 maybeLoadMosaic); |
392 } | 422 } |
393 }; | 423 }; |
394 | 424 |
395 /** | 425 /** |
396 * Close the Gallery. | 426 * Close the Gallery and go to Files.app. |
397 * @private | 427 * @private |
398 */ | 428 */ |
399 Gallery.prototype.close_ = function() { | 429 Gallery.prototype.back_ = function() { |
400 if (util.isFullScreen()) { | 430 if (util.isFullScreen()) { |
401 util.toggleFullScreen(this.document_, | 431 util.toggleFullScreen(this.document_, |
402 false); // Leave the full screen mode. | 432 false); // Leave the full screen mode. |
403 } | 433 } |
404 this.context_.onClose(this.getSelectedUrls()); | 434 this.context_.onBack(this.getSelectedUrls()); |
405 }; | 435 }; |
406 | 436 |
407 /** | 437 /** |
408 * Handle user's 'Close' action (Escape or a click on the X icon). | 438 * Handle user's 'Back' action (Escape or a click on the X icon). |
| 439 * @private |
| 440 */ |
| 441 Gallery.prototype.onBack_ = function() { |
| 442 this.executeWhenReady(this.back_.bind(this)); |
| 443 }; |
| 444 |
| 445 /** |
| 446 * Handle user's 'Close' action. |
409 * @private | 447 * @private |
410 */ | 448 */ |
411 Gallery.prototype.onClose_ = function() { | 449 Gallery.prototype.onClose_ = function() { |
412 this.executeWhenReady(this.close_.bind(this)); | 450 this.executeWhenReady(this.context_.onClose); |
| 451 }; |
| 452 |
| 453 /** |
| 454 * Handle user's 'Maximize' action (Escape or a click on the X icon). |
| 455 * @private |
| 456 */ |
| 457 Gallery.prototype.onMaximize_ = function() { |
| 458 this.executeWhenReady(this.context_.onMaximize); |
413 }; | 459 }; |
414 | 460 |
415 /** | 461 /** |
416 * Execute a function when the editor is done with the modifications. | 462 * Execute a function when the editor is done with the modifications. |
417 * @param {function} callback Function to execute. | 463 * @param {function} callback Function to execute. |
418 */ | 464 */ |
419 Gallery.prototype.executeWhenReady = function(callback) { | 465 Gallery.prototype.executeWhenReady = function(callback) { |
420 this.currentMode_.executeWhenReady(callback); | 466 this.currentMode_.executeWhenReady(callback); |
421 }; | 467 }; |
422 | 468 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 | 692 |
647 switch (util.getKeyModifiers(event) + event.keyIdentifier) { | 693 switch (util.getKeyModifiers(event) + event.keyIdentifier) { |
648 case 'U+0008': // Backspace. | 694 case 'U+0008': // Backspace. |
649 // The default handler would call history.back and close the Gallery. | 695 // The default handler would call history.back and close the Gallery. |
650 event.preventDefault(); | 696 event.preventDefault(); |
651 break; | 697 break; |
652 | 698 |
653 case 'U+001B': // Escape | 699 case 'U+001B': // Escape |
654 // Swallow Esc if it closed the Share menu, otherwise close the Gallery. | 700 // Swallow Esc if it closed the Share menu, otherwise close the Gallery. |
655 if (!wasSharing) | 701 if (!wasSharing) |
656 this.onClose_(); | 702 this.onBack_(); |
657 break; | 703 break; |
658 | 704 |
659 case 'U+004D': // 'm' switches between Slide and Mosaic mode. | 705 case 'U+004D': // 'm' switches between Slide and Mosaic mode. |
660 this.toggleMode_(null, event); | 706 this.toggleMode_(null, event); |
661 break; | 707 break; |
662 | 708 |
663 | 709 |
664 case 'U+0056': // 'v' | 710 case 'U+0056': // 'v' |
665 this.slideMode_.startSlideshow(SlideMode.SLIDESHOW_INTERVAL_FIRST, event); | 711 this.slideMode_.startSlideshow(SlideMode.SLIDESHOW_INTERVAL_FIRST, event); |
666 return; | 712 return; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 Gallery.prototype.updateThumbnails_ = function() { | 947 Gallery.prototype.updateThumbnails_ = function() { |
902 if (this.currentMode_ == this.slideMode_) | 948 if (this.currentMode_ == this.slideMode_) |
903 this.slideMode_.updateThumbnails(); | 949 this.slideMode_.updateThumbnails(); |
904 | 950 |
905 if (this.mosaicMode_) { | 951 if (this.mosaicMode_) { |
906 var mosaic = this.mosaicMode_.getMosaic(); | 952 var mosaic = this.mosaicMode_.getMosaic(); |
907 if (mosaic.isInitialized()) | 953 if (mosaic.isInitialized()) |
908 mosaic.reload(); | 954 mosaic.reload(); |
909 } | 955 } |
910 }; | 956 }; |
OLD | NEW |