- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / feedback.js
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 // Constants.
6 /** @const */ var FEEDBACK_LANDING_PAGE =
7     'https://www.google.com/support/chrome/go/feedback_confirmation';
8 /** @const */ var MAX_ATTACH_FILE_SIZE = 3 * 1024 * 1024;
9
10 var selectedThumbnailDivId = '';
11 var selectedThumbnailId = '';
12 var selectedImageUrl;
13
14 var savedThumbnailIds = [];
15 savedThumbnailIds['current-screenshots'] = '';
16 savedThumbnailIds['saved-screenshots'] = '';
17
18 var categoryTag = '';
19 var filePath = '';
20 var forceDisableScreenshots = false;
21 var traceId = 0;
22
23 // Globals to manage reading data from the attach a file option.
24 var attachFileBinaryData = '';
25 var lastReader = null;
26
27 /**
28  * Returns the base filename for a given path. Handles only Unix style paths.
29  * @param {string} path The path to return the basename for.
30  * @return {string} Basename for the path.
31  */
32 function getBaseName(path) {
33   lastSeparator = path.lastIndexOf('/');
34   if (lastSeparator == -1)
35     return '';
36   else
37     return path.substr(lastSeparator + 1);
38 }
39
40 /**
41  * Selects an image thumbnail in the specified div.
42  * @param {string} divId The id of the div to search in.
43  * @param {string} thumbnailId The id of the thumbnail to search for.
44  */
45 function selectImage(divId, thumbnailId) {
46   var thumbnailDivs = $(divId).children;
47   selectedThumbnailDivId = divId;
48   if (thumbnailDivs.length == 0) {
49     $(divId).hidden = true;
50     return;
51   }
52
53   for (var i = 0; i < thumbnailDivs.length; i++) {
54     thumbnailDivs[i].className = 'image-thumbnail-container';
55
56     // If the the current div matches the thumbnail id provided,
57     // or there is no thumbnail id given, and we're at the first thumbnail.
58     if (thumbnailDivs[i].id == thumbnailId || (!thumbnailId && !i)) {
59       thumbnailDivs[i].classList.add('image-thumbnail-container-selected');
60       selectedThumbnailId = thumbnailDivs[i].id;
61       savedThumbnailIds[divId] = thumbnailId;
62     }
63   }
64 }
65
66 /**
67  * Adds an image thumbnail to the specified div.
68  * @param {string} divId The id of the div to add a screenshot to.
69  * @param {string} screenshot The URL of the screenshot being added.
70  */
71 function addScreenshot(divId, screenshot) {
72   var thumbnailDiv = document.createElement('div');
73   thumbnailDiv.className = 'image-thumbnail-container';
74
75   thumbnailDiv.id = divId + '-thumbnailDiv-' + $(divId).children.length;
76   thumbnailDiv.onclick = function() {
77     selectImage(divId, thumbnailDiv.id);
78   };
79
80   var innerDiv = document.createElement('div');
81   innerDiv.className = 'image-thumbnail';
82
83   var thumbnail = document.createElement('img');
84   thumbnail.id = thumbnailDiv.id + '-image';
85   // We add the ?+timestamp to make sure the image URLs are unique
86   // and Chrome does not load the image from cache.
87   thumbnail.src = screenshot + '?' + Date.now();
88   innerDiv.appendChild(thumbnail);
89
90   thumbnailDiv.appendChild(innerDiv);
91   $(divId).appendChild(thumbnailDiv);
92
93   if (!selectedThumbnailId)
94     selectImage(divId, thumbnailDiv.id);
95 }
96
97 /**
98  * Enables screenshots.
99  */
100 function enableScreenshots() {
101   if (forceDisableScreenshots)
102     return;
103   $('screenshot-row').hidden = false;
104 }
105
106 /**
107  * Reads the selected file when the user selects a file.
108  * @param {event} evtFileSelected The on changed event for the file input box.
109  */
110 function onFileSelected(evtFileSelected) {
111   var file = evtFileSelected.target.files[0];
112   if (!file) {
113     // User canceled file selection.
114     $('attach-file-checkbox').checked = false;
115     attachFileBinaryData = null;
116     return;
117   }
118
119   if (file.size > MAX_ATTACH_FILE_SIZE) {
120     $('attach-error').hidden = false;
121
122     // Clear our selected file.
123     $('attach-file').value = '';
124     attachFileBinaryData = null;
125     $('attach-file-checkbox').checked = false;
126
127     return;
128   }
129
130   $('attach-error').hidden = true;
131
132   // Abort an existing file read operation if one exists.
133   if (lastReader) {
134     lastReader.abort();
135     lastReader = null;
136   }
137
138   var reader = new FileReader();
139   reader.onloadend = function(evtLoadEnd) {
140     if (evtLoadEnd.target.readyState == FileReader.DONE) {
141       attachFileBinaryData = evtLoadEnd.target.result;
142       lastReader = null;
143       // Check the checkbox so we do send this file. Users can uncheck the
144       // box if they don't want to send the file.
145       $('attach-file-checkbox').checked = true;
146       $('reading-file').hidden = true;
147       $('send-report-button').disabled = false;
148     }
149   };
150
151   lastReader = reader;
152   reader.readAsBinaryString(file);
153   $('reading-file').hidden = false;
154   $('send-report-button').disabled = true;
155 }
156
157 /**
158  * Sends the report; after the report is sent, we need to be redirected to
159  * the landing page, but we shouldn't be able to navigate back, hence
160  * we open the landing page in a new tab and sendReport closes this tab.
161  * @return {boolean} True if the report was sent.
162  */
163 function sendReport() {
164   if ($('description-text').value.length == 0) {
165     alert(loadTimeData.getString('no-description'));
166     return false;
167   }
168
169   var imagePath = '';
170   if ($('screenshot-checkbox').checked && selectedThumbnailId)
171     imagePath = $(selectedThumbnailId + '-image').src;
172   var pageUrl = $('page-url-text').value;
173   if (!$('page-url-checkbox').checked)
174     pageUrl = '';
175   var userEmail = $('user-email-text').value;
176   if (!$('user-email-checkbox').checked)
177     userEmail = '';
178
179   var reportArray = [pageUrl,
180                      categoryTag,
181                      $('description-text').value,
182                      userEmail,
183                      imagePath];
184
185   // Add chromeos data if it exists.
186   if ($('sys-info-checkbox')) {
187     reportArray = reportArray.concat([String($('sys-info-checkbox').checked)]);
188     if (!$('performance-info-checkbox').checked) {
189       traceId = 0;
190     }
191     reportArray = reportArray.concat([String(traceId)]);
192   }
193
194   if ($('attach-file-checkbox') &&
195       $('attach-file-checkbox').checked) {
196     if (attachFileBinaryData) {
197       reportArray = reportArray.concat(
198           [$('attach-file').files[0].name, btoa(attachFileBinaryData)]);
199     }
200   } else if ($('attach-file-custom-checkbox') &&
201              $('attach-file-custom-checkbox').checked) {
202     if (filePath)
203       reportArray = reportArray.concat([filePath, '']);
204   }
205
206   // open the landing page in a new tab, sendReport will close this one.
207   window.open(FEEDBACK_LANDING_PAGE, '_blank');
208   chrome.send('sendReport', reportArray);
209   return true;
210 }
211
212 /**
213  * Click listener for the cancel button.
214  * @param {Event} e The click event being handled.
215  */
216 function cancel(e) {
217   chrome.send('cancel');
218   e.preventDefault();
219 }
220
221 /**
222  * Select the current screenshots div, restoring the image that was
223  * selected when we had this div open previously.
224  */
225 function currentSelected() {
226   // TODO(rkc): Change this to use a class instead.
227   $('current-screenshots').hidden = false;
228   if ($('saved-screenshots'))
229     $('saved-screenshots').hidden = true;
230
231   if (selectedThumbnailDivId != 'current-screenshots')
232     selectImage('current-screenshots',
233                 savedThumbnailIds['current-screenshots']);
234 }
235
236 /**
237  * Select the saved screenshots div, restoring the image that was
238  * selected when we had this div open previously.
239  */
240 function savedSelected() {
241   if ($('saved-screenshots').childElementCount == 0) {
242     // setupSavedScreenshots will take care of changing visibility
243     chrome.send('refreshSavedScreenshots');
244   } else {
245     $('current-screenshots').hidden = true;
246     $('saved-screenshots').hidden = false;
247     if (selectedThumbnailDivId != 'saved-screenshots')
248       selectImage('saved-screenshots', savedThumbnailIds['saved-screenshots']);
249   }
250 }
251
252 /**
253  * Change the type of screenshot we're showing to the user from
254  * the current screenshot to saved screenshots
255  */
256 function changeToSaved() {
257   $('screenshot-label-current').hidden = true;
258   $('screenshot-label-saved').hidden = false;
259
260   // Change the link to say "go to original"
261   $('screenshot-link-tosaved').hidden = true;
262   $('screenshot-link-tocurrent').hidden = false;
263
264   savedSelected();
265 }
266
267 /**
268  * Change the type of screenshot we're showing to the user from
269  * the saved screenshots to the current screenshots
270  */
271 function changeToCurrent() {
272   $('screenshot-label-current').hidden = false;
273   $('screenshot-label-saved').hidden = true;
274
275   // Change the link to say "go to saved"
276   $('screenshot-link-tosaved').hidden = false;
277   $('screenshot-link-tocurrent').hidden = true;
278
279   currentSelected();
280 }
281
282 <if expr="pp_ifdef('chromeos')">
283 /**
284  * Update the page when performance feedback state is changed.
285  */
286 function performanceFeedbackChanged() {
287   if ($('performance-info-checkbox').checked) {
288     $('attach-file-checkbox').disabled = true;
289     $('attach-file-checkbox').checked = false;
290
291     $('screenshot-checkbox').disabled = true;
292     $('screenshot-checkbox').checked = false;
293   } else {
294     $('attach-file-checkbox').disabled = false;
295     $('screenshot-checkbox').disabled = false;
296   }
297 }
298 </if>
299
300 ///////////////////////////////////////////////////////////////////////////////
301 // Document Functions:
302 /**
303  * Window onload handler, sets up the page.
304  */
305 function load() {
306   cr.ui.FocusOutlineManager.forDocument(document);
307   if ($('attach-file'))
308     $('attach-file').addEventListener('change', onFileSelected);
309
310   if ($('sysinfo-url')) {
311     $('sysinfo-url').onclick = function(event) {
312       chrome.send('openSystemTab');
313     };
314   }
315
316 <if expr="pp_ifdef('chromeos')">
317   $('screenshot-link-tosaved').onclick = changeToSaved;
318   $('screenshot-link-tocurrent').onclick = changeToCurrent;
319
320   $('performance-info-checkbox').addEventListener(
321       'change', performanceFeedbackChanged);
322 </if>
323   $('send-report-button').onclick = sendReport;
324   $('cancel-button').onclick = cancel;
325
326   // Set default values for the possible parameters, and then parse the actual
327   // values from the URL href.
328   var parameters = {
329     'description': '',
330     'categoryTag': '',
331     'customPageUrl': '',
332     'filePath': '',
333     'traceId': 0,
334   };
335
336   var loc = window.location;
337   // Split the query string into an array of parameters.
338   var query = loc.search.substr(1).split('&');
339   // If we have a query in the hash.
340   if (loc.hash.indexOf('?') >= 0) {
341     // Remove the hash and split this query into parameters too.
342     query = query.concat(loc.hash.substr(loc.hash.indexOf('?') + 1).split('&'));
343   }
344   for (var i = 0; i < query.length; i++) {
345     // Decode and store each parameter value.
346     parameter = query[i].split('=');
347     parameters[parameter[0]] = decodeURIComponent(parameter[1]);
348   }
349
350   // Set the initial description text.
351   $('description-text').textContent = parameters['description'];
352   // If a page url is spcified in the parameters, override the default page url.
353   if (parameters['customPageUrl'] != '') {
354     $('page-url-text').value = parameters['customPageUrl'];
355     // and disable the page image, since it doesn't make sense on a custom url.
356     $('screenshot-checkbox').checked = false;
357     forceDisableScreenshots = true;
358   }
359
360   // Pick up the category tag (for most cases this will be an empty string)
361   categoryTag = parameters['categoryTag'];
362
363   // Pick up the file path for the attached file (only user for this at the
364   // moment is the quick office extension).
365   filePath = parameters['filePath'];
366
367   if (filePath != '') {
368     var baseName = getBaseName(filePath);
369     if (baseName) {
370       // Don't let the user choose another file, we were invoked by an
371       // extension already providing us the file, this report should only
372       // attach that file, or no file at all.
373       $('attach-file-container').hidden = true;
374
375       // Set our filename and unhide the "Attach this file" span.
376       $('attach-file-custom-name').textContent = baseName;
377       $('attach-file-custom-container').hidden = false;
378       // No screenshots if we're being invoked by an extension - screenshot was
379       // never taken.
380       $('screenshot-checkbox').checked = false;
381       forceDisableScreenshots = true;
382     } else {
383       filePath = '';
384     }
385   }
386
387   traceId = parameters['traceId'];
388   if (traceId != 0 && ($('performance-info-area'))) {
389     $('performance-info-area').hidden = false;
390     $('performance-info-checkbox').checked = true;
391     performanceFeedbackChanged();
392   }
393
394   chrome.send('getDialogDefaults');
395   chrome.send('refreshCurrentScreenshot');
396 }
397
398 function setupCurrentScreenshot(screenshot) {
399   addScreenshot('current-screenshots', screenshot);
400 }
401
402 function setupSavedScreenshots(screenshots) {
403   if (screenshots.length == 0) {
404     $('saved-screenshots').textContent =
405         loadTimeData.getString('no-saved-screenshots');
406
407     // Make sure we make the display the message.
408     $('current-screenshots').hidden = true;
409     $('saved-screenshots').hidden = false;
410
411     // In case the user tries to send now; fail safe, do not send a screenshot
412     // at all versus sending the current screenshot.
413     selectedThumbnailDivId = '';
414     selectedThumbnailId = '';
415   } else {
416     $('saved-screenshots').textContent = '';
417     for (i = 0; i < screenshots.length; ++i)
418       addScreenshot('saved-screenshots', screenshots[i]);
419
420     // Now that we have our screenshots, try selecting the saved screenshots
421     // again.
422     savedSelected();
423   }
424 }
425
426 function setupDialogDefaults(defaults) {
427   // Current url.
428   if ($('page-url-text').value == '')
429     $('page-url-text').value = defaults.currentUrl;
430   if (defaults.currentUrl == '')
431     $('page-url-checkbox').checked = false;
432   // User e-mail.
433   $('user-email-text').value = defaults.userEmail;
434   $('user-email-checkbox').checked = defaults.emailCheckboxDefault;
435
436   document.documentElement.classList.toggle('launcher-layout',
437                                             defaults.launcherFeedback);
438
439   if (!defaults.disableScreenshots)
440     enableScreenshots();
441
442   if (defaults.useSaved) {
443     $('screenshot-link-tosaved').hidden = false;
444   }
445 }
446
447 window.addEventListener('DOMContentLoaded', load);