OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 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 Loading... |
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'); |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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; |
OLD | NEW |