OLD | NEW |
---|---|
(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. | |
42 * @param {Object} error The error the element should represent. | |
43 * @constructor | |
44 * @extends {HTMLDivElement} | |
45 */ | |
46 function ExtensionError(error) { | |
47 var div = document.createElement('div'); | |
48 div.__proto__ = ExtensionError.prototype; | |
49 div.className = 'extension-error-simple-wrapper'; | |
50 div.error_ = error; | |
51 div.decorate(); | |
52 return div; | |
53 } | |
54 | |
55 ExtensionError.prototype = { | |
56 __proto__: HTMLDivElement.prototype, | |
57 | |
58 /** @override */ | |
59 decorate: function() { | |
60 var metadata = cloneTemplate('.extension-error-metadata'); | |
61 | |
62 // Set an icon for the level of severity. | |
63 var iconNode = document.createElement('img'); | |
64 if (this.error_.level == 0) | |
65 iconNode.className = 'extension-error-icon-log'; | |
66 else if (this.error_.level == 1) | |
67 iconNode.className = 'extension-error-icon-warn'; | |
68 else | |
69 iconNode.className = 'extension-error-icon-error'; | |
70 | |
71 metadata.insertBefore(iconNode, metadata.firstChild); | |
72 | |
73 // Add a property for the extension's base url in order to determine if | |
74 // a url belongs to the extension. | |
75 this.extensionUrl_ = | |
76 'chrome-extension://' + this.error_.extensionId + '/'; | |
77 | |
78 metadata.querySelector('.extension-error-message').innerText = | |
79 this.error_.message; | |
80 | |
81 metadata.querySelector('.extension-error-source').innerText = | |
82 '(' + getRelativeUrl(this.error_.source, this.extensionUrl_) + ')'; | |
83 | |
84 this.appendChild(metadata); | |
85 this.addViewLinkToNode_(this, this.error_.source); | |
86 }, | |
87 | |
88 /** | |
89 * Add a "view" link to the given node, if a user can view the source of the | |
90 * specified url. | |
91 * @param {HTMLElement} node The node to which we append the view link. | |
92 * @param {string} url The url to the resource to view. | |
93 * @private | |
94 */ | |
95 addViewLinkToNode_: function(node, url) { | |
96 if (this.canViewSource_(url)) | |
97 node.appendChild(this.getViewSourceLink_(url)); | |
98 }, | |
99 | |
100 /** | |
101 * Determine whether we can view the source of a given url. | |
102 * @param {string} url The url to the resource to view. | |
103 * @return {boolean} Whether or not we can view the source for the url. | |
104 * @private | |
105 */ | |
106 canViewSource_: function(url) { | |
107 return isExtensionUrl(url, this.extensionUrl_) || | |
108 url == 'manifest.json'; | |
Dan Beam
2013/08/21 23:41:03
nit: think this fits in one line
Devlin
2013/08/22 18:29:06
Done.
| |
109 }, | |
110 | |
111 /** | |
112 * Create a clickable node to view the source for the given url. | |
113 * @param {string} url The url to the resource to view. | |
114 * @return {HTMLElement} The clickable node to view the source. | |
115 * @private | |
116 */ | |
117 getViewSourceLink_: function(url) { | |
118 var node = document.createElement('a'); | |
119 node.innerText = loadTimeData.getString('extensionErrorViewSource'); | |
120 | |
121 var relativeLink = getRelativeUrl(url, this.extensionUrl_); | |
122 node.addEventListener('click', function(e) { | |
123 chrome.send('extensionErrorRequestFileSource', | |
124 [{'extensionId': this.error_.extensionId, | |
125 'errorMessage': this.error_.message, | |
126 'fileType': 'manifest', | |
127 'pathSuffix': relativeLink, | |
128 'feature': this.error_.manifestKey, | |
129 'specific': this.error_.manifestSpecific}]); | |
130 }.bind(this)); | |
131 return node; | |
132 }, | |
133 }; | |
134 | |
135 /** | |
136 * An ExtensionErrorList represents the list of either runtime or manifest | |
137 * errors for a given extension. Each item in the list is an ExtensionError | |
138 * object, with information about the error. The list will display up to | |
139 * |MAX_ERRORS_TO_SHOW_| errors, with the option to expand (and then shrink) | |
140 * the displayed portion. This is included as part of the Extension node in | |
141 * the ExtensionList in chrome://extensions, if errors are present. | |
142 * @constructor | |
143 * @extends {HTMLDivElement} | |
144 */ | |
145 function ExtensionErrorList(errors) { | |
146 var div = cloneTemplate('.extension-error-list'); | |
147 div.__proto__ = ExtensionErrorList.prototype; | |
148 div.errors_ = errors; | |
149 div.decorate(); | |
150 return div; | |
151 } | |
152 | |
153 ExtensionErrorList.prototype = { | |
154 __proto__: HTMLDivElement.prototype, | |
155 | |
156 /** | |
157 * @private | |
158 * @const | |
Dan Beam
2013/08/21 23:41:03
nit: forgot @type {number}
Devlin
2013/08/22 18:29:06
Done.
| |
159 */ | |
160 MAX_ERRORS_TO_SHOW_: 3, | |
161 | |
162 /** @override */ | |
163 decorate: function() { | |
164 this.contents_ = this.querySelector('.extension-error-list-contents'); | |
165 this.errors_.forEach(function(error) { | |
166 this.contents_.appendChild(document.createElement('li')).appendChild( | |
167 new ExtensionError(error)); | |
168 }, this); | |
169 | |
170 if (this.contents_.children.length > this.MAX_ERRORS_TO_SHOW_) { | |
171 for (var i = this.MAX_ERRORS_TO_SHOW_; | |
172 i < this.contents_.children.length; ++i) { | |
173 this.contents_.children[i].hidden = true; | |
174 } | |
175 this.initShowMoreButton_(); | |
176 } | |
177 }, | |
178 | |
179 /** | |
180 * Initialize the "Show More" button for the error list, if there are more | |
181 * than |MAX_ERRORS_TO_SHOW_| errors in the list. | |
182 * @private | |
183 */ | |
184 initShowMoreButton_: function() { | |
185 var button = this.querySelector('.extension-error-list-show-more a'); | |
186 button.hidden = false; | |
187 button.isShowingAll = false; | |
188 button.addEventListener('click', function(e) { | |
189 for (var i = this.MAX_ERRORS_TO_SHOW_; | |
190 i < this.contents_.children.length; ++i) { | |
191 this.contents_.children[i].hidden = button.isShowingAll; | |
192 } | |
193 var message = button.isShowingAll ? 'extensionErrorsShowMore' : | |
194 'extensionErrorsShowFewer'; | |
195 button.innerText = loadTimeData.getString(message); | |
196 button.isShowingAll = !button.isShowingAll; | |
197 }.bind(this)); | |
198 } | |
199 }; | |
200 | |
201 return { | |
202 ExtensionErrorList: ExtensionErrorList | |
203 }; | |
204 }); | |
OLD | NEW |