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;
19 var FEEDBACK_MIN_WIDTH
= 500;
24 var FEEDBACK_MIN_HEIGHT
= 585;
29 var CONTENT_MARGIN_HEIGHT
= 40;
34 var MAX_SCREENSHOT_WIDTH
= 100;
39 var SYSINFO_WINDOW_ID
= 'sysinfo_window';
44 var STATS_WINDOW_ID
= 'stats_window';
46 var attachedFileBlob
= null;
47 var lastReader
= null;
49 var feedbackInfo
= null;
50 var systemInfo
= null;
53 * Reads the selected file when the user selects a file.
54 * @param {Event} fileSelectedEvent The onChanged event for the file input box.
56 function onFileSelected(fileSelectedEvent
) {
57 $('attach-error').hidden
= true;
58 var file
= fileSelectedEvent
.target
.files
[0];
60 // User canceled file selection.
61 attachedFileBlob
= null;
65 if (file
.size
> MAX_ATTACH_FILE_SIZE
) {
66 $('attach-error').hidden
= false;
68 // Clear our selected file.
69 $('attach-file').value
= '';
70 attachedFileBlob
= null;
74 attachedFileBlob
= file
.slice();
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.
82 function clearAttachedFile() {
83 $('custom-file-container').hidden
= true;
84 attachedFileBlob
= null;
85 feedbackInfo
.attachedFile
= null;
86 $('attach-file').hidden
= false;
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.
95 function windowOpener(windowId
, url
) {
97 chrome
.app
.window
.create(url
, {id
: windowId
});
102 * Opens a new window with chrome://slow_trace, downloading performance data.
104 function openSlowTraceWindow() {
105 chrome
.app
.window
.create(
106 'chrome://slow_trace/tracing.zip#' + feedbackInfo
.traceId
);
110 * Sends the report; after the report is sent, we need to be redirected to
111 * the landing page, but we shouldn't be able to navigate back, hence
112 * we open the landing page in a new tab and sendReport closes this tab.
113 * @return {boolean} True if the report was sent.
115 function sendReport() {
116 if ($('description-text').value
.length
== 0) {
117 var description
= $('description-text');
118 description
.placeholder
= loadTimeData
.getString('no-description');
123 // Prevent double clicking from sending additional reports.
124 $('send-report-button').disabled
= true;
125 console
.log('Feedback: Sending report');
126 if (!feedbackInfo
.attachedFile
&& attachedFileBlob
) {
127 feedbackInfo
.attachedFile
= { name
: $('attach-file').value
,
128 data
: attachedFileBlob
};
131 feedbackInfo
.description
= $('description-text').value
;
132 feedbackInfo
.pageUrl
= $('page-url-text').value
;
133 feedbackInfo
.email
= $('user-email-text').value
;
135 var useSystemInfo
= false;
136 var useHistograms
= false;
137 if ($('sys-info-checkbox') != null &&
138 $('sys-info-checkbox').checked
&&
139 systemInfo
!= null) {
140 // Send histograms along with system info.
141 useSystemInfo
= useHistograms
= true;
143 <if expr
="pp_ifdef('chromeos')">
144 if ($('performance-info-checkbox') == null ||
145 !($('performance-info-checkbox').checked
)) {
146 feedbackInfo
.traceId
= null;
151 if (feedbackInfo
.systemInformation
!= null) {
152 // Concatenate sysinfo if we had any initial system information
153 // sent with the feedback request event.
154 feedbackInfo
.systemInformation
=
155 feedbackInfo
.systemInformation
.concat(systemInfo
);
157 feedbackInfo
.systemInformation
= systemInfo
;
161 feedbackInfo
.sendHistograms
= useHistograms
;
163 // If the user doesn't want to send the screenshot.
164 if (!$('screenshot-checkbox').checked
)
165 feedbackInfo
.screenshot
= null;
167 chrome
.feedbackPrivate
.sendFeedback(feedbackInfo
, function(result
) {
168 window
.open(FEEDBACK_LANDING_PAGE
, '_blank');
176 * Click listener for the cancel button.
177 * @param {Event} e The click event being handled.
185 * Converts a blob data URL to a blob object.
186 * @param {string} url The data URL to convert.
187 * @return {Blob} Blob object containing the data.
189 function dataUrlToBlob(url
) {
190 var mimeString
= url
.split(',')[0].split(':')[1].split(';')[0];
191 var data
= atob(url
.split(',')[1]);
193 for (var i
= 0; i
< data
.length
; ++i
)
194 dataArray
.push(data
.charCodeAt(i
));
196 return new Blob([new Uint8Array(dataArray
)], {type
: mimeString
});
199 <if expr
="pp_ifdef('chromeos')">
201 * Update the page when performance feedback state is changed.
203 function performanceFeedbackChanged() {
204 if ($('performance-info-checkbox').checked
) {
205 $('attach-file').disabled
= true;
206 $('attach-file').checked
= false;
208 $('screenshot-checkbox').disabled
= true;
209 $('screenshot-checkbox').checked
= false;
211 $('attach-file').disabled
= false;
212 $('screenshot-checkbox').disabled
= false;
217 function resizeAppWindow() {
218 // We pick the width from the titlebar, which has no margins.
219 var width
= $('title-bar').scrollWidth
;
220 if (width
< FEEDBACK_MIN_WIDTH
)
221 width
= FEEDBACK_MIN_WIDTH
;
223 // We get the height by adding the titlebar height and the content height +
224 // margins. We can't get the margins for the content-pane here by using
225 // style.margin - the variable seems to not exist.
226 var height
= $('title-bar').scrollHeight
+
227 $('content-pane').scrollHeight
+ CONTENT_MARGIN_HEIGHT
;
228 if (height
< FEEDBACK_MIN_HEIGHT
)
229 height
= FEEDBACK_MIN_HEIGHT
;
231 chrome
.app
.window
.current().resizeTo(width
, height
);
235 * Initializes our page.
237 * .) DOMContent Loaded -> . Request feedbackInfo object
238 * . Setup page event handlers
239 * .) Feedback Object Received -> . take screenshot
241 * . request System info
242 * . request i18n strings
243 * .) Screenshot taken -> . Show Feedback window.
245 function initialize() {
246 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
247 console
.log('FEEDBACK_DEBUG: feedback.js: initialize()');
249 // Add listener to receive the feedback info object.
250 chrome
.runtime
.onMessage
.addListener(function(request
, sender
, sendResponse
) {
251 if (request
.sentFromEventPage
) {
252 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
253 console
.log('FEEDBACK_DEBUG: Received feedbackInfo.');
254 feedbackInfo
= request
.data
;
255 $('description-text').textContent
= feedbackInfo
.description
;
256 if (feedbackInfo
.pageUrl
)
257 $('page-url-text').value
= feedbackInfo
.pageUrl
;
259 takeScreenshot(function(screenshotCanvas
) {
260 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
261 console
.log('FEEDBACK_DEBUG: Taken screenshot. Showing window.');
263 // We've taken our screenshot, show the feedback page without any
265 window
.webkitRequestAnimationFrame(function() {
268 chrome
.app
.window
.current().show();
270 var screenshotDataUrl
= screenshotCanvas
.toDataURL('image/png');
271 $('screenshot-image').src
= screenshotDataUrl
;
272 $('screenshot-image').classList
.toggle('wide-screen',
273 $('screenshot-image').width
> MAX_SCREENSHOT_WIDTH
);
274 feedbackInfo
.screenshot
= dataUrlToBlob(screenshotDataUrl
);
277 chrome
.feedbackPrivate
.getUserEmail(function(email
) {
278 $('user-email-text').value
= email
;
281 chrome
.feedbackPrivate
.getSystemInformation(function(sysInfo
) {
282 systemInfo
= sysInfo
;
285 // An extension called us with an attached file.
286 if (feedbackInfo
.attachedFile
) {
287 $('attached-filename-text').textContent
=
288 feedbackInfo
.attachedFile
.name
;
289 attachedFileBlob
= feedbackInfo
.attachedFile
.data
;
290 $('custom-file-container').hidden
= false;
291 $('attach-file').hidden
= true;
294 <if expr
="pp_ifdef('chromeos')">
295 if (feedbackInfo
.traceId
&& ($('performance-info-area'))) {
296 $('performance-info-area').hidden
= false;
297 $('performance-info-checkbox').checked
= true;
298 performanceFeedbackChanged();
299 $('performance-info-link').onclick
= openSlowTraceWindow
;
303 chrome
.feedbackPrivate
.getStrings(function(strings
) {
304 loadTimeData
.data
= strings
;
305 i18nTemplate
.process(document
, loadTimeData
);
307 if ($('sys-info-url')) {
308 // Opens a new window showing the current system info.
309 $('sys-info-url').onclick
=
310 windowOpener(SYSINFO_WINDOW_ID
, 'chrome://system');
312 if ($('histograms-url')) {
313 // Opens a new window showing the histogram metrics.
314 $('histograms-url').onclick
=
315 windowOpener(STATS_WINDOW_ID
, 'chrome://histograms');
321 window
.addEventListener('DOMContentLoaded', function() {
322 // TODO(rkc): Remove logging once crbug.com/284662 is closed.
323 console
.log('FEEDBACK_DEBUG: feedback.js: DOMContentLoaded');
324 // Ready to receive the feedback object.
325 chrome
.runtime
.sendMessage({ready
: true});
327 // Setup our event handlers.
328 $('attach-file').addEventListener('change', onFileSelected
);
329 $('send-report-button').onclick
= sendReport
;
330 $('cancel-button').onclick
= cancel
;
331 $('remove-attached-file').onclick
= clearAttachedFile
;
332 <if expr
="pp_ifdef('chromeos')">
333 $('performance-info-checkbox').addEventListener(
334 'change', performanceFeedbackChanged
);