Chromium Code Reviews| Index: chrome/browser/resources/extensions/extension_error.js |
| diff --git a/chrome/browser/resources/extensions/extension_error.js b/chrome/browser/resources/extensions/extension_error.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3cd80e30e7d524122881b7632ea6390f96a01299 |
| --- /dev/null |
| +++ b/chrome/browser/resources/extensions/extension_error.js |
| @@ -0,0 +1,188 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +cr.define('extensions', function() { |
| + 'use strict'; |
| + |
| + /** |
| + * Returns whether or not a given |url| is associated with an extension. |
| + * @param {string} url The url to examine. |
| + * @param {string} extensionUrl The url of the extension. |
| + * @return {boolean} Whether or not the url is associated with the extension. |
| + */ |
| + function isExtensionUrl(url, extensionUrl) { |
| + return url.substring(0, extensionUrl.length) === extensionUrl; |
| + } |
| + |
| + /** |
| + * Get the url relative to the main extension url. If the url is |
| + * unassociated with the extension, this will be the full url. |
| + * @param {url} The url to make relative. |
|
Dan Beam
2013/08/20 21:39:26
@param {string} url The url to make relative.
Devlin
2013/08/20 23:06:51
D'oh. Fixed.
|
| + * @param {extensionUrl} The host for which the url is relative. |
|
Dan Beam
2013/08/20 21:39:26
@param {string} extensionURL The host for which th
Devlin
2013/08/20 23:06:51
Is chrome JS style 'URL' or 'Url'? Kept 'Url' her
|
| + * @return {string} The url relative to the host. |
| + */ |
| + function getRelativeUrl(url, extensionUrl) { |
| + return isExtensionUrl(url, extensionUrl) ? |
| + url.substring(extensionUrl.length) : url; |
| + } |
| + |
| + /** |
| + * Clone a template within the extension error template collection. |
| + * @param {string} templateName The class name of the template to clone. |
| + * @return {HTMLElement} The clone of the template. |
| + */ |
| + function cloneTemplate(templateName) { |
| + return $('template-collection-extension-error') |
|
Dan Beam
2013/08/20 21:39:26
nit: operators at end
return $('template-collecti
Devlin
2013/08/20 23:06:51
Done.
|
| + .querySelector(templateName).cloneNode(true); |
| + } |
| + |
| + /** |
| + * Creates a new ExtensionError HTMLElement. |
| + * @param {Object} error The error the element should represent. |
| + * @return {HTMLElement} The created error element. |
|
Dan Beam
2013/08/20 21:39:26
nit: remove @return
Dan Beam
2013/08/20 21:39:26
* @constructor
* @extends {HTMLDivElement}
Devlin
2013/08/20 23:06:51
Done.
Devlin
2013/08/20 23:06:51
Done.
|
| + */ |
| + function ExtensionError(error) { |
| + var div = document.createElement('div'); |
| + div.__proto__ = ExtensionError.prototype; |
| + div.className = 'extension-error-simple-wrapper'; |
| + div.error_ = error; |
| + div.decorate(); |
| + return div; |
| + } |
| + |
| + ExtensionError.prototype = { |
| + __proto__: HTMLDivElement.prototype, |
| + |
| + /** @override */ |
| + decorate: function() { |
| + var metadata = cloneTemplate('.extension-error-metadata'); |
| + |
| + // Set an icon for the level of severity... |
| + var iconNode = metadata.querySelector('img'); |
| + iconNode.className = |
| + this.error_.level == 0 ? 'extension-error-icon-log' : |
| + this.error_.level == 1 ? 'extension-error-icon-warn' : |
| + 'extension-error-icon-error'; |
|
Dan Beam
2013/08/20 21:39:26
nit: something like this is easier to read, IMO
i
Devlin
2013/08/20 23:06:51
Done.
|
| + |
| + // Add a property for the extension's base url in order to determine if |
| + // a url belongs to the extension. |
| + this.extensionUrl_ = |
| + 'chrome-extension://' + this.error_.extensionId + '/'; |
| + |
| + // The error message... |
|
Dan Beam
2013/08/20 21:39:26
^ this seems to be self-evident
Devlin
2013/08/20 23:06:51
Done.
|
| + metadata.querySelector('.extension-error-message').innerText = |
| + this.error_.message; |
| + |
| + // The error source... |
|
Dan Beam
2013/08/20 21:39:26
^ and this (so comments probably aren't required)
Devlin
2013/08/20 23:06:51
Done.
|
| + metadata.querySelector('.extension-error-source').innerText = |
| + '(' + getRelativeUrl(this.error_.source, this.extensionUrl_) + ')'; |
| + |
| + this.appendChild(metadata); |
| + this.addViewLinkToNode_(this, this.error_.source); |
| + }, |
| + |
| + /** |
| + * Add a "view" link to the given node, if a user can view the source of the |
| + * specified url. |
| + * @param {HTMLElement} node The node to which we append the view link. |
| + * @param {string} url The url to the resource to view. |
|
Dan Beam
2013/08/20 21:39:26
* @private
Devlin
2013/08/20 23:06:51
Done.
|
| + */ |
| + addViewLinkToNode_: function(node, url) { |
| + if (this.canViewSource_(url)) |
| + node.appendChild(this.getViewSourceLink_(url)); |
| + }, |
| + |
| + /** |
| + * Determine whether we can view the source of a given url. |
| + * @param {string} url The url to the resource to view. |
| + * @return {boolean} Whether or not we can view the source for the url. |
|
Dan Beam
2013/08/20 21:39:26
* @private
Devlin
2013/08/20 23:06:51
Done.
|
| + */ |
| + canViewSource_: function(url) { |
| + return isExtensionUrl(url, this.extensionUrl_) || |
| + url === 'manifest.json'; |
|
Dan Beam
2013/08/20 21:39:26
nit: s/===/==/ IMO
Devlin
2013/08/20 23:06:51
Mmkay (it's definitely not done enough for any of
|
| + }, |
| + |
| + /** |
| + * Create a clickable node to view the source for the given url. |
| + * @param {string} url The url to the resource to view. |
| + * @return {HTMLElement} The clickable node to view the source. |
|
Dan Beam
2013/08/20 21:39:26
* @private
Devlin
2013/08/20 23:06:51
Done.
|
| + */ |
| + getViewSourceLink_: function(url) { |
| + var node = document.createElement('a'); |
| + node.innerText = loadTimeData.getString('extensionErrorViewSource'); |
| + |
| + var relativeLink = getRelativeUrl(url, this.extensionUrl_); |
| + node.addEventListener('click', function(e) { |
| + chrome.send('extensionErrorRequestFileSource', |
| + [{ |
|
Dan Beam
2013/08/20 21:39:26
nit:
chrome.send('extensionErrorRequestFileSource
Devlin
2013/08/20 23:06:51
Done.
|
| + 'extensionId': this.error_.extensionId, |
| + 'errorMessage': this.error_.message, |
| + 'fileType': 'manifest', |
| + 'pathSuffix': relativeLink, |
| + 'feature': this.error_.manifestKey, |
| + 'specific': this.error_.manifestSpecific |
| + }]); |
| + }.bind(this)); |
| + return node; |
| + } |
|
Dan Beam
2013/08/20 21:39:26
nit: },
Devlin
2013/08/20 23:06:51
Done.
|
| + }; |
| + |
|
Dan Beam
2013/08/20 21:39:26
/**
* What an ExtensionErrorList does in prose as
Devlin
2013/08/20 23:06:51
Done.
|
| + function ExtensionErrorList(errors) { |
| + var div = cloneTemplate('.extension-error-list'); |
| + div.__proto__ = ExtensionErrorList.prototype; |
| + div.errors_ = errors; |
| + div.decorate(); |
| + return div; |
| + } |
| + |
| + ExtensionErrorList.prototype = { |
| + __proto__: HTMLDivElement.prototype, |
| + |
| + kMaxErrorsToShow_: 3, |
|
Dan Beam
2013/08/20 21:39:26
/**
* @private
* @const
*/
MAX_ERRORS_TO_SHOW_:
Devlin
2013/08/20 23:06:51
Done.
|
| + |
| + /** @override */ |
| + decorate: function() { |
| + this.contents_ = this.querySelector('.extension-error-list-contents'); |
| + this.errors_.forEach(function(error) { |
| + this.contents_.appendChild(document.createElement('li')).appendChild( |
| + new ExtensionError(error)); |
| + }.bind(this)); |
|
Dan Beam
2013/08/20 21:39:26
}, this); (forEach() takes a thisArg)
Devlin
2013/08/20 23:06:51
Ooh, much cleaner. :)
|
| + |
| + if (this.contents_.children.length > this.kMaxErrorsToShow_) { |
| + for (var i = this.kMaxErrorsToShow_; |
| + i < this.contents_.children.length; ++i) |
|
Dan Beam
2013/08/20 21:39:26
nit: curlies
Devlin
2013/08/20 23:06:51
Done.
|
| + this.contents_.children[i].hidden = true; |
| + this.initShowMoreButton_(); |
| + } |
| + }, |
| + |
|
Dan Beam
2013/08/20 21:39:26
/** @private */
Devlin
2013/08/20 23:06:51
Done.
|
| + initShowMoreButton_: function() { |
| + var button = this.querySelector('.extension-error-list-show-more') |
|
Dan Beam
2013/08/20 21:39:26
this.querySelector('.extension-error-list-show-mor
Devlin
2013/08/20 23:06:51
nifty. Done.
|
| + .querySelector('a'); |
| + button.hidden = false; |
| + button.isShowingAll = false; |
| + button.addEventListener('click', function(e) { |
|
Dan Beam
2013/08/20 21:39:26
nit:
for (var i = this.MAX_ERRORS_TO_SHOW_;
Devlin
2013/08/20 23:06:51
Done.
|
| + if (button.isShowingAll) { |
| + for (var i = this.kMaxErrorsToShow_; |
| + i < this.contents_.children.length; ++i) { |
| + this.contents_.children[i].hidden = true; |
| + } |
| + button.innerText = loadTimeData.getString('extensionErrorsShowMore'); |
| + } else { |
| + for (var i = this.kMaxErrorsToShow_; |
| + i < this.contents_.children.length; ++i) { |
| + this.contents_.children[i].hidden = false; |
| + } |
| + button.innerText = loadTimeData.getString('extensionErrorsShowFewer'); |
| + } |
| + |
| + button.isShowingAll = !button.isShowingAll; |
| + }.bind(this)); |
| + } |
| + }; |
| + |
| + return { |
| + ExtensionErrorList: ExtensionErrorList |
| + }; |
| +}); |