OLD | NEW |
---|---|
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 * Get the url relative to the main extension url. If the url is | |
10 * unassociated with the extension, this will be the full url. | |
11 * @param {string} url The url to make relative. | |
12 * @param {string} extensionUrl The url for the extension resources, in the | |
13 * form "chrome-etxension://<extension_id>/". | |
14 * @return {string} The url relative to the host. | |
15 */ | |
16 function getRelativeUrl(url, extensionUrl) { | |
17 return url.substring(0, extensionUrl.length) == extensionUrl ? | |
18 url.substring(extensionUrl.length) : url; | |
19 } | |
20 | |
21 /** | |
9 * The RuntimeErrorContent manages all content specifically associated with | 22 * The RuntimeErrorContent manages all content specifically associated with |
10 * runtime errors; this includes stack frames and the context url. | 23 * runtime errors; this includes stack frames and the context url. |
11 * @constructor | 24 * @constructor |
12 * @extends {HTMLDivElement} | 25 * @extends {HTMLDivElement} |
13 */ | 26 */ |
14 function RuntimeErrorContent() { | 27 function RuntimeErrorContent() { |
15 var contentArea = $('template-collection-extension-error-overlay'). | 28 var contentArea = $('template-collection-extension-error-overlay'). |
16 querySelector('.extension-error-overlay-runtime-content'). | 29 querySelector('.extension-error-overlay-runtime-content'). |
17 cloneNode(true); | 30 cloneNode(true); |
18 contentArea.__proto__ = RuntimeErrorContent.prototype; | 31 contentArea.__proto__ = RuntimeErrorContent.prototype; |
(...skipping 14 matching lines...) Expand all Loading... | |
33 * want to include any of our own code in stack traces. | 46 * want to include any of our own code in stack traces. |
34 * @param {string} url The url in question. | 47 * @param {string} url The url in question. |
35 * @return {boolean} True if the url should be displayed, and false | 48 * @return {boolean} True if the url should be displayed, and false |
36 * otherwise (i.e., if it is an internal script). | 49 * otherwise (i.e., if it is an internal script). |
37 */ | 50 */ |
38 RuntimeErrorContent.shouldDisplayForUrl = function(url) { | 51 RuntimeErrorContent.shouldDisplayForUrl = function(url) { |
39 // All our internal scripts are in the 'extensions::' namespace. | 52 // All our internal scripts are in the 'extensions::' namespace. |
40 return !/^extensions::/.test(url); | 53 return !/^extensions::/.test(url); |
41 }; | 54 }; |
42 | 55 |
56 /** | |
57 * Send a call to chrome to open the developer tools for an error. | |
58 * This will call either the bound function in ExtensionErrorHandler or the | |
59 * API function from developerPrivate, depending on whether this is being | |
60 * used in the native chrome:extensions page or the Apps Developer Tool. | |
61 * @see chrome/browser/ui/webui/extensions/extension_error_ui_util.h | |
62 * @param {Object} args The arguments to pass to openDevTools. | |
63 * @private | |
64 */ | |
65 RuntimeErrorContent.openDevtools_ = function(args) { | |
66 if (chrome.send) { | |
67 chrome.send('extensionErrorOpenDevTools', [args]); | |
68 } else if (chrome.developerPrivate) { | |
69 chrome.developerPrivate.openDevTools(args); | |
70 } else { | |
71 console.error('Cannot call either openDevTools function.'); | |
Dan Beam
2014/02/11 02:43:49
when do you expect this to ever happen?
Devlin
2014/02/11 18:41:16
Ideally, _never_. Would it be best to remove it,
| |
72 } | |
Dan Beam
2014/02/11 02:43:49
no curlies
Devlin
2014/02/11 18:41:16
Done.
| |
73 }; | |
74 | |
43 RuntimeErrorContent.prototype = { | 75 RuntimeErrorContent.prototype = { |
44 __proto__: HTMLDivElement.prototype, | 76 __proto__: HTMLDivElement.prototype, |
45 | 77 |
46 /** | 78 /** |
47 * The underlying error whose details are being displayed. | 79 * The underlying error whose details are being displayed. |
48 * @type {Object} | 80 * @type {Object} |
49 * @private | 81 * @private |
50 */ | 82 */ |
51 error_: undefined, | 83 error_: undefined, |
52 | 84 |
53 /** | 85 /** |
54 * The URL associated with this extension, i.e. chrome-extension://<id>. | 86 * The URL associated with this extension, i.e. chrome-extension://<id>/. |
55 * @type {string} | 87 * @type {string} |
56 * @private | 88 * @private |
57 */ | 89 */ |
58 extensionUrl_: undefined, | 90 extensionUrl_: undefined, |
59 | 91 |
60 /** | 92 /** |
61 * The node of the stack trace which is currently active. | 93 * The node of the stack trace which is currently active. |
62 * @type {HTMLElement} | 94 * @type {HTMLElement} |
63 * @private | 95 * @private |
64 */ | 96 */ |
(...skipping 18 matching lines...) Expand all Loading... | |
83 * @private | 115 * @private |
84 */ | 116 */ |
85 this.contextUrl_ = | 117 this.contextUrl_ = |
86 this.querySelector('.extension-error-overlay-context-url'); | 118 this.querySelector('.extension-error-overlay-context-url'); |
87 assert(this.contextUrl_); | 119 assert(this.contextUrl_); |
88 }, | 120 }, |
89 | 121 |
90 /** | 122 /** |
91 * Sets the error for the content. | 123 * Sets the error for the content. |
92 * @param {Object} error The error whose content should be displayed. | 124 * @param {Object} error The error whose content should be displayed. |
125 * @param {string} extensionUrl The URL associated with this extension. | |
93 */ | 126 */ |
94 setError: function(error) { | 127 setError: function(error, extensionUrl) { |
95 this.error_ = error; | 128 this.error_ = error; |
96 this.extensionUrl_ = 'chrome-extension://' + error.extensionId + '/'; | 129 this.extensionUrl_ = extensionUrl; |
97 this.contextUrl_.textContent = error.contextUrl ? | 130 this.contextUrl_.textContent = error.contextUrl ? |
98 this.getRelativeUrl_(error.contextUrl) : | 131 getRelativeUrl(error.contextUrl, this.extensionUrl_) : |
99 loadTimeData.getString('extensionErrorOverlayContextUnknown'); | 132 loadTimeData.getString('extensionErrorOverlayContextUnknown'); |
100 this.initStackTrace_(); | 133 this.initStackTrace_(); |
101 }, | 134 }, |
102 | 135 |
103 /** | 136 /** |
104 * Wipe content associated with a specific error. | 137 * Wipe content associated with a specific error. |
105 */ | 138 */ |
106 clearError: function() { | 139 clearError: function() { |
107 this.error_ = undefined; | 140 this.error_ = undefined; |
108 this.extensionUrl_ = undefined; | 141 this.extensionUrl_ = undefined; |
109 this.currentFrameNode_ = undefined; | 142 this.currentFrameNode_ = undefined; |
110 this.stackTrace_.innerHTML = ''; | 143 this.stackTrace_.innerHTML = ''; |
111 this.stackTrace_.hidden = true; | 144 this.stackTrace_.hidden = true; |
112 }, | 145 }, |
113 | 146 |
114 /** | 147 /** |
115 * Returns whether or not a given |url| is associated with the current | |
116 * extension. | |
117 * @param {string} url The url to examine. | |
118 * @return {boolean} Whether or not the url is associated with the extension | |
119 * @private | |
120 */ | |
121 isRelatedUrl_: function(url) { | |
122 return url.substring(0, this.extensionUrl_.length) == this.extensionUrl_; | |
123 }, | |
124 | |
125 /** | |
126 * Get the url relative to the main extension url. If the url is | |
127 * unassociated with the extension, this will be the full url. | |
128 * @param {string} url The url to make relative. | |
129 * @return {string} The url relative to the host. | |
130 * @private | |
131 */ | |
132 getRelativeUrl_: function(url) { | |
133 return this.isRelatedUrl_(url, this.extensionUrl_) ? | |
134 url.substring(this.extensionUrl_.length) : url; | |
135 }, | |
136 | |
137 /** | |
138 * Makes |frame| active and deactivates the previously active frame (if | 148 * Makes |frame| active and deactivates the previously active frame (if |
139 * there was one). | 149 * there was one). |
140 * @param {HTMLElement} frame The frame to activate. | 150 * @param {HTMLElement} frame The frame to activate. |
141 * @private | 151 * @private |
142 */ | 152 */ |
143 setActiveFrame_: function(frameNode) { | 153 setActiveFrame_: function(frameNode) { |
144 if (this.currentFrameNode_) { | 154 if (this.currentFrameNode_) { |
145 this.currentFrameNode_.classList.remove( | 155 this.currentFrameNode_.classList.remove( |
146 RuntimeErrorContent.ACTIVE_CLASS_NAME); | 156 RuntimeErrorContent.ACTIVE_CLASS_NAME); |
147 } | 157 } |
(...skipping 16 matching lines...) Expand all Loading... | |
164 continue; | 174 continue; |
165 | 175 |
166 var frameNode = document.createElement('li'); | 176 var frameNode = document.createElement('li'); |
167 // Attach the index of the frame to which this node refers (since we | 177 // Attach the index of the frame to which this node refers (since we |
168 // may skip some, this isn't a 1-to-1 match). | 178 // may skip some, this isn't a 1-to-1 match). |
169 frameNode.indexIntoTrace = i; | 179 frameNode.indexIntoTrace = i; |
170 | 180 |
171 // The description is a human-readable summation of the frame, in the | 181 // The description is a human-readable summation of the frame, in the |
172 // form "<relative_url>:<line_number> (function)", e.g. | 182 // form "<relative_url>:<line_number> (function)", e.g. |
173 // "myfile.js:25 (myFunction)". | 183 // "myfile.js:25 (myFunction)". |
174 var description = | 184 var description = getRelativeUrl(frame.url, this.extensionUrl_) + |
175 this.getRelativeUrl_(frame.url) + ':' + frame.lineNumber; | 185 ':' + frame.lineNumber; |
Dan Beam
2014/02/11 02:43:49
nit: arguably, revert the style difference
Devlin
2014/02/11 18:41:16
Doesn't fit on one line anymore (needs the new par
| |
176 if (frame.functionName) { | 186 if (frame.functionName) { |
177 var functionName = frame.functionName == '(anonymous function)' ? | 187 var functionName = frame.functionName == '(anonymous function)' ? |
178 loadTimeData.getString('extensionErrorOverlayAnonymousFunction') : | 188 loadTimeData.getString('extensionErrorOverlayAnonymousFunction') : |
179 frame.functionName; | 189 frame.functionName; |
180 description += ' (' + functionName + ')'; | 190 description += ' (' + functionName + ')'; |
181 } | 191 } |
182 frameNode.textContent = description; | 192 frameNode.textContent = description; |
183 | 193 |
184 // When the user clicks on a frame in the stack trace, we should | 194 // When the user clicks on a frame in the stack trace, we should |
185 // highlight that overlay in the list, display the appropriate source | 195 // highlight that overlay in the list, display the appropriate source |
186 // code with the line highlighted, and link the "Open DevTools" button | 196 // code with the line highlighted, and link the "Open DevTools" button |
187 // with that frame. | 197 // with that frame. |
188 frameNode.addEventListener('click', function(frame, frameNode, e) { | 198 frameNode.addEventListener('click', function(frame, frameNode, e) { |
189 if (this.currStackFrame_ == frameNode) | 199 if (this.currStackFrame_ == frameNode) |
190 return; | 200 return; |
191 | 201 |
192 this.setActiveFrame_(frameNode); | 202 this.setActiveFrame_(frameNode); |
193 | 203 |
194 // Request the file source with the section highlighted; this will | 204 // Request the file source with the section highlighted; this will |
195 // call ExtensionErrorOverlay.requestFileSourceResponse() when | 205 // call ExtensionErrorOverlay.requestFileSourceResponse() when |
196 // completed, which in turn calls setCode(). | 206 // completed, which in turn calls setCode(). |
197 chrome.send('extensionErrorRequestFileSource', | 207 ExtensionErrorOverlay.requestFileSource( |
198 [{extensionId: this.error_.extensionId, | 208 {extensionId: this.error_.extensionId, |
199 message: this.error_.message, | 209 message: this.error_.message, |
200 pathSuffix: this.getRelativeUrl_(frame.url), | 210 pathSuffix: getRelativeUrl(frame.url, this.extensionUrl_), |
201 lineNumber: frame.lineNumber}]); | 211 lineNumber: frame.lineNumber}); |
202 }.bind(this, frame, frameNode)); | 212 }.bind(this, frame, frameNode)); |
203 | 213 |
204 this.stackTrace_.appendChild(frameNode); | 214 this.stackTrace_.appendChild(frameNode); |
205 } | 215 } |
206 | 216 |
207 // Set the current stack frame to the first stack frame and show the | 217 // Set the current stack frame to the first stack frame and show the |
208 // trace, if one exists. (We can't just check error.stackTrace, because | 218 // trace, if one exists. (We can't just check error.stackTrace, because |
209 // it's possible the trace was purely internal, and we don't show | 219 // it's possible the trace was purely internal, and we don't show |
210 // internal frames.) | 220 // internal frames.) |
211 if (this.stackTrace_.children.length > 0) { | 221 if (this.stackTrace_.children.length > 0) { |
212 this.stackTrace_.hidden = false; | 222 this.stackTrace_.hidden = false; |
213 this.setActiveFrame_(this.stackTrace_.firstChild); | 223 this.setActiveFrame_(this.stackTrace_.firstChild); |
214 } | 224 } |
215 }, | 225 }, |
216 | 226 |
217 /** | 227 /** |
218 * Open the developer tools for the active stack frame. | 228 * Open the developer tools for the active stack frame. |
219 */ | 229 */ |
220 openDevtools: function() { | 230 openDevtools: function() { |
221 var stackFrame = | 231 var stackFrame = |
222 this.error_.stackTrace[this.currentFrameNode_.indexIntoTrace]; | 232 this.error_.stackTrace[this.currentFrameNode_.indexIntoTrace]; |
223 | 233 |
224 chrome.send('extensionErrorOpenDevTools', | 234 RuntimeErrorContent.openDevtools_( |
225 [{renderProcessId: this.error_.renderProcessId, | 235 {renderProcessId: this.error_.renderProcessId, |
226 renderViewId: this.error_.renderViewId, | 236 renderViewId: this.error_.renderViewId, |
227 url: stackFrame.url, | 237 url: stackFrame.url, |
228 lineNumber: stackFrame.lineNumber || 0, | 238 lineNumber: stackFrame.lineNumber || 0, |
229 columnNumber: stackFrame.columnNumber || 0}]); | 239 columnNumber: stackFrame.columnNumber || 0}); |
230 } | 240 } |
231 }; | 241 }; |
232 | 242 |
233 /** | 243 /** |
234 * The ExtensionErrorOverlay will show the contents of a file which pertains | 244 * The ExtensionErrorOverlay will show the contents of a file which pertains |
235 * to the ExtensionError; this is either the manifest file (for manifest | 245 * to the ExtensionError; this is either the manifest file (for manifest |
236 * errors) or a source file (for runtime errors). If possible, the portion | 246 * errors) or a source file (for runtime errors). If possible, the portion |
237 * of the file which caused the error will be highlighted. | 247 * of the file which caused the error will be highlighted. |
238 * @constructor | 248 * @constructor |
239 */ | 249 */ |
240 function ExtensionErrorOverlay() { | 250 function ExtensionErrorOverlay() { |
241 /** | 251 /** |
242 * The content section for runtime errors; this is re-used for all | 252 * The content section for runtime errors; this is re-used for all |
243 * runtime errors and attached/detached from the overlay as needed. | 253 * runtime errors and attached/detached from the overlay as needed. |
244 * @type {RuntimeErrorContent} | 254 * @type {RuntimeErrorContent} |
245 * @private | 255 * @private |
246 */ | 256 */ |
247 this.runtimeErrorContent_ = new RuntimeErrorContent(); | 257 this.runtimeErrorContent_ = new RuntimeErrorContent(); |
248 } | 258 } |
249 | 259 |
250 /** | 260 /** |
251 * Value of ExtensionError::RUNTIME_ERROR enum. | 261 * Value of ExtensionError::RUNTIME_ERROR enum. |
252 * @see extensions/browser/extension_error.h | 262 * @see extensions/browser/extension_error.h |
253 * @type {number} | 263 * @type {number} |
254 * @const | 264 * @const |
255 * @private | 265 * @private |
256 */ | 266 */ |
257 ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_ = 1; | 267 ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_ = 1; |
258 | 268 |
269 /** | |
270 * The manifest filename. | |
271 * @type {string} | |
272 * @const | |
273 * @private | |
274 */ | |
275 ExtensionErrorOverlay.MANIFEST_FILENAME_ = 'manifest.json'; | |
276 | |
277 /** | |
278 * Determine whether or not chrome can load the source for a given file; this | |
279 * can only be done if the file belongs to the extension. | |
280 * @param {string} file The file to load. | |
281 * @param {string} extensionUrl The url for the extension, in the form | |
282 * chrome-extension://<extension-id>/. | |
283 * @return {boolean} True if the file can be loaded, false otherwise. | |
284 * @private | |
285 */ | |
286 ExtensionErrorOverlay.canLoadFileSource = function(file, extensionUrl) { | |
287 return RegExp('^' + extensionUrl).test(file) || | |
Dan Beam
2014/02/11 02:43:49
nit: arguably just re-use the .substr(0, extension
Devlin
2014/02/11 18:41:16
Done.
| |
288 file.toLowerCase() == ExtensionErrorOverlay.MANIFEST_FILENAME_; | |
289 }; | |
290 | |
291 /** | |
292 * Determine whether or not we can show an overlay with more details for | |
293 * the given extension error. | |
294 * @param {Object} error The extension error. | |
295 * @param {string} extensionUrl The url for the extension, in the form | |
296 * "chrome-extension://<extension-id>/". | |
297 * @return {boolean} True if we can show an overlay for the error, | |
298 * false otherwise. | |
299 */ | |
300 ExtensionErrorOverlay.canShowOverlayForError = function(error, extensionUrl) { | |
301 if (ExtensionErrorOverlay.canLoadFileSource(error.source, extensionUrl)) | |
302 return true; | |
303 | |
304 if (error.stackTrace) { | |
305 for (var i = 0; i < error.stackTrace.length; ++i) { | |
306 if (RuntimeErrorContent.shouldDisplayForUrl(error.stackTrace[i].url)) | |
307 return true; | |
308 } | |
309 } | |
310 | |
311 return false; | |
312 }; | |
313 | |
314 /** | |
315 * Send a call to chrome to request the source of a given file. | |
316 * This will call either the bound function in ExtensionErrorHandler or the | |
317 * API function from developerPrivate, depending on whether this is being | |
318 * used in the native chrome:extensions page or the Apps Developer Tool. | |
319 * @see chrome/browser/ui/webui/extensions/extension_error_ui_util.h | |
320 * @param {Object} args The arguments to pass to requestFileSource. | |
321 */ | |
322 ExtensionErrorOverlay.requestFileSource = function(args) { | |
323 if (chrome.send) { | |
324 chrome.send('extensionErrorRequestFileSource', [args]); | |
325 } else if (chrome.developerPrivate) { | |
326 chrome.developerPrivate.requestFileSource(args, function(result) { | |
327 extensions.ExtensionErrorOverlay.requestFileSourceResponse(result); | |
Dan Beam
2014/02/11 02:43:49
-2\s
Devlin
2014/02/11 18:41:16
Done.
| |
328 }); | |
329 } else { | |
330 console.error('Cannot call either requestFileSource function.'); | |
Dan Beam
2014/02/11 02:43:49
why will this happen?
Devlin
2014/02/11 18:41:16
Again, ideally never (see above).
| |
331 } | |
332 }; | |
333 | |
259 cr.addSingletonGetter(ExtensionErrorOverlay); | 334 cr.addSingletonGetter(ExtensionErrorOverlay); |
260 | 335 |
261 ExtensionErrorOverlay.prototype = { | 336 ExtensionErrorOverlay.prototype = { |
262 /** | 337 /** |
263 * The underlying error whose details are being displayed. | 338 * The underlying error whose details are being displayed. |
264 * @type {Object} | 339 * @type {Object} |
265 * @private | 340 * @private |
266 */ | 341 */ |
267 error_: undefined, | 342 error_: undefined, |
268 | 343 |
269 /** | 344 /** |
270 * Initialize the page. | 345 * Initialize the page. |
346 * @param {function} showOverlay The function to show or hide the | |
Dan Beam
2014/02/11 02:43:49
@param {function(HTMLDivElement)} showOverlay
Devlin
2014/02/11 18:41:16
Done.
| |
347 * ExtensionErrorOverlay; this should take a single parameter which is | |
348 * either the overlay Div if the overlay should be displayed, or null | |
349 * if the overlay should be hidden. | |
271 */ | 350 */ |
272 initializePage: function() { | 351 initializePage: function(showOverlay) { |
273 var overlay = $('overlay'); | 352 var overlay = $('overlay'); |
274 cr.ui.overlay.setupOverlay(overlay); | 353 cr.ui.overlay.setupOverlay(overlay); |
275 cr.ui.overlay.globalInitialization(); | 354 cr.ui.overlay.globalInitialization(); |
276 overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); | 355 overlay.addEventListener('cancelOverlay', this.handleDismiss_.bind(this)); |
277 | 356 |
278 $('extension-error-overlay-dismiss').addEventListener( | 357 $('extension-error-overlay-dismiss').addEventListener( |
279 'click', this.handleDismiss_.bind(this)); | 358 'click', this.handleDismiss_.bind(this)); |
280 | 359 |
281 /** | 360 /** |
282 * The element of the full overlay. | 361 * The element of the full overlay. |
283 * @type {HTMLDivElement} | 362 * @type {HTMLDivElement} |
284 * @private | 363 * @private |
285 */ | 364 */ |
286 this.overlayDiv_ = $('extension-error-overlay'); | 365 this.overlayDiv_ = $('extension-error-overlay'); |
287 | 366 |
288 /** | 367 /** |
368 * The function to show or hide the ExtensionErrorOverlay. | |
369 * @type {function} | |
370 * @param {boolean} isVisible Whether the overlay should be visible. | |
371 */ | |
372 this.setVisible = function(isVisible) { | |
373 showOverlay(isVisible ? this.overlayDiv_ : null); | |
374 }; | |
Dan Beam
2014/02/11 02:43:49
please move this out of the ctor
Devlin
2014/02/11 18:41:16
This uses the showOverlay parameter passed into th
| |
375 | |
376 /** | |
289 * The portion of the overlay which shows the code relating to the error. | 377 * The portion of the overlay which shows the code relating to the error. |
290 * @type {HTMLElement} | 378 * @type {HTMLElement} |
291 * @private | 379 * @private |
292 */ | 380 */ |
293 this.codeDiv_ = $('extension-error-overlay-code'); | 381 this.codeDiv_ = $('extension-error-overlay-code'); |
294 | 382 |
295 /** | 383 /** |
296 * The button to open the developer tools (only available for runtime | 384 * The button to open the developer tools (only available for runtime |
297 * errors). | 385 * errors). |
298 * @type {HTMLButtonElement} | 386 * @type {HTMLButtonElement} |
299 * @private | 387 * @private |
300 */ | 388 */ |
301 this.openDevtoolsButton_ = $('extension-error-overlay-devtools-button'); | 389 this.openDevtoolsButton_ = $('extension-error-overlay-devtools-button'); |
302 this.openDevtoolsButton_.addEventListener('click', function() { | 390 this.openDevtoolsButton_.addEventListener('click', function() { |
303 this.runtimeErrorContent_.openDevtools(); | 391 this.runtimeErrorContent_.openDevtools(); |
304 }.bind(this)); | 392 }.bind(this)); |
305 }, | 393 }, |
306 | 394 |
Dan Beam
2014/02/11 02:43:49
to somewhere like here:
/* ... */
setVisible:
Devlin
2014/02/11 18:41:16
See above.
| |
307 /** | 395 /** |
308 * Handles a click on the dismiss ("OK" or close) buttons. | 396 * Handles a click on the dismiss ("OK" or close) buttons. |
309 * @param {Event} e The click event. | 397 * @param {Event} e The click event. |
310 * @private | 398 * @private |
311 */ | 399 */ |
312 handleDismiss_: function(e) { | 400 handleDismiss_: function(e) { |
313 extensions.ExtensionSettings.showOverlay(null); | 401 this.setVisible(false); |
314 | 402 |
315 // There's a chance that the overlay receives multiple dismiss events; in | 403 // There's a chance that the overlay receives multiple dismiss events; in |
316 // this case, handle it gracefully and return (since all necessary work | 404 // this case, handle it gracefully and return (since all necessary work |
317 // will already have been done). | 405 // will already have been done). |
318 if (!this.error_) | 406 if (!this.error_) |
319 return; | 407 return; |
320 | 408 |
321 this.codeDiv_.innerHTML = ''; | 409 this.codeDiv_.innerHTML = ''; |
322 this.openDevtoolsButton_.hidden = true; | 410 this.openDevtoolsButton_.hidden = true; |
323 | 411 |
324 if (this.error_.type == ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_) { | 412 if (this.error_.type == ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_) { |
325 this.overlayDiv_.querySelector('.content-area').removeChild( | 413 this.overlayDiv_.querySelector('.content-area').removeChild( |
326 this.runtimeErrorContent_); | 414 this.runtimeErrorContent_); |
327 this.runtimeErrorContent_.clearError(); | 415 this.runtimeErrorContent_.clearError(); |
328 } | 416 } |
329 | 417 |
330 this.error_ = undefined; | 418 this.error_ = undefined; |
331 }, | 419 }, |
332 | 420 |
333 /** | 421 /** |
334 * Associate an error with the overlay. This will set the error for the | 422 * Associate an error with the overlay. This will set the error for the |
335 * overlay, and, if possible, will populate the code section of the overlay | 423 * overlay, and, if possible, will populate the code section of the overlay |
336 * with the relevant file, load the stack trace, and generate links for | 424 * with the relevant file, load the stack trace, and generate links for |
337 * opening devtools (the latter two only happen for runtime errors). | 425 * opening devtools (the latter two only happen for runtime errors). |
338 * @param {Object} error The error to show in the overlay. | 426 * @param {Object} error The error to show in the overlay. |
427 * @param {string} extensionUrl The URL of the extension, in the form | |
428 * "chrome-extension://<extension_id>". | |
339 */ | 429 */ |
340 setError: function(error) { | 430 setErrorAndShowOverlay: function(error, extensionUrl) { |
341 this.error_ = error; | 431 this.error_ = error; |
342 | 432 |
343 if (this.error_.type == ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_) { | 433 if (this.error_.type == ExtensionErrorOverlay.RUNTIME_ERROR_TYPE_) { |
344 this.runtimeErrorContent_.setError(this.error_); | 434 this.runtimeErrorContent_.setError(this.error_, extensionUrl); |
345 this.overlayDiv_.querySelector('.content-area').insertBefore( | 435 this.overlayDiv_.querySelector('.content-area').insertBefore( |
346 this.runtimeErrorContent_, | 436 this.runtimeErrorContent_, |
347 this.codeDiv_.nextSibling); | 437 this.codeDiv_.nextSibling); |
348 this.openDevtoolsButton_.hidden = false; | 438 this.openDevtoolsButton_.hidden = false; |
349 this.openDevtoolsButton_.disabled = !error.canInspect; | 439 this.openDevtoolsButton_.disabled = !error.canInspect; |
350 } | 440 } |
441 | |
442 if (ExtensionErrorOverlay.canLoadFileSource(error.source, extensionUrl)) { | |
443 var relativeUrl = getRelativeUrl(error.source, extensionUrl); | |
444 | |
445 var requestFileSourceArgs = {extensionId: error.extensionId, | |
446 message: error.message, | |
447 pathSuffix: relativeUrl}; | |
448 | |
449 if (relativeUrl.toLowerCase() == | |
450 ExtensionErrorOverlay.MANIFEST_FILENAME_) { | |
451 requestFileSourceArgs.manifestKey = error.manifestKey; | |
452 requestFileSourceArgs.manifestSpecific = error.manifestSpecific; | |
453 } else { | |
454 requestFileSourceArgs.lineNumber = | |
455 error.stackTrace && error.stackTrace[0] ? | |
456 error.stackTrace[0].lineNumber : 0; | |
457 } | |
458 ExtensionErrorOverlay.requestFileSource(requestFileSourceArgs); | |
459 } else { | |
460 ExtensionErrorOverlay.requestFileSourceResponse(null); | |
461 } | |
351 }, | 462 }, |
352 | 463 |
353 /** | 464 /** |
354 * Set the code to be displayed in the code portion of the overlay. | 465 * Set the code to be displayed in the code portion of the overlay. |
355 * @see ExtensionErrorOverlay.requestFileSourceResponse(). | 466 * @see ExtensionErrorOverlay.requestFileSourceResponse(). |
356 * @param {?Object} code The code to be displayed. If |code| is null, then | 467 * @param {?Object} code The code to be displayed. If |code| is null, then |
357 * a "Could not display code" message will be displayed instead. | 468 * a "Could not display code" message will be displayed instead. |
358 */ | 469 */ |
359 setCode: function(code) { | 470 setCode: function(code) { |
360 document.querySelector( | 471 document.querySelector( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
396 /** | 507 /** |
397 * Called by the ExtensionErrorHandler responding to the request for a file's | 508 * Called by the ExtensionErrorHandler responding to the request for a file's |
398 * source. Populate the content area of the overlay and display the overlay. | 509 * source. Populate the content area of the overlay and display the overlay. |
399 * @param {Object?} result An object with four strings - the title, | 510 * @param {Object?} result An object with four strings - the title, |
400 * beforeHighlight, afterHighlight, and highlight. The three 'highlight' | 511 * beforeHighlight, afterHighlight, and highlight. The three 'highlight' |
401 * strings represent three portions of the file's content to display - the | 512 * strings represent three portions of the file's content to display - the |
402 * portion which is most relevant and should be emphasized (highlight), | 513 * portion which is most relevant and should be emphasized (highlight), |
403 * and the parts both before and after this portion. These may be empty. | 514 * and the parts both before and after this portion. These may be empty. |
404 */ | 515 */ |
405 ExtensionErrorOverlay.requestFileSourceResponse = function(result) { | 516 ExtensionErrorOverlay.requestFileSourceResponse = function(result) { |
406 extensions.ExtensionErrorOverlay.getInstance().setCode(result); | 517 var overlay = extensions.ExtensionErrorOverlay.getInstance(); |
407 extensions.ExtensionSettings.showOverlay($('extension-error-overlay')); | 518 overlay.setCode(result); |
519 overlay.setVisible(true); | |
408 }; | 520 }; |
409 | 521 |
410 // Export | 522 // Export |
411 return { | 523 return { |
412 ExtensionErrorOverlay: ExtensionErrorOverlay | 524 ExtensionErrorOverlay: ExtensionErrorOverlay |
413 }; | 525 }; |
414 }); | 526 }); |
OLD | NEW |