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

Side by Side Diff: chrome/browser/resources/file_manager/foreground/js/photo/gallery.js

Issue 109973002: Migrate from URLs to Entries in the Files App's gallery. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. Created 7 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 | 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 'use strict'; 5 'use strict';
6 6
7 /** 7 /**
8 * Called from the main frame when unloading. 8 * Called from the main frame when unloading.
9 * @return {string?} User-visible message on null if it is OK to close. 9 * @return {string?} User-visible message on null if it is OK to close.
10 */ 10 */
(...skipping 25 matching lines...) Expand all
36 * the system. 36 * the system.
37 * @class 37 * @class
38 * @constructor 38 * @constructor
39 */ 39 */
40 function Gallery(context, volumeManager) { 40 function Gallery(context, volumeManager) {
41 this.container_ = document.querySelector('.gallery'); 41 this.container_ = document.querySelector('.gallery');
42 this.document_ = document; 42 this.document_ = document;
43 this.context_ = context; 43 this.context_ = context;
44 this.metadataCache_ = context.metadataCache; 44 this.metadataCache_ = context.metadataCache;
45 this.volumeManager_ = volumeManager; 45 this.volumeManager_ = volumeManager;
46 this.selectedEntry_ = null;
46 47
47 this.dataModel_ = new cr.ui.ArrayDataModel([]); 48 this.dataModel_ = new cr.ui.ArrayDataModel([]);
48 this.selectionModel_ = new cr.ui.ListSelectionModel(); 49 this.selectionModel_ = new cr.ui.ListSelectionModel();
49 this.displayStringFunction_ = context.displayStringFunction; 50 this.displayStringFunction_ = context.displayStringFunction;
50 51
51 this.initDom_(); 52 this.initDom_();
52 this.initListeners_(); 53 this.initListeners_();
53 } 54 }
54 55
55 /** 56 /**
56 * Gallery extends cr.EventTarget. 57 * Gallery extends cr.EventTarget.
57 */ 58 */
58 Gallery.prototype.__proto__ = cr.EventTarget.prototype; 59 Gallery.prototype.__proto__ = cr.EventTarget.prototype;
59 60
60 /** 61 /**
61 * Create and initialize a Gallery object based on a context. 62 * Creates and initializes a Gallery object based on a context.
62 * 63 *
63 * @param {Object} context Gallery context. 64 * @param {Object} context Gallery context.
64 * @param {VolumeManagerWrapper} volumeManager VolumeManager of the system. 65 * @param {VolumeManagerWrapper} volumeManager VolumeManager of the system.
65 * @param {Array.<string>} urls Array of urls. 66 * @param {Array.<Entry>} entries Array of entries.
66 * @param {Array.<string>} selectedUrls Array of selected urls. 67 * @param {Array.<Entry>} selectedEntries Array of selected entries.
67 */ 68 */
68 Gallery.open = function(context, volumeManager, urls, selectedUrls) { 69 Gallery.open = function(context, volumeManager, entries, selectedEntries) {
69 Gallery.instance = new Gallery(context, volumeManager); 70 Gallery.instance = new Gallery(context, volumeManager);
70 Gallery.instance.load(urls, selectedUrls); 71 Gallery.instance.load(entries, selectedEntries);
71 }; 72 };
72 73
73 /** 74 /**
74 * Tools fade-out timeout im milliseconds. 75 * Tools fade-out timeout im milliseconds.
75 * @const 76 * @const
76 * @type {number} 77 * @type {number}
77 */ 78 */
78 Gallery.FADE_TIMEOUT = 3000; 79 Gallery.FADE_TIMEOUT = 3000;
79 80
80 /** 81 /**
(...skipping 12 matching lines...) Expand all
93 Gallery.MOSAIC_BACKGROUND_INIT_DELAY = 1000; 94 Gallery.MOSAIC_BACKGROUND_INIT_DELAY = 1000;
94 95
95 /** 96 /**
96 * Types of metadata Gallery uses (to query the metadata cache). 97 * Types of metadata Gallery uses (to query the metadata cache).
97 * @const 98 * @const
98 * @type {string} 99 * @type {string}
99 */ 100 */
100 Gallery.METADATA_TYPE = 'thumbnail|filesystem|media|streaming|drive'; 101 Gallery.METADATA_TYPE = 'thumbnail|filesystem|media|streaming|drive';
101 102
102 /** 103 /**
103 * Initialize listeners. 104 * Initializes listeners.
104 * @private 105 * @private
105 */ 106 */
106 Gallery.prototype.initListeners_ = function() { 107 Gallery.prototype.initListeners_ = function() {
107 this.document_.oncontextmenu = function(e) { e.preventDefault(); }; 108 this.document_.oncontextmenu = function(e) { e.preventDefault(); };
108 this.keyDownBound_ = this.onKeyDown_.bind(this); 109 this.keyDownBound_ = this.onKeyDown_.bind(this);
109 this.document_.body.addEventListener('keydown', this.keyDownBound_); 110 this.document_.body.addEventListener('keydown', this.keyDownBound_);
110 111
111 this.inactivityWatcher_ = new MouseInactivityWatcher( 112 this.inactivityWatcher_ = new MouseInactivityWatcher(
112 this.container_, Gallery.FADE_TIMEOUT, this.hasActiveTool.bind(this)); 113 this.container_, Gallery.FADE_TIMEOUT, this.hasActiveTool.bind(this));
113 114
(...skipping 10 matching lines...) Expand all
124 this.volumeManager_.addEventListener('externally-unmounted', 125 this.volumeManager_.addEventListener('externally-unmounted',
125 this.onExternallyUnmounted_.bind(this)); 126 this.onExternallyUnmounted_.bind(this));
126 }; 127 };
127 128
128 /** 129 /**
129 * Closes gallery when a volume containing the selected item is unmounted. 130 * Closes gallery when a volume containing the selected item is unmounted.
130 * @param {Event} event The unmount event. 131 * @param {Event} event The unmount event.
131 * @private 132 * @private
132 */ 133 */
133 Gallery.prototype.onExternallyUnmounted_ = function(event) { 134 Gallery.prototype.onExternallyUnmounted_ = function(event) {
134 if (!this.selectedItemFilesystemPath_) 135 if (!this.selectedEntry_)
135 return; 136 return;
136 if (this.selectedItemFilesystemPath_.indexOf(event.mountPath) == 0) 137
138 if (this.volumeManager_.getVolumeInfo(this.selectedEntry_) ===
139 event.volumeInfo) {
137 this.onBack_(); 140 this.onBack_();
141 }
138 }; 142 };
139 143
140 /** 144 /**
141 * Beforeunload handler. 145 * Beforeunload handler.
142 * @return {string?} User-visible message on null if it is OK to close. 146 * @return {string?} User-visible message on null if it is OK to close.
143 */ 147 */
144 Gallery.prototype.onBeforeUnload = function() { 148 Gallery.prototype.onBeforeUnload = function() {
145 return this.slideMode_.onBeforeUnload(); 149 return this.slideMode_.onBeforeUnload();
146 }; 150 };
147 151
148 /** 152 /**
149 * Unload the Gallery. 153 * Unloads the Gallery.
150 * @param {boolean} exiting True if the app is exiting. 154 * @param {boolean} exiting True if the app is exiting.
151 */ 155 */
152 Gallery.prototype.onUnload = function(exiting) { 156 Gallery.prototype.onUnload = function(exiting) {
153 if (!this.context_.searchResults) { 157 if (!this.context_.searchResults) {
154 this.metadataCache_.removeObserver(this.thumbnailObserverId_); 158 this.metadataCache_.removeObserver(this.thumbnailObserverId_);
155 } 159 }
156 this.slideMode_.onUnload(exiting); 160 this.slideMode_.onUnload(exiting);
157 }; 161 };
158 162
159 /** 163 /**
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 * @return {HTMLElement} Newly created button. 264 * @return {HTMLElement} Newly created button.
261 * @private 265 * @private
262 */ 266 */
263 Gallery.prototype.createToolbarButton_ = function(className, title) { 267 Gallery.prototype.createToolbarButton_ = function(className, title) {
264 var button = util.createChild(this.toolbar_, className, 'button'); 268 var button = util.createChild(this.toolbar_, className, 'button');
265 button.title = this.displayStringFunction_(title); 269 button.title = this.displayStringFunction_(title);
266 return button; 270 return button;
267 }; 271 };
268 272
269 /** 273 /**
270 * Load the content. 274 * Loads the content.
271 * 275 *
272 * @param {Array.<string>} urls Array of urls. 276 * @param {Array.<Entry>} entries Array of entries.
273 * @param {Array.<string>} selectedUrls Array of selected urls. 277 * @param {Array.<Entry>} selectedEntries Array of selected entries. Must be a
278 * subset of {@code entries}.
274 */ 279 */
275 Gallery.prototype.load = function(urls, selectedUrls) { 280 Gallery.prototype.load = function(entries, selectedEntries) {
276 var items = []; 281 var items = [];
277 for (var index = 0; index < urls.length; ++index) { 282 for (var index = 0; index < entries.length; ++index) {
278 items.push(new Gallery.Item(urls[index])); 283 items.push(new Gallery.Item(entries[index]));
279 } 284 }
280 this.dataModel_.push.apply(this.dataModel_, items); 285 this.dataModel_.push.apply(this.dataModel_, items);
281 286
282 this.selectionModel_.adjustLength(this.dataModel_.length); 287 this.selectionModel_.adjustLength(this.dataModel_.length);
283 288
284 for (var i = 0; i != selectedUrls.length; i++) { 289 for (var i = 0; i !== selectedEntries.length; i++) {
285 var selectedIndex = urls.indexOf(selectedUrls[i]); 290 var selectedIndex = entries.indexOf(selectedEntries[i]);
286 if (selectedIndex >= 0) 291 if (selectedIndex >= 0)
287 this.selectionModel_.setIndexSelected(selectedIndex, true); 292 this.selectionModel_.setIndexSelected(selectedIndex, true);
288 else 293 else
289 console.error('Cannot select ' + selectedUrls[i]); 294 console.error('Cannot select ' + selectedEntries[i]);
290 } 295 }
291 296
292 if (this.selectionModel_.selectedIndexes.length == 0) 297 if (this.selectionModel_.selectedIndexes.length === 0)
293 this.onSelection_(); 298 this.onSelection_();
294 299
295 var mosaic = this.mosaicMode_ && this.mosaicMode_.getMosaic(); 300 var mosaic = this.mosaicMode_ && this.mosaicMode_.getMosaic();
296 301
297 // Mosaic view should show up if most of the selected files are images. 302 // Mosaic view should show up if most of the selected files are images.
298 var imagesCount = 0; 303 var imagesCount = 0;
299 for (var i = 0; i != selectedUrls.length; i++) { 304 for (var i = 0; i !== selectedEntries.length; i++) {
300 if (FileType.getMediaType(selectedUrls[i]) == 'image') 305 if (FileType.getMediaType(selectedEntries[i]) === 'image')
301 imagesCount++; 306 imagesCount++;
302 } 307 }
303 var mostlyImages = imagesCount > (selectedUrls.length / 2.0); 308 var mostlyImages = imagesCount > (selectedEntries.length / 2.0);
304 309
305 var forcedMosaic = (this.context_.pageState && 310 var forcedMosaic = (this.context_.pageState &&
306 this.context_.pageState.gallery == 'mosaic'); 311 this.context_.pageState.gallery === 'mosaic');
307 312
308 var showMosaic = (mostlyImages && selectedUrls.length > 1) || forcedMosaic; 313 var showMosaic = (mostlyImages && selectedEntries.length > 1) || forcedMosaic;
309 if (mosaic && showMosaic) { 314 if (mosaic && showMosaic) {
310 this.setCurrentMode_(this.mosaicMode_); 315 this.setCurrentMode_(this.mosaicMode_);
311 mosaic.init(); 316 mosaic.init();
312 mosaic.show(); 317 mosaic.show();
313 this.inactivityWatcher_.check(); // Show the toolbar. 318 this.inactivityWatcher_.check(); // Show the toolbar.
314 cr.dispatchSimpleEvent(this, 'loaded'); 319 cr.dispatchSimpleEvent(this, 'loaded');
315 } else { 320 } else {
316 this.setCurrentMode_(this.slideMode_); 321 this.setCurrentMode_(this.slideMode_);
317 var maybeLoadMosaic = function() { 322 var maybeLoadMosaic = function() {
318 if (mosaic) 323 if (mosaic)
319 mosaic.init(); 324 mosaic.init();
320 cr.dispatchSimpleEvent(this, 'loaded'); 325 cr.dispatchSimpleEvent(this, 'loaded');
321 }.bind(this); 326 }.bind(this);
322 /* TODO: consider nice blow-up animation for the first image */ 327 /* TODO: consider nice blow-up animation for the first image */
323 this.slideMode_.enter(null, function() { 328 this.slideMode_.enter(null, function() {
324 // Flash the toolbar briefly to show it is there. 329 // Flash the toolbar briefly to show it is there.
325 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT); 330 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT);
326 }.bind(this), 331 }.bind(this),
327 maybeLoadMosaic); 332 maybeLoadMosaic);
328 } 333 }
329 }; 334 };
330 335
331 /** 336 /**
332 * Close the Gallery and go to Files.app. 337 * Closes the Gallery and go to Files.app.
333 * @private 338 * @private
334 */ 339 */
335 Gallery.prototype.back_ = function() { 340 Gallery.prototype.back_ = function() {
336 if (util.isFullScreen(this.context_.appWindow)) { 341 if (util.isFullScreen(this.context_.appWindow)) {
337 util.toggleFullScreen(this.context_.appWindow, 342 util.toggleFullScreen(this.context_.appWindow,
338 false); // Leave the full screen mode. 343 false); // Leave the full screen mode.
339 } 344 }
340 this.context_.onBack(this.getSelectedUrls()); 345 this.context_.onBack(this.getSelectedEntries());
341 }; 346 };
342 347
343 /** 348 /**
344 * Handle user's 'Back' action (Escape or a click on the X icon). 349 * Handles user's 'Back' action (Escape or a click on the X icon).
345 * @private 350 * @private
346 */ 351 */
347 Gallery.prototype.onBack_ = function() { 352 Gallery.prototype.onBack_ = function() {
348 this.executeWhenReady(this.back_.bind(this)); 353 this.executeWhenReady(this.back_.bind(this));
349 }; 354 };
350 355
351 /** 356 /**
352 * Handle user's 'Close' action. 357 * Handles user's 'Close' action.
353 * @private 358 * @private
354 */ 359 */
355 Gallery.prototype.onClose_ = function() { 360 Gallery.prototype.onClose_ = function() {
356 this.executeWhenReady(this.context_.onClose); 361 this.executeWhenReady(this.context_.onClose);
357 }; 362 };
358 363
359 /** 364 /**
360 * Handle user's 'Maximize' action (Escape or a click on the X icon). 365 * Handles user's 'Maximize' action (Escape or a click on the X icon).
361 * @private 366 * @private
362 */ 367 */
363 Gallery.prototype.onMaximize_ = function() { 368 Gallery.prototype.onMaximize_ = function() {
364 this.executeWhenReady(this.context_.onMaximize); 369 this.executeWhenReady(this.context_.onMaximize);
365 }; 370 };
366 371
367 /** 372 /**
368 * Execute a function when the editor is done with the modifications. 373 * Executes a function when the editor is done with the modifications.
369 * @param {function} callback Function to execute. 374 * @param {function} callback Function to execute.
370 */ 375 */
371 Gallery.prototype.executeWhenReady = function(callback) { 376 Gallery.prototype.executeWhenReady = function(callback) {
372 this.currentMode_.executeWhenReady(callback); 377 this.currentMode_.executeWhenReady(callback);
373 }; 378 };
374 379
375 /** 380 /**
376 * @return {Object} File browser private API. 381 * @return {Object} File browser private API.
377 */ 382 */
378 Gallery.getFileBrowserPrivate = function() { 383 Gallery.getFileBrowserPrivate = function() {
(...skipping 12 matching lines...) Expand all
391 * External user action event handler. 396 * External user action event handler.
392 * @private 397 * @private
393 */ 398 */
394 Gallery.prototype.onUserAction_ = function() { 399 Gallery.prototype.onUserAction_ = function() {
395 this.closeShareMenu_(); 400 this.closeShareMenu_();
396 // Show the toolbar and hide it after the default timeout. 401 // Show the toolbar and hide it after the default timeout.
397 this.inactivityWatcher_.kick(); 402 this.inactivityWatcher_.kick();
398 }; 403 };
399 404
400 /** 405 /**
401 * Set the current mode, update the UI. 406 * Sets the current mode, update the UI.
402 * @param {Object} mode Current mode. 407 * @param {Object} mode Current mode.
403 * @private 408 * @private
404 */ 409 */
405 Gallery.prototype.setCurrentMode_ = function(mode) { 410 Gallery.prototype.setCurrentMode_ = function(mode) {
406 if (mode != this.slideMode_ && mode != this.mosaicMode_) 411 if (mode !== this.slideMode_ && mode !== this.mosaicMode_)
407 console.error('Invalid Gallery mode'); 412 console.error('Invalid Gallery mode');
408 413
409 this.currentMode_ = mode; 414 this.currentMode_ = mode;
410 this.container_.setAttribute('mode', this.currentMode_.getName()); 415 this.container_.setAttribute('mode', this.currentMode_.getName());
411 this.updateSelectionAndState_(); 416 this.updateSelectionAndState_();
412 this.updateButtons_(); 417 this.updateButtons_();
413 }; 418 };
414 419
415 /** 420 /**
416 * Mode toggle event handler. 421 * Mode toggle event handler.
(...skipping 16 matching lines...) Expand all
433 var onModeChanged = function() { 438 var onModeChanged = function() {
434 this.changingMode_ = false; 439 this.changingMode_ = false;
435 if (opt_callback) opt_callback(); 440 if (opt_callback) opt_callback();
436 }.bind(this); 441 }.bind(this);
437 442
438 var tileIndex = Math.max(0, this.selectionModel_.selectedIndex); 443 var tileIndex = Math.max(0, this.selectionModel_.selectedIndex);
439 444
440 var mosaic = this.mosaicMode_.getMosaic(); 445 var mosaic = this.mosaicMode_.getMosaic();
441 var tileRect = mosaic.getTileRect(tileIndex); 446 var tileRect = mosaic.getTileRect(tileIndex);
442 447
443 if (this.currentMode_ == this.slideMode_) { 448 if (this.currentMode_ === this.slideMode_) {
444 this.setCurrentMode_(this.mosaicMode_); 449 this.setCurrentMode_(this.mosaicMode_);
445 mosaic.transform( 450 mosaic.transform(
446 tileRect, this.slideMode_.getSelectedImageRect(), true /* instant */); 451 tileRect, this.slideMode_.getSelectedImageRect(), true /* instant */);
447 this.slideMode_.leave(tileRect, 452 this.slideMode_.leave(tileRect,
448 function() { 453 function() {
449 // Animate back to normal position. 454 // Animate back to normal position.
450 mosaic.transform(); 455 mosaic.transform();
451 mosaic.show(); 456 mosaic.show();
452 onModeChanged(); 457 onModeChanged();
453 }.bind(this)); 458 }.bind(this));
(...skipping 24 matching lines...) Expand all
478 /* TODO(dgozman): Implement Undo delete, Remove the confirmation dialog. */ 483 /* TODO(dgozman): Implement Undo delete, Remove the confirmation dialog. */
479 484
480 var itemsToRemove = this.getSelectedItems(); 485 var itemsToRemove = this.getSelectedItems();
481 var plural = itemsToRemove.length > 1; 486 var plural = itemsToRemove.length > 1;
482 var param = plural ? itemsToRemove.length : itemsToRemove[0].getFileName(); 487 var param = plural ? itemsToRemove.length : itemsToRemove[0].getFileName();
483 488
484 function deleteNext() { 489 function deleteNext() {
485 if (!itemsToRemove.length) 490 if (!itemsToRemove.length)
486 return; // All deleted. 491 return; // All deleted.
487 492
488 var url = itemsToRemove.pop().getUrl(); 493 // TODO(hirono): Use fileOperationManager.
489 webkitResolveLocalFileSystemURL(url, 494 var entry = itemsToRemove.pop().getEntry();
490 function(entry) { 495 entry.remove(deleteNext, function() {
491 entry.remove(deleteNext, 496 util.flog('Error deleting: ' + entry.fullPath, deleteNext);
492 util.flog('Error deleting ' + url, deleteNext)); 497 });
493 },
494 util.flog('Error resolving ' + url, deleteNext));
495 } 498 }
496 499
497 // Prevent the Gallery from handling Esc and Enter. 500 // Prevent the Gallery from handling Esc and Enter.
498 this.document_.body.removeEventListener('keydown', this.keyDownBound_); 501 this.document_.body.removeEventListener('keydown', this.keyDownBound_);
499 var restoreListener = function() { 502 var restoreListener = function() {
500 this.document_.body.addEventListener('keydown', this.keyDownBound_); 503 this.document_.body.addEventListener('keydown', this.keyDownBound_);
501 }.bind(this); 504 }.bind(this);
502 505
503 cr.ui.dialogs.BaseDialog.OK_LABEL = this.displayStringFunction_( 506 cr.ui.dialogs.BaseDialog.OK_LABEL = this.displayStringFunction_(
504 'GALLERY_OK_LABEL'); 507 'GALLERY_OK_LABEL');
(...skipping 21 matching lines...) Expand all
526 529
527 /** 530 /**
528 * @return {Array.<Gallery.Item>} Current selection. 531 * @return {Array.<Gallery.Item>} Current selection.
529 */ 532 */
530 Gallery.prototype.getSelectedItems = function() { 533 Gallery.prototype.getSelectedItems = function() {
531 return this.selectionModel_.selectedIndexes.map( 534 return this.selectionModel_.selectedIndexes.map(
532 this.dataModel_.item.bind(this.dataModel_)); 535 this.dataModel_.item.bind(this.dataModel_));
533 }; 536 };
534 537
535 /** 538 /**
536 * @return {Array.<string>} Array of currently selected urls. 539 * @return {Array.<Entry>} Array of currently selected entries.
537 */ 540 */
538 Gallery.prototype.getSelectedUrls = function() { 541 Gallery.prototype.getSelectedEntries = function() {
539 return this.selectionModel_.selectedIndexes.map(function(index) { 542 return this.selectionModel_.selectedIndexes.map(function(index) {
540 return this.dataModel_.item(index).getUrl(); 543 return this.dataModel_.item(index).getEntry();
541 }.bind(this)); 544 }.bind(this));
542 }; 545 };
543 546
544 /** 547 /**
545 * @return {Gallery.Item} Current single selection. 548 * @return {Gallery.Item} Current single selection.
546 */ 549 */
547 Gallery.prototype.getSingleSelectedItem = function() { 550 Gallery.prototype.getSingleSelectedItem = function() {
548 var items = this.getSelectedItems(); 551 var items = this.getSelectedItems();
549 if (items.length > 1) 552 if (items.length > 1)
550 throw new Error('Unexpected multiple selection'); 553 throw new Error('Unexpected multiple selection');
(...skipping 17 matching lines...) Expand all
568 this.selectionModel_.adjustLength(this.dataModel_.length); 571 this.selectionModel_.adjustLength(this.dataModel_.length);
569 }; 572 };
570 573
571 /** 574 /**
572 * Content change event handler. 575 * Content change event handler.
573 * @param {Event} event Event. 576 * @param {Event} event Event.
574 * @private 577 * @private
575 */ 578 */
576 Gallery.prototype.onContentChange_ = function(event) { 579 Gallery.prototype.onContentChange_ = function(event) {
577 var index = this.dataModel_.indexOf(event.item); 580 var index = this.dataModel_.indexOf(event.item);
578 if (index != this.selectionModel_.selectedIndex) 581 if (index !== this.selectionModel_.selectedIndex)
579 console.error('Content changed for unselected item'); 582 console.error('Content changed for unselected item');
580 this.updateSelectionAndState_(); 583 this.updateSelectionAndState_();
581 }; 584 };
582 585
583 /** 586 /**
584 * Keydown handler. 587 * Keydown handler.
585 * 588 *
586 * @param {Event} event Event. 589 * @param {Event} event Event.
587 * @private 590 * @private
588 */ 591 */
(...skipping 27 matching lines...) Expand all
616 case 'U+007F': // Delete 619 case 'U+007F': // Delete
617 case 'Shift-U+0033': // Shift+'3' (Delete key might be missing). 620 case 'Shift-U+0033': // Shift+'3' (Delete key might be missing).
618 this.delete_(); 621 this.delete_();
619 break; 622 break;
620 } 623 }
621 }; 624 };
622 625
623 // Name box and rename support. 626 // Name box and rename support.
624 627
625 /** 628 /**
626 * Update the UI related to the selected item and the persistent state. 629 * Updates the UI related to the selected item and the persistent state.
627 * 630 *
628 * @private 631 * @private
629 */ 632 */
630 Gallery.prototype.updateSelectionAndState_ = function() { 633 Gallery.prototype.updateSelectionAndState_ = function() {
631 var path; 634 var path;
632 var displayName = ''; 635 var displayName = '';
633 636
634 var selectedItems = this.getSelectedItems(); 637 var selectedItems = this.getSelectedItems();
635 if (selectedItems.length == 1) { 638 if (selectedItems.length === 1) {
636 var item = selectedItems[0]; 639 var item = selectedItems[0];
637 path = util.extractFilePath(item.getUrl()); 640 var entry = item.getEntry();
638 var fullName = item.getFileName(); 641 window.top.document.title = entry.name;
639 window.top.document.title = fullName; 642 displayName = ImageUtil.getDisplayNameFromName(entry.name);
640 displayName = ImageUtil.getFileNameFromFullName(fullName);
641 } else if (selectedItems.length > 1 && this.context_.curDirEntry) { 643 } else if (selectedItems.length > 1 && this.context_.curDirEntry) {
642 // If the Gallery was opened on search results the search query will not be 644 // If the Gallery was opened on search results the search query will not be
643 // recorded in the app state and the relaunch will just open the gallery 645 // recorded in the app state and the relaunch will just open the gallery
644 // in the curDirEntry directory. 646 // in the curDirEntry directory.
645 path = this.context_.curDirEntry.fullPath; 647 path = this.context_.curDirEntry.fullPath;
646 window.top.document.title = this.context_.curDirEntry.name; 648 window.top.document.title = this.context_.curDirEntry.name;
647 displayName = 649 displayName =
648 this.displayStringFunction_('GALLERY_ITEMS_SELECTED', 650 this.displayStringFunction_('GALLERY_ITEMS_SELECTED',
649 selectedItems.length); 651 selectedItems.length);
650 } 652 }
651 653
652 window.top.util.updateAppState(path, 654 window.top.util.updateAppState(path,
653 {gallery: (this.currentMode_ == this.mosaicMode_ ? 'mosaic' : 'slide')}); 655 {gallery: (this.currentMode_ === this.mosaicMode_ ? 'mosaic' : 'slide')});
654 656
655 // We can't rename files in readonly directory. 657 // We can't rename files in readonly directory.
656 // We can only rename a single file. 658 // We can only rename a single file.
657 this.filenameEdit_.disabled = selectedItems.length != 1 || 659 this.filenameEdit_.disabled = selectedItems.length !== 1 ||
658 this.context_.readonlyDirName; 660 this.context_.readonlyDirName;
659 661
660 this.filenameEdit_.value = displayName; 662 this.filenameEdit_.value = displayName;
661 663
662 // Resolve real filesystem path of the current file. 664 // Resolve real filesystem path of the current file.
663 if (this.selectionModel_.selectedIndexes.length) { 665 if (this.selectionModel_.selectedIndexes.length) {
664 var selectedIndex = this.selectionModel_.selectedIndex; 666 var selectedIndex = this.selectionModel_.selectedIndex;
665 var selectedItem = 667 var selectedItem =
666 this.dataModel_.item(this.selectionModel_.selectedIndex); 668 this.dataModel_.item(this.selectionModel_.selectedIndex);
667 669 this.selectedEntry_ = selectedItem.getEntry();
668 this.selectedItemFilesystemPath_ = null;
669 webkitResolveLocalFileSystemURL(selectedItem.getUrl(),
670 function(entry) {
671 if (this.selectionModel_.selectedIndex != selectedIndex)
672 return;
673 this.selectedItemFilesystemPath_ = entry.fullPath;
674 }.bind(this));
675 } 670 }
676 }; 671 };
677 672
678 /** 673 /**
679 * Click event handler on filename edit box 674 * Click event handler on filename edit box
680 * @private 675 * @private
681 */ 676 */
682 Gallery.prototype.onFilenameFocus_ = function() { 677 Gallery.prototype.onFilenameFocus_ = function() {
683 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true); 678 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true);
684 this.filenameEdit_.originalValue = this.filenameEdit_.value; 679 this.filenameEdit_.originalValue = this.filenameEdit_.value;
685 setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0); 680 setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0);
686 this.onUserAction_(); 681 this.onUserAction_();
687 }; 682 };
688 683
689 /** 684 /**
690 * Blur event handler on filename edit box. 685 * Blur event handler on filename edit box.
691 * 686 *
692 * @param {Event} event Blur event. 687 * @param {Event} event Blur event.
693 * @return {boolean} if default action should be prevented. 688 * @return {boolean} if default action should be prevented.
694 * @private 689 * @private
695 */ 690 */
696 Gallery.prototype.onFilenameEditBlur_ = function(event) { 691 Gallery.prototype.onFilenameEditBlur_ = function(event) {
697 if (this.filenameEdit_.value && this.filenameEdit_.value[0] == '.') { 692 if (this.filenameEdit_.value && this.filenameEdit_.value[0] === '.') {
698 this.prompt_.show('GALLERY_FILE_HIDDEN_NAME', 5000); 693 this.prompt_.show('GALLERY_FILE_HIDDEN_NAME', 5000);
699 this.filenameEdit_.focus(); 694 this.filenameEdit_.focus();
700 event.stopPropagation(); 695 event.stopPropagation();
701 event.preventDefault(); 696 event.preventDefault();
702 return false; 697 return false;
703 } 698 }
704 699
705 var item = this.getSingleSelectedItem(); 700 var item = this.getSingleSelectedItem();
706 var oldUrl = item.getUrl(); 701 var oldEntry = item.getEntry();
707 702
708 var onFileExists = function() { 703 var onFileExists = function() {
709 this.prompt_.show('GALLERY_FILE_EXISTS', 3000); 704 this.prompt_.show('GALLERY_FILE_EXISTS', 3000);
710 this.filenameEdit_.value = name; 705 this.filenameEdit_.value = name;
711 this.filenameEdit_.focus(); 706 this.filenameEdit_.focus();
712 }.bind(this); 707 }.bind(this);
713 708
714 var onSuccess = function() { 709 var onSuccess = function() {
715 var e = new Event('content'); 710 var event = new Event('content');
716 e.item = item; 711 event.item = item;
717 e.oldUrl = oldUrl; 712 event.oldEntry = oldEntry;
718 e.metadata = null; // Metadata unchanged. 713 event.metadata = null; // Metadata unchanged.
719 this.dataModel_.dispatchEvent(e); 714 this.dataModel_.dispatchEvent(event);
720 }.bind(this); 715 }.bind(this);
721 716
722 if (this.filenameEdit_.value) { 717 if (this.filenameEdit_.value) {
723 this.getSingleSelectedItem().rename( 718 this.getSingleSelectedItem().rename(
724 this.filenameEdit_.value, onSuccess, onFileExists); 719 this.filenameEdit_.value, onSuccess, onFileExists);
725 } 720 }
726 721
727 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false); 722 ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false);
728 this.onUserAction_(); 723 this.onUserAction_();
729 }; 724 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 if (!this.shareButton_.hasAttribute('disabled')) 785 if (!this.shareButton_.hasAttribute('disabled'))
791 this.shareMenu_.hidden = !this.shareMenu_.hidden; 786 this.shareMenu_.hidden = !this.shareMenu_.hidden;
792 this.inactivityWatcher_.check(); 787 this.inactivityWatcher_.check();
793 }; 788 };
794 789
795 /** 790 /**
796 * Updates available actions list based on the currently selected urls. 791 * Updates available actions list based on the currently selected urls.
797 * @private. 792 * @private.
798 */ 793 */
799 Gallery.prototype.updateShareMenu_ = function() { 794 Gallery.prototype.updateShareMenu_ = function() {
800 var urls = this.getSelectedUrls(); 795 var entries = this.getSelectedEntries();
801 796
802 function isShareAction(task) { 797 function isShareAction(task) {
803 var taskParts = task.taskId.split('|'); 798 var taskParts = task.taskId.split('|');
804 return taskParts[0] != chrome.runtime.id; 799 return taskParts[0] !== chrome.runtime.id;
805 } 800 }
806 801
807 var api = Gallery.getFileBrowserPrivate(); 802 var api = Gallery.getFileBrowserPrivate();
808 var mimeTypes = []; // TODO(kaznacheev) Collect mime types properly. 803 var mimeTypes = []; // TODO(kaznacheev) Collect mime types properly.
809 804
810 var createShareMenu = function(tasks) { 805 var createShareMenu = function(tasks) {
811 var wasHidden = this.shareMenu_.hidden; 806 var wasHidden = this.shareMenu_.hidden;
812 this.shareMenu_.hidden = true; 807 this.shareMenu_.hidden = true;
813 var items = this.shareMenu_.querySelectorAll('.item'); 808 var items = this.shareMenu_.querySelectorAll('.item');
814 for (var i = 0; i != items.length; i++) { 809 for (var i = 0; i !== items.length; i++) {
815 items[i].parentNode.removeChild(items[i]); 810 items[i].parentNode.removeChild(items[i]);
816 } 811 }
817 812
818 for (var t = 0; t != tasks.length; t++) { 813 for (var t = 0; t !== tasks.length; t++) {
819 var task = tasks[t]; 814 var task = tasks[t];
820 if (!isShareAction(task)) continue; 815 if (!isShareAction(task)) continue;
821 816
822 var item = util.createChild(this.shareMenu_, 'item'); 817 var item = util.createChild(this.shareMenu_, 'item');
823 item.textContent = task.title; 818 item.textContent = task.title;
824 item.style.backgroundImage = 'url(' + task.iconUrl + ')'; 819 item.style.backgroundImage = 'url(' + task.iconUrl + ')';
825 item.addEventListener('click', function(taskId) { 820 item.addEventListener('click', function(taskId) {
826 this.toggleShare_(); // Hide the menu. 821 this.toggleShare_(); // Hide the menu.
827 this.executeWhenReady(api.executeTask.bind(api, taskId, urls)); 822 this.executeWhenReady(api.executeTask.bind(api, taskId, entries));
828 }.bind(this, task.taskId)); 823 }.bind(this, task.taskId));
829 } 824 }
830 825
831 var empty = this.shareMenu_.querySelector('.item') == null; 826 var empty = this.shareMenu_.querySelector('.item') === null;
832 ImageUtil.setAttribute(this.shareButton_, 'disabled', empty); 827 ImageUtil.setAttribute(this.shareButton_, 'disabled', empty);
833 this.shareMenu_.hidden = wasHidden || empty; 828 this.shareMenu_.hidden = wasHidden || empty;
834 }.bind(this); 829 }.bind(this);
835 830
836 // Create or update the share menu with a list of sharing tasks and show 831 // Create or update the share menu with a list of sharing tasks and show
837 // or hide the share button. 832 // or hide the share button.
838 if (!urls.length) 833 // TODO(mtomasz): Pass Entries directly, instead of URLs.
834 if (!entries.length)
839 createShareMenu([]); // Empty list of tasks, since there is no selection. 835 createShareMenu([]); // Empty list of tasks, since there is no selection.
840 else 836 else
841 api.getFileTasks(urls, mimeTypes, createShareMenu); 837 api.getFileTasks(util.entriesToURLs(entries), mimeTypes, createShareMenu);
842 }; 838 };
843 839
844 /** 840 /**
845 * Updates thumbnails. 841 * Updates thumbnails.
846 * @private 842 * @private
847 */ 843 */
848 Gallery.prototype.updateThumbnails_ = function() { 844 Gallery.prototype.updateThumbnails_ = function() {
849 if (this.currentMode_ == this.slideMode_) 845 if (this.currentMode_ === this.slideMode_)
850 this.slideMode_.updateThumbnails(); 846 this.slideMode_.updateThumbnails();
851 847
852 if (this.mosaicMode_) { 848 if (this.mosaicMode_) {
853 var mosaic = this.mosaicMode_.getMosaic(); 849 var mosaic = this.mosaicMode_.getMosaic();
854 if (mosaic.isInitialized()) 850 if (mosaic.isInitialized())
855 mosaic.reload(); 851 mosaic.reload();
856 } 852 }
857 }; 853 };
858 854
859 /** 855 /**
860 * Updates buttons. 856 * Updates buttons.
861 * @private 857 * @private
862 */ 858 */
863 Gallery.prototype.updateButtons_ = function() { 859 Gallery.prototype.updateButtons_ = function() {
864 if (this.modeButton_) { 860 if (this.modeButton_) {
865 var oppositeMode = 861 var oppositeMode =
866 this.currentMode_ == this.slideMode_ ? this.mosaicMode_ : 862 this.currentMode_ === this.slideMode_ ? this.mosaicMode_ :
867 this.slideMode_; 863 this.slideMode_;
868 this.modeButton_.title = 864 this.modeButton_.title =
869 this.displayStringFunction_(oppositeMode.getTitle()); 865 this.displayStringFunction_(oppositeMode.getTitle());
870 } 866 }
871 }; 867 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698