OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * The type of the stack trace object. The definition is based on | 6 * The type of the stack trace object. The definition is based on |
7 * extensions/browser/extension_error.cc:RuntimeError::ToValue(). | 7 * extensions/browser/extension_error.cc:RuntimeError::ToValue(). |
8 * @typedef {{columnNumber: number, | 8 * @typedef {{columnNumber: number, |
9 * functionName: string, | 9 * functionName: string, |
10 * lineNumber: number, | 10 * lineNumber: number, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 * want to include any of our own code in stack traces. | 84 * want to include any of our own code in stack traces. |
85 * @param {string} url The url in question. | 85 * @param {string} url The url in question. |
86 * @return {boolean} True if the url should be displayed, and false | 86 * @return {boolean} True if the url should be displayed, and false |
87 * otherwise (i.e., if it is an internal script). | 87 * otherwise (i.e., if it is an internal script). |
88 */ | 88 */ |
89 RuntimeErrorContent.shouldDisplayForUrl = function(url) { | 89 RuntimeErrorContent.shouldDisplayForUrl = function(url) { |
90 // All our internal scripts are in the 'extensions::' namespace. | 90 // All our internal scripts are in the 'extensions::' namespace. |
91 return !/^extensions::/.test(url); | 91 return !/^extensions::/.test(url); |
92 }; | 92 }; |
93 | 93 |
94 /** | |
95 * Send a call to chrome to open the developer tools for an error. | |
96 * This will call either the bound function in ExtensionErrorHandler or the | |
97 * API function from developerPrivate, depending on whether this is being | |
98 * used in the native chrome:extensions page or the Apps Developer Tool. | |
99 * @see chrome/browser/ui/webui/extensions/extension_error_ui_util.h | |
100 * @param {OpenDevToolsProperties} args The arguments to pass to openDevTools. | |
101 * @private | |
102 */ | |
103 RuntimeErrorContent.openDevtools_ = function(args) { | |
104 if (chrome.send) | |
105 chrome.send('extensionErrorOpenDevTools', [args]); | |
106 else if (chrome.developerPrivate) | |
107 chrome.developerPrivate.openDevTools(args); | |
108 else | |
109 assertNotReached('Cannot call either openDevTools function.'); | |
110 }; | |
111 | |
112 RuntimeErrorContent.prototype = { | 94 RuntimeErrorContent.prototype = { |
113 __proto__: HTMLDivElement.prototype, | 95 __proto__: HTMLDivElement.prototype, |
114 | 96 |
115 /** | 97 /** |
116 * The underlying error whose details are being displayed. | 98 * The underlying error whose details are being displayed. |
117 * @type {?RuntimeError} | 99 * @type {?RuntimeError} |
118 * @private | 100 * @private |
119 */ | 101 */ |
120 error_: null, | 102 error_: null, |
121 | 103 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 211 } |
230 frameNode.textContent = description; | 212 frameNode.textContent = description; |
231 | 213 |
232 // When the user clicks on a frame in the stack trace, we should | 214 // When the user clicks on a frame in the stack trace, we should |
233 // highlight that overlay in the list, display the appropriate source | 215 // highlight that overlay in the list, display the appropriate source |
234 // code with the line highlighted, and link the "Open DevTools" button | 216 // code with the line highlighted, and link the "Open DevTools" button |
235 // with that frame. | 217 // with that frame. |
236 frameNode.addEventListener('click', function(frame, frameNode, e) { | 218 frameNode.addEventListener('click', function(frame, frameNode, e) { |
237 this.setActiveFrame_(frameNode); | 219 this.setActiveFrame_(frameNode); |
238 | 220 |
239 // Request the file source with the section highlighted; this will | 221 // Request the file source with the section highlighted. |
240 // call ExtensionErrorOverlay.requestFileSourceResponse() when | 222 extensions.ExtensionErrorOverlay.getInstance().requestFileSource( |
241 // completed, which in turn calls setCode(). | |
242 ExtensionErrorOverlay.requestFileSource( | |
243 {extensionId: this.error_.extensionId, | 223 {extensionId: this.error_.extensionId, |
244 message: this.error_.message, | 224 message: this.error_.message, |
245 pathSuffix: getRelativeUrl(frame.url, | 225 pathSuffix: getRelativeUrl(frame.url, |
246 assert(this.extensionUrl_)), | 226 assert(this.extensionUrl_)), |
247 lineNumber: frame.lineNumber}); | 227 lineNumber: frame.lineNumber}); |
248 }.bind(this, frame, frameNode)); | 228 }.bind(this, frame, frameNode)); |
249 | 229 |
250 this.stackTrace_.appendChild(frameNode); | 230 this.stackTrace_.appendChild(frameNode); |
251 } | 231 } |
252 | 232 |
253 // Set the current stack frame to the first stack frame and show the | 233 // Set the current stack frame to the first stack frame and show the |
254 // trace, if one exists. (We can't just check error.stackTrace, because | 234 // trace, if one exists. (We can't just check error.stackTrace, because |
255 // it's possible the trace was purely internal, and we don't show | 235 // it's possible the trace was purely internal, and we don't show |
256 // internal frames.) | 236 // internal frames.) |
257 if (this.stackTrace_.children.length > 0) { | 237 if (this.stackTrace_.children.length > 0) { |
258 this.stackTrace_.hidden = false; | 238 this.stackTrace_.hidden = false; |
259 this.setActiveFrame_(assertInstanceof(this.stackTrace_.firstChild, | 239 this.setActiveFrame_(assertInstanceof(this.stackTrace_.firstChild, |
260 HTMLElement)); | 240 HTMLElement)); |
261 } | 241 } |
262 }, | 242 }, |
263 | 243 |
264 /** | 244 /** |
265 * Open the developer tools for the active stack frame. | 245 * Open the developer tools for the active stack frame. |
266 */ | 246 */ |
267 openDevtools: function() { | 247 openDevtools: function() { |
268 var stackFrame = | 248 var stackFrame = |
269 this.error_.stackTrace[this.currentFrameNode_.indexIntoTrace]; | 249 this.error_.stackTrace[this.currentFrameNode_.indexIntoTrace]; |
270 | 250 |
271 RuntimeErrorContent.openDevtools_( | 251 chrome.developerPrivate.openDevTools( |
272 {renderProcessId: this.error_.renderProcessId || -1, | 252 {renderProcessId: this.error_.renderProcessId || -1, |
273 renderViewId: this.error_.renderViewId || -1, | 253 renderViewId: this.error_.renderViewId || -1, |
274 url: stackFrame.url, | 254 url: stackFrame.url, |
275 lineNumber: stackFrame.lineNumber || 0, | 255 lineNumber: stackFrame.lineNumber || 0, |
276 columnNumber: stackFrame.columnNumber || 0}); | 256 columnNumber: stackFrame.columnNumber || 0}); |
277 } | 257 } |
278 }; | 258 }; |
279 | 259 |
280 /** | 260 /** |
281 * The ExtensionErrorOverlay will show the contents of a file which pertains | 261 * The ExtensionErrorOverlay will show the contents of a file which pertains |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 if (error.stackTrace) { | 321 if (error.stackTrace) { |
342 for (var i = 0; i < error.stackTrace.length; ++i) { | 322 for (var i = 0; i < error.stackTrace.length; ++i) { |
343 if (RuntimeErrorContent.shouldDisplayForUrl(error.stackTrace[i].url)) | 323 if (RuntimeErrorContent.shouldDisplayForUrl(error.stackTrace[i].url)) |
344 return true; | 324 return true; |
345 } | 325 } |
346 } | 326 } |
347 | 327 |
348 return false; | 328 return false; |
349 }; | 329 }; |
350 | 330 |
351 /** | |
352 * Send a call to chrome to request the source of a given file. | |
353 * This will call either the bound function in ExtensionErrorHandler or the | |
354 * API function from developerPrivate, depending on whether this is being | |
355 * used in the native chrome:extensions page or the Apps Developer Tool. | |
356 * @see chrome/browser/ui/webui/extensions/extension_error_ui_util.h | |
357 * @param {RequestFileSourceProperties} args The arguments to pass to | |
358 * requestFileSource. | |
359 */ | |
360 ExtensionErrorOverlay.requestFileSource = function(args) { | |
361 if (chrome.send) { | |
362 chrome.send('extensionErrorRequestFileSource', [args]); | |
363 } else if (chrome.developerPrivate) { | |
364 chrome.developerPrivate.requestFileSource(args, function(result) { | |
365 extensions.ExtensionErrorOverlay.requestFileSourceResponse(result); | |
366 }); | |
367 } else { | |
368 assertNotReached('Cannot call either requestFileSource function.'); | |
369 } | |
370 }; | |
371 | |
372 cr.addSingletonGetter(ExtensionErrorOverlay); | 331 cr.addSingletonGetter(ExtensionErrorOverlay); |
373 | 332 |
374 ExtensionErrorOverlay.prototype = { | 333 ExtensionErrorOverlay.prototype = { |
375 /** | 334 /** |
376 * The underlying error whose details are being displayed. | 335 * The underlying error whose details are being displayed. |
377 * @type {?RuntimeError} | 336 * @type {?RuntimeError} |
378 * @private | 337 * @private |
379 */ | 338 */ |
380 error_: null, | 339 error_: null, |
381 | 340 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 452 |
494 if (relativeUrl.toLowerCase() == | 453 if (relativeUrl.toLowerCase() == |
495 ExtensionErrorOverlay.MANIFEST_FILENAME_) { | 454 ExtensionErrorOverlay.MANIFEST_FILENAME_) { |
496 requestFileSourceArgs.manifestKey = error.manifestKey; | 455 requestFileSourceArgs.manifestKey = error.manifestKey; |
497 requestFileSourceArgs.manifestSpecific = error.manifestSpecific; | 456 requestFileSourceArgs.manifestSpecific = error.manifestSpecific; |
498 } else { | 457 } else { |
499 requestFileSourceArgs.lineNumber = | 458 requestFileSourceArgs.lineNumber = |
500 error.stackTrace && error.stackTrace[0] ? | 459 error.stackTrace && error.stackTrace[0] ? |
501 error.stackTrace[0].lineNumber : 0; | 460 error.stackTrace[0].lineNumber : 0; |
502 } | 461 } |
503 ExtensionErrorOverlay.requestFileSource(requestFileSourceArgs); | 462 this.requestFileSource(requestFileSourceArgs); |
504 } else { | 463 } else { |
505 ExtensionErrorOverlay.requestFileSourceResponse(null); | 464 this.onFileSourceResponse_(null); |
506 } | 465 } |
507 }, | 466 }, |
508 | 467 |
| 468 /** |
| 469 * Requests a file's source. |
| 470 * @param {RequestFileSourceProperties} args The arguments for the call. |
| 471 */ |
| 472 requestFileSource: function(args) { |
| 473 chrome.developerPrivate.requestFileSource( |
| 474 args, this.onFileSourceResponse_.bind(this)); |
| 475 }, |
509 | 476 |
510 /** | 477 /** |
511 * Set the code to be displayed in the code portion of the overlay. | 478 * Set the code to be displayed in the code portion of the overlay. |
512 * @see ExtensionErrorOverlay.requestFileSourceResponse(). | 479 * @see ExtensionErrorOverlay.requestFileSourceResponse(). |
513 * @param {?ExtensionHighlight} code The code to be displayed. If |code| is | 480 * @param {?RequestFileSourceResponse} response The response from the |
514 * null, then | 481 * request file source call, which will be shown as code. If |response| |
515 * a "Could not display code" message will be displayed instead. | 482 * is null, then a "Could not display code" message will be displayed |
| 483 * instead. |
516 */ | 484 */ |
517 setCode: function(code) { | 485 onFileSourceResponse_: function(response) { |
518 document.querySelector( | 486 if (response) { |
519 '#extension-error-overlay .extension-error-overlay-title'). | 487 document.querySelector( |
520 textContent = code.title; | 488 '#extension-error-overlay .extension-error-overlay-title'). |
521 | 489 textContent = response.title; |
| 490 } |
522 this.codeDiv_.populate( | 491 this.codeDiv_.populate( |
523 code, | 492 response, // ExtensionCode can handle a null response. |
524 loadTimeData.getString('extensionErrorOverlayNoCodeToDisplay')); | 493 loadTimeData.getString('extensionErrorOverlayNoCodeToDisplay')); |
| 494 this.setVisible(true); |
525 }, | 495 }, |
526 }; | 496 }; |
527 | 497 |
528 /** | |
529 * Called by the ExtensionErrorHandler responding to the request for a file's | |
530 * source. Populate the content area of the overlay and display the overlay. | |
531 * @param {?ExtensionHighlight} result The three 'highlight' strings represent | |
532 * three portions of the file's content to display - the portion which is | |
533 * most relevant and should be emphasized (highlight), and the parts both | |
534 * before and after this portion. These may be empty. | |
535 */ | |
536 ExtensionErrorOverlay.requestFileSourceResponse = function(result) { | |
537 var overlay = extensions.ExtensionErrorOverlay.getInstance(); | |
538 overlay.setCode(result); | |
539 overlay.setVisible(true); | |
540 }; | |
541 | |
542 // Export | 498 // Export |
543 return { | 499 return { |
544 ExtensionErrorOverlay: ExtensionErrorOverlay | 500 ExtensionErrorOverlay: ExtensionErrorOverlay |
545 }; | 501 }; |
546 }); | 502 }); |
OLD | NEW |