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 <include src="extension_error_overlay.js"></include> | 5 <include src="extension_error_overlay.js"></include> |
6 | 6 |
7 cr.define('extensions', function() { | 7 cr.define('extensions', function() { |
8 'use strict'; | 8 'use strict'; |
9 | 9 |
10 /** | 10 /** |
(...skipping 23 matching lines...) Expand all Loading... |
34 * @constructor | 34 * @constructor |
35 * @extends {HTMLDivElement} | 35 * @extends {HTMLDivElement} |
36 */ | 36 */ |
37 function ExtensionError(error) { | 37 function ExtensionError(error) { |
38 var div = cloneTemplate('extension-error-metadata'); | 38 var div = cloneTemplate('extension-error-metadata'); |
39 div.__proto__ = ExtensionError.prototype; | 39 div.__proto__ = ExtensionError.prototype; |
40 div.decorate(error); | 40 div.decorate(error); |
41 return div; | 41 return div; |
42 } | 42 } |
43 | 43 |
44 /** | |
45 * The manifest filename. | |
46 * @type {string} | |
47 * @const | |
48 * @private | |
49 */ | |
50 ExtensionError.MANIFEST_FILENAME_ = 'manifest.json'; | |
51 | |
52 /** | |
53 * Determine whether or not chrome can load the source for a given file; this | |
54 * can only be done if the file belongs to the extension. | |
55 * @param {string} file The file to load. | |
56 * @param {string} extensionUrl The url for the extension, in the form | |
57 * chrome-extension://<extension-id>/. | |
58 * @return {boolean} True if the file can be loaded, false otherwise. | |
59 * @private | |
60 */ | |
61 ExtensionError.canLoadFileSource_ = function(file, extensionUrl) { | |
62 return RegExp('^' + extensionUrl).test(file) || | |
63 file.toLowerCase() == ExtensionError.MANIFEST_FILENAME_; | |
64 }; | |
65 | |
66 /** | |
67 * Determine whether or not there are any user-friendly (non-internal) frames | |
68 * in the error's stack trace. | |
69 * @param {Object} error The error to examine. | |
70 * @return {boolean} True if there are user-friendly stack frames for the | |
71 * error, false otherwise. | |
72 * @private | |
73 */ | |
74 ExtensionError.hasExternalStackFrames_ = function(error) { | |
75 // All our internal source begins with the "extensions::" prefix. | |
76 var extensionPrefix = /^extensions::/; | |
77 for (var i = 0; i < error.stackTrace.length; ++i) { | |
78 if (!extensionPrefix.test(error.stackTrace[i].url)) | |
79 return true; | |
80 } | |
81 return false; | |
82 }; | |
83 | |
84 ExtensionError.prototype = { | 44 ExtensionError.prototype = { |
85 __proto__: HTMLDivElement.prototype, | 45 __proto__: HTMLDivElement.prototype, |
86 | 46 |
87 /** @override */ | 47 /** @override */ |
88 decorate: function(error) { | 48 decorate: function(error) { |
89 // Add an additional class for the severity level. | 49 // Add an additional class for the severity level. |
90 if (error.level == 0) | 50 if (error.level == 0) |
91 this.classList.add('extension-error-severity-info'); | 51 this.classList.add('extension-error-severity-info'); |
92 else if (error.level == 1) | 52 else if (error.level == 1) |
93 this.classList.add('extension-error-severity-warning'); | 53 this.classList.add('extension-error-severity-warning'); |
94 else | 54 else |
95 this.classList.add('extension-error-severity-fatal'); | 55 this.classList.add('extension-error-severity-fatal'); |
96 | 56 |
97 var iconNode = document.createElement('img'); | 57 var iconNode = document.createElement('img'); |
98 iconNode.className = 'extension-error-icon'; | 58 iconNode.className = 'extension-error-icon'; |
99 this.insertBefore(iconNode, this.firstChild); | 59 this.insertBefore(iconNode, this.firstChild); |
100 | 60 |
101 var messageSpan = this.querySelector('.extension-error-message'); | 61 var messageSpan = this.querySelector('.extension-error-message'); |
102 messageSpan.textContent = error.message; | 62 messageSpan.textContent = error.message; |
103 messageSpan.title = error.message; | 63 messageSpan.title = error.message; |
104 | 64 |
105 var extensionUrl = 'chrome-extension://' + error.extensionId + '/'; | 65 var extensionUrl = 'chrome-extension://' + error.extensionId + '/'; |
106 var viewDetailsLink = this.querySelector('.extension-error-view-details'); | 66 var viewDetailsLink = this.querySelector('.extension-error-view-details'); |
107 | 67 |
108 // If we cannot open the file source and there are no external frames in | 68 // If we cannot open the file source and there are no external frames in |
109 // the stack, then there are no details to display. | 69 // the stack, then there are no details to display. |
110 if (!ExtensionError.canLoadFileSource_(error.source, extensionUrl) && | 70 if (!extensions.ExtensionErrorOverlay.canShowOverlayForError( |
111 !ExtensionError.hasExternalStackFrames_(error)) { | 71 error, extensionUrl)) { |
112 viewDetailsLink.hidden = true; | 72 viewDetailsLink.hidden = true; |
113 return; | 73 } else { |
| 74 var stringId = extensionUrl.toLowerCase() == 'manifest.json' ? |
| 75 'extensionErrorViewManifest' : 'extensionErrorViewDetails'; |
| 76 viewDetailsLink.textContent = loadTimeData.getString(stringId); |
| 77 |
| 78 viewDetailsLink.addEventListener('click', function(e) { |
| 79 extensions.ExtensionErrorOverlay.getInstance().setErrorAndShowOverlay( |
| 80 error, extensionUrl); |
| 81 }); |
114 } | 82 } |
115 | |
116 // The relative url is the url without the preceeding | |
117 // "chrome-extension://<id>"; this is the format which the | |
118 // requestFileSource call expects. | |
119 var relativeUrl = | |
120 error.source.substring(0, extensionUrl.length) == extensionUrl ? | |
121 error.source.substring(extensionUrl.length) : error.source; | |
122 | |
123 var requestFileSourceArgs = {extensionId: error.extensionId, | |
124 message: error.message, | |
125 pathSuffix: relativeUrl}; | |
126 | |
127 var viewDetailsStringId; | |
128 if (relativeUrl.toLowerCase() == 'manifest.json') { | |
129 requestFileSourceArgs.manifestKey = error.manifestKey; | |
130 requestFileSourceArgs.manifestSpecific = error.manifestSpecific; | |
131 viewDetailsStringId = 'extensionErrorViewManifest'; | |
132 } else { | |
133 requestFileSourceArgs.lineNumber = | |
134 error.stackTrace && error.stackTrace[0] ? | |
135 error.stackTrace[0].lineNumber : 0; | |
136 viewDetailsStringId = 'extensionErrorViewDetails'; | |
137 } | |
138 viewDetailsLink.textContent = loadTimeData.getString(viewDetailsStringId); | |
139 | |
140 viewDetailsLink.addEventListener('click', function(e) { | |
141 var overlay = extensions.ExtensionErrorOverlay.getInstance(); | |
142 overlay.setError(error); | |
143 | |
144 // If we can, request the file source to show to the user in the | |
145 // overlay. Otherwise, simply show the overlay. | |
146 if (ExtensionError.canLoadFileSource_(error.source, extensionUrl)) { | |
147 chrome.send('extensionErrorRequestFileSource', | |
148 [requestFileSourceArgs]); | |
149 } else { | |
150 overlay.requestFileSourceResponse(null); | |
151 } | |
152 }.bind(this)); | |
153 }, | 83 }, |
154 }; | 84 }; |
155 | 85 |
156 /** | 86 /** |
157 * A variable length list of runtime or manifest errors for a given extension. | 87 * A variable length list of runtime or manifest errors for a given extension. |
158 * @param {Array.<Object>} errors The list of extension errors with which | 88 * @param {Array.<Object>} errors The list of extension errors with which |
159 * to populate the list. | 89 * to populate the list. |
160 * @constructor | 90 * @constructor |
161 * @extends {HTMLDivElement} | 91 * @extends {HTMLDivElement} |
162 */ | 92 */ |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 button.textContent = loadTimeData.getString(message); | 146 button.textContent = loadTimeData.getString(message); |
217 button.isShowingAll = !button.isShowingAll; | 147 button.isShowingAll = !button.isShowingAll; |
218 }.bind(this)); | 148 }.bind(this)); |
219 } | 149 } |
220 }; | 150 }; |
221 | 151 |
222 return { | 152 return { |
223 ExtensionErrorList: ExtensionErrorList | 153 ExtensionErrorList: ExtensionErrorList |
224 }; | 154 }; |
225 }); | 155 }); |
OLD | NEW |