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

Side by Side Diff: ui/file_manager/gallery/js/gallery.js

Issue 801533006: Add type annotations to gallery/js/gallery.js. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed unnecessary annotations. Created 6 years 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 * Called from the main frame when unloading. 6 * Called from the main frame when unloading.
7 * @param {boolean=} opt_exiting True if the app is exiting. 7 * @param {boolean=} opt_exiting True if the app is exiting.
8 */ 8 */
9 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); } 9 function unload(opt_exiting) { gallery.onUnload(opt_exiting); }
10 10
11 /** 11 /**
12 * Overrided metadata worker's path. 12 * Overrided metadata worker's path.
13 * @type {string} 13 * @type {string}
fukino 2014/12/12 15:15:25 cannot this be const?
yawano 2014/12/15 01:45:24 Added reply at ContentProvider.WORKER_SCRIPT of me
14 * @const
15 */ 14 */
16 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; 15 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js';
17 16
18 /** 17 /**
19 * Data model for gallery. 18 * Data model for gallery.
20 * 19 *
21 * @param {MetadataCache} metadataCache Metadata cache. 20 * @param {!MetadataCache} metadataCache Metadata cache.
22 * @constructor 21 * @constructor
23 * @extends {cr.ui.ArrayDataModel} 22 * @extends {cr.ui.ArrayDataModel}
24 */ 23 */
25 function GalleryDataModel(metadataCache) { 24 function GalleryDataModel(metadataCache) {
26 cr.ui.ArrayDataModel.call(this, []); 25 cr.ui.ArrayDataModel.call(this, []);
27 26
28 /** 27 /**
29 * Metadata cache. 28 * Metadata cache.
30 * @type {MetadataCache} 29 * @type {!MetadataCache}
31 * @private 30 * @private
32 */ 31 */
33 this.metadataCache_ = metadataCache; 32 this.metadataCache_ = metadataCache;
34 33
35 /** 34 /**
36 * Directory where the image is saved if the image is located in a read-only 35 * Directory where the image is saved if the image is located in a read-only
37 * volume. 36 * volume.
38 * @type {DirectoryEntry} 37 * @type {DirectoryEntry}
39 */ 38 */
40 this.fallbackSaveDirectory = null; 39 this.fallbackSaveDirectory = null;
(...skipping 15 matching lines...) Expand all
56 */ 55 */
57 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5; 56 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5;
58 57
59 GalleryDataModel.prototype = { 58 GalleryDataModel.prototype = {
60 __proto__: cr.ui.ArrayDataModel.prototype 59 __proto__: cr.ui.ArrayDataModel.prototype
61 }; 60 };
62 61
63 /** 62 /**
64 * Saves new image. 63 * Saves new image.
65 * 64 *
66 * @param {VolumeManager} volumeManager Volume manager instance. 65 * @param {!VolumeManager} volumeManager Volume manager instance.
67 * @param {Gallery.Item} item Original gallery item. 66 * @param {!Gallery.Item} item Original gallery item.
68 * @param {HTMLCanvasElement} canvas Canvas containing new image. 67 * @param {!HTMLCanvasElement} canvas Canvas containing new image.
69 * @param {boolean} overwrite Whether to overwrite the image to the item or not. 68 * @param {boolean} overwrite Whether to overwrite the image to the item or not.
70 * @return {Promise} Promise to be fulfilled with when the operation completes. 69 * @return {!Promise} Promise to be fulfilled with when the operation completes.
71 */ 70 */
72 GalleryDataModel.prototype.saveItem = function( 71 GalleryDataModel.prototype.saveItem = function(
73 volumeManager, item, canvas, overwrite) { 72 volumeManager, item, canvas, overwrite) {
74 var oldEntry = item.getEntry(); 73 var oldEntry = item.getEntry();
75 var oldMetadata = item.getMetadata(); 74 var oldMetadata = item.getMetadata();
76 var oldLocationInfo = item.getLocationInfo(); 75 var oldLocationInfo = item.getLocationInfo();
77 var metadataEncoder = ImageEncoder.encodeMetadata( 76 var metadataEncoder = ImageEncoder.encodeMetadata(
78 item.getMetadata(), canvas, 1 /* quality */); 77 item.getMetadata(), canvas, 1 /* quality */);
79 var newMetadata = ContentProvider.ConvertContentMetadata( 78 var newMetadata = ContentProvider.ConvertContentMetadata(
80 metadataEncoder.getMetadata(), 79 metadataEncoder.getMetadata(),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 this.splice(this.indexOf(item) + 1, 0, anotherItem); 129 this.splice(this.indexOf(item) + 1, 0, anotherItem);
131 } 130 }
132 131
133 fulfill(); 132 fulfill();
134 }.bind(this)); 133 }.bind(this));
135 }.bind(this)); 134 }.bind(this));
136 }; 135 };
137 136
138 /** 137 /**
139 * Evicts image caches in the items. 138 * Evicts image caches in the items.
140 * @param {Gallery.Item} currentSelectedItem Current selected item.
141 */ 139 */
142 GalleryDataModel.prototype.evictCache = function(currentSelectedItem) { 140 GalleryDataModel.prototype.evictCache = function() {
143 // Sort the item by the last accessed date. 141 // Sort the item by the last accessed date.
144 var sorted = this.slice().sort(function(a, b) { 142 var sorted = this.slice().sort(function(a, b) {
145 return b.getLastAccessedDate() - a.getLastAccessedDate(); 143 return b.getLastAccessedDate() - a.getLastAccessedDate();
146 }); 144 });
147 145
148 // Evict caches. 146 // Evict caches.
149 var contentCacheCount = 0; 147 var contentCacheCount = 0;
150 var screenCacheCount = 0; 148 var screenCacheCount = 0;
151 for (var i = 0; i < sorted.length; i++) { 149 for (var i = 0; i < sorted.length; i++) {
152 if (sorted[i].contentImage) { 150 if (sorted[i].contentImage) {
(...skipping 22 matching lines...) Expand all
175 } 173 }
176 } 174 }
177 }; 175 };
178 176
179 /** 177 /**
180 * Gallery for viewing and editing image files. 178 * Gallery for viewing and editing image files.
181 * 179 *
182 * @param {!VolumeManager} volumeManager The VolumeManager instance of the 180 * @param {!VolumeManager} volumeManager The VolumeManager instance of the
183 * system. 181 * system.
184 * @constructor 182 * @constructor
183 * @struct
185 */ 184 */
186 function Gallery(volumeManager) { 185 function Gallery(volumeManager) {
186 /**
187 * @type {{appWindow: chrome.app.window.AppWindow, onClose: function(),
188 * onMaximize: function(), onMinimize: function(),
189 * onAppRegionChanged: function(), metadataCache: MetadataCache,
190 * readonlyDirName: string, displayStringFunction: function(),
191 * loadTimeData: Object, curDirEntry: Entry, searchResults: *}}
192 * @private
193 *
194 * TODO(yawano): curDirEntry and searchResults seem not to be used.
195 * Investigate them and remove them if possible.
196 */
187 this.context_ = { 197 this.context_ = {
188 appWindow: chrome.app.window.current(), 198 appWindow: chrome.app.window.current(),
189 onClose: function() { close(); }, 199 onClose: function() { window.close(); },
190 onMaximize: function() { 200 onMaximize: function() {
191 var appWindow = chrome.app.window.current(); 201 var appWindow = chrome.app.window.current();
192 if (appWindow.isMaximized()) 202 if (appWindow.isMaximized())
193 appWindow.restore(); 203 appWindow.restore();
194 else 204 else
195 appWindow.maximize(); 205 appWindow.maximize();
196 }, 206 },
197 onMinimize: function() { chrome.app.window.current().minimize(); }, 207 onMinimize: function() { chrome.app.window.current().minimize(); },
198 onAppRegionChanged: function() {}, 208 onAppRegionChanged: function() {},
199 metadataCache: MetadataCache.createFull(volumeManager), 209 metadataCache: MetadataCache.createFull(volumeManager),
200 readonlyDirName: '', 210 readonlyDirName: '',
201 displayStringFunction: function() { return ''; }, 211 displayStringFunction: function() { return ''; },
202 loadTimeData: {} 212 loadTimeData: {},
213 curDirEntry: null,
214 searchResults: null
203 }; 215 };
204 this.container_ = document.querySelector('.gallery'); 216 this.container_ = queryRequiredElement(document, '.gallery');
205 this.document_ = document; 217 this.document_ = document;
206 this.metadataCache_ = this.context_.metadataCache; 218 this.metadataCache_ = this.context_.metadataCache;
207 this.volumeManager_ = volumeManager; 219 this.volumeManager_ = volumeManager;
208 this.selectedEntry_ = null; 220 this.selectedEntry_ = null;
209 this.metadataCacheObserverId_ = null; 221 this.metadataCacheObserverId_ = null;
210 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this); 222 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this);
211 223
212 this.dataModel_ = new GalleryDataModel( 224 this.dataModel_ = new GalleryDataModel(
213 this.context_.metadataCache); 225 this.context_.metadataCache);
214 var downloadVolumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo( 226 var downloadVolumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo(
215 VolumeManagerCommon.VolumeType.DOWNLOADS); 227 VolumeManagerCommon.VolumeType.DOWNLOADS);
216 downloadVolumeInfo.resolveDisplayRoot().then(function(entry) { 228 downloadVolumeInfo.resolveDisplayRoot().then(function(entry) {
217 this.dataModel_.fallbackSaveDirectory = entry; 229 this.dataModel_.fallbackSaveDirectory = entry;
218 }.bind(this)).catch(function(error) { 230 }.bind(this)).catch(function(error) {
219 console.error( 231 console.error(
220 'Failed to obtain the fallback directory: ' + (error.stack || error)); 232 'Failed to obtain the fallback directory: ' + (error.stack || error));
221 }); 233 });
222 this.selectionModel_ = new cr.ui.ListSelectionModel(); 234 this.selectionModel_ = new cr.ui.ListSelectionModel();
223 235
224 this.initDom_(); 236 /**
225 this.initListeners_(); 237 * @type {(SlideMode|MosaicMode)}
226 } 238 * @private
239 */
240 this.currentMode_ = null;
227 241
228 /** 242 /**
229 * Gallery extends cr.EventTarget. 243 * @type {boolean}
230 */ 244 * @private
231 Gallery.prototype.__proto__ = cr.EventTarget.prototype; 245 */
246 this.changingMode_ = false;
232 247
233 /** 248 // -----------------------------------------------------------------
234 * Tools fade-out timeout in milliseconds. 249 // Initializes the UI.
235 * @const
236 * @type {number}
237 */
238 Gallery.FADE_TIMEOUT = 2000;
239 250
240 /**
241 * First time tools fade-out timeout in milliseconds.
242 * @const
243 * @type {number}
244 */
245 Gallery.FIRST_FADE_TIMEOUT = 1000;
246
247 /**
248 * Time until mosaic is initialized in the background. Used to make gallery
249 * in the slide mode load faster. In milliseconds.
250 * @const
251 * @type {number}
252 */
253 Gallery.MOSAIC_BACKGROUND_INIT_DELAY = 1000;
254
255 /**
256 * Types of metadata Gallery uses (to query the metadata cache).
257 * @const
258 * @type {string}
259 */
260 Gallery.METADATA_TYPE = 'thumbnail|filesystem|media|external';
261
262 /**
263 * Initializes listeners.
264 * @private
265 */
266 Gallery.prototype.initListeners_ = function() {
267 this.keyDownBound_ = this.onKeyDown_.bind(this);
268 this.document_.body.addEventListener('keydown', this.keyDownBound_);
269
270 this.inactivityWatcher_ = new MouseInactivityWatcher(
271 this.container_, Gallery.FADE_TIMEOUT, this.hasActiveTool.bind(this));
272
273 // Search results may contain files from different subdirectories so
274 // the observer is not going to work.
275 if (!this.context_.searchResults && this.context_.curDirEntry) {
276 this.metadataCacheObserverId_ = this.metadataCache_.addObserver(
277 this.context_.curDirEntry,
278 MetadataCache.CHILDREN,
279 'thumbnail',
280 this.updateThumbnails_.bind(this));
281 }
282 this.volumeManager_.addEventListener(
283 'externally-unmounted', this.onExternallyUnmountedBound_);
284 };
285
286 /**
287 * Closes gallery when a volume containing the selected item is unmounted.
288 * @param {!Event} event The unmount event.
289 * @private
290 */
291 Gallery.prototype.onExternallyUnmounted_ = function(event) {
292 if (!this.selectedEntry_)
293 return;
294
295 if (this.volumeManager_.getVolumeInfo(this.selectedEntry_) ===
296 event.volumeInfo) {
297 close();
298 }
299 };
300
301 /**
302 * Unloads the Gallery.
303 * @param {boolean} exiting True if the app is exiting.
304 */
305 Gallery.prototype.onUnload = function(exiting) {
306 if (this.metadataCacheObserverId_ !== null)
307 this.metadataCache_.removeObserver(this.metadataCacheObserverId_);
308 this.volumeManager_.removeEventListener(
309 'externally-unmounted', this.onExternallyUnmountedBound_);
310 this.slideMode_.onUnload(exiting);
311 };
312
313 /**
314 * Initializes DOM UI
315 * @private
316 */
317 Gallery.prototype.initDom_ = function() {
318 // Initialize the dialog label. 251 // Initialize the dialog label.
319 cr.ui.dialogs.BaseDialog.OK_LABEL = str('GALLERY_OK_LABEL'); 252 cr.ui.dialogs.BaseDialog.OK_LABEL = str('GALLERY_OK_LABEL');
320 cr.ui.dialogs.BaseDialog.CANCEL_LABEL = str('GALLERY_CANCEL_LABEL'); 253 cr.ui.dialogs.BaseDialog.CANCEL_LABEL = str('GALLERY_CANCEL_LABEL');
321 254
322 var content = document.querySelector('#content'); 255 var content = queryRequiredElement(document, '#content');
323 content.addEventListener('click', this.onContentClick_.bind(this)); 256 content.addEventListener('click', this.onContentClick_.bind(this));
324 257
325 this.header_ = document.querySelector('#header'); 258 this.header_ = queryRequiredElement(document, '#header');
326 this.toolbar_ = document.querySelector('#toolbar'); 259 this.toolbar_ = queryRequiredElement(document, '#toolbar');
327 260
328 var preventDefault = function(event) { event.preventDefault(); }; 261 var preventDefault = function(event) { event.preventDefault(); };
329 262
330 var minimizeButton = util.createChild(this.header_, 263 var minimizeButton = util.createChild(this.header_,
331 'minimize-button tool dimmable', 264 'minimize-button tool dimmable',
332 'button'); 265 'button');
333 minimizeButton.tabIndex = -1; 266 minimizeButton.tabIndex = -1;
334 minimizeButton.addEventListener('click', this.onMinimize_.bind(this)); 267 minimizeButton.addEventListener('click', this.onMinimize_.bind(this));
335 minimizeButton.addEventListener('mousedown', preventDefault); 268 minimizeButton.addEventListener('mousedown', preventDefault);
336 269
337 var maximizeButton = util.createChild(this.header_, 270 var maximizeButton = util.createChild(this.header_,
338 'maximize-button tool dimmable', 271 'maximize-button tool dimmable',
339 'button'); 272 'button');
340 maximizeButton.tabIndex = -1; 273 maximizeButton.tabIndex = -1;
341 maximizeButton.addEventListener('click', this.onMaximize_.bind(this)); 274 maximizeButton.addEventListener('click', this.onMaximize_.bind(this));
342 maximizeButton.addEventListener('mousedown', preventDefault); 275 maximizeButton.addEventListener('mousedown', preventDefault);
343 276
344 var closeButton = util.createChild(this.header_, 277 var closeButton = util.createChild(this.header_,
345 'close-button tool dimmable', 278 'close-button tool dimmable',
346 'button'); 279 'button');
347 closeButton.tabIndex = -1; 280 closeButton.tabIndex = -1;
348 closeButton.addEventListener('click', this.onClose_.bind(this)); 281 closeButton.addEventListener('click', this.onClose_.bind(this));
349 closeButton.addEventListener('mousedown', preventDefault); 282 closeButton.addEventListener('mousedown', preventDefault);
350 283
351 this.filenameSpacer_ = this.toolbar_.querySelector('.filename-spacer'); 284 this.filenameSpacer_ = queryRequiredElement(this.toolbar_,
285 '.filename-spacer');
352 this.filenameEdit_ = util.createChild(this.filenameSpacer_, 286 this.filenameEdit_ = util.createChild(this.filenameSpacer_,
353 'namebox', 'input'); 287 'namebox', 'input');
354 288
355 this.filenameEdit_.setAttribute('type', 'text'); 289 this.filenameEdit_.setAttribute('type', 'text');
356 this.filenameEdit_.addEventListener('blur', 290 this.filenameEdit_.addEventListener('blur',
357 this.onFilenameEditBlur_.bind(this)); 291 this.onFilenameEditBlur_.bind(this));
358 292
359 this.filenameEdit_.addEventListener('focus', 293 this.filenameEdit_.addEventListener('focus',
360 this.onFilenameFocus_.bind(this)); 294 this.onFilenameFocus_.bind(this));
361 295
362 this.filenameEdit_.addEventListener('keydown', 296 this.filenameEdit_.addEventListener('keydown',
363 this.onFilenameEditKeydown_.bind(this)); 297 this.onFilenameEditKeydown_.bind(this));
364 298
365 var middleSpacer = this.filenameSpacer_ = 299 var middleSpacer = queryRequiredElement(this.toolbar_, '.middle-spacer');
366 this.toolbar_.querySelector('.middle-spacer'); 300 var buttonSpacer = queryRequiredElement(this.toolbar_, '.button-spacer');
367 var buttonSpacer = this.toolbar_.querySelector('button-spacer');
368 301
369 this.prompt_ = new ImageEditor.Prompt(this.container_, strf); 302 this.prompt_ = new ImageEditor.Prompt(this.container_, strf);
370 303
371 this.errorBanner_ = new ErrorBanner(this.container_); 304 this.errorBanner_ = new ErrorBanner(this.container_);
372 305
373 this.modeButton_ = this.toolbar_.querySelector('button.mode'); 306 this.modeButton_ = queryRequiredElement(this.toolbar_, 'button.mode');
374 this.modeButton_.addEventListener('click', this.toggleMode_.bind(this, null)); 307 this.modeButton_.addEventListener('click',
308 this.toggleMode_.bind(this, undefined));
fukino 2014/12/12 15:15:25 'undefined' looks redundant
yawano 2014/12/15 01:45:24 Interface of toggleMode_ is function(opt_callback,
fukino 2014/12/15 02:15:28 Sorry, I misunderstood the code. Thank you for ex
375 309
376 this.mosaicMode_ = new MosaicMode(content, 310 this.mosaicMode_ = new MosaicMode(content,
377 this.errorBanner_, 311 this.errorBanner_,
378 this.dataModel_, 312 this.dataModel_,
379 this.selectionModel_, 313 this.selectionModel_,
380 this.volumeManager_, 314 this.volumeManager_,
381 this.toggleMode_.bind(this, null)); 315 this.toggleMode_.bind(this));
382 316
383 this.slideMode_ = new SlideMode(this.container_, 317 this.slideMode_ = new SlideMode(this.container_,
384 content, 318 content,
385 this.toolbar_, 319 this.toolbar_,
386 this.prompt_, 320 this.prompt_,
387 this.errorBanner_, 321 this.errorBanner_,
388 this.dataModel_, 322 this.dataModel_,
389 this.selectionModel_, 323 this.selectionModel_,
390 this.context_, 324 this.context_,
391 this.volumeManager_, 325 this.volumeManager_,
(...skipping 14 matching lines...) Expand all
406 this.shareButton_.addEventListener( 340 this.shareButton_.addEventListener(
407 'click', this.onShareButtonClick_.bind(this)); 341 'click', this.onShareButtonClick_.bind(this));
408 342
409 this.dataModel_.addEventListener('splice', this.onSplice_.bind(this)); 343 this.dataModel_.addEventListener('splice', this.onSplice_.bind(this));
410 this.dataModel_.addEventListener('content', this.onContentChange_.bind(this)); 344 this.dataModel_.addEventListener('content', this.onContentChange_.bind(this));
411 345
412 this.selectionModel_.addEventListener('change', this.onSelection_.bind(this)); 346 this.selectionModel_.addEventListener('change', this.onSelection_.bind(this));
413 this.slideMode_.addEventListener('useraction', this.onUserAction_.bind(this)); 347 this.slideMode_.addEventListener('useraction', this.onUserAction_.bind(this));
414 348
415 this.shareDialog_ = new ShareDialog(this.container_); 349 this.shareDialog_ = new ShareDialog(this.container_);
350
351 // -----------------------------------------------------------------
352 // Initialize listeners.
353
354 this.keyDownBound_ = this.onKeyDown_.bind(this);
355 this.document_.body.addEventListener('keydown', this.keyDownBound_);
356
357 this.inactivityWatcher_ = new MouseInactivityWatcher(
358 this.container_, Gallery.FADE_TIMEOUT, this.hasActiveTool.bind(this));
359
360 // Search results may contain files from different subdirectories so
361 // the observer is not going to work.
362 if (!this.context_.searchResults && this.context_.curDirEntry) {
363 this.metadataCacheObserverId_ = this.metadataCache_.addObserver(
364 this.context_.curDirEntry,
365 MetadataCache.CHILDREN,
366 'thumbnail',
367 this.updateThumbnails_.bind(this));
368 }
369 this.volumeManager_.addEventListener(
370 'externally-unmounted', this.onExternallyUnmountedBound_);
371
372 }
373
374 /**
375 * Gallery extends cr.EventTarget.
376 */
377 Gallery.prototype.__proto__ = cr.EventTarget.prototype;
378
379 /**
380 * Tools fade-out timeout in milliseconds.
381 * @const
382 * @type {number}
383 */
384 Gallery.FADE_TIMEOUT = 2000;
385
386 /**
387 * First time tools fade-out timeout in milliseconds.
388 * @const
389 * @type {number}
390 */
391 Gallery.FIRST_FADE_TIMEOUT = 1000;
392
393 /**
394 * Time until mosaic is initialized in the background. Used to make gallery
395 * in the slide mode load faster. In milliseconds.
396 * @const
397 * @type {number}
398 */
399 Gallery.MOSAIC_BACKGROUND_INIT_DELAY = 1000;
400
401 /**
402 * Types of metadata Gallery uses (to query the metadata cache).
403 * @const
404 * @type {string}
405 */
406 Gallery.METADATA_TYPE = 'thumbnail|filesystem|media|external';
407
408 /**
409 * Closes gallery when a volume containing the selected item is unmounted.
410 * @param {!Event} event The unmount event.
411 * @private
412 */
413 Gallery.prototype.onExternallyUnmounted_ = function(event) {
414 if (!this.selectedEntry_)
415 return;
416
417 if (this.volumeManager_.getVolumeInfo(this.selectedEntry_) ===
418 event.volumeInfo) {
419 window.close();
420 }
416 }; 421 };
417 422
418 /** 423 /**
424 * Unloads the Gallery.
425 * @param {boolean=} opt_exiting True if the app is exiting.
426 */
427 Gallery.prototype.onUnload = function(opt_exiting) {
428 if (this.metadataCacheObserverId_ !== null)
429 this.metadataCache_.removeObserver(this.metadataCacheObserverId_);
430 this.volumeManager_.removeEventListener(
431 'externally-unmounted', this.onExternallyUnmountedBound_);
432 };
433
434 /**
419 * Initializes a toolbar button. 435 * Initializes a toolbar button.
420 * 436 *
421 * @param {string} className Class to add. 437 * @param {string} className Class to add.
422 * @param {string} title Button title. 438 * @param {string} title Button title.
423 * @return {!HTMLElement} Newly created button. 439 * @return {!HTMLElement} Newly created button.
424 * @private 440 * @private
425 */ 441 */
426 Gallery.prototype.initToolbarButton_ = function(className, title) { 442 Gallery.prototype.initToolbarButton_ = function(className, title) {
427 var button = this.toolbar_.querySelector('button.' + className); 443 var button = queryRequiredElement(this.toolbar_, 'button.' + className);
428 button.title = str(title); 444 button.title = str(title);
429 return button; 445 return button;
430 }; 446 };
431 447
432 /** 448 /**
433 * Loads the content. 449 * Loads the content.
434 * 450 *
435 * @param {!Array.<Entry>} entries Array of entries. 451 * @param {!Array.<Entry>} entries Array of entries.
436 * @param {!Array.<Entry>} selectedEntries Array of selected entries. 452 * @param {!Array.<Entry>} selectedEntries Array of selected entries.
437 */ 453 */
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 608
593 /** 609 /**
594 * Executes a function when the editor is done with the modifications. 610 * Executes a function when the editor is done with the modifications.
595 * @param {function()} callback Function to execute. 611 * @param {function()} callback Function to execute.
596 */ 612 */
597 Gallery.prototype.executeWhenReady = function(callback) { 613 Gallery.prototype.executeWhenReady = function(callback) {
598 this.currentMode_.executeWhenReady(callback); 614 this.currentMode_.executeWhenReady(callback);
599 }; 615 };
600 616
601 /** 617 /**
602 * @return {Object} File manager private API. 618 * @return {!Object} File manager private API.
603 */ 619 */
604 Gallery.getFileManagerPrivate = function() { 620 Gallery.getFileManagerPrivate = function() {
605 return chrome.fileManagerPrivate || window.top.chrome.fileManagerPrivate; 621 return chrome.fileManagerPrivate || window.top.chrome.fileManagerPrivate;
606 }; 622 };
607 623
608 /** 624 /**
609 * @return {boolean} True if some tool is currently active. 625 * @return {boolean} True if some tool is currently active.
610 */ 626 */
611 Gallery.prototype.hasActiveTool = function() { 627 Gallery.prototype.hasActiveTool = function() {
612 return (this.currentMode_ && this.currentMode_.hasActiveTool()) || 628 return (this.currentMode_ && this.currentMode_.hasActiveTool()) ||
613 this.isRenaming_(); 629 this.isRenaming_();
614 }; 630 };
615 631
616 /** 632 /**
617 * External user action event handler. 633 * External user action event handler.
618 * @private 634 * @private
619 */ 635 */
620 Gallery.prototype.onUserAction_ = function() { 636 Gallery.prototype.onUserAction_ = function() {
621 // Show the toolbar and hide it after the default timeout. 637 // Show the toolbar and hide it after the default timeout.
622 this.inactivityWatcher_.kick(); 638 this.inactivityWatcher_.kick();
623 }; 639 };
624 640
625 /** 641 /**
626 * Sets the current mode, update the UI. 642 * Sets the current mode, update the UI.
627 * @param {Object} mode Current mode. 643 * @param {!(SlideMode|MosaicMode)} mode Current mode.
628 * @private 644 * @private
629 */ 645 */
630 Gallery.prototype.setCurrentMode_ = function(mode) { 646 Gallery.prototype.setCurrentMode_ = function(mode) {
631 if (mode !== this.slideMode_ && mode !== this.mosaicMode_) 647 if (mode !== this.slideMode_ && mode !== this.mosaicMode_)
632 console.error('Invalid Gallery mode'); 648 console.error('Invalid Gallery mode');
633 649
634 this.currentMode_ = mode; 650 this.currentMode_ = mode;
635 this.container_.setAttribute('mode', this.currentMode_.getName()); 651 this.container_.setAttribute('mode', this.currentMode_.getName());
636 this.updateSelectionAndState_(); 652 this.updateSelectionAndState_();
637 this.updateButtons_(); 653 this.updateButtons_();
(...skipping 28 matching lines...) Expand all
666 var tileRect = mosaic.getTileRect(tileIndex); 682 var tileRect = mosaic.getTileRect(tileIndex);
667 683
668 if (this.currentMode_ === this.slideMode_) { 684 if (this.currentMode_ === this.slideMode_) {
669 this.setCurrentMode_(this.mosaicMode_); 685 this.setCurrentMode_(this.mosaicMode_);
670 mosaic.transform( 686 mosaic.transform(
671 tileRect, this.slideMode_.getSelectedImageRect(), true /* instant */); 687 tileRect, this.slideMode_.getSelectedImageRect(), true /* instant */);
672 this.slideMode_.leave( 688 this.slideMode_.leave(
673 tileRect, 689 tileRect,
674 function() { 690 function() {
675 // Animate back to normal position. 691 // Animate back to normal position.
676 mosaic.transform(); 692 mosaic.transform(null, null);
677 mosaic.show(); 693 mosaic.show();
678 onModeChanged(); 694 onModeChanged();
679 }.bind(this)); 695 }.bind(this));
680 } else { 696 } else {
681 this.setCurrentMode_(this.slideMode_); 697 this.setCurrentMode_(this.slideMode_);
682 this.slideMode_.enter( 698 this.slideMode_.enter(
683 tileRect, 699 tileRect,
684 function() { 700 function() {
685 // Animate to zoomed position. 701 // Animate to zoomed position.
686 mosaic.transform(tileRect, this.slideMode_.getSelectedImageRect()); 702 mosaic.transform(tileRect, this.slideMode_.getSelectedImageRect());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 this.selectionModel_.leadIndex = -1; 752 this.selectionModel_.leadIndex = -1;
737 // Remove items from the data model, starting from the highest index. 753 // Remove items from the data model, starting from the highest index.
738 while (indexesToRemove.length) 754 while (indexesToRemove.length)
739 this.dataModel_.splice(indexesToRemove.pop(), 1); 755 this.dataModel_.splice(indexesToRemove.pop(), 1);
740 // Delete actual files. 756 // Delete actual files.
741 deleteNext(); 757 deleteNext();
742 }.bind(this), 758 }.bind(this),
743 function() { 759 function() {
744 // Restore the listener after a timeout so that ESC is processed. 760 // Restore the listener after a timeout so that ESC is processed.
745 setTimeout(restoreListener, 0); 761 setTimeout(restoreListener, 0);
746 }); 762 },
763 null);
747 }; 764 };
748 765
749 /** 766 /**
750 * @return {Array.<Gallery.Item>} Current selection. 767 * @return {!Array.<Gallery.Item>} Current selection.
751 */ 768 */
752 Gallery.prototype.getSelectedItems = function() { 769 Gallery.prototype.getSelectedItems = function() {
753 return this.selectionModel_.selectedIndexes.map( 770 return this.selectionModel_.selectedIndexes.map(
754 this.dataModel_.item.bind(this.dataModel_)); 771 this.dataModel_.item.bind(this.dataModel_));
755 }; 772 };
756 773
757 /** 774 /**
758 * @return {Array.<Entry>} Array of currently selected entries. 775 * @return {!Array.<Entry>} Array of currently selected entries.
759 */ 776 */
760 Gallery.prototype.getSelectedEntries = function() { 777 Gallery.prototype.getSelectedEntries = function() {
761 return this.selectionModel_.selectedIndexes.map(function(index) { 778 return this.selectionModel_.selectedIndexes.map(function(index) {
762 return this.dataModel_.item(index).getEntry(); 779 return this.dataModel_.item(index).getEntry();
763 }.bind(this)); 780 }.bind(this));
764 }; 781 };
765 782
766 /** 783 /**
767 * @return {?Gallery.Item} Current single selection. 784 * @return {?Gallery.Item} Current single selection.
768 */ 785 */
(...skipping 17 matching lines...) Expand all
786 /** 803 /**
787 * Data model splice event handler. 804 * Data model splice event handler.
788 * @private 805 * @private
789 */ 806 */
790 Gallery.prototype.onSplice_ = function() { 807 Gallery.prototype.onSplice_ = function() {
791 this.selectionModel_.adjustLength(this.dataModel_.length); 808 this.selectionModel_.adjustLength(this.dataModel_.length);
792 }; 809 };
793 810
794 /** 811 /**
795 * Content change event handler. 812 * Content change event handler.
796 * @param {Event} event Event. 813 * @param {!Event} event Event.
797 * @private 814 * @private
798 */ 815 */
799 Gallery.prototype.onContentChange_ = function(event) { 816 Gallery.prototype.onContentChange_ = function(event) {
800 var index = this.dataModel_.indexOf(event.item); 817 var index = this.dataModel_.indexOf(event.item);
801 if (index !== this.selectionModel_.selectedIndex) 818 if (index !== this.selectionModel_.selectedIndex)
802 console.error('Content changed for unselected item'); 819 console.error('Content changed for unselected item');
803 this.updateSelectionAndState_(); 820 this.updateSelectionAndState_();
804 }; 821 };
805 822
806 /** 823 /**
807 * Keydown handler. 824 * Keydown handler.
808 * 825 *
809 * @param {Event} event Event. 826 * @param {!Event} event Event.
810 * @private 827 * @private
811 */ 828 */
812 Gallery.prototype.onKeyDown_ = function(event) { 829 Gallery.prototype.onKeyDown_ = function(event) {
813 if (this.currentMode_.onKeyDown(event)) 830 if (this.currentMode_.onKeyDown(event))
814 return; 831 return;
815 832
816 switch (util.getKeyModifiers(event) + event.keyIdentifier) { 833 switch (util.getKeyModifiers(event) + event.keyIdentifier) {
817 case 'U+0008': // Backspace. 834 case 'U+0008': // Backspace.
818 // The default handler would call history.back and close the Gallery. 835 // The default handler would call history.back and close the Gallery.
819 event.preventDefault(); 836 event.preventDefault();
820 break; 837 break;
821 838
822 case 'U+004D': // 'm' switches between Slide and Mosaic mode. 839 case 'U+004D': // 'm' switches between Slide and Mosaic mode.
823 this.toggleMode_(null, event); 840 this.toggleMode_(undefined, event);
824 break; 841 break;
825 842
826 case 'U+0056': // 'v' 843 case 'U+0056': // 'v'
827 case 'MediaPlayPause': 844 case 'MediaPlayPause':
828 this.slideMode_.startSlideshow(SlideMode.SLIDESHOW_INTERVAL_FIRST, event); 845 this.slideMode_.startSlideshow(SlideMode.SLIDESHOW_INTERVAL_FIRST, event);
829 break; 846 break;
830 847
831 case 'U+007F': // Delete 848 case 'U+007F': // Delete
832 case 'Shift-U+0033': // Shift+'3' (Delete key might be missing). 849 case 'Shift-U+0033': // Shift+'3' (Delete key might be missing).
833 case 'U+0044': // 'd' 850 case 'U+0044': // 'd'
834 this.delete_(); 851 this.delete_();
835 break; 852 break;
836 853
837 case 'U+001B': // Escape 854 case 'U+001B': // Escape
838 close(); 855 window.close();
839 break; 856 break;
840 } 857 }
841 }; 858 };
842 859
843 // Name box and rename support. 860 // Name box and rename support.
844 861
845 /** 862 /**
846 * Updates the UI related to the selected item and the persistent state. 863 * Updates the UI related to the selected item and the persistent state.
847 * 864 *
848 * @private 865 * @private
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 Gallery.prototype.onFilenameFocus_ = function() { 928 Gallery.prototype.onFilenameFocus_ = function() {
912 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true); 929 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true);
913 this.filenameEdit_.originalValue = this.filenameEdit_.value; 930 this.filenameEdit_.originalValue = this.filenameEdit_.value;
914 setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0); 931 setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0);
915 this.onUserAction_(); 932 this.onUserAction_();
916 }; 933 };
917 934
918 /** 935 /**
919 * Blur event handler on filename edit box. 936 * Blur event handler on filename edit box.
920 * 937 *
921 * @param {Event} event Blur event. 938 * @param {!Event} event Blur event.
922 * @return {Promise} Promise fulfilled on renaming completed.
923 * @private 939 * @private
924 */ 940 */
925 Gallery.prototype.onFilenameEditBlur_ = function(event) { 941 Gallery.prototype.onFilenameEditBlur_ = function(event) {
926 var item = this.getSingleSelectedItem(); 942 var item = this.getSingleSelectedItem();
927 if (item) { 943 if (item) {
928 var oldEntry = item.getEntry(); 944 var oldEntry = item.getEntry();
929 945
930 item.rename(this.filenameEdit_.value).then(function() { 946 item.rename(this.filenameEdit_.value).then(function() {
931 var event = new Event('content'); 947 var event = new Event('content');
932 event.item = item; 948 event.item = item;
(...skipping 10 matching lines...) Expand all
943 this.prompt_.showStringAt('center', error, 5000); 959 this.prompt_.showStringAt('center', error, 5000);
944 else 960 else
945 return Promise.reject(error); 961 return Promise.reject(error);
946 }.bind(this)).catch(function(error) { 962 }.bind(this)).catch(function(error) {
947 console.error(error.stack || error); 963 console.error(error.stack || error);
948 }); 964 });
949 } 965 }
950 966
951 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false); 967 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false);
952 this.onUserAction_(); 968 this.onUserAction_();
953 return Promise.resolve();
954 }; 969 };
955 970
956 /** 971 /**
957 * Keydown event handler on filename edit box 972 * Keydown event handler on filename edit box
973 * @param {!Event} event A keyboard event.
958 * @private 974 * @private
959 */ 975 */
960 Gallery.prototype.onFilenameEditKeydown_ = function() { 976 Gallery.prototype.onFilenameEditKeydown_ = function(event) {
977 event = assertInstanceof(event, KeyboardEvent);
961 switch (event.keyCode) { 978 switch (event.keyCode) {
962 case 27: // Escape 979 case 27: // Escape
963 this.filenameEdit_.value = this.filenameEdit_.originalValue; 980 this.filenameEdit_.value = this.filenameEdit_.originalValue;
964 this.filenameEdit_.blur(); 981 this.filenameEdit_.blur();
965 break; 982 break;
966 983
967 case 13: // Enter 984 case 13: // Enter
968 this.filenameEdit_.blur(); 985 this.filenameEdit_.blur();
969 break; 986 break;
970 } 987 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 }; 1044 };
1028 1045
1029 /** 1046 /**
1030 * Singleton gallery. 1047 * Singleton gallery.
1031 * @type {Gallery} 1048 * @type {Gallery}
1032 */ 1049 */
1033 var gallery = null; 1050 var gallery = null;
1034 1051
1035 /** 1052 /**
1036 * Initialize the window. 1053 * Initialize the window.
1037 * @param {Object} backgroundComponents Background components. 1054 * @param {!BackgroundComponents} backgroundComponents Background components.
1038 */ 1055 */
1039 window.initialize = function(backgroundComponents) { 1056 window.initialize = function(backgroundComponents) {
1040 window.loadTimeData.data = backgroundComponents.stringData; 1057 window.loadTimeData.data = backgroundComponents.stringData;
1041 gallery = new Gallery(backgroundComponents.volumeManager); 1058 gallery = new Gallery(backgroundComponents.volumeManager);
1042 }; 1059 };
1043 1060
1044 /** 1061 /**
1045 * Loads entries. 1062 * Loads entries.
1046 * @param {!Array.<Entry>} entries Array of entries. 1063 * @param {!Array.<Entry>} entries Array of entries.
1047 * @param {!Array.<Entry>} selectedEntries Array of selected entries. 1064 * @param {!Array.<Entry>} selectedEntries Array of selected entries.
1048 */ 1065 */
1049 window.loadEntries = function(entries, selectedEntries) { 1066 window.loadEntries = function(entries, selectedEntries) {
1050 gallery.load(entries, selectedEntries); 1067 gallery.load(entries, selectedEntries);
1051 }; 1068 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698