Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1235)

Side by Side Diff: chrome/browser/resources/extensions/extension_error_overlay.js

Issue 1016413004: [Extensions] Update Error Console UI (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Dan's Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 cr.define('extensions', function() { 5 cr.define('extensions', function() {
6 'use strict'; 6 'use strict';
7 7
8 /** 8 /**
9 * Clear all the content of a given element. 9 * Clear all the content of a given element.
10 * @param {HTMLElement} element The element to be cleared. 10 * @param {HTMLElement} element The element to be cleared.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 assert(this.contextUrl_); 109 assert(this.contextUrl_);
110 }, 110 },
111 111
112 /** 112 /**
113 * Sets the error for the content. 113 * Sets the error for the content.
114 * @param {(RuntimeError|ManifestError)} error The error whose content 114 * @param {(RuntimeError|ManifestError)} error The error whose content
115 * should be displayed. 115 * should be displayed.
116 * @param {string} extensionUrl The URL associated with this extension. 116 * @param {string} extensionUrl The URL associated with this extension.
117 */ 117 */
118 setError: function(error, extensionUrl) { 118 setError: function(error, extensionUrl) {
119 if (this.error_)
Dan Beam 2015/04/22 21:02:38 is this if() necessary?
Devlin 2015/04/22 23:17:31 If your asking if this.error_ is ever null, the an
120 this.clearError();
121
119 this.error_ = error; 122 this.error_ = error;
120 this.extensionUrl_ = extensionUrl; 123 this.extensionUrl_ = extensionUrl;
121 this.contextUrl_.textContent = error.contextUrl ? 124 this.contextUrl_.textContent = error.contextUrl ?
122 getRelativeUrl(error.contextUrl, this.extensionUrl_) : 125 getRelativeUrl(error.contextUrl, this.extensionUrl_) :
123 loadTimeData.getString('extensionErrorOverlayContextUnknown'); 126 loadTimeData.getString('extensionErrorOverlayContextUnknown');
124 this.initStackTrace_(); 127 this.initStackTrace_();
125 }, 128 },
126 129
127 /** 130 /**
128 * Wipe content associated with a specific error. 131 * Wipe content associated with a specific error.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 /** 242 /**
240 * The content section for runtime errors; this is re-used for all 243 * The content section for runtime errors; this is re-used for all
241 * runtime errors and attached/detached from the overlay as needed. 244 * runtime errors and attached/detached from the overlay as needed.
242 * @type {RuntimeErrorContent} 245 * @type {RuntimeErrorContent}
243 * @private 246 * @private
244 */ 247 */
245 this.runtimeErrorContent_ = new RuntimeErrorContent(); 248 this.runtimeErrorContent_ = new RuntimeErrorContent();
246 } 249 }
247 250
248 /** 251 /**
249 * Value of ExtensionError::RUNTIME_ERROR enum.
250 * @see extensions/browser/extension_error.h
251 * @type {number}
252 * @const
253 * @private
254 */
255 ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_ = 1;
256
257 /**
258 * The manifest filename. 252 * The manifest filename.
259 * @type {string} 253 * @type {string}
260 * @const 254 * @const
261 * @private 255 * @private
262 */ 256 */
263 ExtensionErrorOverlay.MANIFEST_FILENAME_ = 'manifest.json'; 257 ExtensionErrorOverlay.MANIFEST_FILENAME_ = 'manifest.json';
264 258
265 /** 259 /**
266 * Determine whether or not chrome can load the source for a given file; this 260 * Determine whether or not chrome can load the source for a given file; this
267 * can only be done if the file belongs to the extension. 261 * can only be done if the file belongs to the extension.
268 * @param {string} file The file to load. 262 * @param {string} file The file to load.
269 * @param {string} extensionUrl The url for the extension, in the form 263 * @param {string} extensionUrl The url for the extension, in the form
270 * chrome-extension://<extension-id>/. 264 * chrome-extension://<extension-id>/.
271 * @return {boolean} True if the file can be loaded, false otherwise. 265 * @return {boolean} True if the file can be loaded, false otherwise.
272 * @private 266 * @private
273 */ 267 */
274 ExtensionErrorOverlay.canLoadFileSource = function(file, extensionUrl) { 268 ExtensionErrorOverlay.canLoadFileSource = function(file, extensionUrl) {
275 return file.substr(0, extensionUrl.length) == extensionUrl || 269 return file.substr(0, extensionUrl.length) == extensionUrl ||
276 file.toLowerCase() == ExtensionErrorOverlay.MANIFEST_FILENAME_; 270 file.toLowerCase() == ExtensionErrorOverlay.MANIFEST_FILENAME_;
277 }; 271 };
278 272
279 /**
280 * Determine whether or not we can show an overlay with more details for
281 * the given extension error.
282 * @param {Object} error The extension error.
283 * @param {string} extensionUrl The url for the extension, in the form
284 * "chrome-extension://<extension-id>/".
285 * @return {boolean} True if we can show an overlay for the error,
286 * false otherwise.
287 */
288 ExtensionErrorOverlay.canShowOverlayForError = function(error, extensionUrl) {
289 if (ExtensionErrorOverlay.canLoadFileSource(error.source, extensionUrl))
290 return true;
291
292 if (error.stackTrace) {
293 for (var i = 0; i < error.stackTrace.length; ++i) {
294 if (RuntimeErrorContent.shouldDisplayForUrl(error.stackTrace[i].url))
295 return true;
296 }
297 }
298
299 return false;
300 };
301
302 cr.addSingletonGetter(ExtensionErrorOverlay); 273 cr.addSingletonGetter(ExtensionErrorOverlay);
303 274
304 ExtensionErrorOverlay.prototype = { 275 ExtensionErrorOverlay.prototype = {
305 /** 276 /**
306 * The underlying error whose details are being displayed. 277 * The underlying error whose details are being displayed.
307 * @type {?(RuntimeError|ManifestError)} 278 * @type {?(RuntimeError|ManifestError)}
308 * @private 279 * @private
309 */ 280 */
310 error_: null, 281 selectedError_: null,
311 282
312 /** 283 /**
313 * Initialize the page. 284 * Initialize the page.
314 * @param {function(HTMLDivElement)} showOverlay The function to show or 285 * @param {function(HTMLDivElement)} showOverlay The function to show or
315 * hide the ExtensionErrorOverlay; this should take a single parameter 286 * hide the ExtensionErrorOverlay; this should take a single parameter
316 * which is either the overlay Div if the overlay should be displayed, 287 * which is either the overlay Div if the overlay should be displayed,
317 * or null if the overlay should be hidden. 288 * or null if the overlay should be hidden.
318 */ 289 */
319 initializePage: function(showOverlay) { 290 initializePage: function(showOverlay) {
320 var overlay = $('overlay'); 291 var overlay = $('overlay');
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 * Handles a click on the dismiss ("OK" or close) buttons. 340 * Handles a click on the dismiss ("OK" or close) buttons.
370 * @param {Event} e The click event. 341 * @param {Event} e The click event.
371 * @private 342 * @private
372 */ 343 */
373 handleDismiss_: function(e) { 344 handleDismiss_: function(e) {
374 this.setVisible(false); 345 this.setVisible(false);
375 346
376 // There's a chance that the overlay receives multiple dismiss events; in 347 // There's a chance that the overlay receives multiple dismiss events; in
377 // this case, handle it gracefully and return (since all necessary work 348 // this case, handle it gracefully and return (since all necessary work
378 // will already have been done). 349 // will already have been done).
379 if (!this.error_) 350 if (!this.selectedError_)
380 return; 351 return;
381 352
382 // Remove all previous content. 353 // Remove all previous content.
383 this.codeDiv_.clear(); 354 this.codeDiv_.clear();
384 355
385 this.openDevtoolsButton_.hidden = true; 356 // Note: We don't use ExtensionErrorList.clear() here because that would
357 // delete the errors on the backend, too.
358 clearElement(/** @type {HTMLElement} */(this.overlayDiv_.querySelector(
359 '.extension-error-list')));
386 360
387 if (this.error_.type == ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_) { 361 this.clearRuntimeContent_();
388 this.overlayDiv_.querySelector('.content-area').removeChild( 362
363 this.selectedError_ = null;
364 },
365
366 /**
367 * Clears the current content.
368 * @private
369 */
370 clearRuntimeContent_: function() {
371 if (this.runtimeErrorContent_.parentNode) {
372 this.runtimeErrorContent_.parentNode.removeChild(
389 this.runtimeErrorContent_); 373 this.runtimeErrorContent_);
390 this.runtimeErrorContent_.clearError(); 374 this.runtimeErrorContent_.clearError();
391 } 375 }
392 376 this.openDevtoolsButton_.hidden = true;
393 this.error_ = null;
394 }, 377 },
395 378
396 /** 379 /**
397 * Associate an error with the overlay. This will set the error for the 380 * Sets the active error for the overlay.
398 * overlay, and, if possible, will populate the code section of the overlay 381 * @param {?(ManifestError|RuntimeError)} error The error to make active.
399 * with the relevant file, load the stack trace, and generate links for 382 * @private
400 * opening devtools (the latter two only happen for runtime errors).
401 * @param {(RuntimeError|ManifestError)} error The error to show in the
402 * overlay.
403 * @param {string} extensionUrl The URL of the extension, in the form
404 * "chrome-extension://<extension_id>".
405 */ 383 */
406 setErrorAndShowOverlay: function(error, extensionUrl) { 384 setActiveError_: function(error) {
407 this.error_ = error; 385 this.selectedError_ = error;
408 386
409 if (this.error_.type == ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_) { 387 // If there is no error (this can happen if, e.g., the user deleted all
410 this.runtimeErrorContent_.setError(this.error_, extensionUrl); 388 // the errors), then clear the content.
389 if (!error) {
390 this.codeDiv_.populate(
391 null, loadTimeData.getString('extensionErrorNoErrorsCodeMessage'));
392 this.clearRuntimeContent_();
393 return;
394 }
395
396 var extensionUrl = 'chrome-extension://' + error.extensionId + '/';
397 // Set or hide runtime content.
398 if (error.type == chrome.developerPrivate.ErrorType.RUNTIME) {
399 this.runtimeErrorContent_.setError(error, extensionUrl);
411 this.overlayDiv_.querySelector('.content-area').insertBefore( 400 this.overlayDiv_.querySelector('.content-area').insertBefore(
412 this.runtimeErrorContent_, 401 this.runtimeErrorContent_,
413 this.codeDiv_.nextSibling); 402 this.codeDiv_.nextSibling);
414 this.openDevtoolsButton_.hidden = false; 403 this.openDevtoolsButton_.hidden = false;
415 this.openDevtoolsButton_.disabled = !error.canInspect; 404 this.openDevtoolsButton_.disabled = !error.canInspect;
405 } else {
406 this.clearRuntimeContent_();
416 } 407 }
417 408
409 // Read the file source to populate the code section, or set it to null if
410 // the file is unreadable.
418 if (ExtensionErrorOverlay.canLoadFileSource(error.source, extensionUrl)) { 411 if (ExtensionErrorOverlay.canLoadFileSource(error.source, extensionUrl)) {
419 var relativeUrl = getRelativeUrl(error.source, extensionUrl); 412 var relativeUrl = getRelativeUrl(error.source, extensionUrl);
420 413
421 var requestFileSourceArgs = {extensionId: error.extensionId, 414 var requestFileSourceArgs = {extensionId: error.extensionId,
422 message: error.message, 415 message: error.message,
423 pathSuffix: relativeUrl}; 416 pathSuffix: relativeUrl};
424 417 switch (error.type) {
425 if (relativeUrl.toLowerCase() == 418 case chrome.developerPrivate.ErrorType.MANIFEST:
426 ExtensionErrorOverlay.MANIFEST_FILENAME_) { 419 requestFileSourceArgs.manifestKey = error.manifestKey;
427 requestFileSourceArgs.manifestKey = error.manifestKey; 420 requestFileSourceArgs.manifestSpecific = error.manifestSpecific;
428 requestFileSourceArgs.manifestSpecific = error.manifestSpecific; 421 break;
429 } else { 422 case chrome.developerPrivate.ErrorType.RUNTIME:
430 requestFileSourceArgs.lineNumber = 423 requestFileSourceArgs.lineNumber =
431 error.stackTrace && error.stackTrace[0] ? 424 error.stackTrace && error.stackTrace[0] ?
432 error.stackTrace[0].lineNumber : 0; 425 error.stackTrace[0].lineNumber : 0;
426 break;
427 default:
428 assertNotReached();
433 } 429 }
434 this.requestFileSource(requestFileSourceArgs); 430 this.requestFileSource(requestFileSourceArgs);
435 } else { 431 } else {
436 this.onFileSourceResponse_(null); 432 this.onFileSourceResponse_(null);
437 } 433 }
438 }, 434 },
439 435
440 /** 436 /**
437 * Associate an error with the overlay. This will set the error for the
438 * overlay, and, if possible, will populate the code section of the overlay
439 * with the relevant file, load the stack trace, and generate links for
440 * opening devtools (the latter two only happen for runtime errors).
441 * @param {Array<(RuntimeError|ManifestError)>} errors The error to show in
442 * the overlay.
443 * @param {string} extensionId The id of the extension.
444 * @param {string} extensionName The name of the extension.
445 */
446 setErrorsAndShowOverlay: function(errors, extensionId, extensionName) {
447 document.querySelector(
448 '#extension-error-overlay .extension-error-overlay-title').
449 textContent = extensionName;
450 var errorsDiv = this.overlayDiv_.querySelector('.extension-error-list');
451 var extensionErrors =
452 new extensions.ExtensionErrorList(errors, extensionId);
453 errorsDiv.parentNode.replaceChild(extensionErrors, errorsDiv);
454 extensionErrors.addEventListener('activeExtensionErrorChanged',
455 function(e) {
456 this.setActiveError_(e.detail);
457 }.bind(this));
458
459 if (errors.length > 0)
460 this.setActiveError_(errors[0]);
461 this.setVisible(true);
462 },
463
464 /**
441 * Requests a file's source. 465 * Requests a file's source.
442 * @param {RequestFileSourceProperties} args The arguments for the call. 466 * @param {RequestFileSourceProperties} args The arguments for the call.
443 */ 467 */
444 requestFileSource: function(args) { 468 requestFileSource: function(args) {
445 chrome.developerPrivate.requestFileSource( 469 chrome.developerPrivate.requestFileSource(
446 args, this.onFileSourceResponse_.bind(this)); 470 args, this.onFileSourceResponse_.bind(this));
447 }, 471 },
448 472
449 /** 473 /**
450 * Set the code to be displayed in the code portion of the overlay. 474 * Set the code to be displayed in the code portion of the overlay.
451 * @see ExtensionErrorOverlay.requestFileSourceResponse(). 475 * @see ExtensionErrorOverlay.requestFileSourceResponse().
452 * @param {?RequestFileSourceResponse} response The response from the 476 * @param {?RequestFileSourceResponse} response The response from the
453 * request file source call, which will be shown as code. If |response| 477 * request file source call, which will be shown as code. If |response|
454 * is null, then a "Could not display code" message will be displayed 478 * is null, then a "Could not display code" message will be displayed
455 * instead. 479 * instead.
456 */ 480 */
457 onFileSourceResponse_: function(response) { 481 onFileSourceResponse_: function(response) {
458 if (response) {
459 document.querySelector(
460 '#extension-error-overlay .extension-error-overlay-title').
461 textContent = response.title;
462 }
463 this.codeDiv_.populate( 482 this.codeDiv_.populate(
464 response, // ExtensionCode can handle a null response. 483 response, // ExtensionCode can handle a null response.
465 loadTimeData.getString('extensionErrorOverlayNoCodeToDisplay')); 484 loadTimeData.getString('extensionErrorOverlayNoCodeToDisplay'));
466 this.setVisible(true); 485 this.setVisible(true);
467 }, 486 },
468 }; 487 };
469 488
470 // Export 489 // Export
471 return { 490 return {
472 ExtensionErrorOverlay: ExtensionErrorOverlay 491 ExtensionErrorOverlay: ExtensionErrorOverlay
473 }; 492 };
474 }); 493 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698