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 /* | 5 /* |
6 * Base class that Ribbon uses to display photos. | 6 * Base class that Ribbon uses to display photos. |
7 */ | 7 */ |
8 | 8 |
9 function RibbonClient() {} | 9 function RibbonClient() {} |
10 | 10 |
11 RibbonClient.prototype.prefetchImage = function(id, content, metadata) {}; | 11 RibbonClient.prototype.prefetchImage = function(id, url) {}; |
12 | 12 |
13 RibbonClient.prototype.openImage = function(id, content, metadata, direction) { | 13 RibbonClient.prototype.openImage = function(id, url, metadata, direction) { |
14 }; | 14 }; |
15 | 15 |
16 RibbonClient.prototype.closeImage = function(item) {}; | 16 RibbonClient.prototype.closeImage = function(item) {}; |
17 | 17 |
18 /** | 18 /** |
19 * Image gallery for viewing and editing image files. | 19 * Image gallery for viewing and editing image files. |
20 * | 20 * |
21 * @param {HTMLDivElement} container | 21 * @param {HTMLDivElement} container |
22 * @param {Object} context Object containing the following: | 22 * @param {Object} context Object containing the following: |
23 * {function(string)} onNameChange Called every time a selected | 23 * {function(string)} onNameChange Called every time a selected |
(...skipping 13 matching lines...) Expand all Loading... | |
37 var strf = context.displayStringFunction; | 37 var strf = context.displayStringFunction; |
38 this.displayStringFunction_ = function(id, formatArgs) { | 38 this.displayStringFunction_ = function(id, formatArgs) { |
39 var args = Array.prototype.slice.call(arguments); | 39 var args = Array.prototype.slice.call(arguments); |
40 args[0] = 'GALLERY_' + id.toUpperCase(); | 40 args[0] = 'GALLERY_' + id.toUpperCase(); |
41 return strf.apply(null, args); | 41 return strf.apply(null, args); |
42 }; | 42 }; |
43 | 43 |
44 this.onFadeTimeoutBound_ = this.onFadeTimeout_.bind(this); | 44 this.onFadeTimeoutBound_ = this.onFadeTimeout_.bind(this); |
45 this.fadeTimeoutId_ = null; | 45 this.fadeTimeoutId_ = null; |
46 this.mouseOverTool_ = false; | 46 this.mouseOverTool_ = false; |
47 this.imageChanges_ = 0; | |
48 | 47 |
49 this.initDom_(); | 48 this.initDom_(); |
50 } | 49 } |
51 | 50 |
52 Gallery.prototype = { __proto__: RibbonClient.prototype }; | 51 Gallery.prototype = { __proto__: RibbonClient.prototype }; |
53 | 52 |
54 Gallery.open = function(context, items, selectedItem) { | 53 Gallery.open = function(context, items, selectedItem) { |
55 var container = document.querySelector('.gallery'); | 54 var container = document.querySelector('.gallery'); |
56 ImageUtil.removeChildren(container); | 55 ImageUtil.removeChildren(container); |
57 var gallery = new Gallery(container, context); | 56 var gallery = new Gallery(container, context); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 // Append a file name after an anchor so that the Gallery | 304 // Append a file name after an anchor so that the Gallery |
306 // code can find the file extension at the end of the url. | 305 // code can find the file extension at the end of the url. |
307 // A File instance contains the real file name in the 'name' property. | 306 // A File instance contains the real file name in the 'name' property. |
308 // For a Blob instance we make up a fake file name out of the mime type | 307 // For a Blob instance we make up a fake file name out of the mime type |
309 // (image/jpeg -> image.jpg). | 308 // (image/jpeg -> image.jpg). |
310 return window.webkitURL.createObjectURL(blob) + | 309 return window.webkitURL.createObjectURL(blob) + |
311 '#' + (blob.name || (blob.type.replace('/', '.'))); | 310 '#' + (blob.name || (blob.type.replace('/', '.'))); |
312 }; | 311 }; |
313 | 312 |
314 Gallery.prototype.onBeforeUnload_ = function(event) { | 313 Gallery.prototype.onBeforeUnload_ = function(event) { |
315 if (this.imageChanges_ > 0) { | 314 if (this.editor_.isBusy()) |
316 setTimeout(this.saveChanges_.bind(this), 1000); | |
317 return this.displayStringFunction_('unsaved_changes'); | 315 return this.displayStringFunction_('unsaved_changes'); |
318 } | |
319 return null; | 316 return null; |
320 }; | 317 }; |
321 | 318 |
322 Gallery.prototype.load = function(items, selectedItem) { | 319 Gallery.prototype.load = function(items, selectedItem) { |
323 var urls = []; | 320 var urls = []; |
324 var selectedIndex = -1; | 321 var selectedIndex = -1; |
325 | 322 |
326 // Convert canvas and blob items to blob urls. | 323 // Convert canvas and blob items to blob urls. |
327 for (var i = 0; i != items.length; i++) { | 324 for (var i = 0; i != items.length; i++) { |
328 var item = items[i]; | 325 var item = items[i]; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 this.toolbar_, tasks, | 377 this.toolbar_, tasks, |
381 this.onShare_.bind(this), this.onActionExecute_.bind(this), | 378 this.onShare_.bind(this), this.onActionExecute_.bind(this), |
382 this.displayStringFunction_); | 379 this.displayStringFunction_); |
383 } else { | 380 } else { |
384 this.shareMode_ = null; | 381 this.shareMode_ = null; |
385 } | 382 } |
386 }.bind(this)); | 383 }.bind(this)); |
387 }; | 384 }; |
388 | 385 |
389 Gallery.prototype.onImageContentChanged_ = function() { | 386 Gallery.prototype.onImageContentChanged_ = function() { |
390 this.imageChanges_++; | 387 var revision = this.imageView_.getContentRevision(); |
391 if (this.imageChanges_ == 0) return; | 388 if (revision == 0) return; // Just loaded. |
392 | 389 |
393 if (this.imageChanges_ == 1) { | 390 if (revision == 1) { |
394 // First edit. | 391 // First edit. |
395 this.filenameSpacer_.setAttribute('saved', 'saved'); | 392 this.filenameSpacer_.setAttribute('saved', 'saved'); |
396 this.filenameSpacer_.setAttribute('overwrite', 'overwrite'); | 393 this.filenameSpacer_.setAttribute('overwrite', 'overwrite'); |
397 | 394 |
398 var key = 'gallery-overwrite-original'; | 395 var key = 'gallery-overwrite-original'; |
399 var overwrite = key in localStorage ? (localStorage[key] == "true") : true; | 396 var overwrite = key in localStorage ? (localStorage[key] == "true") : true; |
400 this.overwriteOriginal_.checked = overwrite; | 397 this.overwriteOriginal_.checked = overwrite; |
401 this.applyOverwrite_(overwrite); | 398 this.applyOverwrite_(overwrite); |
402 | 399 |
403 key = 'gallery-overwrite-bubble'; | 400 key = 'gallery-overwrite-bubble'; |
404 var times = key in localStorage ? parseInt(localStorage[key], 10) : 0; | 401 var times = key in localStorage ? parseInt(localStorage[key], 10) : 0; |
405 if (times < Gallery.OVERWRITE_BUBBLE_MAX_TIMES) { | 402 if (times < Gallery.OVERWRITE_BUBBLE_MAX_TIMES) { |
406 this.bubble_.removeAttribute('hidden'); | 403 this.bubble_.removeAttribute('hidden'); |
407 localStorage[key] = times + 1; | 404 localStorage[key] = times + 1; |
408 } | 405 } |
409 | 406 |
410 ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit')); | 407 ImageUtil.metrics.recordUserAction(ImageUtil.getMetricName('Edit')); |
411 } | 408 } |
409 }; | |
412 | 410 |
411 Gallery.prototype.flashSavedLabel_ = function() { | |
413 var label = this.savedLabel_; | 412 var label = this.savedLabel_; |
414 setTimeout(function(){ label.setAttribute('highlighted', 'true'); }, 0); | 413 setTimeout(function(){ label.setAttribute('highlighted', 'true'); }, 0); |
415 setTimeout(function(){ label.removeAttribute('highlighted'); }, 300); | 414 setTimeout(function(){ label.removeAttribute('highlighted'); }, 300); |
416 }; | 415 }; |
417 | 416 |
418 Gallery.prototype.applyOverwrite_ = function(overwrite) { | 417 Gallery.prototype.applyOverwrite_ = function(overwrite) { |
419 if (overwrite) { | 418 if (overwrite) { |
420 this.ribbon_.getSelectedItem().setOriginalName(this.context_.saveDirEntry, | 419 this.ribbon_.getSelectedItem().setOriginalName(this.context_.saveDirEntry, |
421 this.updateFilename_.bind(this)); | 420 this.updateFilename_.bind(this)); |
422 } else { | 421 } else { |
423 this.ribbon_.getSelectedItem().setCopyName(this.context_.saveDirEntry, | 422 this.ribbon_.getSelectedItem().setCopyName(this.context_.saveDirEntry, |
424 this.updateFilename_.bind(this)); | 423 this.selectedImageMetadata_, |
424 this.updateFilename_.bind(this)); | |
425 } | 425 } |
426 }; | 426 }; |
427 | 427 |
428 Gallery.prototype.onOverwriteOriginalClick_ = function(event) { | 428 Gallery.prototype.onOverwriteOriginalClick_ = function(event) { |
429 var overwrite = event.target.checked; | 429 var overwrite = event.target.checked; |
430 localStorage['gallery-overwrite-original'] = overwrite; | 430 localStorage['gallery-overwrite-original'] = overwrite; |
431 this.applyOverwrite_(overwrite); | 431 this.applyOverwrite_(overwrite); |
432 }; | 432 }; |
433 | 433 |
434 Gallery.prototype.onCloseBubble_ = function(event) { | 434 Gallery.prototype.onCloseBubble_ = function(event) { |
435 this.bubble_.setAttribute('hidden', 'hidden'); | 435 this.bubble_.setAttribute('hidden', 'hidden'); |
436 localStorage['gallery-overwrite-bubble'] = Gallery.OVERWRITE_BUBBLE_MAX_TIMES; | 436 localStorage['gallery-overwrite-bubble'] = Gallery.OVERWRITE_BUBBLE_MAX_TIMES; |
437 }; | 437 }; |
438 | 438 |
439 Gallery.prototype.saveItem_ = function(item, callback, canvas, modified) { | 439 Gallery.prototype.saveCurrentImage_ = function(callback) { |
440 if (modified) { | 440 var item = this.ribbon_.getSelectedItem(); |
441 item.save(this.context_.saveDirEntry, this.context_.metadataProvider, | 441 var canvas = this.imageView_.getCanvas(); |
442 canvas, callback); | |
443 } else { | |
444 if (callback) callback(); | |
445 } | |
446 }; | |
447 | 442 |
448 Gallery.prototype.saveChanges_ = function(opt_callback) { | 443 var metadataEncoder = ImageEncoder.encodeMetadata( |
449 this.imageChanges_ = 0; | 444 this.selectedImageMetadata_, canvas, 1); |
dgozman
2012/05/16 16:05:40
Comment what 1 means.
Vladislav Kaznacheev
2012/05/17 09:04:40
Done.
| |
450 this.bubble_.setAttribute('hidden', 'hidden'); | 445 |
451 if (this.isShowingVideo_()) { | 446 this.selectedImageMetadata_ = metadataEncoder.getMetadata(); |
452 // This call ensures that editor leaves the mode and closes respective UI | 447 item.setThumbnail(this.selectedImageMetadata_); |
453 // elements. Currently, the only mode for videos is sharing. | 448 |
454 this.editor_.leaveModeGently(); | 449 item.saveToFile( |
455 if (opt_callback) opt_callback(); | 450 this.context_.saveDirEntry, |
456 return; | 451 canvas, |
457 } | 452 metadataEncoder, |
458 this.editor_.requestImage( | 453 function(success) { |
459 this.saveItem_.bind(this, this.ribbon_.getSelectedItem(), opt_callback)); | 454 // TODO(kaznacheev): Implement write error handling. |
455 // Until then pretend that the save succeeded. | |
456 this.flashSavedLabel_(); | |
457 this.context_.metadataProvider.reset(item.getUrl()); | |
458 callback(); | |
459 }.bind(this)); | |
460 }; | 460 }; |
461 | 461 |
462 Gallery.prototype.onActionExecute_ = function(action) { | 462 Gallery.prototype.onActionExecute_ = function(action) { |
463 var url = this.ribbon_.getSelectedItem().getUrl(); | 463 // |executeWhenReady| closes the sharing menu. |
464 // saveChanges_ makes the editor leave the mode and close the sharing menu. | 464 this.editor_.executeWhenReady(function() { |
465 this.saveChanges_(action.execute.bind(action, [url])); | 465 action.execute([this.ribbon_.getSelectedItem().getUrl()]); |
466 }.bind(this)); | |
466 }; | 467 }; |
467 | 468 |
468 Gallery.prototype.updateFilename_ = function(opt_url) { | 469 Gallery.prototype.updateFilename_ = function(opt_url) { |
469 var fullName; | 470 var fullName; |
470 | 471 |
471 var item = this.ribbon_.getSelectedItem(); | 472 var item = this.ribbon_.getSelectedItem(); |
472 if (item) { | 473 if (item) { |
473 fullName = item.getNameAfterSaving(); | 474 fullName = item.getNameAfterSaving(); |
474 } else if (opt_url) { | 475 } else if (opt_url) { |
475 fullName = ImageUtil.getFullNameFromUrl(opt_url); | 476 fullName = ImageUtil.getFullNameFromUrl(opt_url); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
588 } | 589 } |
589 this.context_.onClose(); | 590 this.context_.onClose(); |
590 }.bind(this)); | 591 }.bind(this)); |
591 }; | 592 }; |
592 | 593 |
593 /** | 594 /** |
594 * Handle user's 'Close' action (Escape or a click on the X icon). | 595 * Handle user's 'Close' action (Escape or a click on the X icon). |
595 */ | 596 */ |
596 Gallery.prototype.onClose_ = function() { | 597 Gallery.prototype.onClose_ = function() { |
597 // TODO: handle write errors gracefully (suggest retry or saving elsewhere). | 598 // TODO: handle write errors gracefully (suggest retry or saving elsewhere). |
598 this.saveChanges_(this.close_.bind(this)); | 599 this.editor_.executeWhenReady(this.close_.bind(this)); |
599 }; | 600 }; |
600 | 601 |
601 Gallery.prototype.prefetchImage = function(id, content, metadata) { | 602 Gallery.prototype.prefetchImage = function(id, url) { |
602 this.editor_.prefetchImage(id, content, metadata); | 603 this.editor_.prefetchImage(id, url); |
603 }; | 604 }; |
604 | 605 |
605 Gallery.prototype.openImage = function(id, content, metadata, slide, callback) { | 606 Gallery.prototype.openImage = function(id, url, metadata, slide, callback) { |
606 // The first change is load, we should not count it. | |
607 this.imageChanges_ = -1; | |
608 this.filenameSpacer_.removeAttribute('overwrite'); | 607 this.filenameSpacer_.removeAttribute('overwrite'); |
609 this.filenameSpacer_.removeAttribute('saved'); | 608 this.filenameSpacer_.removeAttribute('saved'); |
610 | 609 |
611 var item = this.ribbon_.getSelectedItem(); | 610 this.selectedImageMetadata_ = metadata; |
612 this.updateFilename_(content); | 611 this.updateFilename_(url); |
613 | 612 |
614 this.showSpinner_(true); | 613 this.showSpinner_(true); |
615 | 614 |
616 var self = this; | 615 var self = this; |
617 function loadDone(loadType) { | 616 function loadDone(loadType) { |
618 var video = self.isShowingVideo_(); | 617 var video = self.isShowingVideo_(); |
619 ImageUtil.setAttribute(self.container_, 'video', video); | 618 ImageUtil.setAttribute(self.container_, 'video', video); |
620 | 619 |
621 self.showSpinner_(false); | 620 self.showSpinner_(false); |
622 if (loadType == ImageView.LOAD_TYPE_ERROR) { | 621 if (loadType == ImageView.LOAD_TYPE_ERROR) { |
(...skipping 12 matching lines...) Expand all Loading... | |
635 | 634 |
636 function toMillions(number) { return Math.round(number / (1000 * 1000)) } | 635 function toMillions(number) { return Math.round(number / (1000 * 1000)) } |
637 | 636 |
638 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MB'), | 637 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MB'), |
639 toMillions(metadata.fileSize)); | 638 toMillions(metadata.fileSize)); |
640 | 639 |
641 var canvas = self.imageView_.getCanvas(); | 640 var canvas = self.imageView_.getCanvas(); |
642 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MPix'), | 641 ImageUtil.metrics.recordSmallCount(ImageUtil.getMetricName('Size.MPix'), |
643 toMillions(canvas.width * canvas.height)); | 642 toMillions(canvas.width * canvas.height)); |
644 | 643 |
645 var url = item ? item.getUrl() : content; | |
646 var extIndex = url.lastIndexOf('.'); | 644 var extIndex = url.lastIndexOf('.'); |
647 var ext = extIndex < 0 ? '' : url.substr(extIndex + 1).toLowerCase(); | 645 var ext = extIndex < 0 ? '' : url.substr(extIndex + 1).toLowerCase(); |
648 if (ext == 'jpeg') ext = 'jpg'; | 646 if (ext == 'jpeg') ext = 'jpg'; |
649 ImageUtil.metrics.recordEnum( | 647 ImageUtil.metrics.recordEnum( |
650 ImageUtil.getMetricName('FileType'), ext, ImageUtil.FILE_TYPES); | 648 ImageUtil.getMetricName('FileType'), ext, ImageUtil.FILE_TYPES); |
651 } | 649 } |
652 | 650 |
653 callback(loadType); | 651 callback(loadType); |
654 } | 652 } |
655 | 653 |
656 this.editor_.openSession(id, content, metadata, slide, loadDone); | 654 this.editor_.openSession( |
655 id, url, metadata, slide, this.saveCurrentImage_.bind(this), loadDone); | |
657 }; | 656 }; |
658 | 657 |
659 Gallery.prototype.closeImage = function(item) { | 658 Gallery.prototype.closeImage = function(callback) { |
660 this.showSpinner_(false); | 659 this.showSpinner_(false); |
661 this.showErrorBanner_(false); | 660 this.showErrorBanner_(false); |
662 this.editor_.getPrompt().hide(); | 661 this.editor_.getPrompt().hide(); |
663 if (this.isShowingVideo_()) { | 662 if (this.isShowingVideo_()) { |
664 this.mediaControls_.pause(); | 663 this.mediaControls_.pause(); |
665 this.mediaControls_.detachMedia(); | 664 this.mediaControls_.detachMedia(); |
666 } | 665 } |
667 this.editor_.closeSession(this.saveItem_.bind(this, item, null)); | 666 this.editor_.closeSession(callback); |
668 }; | 667 }; |
669 | 668 |
670 Gallery.prototype.showSpinner_ = function(on) { | 669 Gallery.prototype.showSpinner_ = function(on) { |
671 if (this.spinnerTimer_) { | 670 if (this.spinnerTimer_) { |
672 clearTimeout(this.spinnerTimer_); | 671 clearTimeout(this.spinnerTimer_); |
673 this.spinnerTimer_ = null; | 672 this.spinnerTimer_ = null; |
674 } | 673 } |
675 | 674 |
676 if (on) { | 675 if (on) { |
677 this.spinnerTimer_ = setTimeout(function() { | 676 this.spinnerTimer_ = setTimeout(function() { |
678 this.spinnerTimer_ = null; | 677 this.spinnerTimer_ = null; |
679 ImageUtil.setAttribute(this.container_, 'spinner', true); | 678 ImageUtil.setAttribute(this.container_, 'spinner', true); |
680 }.bind(this), 1000); | 679 }.bind(this), 1000); |
681 } else { | 680 } else { |
682 ImageUtil.setAttribute(this.container_, 'spinner', false); | 681 ImageUtil.setAttribute(this.container_, 'spinner', false); |
683 } | 682 } |
684 } | 683 }; |
685 | 684 |
686 Gallery.prototype.showErrorBanner_ = function(message) { | 685 Gallery.prototype.showErrorBanner_ = function(message) { |
687 if (message) { | 686 if (message) { |
688 this.errorBanner_.textContent = this.displayStringFunction_(message); | 687 this.errorBanner_.textContent = this.displayStringFunction_(message); |
689 } | 688 } |
690 ImageUtil.setAttribute(this.container_, 'error', !!message); | 689 ImageUtil.setAttribute(this.container_, 'error', !!message); |
691 }; | 690 }; |
692 | 691 |
693 Gallery.prototype.isShowingVideo_ = function() { | 692 Gallery.prototype.isShowingVideo_ = function() { |
694 return !!this.imageView_.getVideo(); | 693 return !!this.imageView_.getVideo(); |
(...skipping 30 matching lines...) Expand all Loading... | |
725 | 724 |
726 // isEditing_ has just been flipped to a new value. | 725 // isEditing_ has just been flipped to a new value. |
727 if (this.isEditing_()) { | 726 if (this.isEditing_()) { |
728 if (this.context_.readonlyDirName) { | 727 if (this.context_.readonlyDirName) { |
729 this.editor_.getPrompt().showAt( | 728 this.editor_.getPrompt().showAt( |
730 'top', 'readonly_warning', 0, this.context_.readonlyDirName); | 729 'top', 'readonly_warning', 0, this.context_.readonlyDirName); |
731 } | 730 } |
732 this.cancelFading_(); | 731 this.cancelFading_(); |
733 } else { | 732 } else { |
734 this.editor_.getPrompt().hide(); | 733 this.editor_.getPrompt().hide(); |
735 if (!this.isShowingVideo_()) { | |
736 var item = this.ribbon_.getSelectedItem(); | |
737 this.editor_.requestImage(item.updateThumbnail.bind(item)); | |
738 } | |
739 this.filenameSpacer_.removeAttribute('saved'); | 734 this.filenameSpacer_.removeAttribute('saved'); |
740 this.filenameSpacer_.removeAttribute('overwrite'); | 735 this.filenameSpacer_.removeAttribute('overwrite'); |
741 this.saveChanges_(); | |
742 this.initiateFading_(); | 736 this.initiateFading_(); |
743 } | 737 } |
744 | 738 |
745 ImageUtil.setAttribute(this.editButton_, 'pressed', this.isEditing_()); | 739 ImageUtil.setAttribute(this.editButton_, 'pressed', this.isEditing_()); |
746 }; | 740 }; |
747 | 741 |
748 Gallery.prototype.isSharing_ = function(event) { | 742 Gallery.prototype.isSharing_ = function(event) { |
749 return this.shareMode_ && this.shareMode_ == this.editor_.getMode(); | 743 return this.shareMode_ && this.shareMode_ == this.editor_.getMode(); |
750 }; | 744 }; |
751 | 745 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
900 this.lastVisibleIndex_ = -1; // Zero thumbnails | 894 this.lastVisibleIndex_ = -1; // Zero thumbnails |
901 this.sequenceDirection_ = 0; | 895 this.sequenceDirection_ = 0; |
902 this.sequenceLength_ = 0; | 896 this.sequenceLength_ = 0; |
903 }; | 897 }; |
904 | 898 |
905 Ribbon.prototype.add = function(url) { | 899 Ribbon.prototype.add = function(url) { |
906 var index = this.items_.length; | 900 var index = this.items_.length; |
907 var selectClosure = this.select.bind(this, index, 0, null); | 901 var selectClosure = this.select.bind(this, index, 0, null); |
908 var item = new Ribbon.Item(index, url, this.document_, selectClosure); | 902 var item = new Ribbon.Item(index, url, this.document_, selectClosure); |
909 this.items_.push(item); | 903 this.items_.push(item); |
910 this.metadataProvider_.fetch(url, item.setMetadata.bind(item)); | |
911 }; | 904 }; |
912 | 905 |
913 Ribbon.prototype.load = function(urls, selectedIndex) { | 906 Ribbon.prototype.load = function(urls, selectedIndex) { |
914 this.clear(); | 907 this.clear(); |
915 for (var index = 0; index < urls.length; ++index) { | 908 for (var index = 0; index < urls.length; ++index) { |
916 this.add(urls[index]); | 909 this.add(urls[index]); |
917 } | 910 } |
918 this.selectedIndex_ = selectedIndex; | 911 this.selectedIndex_ = selectedIndex; |
919 | 912 |
920 // We do not want to call this.select because the selected image is already | 913 // We do not want to call this.select because the selected image is already |
921 // displayed. Instead we just update the UI. | 914 // displayed. Instead we just update the UI. |
922 this.getSelectedItem().select(true); | 915 this.getSelectedItem().select(true); |
923 this.redraw(); | 916 this.redraw(); |
924 | 917 |
925 // Let the thumbnails load before prefetching the next image. | 918 // Let the thumbnails load before prefetching the next image. |
926 setTimeout(this.requestPrefetch.bind(this, 1), 1000); | 919 setTimeout(this.requestPrefetch.bind(this, 1), 1000); |
927 | 920 |
928 // Make the arrows visible if there are more than 1 image. | 921 // Make the arrows visible if there are more than 1 image. |
929 ImageUtil.setAttribute(this.arrowLeft_, 'active', this.items_.length > 1); | 922 ImageUtil.setAttribute(this.arrowLeft_, 'active', this.items_.length > 1); |
930 ImageUtil.setAttribute(this.arrowRight_, 'active', this.items_.length > 1); | 923 ImageUtil.setAttribute(this.arrowRight_, 'active', this.items_.length > 1); |
931 }; | 924 }; |
932 | 925 |
933 Ribbon.prototype.select = function(index, opt_forceStep, opt_callback) { | 926 Ribbon.prototype.select = function(index, opt_forceStep, opt_callback) { |
934 if (index == this.selectedIndex_) | 927 if (index == this.selectedIndex_) |
935 return; // Do not reselect. | 928 return; // Do not reselect. |
936 | 929 |
937 var oldSelectedItem = this.getSelectedItem(); | 930 this.client_.closeImage( |
938 oldSelectedItem.select(false); | 931 this.doSelect_.bind(this, index, opt_forceStep, opt_callback)); |
939 this.client_.closeImage(oldSelectedItem); | 932 }; |
933 | |
934 Ribbon.prototype.doSelect_ = function(index, opt_forceStep, opt_callback) { | |
935 if (index == this.selectedIndex_) | |
936 return; // Do not reselect | |
937 | |
938 var selectedItem = this.getSelectedItem(); | |
939 selectedItem.select(false); | |
940 | 940 |
941 var step = opt_forceStep || (index - this.selectedIndex_); | 941 var step = opt_forceStep || (index - this.selectedIndex_); |
942 | 942 |
943 if (Math.abs(step) != 1) { | 943 if (Math.abs(step) != 1) { |
944 // Long leap, the sequence is broken, we have no good prefetch candidate. | 944 // Long leap, the sequence is broken, we have no good prefetch candidate. |
945 this.sequenceDirection_ = 0; | 945 this.sequenceDirection_ = 0; |
946 this.sequenceLength_ = 0; | 946 this.sequenceLength_ = 0; |
947 } else if (this.sequenceDirection_ == step) { | 947 } else if (this.sequenceDirection_ == step) { |
948 // Keeping going in sequence. | 948 // Keeping going in sequence. |
949 this.sequenceLength_++; | 949 this.sequenceLength_++; |
950 } else { | 950 } else { |
951 // Reversed the direction. Reset the counter. | 951 // Reversed the direction. Reset the counter. |
952 this.sequenceDirection_ = step; | 952 this.sequenceDirection_ = step; |
953 this.sequenceLength_ = 1; | 953 this.sequenceLength_ = 1; |
954 } | 954 } |
955 | 955 |
956 if (this.sequenceLength_ <= 1) { | 956 if (this.sequenceLength_ <= 1) { |
957 // We have just broke the sequence. Touch the current image so that it stays | 957 // We have just broke the sequence. Touch the current image so that it stays |
958 // in the cache longer. | 958 // in the cache longer. |
959 this.client_.prefetchImage(oldSelectedItem.getIndex(), | 959 this.client_.prefetchImage(selectedItem.getIndex(), selectedItem.getUrl()); |
960 oldSelectedItem.getContent(), oldSelectedItem.getMetadata()); | |
961 } | 960 } |
962 | 961 |
963 this.selectedIndex_ = index; | 962 this.selectedIndex_ = index; |
964 | 963 |
965 var selectedItem = this.getSelectedItem(); | 964 selectedItem = this.getSelectedItem(); |
966 selectedItem.select(true); | 965 selectedItem.select(true); |
967 this.redraw(); | 966 this.redraw(); |
968 | 967 |
969 function shouldPrefetch(loadType, step, sequenceLength) { | 968 function shouldPrefetch(loadType, step, sequenceLength) { |
970 // Never prefetch when selecting out of sequence. | 969 // Never prefetch when selecting out of sequence. |
971 if (Math.abs(step) != 1) | 970 if (Math.abs(step) != 1) |
972 return false; | 971 return false; |
973 | 972 |
974 // Never prefetch after a video load (decoding the next image can freeze | 973 // Never prefetch after a video load (decoding the next image can freeze |
975 // the UI for a second or two). | 974 // the UI for a second or two). |
976 if (loadType == ImageView.LOAD_TYPE_VIDEO_FILE) | 975 if (loadType == ImageView.LOAD_TYPE_VIDEO_FILE) |
977 return false; | 976 return false; |
978 | 977 |
979 // Always prefetch if the previous load was from cache. | 978 // Always prefetch if the previous load was from cache. |
980 if (loadType == ImageView.LOAD_TYPE_CACHED_FULL) | 979 if (loadType == ImageView.LOAD_TYPE_CACHED_FULL) |
981 return true; | 980 return true; |
982 | 981 |
983 // Prefetch if we have been going in the same direction for long enough. | 982 // Prefetch if we have been going in the same direction for long enough. |
984 return sequenceLength >= 3; | 983 return sequenceLength >= 3; |
985 } | 984 } |
986 | 985 |
987 var self = this; | 986 var self = this; |
988 selectedItem.fetchMetadata(this.metadataProvider_, function(metadata){ | 987 this.metadataProvider_.fetch(selectedItem.getUrl(), function(metadata){ |
989 if (!selectedItem.isSelected()) return; | 988 if (!selectedItem.isSelected()) return; |
990 self.client_.openImage( | 989 self.client_.openImage( |
991 selectedItem.getIndex(), selectedItem.getContent(), metadata, step, | 990 selectedItem.getIndex(), selectedItem.getUrl(), metadata, step, |
992 function(loadType) { | 991 function(loadType) { |
993 if (!selectedItem.isSelected()) return; | 992 if (!selectedItem.isSelected()) return; |
994 if (shouldPrefetch(loadType, step, self.sequenceLength_)) { | 993 if (shouldPrefetch(loadType, step, self.sequenceLength_)) { |
995 self.requestPrefetch(step); | 994 self.requestPrefetch(step); |
996 } | 995 } |
997 if (opt_callback) opt_callback(); | 996 if (opt_callback) opt_callback(); |
998 }); | 997 }); |
999 }); | 998 }); |
1000 }; | 999 }; |
1001 | 1000 |
1002 Ribbon.prototype.requestPrefetch = function(direction) { | 1001 Ribbon.prototype.requestPrefetch = function(direction) { |
1003 if (this.items_.length < 2) return; | 1002 if (this.items_.length < 2) return; |
1004 | 1003 |
1005 var index = this.getNextSelectedIndex_(direction); | 1004 var index = this.getNextSelectedIndex_(direction); |
1005 var nextItemUrl = this.items_[index].getUrl(); | |
1006 | 1006 |
1007 var selectedItem = this.getSelectedItem(); | 1007 var selectedItem = this.getSelectedItem(); |
1008 var self = this; | 1008 this.metadataProvider_.fetch(nextItemUrl, function(metadata) { |
1009 var item = this.items_[index]; | |
1010 item.fetchMetadata(this.metadataProvider_, function(metadata) { | |
1011 if (!selectedItem.isSelected()) return; | 1009 if (!selectedItem.isSelected()) return; |
1012 self.client_.prefetchImage(index, item.getContent(), metadata); | 1010 this.client_.prefetchImage(index, nextItemUrl, metadata); |
1013 }); | 1011 }.bind(this)); |
1014 }; | 1012 }; |
1015 | 1013 |
1016 Ribbon.ITEMS_COUNT = 5; | 1014 Ribbon.ITEMS_COUNT = 5; |
1017 | 1015 |
1018 Ribbon.prototype.redraw = function() { | 1016 Ribbon.prototype.redraw = function() { |
1019 // Never show a single thumbnail. | 1017 // Never show a single thumbnail. |
1020 if (this.items_.length == 1) | 1018 if (this.items_.length == 1) |
1021 return; | 1019 return; |
1022 | 1020 |
1021 var initThumbnail = function(index) { | |
1022 var item = this.items_[index]; | |
1023 if (!item.hasThumbnail()) | |
1024 this.metadataProvider_.fetch(item.getUrl(), item.setThumbnail.bind(item)); | |
1025 }.bind(this); | |
1026 | |
1023 // TODO(dgozman): use margin instead of 2 here. | 1027 // TODO(dgozman): use margin instead of 2 here. |
1024 var itemWidth = this.bar_.clientHeight - 2; | 1028 var itemWidth = this.bar_.clientHeight - 2; |
1025 var fullItems = Ribbon.ITEMS_COUNT; | 1029 var fullItems = Ribbon.ITEMS_COUNT; |
1026 fullItems = Math.min(fullItems, this.items_.length); | 1030 fullItems = Math.min(fullItems, this.items_.length); |
1027 var right = Math.floor((fullItems - 1) / 2); | 1031 var right = Math.floor((fullItems - 1) / 2); |
1028 | 1032 |
1029 var fullWidth = fullItems * itemWidth; | 1033 var fullWidth = fullItems * itemWidth; |
1030 this.bar_.style.width = fullWidth + 'px'; | 1034 this.bar_.style.width = fullWidth + 'px'; |
1031 | 1035 |
1032 var lastIndex = this.selectedIndex_ + right; | 1036 var lastIndex = this.selectedIndex_ + right; |
(...skipping 11 matching lines...) Expand all Loading... | |
1044 this.lastVisibleIndex_ = lastIndex; | 1048 this.lastVisibleIndex_ = lastIndex; |
1045 } | 1049 } |
1046 | 1050 |
1047 this.bar_.textContent = ''; | 1051 this.bar_.textContent = ''; |
1048 var startIndex = Math.min(firstIndex, this.firstVisibleIndex_); | 1052 var startIndex = Math.min(firstIndex, this.firstVisibleIndex_); |
1049 var toRemove = []; | 1053 var toRemove = []; |
1050 // All the items except the first one treated equally. | 1054 // All the items except the first one treated equally. |
1051 for (var index = startIndex + 1; | 1055 for (var index = startIndex + 1; |
1052 index <= Math.max(lastIndex, this.lastVisibleIndex_); | 1056 index <= Math.max(lastIndex, this.lastVisibleIndex_); |
1053 ++index) { | 1057 ++index) { |
1058 initThumbnail(index); | |
1054 var box = this.items_[index].getBox(); | 1059 var box = this.items_[index].getBox(); |
1055 box.style.marginLeft = '0'; | 1060 box.style.marginLeft = '0'; |
1056 this.bar_.appendChild(box); | 1061 this.bar_.appendChild(box); |
1057 if (index < firstIndex || index > lastIndex) { | 1062 if (index < firstIndex || index > lastIndex) { |
1058 toRemove.push(index); | 1063 toRemove.push(index); |
1059 } | 1064 } |
1060 } | 1065 } |
1061 | 1066 |
1062 var margin = itemWidth * Math.abs(firstIndex - this.firstVisibleIndex_); | 1067 var margin = itemWidth * Math.abs(firstIndex - this.firstVisibleIndex_); |
1068 initThumbnail(startIndex); | |
1063 var startBox = this.items_[startIndex].getBox(); | 1069 var startBox = this.items_[startIndex].getBox(); |
1064 if (startIndex == firstIndex) { | 1070 if (startIndex == firstIndex) { |
1065 // Sliding to the right. | 1071 // Sliding to the right. |
1066 startBox.style.marginLeft = -margin + 'px'; | 1072 startBox.style.marginLeft = -margin + 'px'; |
1067 if (this.bar_.firstChild) | 1073 if (this.bar_.firstChild) |
1068 this.bar_.insertBefore(startBox, this.bar_.firstChild); | 1074 this.bar_.insertBefore(startBox, this.bar_.firstChild); |
1069 else | 1075 else |
1070 this.bar_.appendChild(startBox); | 1076 this.bar_.appendChild(startBox); |
1071 setTimeout(function() { | 1077 setTimeout(function() { |
1072 startBox.style.marginLeft = '0'; | 1078 startBox.style.marginLeft = '0'; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1186 }; | 1192 }; |
1187 | 1193 |
1188 Ribbon.Item.prototype.isSelected = function() { | 1194 Ribbon.Item.prototype.isSelected = function() { |
1189 return this.box_.hasAttribute('selected'); | 1195 return this.box_.hasAttribute('selected'); |
1190 }; | 1196 }; |
1191 | 1197 |
1192 Ribbon.Item.prototype.select = function(on) { | 1198 Ribbon.Item.prototype.select = function(on) { |
1193 ImageUtil.setAttribute(this.box_, 'selected', on); | 1199 ImageUtil.setAttribute(this.box_, 'selected', on); |
1194 }; | 1200 }; |
1195 | 1201 |
1196 Ribbon.Item.prototype.updateThumbnail = function(canvas) { | 1202 Ribbon.Item.prototype.saveToFile = function( |
1197 if (this.canvas_) | 1203 dirEntry, canvas, metadataEncoder, opt_callback) { |
1198 return; // The image is being saved, the thumbnail is already up-to-date. | |
1199 | |
1200 var metadataEncoder = | |
1201 ImageEncoder.encodeMetadata(this.getMetadata(), canvas, 1); | |
1202 this.setMetadata(metadataEncoder.getMetadata()); | |
1203 }; | |
1204 | |
1205 Ribbon.Item.prototype.save = function( | |
1206 dirEntry, metadataProvider, canvas, opt_callback) { | |
1207 ImageUtil.metrics.startInterval(ImageUtil.getMetricName('SaveTime')); | 1204 ImageUtil.metrics.startInterval(ImageUtil.getMetricName('SaveTime')); |
1208 | 1205 |
1209 var metadataEncoder = | |
1210 ImageEncoder.encodeMetadata(this.getMetadata(), canvas, 1); | |
1211 | |
1212 this.overrideContent(canvas, metadataEncoder.getMetadata()); | |
1213 | |
1214 var self = this; | 1206 var self = this; |
1215 | 1207 |
1216 if (!dirEntry) { // Happens only in gallery_demo.js | |
dgozman
2012/05/16 16:05:40
I've just found the gallery_demo.js. We should rem
Vladislav Kaznacheev
2012/05/17 09:04:40
Done. Also removed the code needed to support it.
| |
1217 self.onSaveSuccess( | |
1218 Gallery.blobToURL_(ImageEncoder.getBlob(canvas, metadataEncoder))); | |
1219 if (opt_callback) opt_callback(); | |
1220 return; | |
1221 } | |
1222 | |
1223 var name = this.getNameAfterSaving(); | 1208 var name = this.getNameAfterSaving(); |
1224 this.original_ = false; | 1209 this.original_ = false; |
1225 this.nameForSaving_ = null; | 1210 this.nameForSaving_ = null; |
1226 | 1211 |
1227 function onSuccess(url) { | 1212 function onSuccess(url) { |
1228 console.log('Saved from gallery', name); | 1213 console.log('Saved from gallery', name); |
1229 // Force the metadata provider to reread the metadata from the file. | 1214 ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 1, 2); |
1230 metadataProvider.reset(url); | 1215 ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('SaveTime')); |
1231 self.onSaveSuccess(url); | 1216 self.setUrl(url); |
1232 if (opt_callback) opt_callback(); | 1217 if (opt_callback) opt_callback(true); |
1233 } | 1218 } |
1234 | 1219 |
1235 function onError(error) { | 1220 function onError(error) { |
1236 console.log('Error saving from gallery', name, error); | 1221 console.log('Error saving from gallery', name, error); |
1237 self.onSaveError(error); | 1222 ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 0, 2); |
1238 if (opt_callback) opt_callback(); | 1223 if (opt_callback) opt_callback(false); |
1239 } | 1224 } |
1240 | 1225 |
1241 function doSave(newFile, fileEntry) { | 1226 function doSave(newFile, fileEntry) { |
1242 fileEntry.createWriter(function(fileWriter) { | 1227 fileEntry.createWriter(function(fileWriter) { |
1243 function writeContent() { | 1228 function writeContent() { |
1244 fileWriter.onwriteend = onSuccess.bind(null, fileEntry.toURL()); | 1229 fileWriter.onwriteend = onSuccess.bind(null, fileEntry.toURL()); |
1245 fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder)); | 1230 fileWriter.write(ImageEncoder.getBlob(canvas, metadataEncoder)); |
1246 } | 1231 } |
1247 fileWriter.onerror = onError; | 1232 fileWriter.onerror = onError; |
1248 if (newFile) { | 1233 if (newFile) { |
(...skipping 17 matching lines...) Expand all Loading... | |
1266 | 1251 |
1267 // TODO: Localize? | 1252 // TODO: Localize? |
1268 Ribbon.Item.COPY_SIGNATURE = 'Edited'; | 1253 Ribbon.Item.COPY_SIGNATURE = 'Edited'; |
1269 | 1254 |
1270 Ribbon.Item.REGEXP_COPY_N = | 1255 Ribbon.Item.REGEXP_COPY_N = |
1271 new RegExp('^' + Ribbon.Item.COPY_SIGNATURE + ' \\((\\d+)\\)( - .+)$'); | 1256 new RegExp('^' + Ribbon.Item.COPY_SIGNATURE + ' \\((\\d+)\\)( - .+)$'); |
1272 | 1257 |
1273 Ribbon.Item.REGEXP_COPY_0 = | 1258 Ribbon.Item.REGEXP_COPY_0 = |
1274 new RegExp('^' + Ribbon.Item.COPY_SIGNATURE + '( - .+)$'); | 1259 new RegExp('^' + Ribbon.Item.COPY_SIGNATURE + '( - .+)$'); |
1275 | 1260 |
1276 Ribbon.Item.prototype.createCopyName_ = function(dirEntry, callback) { | 1261 Ribbon.Item.prototype.createCopyName_ = function(dirEntry, metadata, callback) { |
1277 var name = ImageUtil.getFullNameFromUrl(this.url_); | 1262 var name = ImageUtil.getFullNameFromUrl(this.url_); |
1278 | 1263 |
1279 // If the item represents a file created during the current Gallery session | 1264 // If the item represents a file created during the current Gallery session |
1280 // we reuse it for subsequent saves instead of creating multiple copies. | 1265 // we reuse it for subsequent saves instead of creating multiple copies. |
1281 if (!this.original_) | 1266 if (!this.original_) |
1282 return name; | 1267 return name; |
1283 | 1268 |
1284 var ext = ''; | 1269 var ext = ''; |
1285 var index = name.lastIndexOf('.'); | 1270 var index = name.lastIndexOf('.'); |
1286 if (index != -1) { | 1271 if (index != -1) { |
1287 ext = name.substr(index); | 1272 ext = name.substr(index); |
1288 name = name.substr(0, index); | 1273 name = name.substr(0, index); |
1289 } | 1274 } |
1290 | 1275 |
1291 var mimeType = this.metadata_.mimeType.toLowerCase(); | 1276 var mimeType = metadata.mimeType.toLowerCase(); |
1292 if (mimeType != 'image/jpeg') { | 1277 if (mimeType != 'image/jpeg') { |
1293 // Chrome can natively encode only two formats: JPEG and PNG. | 1278 // Chrome can natively encode only two formats: JPEG and PNG. |
1294 // All non-JPEG images are saved in PNG, hence forcing the file extension. | 1279 // All non-JPEG images are saved in PNG, hence forcing the file extension. |
1295 ext = '.png'; | 1280 ext = '.png'; |
1296 } | 1281 } |
1297 | 1282 |
1298 function tryNext(tries) { | 1283 function tryNext(tries) { |
1299 // All the names are used. Let's overwrite the last one. | 1284 // All the names are used. Let's overwrite the last one. |
1300 if (tries == 0) { | 1285 if (tries == 0) { |
1301 setTimeout(callback, 0, name + ext); | 1286 setTimeout(callback, 0, name + ext); |
(...skipping 14 matching lines...) Expand all Loading... | |
1316 } | 1301 } |
1317 | 1302 |
1318 dirEntry.getFile(name + ext, {create: false, exclusive: false}, | 1303 dirEntry.getFile(name + ext, {create: false, exclusive: false}, |
1319 tryNext.bind(null, tries - 1), | 1304 tryNext.bind(null, tries - 1), |
1320 callback.bind(null, name + ext)); | 1305 callback.bind(null, name + ext)); |
1321 } | 1306 } |
1322 | 1307 |
1323 tryNext(10); | 1308 tryNext(10); |
1324 }; | 1309 }; |
1325 | 1310 |
1326 Ribbon.Item.prototype.setCopyName = function(dirEntry, opt_callback) { | 1311 Ribbon.Item.prototype.setCopyName = function(dirEntry, metadata, opt_callback) { |
1327 this.createCopyName_(dirEntry, function(name) { | 1312 this.createCopyName_(dirEntry, metadata, function(name) { |
1328 this.nameForSaving_ = name; | 1313 this.nameForSaving_ = name; |
1329 if (opt_callback) opt_callback(); | 1314 if (opt_callback) opt_callback(); |
1330 }.bind(this)); | 1315 }.bind(this)); |
1331 }; | 1316 }; |
1332 | 1317 |
1333 Ribbon.Item.prototype.setOriginalName = function(dirEntry, opt_callback) { | 1318 Ribbon.Item.prototype.setOriginalName = function(dirEntry, opt_callback) { |
1334 this.nameForSaving_ = null; | 1319 this.nameForSaving_ = null; |
1335 if (opt_callback) opt_callback(); | 1320 if (opt_callback) opt_callback(); |
1336 }; | 1321 }; |
1337 | 1322 |
1338 Ribbon.Item.prototype.setNameForSaving = function(newName) { | 1323 Ribbon.Item.prototype.setNameForSaving = function(newName) { |
1339 this.nameForSaving_ = newName; | 1324 this.nameForSaving_ = newName; |
1340 }; | 1325 }; |
1341 | 1326 |
1342 // The url and metadata stored in the item are not valid while the modified | 1327 Ribbon.Item.prototype.hasThumbnail = function() { |
1343 // image is being saved. Use the results of the latest edit instead. | 1328 return this.img_.hasAttribute('src'); |
1344 | |
1345 Ribbon.Item.prototype.overrideContent = function(canvas, metadata) { | |
1346 this.canvas_ = canvas; | |
1347 this.backupMetadata_ = this.metadata_; | |
1348 this.setMetadata(metadata); | |
1349 }; | 1329 }; |
1350 | 1330 |
1351 Ribbon.Item.prototype.getContent = function () { | 1331 Ribbon.Item.prototype.setThumbnail = function(metadata) { |
1352 return this.canvas_ || this.url_; | |
1353 }; | |
1354 | |
1355 Ribbon.Item.prototype.getMetadata = function () { | |
1356 return this.metadata_; | |
1357 }; | |
1358 | |
1359 Ribbon.Item.prototype.fetchMetadata = function (metadataProvider, callback) { | |
1360 if (this.metadata_) { | |
1361 callback(this.metadata_); // Every millisecond counts, call directly | |
1362 } else { | |
1363 metadataProvider.fetch(this.getUrl(), callback); | |
1364 } | |
1365 }; | |
1366 | |
1367 Ribbon.Item.prototype.onSaveSuccess = function(url) { | |
1368 this.url_ = url; | |
1369 delete this.backupMetadata_; | |
1370 delete this.canvas_; | |
1371 ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 1, 2); | |
1372 ImageUtil.metrics.recordInterval(ImageUtil.getMetricName('SaveTime')); | |
1373 }; | |
1374 | |
1375 Ribbon.Item.prototype.onSaveError = function(error) { | |
1376 // TODO(kaznacheev): notify the user that the file write failed and | |
1377 // suggest ways to rescue the modified image (retry/save elsewhere). | |
1378 // For now - just drop the modified content and revert the thumbnail. | |
1379 this.setMetadata(this.backupMetadata_); | |
1380 delete this.backupMetadata_; | |
1381 delete this.canvas_; | |
1382 ImageUtil.metrics.recordEnum(ImageUtil.getMetricName('SaveResult'), 0, 2); | |
1383 }; | |
1384 | |
1385 Ribbon.Item.prototype.setMetadata = function(metadata) { | |
1386 this.metadata_ = metadata; | |
1387 | |
1388 var url; | 1332 var url; |
1389 var transform; | 1333 var transform; |
1390 | 1334 |
1391 var mediaType = FileType.getMediaType(this.url_); | 1335 var mediaType = FileType.getMediaType(this.url_); |
1392 | 1336 |
1393 if (metadata.thumbnailURL) { | 1337 if (metadata.thumbnailURL) { |
1394 url = metadata.thumbnailURL; | 1338 url = metadata.thumbnailURL; |
1395 transform = metadata.thumbnailTransform; | 1339 transform = metadata.thumbnailTransform; |
1396 } else if (mediaType == 'image' && | 1340 } else if (mediaType == 'image' && |
1397 FileType.canUseImageUrlForPreview(metadata)) { | 1341 FileType.canUseImageUrlForPreview(metadata)) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1489 ShareMode.prototype.setUp = function() { | 1433 ShareMode.prototype.setUp = function() { |
1490 ImageEditor.Mode.prototype.setUp.apply(this, arguments); | 1434 ImageEditor.Mode.prototype.setUp.apply(this, arguments); |
1491 ImageUtil.setAttribute(this.menu_, 'hidden', false); | 1435 ImageUtil.setAttribute(this.menu_, 'hidden', false); |
1492 ImageUtil.setAttribute(this.button_, 'pressed', false); | 1436 ImageUtil.setAttribute(this.button_, 'pressed', false); |
1493 }; | 1437 }; |
1494 | 1438 |
1495 ShareMode.prototype.cleanUpUI = function() { | 1439 ShareMode.prototype.cleanUpUI = function() { |
1496 ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); | 1440 ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); |
1497 ImageUtil.setAttribute(this.menu_, 'hidden', true); | 1441 ImageUtil.setAttribute(this.menu_, 'hidden', true); |
1498 }; | 1442 }; |
OLD | NEW |