| 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 document.querySelector( |
| 519 '#extension-error-overlay .extension-error-overlay-title'). | 487 '#extension-error-overlay .extension-error-overlay-title'). |
| 520 textContent = code.title; | 488 textContent = response.title; |
| 521 | |
| 522 this.codeDiv_.populate( | 489 this.codeDiv_.populate( |
| 523 code, | 490 response, |
| 524 loadTimeData.getString('extensionErrorOverlayNoCodeToDisplay')); | 491 loadTimeData.getString('extensionErrorOverlayNoCodeToDisplay')); |
| 492 this.setVisible(true); |
| 525 }, | 493 }, |
| 526 }; | 494 }; |
| 527 | 495 |
| 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 | 496 // Export |
| 543 return { | 497 return { |
| 544 ExtensionErrorOverlay: ExtensionErrorOverlay | 498 ExtensionErrorOverlay: ExtensionErrorOverlay |
| 545 }; | 499 }; |
| 546 }); | 500 }); |
| OLD | NEW |