Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / feedback / js / feedback.js
1 // Copyright 2013 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 /** @type {string}
6  * @const
7  */
8 var FEEDBACK_LANDING_PAGE =
9     'https://www.google.com/support/chrome/go/feedback_confirmation';
10 /** @type {number}
11  * @const
12  */
13 var MAX_ATTACH_FILE_SIZE = 3 * 1024 * 1024;
14
15 /**
16  * @type {number}
17  * @const
18  */
19 var FEEDBACK_MIN_WIDTH = 500;
20 /**
21  * @type {number}
22  * @const
23  */
24 var FEEDBACK_MIN_HEIGHT = 585;
25
26 /** @type {number}
27  * @const
28  */
29 var CONTENT_MARGIN_HEIGHT = 40;
30
31 /** @type {number}
32  * @const
33  */
34 var MAX_SCREENSHOT_WIDTH = 100;
35
36 /** @type {string}
37  * @const
38  */
39 var SYSINFO_WINDOW_ID = 'sysinfo_window';
40
41 /** @type {string}
42  * @const
43  */
44 var STATS_WINDOW_ID = 'stats_window';
45
46 var attachedFileBlob = null;
47 var lastReader = null;
48
49 var feedbackInfo = null;
50 var systemInfo = null;
51
52 /**
53  * Reads the selected file when the user selects a file.
54  * @param {Event} fileSelectedEvent The onChanged event for the file input box.
55  */
56 function onFileSelected(fileSelectedEvent) {
57   $('attach-error').hidden = true;
58   var file = fileSelectedEvent.target.files[0];
59   if (!file) {
60     // User canceled file selection.
61     attachedFileBlob = null;
62     return;
63   }
64
65   if (file.size > MAX_ATTACH_FILE_SIZE) {
66     $('attach-error').hidden = false;
67
68     // Clear our selected file.
69     $('attach-file').value = '';
70     attachedFileBlob = null;
71     return;
72   }
73
74   attachedFileBlob = file.slice();
75 }
76
77 /**
78  * Clears the file that was attached to the report with the initial request.
79  * Instead we will now show the attach file button in case the user wants to
80  * attach another file.
81  */
82 function clearAttachedFile() {
83   $('custom-file-container').hidden = true;
84   attachedFileBlob = null;
85   feedbackInfo.attachedFile = null;
86   $('attach-file').hidden = false;
87 }
88
89 /**
90  * Creates a closure that creates or shows a window with the given url.
91  * @param {string} windowId A string with the ID of the window we are opening.
92  * @param {string} url The destination URL of the new window.
93  * @return {function()} A function to be called to open the window.
94  */
95 function windowOpener(windowId, url) {
96   return function(e) {
97     e.preventDefault();
98     chrome.app.window.create(url, {id: windowId});
99   };
100 }
101
102 /**
103  * Opens a new window with chrome://slow_trace, downloading performance data.
104  */
105 function openSlowTraceWindow() {
106   chrome.app.window.create(
107       'chrome://slow_trace/tracing.zip#' + feedbackInfo.traceId);
108 }
109
110 /**
111  * Sends the report; after the report is sent, we need to be redirected to
112  * the landing page, but we shouldn't be able to navigate back, hence
113  * we open the landing page in a new tab and sendReport closes this tab.
114  * @return {boolean} True if the report was sent.
115  */
116 function sendReport() {
117   if ($('description-text').value.length == 0) {
118     var description = $('description-text');
119     description.placeholder = loadTimeData.getString('no-description');
120     description.focus();
121     return false;
122   }
123
124   // Prevent double clicking from sending additional reports.
125   $('send-report-button').disabled = true;
126   console.log('Feedback: Sending report');
127   if (!feedbackInfo.attachedFile && attachedFileBlob) {
128     feedbackInfo.attachedFile = { name: $('attach-file').value,
129                                   data: attachedFileBlob };
130   }
131
132   feedbackInfo.description = $('description-text').value;
133   feedbackInfo.pageUrl = $('page-url-text').value;
134   feedbackInfo.email = $('user-email-text').value;
135
136   var useSystemInfo = false;
137   var useHistograms = false;
138   if ($('sys-info-checkbox') != null &&
139       $('sys-info-checkbox').checked &&
140       systemInfo != null) {
141     // Send histograms along with system info.
142     useSystemInfo = useHistograms = true;
143   }
144 <if expr="pp_ifdef('chromeos')">
145   if ($('performance-info-checkbox') == null ||
146       !($('performance-info-checkbox').checked)) {
147     feedbackInfo.traceId = null;
148   }
149 </if>
150
151   if (useSystemInfo) {
152     if (feedbackInfo.systemInformation != null) {
153       // Concatenate sysinfo if we had any initial system information
154       // sent with the feedback request event.
155       feedbackInfo.systemInformation =
156           feedbackInfo.systemInformation.concat(systemInfo);
157     } else {
158       feedbackInfo.systemInformation = systemInfo;
159     }
160   }
161
162   feedbackInfo.sendHistograms = useHistograms;
163
164   // If the user doesn't want to send the screenshot.
165   if (!$('screenshot-checkbox').checked)
166     feedbackInfo.screenshot = null;
167
168   chrome.feedbackPrivate.sendFeedback(feedbackInfo, function(result) {
169     window.open(FEEDBACK_LANDING_PAGE, '_blank');
170     window.close();
171   });
172
173   return true;
174 }
175
176 /**
177  * Click listener for the cancel button.
178  * @param {Event} e The click event being handled.
179  */
180 function cancel(e) {
181   e.preventDefault();
182   window.close();
183 }
184
185 /**
186  * Converts a blob data URL to a blob object.
187  * @param {string} url The data URL to convert.
188  * @return {Blob} Blob object containing the data.
189  */
190 function dataUrlToBlob(url) {
191   var mimeString = url.split(',')[0].split(':')[1].split(';')[0];
192   var data = atob(url.split(',')[1]);
193   var dataArray = [];
194   for (var i = 0; i < data.length; ++i)
195     dataArray.push(data.charCodeAt(i));
196
197   return new Blob([new Uint8Array(dataArray)], {type: mimeString});
198 }
199
200 <if expr="pp_ifdef('chromeos')">
201 /**
202  * Update the page when performance feedback state is changed.
203  */
204 function performanceFeedbackChanged() {
205   if ($('performance-info-checkbox').checked) {
206     $('attach-file').disabled = true;
207     $('attach-file').checked = false;
208
209     $('screenshot-checkbox').disabled = true;
210     $('screenshot-checkbox').checked = false;
211   } else {
212     $('attach-file').disabled = false;
213     $('screenshot-checkbox').disabled = false;
214   }
215 }
216 </if>
217
218 function resizeAppWindow() {
219   // We pick the width from the titlebar, which has no margins.
220   var width = $('title-bar').scrollWidth;
221   if (width < FEEDBACK_MIN_WIDTH)
222     width = FEEDBACK_MIN_WIDTH;
223
224   // We get the height by adding the titlebar height and the content height +
225   // margins. We can't get the margins for the content-pane here by using
226   // style.margin - the variable seems to not exist.
227   var height = $('title-bar').scrollHeight +
228       $('content-pane').scrollHeight + CONTENT_MARGIN_HEIGHT;
229   if (height < FEEDBACK_MIN_HEIGHT)
230     height = FEEDBACK_MIN_HEIGHT;
231
232   chrome.app.window.current().resizeTo(width, height);
233 }
234
235 /**
236  * Initializes our page.
237  * Flow:
238  * .) DOMContent Loaded        -> . Request feedbackInfo object
239  *                                . Setup page event handlers
240  * .) Feedback Object Received -> . take screenshot
241  *                                . request email
242  *                                . request System info
243  *                                . request i18n strings
244  * .) Screenshot taken         -> . Show Feedback window.
245  */
246 function initialize() {
247   // TODO(rkc):  Remove logging once crbug.com/284662 is closed.
248   console.log('FEEDBACK_DEBUG: feedback.js: initialize()');
249
250   // Add listener to receive the feedback info object.
251   chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
252     if (request.sentFromEventPage) {
253       // TODO(rkc):  Remove logging once crbug.com/284662 is closed.
254       console.log('FEEDBACK_DEBUG: Received feedbackInfo.');
255       feedbackInfo = request.data;
256       $('description-text').textContent = feedbackInfo.description;
257       if (feedbackInfo.pageUrl)
258         $('page-url-text').value = feedbackInfo.pageUrl;
259
260       takeScreenshot(function(screenshotCanvas) {
261         // TODO(rkc):  Remove logging once crbug.com/284662 is closed.
262         console.log('FEEDBACK_DEBUG: Taken screenshot. Showing window.');
263
264         // We've taken our screenshot, show the feedback page without any
265         // further delay.
266         window.webkitRequestAnimationFrame(function() {
267           resizeAppWindow();
268         });
269         chrome.app.window.current().show();
270
271         var screenshotDataUrl = screenshotCanvas.toDataURL('image/png');
272         $('screenshot-image').src = screenshotDataUrl;
273         $('screenshot-image').classList.toggle('wide-screen',
274             $('screenshot-image').width > MAX_SCREENSHOT_WIDTH);
275         feedbackInfo.screenshot = dataUrlToBlob(screenshotDataUrl);
276       });
277
278       chrome.feedbackPrivate.getUserEmail(function(email) {
279         $('user-email-text').value = email;
280       });
281
282       chrome.feedbackPrivate.getSystemInformation(function(sysInfo) {
283         systemInfo = sysInfo;
284       });
285
286       // An extension called us with an attached file.
287       if (feedbackInfo.attachedFile) {
288         $('attached-filename-text').textContent =
289             feedbackInfo.attachedFile.name;
290         attachedFileBlob = feedbackInfo.attachedFile.data;
291         $('custom-file-container').hidden = false;
292         $('attach-file').hidden = true;
293       }
294
295 <if expr="pp_ifdef('chromeos')">
296       if (feedbackInfo.traceId && ($('performance-info-area'))) {
297         $('performance-info-area').hidden = false;
298         $('performance-info-checkbox').checked = true;
299         performanceFeedbackChanged();
300         $('performance-info-link').onclick = openSlowTraceWindow;
301       }
302 </if>
303
304       chrome.feedbackPrivate.getStrings(function(strings) {
305         loadTimeData.data = strings;
306         i18nTemplate.process(document, loadTimeData);
307
308         if ($('sys-info-url')) {
309           // Opens a new window showing the current system info.
310           $('sys-info-url').onclick =
311               windowOpener(SYSINFO_WINDOW_ID, 'chrome://system');
312         }
313         if ($('histograms-url')) {
314           // Opens a new window showing the histogram metrics.
315           $('histograms-url').onclick =
316               windowOpener(STATS_WINDOW_ID, 'chrome://histograms');
317         }
318       });
319     }
320   });
321
322   window.addEventListener('DOMContentLoaded', function() {
323     // TODO(rkc):  Remove logging once crbug.com/284662 is closed.
324     console.log('FEEDBACK_DEBUG: feedback.js: DOMContentLoaded');
325     // Ready to receive the feedback object.
326     chrome.runtime.sendMessage({ready: true});
327
328     // Setup our event handlers.
329     $('attach-file').addEventListener('change', onFileSelected);
330     $('send-report-button').onclick = sendReport;
331     $('cancel-button').onclick = cancel;
332     $('remove-attached-file').onclick = clearAttachedFile;
333 <if expr="pp_ifdef('chromeos')">
334     $('performance-info-checkbox').addEventListener(
335         'change', performanceFeedbackChanged);
336 </if>
337   });
338 }
339
340 initialize();