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..a1f4aed8dfeb25a443961f5fd5f091d06b7d752e |
--- /dev/null |
+++ b/chrome/browser/resources/extensions/extension_error.js |
@@ -0,0 +1,208 @@ |
+// 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 {string} url The url to make relative. |
+ * @param {string} extensionUrl The host for which the url is relative. |
+ * @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'). |
+ querySelector(templateName).cloneNode(true); |
Dan Beam
2013/08/29 00:24:30
maybe: querySelector('.' + templateName) and remov
Devlin
2013/08/29 21:02:04
Done.
|
+ } |
+ |
+ /** |
+ * Creates a new ExtensionError HTMLElement. |
Dan Beam
2013/08/29 00:24:30
^ this is kind of a lacking description. what doe
Devlin
2013/08/29 21:02:04
Done.
|
+ * @param {Object} error The error the element should represent. |
+ * @constructor |
+ * @extends {HTMLDivElement} |
+ */ |
+ 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'); |
+ |
+ // Add an additional class for the severity level. |
+ if (this.error_.level == 0) |
+ metadata.className += ' extension-error-log'; |
+ else if (this.error_.level == 1) |
+ metadata.className += ' extension-error-warn'; |
+ else |
+ metadata.className += ' extension-error-error'; |
+ |
+ // 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 + '/'; |
+ |
+ metadata.querySelector('.extension-error-message').innerText = |
+ this.error_.message; |
+ |
+ metadata.appendChild(this.getViewSourceOrPlain_( |
+ '(' + getRelativeUrl(this.error_.source, this.extensionUrl_) + ')', |
+ this.error_.source)); |
+ |
+ this.appendChild(metadata); |
+ }, |
+ |
+ /** |
+ * If it's possible to view the source for the given |url|, then return a |
+ * link to do so. Otherwise, return a plain-text node. |
Dan Beam
2013/08/29 00:24:30
^ is this still returning a text node?
Devlin
2013/08/29 21:02:04
Yeah - it returns a div with just plain text (and
|
+ * @param {string} description The innerText of the node to create; |
+ * a human-friendly description the location (e.g., filename, line). |
Dan Beam
2013/08/29 00:24:30
nit: i think it'd be better to just explain what s
Devlin
2013/08/29 21:02:04
Done.
|
+ * @param {string} url The url of the resource to view. |
+ * @return {HTMLElement} The created node, either a link or plaintext. |
+ * @private |
+ */ |
+ getViewSourceOrPlain_: function(description, url) { |
+ if (this.canViewSource_(url)) { |
Dan Beam
2013/08/29 00:24:30
nit: no curlies
Devlin
2013/08/29 21:02:04
Done.
|
+ var node = this.getViewSourceLink_(url); |
+ } else { |
+ var node = document.createElement('div'); |
+ } |
+ node.className = 'extension-error-view-source'; |
Dan Beam
2013/08/29 00:24:30
what does setting the classname of a text node do?
Devlin
2013/08/29 21:02:04
It's so the css can take effect. Right now, there
|
+ node.innerText = description; |
+ return node; |
+ }, |
+ |
+ /** |
+ * Determine whether we can view the source of a given url. |
+ * @param {string} url The url to the resource to view. |
Dan Beam
2013/08/29 00:24:30
nit: the url _of_ the resource to view?
Devlin
2013/08/29 21:02:04
Done.
|
+ * @return {boolean} Whether or not we can view the source for the url. |
+ * @private |
+ */ |
+ canViewSource_: function(url) { |
+ return isExtensionUrl(url, this.extensionUrl_) || url == 'manifest.json'; |
+ }, |
+ |
+ /** |
+ * 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. |
+ * @private |
+ */ |
+ getViewSourceLink_: function(url) { |
+ var node = document.createElement('a'); |
+ var relativeUrl = getRelativeUrl(url, this.extensionUrl_); |
+ |
+ node.addEventListener('click', function(e) { |
+ chrome.send('extensionErrorRequestFileSource', |
+ [{'extensionId': this.error_.extensionId, |
+ 'errorMessage': this.error_.message, |
+ 'fileType': 'manifest', |
+ 'pathSuffix': relativeUrl, |
+ 'feature': this.error_.manifestKey, |
+ 'specific': this.error_.manifestSpecific}]); |
+ }.bind(this)); |
+ return node; |
+ }, |
+ }; |
+ |
+ /** |
+ * An ExtensionErrorList represents the list of either runtime or manifest |
+ * errors for a given extension. Each item in the list is an ExtensionError |
+ * object, with information about the error. The list will display up to |
+ * |MAX_ERRORS_TO_SHOW_| errors, with the option to expand (and then shrink) |
+ * the displayed portion. This is included as part of the Extension node in |
+ * the ExtensionList in chrome://extensions, if errors are present. |
Dan Beam
2013/08/29 00:24:30
nit: this whole paragraph could be shortened to:
Devlin
2013/08/29 21:02:04
Done.
|
+ * @constructor |
+ * @extends {HTMLDivElement} |
+ */ |
+ 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, |
+ |
+ /** |
+ * @private |
+ * @const |
+ * @type {number} |
+ */ |
+ MAX_ERRORS_TO_SHOW_: 3, |
+ |
+ /** @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)); |
+ }, this); |
+ |
+ if (this.contents_.children.length > this.MAX_ERRORS_TO_SHOW_) { |
+ for (var i = this.MAX_ERRORS_TO_SHOW_; |
+ i < this.contents_.children.length; ++i) { |
+ this.contents_.children[i].hidden = true; |
+ } |
+ this.initShowMoreButton_(); |
+ } |
+ }, |
+ |
+ /** |
+ * Initialize the "Show More" button for the error list, if there are more |
Dan Beam
2013/08/29 00:24:30
nit: Initialize the "Show More" button for the err
Devlin
2013/08/29 21:02:04
Done.
|
+ * than |MAX_ERRORS_TO_SHOW_| errors in the list. |
+ * @private |
+ */ |
+ initShowMoreButton_: function() { |
+ var button = this.querySelector('.extension-error-list-show-more a'); |
+ button.hidden = false; |
+ button.isShowingAll = false; |
+ button.addEventListener('click', function(e) { |
+ for (var i = this.MAX_ERRORS_TO_SHOW_; |
+ i < this.contents_.children.length; ++i) { |
+ this.contents_.children[i].hidden = button.isShowingAll; |
+ } |
+ var message = button.isShowingAll ? 'extensionErrorsShowMore' : |
+ 'extensionErrorsShowFewer'; |
+ button.innerText = loadTimeData.getString(message); |
+ button.isShowingAll = !button.isShowingAll; |
+ }.bind(this)); |
+ } |
+ }; |
+ |
+ return { |
+ ExtensionErrorList: ExtensionErrorList |
+ }; |
+}); |