• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3// found in the LICENSE file.
4
5cr.define('options', function() {
6  var Page = cr.ui.pageManager.Page;
7  var PageManager = cr.ui.pageManager.PageManager;
8  var UserImagesGrid = options.UserImagesGrid;
9  var ButtonImages = UserImagesGrid.ButtonImages;
10
11  /**
12   * Array of button URLs used on this page.
13   * @type {Array.<string>}
14   * @const
15   */
16  var ButtonImageUrls = [
17    ButtonImages.TAKE_PHOTO,
18    ButtonImages.CHOOSE_FILE
19  ];
20
21  /////////////////////////////////////////////////////////////////////////////
22  // ChangePictureOptions class:
23
24  /**
25   * Encapsulated handling of ChromeOS change picture options page.
26   * @constructor
27   * @extends {cr.ui.pageManager.Page}
28   */
29  function ChangePictureOptions() {
30    Page.call(this, 'changePicture',
31              loadTimeData.getString('changePicturePage'),
32              'change-picture-page');
33  }
34
35  cr.addSingletonGetter(ChangePictureOptions);
36
37  ChangePictureOptions.prototype = {
38    // Inherit ChangePictureOptions from Page.
39    __proto__: Page.prototype,
40
41    /** @override */
42    initializePage: function() {
43      Page.prototype.initializePage.call(this);
44
45      var imageGrid = $('user-image-grid');
46      UserImagesGrid.decorate(imageGrid);
47
48      // Preview image will track the selected item's URL.
49      var previewElement = $('user-image-preview');
50      previewElement.oncontextmenu = function(e) { e.preventDefault(); };
51
52      imageGrid.previewElement = previewElement;
53      imageGrid.selectionType = 'default';
54      imageGrid.flipPhotoElement = $('flip-photo');
55
56      imageGrid.addEventListener('select',
57                                 this.handleImageSelected_.bind(this));
58      imageGrid.addEventListener('activate',
59                                 this.handleImageActivated_.bind(this));
60      imageGrid.addEventListener('phototaken',
61                                 this.handlePhotoTaken_.bind(this));
62      imageGrid.addEventListener('photoupdated',
63                                 this.handlePhotoTaken_.bind(this));
64
65      // Add the "Choose file" button.
66      imageGrid.addItem(ButtonImages.CHOOSE_FILE,
67                        loadTimeData.getString('chooseFile'),
68                        this.handleChooseFile_.bind(this)).type = 'file';
69
70      // Profile image data.
71      this.profileImage_ = imageGrid.addItem(
72          ButtonImages.PROFILE_PICTURE,
73          loadTimeData.getString('profilePhotoLoading'));
74      this.profileImage_.type = 'profile';
75
76      // Set the title for camera item in the grid.
77      imageGrid.setCameraTitles(
78          loadTimeData.getString('takePhoto'),
79          loadTimeData.getString('photoFromCamera'));
80
81      $('take-photo').addEventListener(
82          'click', this.handleTakePhoto_.bind(this));
83      $('discard-photo').addEventListener(
84          'click', this.handleDiscardPhoto_.bind(this));
85
86      // Toggle 'animation' class for the duration of WebKit transition.
87      $('flip-photo').addEventListener(
88          'click', this.handleFlipPhoto_.bind(this));
89      $('user-image-stream-crop').addEventListener(
90          'webkitTransitionEnd', function(e) {
91            previewElement.classList.remove('animation');
92          });
93      $('user-image-preview-img').addEventListener(
94          'webkitTransitionEnd', function(e) {
95            previewElement.classList.remove('animation');
96          });
97
98      // Old user image data (if present).
99      this.oldImage_ = null;
100
101      $('change-picture-overlay-confirm').addEventListener(
102          'click', this.closeOverlay_.bind(this));
103
104      chrome.send('onChangePicturePageInitialized');
105    },
106
107    /** @override */
108    didShowPage: function() {
109      var imageGrid = $('user-image-grid');
110      // Reset camera element.
111      imageGrid.cameraImage = null;
112      imageGrid.updateAndFocus();
113      chrome.send('onChangePicturePageShown');
114    },
115
116    /** @override */
117    willHidePage: function() {
118      var imageGrid = $('user-image-grid');
119      imageGrid.blur();  // Make sure the image grid is not active.
120      imageGrid.stopCamera();
121      if (this.oldImage_) {
122        imageGrid.removeItem(this.oldImage_);
123        this.oldImage_ = null;
124      }
125      chrome.send('onChangePicturePageHidden');
126    },
127
128    /**
129     * Either willHidePage or didClosePage may be called depending on the way
130     * the page was closed.
131     * @override
132     */
133    didClosePage: function() {
134      this.willHidePage();
135    },
136
137    /**
138     * Closes the overlay, returning to the main settings page.
139     * @private
140     */
141    closeOverlay_: function() {
142      if (!$('change-picture-page').hidden)
143        PageManager.closeOverlay();
144    },
145
146    /**
147     * Handle camera-photo flip.
148     */
149    handleFlipPhoto_: function() {
150      var imageGrid = $('user-image-grid');
151      imageGrid.previewElement.classList.add('animation');
152      imageGrid.flipPhoto = !imageGrid.flipPhoto;
153      var flipMessageId = imageGrid.flipPhoto ?
154         'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText';
155      announceAccessibleMessage(loadTimeData.getString(flipMessageId));
156    },
157
158    /**
159     * Handles "Take photo" button click.
160     * @private
161     */
162    handleTakePhoto_: function() {
163      $('user-image-grid').takePhoto();
164      chrome.send('takePhoto');
165    },
166
167    /**
168     * Handle photo captured event.
169     * @param {Event} e Event with 'dataURL' property containing a data URL.
170     */
171    handlePhotoTaken_: function(e) {
172      chrome.send('photoTaken', [e.dataURL]);
173      announceAccessibleMessage(
174          loadTimeData.getString('photoCaptureAccessibleText'));
175    },
176
177    /**
178     * Handles "Discard photo" button click.
179     * @private
180     */
181    handleDiscardPhoto_: function() {
182      $('user-image-grid').discardPhoto();
183      chrome.send('discardPhoto');
184      announceAccessibleMessage(
185          loadTimeData.getString('photoDiscardAccessibleText'));
186    },
187
188    /**
189     * Handles "Choose a file" button activation.
190     * @private
191     */
192    handleChooseFile_: function() {
193      chrome.send('chooseFile');
194      this.closeOverlay_();
195    },
196
197    /**
198     * Handles image selection change.
199     * @param {Event} e Selection change Event.
200     * @private
201     */
202    handleImageSelected_: function(e) {
203      var imageGrid = $('user-image-grid');
204      var url = imageGrid.selectedItemUrl;
205
206      // Flip button available only for camera picture.
207      imageGrid.flipPhotoElement.tabIndex =
208          imageGrid.selectionType == 'camera' ? 1 : -1;
209      // Ignore selection change caused by program itself and selection of one
210      // of the action buttons.
211      if (!imageGrid.inProgramSelection &&
212          url != ButtonImages.TAKE_PHOTO && url != ButtonImages.CHOOSE_FILE) {
213        chrome.send('selectImage', [url, imageGrid.selectionType]);
214      }
215      // Start/stop camera on (de)selection.
216      if (!imageGrid.inProgramSelection &&
217          imageGrid.selectionType != e.oldSelectionType) {
218        if (imageGrid.selectionType == 'camera') {
219          imageGrid.startCamera(
220              function() {
221                // Start capture if camera is still the selected item.
222                return imageGrid.selectedItem == imageGrid.cameraImage;
223              });
224        } else {
225          imageGrid.stopCamera();
226        }
227      }
228      // Update image attribution text.
229      var image = imageGrid.selectedItem;
230      $('user-image-author-name').textContent = image.author;
231      $('user-image-author-website').textContent = image.website;
232      $('user-image-author-website').href = image.website;
233      $('user-image-attribution').style.visibility =
234          (image.author || image.website) ? 'visible' : 'hidden';
235    },
236
237    /**
238     * Handles image activation (by pressing Enter).
239     * @private
240     */
241    handleImageActivated_: function() {
242      switch ($('user-image-grid').selectedItemUrl) {
243        case ButtonImages.TAKE_PHOTO:
244          this.handleTakePhoto_();
245          break;
246        case ButtonImages.CHOOSE_FILE:
247          this.handleChooseFile_();
248          break;
249        default:
250          this.closeOverlay_();
251          break;
252      }
253    },
254
255    /**
256     * Adds or updates old user image taken from file/camera (neither a profile
257     * image nor a default one).
258     * @param {string} imageUrl Old user image, as data or internal URL.
259     * @private
260     */
261    setOldImage_: function(imageUrl) {
262      var imageGrid = $('user-image-grid');
263      if (this.oldImage_) {
264        this.oldImage_ = imageGrid.updateItem(this.oldImage_, imageUrl);
265      } else {
266        // Insert next to the profile image.
267        var pos = imageGrid.indexOf(this.profileImage_) + 1;
268        this.oldImage_ = imageGrid.addItem(imageUrl, undefined, undefined, pos);
269        this.oldImage_.type = 'old';
270        imageGrid.selectedItem = this.oldImage_;
271      }
272    },
273
274    /**
275     * Updates user's profile image.
276     * @param {string} imageUrl Profile image, encoded as data URL.
277     * @param {boolean} select If true, profile image should be selected.
278     * @private
279     */
280    setProfileImage_: function(imageUrl, select) {
281      var imageGrid = $('user-image-grid');
282      this.profileImage_ = imageGrid.updateItem(
283          this.profileImage_, imageUrl, loadTimeData.getString('profilePhoto'));
284      if (select)
285        imageGrid.selectedItem = this.profileImage_;
286    },
287
288    /**
289     * Selects user image with the given URL.
290     * @param {string} url URL of the image to select.
291     * @private
292     */
293    setSelectedImage_: function(url) {
294      $('user-image-grid').selectedItemUrl = url;
295    },
296
297    /**
298     * @param {boolean} present Whether camera is detected.
299     */
300    setCameraPresent_: function(present) {
301      $('user-image-grid').cameraPresent = present;
302    },
303
304    /**
305     * Appends default images to the image grid. Should only be called once.
306     * @param {Array.<{url: string, author: string, website: string}>}
307     *   imagesData An array of default images data, including URL, author and
308     *   website.
309     * @private
310     */
311    setDefaultImages_: function(imagesData) {
312      var imageGrid = $('user-image-grid');
313      for (var i = 0, data; data = imagesData[i]; i++) {
314        var item = imageGrid.addItem(data.url, data.title);
315        item.type = 'default';
316        item.author = data.author || '';
317        item.website = data.website || '';
318      }
319    },
320  };
321
322  // Forward public APIs to private implementations.
323  cr.makePublic(ChangePictureOptions, [
324    'closeOverlay',
325    'setCameraPresent',
326    'setDefaultImages',
327    'setOldImage',
328    'setProfileImage',
329    'setSelectedImage',
330  ]);
331
332  // Export
333  return {
334    ChangePictureOptions: ChangePictureOptions
335  };
336
337});
338