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

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

Issue 22938005: Add ErrorConsole UI for Extension Install Warnings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dc_ec_install_warnings
Patch Set: License Created 7 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 cr.define('extensions', function() {
6 'use strict';
7
8 /**
9 * Returns whether or not a given |url| is associated with an extension.
10 * @param {string} url The url to examine.
11 * @param {string} extensionUrl The url of the extension.
12 * @return {boolean} Whether or not the url is associated with the extension.
13 */
14 function isExtensionUrl(url, extensionUrl) {
15 return url.substring(0, extensionUrl.length) == extensionUrl;
16 }
17
18 /**
19 * Get the url relative to the main extension url. If the url is
20 * unassociated with the extension, this will be the full url.
21 * @param {string} url The url to make relative.
22 * @param {string} extensionUrl The host for which the url is relative.
23 * @return {string} The url relative to the host.
24 */
25 function getRelativeUrl(url, extensionUrl) {
26 return isExtensionUrl(url, extensionUrl) ?
27 url.substring(extensionUrl.length) : url;
28 }
29
30 /**
31 * Clone a template within the extension error template collection.
32 * @param {string} templateName The class name of the template to clone.
33 * @return {HTMLElement} The clone of the template.
34 */
35 function cloneTemplate(templateName) {
36 return $('template-collection-extension-error').
37 querySelector('.' + templateName).cloneNode(true);
38 }
39
40 /**
41 * Creates a new ExtensionError HTMLElement; this is used to show a
42 * notification to the user when an error is caused by an extension.
43 * @param {Object} error The error the element should represent.
44 * @constructor
45 * @extends {HTMLDivElement}
46 */
47 function ExtensionError(error) {
48 var div = document.createElement('div');
49 div.__proto__ = ExtensionError.prototype;
50 div.className = 'extension-error-simple-wrapper';
51 div.error_ = error;
52 div.decorate();
53 return div;
54 }
55
56 ExtensionError.prototype = {
57 __proto__: HTMLDivElement.prototype,
58
59 /** @override */
60 decorate: function() {
61 var metadata = cloneTemplate('extension-error-metadata');
62
63 // Add an additional class for the severity level.
64 if (this.error_.level == 0)
65 metadata.className += ' extension-error-severity-info';
66 else if (this.error_.level == 1)
67 metadata.className += ' extension-error-severity-warning';
68 else
69 metadata.className += ' extension-error-severity-fatal';
70
71 var iconNode = document.createElement('img');
72 iconNode.className = 'extension-error-icon';
73 metadata.insertBefore(iconNode, metadata.firstChild);
74
75 // Add a property for the extension's base url in order to determine if
76 // a url belongs to the extension.
77 this.extensionUrl_ =
78 'chrome-extension://' + this.error_.extensionId + '/';
79
80 metadata.querySelector('.extension-error-message').innerText =
81 this.error_.message;
82
83 metadata.appendChild(this.getViewSourceOrPlain_(
84 getRelativeUrl(this.error_.source, this.extensionUrl_),
85 this.error_.source));
86
87 this.appendChild(metadata);
88 },
89
90 /**
91 * Return a div with text |description|. If it's possible to view the source
92 * for |url|, linkify the div to do so.
93 * @param {string} description a human-friendly description the location
94 * (e.g., filename, line).
95 * @param {string} url The url of the resource to view.
96 * @return {HTMLElement} The created node, either a link or plaintext.
97 * @private
98 */
99 getViewSourceOrPlain_: function(description, url) {
100 if (this.canViewSource_(url))
101 var node = this.getViewSourceLink_(url);
102 else
103 var node = document.createElement('div');
104 node.className = 'extension-error-view-source';
105 node.innerText = description;
106 return node;
107 },
108
109 /**
110 * Determine whether we can view the source of a given url.
111 * @param {string} url The url of the resource to view.
112 * @return {boolean} Whether or not we can view the source for the url.
113 * @private
114 */
115 canViewSource_: function(url) {
116 return isExtensionUrl(url, this.extensionUrl_) || url == 'manifest.json';
117 },
118
119 /**
120 * Create a clickable node to view the source for the given url.
121 * @param {string} url The url to the resource to view.
122 * @return {HTMLElement} The clickable node to view the source.
123 * @private
124 */
125 getViewSourceLink_: function(url) {
126 var node = document.createElement('a');
127 var relativeUrl = getRelativeUrl(url, this.extensionUrl_);
128
129 node.addEventListener('click', function(e) {
130 chrome.send('extensionErrorRequestFileSource',
131 [{'extensionId': this.error_.extensionId,
132 'message': this.error_.message,
133 'fileType': 'manifest',
134 'pathSuffix': relativeUrl,
135 'manifestKey': this.error_.manifestKey,
136 'manifestSpecific': this.error_.manifestSpecific}]);
137 }.bind(this));
138 return node;
139 },
140 };
141
142 /**
143 * A variable length list of runtime or manifest errors for a given extension.
144 * @constructor
145 * @extends {HTMLDivElement}
146 */
147 function ExtensionErrorList(errors) {
148 var div = cloneTemplate('extension-error-list');
149 div.__proto__ = ExtensionErrorList.prototype;
150 div.errors_ = errors;
151 div.decorate();
152 return div;
153 }
154
155 ExtensionErrorList.prototype = {
156 __proto__: HTMLDivElement.prototype,
157
158 /**
159 * @private
160 * @const
161 * @type {number}
162 */
163 MAX_ERRORS_TO_SHOW_: 3,
164
165 /** @override */
166 decorate: function() {
167 this.contents_ = this.querySelector('.extension-error-list-contents');
168 this.errors_.forEach(function(error) {
169 this.contents_.appendChild(document.createElement('li')).appendChild(
170 new ExtensionError(error));
171 }, this);
172
173 if (this.contents_.children.length > this.MAX_ERRORS_TO_SHOW_) {
174 for (var i = this.MAX_ERRORS_TO_SHOW_;
175 i < this.contents_.children.length; ++i) {
176 this.contents_.children[i].hidden = true;
177 }
178 this.initShowMoreButton_();
179 }
180 },
181
182 /**
183 * Initialize the "Show More" button for the error list. If there are more
184 * than |MAX_ERRORS_TO_SHOW_| errors in the list.
185 * @private
186 */
187 initShowMoreButton_: function() {
188 var button = this.querySelector('.extension-error-list-show-more a');
189 button.hidden = false;
190 button.isShowingAll = false;
191 button.addEventListener('click', function(e) {
192 for (var i = this.MAX_ERRORS_TO_SHOW_;
193 i < this.contents_.children.length; ++i) {
194 this.contents_.children[i].hidden = button.isShowingAll;
195 }
196 var message = button.isShowingAll ? 'extensionErrorsShowMore' :
197 'extensionErrorsShowFewer';
198 button.innerText = loadTimeData.getString(message);
199 button.isShowingAll = !button.isShowingAll;
200 }.bind(this));
201 }
202 };
203
204 return {
205 ExtensionErrorList: ExtensionErrorList
206 };
207 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698