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

Side by Side Diff: chrome/browser/resources/file_manager/foreground/js/photo/slide_mode.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 + rebased. 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 * Slide mode displays a single image and has a set of controls to navigate 8 * Slide mode displays a single image and has a set of controls to navigate
9 * between the images and to edit an image. 9 * between the images and to edit an image.
10 * 10 *
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 var overwriteOriginalBox = 109 var overwriteOriginalBox =
110 util.createChild(this.options_, 'overwrite-original'); 110 util.createChild(this.options_, 'overwrite-original');
111 111
112 this.overwriteOriginal_ = util.createChild( 112 this.overwriteOriginal_ = util.createChild(
113 overwriteOriginalBox, 'common white', 'input'); 113 overwriteOriginalBox, 'common white', 'input');
114 this.overwriteOriginal_.type = 'checkbox'; 114 this.overwriteOriginal_.type = 'checkbox';
115 this.overwriteOriginal_.id = 'overwrite-checkbox'; 115 this.overwriteOriginal_.id = 'overwrite-checkbox';
116 util.platform.getPreference(SlideMode.OVERWRITE_KEY, function(value) { 116 util.platform.getPreference(SlideMode.OVERWRITE_KEY, function(value) {
117 // Out-of-the box default is 'true' 117 // Out-of-the box default is 'true'
118 this.overwriteOriginal_.checked = 118 this.overwriteOriginal_.checked =
119 (typeof value != 'string' || value == 'true'); 119 (typeof value != 'string' || value === 'true');
hirono 2013/12/10 03:36:53 !== is preferred.
mtomasz 2013/12/10 05:07:01 Done.
120 }.bind(this)); 120 }.bind(this));
121 this.overwriteOriginal_.addEventListener('click', 121 this.overwriteOriginal_.addEventListener('click',
122 this.onOverwriteOriginalClick_.bind(this)); 122 this.onOverwriteOriginalClick_.bind(this));
123 123
124 var overwriteLabel = util.createChild(overwriteOriginalBox, '', 'label'); 124 var overwriteLabel = util.createChild(overwriteOriginalBox, '', 'label');
125 overwriteLabel.textContent = 125 overwriteLabel.textContent =
126 this.displayStringFunction_('GALLERY_OVERWRITE_ORIGINAL'); 126 this.displayStringFunction_('GALLERY_OVERWRITE_ORIGINAL');
127 overwriteLabel.setAttribute('for', 'overwrite-checkbox'); 127 overwriteLabel.setAttribute('for', 'overwrite-checkbox');
128 128
129 this.bubble_ = util.createChild(this.toolbar_, 'bubble'); 129 this.bubble_ = util.createChild(this.toolbar_, 'bubble');
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 261
262 // Wait 1000ms after the animation is done, then prefetch the next image. 262 // Wait 1000ms after the animation is done, then prefetch the next image.
263 this.requestPrefetch(1, delay + 1000); 263 this.requestPrefetch(1, delay + 1000);
264 264
265 if (loadCallback) loadCallback(); 265 if (loadCallback) loadCallback();
266 }.bind(this); 266 }.bind(this);
267 267
268 // The latest |leave| call might have left the image animating. Remove it. 268 // The latest |leave| call might have left the image animating. Remove it.
269 this.unloadImage_(); 269 this.unloadImage_();
270 270
271 if (this.getItemCount_() == 0) { 271 if (this.getItemCount_() === 0) {
272 this.displayedIndex_ = -1; 272 this.displayedIndex_ = -1;
273 //TODO(kaznacheev) Show this message in the grid mode too. 273 //TODO(kaznacheev) Show this message in the grid mode too.
274 this.showErrorBanner_('GALLERY_NO_IMAGES'); 274 this.showErrorBanner_('GALLERY_NO_IMAGES');
275 loadDone(); 275 loadDone();
276 } else { 276 } else {
277 // Remember the selection if it is empty or multiple. It will be restored 277 // Remember the selection if it is empty or multiple. It will be restored
278 // in |leave| if the user did not changing the selection manually. 278 // in |leave| if the user did not changing the selection manually.
279 var currentSelection = this.selectionModel_.selectedIndexes; 279 var currentSelection = this.selectionModel_.selectedIndexes;
280 if (currentSelection.length == 1) 280 if (currentSelection.length === 1)
281 this.savedSelection_ = null; 281 this.savedSelection_ = null;
282 else 282 else
283 this.savedSelection_ = currentSelection; 283 this.savedSelection_ = currentSelection;
284 284
285 // Ensure valid single selection. 285 // Ensure valid single selection.
286 // Note that the SlideMode object is not listening to selection change yet. 286 // Note that the SlideMode object is not listening to selection change yet.
287 this.select(Math.max(0, this.getSelectedIndex())); 287 this.select(Math.max(0, this.getSelectedIndex()));
288 this.displayedIndex_ = this.getSelectedIndex(); 288 this.displayedIndex_ = this.getSelectedIndex();
289 289
290 var selectedItem = this.getSelectedItem(); 290 var selectedItem = this.getSelectedItem();
291 var selectedUrl = selectedItem.getUrl();
292 // Show the selected item ASAP, then complete the initialization 291 // Show the selected item ASAP, then complete the initialization
293 // (loading the ribbon thumbnails can take some time). 292 // (loading the ribbon thumbnails can take some time).
294 this.metadataCache_.get(selectedUrl, Gallery.METADATA_TYPE, 293 this.metadataCache_.get(selectedItem.getEntry(), Gallery.METADATA_TYPE,
295 function(metadata) { 294 function(metadata) {
296 this.loadItem_(selectedUrl, metadata, 295 this.loadItem_(selectedItem.getEntry(), metadata,
297 zoomFromRect && this.imageView_.createZoomEffect(zoomFromRect), 296 zoomFromRect && this.imageView_.createZoomEffect(zoomFromRect),
298 displayCallback, loadDone); 297 displayCallback, loadDone);
299 }.bind(this)); 298 }.bind(this));
300 299
301 } 300 }
302 }; 301 };
303 302
304 /** 303 /**
305 * Leave the mode. 304 * Leave the mode.
306 * @param {Rect} zoomToRect Rectangle for zoom effect. 305 * @param {Rect} zoomToRect Rectangle for zoom effect.
(...skipping 10 matching lines...) Expand all
317 this.dataModel_.removeEventListener('splice', this.onSpliceBound_); 316 this.dataModel_.removeEventListener('splice', this.onSpliceBound_);
318 this.dataModel_.removeEventListener('content', this.onContentBound_); 317 this.dataModel_.removeEventListener('content', this.onContentBound_);
319 this.ribbon_.disable(); 318 this.ribbon_.disable();
320 this.active_ = false; 319 this.active_ = false;
321 if (this.savedSelection_) 320 if (this.savedSelection_)
322 this.selectionModel_.selectedIndexes = this.savedSelection_; 321 this.selectionModel_.selectedIndexes = this.savedSelection_;
323 this.unloadImage_(zoomToRect); 322 this.unloadImage_(zoomToRect);
324 callback(); 323 callback();
325 }.bind(this); 324 }.bind(this);
326 325
327 if (this.getItemCount_() == 0) { 326 if (this.getItemCount_() === 0) {
328 this.showErrorBanner_(false); 327 this.showErrorBanner_(false);
329 commitDone(); 328 commitDone();
330 } else { 329 } else {
331 this.commitItem_(commitDone); 330 this.commitItem_(commitDone);
332 } 331 }
333 332
334 // Disable the slide-mode only buttons when leaving. 333 // Disable the slide-mode only buttons when leaving.
335 this.editButton_.setAttribute('disabled', ''); 334 this.editButton_.setAttribute('disabled', '');
336 this.printButton_.setAttribute('disabled', ''); 335 this.printButton_.setAttribute('disabled', '');
337 }; 336 };
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 !util.isFullScreen(this.context_.appWindow)); 401 !util.isFullScreen(this.context_.appWindow));
403 }; 402 };
404 403
405 /** 404 /**
406 * Selection change handler. 405 * Selection change handler.
407 * 406 *
408 * Commits the current image and displays the newly selected image. 407 * Commits the current image and displays the newly selected image.
409 * @private 408 * @private
410 */ 409 */
411 SlideMode.prototype.onSelection_ = function() { 410 SlideMode.prototype.onSelection_ = function() {
412 if (this.selectionModel_.selectedIndexes.length == 0) 411 if (this.selectionModel_.selectedIndexes.length === 0)
413 return; // Temporary empty selection. 412 return; // Temporary empty selection.
414 413
415 // Forget the saved selection if the user changed the selection manually. 414 // Forget the saved selection if the user changed the selection manually.
416 if (!this.isSlideshowOn_()) 415 if (!this.isSlideshowOn_())
417 this.savedSelection_ = null; 416 this.savedSelection_ = null;
418 417
419 if (this.getSelectedIndex() == this.displayedIndex_) 418 if (this.getSelectedIndex() === this.displayedIndex_)
420 return; // Do not reselect. 419 return; // Do not reselect.
421 420
422 this.commitItem_(this.loadSelectedItem_.bind(this)); 421 this.commitItem_(this.loadSelectedItem_.bind(this));
423 }; 422 };
424 423
425 /** 424 /**
426 * Handles changes in tools visibility, and if the header is dimmed, then 425 * Handles changes in tools visibility, and if the header is dimmed, then
427 * requests disabling the draggable app region. 426 * requests disabling the draggable app region.
428 * 427 *
429 * @private 428 * @private
(...skipping 19 matching lines...) Expand all
449 /** 448 /**
450 * Load the selected item. 449 * Load the selected item.
451 * 450 *
452 * @private 451 * @private
453 */ 452 */
454 SlideMode.prototype.loadSelectedItem_ = function() { 453 SlideMode.prototype.loadSelectedItem_ = function() {
455 var slideHint = this.slideHint_; 454 var slideHint = this.slideHint_;
456 this.slideHint_ = undefined; 455 this.slideHint_ = undefined;
457 456
458 var index = this.getSelectedIndex(); 457 var index = this.getSelectedIndex();
459 if (index == this.displayedIndex_) 458 if (index === this.displayedIndex_)
460 return; // Do not reselect. 459 return; // Do not reselect.
461 460
462 var step = slideHint || (index - this.displayedIndex_); 461 var step = slideHint || (index - this.displayedIndex_);
463 462
464 if (Math.abs(step) != 1) { 463 if (Math.abs(step) != 1) {
465 // Long leap, the sequence is broken, we have no good prefetch candidate. 464 // Long leap, the sequence is broken, we have no good prefetch candidate.
466 this.sequenceDirection_ = 0; 465 this.sequenceDirection_ = 0;
467 this.sequenceLength_ = 0; 466 this.sequenceLength_ = 0;
468 } else if (this.sequenceDirection_ == step) { 467 } else if (this.sequenceDirection_ === step) {
469 // Keeping going in sequence. 468 // Keeping going in sequence.
470 this.sequenceLength_++; 469 this.sequenceLength_++;
471 } else { 470 } else {
472 // Reversed the direction. Reset the counter. 471 // Reversed the direction. Reset the counter.
473 this.sequenceDirection_ = step; 472 this.sequenceDirection_ = step;
474 this.sequenceLength_ = 1; 473 this.sequenceLength_ = 1;
475 } 474 }
476 475
477 if (this.sequenceLength_ <= 1) { 476 if (this.sequenceLength_ <= 1) {
478 // We have just broke the sequence. Touch the current image so that it stays 477 // We have just broke the sequence. Touch the current image so that it stays
479 // in the cache longer. 478 // in the cache longer.
480 this.imageView_.prefetch(this.imageView_.contentID_); 479 this.imageView_.prefetch(this.imageView_.contentEntry_);
481 } 480 }
482 481
483 this.displayedIndex_ = index; 482 this.displayedIndex_ = index;
484 483
485 function shouldPrefetch(loadType, step, sequenceLength) { 484 function shouldPrefetch(loadType, step, sequenceLength) {
486 // Never prefetch when selecting out of sequence. 485 // Never prefetch when selecting out of sequence.
487 if (Math.abs(step) != 1) 486 if (Math.abs(step) != 1)
488 return false; 487 return false;
489 488
490 // Never prefetch after a video load (decoding the next image can freeze 489 // Never prefetch after a video load (decoding the next image can freeze
491 // the UI for a second or two). 490 // the UI for a second or two).
492 if (loadType == ImageView.LOAD_TYPE_VIDEO_FILE) 491 if (loadType === ImageView.LOAD_TYPE_VIDEO_FILE)
493 return false; 492 return false;
494 493
495 // Always prefetch if the previous load was from cache. 494 // Always prefetch if the previous load was from cache.
496 if (loadType == ImageView.LOAD_TYPE_CACHED_FULL) 495 if (loadType === ImageView.LOAD_TYPE_CACHED_FULL)
497 return true; 496 return true;
498 497
499 // Prefetch if we have been going in the same direction for long enough. 498 // Prefetch if we have been going in the same direction for long enough.
500 return sequenceLength >= 3; 499 return sequenceLength >= 3;
501 } 500 }
502 501
503 var selectedItem = this.getSelectedItem(); 502 var selectedItem = this.getSelectedItem();
504 this.currentUniqueKey_++; 503 this.currentUniqueKey_++;
505 var selectedUniqueKey = this.currentUniqueKey_; 504 var selectedUniqueKey = this.currentUniqueKey_;
506 var onMetadata = function(metadata) { 505 var onMetadata = function(metadata) {
507 // Discard, since another load has been invoked after this one. 506 // Discard, since another load has been invoked after this one.
508 if (selectedUniqueKey != this.currentUniqueKey_) return; 507 if (selectedUniqueKey != this.currentUniqueKey_) return;
509 this.loadItem_(selectedItem.getUrl(), metadata, 508 this.loadItem_(selectedItem.getEntry(), metadata,
510 new ImageView.Effect.Slide(step, this.isSlideshowPlaying_()), 509 new ImageView.Effect.Slide(step, this.isSlideshowPlaying_()),
511 function() {} /* no displayCallback */, 510 function() {} /* no displayCallback */,
512 function(loadType, delay) { 511 function(loadType, delay) {
513 // Discard, since another load has been invoked after this one. 512 // Discard, since another load has been invoked after this one.
514 if (selectedUniqueKey != this.currentUniqueKey_) return; 513 if (selectedUniqueKey != this.currentUniqueKey_) return;
515 if (shouldPrefetch(loadType, step, this.sequenceLength_)) { 514 if (shouldPrefetch(loadType, step, this.sequenceLength_)) {
516 this.requestPrefetch(step, delay); 515 this.requestPrefetch(step, delay);
517 } 516 }
518 if (this.isSlideshowPlaying_()) 517 if (this.isSlideshowPlaying_())
519 this.scheduleNextSlide_(); 518 this.scheduleNextSlide_();
520 }.bind(this)); 519 }.bind(this));
521 }.bind(this); 520 }.bind(this);
522 this.metadataCache_.get( 521 this.metadataCache_.get(
523 selectedItem.getUrl(), Gallery.METADATA_TYPE, onMetadata); 522 selectedItem.getEntry(), Gallery.METADATA_TYPE, onMetadata);
524 }; 523 };
525 524
526 /** 525 /**
527 * Unload the current image. 526 * Unload the current image.
528 * 527 *
529 * @param {Rect} zoomToRect Rectangle for zoom effect. 528 * @param {Rect} zoomToRect Rectangle for zoom effect.
530 * @private 529 * @private
531 */ 530 */
532 SlideMode.prototype.unloadImage_ = function(zoomToRect) { 531 SlideMode.prototype.unloadImage_ = function(zoomToRect) {
533 this.imageView_.unload(zoomToRect); 532 this.imageView_.unload(zoomToRect);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 /** 573 /**
575 * @param {number} direction -1 for left, 1 for right. 574 * @param {number} direction -1 for left, 1 for right.
576 * @return {number} Next index in the given direction, with wrapping. 575 * @return {number} Next index in the given direction, with wrapping.
577 * @private 576 * @private
578 */ 577 */
579 SlideMode.prototype.getNextSelectedIndex_ = function(direction) { 578 SlideMode.prototype.getNextSelectedIndex_ = function(direction) {
580 function advance(index, limit) { 579 function advance(index, limit) {
581 index += (direction > 0 ? 1 : -1); 580 index += (direction > 0 ? 1 : -1);
582 if (index < 0) 581 if (index < 0)
583 return limit - 1; 582 return limit - 1;
584 if (index == limit) 583 if (index === limit)
585 return 0; 584 return 0;
586 return index; 585 return index;
587 } 586 }
588 587
589 // If the saved selection is multiple the Slideshow should cycle through 588 // If the saved selection is multiple the Slideshow should cycle through
590 // the saved selection. 589 // the saved selection.
591 if (this.isSlideshowOn_() && 590 if (this.isSlideshowOn_() &&
592 this.savedSelection_ && this.savedSelection_.length > 1) { 591 this.savedSelection_ && this.savedSelection_.length > 1) {
593 var pos = advance(this.savedSelection_.indexOf(this.getSelectedIndex()), 592 var pos = advance(this.savedSelection_.indexOf(this.getSelectedIndex()),
594 this.savedSelection_.length); 593 this.savedSelection_.length);
595 return this.savedSelection_[pos]; 594 return this.savedSelection_[pos];
596 } else { 595 } else {
597 return advance(this.getSelectedIndex(), this.getItemCount_()); 596 return advance(this.getSelectedIndex(), this.getItemCount_());
598 } 597 }
599 }; 598 };
600 599
601 /** 600 /**
602 * Advance the selection based on the pressed key ID. 601 * Advance the selection based on the pressed key ID.
603 * @param {string} keyID Key identifier. 602 * @param {string} keyID Key identifier.
604 */ 603 */
605 SlideMode.prototype.advanceWithKeyboard = function(keyID) { 604 SlideMode.prototype.advanceWithKeyboard = function(keyID) {
606 this.advanceManually(keyID == 'Up' || keyID == 'Left' ? -1 : 1); 605 this.advanceManually(keyID === 'Up' || keyID === 'Left' ? -1 : 1);
607 }; 606 };
608 607
609 /** 608 /**
610 * Advance the selection as a result of a user action (as opposed to an 609 * Advance the selection as a result of a user action (as opposed to an
611 * automatic change in the slideshow mode). 610 * automatic change in the slideshow mode).
612 * @param {number} direction -1 for left, 1 for right. 611 * @param {number} direction -1 for left, 1 for right.
613 */ 612 */
614 SlideMode.prototype.advanceManually = function(direction) { 613 SlideMode.prototype.advanceManually = function(direction) {
615 if (this.isSlideshowPlaying_()) { 614 if (this.isSlideshowPlaying_()) {
616 this.pauseSlideshow_(); 615 this.pauseSlideshow_();
(...skipping 22 matching lines...) Expand all
639 */ 638 */
640 SlideMode.prototype.selectLast = function() { 639 SlideMode.prototype.selectLast = function() {
641 this.select(this.getItemCount_() - 1); 640 this.select(this.getItemCount_() - 1);
642 }; 641 };
643 642
644 // Loading/unloading 643 // Loading/unloading
645 644
646 /** 645 /**
647 * Load and display an item. 646 * Load and display an item.
648 * 647 *
649 * @param {string} url Item url. 648 * @param {FileEntry} entry Item entry to be loaded.
650 * @param {Object} metadata Item metadata. 649 * @param {Object} metadata Item metadata.
651 * @param {Object} effect Transition effect object. 650 * @param {Object} effect Transition effect object.
652 * @param {function} displayCallback Called when the image is displayed 651 * @param {function} displayCallback Called when the image is displayed
653 * (which can happen before the image load due to caching). 652 * (which can happen before the image load due to caching).
654 * @param {function} loadCallback Called when the image is fully loaded. 653 * @param {function} loadCallback Called when the image is fully loaded.
655 * @private 654 * @private
656 */ 655 */
657 SlideMode.prototype.loadItem_ = function( 656 SlideMode.prototype.loadItem_ = function(
658 url, metadata, effect, displayCallback, loadCallback) { 657 entry, metadata, effect, displayCallback, loadCallback) {
659 this.selectedImageMetadata_ = MetadataCache.cloneMetadata(metadata); 658 this.selectedImageMetadata_ = MetadataCache.cloneMetadata(metadata);
660 659
661 this.showSpinner_(true); 660 this.showSpinner_(true);
662 661
663 var loadDone = function(loadType, delay, error) { 662 var loadDone = function(loadType, delay, error) {
664 var video = this.isShowingVideo_(); 663 var video = this.isShowingVideo_();
665 ImageUtil.setAttribute(this.container_, 'video', video); 664 ImageUtil.setAttribute(this.container_, 'video', video);
666 665
667 this.showSpinner_(false); 666 this.showSpinner_(false);
668 if (loadType == ImageView.LOAD_TYPE_ERROR) { 667 if (loadType === ImageView.LOAD_TYPE_ERROR) {
669 // if we have a specific error, then display it 668 // if we have a specific error, then display it
670 if (error) { 669 if (error) {
671 this.showErrorBanner_(error); 670 this.showErrorBanner_(error);
672 } else { 671 } else {
673 // otherwise try to infer general error 672 // otherwise try to infer general error
674 this.showErrorBanner_( 673 this.showErrorBanner_(
675 video ? 'GALLERY_VIDEO_ERROR' : 'GALLERY_IMAGE_ERROR'); 674 video ? 'GALLERY_VIDEO_ERROR' : 'GALLERY_IMAGE_ERROR');
676 } 675 }
677 } else if (loadType == ImageView.LOAD_TYPE_OFFLINE) { 676 } else if (loadType === ImageView.LOAD_TYPE_OFFLINE) {
678 this.showErrorBanner_( 677 this.showErrorBanner_(
679 video ? 'GALLERY_VIDEO_OFFLINE' : 'GALLERY_IMAGE_OFFLINE'); 678 video ? 'GALLERY_VIDEO_OFFLINE' : 'GALLERY_IMAGE_OFFLINE');
680 } 679 }
681 680
682 if (video) { 681 if (video) {
683 // The editor toolbar does not make sense for video, hide it. 682 // The editor toolbar does not make sense for video, hide it.
684 this.stopEditing_(); 683 this.stopEditing_();
685 this.mediaControls_.attachMedia(this.imageView_.getVideo()); 684 this.mediaControls_.attachMedia(this.imageView_.getVideo());
686 685
687 // TODO(kaznacheev): Add metrics for video playback. 686 // TODO(kaznacheev): Add metrics for video playback.
688 } else { 687 } else {
689 ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('View')); 688 ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('View'));
690 689
691 var toMillions = function(number) { 690 var toMillions = function(number) {
692 return Math.round(number / (1000 * 1000)); 691 return Math.round(number / (1000 * 1000));
693 }; 692 };
694 693
695 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MB'), 694 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MB'),
696 toMillions(metadata.filesystem.size)); 695 toMillions(metadata.filesystem.size));
697 696
698 var canvas = this.imageView_.getCanvas(); 697 var canvas = this.imageView_.getCanvas();
699 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MPix'), 698 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MPix'),
700 toMillions(canvas.width * canvas.height)); 699 toMillions(canvas.width * canvas.height));
701 700
702 var extIndex = url.lastIndexOf('.'); 701 var extIndex = entry.name.lastIndexOf('.');
703 var ext = extIndex < 0 ? '' : url.substr(extIndex + 1).toLowerCase(); 702 var ext = extIndex < 0 ? '' :
704 if (ext == 'jpeg') ext = 'jpg'; 703 entry.name.substr(extIndex + 1).toLowerCase();
704 if (ext === 'jpeg') ext = 'jpg';
705 ImageUtil.metrics.recordEnum( 705 ImageUtil.metrics.recordEnum(
706 ImageUtil.getMetricName('FileType'), ext, ImageUtil.FILE_TYPES); 706 ImageUtil.getMetricName('FileType'), ext, ImageUtil.FILE_TYPES);
707 } 707 }
708 708
709 // Enable or disable buttons for editing and printing. 709 // Enable or disable buttons for editing and printing.
710 if (video || error) { 710 if (video || error) {
711 this.editButton_.setAttribute('disabled', ''); 711 this.editButton_.setAttribute('disabled', '');
712 this.printButton_.setAttribute('disabled', ''); 712 this.printButton_.setAttribute('disabled', '');
713 } else { 713 } else {
714 this.editButton_.removeAttribute('disabled'); 714 this.editButton_.removeAttribute('disabled');
715 this.printButton_.removeAttribute('disabled'); 715 this.printButton_.removeAttribute('disabled');
716 } 716 }
717 717
718 // For once edited image, disallow the 'overwrite' setting change. 718 // For once edited image, disallow the 'overwrite' setting change.
719 ImageUtil.setAttribute(this.options_, 'saved', 719 ImageUtil.setAttribute(this.options_, 'saved',
720 !this.getSelectedItem().isOriginal()); 720 !this.getSelectedItem().isOriginal());
721 721
722 util.platform.getPreference(SlideMode.OVERWRITE_BUBBLE_KEY, 722 util.platform.getPreference(SlideMode.OVERWRITE_BUBBLE_KEY,
723 function(value) { 723 function(value) {
724 var times = typeof value == 'string' ? parseInt(value, 10) : 0; 724 var times = typeof value === 'string' ? parseInt(value, 10) : 0;
725 if (times < SlideMode.OVERWRITE_BUBBLE_MAX_TIMES) { 725 if (times < SlideMode.OVERWRITE_BUBBLE_MAX_TIMES) {
726 this.bubble_.hidden = false; 726 this.bubble_.hidden = false;
727 if (this.isEditing()) { 727 if (this.isEditing()) {
728 util.platform.setPreference( 728 util.platform.setPreference(
729 SlideMode.OVERWRITE_BUBBLE_KEY, times + 1); 729 SlideMode.OVERWRITE_BUBBLE_KEY, times + 1);
730 } 730 }
731 } 731 }
732 }.bind(this)); 732 }.bind(this));
733 733
734 loadCallback(loadType, delay); 734 loadCallback(loadType, delay);
735 }.bind(this); 735 }.bind(this);
736 736
737 var displayDone = function() { 737 var displayDone = function() {
738 cr.dispatchSimpleEvent(this, 'image-displayed'); 738 cr.dispatchSimpleEvent(this, 'image-displayed');
739 displayCallback(); 739 displayCallback();
740 }.bind(this); 740 }.bind(this);
741 741
742 this.editor_.openSession(url, metadata, effect, 742 this.editor_.openSession(entry, metadata, effect,
743 this.saveCurrentImage_.bind(this), displayDone, loadDone); 743 this.saveCurrentImage_.bind(this), displayDone, loadDone);
744 }; 744 };
745 745
746 /** 746 /**
747 * Commit changes to the current item and reset all messages/indicators. 747 * Commit changes to the current item and reset all messages/indicators.
748 * 748 *
749 * @param {function} callback Callback. 749 * @param {function} callback Callback.
750 * @private 750 * @private
751 */ 751 */
752 SlideMode.prototype.commitItem_ = function(callback) { 752 SlideMode.prototype.commitItem_ = function(callback) {
(...skipping 21 matching lines...) Expand all
774 * Request a prefetch for the next image. 774 * Request a prefetch for the next image.
775 * 775 *
776 * @param {number} direction -1 or 1. 776 * @param {number} direction -1 or 1.
777 * @param {number} delay Delay in ms. Used to prevent the CPU-heavy image 777 * @param {number} delay Delay in ms. Used to prevent the CPU-heavy image
778 * loading from disrupting the animation that might be still in progress. 778 * loading from disrupting the animation that might be still in progress.
779 */ 779 */
780 SlideMode.prototype.requestPrefetch = function(direction, delay) { 780 SlideMode.prototype.requestPrefetch = function(direction, delay) {
781 if (this.getItemCount_() <= 1) return; 781 if (this.getItemCount_() <= 1) return;
782 782
783 var index = this.getNextSelectedIndex_(direction); 783 var index = this.getNextSelectedIndex_(direction);
784 var nextItemUrl = this.getItem(index).getUrl(); 784 var nextItemEntry = this.getItem(index).getEntry();
785 this.imageView_.prefetch(nextItemUrl, delay); 785 this.imageView_.prefetch(nextItemEntry, delay);
786 }; 786 };
787 787
788 // Event handlers. 788 // Event handlers.
789 789
790 /** 790 /**
791 * Unload handler, to be called from the top frame. 791 * Unload handler, to be called from the top frame.
792 * @param {boolean} exiting True if the app is exiting. 792 * @param {boolean} exiting True if the app is exiting.
793 */ 793 */
794 SlideMode.prototype.onUnload = function(exiting) { 794 SlideMode.prototype.onUnload = function(exiting) {
795 if (this.isShowingVideo_() && this.mediaControls_.isPlaying()) { 795 if (this.isShowingVideo_() && this.mediaControls_.isPlaying()) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 // Saving 935 // Saving
936 936
937 /** 937 /**
938 * Save the current image to a file. 938 * Save the current image to a file.
939 * 939 *
940 * @param {function} callback Callback. 940 * @param {function} callback Callback.
941 * @private 941 * @private
942 */ 942 */
943 SlideMode.prototype.saveCurrentImage_ = function(callback) { 943 SlideMode.prototype.saveCurrentImage_ = function(callback) {
944 var item = this.getSelectedItem(); 944 var item = this.getSelectedItem();
945 var oldUrl = item.getUrl(); 945 var oldEntry = item.getEntry();
946 var canvas = this.imageView_.getCanvas(); 946 var canvas = this.imageView_.getCanvas();
947 947
948 this.showSpinner_(true); 948 this.showSpinner_(true);
949 var metadataEncoder = ImageEncoder.encodeMetadata( 949 var metadataEncoder = ImageEncoder.encodeMetadata(
950 this.selectedImageMetadata_.media, canvas, 1 /* quality */); 950 this.selectedImageMetadata_.media, canvas, 1 /* quality */);
951 951
952 this.selectedImageMetadata_ = ContentProvider.ConvertContentMetadata( 952 this.selectedImageMetadata_ = ContentProvider.ConvertContentMetadata(
953 metadataEncoder.getMetadata(), this.selectedImageMetadata_); 953 metadataEncoder.getMetadata(), this.selectedImageMetadata_);
954 954
955 item.saveToFile( 955 item.saveToFile(
956 this.context_.saveDirEntry, 956 this.context_.saveDirEntry,
957 this.shouldOverwriteOriginal_(), 957 this.shouldOverwriteOriginal_(),
958 canvas, 958 canvas,
959 metadataEncoder, 959 metadataEncoder,
960 function(success) { 960 function(success) {
961 // TODO(kaznacheev): Implement write error handling. 961 // TODO(kaznacheev): Implement write error handling.
962 // Until then pretend that the save succeeded. 962 // Until then pretend that the save succeeded.
963 this.showSpinner_(false); 963 this.showSpinner_(false);
964 this.flashSavedLabel_(); 964 this.flashSavedLabel_();
965 965
966 var e = new Event('content'); 966 var event = new Event('content');
967 e.item = item; 967 event.item = item;
968 e.oldUrl = oldUrl; 968 event.oldEntry = oldEntry;
969 e.metadata = this.selectedImageMetadata_; 969 event.metadata = this.selectedImageMetadata_;
970 this.dataModel_.dispatchEvent(e); 970 this.dataModel_.dispatchEvent(event);
971 971
972 // Allow changing the 'Overwrite original' setting only if the user 972 // Allow changing the 'Overwrite original' setting only if the user
973 // used Undo to restore the original image AND it is not a copy. 973 // used Undo to restore the original image AND it is not a copy.
974 // Otherwise lock the setting in its current state. 974 // Otherwise lock the setting in its current state.
975 var mayChangeOverwrite = !this.editor_.canUndo() && item.isOriginal(); 975 var mayChangeOverwrite = !this.editor_.canUndo() && item.isOriginal();
976 ImageUtil.setAttribute(this.options_, 'saved', !mayChangeOverwrite); 976 ImageUtil.setAttribute(this.options_, 'saved', !mayChangeOverwrite);
977 977
978 if (this.imageView_.getContentRevision() == 1) { // First edit. 978 if (this.imageView_.getContentRevision() === 1) { // First edit.
979 ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit')); 979 ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit'));
980 } 980 }
981 981
982 if (oldUrl != item.getUrl()) { 982 if (util.isSameEntry(oldEntry, item.getEntry())) {
983 this.dataModel_.splice( 983 this.dataModel_.splice(
984 this.getSelectedIndex(), 0, new Gallery.Item(oldUrl)); 984 this.getSelectedIndex(), 0, new Gallery.Item(oldEntry));
985 // The ribbon will ignore the splice above and redraw after the 985 // The ribbon will ignore the splice above and redraw after the
986 // select call below (while being obscured by the Editor toolbar, 986 // select call below (while being obscured by the Editor toolbar,
987 // so there is no need for nice animation here). 987 // so there is no need for nice animation here).
988 // SlideMode will ignore the selection change as the displayed item 988 // SlideMode will ignore the selection change as the displayed item
989 // index has not changed. 989 // index has not changed.
990 this.select(++this.displayedIndex_); 990 this.select(++this.displayedIndex_);
991 } 991 }
992 callback(); 992 callback();
993 cr.dispatchSimpleEvent(this, 'image-saved'); 993 cr.dispatchSimpleEvent(this, 'image-saved');
994 }.bind(this)); 994 }.bind(this));
995 }; 995 };
996 996
997 /** 997 /**
998 * Update caches when the selected item url has changed. 998 * Update caches when the selected item has been renamed.
999 *
1000 * @param {Event} event Event. 999 * @param {Event} event Event.
1001 * @private 1000 * @private
1002 */ 1001 */
1003 SlideMode.prototype.onContentChange_ = function(event) { 1002 SlideMode.prototype.onContentChange_ = function(event) {
1004 var newUrl = event.item.getUrl(); 1003 var newEntry = event.item.getEntry();
1005 if (newUrl != event.oldUrl) { 1004 if (util.isSameEntry(newEntry, event.oldEntry))
1006 this.imageView_.changeUrl(newUrl); 1005 this.imageView_.changeEntry(newEntry);
1007 } 1006 this.metadataCache_.clear(event.oldEntry, Gallery.METADATA_TYPE);
1008 this.metadataCache_.clear(event.oldUrl, Gallery.METADATA_TYPE);
1009 }; 1007 };
1010 1008
1011 /** 1009 /**
1012 * Flash 'Saved' label briefly to indicate that the image has been saved. 1010 * Flash 'Saved' label briefly to indicate that the image has been saved.
1013 * @private 1011 * @private
1014 */ 1012 */
1015 SlideMode.prototype.flashSavedLabel_ = function() { 1013 SlideMode.prototype.flashSavedLabel_ = function() {
1016 var setLabelHighlighted = 1014 var setLabelHighlighted =
1017 ImageUtil.setAttribute.bind(null, this.savedLabel_, 'highlighted'); 1015 ImageUtil.setAttribute.bind(null, this.savedLabel_, 'highlighted');
1018 setTimeout(setLabelHighlighted.bind(null, true), 0); 1016 setTimeout(setLabelHighlighted.bind(null, true), 0);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 this.leaveAfterSlideshow_ = false; 1150 this.leaveAfterSlideshow_ = false;
1153 setTimeout(this.toggleMode_.bind(this), toggleModeDelay); 1151 setTimeout(this.toggleMode_.bind(this), toggleModeDelay);
1154 } 1152 }
1155 }; 1153 };
1156 1154
1157 /** 1155 /**
1158 * @return {boolean} True if the slideshow is playing (not paused). 1156 * @return {boolean} True if the slideshow is playing (not paused).
1159 * @private 1157 * @private
1160 */ 1158 */
1161 SlideMode.prototype.isSlideshowPlaying_ = function() { 1159 SlideMode.prototype.isSlideshowPlaying_ = function() {
1162 return this.container_.getAttribute('slideshow') == 'playing'; 1160 return this.container_.getAttribute('slideshow') === 'playing';
1163 }; 1161 };
1164 1162
1165 /** 1163 /**
1166 * Pause/resume the slideshow. 1164 * Pause/resume the slideshow.
1167 * @private 1165 * @private
1168 */ 1166 */
1169 SlideMode.prototype.toggleSlideshowPause_ = function() { 1167 SlideMode.prototype.toggleSlideshowPause_ = function() {
1170 cr.dispatchSimpleEvent(this, 'useraction'); // Show the tools. 1168 cr.dispatchSimpleEvent(this, 'useraction'); // Show the tools.
1171 if (this.isSlideshowPlaying_()) { 1169 if (this.isSlideshowPlaying_()) {
1172 this.pauseSlideshow_(); 1170 this.pauseSlideshow_();
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 done = true; 1345 done = true;
1348 } 1346 }
1349 }.bind(this); 1347 }.bind(this);
1350 }; 1348 };
1351 1349
1352 /** 1350 /**
1353 * If the user touched the image and moved the finger more than SWIPE_THRESHOLD 1351 * If the user touched the image and moved the finger more than SWIPE_THRESHOLD
1354 * horizontally it's considered as a swipe gesture (change the current image). 1352 * horizontally it's considered as a swipe gesture (change the current image).
1355 */ 1353 */
1356 SwipeOverlay.SWIPE_THRESHOLD = 100; 1354 SwipeOverlay.SWIPE_THRESHOLD = 100;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698