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.
8 var FEEDBACK_LANDING_PAGE =
9 'https://www.google.com/support/chrome/go/feedback_confirmation';
13 var MAX_ATTACH_FILE_SIZE = 3 * 1024 * 1024;
15 var attachedFileBlob = null;
16 var lastReader = null;
18 var feedbackInfo = null;
19 var systemInfo = null;
21 var systemInfoWindowId = 0;
24 * Reads the selected file when the user selects a file.
25 * @param {Event} fileSelectedEvent The onChanged event for the file input box.
27 function onFileSelected(fileSelectedEvent) {
28 $('attach-error').hidden = true;
29 var file = fileSelectedEvent.target.files[0];
31 // User canceled file selection.
32 attachedFileBlob = null;
36 if (file.size > MAX_ATTACH_FILE_SIZE) {
37 $('attach-error').hidden = false;
39 // Clear our selected file.
40 $('attach-file').value = '';
41 attachedFileBlob = null;
45 attachedFileBlob = file.slice();
49 * Clears the file that was attached to the report with the initial request.
50 * Instead we will now show the attach file button in case the user wants to
51 * attach another file.
53 function clearAttachedFile() {
54 $('custom-file-container').hidden = true;
55 attachedFileBlob = null;
56 feedbackInfo.attachedFile = null;
57 $('attach-file').hidden = false;
61 * Opens a new window with chrome://system, showing the current system info.
63 function openSystemInfoWindow() {
64 if (systemInfoWindowId == 0) {
65 chrome.windows.create({url: 'chrome://system'}, function(win) {
66 systemInfoWindowId = win.id;
67 chrome.app.window.current().show();
70 chrome.windows.update(systemInfoWindowId, {drawAttention: true});
75 * Opens a new window with chrome://slow_trace, downloading performance data.
77 function openSlowTraceWindow() {
78 chrome.windows.create(
79 {url: 'chrome://slow_trace/tracing.zip#' + feedbackInfo.traceId},
84 * Sends the report; after the report is sent, we need to be redirected to
85 * the landing page, but we shouldn't be able to navigate back, hence
86 * we open the landing page in a new tab and sendReport closes this tab.
87 * @return {boolean} True if the report was sent.
89 function sendReport() {
90 if ($('description-text').value.length == 0) {
91 var description = $('description-text');
92 description.placeholder = loadTimeData.getString('no-description');
97 // Prevent double clicking from sending additional reports.
98 $('send-report-button').disabled = true;
99 console.log('Feedback: Sending report');
100 if (!feedbackInfo.attachedFile && attachedFileBlob) {
101 feedbackInfo.attachedFile = { name: $('attach-file').value,
102 data: attachedFileBlob };
105 feedbackInfo.description = $('description-text').value;
106 feedbackInfo.pageUrl = $('page-url-text').value;
107 feedbackInfo.email = $('user-email-text').value;
109 var useSystemInfo = false;
110 // On ChromeOS, since we gather System info, check if the user has given his
111 // permission for us to send system info.
112 <if expr="pp_ifdef('chromeos')">
113 if ($('sys-info-checkbox') != null &&
114 $('sys-info-checkbox').checked &&
115 systemInfo != null) {
116 useSystemInfo = true;
118 if ($('performance-info-checkbox') == null ||
119 !($('performance-info-checkbox').checked)) {
120 feedbackInfo.traceId = null;
124 // On NonChromeOS, we don't have any system information gathered except the
125 // Chrome version and the OS version. Hence for Chrome, pass the system info
127 <if expr="not pp_ifdef('chromeos')">
128 if (systemInfo != null)
129 useSystemInfo = true;
133 if (feedbackInfo.systemInformation != null) {
134 // Concatenate sysinfo if we had any initial system information
135 // sent with the feedback request event.
136 feedbackInfo.systemInformation =
137 feedbackInfo.systemInformation.concat(systemInfo);
139 feedbackInfo.systemInformation = systemInfo;
143 // If the user doesn't want to send the screenshot.
144 if (!$('screenshot-checkbox').checked)
145 feedbackInfo.screenshot = null;
147 chrome.feedbackPrivate.sendFeedback(feedbackInfo, function(result) {
148 window.open(FEEDBACK_LANDING_PAGE, '_blank');
156 * Click listener for the cancel button.
157 * @param {Event} e The click event being handled.
165 * Converts a blob data URL to a blob object.
166 * @param {string} url The data URL to convert.
167 * @return {Blob} Blob object containing the data.
169 function dataUrlToBlob(url) {
170 var mimeString = url.split(',')[0].split(':')[1].split(';')[0];
171 var data = atob(url.split(',')[1]);
173 for (var i = 0; i < data.length; ++i)
174 dataArray.push(data.charCodeAt(i));
176 return new Blob([new Uint8Array(dataArray)], {type: mimeString});
179 <if expr="pp_ifdef('chromeos')">
181 * Update the page when performance feedback state is changed.
183 function performanceFeedbackChanged() {
184 if ($('performance-info-checkbox').checked) {
185 $('attach-file').disabled = true;
186 $('attach-file').checked = false;
188 $('screenshot-checkbox').disabled = true;
189 $('screenshot-checkbox').checked = false;
191 $('attach-file').disabled = false;
192 $('screenshot-checkbox').disabled = false;
198 * Initializes our page.
200 * .) DOMContent Loaded -> . Request feedbackInfo object
201 * . Setup page event handlers
202 * .) Feedback Object Received -> . take screenshot
204 * . request System info
205 * . request i18n strings
206 * .) Screenshot taken -> . Show Feedback window.
208 function initialize() {
209 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
210 console.log('FEEDBACK_DEBUG: feedback.js: initialize()');
212 // Add listener to receive the feedback info object.
213 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
214 if (request.sentFromEventPage) {
215 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
216 console.log('FEEDBACK_DEBUG: Received feedbackInfo.');
217 feedbackInfo = request.data;
218 $('description-text').textContent = feedbackInfo.description;
219 if (feedbackInfo.pageUrl)
220 $('page-url-text').value = feedbackInfo.pageUrl;
222 takeScreenshot(function(screenshotDataUrl) {
223 $('screenshot-image').src = screenshotDataUrl;
224 feedbackInfo.screenshot = dataUrlToBlob(screenshotDataUrl);
225 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
226 console.log('FEEDBACK_DEBUG: Taken screenshot. Showing window.');
227 chrome.app.window.current().show();
230 chrome.feedbackPrivate.getUserEmail(function(email) {
231 $('user-email-text').value = email;
234 chrome.feedbackPrivate.getSystemInformation(function(sysInfo) {
235 systemInfo = sysInfo;
238 // An extension called us with an attached file.
239 if (feedbackInfo.attachedFile) {
240 $('attached-filename-text').textContent =
241 feedbackInfo.attachedFile.name;
242 attachedFileBlob = feedbackInfo.attachedFile.data;
243 $('custom-file-container').hidden = false;
244 $('attach-file').hidden = true;
247 <if expr="pp_ifdef('chromeos')">
248 if (feedbackInfo.traceId && ($('performance-info-area'))) {
249 $('performance-info-area').hidden = false;
250 $('performance-info-checkbox').checked = true;
251 performanceFeedbackChanged();
252 $('performance-info-link').onclick = openSlowTraceWindow;
256 chrome.feedbackPrivate.getStrings(function(strings) {
257 loadTimeData.data = strings;
258 i18nTemplate.process(document, loadTimeData);
263 window.addEventListener('DOMContentLoaded', function() {
264 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
265 console.log('FEEDBACK_DEBUG: feedback.js: DOMContentLoaded');
266 // Ready to receive the feedback object.
267 chrome.runtime.sendMessage({ready: true});
269 // Setup our event handlers.
270 $('attach-file').addEventListener('change', onFileSelected);
271 $('send-report-button').onclick = sendReport;
272 $('cancel-button').onclick = cancel;
273 $('remove-attached-file').onclick = clearAttachedFile;
274 <if expr="pp_ifdef('chromeos')">
275 $('performance-info-checkbox').addEventListener(
276 'change', performanceFeedbackChanged);
279 chrome.windows.onRemoved.addListener(function(windowId, removeInfo) {
280 if (windowId == systemInfoWindowId)
281 systemInfoWindowId = 0;
283 if ($('sysinfo-url')) {
284 $('sysinfo-url').onclick = openSystemInfoWindow;