// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. cr.define('options', function() { var OptionsPage = options.OptionsPage; var UserImagesGrid = options.UserImagesGrid; var ButtonImages = UserImagesGrid.ButtonImages; /** * Array of button URLs used on this page. * @type {Array.} * @const */ var ButtonImageUrls = [ ButtonImages.TAKE_PHOTO, ButtonImages.CHOOSE_FILE ]; ///////////////////////////////////////////////////////////////////////////// // ChangePictureOptions class: /** * Encapsulated handling of ChromeOS change picture options page. * @constructor */ function ChangePictureOptions() { OptionsPage.call( this, 'changePicture', loadTimeData.getString('changePicturePage'), 'change-picture-page'); } cr.addSingletonGetter(ChangePictureOptions); ChangePictureOptions.prototype = { // Inherit ChangePictureOptions from OptionsPage. __proto__: options.OptionsPage.prototype, /** * Initializes ChangePictureOptions page. */ initializePage: function() { // Call base class implementation to start preferences initialization. OptionsPage.prototype.initializePage.call(this); var imageGrid = $('user-image-grid'); UserImagesGrid.decorate(imageGrid); // Preview image will track the selected item's URL. var previewElement = $('user-image-preview'); previewElement.oncontextmenu = function(e) { e.preventDefault(); }; imageGrid.previewElement = previewElement; imageGrid.selectionType = 'default'; imageGrid.flipPhotoElement = $('flip-photo'); imageGrid.addEventListener('select', this.handleImageSelected_.bind(this)); imageGrid.addEventListener('activate', this.handleImageActivated_.bind(this)); imageGrid.addEventListener('phototaken', this.handlePhotoTaken_.bind(this)); imageGrid.addEventListener('photoupdated', this.handlePhotoTaken_.bind(this)); // Set the title for "Take Photo" button. imageGrid.cameraTitle = loadTimeData.getString('takePhoto'); // Add the "Choose file" button. imageGrid.addItem(ButtonImages.CHOOSE_FILE, loadTimeData.getString('chooseFile'), this.handleChooseFile_.bind(this)).type = 'file'; // Profile image data. this.profileImage_ = imageGrid.addItem( ButtonImages.PROFILE_PICTURE, loadTimeData.getString('profilePhotoLoading')); this.profileImage_.type = 'profile'; $('take-photo').addEventListener( 'click', this.handleTakePhoto_.bind(this)); $('discard-photo').addEventListener( 'click', imageGrid.discardPhoto.bind(imageGrid)); // Toggle 'animation' class for the duration of WebKit transition. $('flip-photo').addEventListener( 'click', function(e) { previewElement.classList.add('animation'); imageGrid.flipPhoto = !imageGrid.flipPhoto; }); $('user-image-stream-crop').addEventListener( 'webkitTransitionEnd', function(e) { previewElement.classList.remove('animation'); }); $('user-image-preview-img').addEventListener( 'webkitTransitionEnd', function(e) { previewElement.classList.remove('animation'); }); // Old user image data (if present). this.oldImage_ = null; $('change-picture-overlay-confirm').addEventListener( 'click', this.closeOverlay_.bind(this)); chrome.send('onChangePicturePageInitialized'); }, /** * Called right after the page has been shown to user. */ didShowPage: function() { var imageGrid = $('user-image-grid'); // Reset camera element. imageGrid.cameraImage = null; imageGrid.updateAndFocus(); chrome.send('onChangePicturePageShown'); }, /** * Called right before the page is hidden. */ willHidePage: function() { var imageGrid = $('user-image-grid'); imageGrid.blur(); // Make sure the image grid is not active. imageGrid.stopCamera(); if (this.oldImage_) { imageGrid.removeItem(this.oldImage_); this.oldImage_ = null; } }, /** * Called right after the page has been hidden. */ // TODO(ivankr): both callbacks are required as only one of them is called // depending on the way the page was closed, see http://crbug.com/118923. didClosePage: function() { this.willHidePage(); }, /** * Closes the overlay, returning to the main settings page. * @private */ closeOverlay_: function() { if (!$('change-picture-page').hidden) OptionsPage.closeOverlay(); }, /** * Handles "Take photo" button click. * @private */ handleTakePhoto_: function() { $('user-image-grid').takePhoto(); }, /** * Handle photo captured event. * @param {Event} e Event with 'dataURL' property containing a data URL. */ handlePhotoTaken_: function(e) { chrome.send('photoTaken', [e.dataURL]); }, /** * Handles "Choose a file" button activation. * @private */ handleChooseFile_: function() { chrome.send('chooseFile'); this.closeOverlay_(); }, /** * Handles image selection change. * @param {Event} e Selection change Event. * @private */ handleImageSelected_: function(e) { var imageGrid = $('user-image-grid'); var url = imageGrid.selectedItemUrl; // Ignore selection change caused by program itself and selection of one // of the action buttons. if (!imageGrid.inProgramSelection && url != ButtonImages.TAKE_PHOTO && url != ButtonImages.CHOOSE_FILE) { chrome.send('selectImage', [url, imageGrid.selectionType]); } // Start/stop camera on (de)selection. if (!imageGrid.inProgramSelection && imageGrid.selectionType != e.oldSelectionType) { if (imageGrid.selectionType == 'camera') { imageGrid.startCamera( function() { // Start capture if camera is still the selected item. return imageGrid.selectedItem == imageGrid.cameraImage; }); } else { imageGrid.stopCamera(); } } // Update image attribution text. var image = imageGrid.selectedItem; $('user-image-author-name').textContent = image.author; $('user-image-author-website').textContent = image.website; $('user-image-author-website').href = image.website; $('user-image-attribution').style.visibility = (image.author || image.website) ? 'visible' : 'hidden'; }, /** * Handles image activation (by pressing Enter). * @private */ handleImageActivated_: function() { switch ($('user-image-grid').selectedItemUrl) { case ButtonImages.TAKE_PHOTO: this.handleTakePhoto_(); break; case ButtonImages.CHOOSE_FILE: this.handleChooseFile_(); break; default: this.closeOverlay_(); break; } }, /** * Adds or updates old user image taken from file/camera (neither a profile * image nor a default one). * @param {string} imageUrl Old user image, as data or internal URL. * @private */ setOldImage_: function(imageUrl) { var imageGrid = $('user-image-grid'); if (this.oldImage_) { this.oldImage_ = imageGrid.updateItem(this.oldImage_, imageUrl); } else { // Insert next to the profile image. var pos = imageGrid.indexOf(this.profileImage_) + 1; this.oldImage_ = imageGrid.addItem(imageUrl, undefined, undefined, pos); this.oldImage_.type = 'old'; imageGrid.selectedItem = this.oldImage_; } }, /** * Updates user's profile image. * @param {string} imageUrl Profile image, encoded as data URL. * @param {boolean} select If true, profile image should be selected. * @private */ setProfileImage_: function(imageUrl, select) { var imageGrid = $('user-image-grid'); this.profileImage_ = imageGrid.updateItem( this.profileImage_, imageUrl, loadTimeData.getString('profilePhoto')); if (select) imageGrid.selectedItem = this.profileImage_; }, /** * Selects user image with the given URL. * @param {string} url URL of the image to select. * @private */ setSelectedImage_: function(url) { $('user-image-grid').selectedItemUrl = url; }, /** * @param {boolean} present Whether camera is detected. */ setCameraPresent_: function(present) { $('user-image-grid').cameraPresent = present; }, /** * Appends default images to the image grid. Should only be called once. * @param {Array.<{url: string, author: string, website: string}>} * imagesData An array of default images data, including URL, author and * website. * @private */ setDefaultImages_: function(imagesData) { var imageGrid = $('user-image-grid'); for (var i = 0, data; data = imagesData[i]; i++) { var item = imageGrid.addItem(data.url); item.type = 'default'; item.author = data.author || ''; item.website = data.website || ''; } }, }; // Forward public APIs to private implementations. [ 'closeOverlay', 'setCameraPresent', 'setDefaultImages', 'setOldImage', 'setProfileImage', 'setSelectedImage', ].forEach(function(name) { ChangePictureOptions[name] = function() { var instance = ChangePictureOptions.getInstance(); return instance[name + '_'].apply(instance, arguments); }; }); // Export return { ChangePictureOptions: ChangePictureOptions }; });