OLD | NEW |
| (Empty) |
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 | |
5 cr.define('options', function() { | |
6 | |
7 var OptionsPage = options.OptionsPage; | |
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 */ | |
28 function ChangePictureOptions() { | |
29 var isWebRTC = $('change-picture-page').getAttribute('camera') == 'webrtc'; | |
30 ChangePictureOptions.prototype = isWebRTC ? | |
31 ChangePictureOptionsWebRTCProto : ChangePictureOptionsOldProto; | |
32 // |this| has been already created so it's |__proto__| has to be reset. | |
33 this.__proto__ = ChangePictureOptions.prototype; | |
34 OptionsPage.call( | |
35 this, | |
36 'changePicture', | |
37 loadTimeData.getString('changePicturePage'), | |
38 'change-picture-page'); | |
39 } | |
40 | |
41 cr.addSingletonGetter(ChangePictureOptions); | |
42 | |
43 var ChangePictureOptionsOldProto = { | |
44 // Inherit ChangePictureOptions from OptionsPage. | |
45 __proto__: options.OptionsPage.prototype, | |
46 | |
47 /** | |
48 * Initializes ChangePictureOptions page. | |
49 */ | |
50 initializePage: function() { | |
51 // Call base class implementation to start preferences initialization. | |
52 OptionsPage.prototype.initializePage.call(this); | |
53 | |
54 var imageGrid = $('user-image-grid'); | |
55 UserImagesGrid.decorate(imageGrid); | |
56 | |
57 imageGrid.previewElement = $('user-image-preview'); | |
58 | |
59 imageGrid.addEventListener('select', | |
60 this.handleImageSelected_.bind(this)); | |
61 imageGrid.addEventListener('activate', | |
62 this.handleImageActivated_.bind(this)); | |
63 | |
64 // Add the "Choose file" button. | |
65 imageGrid.addItem(ButtonImages.CHOOSE_FILE, | |
66 loadTimeData.getString('chooseFile'), | |
67 this.handleChooseFile_.bind(this)); | |
68 | |
69 // Profile image data. | |
70 this.profileImage_ = imageGrid.addItem( | |
71 ButtonImages.PROFILE_PICTURE, | |
72 loadTimeData.getString('profilePhotoLoading')); | |
73 | |
74 // Old user image data (if present). | |
75 this.oldImage_ = null; | |
76 | |
77 $('change-picture-overlay-confirm').onclick = this.closePage_; | |
78 | |
79 chrome.send('onChangePicturePageInitialized'); | |
80 }, | |
81 | |
82 /** | |
83 * Called right after the page has been shown to user. | |
84 */ | |
85 didShowPage: function() { | |
86 $('user-image-grid').updateAndFocus(); | |
87 chrome.send('onChangePicturePageShown'); | |
88 }, | |
89 | |
90 /** | |
91 * Called right before the page is hidden. | |
92 */ | |
93 willHidePage: function() { | |
94 var imageGrid = $('user-image-grid'); | |
95 imageGrid.blur(); // Make sure the image grid is not active. | |
96 if (this.oldImage_) { | |
97 imageGrid.removeItem(this.oldImage_); | |
98 this.oldImage_ = null; | |
99 } | |
100 }, | |
101 | |
102 /** | |
103 * Called right after the page has been hidden. | |
104 */ | |
105 // TODO(ivankr): both callbacks are required as only one of them is called | |
106 // depending on the way the page was closed, see http://crbug.com/118923. | |
107 didClosePage: function() { | |
108 this.willHidePage(); | |
109 }, | |
110 | |
111 /** | |
112 * Closes current page, returning back to Personal Stuff page. | |
113 * @private | |
114 */ | |
115 closePage_: function() { | |
116 OptionsPage.closeOverlay(); | |
117 }, | |
118 | |
119 /** | |
120 * Handles "Take photo" button activation. | |
121 * @private | |
122 */ | |
123 handleTakePhoto_: function() { | |
124 chrome.send('takePhoto'); | |
125 this.closePage_(); | |
126 }, | |
127 | |
128 /** | |
129 * Handles "Choose a file" button activation. | |
130 * @private | |
131 */ | |
132 handleChooseFile_: function() { | |
133 chrome.send('chooseFile'); | |
134 this.closePage_(); | |
135 }, | |
136 | |
137 /** | |
138 * Handles image selection change. | |
139 * @private | |
140 */ | |
141 handleImageSelected_: function() { | |
142 var imageGrid = $('user-image-grid'); | |
143 var url = imageGrid.selectedItemUrl; | |
144 // Ignore deselection, selection change caused by program itself and | |
145 // selection of one of the action buttons. | |
146 if (url && | |
147 !imageGrid.inProgramSelection && | |
148 ButtonImageUrls.indexOf(url) == -1) { | |
149 chrome.send('selectImage', [url]); | |
150 } | |
151 }, | |
152 | |
153 /** | |
154 * Handles image activation (by pressing Enter). | |
155 * @private | |
156 */ | |
157 handleImageActivated_: function() { | |
158 switch ($('user-image-grid').selectedItemUrl) { | |
159 case ButtonImages.TAKE_PHOTO: | |
160 this.handleTakePhoto_(); | |
161 break; | |
162 case ButtonImages.CHOOSE_FILE: | |
163 this.handleChooseFile_(); | |
164 break; | |
165 default: | |
166 this.closePage_(); | |
167 break; | |
168 } | |
169 }, | |
170 | |
171 /** | |
172 * URL of the current user image. | |
173 * @type {string} | |
174 */ | |
175 get currentUserImageUrl() { | |
176 return 'chrome://userimage/' + BrowserOptions.getLoggedInUsername() + | |
177 '?id=' + (new Date()).getTime() + '&animated'; | |
178 }, | |
179 | |
180 /** | |
181 * Notifies about camera presence change. | |
182 * @param {boolean} present Whether a camera is present or not. | |
183 * @private | |
184 */ | |
185 setCameraPresent_: function(present) { | |
186 var imageGrid = $('user-image-grid'); | |
187 var showTakePhotoButton = present; | |
188 if (showTakePhotoButton && !this.takePhotoButton_) { | |
189 this.takePhotoButton_ = imageGrid.addItem( | |
190 ButtonImages.TAKE_PHOTO, | |
191 loadTimeData.getString('takePhoto'), | |
192 this.handleTakePhoto_.bind(this), | |
193 1); | |
194 } else if (!showTakePhotoButton && this.takePhotoButton_) { | |
195 imageGrid.removeItem(this.takePhotoButton_); | |
196 this.takePhotoButton_ = null; | |
197 } | |
198 }, | |
199 | |
200 /** | |
201 * Adds or updates old user image taken from file/camera (neither a profile | |
202 * image nor a default one). | |
203 * @private | |
204 */ | |
205 setOldImage_: function() { | |
206 var imageGrid = $('user-image-grid'); | |
207 var url = this.currentUserImageUrl; | |
208 if (this.oldImage_) { | |
209 this.oldImage_ = imageGrid.updateItem(this.oldImage_, url); | |
210 } else { | |
211 // Insert next to the profile image. | |
212 var pos = imageGrid.indexOf(this.profileImage_) + 1; | |
213 this.oldImage_ = imageGrid.addItem(url, undefined, undefined, pos); | |
214 imageGrid.selectedItem = this.oldImage_; | |
215 } | |
216 }, | |
217 | |
218 /** | |
219 * Updates user's profile image. | |
220 * @param {string} imageUrl Profile image, encoded as data URL. | |
221 * @param {boolean} select If true, profile image should be selected. | |
222 * @private | |
223 */ | |
224 setProfileImage_: function(imageUrl, select) { | |
225 var imageGrid = $('user-image-grid'); | |
226 this.profileImage_ = imageGrid.updateItem( | |
227 this.profileImage_, imageUrl, loadTimeData.getString('profilePhoto')); | |
228 if (select) | |
229 imageGrid.selectedItem = this.profileImage_; | |
230 }, | |
231 | |
232 /** | |
233 * Selects user image with the given URL. | |
234 * @param {string} url URL of the image to select. | |
235 * @private | |
236 */ | |
237 setSelectedImage_: function(url) { | |
238 $('user-image-grid').selectedItemUrl = url; | |
239 }, | |
240 | |
241 /** | |
242 * Appends default images to the image grid. Should only be called once. | |
243 * @param {Array.<{url: string, author: string, website: string}>} images | |
244 * An array of default images data, including URL, author and website. | |
245 * @private | |
246 */ | |
247 setDefaultImages_: function(images) { | |
248 var imageGrid = $('user-image-grid'); | |
249 for (var i = 0, data; data = imagesData[i]; i++) { | |
250 imageGrid.addItem(data.url); | |
251 } | |
252 }, | |
253 }; | |
254 | |
255 var ChangePictureOptionsWebRTCProto = { | |
256 // Inherit ChangePictureOptions from OptionsPage. | |
257 __proto__: options.OptionsPage.prototype, | |
258 | |
259 /** | |
260 * Initializes ChangePictureOptions page. | |
261 */ | |
262 initializePage: function() { | |
263 // Call base class implementation to start preferences initialization. | |
264 OptionsPage.prototype.initializePage.call(this); | |
265 | |
266 var imageGrid = $('user-image-grid'); | |
267 UserImagesGrid.decorate(imageGrid); | |
268 | |
269 // Preview image will track the selected item's URL. | |
270 var previewElement = $('user-image-preview'); | |
271 imageGrid.previewElement = previewElement; | |
272 imageGrid.selectionType = 'default'; | |
273 | |
274 imageGrid.addEventListener('select', | |
275 this.handleImageSelected_.bind(this)); | |
276 imageGrid.addEventListener('activate', | |
277 this.handleImageActivated_.bind(this)); | |
278 | |
279 // Set the title for "Take Photo" button. | |
280 imageGrid.cameraTitle = loadTimeData.getString('takePhoto'); | |
281 | |
282 // Add the "Choose file" button. | |
283 imageGrid.addItem(ButtonImages.CHOOSE_FILE, | |
284 loadTimeData.getString('chooseFile'), | |
285 this.handleChooseFile_.bind(this)).type = 'file'; | |
286 | |
287 // Profile image data. | |
288 this.profileImage_ = imageGrid.addItem( | |
289 ButtonImages.PROFILE_PICTURE, | |
290 loadTimeData.getString('profilePhotoLoading')); | |
291 this.profileImage_.type = 'profile'; | |
292 | |
293 $('take-photo').addEventListener( | |
294 'click', this.handleTakePhoto_.bind(this)); | |
295 $('discard-photo').addEventListener( | |
296 'click', imageGrid.discardPhoto.bind(imageGrid)); | |
297 | |
298 // Toggle 'animation' class for the duration of WebKit transition. | |
299 $('flip-photo').addEventListener( | |
300 'click', function(e) { | |
301 previewElement.classList.add('animation'); | |
302 imageGrid.flipPhoto = !imageGrid.flipPhoto; | |
303 }); | |
304 $('user-image-stream-crop').addEventListener( | |
305 'webkitTransitionEnd', function(e) { | |
306 previewElement.classList.remove('animation'); | |
307 }); | |
308 | |
309 // Old user image data (if present). | |
310 this.oldImage_ = null; | |
311 | |
312 $('change-picture-overlay-confirm').addEventListener( | |
313 'click', this.closePage_.bind(this)); | |
314 | |
315 chrome.send('onChangePicturePageInitialized'); | |
316 }, | |
317 | |
318 /** | |
319 * Called right after the page has been shown to user. | |
320 */ | |
321 didShowPage: function() { | |
322 var imageGrid = $('user-image-grid'); | |
323 imageGrid.updateAndFocus(); | |
324 // Reset camera element. | |
325 imageGrid.cameraImage = null; | |
326 // Autoplay but do not preselect. | |
327 imageGrid.checkCameraPresence(true, false); | |
328 chrome.send('onChangePicturePageShown'); | |
329 }, | |
330 | |
331 /** | |
332 * Called right before the page is hidden. | |
333 */ | |
334 willHidePage: function() { | |
335 var imageGrid = $('user-image-grid'); | |
336 imageGrid.blur(); // Make sure the image grid is not active. | |
337 imageGrid.stopCamera(); | |
338 if (this.oldImage_) { | |
339 imageGrid.removeItem(this.oldImage_); | |
340 this.oldImage_ = null; | |
341 } | |
342 }, | |
343 | |
344 /** | |
345 * Called right after the page has been hidden. | |
346 */ | |
347 // TODO(ivankr): both callbacks are required as only one of them is called | |
348 // depending on the way the page was closed, see http://crbug.com/118923. | |
349 didClosePage: function() { | |
350 this.willHidePage(); | |
351 }, | |
352 | |
353 /** | |
354 * Closes current page, returning back to Personal Stuff page. | |
355 * @private | |
356 */ | |
357 closePage_: function() { | |
358 OptionsPage.closeOverlay(); | |
359 }, | |
360 | |
361 /** | |
362 * Handles "Take photo" button click. | |
363 * @private | |
364 */ | |
365 handleTakePhoto_: function() { | |
366 $('user-image-grid').takePhoto(function(photoURL) { | |
367 chrome.send('photoTaken', [photoURL]); | |
368 }); | |
369 }, | |
370 | |
371 /** | |
372 * Handles "Choose a file" button activation. | |
373 * @private | |
374 */ | |
375 handleChooseFile_: function() { | |
376 chrome.send('chooseFile'); | |
377 this.closePage_(); | |
378 }, | |
379 | |
380 /** | |
381 * Handles image selection change. | |
382 * @private | |
383 */ | |
384 handleImageSelected_: function() { | |
385 var imageGrid = $('user-image-grid'); | |
386 var url = imageGrid.selectedItemUrl; | |
387 // Ignore selection change caused by program itself and selection of one | |
388 // of the action buttons. | |
389 if (!imageGrid.inProgramSelection && | |
390 url != ButtonImages.TAKE_PHOTO && url != ButtonImages.CHOOSE_FILE) { | |
391 chrome.send('selectImage', [url]); | |
392 } | |
393 // Update image attribution text. | |
394 var image = imageGrid.selectedItem; | |
395 $('user-image-author-name').textContent = image.author; | |
396 $('user-image-author-website').textContent = image.website; | |
397 $('user-image-author-website').href = image.website; | |
398 $('user-image-attribution').style.visibility = | |
399 (image.author || image.website) ? 'visible' : 'hidden'; | |
400 }, | |
401 | |
402 /** | |
403 * Handles image activation (by pressing Enter). | |
404 * @private | |
405 */ | |
406 handleImageActivated_: function() { | |
407 switch ($('user-image-grid').selectedItemUrl) { | |
408 case ButtonImages.TAKE_PHOTO: | |
409 this.handleTakePhoto_(); | |
410 break; | |
411 case ButtonImages.CHOOSE_FILE: | |
412 this.handleChooseFile_(); | |
413 break; | |
414 default: | |
415 this.closePage_(); | |
416 break; | |
417 } | |
418 }, | |
419 | |
420 /** | |
421 * URL of the current user image. | |
422 * @type {string} | |
423 */ | |
424 get currentUserImageUrl() { | |
425 return 'chrome://userimage/' + BrowserOptions.getLoggedInUsername() + | |
426 '?id=' + new Date().getTime(); | |
427 }, | |
428 | |
429 /** | |
430 * Adds or updates old user image taken from file/camera (neither a profile | |
431 * image nor a default one). | |
432 * @private | |
433 */ | |
434 setOldImage_: function() { | |
435 var imageGrid = $('user-image-grid'); | |
436 var url = this.currentUserImageUrl; | |
437 if (this.oldImage_) { | |
438 this.oldImage_ = imageGrid.updateItem(this.oldImage_, url); | |
439 } else { | |
440 // Insert next to the profile image. | |
441 var pos = imageGrid.indexOf(this.profileImage_) + 1; | |
442 this.oldImage_ = imageGrid.addItem(url, undefined, undefined, pos); | |
443 imageGrid.selectedItem = this.oldImage_; | |
444 } | |
445 }, | |
446 | |
447 /** | |
448 * Updates user's profile image. | |
449 * @param {string} imageUrl Profile image, encoded as data URL. | |
450 * @param {boolean} select If true, profile image should be selected. | |
451 * @private | |
452 */ | |
453 setProfileImage_: function(imageUrl, select) { | |
454 var imageGrid = $('user-image-grid'); | |
455 this.profileImage_ = imageGrid.updateItem( | |
456 this.profileImage_, imageUrl, loadTimeData.getString('profilePhoto')); | |
457 if (select) | |
458 imageGrid.selectedItem = this.profileImage_; | |
459 }, | |
460 | |
461 /** | |
462 * Selects user image with the given URL. | |
463 * @param {string} url URL of the image to select. | |
464 * @private | |
465 */ | |
466 setSelectedImage_: function(url) { | |
467 $('user-image-grid').selectedItemUrl = url; | |
468 }, | |
469 | |
470 /** | |
471 * Appends default images to the image grid. Should only be called once. | |
472 * @param {Array.<{url: string, author: string, website: string}>} images | |
473 * An array of default images data, including URL, author and website. | |
474 * @private | |
475 */ | |
476 setDefaultImages_: function(imagesData) { | |
477 var imageGrid = $('user-image-grid'); | |
478 for (var i = 0, data; data = imagesData[i]; i++) { | |
479 var item = imageGrid.addItem(data.url); | |
480 item.type = 'default'; | |
481 item.author = data.author || ''; | |
482 item.website = data.website || ''; | |
483 } | |
484 }, | |
485 }; | |
486 | |
487 // Forward public APIs to private implementations. | |
488 [ | |
489 'setCameraPresent', | |
490 'setDefaultImages', | |
491 'setOldImage', | |
492 'setProfileImage', | |
493 'setSelectedImage', | |
494 ].forEach(function(name) { | |
495 ChangePictureOptions[name] = function() { | |
496 var instance = ChangePictureOptions.getInstance(); | |
497 return instance[name + '_'].apply(instance, arguments); | |
498 }; | |
499 }); | |
500 | |
501 // Export | |
502 return { | |
503 ChangePictureOptions: ChangePictureOptions | |
504 }; | |
505 | |
506 }); | |
OLD | NEW |