OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 * Construct an ExtensionLoadError around the given |div|. | 9 * Construct an ExtensionLoadError around the given |div|. |
10 * @param {HTMLDivElement} div The HTML div for the extension load error. | 10 * @param {HTMLDivElement} div The HTML div for the extension load error. |
11 * @constructor | 11 * @constructor |
12 */ | 12 */ |
13 function ExtensionLoadError(div) { | 13 function ExtensionLoadError(div) { |
14 div.__proto__ = ExtensionLoadError.prototype; | 14 div.__proto__ = ExtensionLoadError.prototype; |
15 div.init(); | 15 div.init(); |
16 return div; | 16 return div; |
17 } | 17 } |
18 | 18 |
19 /** | |
20 * Construct a Failure. | |
21 * @param {string} filePath The path to the unpacked extension. | |
22 * @param {string} reason The reason the extension failed to load. | |
23 * @param {Object} manifest An object with three strings: beforeHighlight, | |
24 * afterHighlight, and highlight. These represent three portions of the | |
25 * file's content to display - the portion which is most relevant and | |
26 * should be emphasized (highlight), and the parts both before and after | |
27 * this portion. These may be empty. | |
28 * @param {Element} listElement The HTML element used for displaying the | |
Devlin
2014/07/09 23:03:32
HTMLLIElement
gpdavis
2014/07/10 00:59:25
Done.
| |
29 * failure path for the additional failures UI. | |
30 * @constructor | |
31 */ | |
32 function Failure(filePath, reason, manifest, listElement) { | |
33 this.path = filePath; | |
34 this.reason = reason; | |
35 this.manifest = manifest; | |
36 this.listElement = listElement; | |
37 } | |
38 | |
19 ExtensionLoadError.prototype = { | 39 ExtensionLoadError.prototype = { |
20 __proto__: HTMLDivElement.prototype, | 40 __proto__: HTMLDivElement.prototype, |
21 | 41 |
22 /** | 42 /** |
23 * Initialize the ExtensionLoadError div. | 43 * Initialize the ExtensionLoadError div. |
24 */ | 44 */ |
25 init: function() { | 45 init: function() { |
26 /** | 46 /** |
27 * The element which displays the path of the extension. | 47 * The element which displays the path of the extension. |
28 * @type {HTMLSpanElement} | 48 * @type {HTMLSpanElement} |
29 * @private | 49 * @private |
30 */ | 50 */ |
31 this.path_ = this.querySelector('#extension-load-error-path'); | 51 this.path_ = this.querySelector('#extension-load-error-path'); |
32 | 52 |
33 /** | 53 /** |
34 * The element which displays the reason the extension failed to load. | 54 * The element which displays the reason the extension failed to load. |
35 * @type {HTMLSpanElement} | 55 * @type {HTMLSpanElement} |
36 * @private | 56 * @private |
37 */ | 57 */ |
38 this.reason_ = this.querySelector('#extension-load-error-reason'); | 58 this.reason_ = this.querySelector('#extension-load-error-reason'); |
39 | 59 |
40 /** | 60 /** |
41 * The element which displays the manifest code. | 61 * The element which displays the manifest code. |
42 * @type {ExtensionCode} | 62 * @type {ExtensionCode} |
43 * @private | 63 * @private |
44 */ | 64 */ |
45 this.manifest_ = new extensions.ExtensionCode( | 65 this.manifest_ = new extensions.ExtensionCode( |
46 this.querySelector('#extension-load-error-manifest')); | 66 this.querySelector('#extension-load-error-manifest')); |
47 | 67 |
68 /** | |
69 * The element which displays information about additional errors. | |
70 * @type {HTMLPreElement} | |
Devlin
2014/07/09 23:03:32
Update.
gpdavis
2014/07/10 00:59:25
Done.
| |
71 * @private | |
72 */ | |
73 this.additional_ = this.querySelector('#extension-load-error-additional'); | |
74 | |
75 /** | |
76 * An array of Failures for keeping track of multiple active failures. | |
77 * @type {Array.<Failure>} | |
78 * @private | |
79 */ | |
80 this.failures_ = []; | |
81 | |
48 this.querySelector('#extension-load-error-retry-button').addEventListener( | 82 this.querySelector('#extension-load-error-retry-button').addEventListener( |
49 'click', function(e) { | 83 'click', function(e) { |
50 chrome.send('extensionLoaderRetry'); | 84 chrome.send('extensionLoaderRetry'); |
51 this.hide_(); | 85 this.remove_(); |
52 }.bind(this)); | 86 }.bind(this)); |
53 | 87 |
54 this.querySelector('#extension-load-error-give-up-button'). | 88 this.querySelector('#extension-load-error-give-up-button'). |
55 addEventListener('click', function(e) { | 89 addEventListener('click', function(e) { |
56 this.hide_(); | 90 chrome.send('extensionLoaderIgnoreFailure'); |
91 this.remove_(); | |
57 }.bind(this)); | 92 }.bind(this)); |
93 | |
94 chrome.send('extensionLoaderDisplayFailures'); | |
58 }, | 95 }, |
59 | 96 |
60 /** | 97 /** |
61 * Display the load error to the user. | 98 * Add a failure to failures_ array. If there is already a displayed |
62 * @param {string} path The path from which the extension was loaded. | 99 * failure, display the additional failures element. |
63 * @param {string} reason The reason the extension failed to load. | 100 * @param {Array.<Object>} failures Array of failures containing paths, |
64 * @param {string} manifest The manifest object, with highlighted regions. | 101 * errors, manifests, and listElements. |
102 * @private | |
65 */ | 103 */ |
66 show: function(path, reason, manifest) { | 104 add_: function(failures) { |
67 this.path_.textContent = path; | 105 // If a failure is already being displayed, unhide the last item. |
68 this.reason_.textContent = reason; | 106 if (this.failures_.length > 0) |
107 this.failures_[this.failures_.length - 1].listElement.hidden = false; | |
108 for (var i = 0; i < failures.length; ++i) { | |
109 var listItem = document.createElement('li'); | |
110 listItem.textContent = failures[i].path; | |
111 this.additional_.appendChild(listItem); | |
112 failures[i].listElement = listItem; | |
113 this.failures_.push(failures[i]); | |
114 } | |
115 // Hide the last item because the UI is displaying its information. | |
116 failures[failures.length - 1].listElement.hidden = true; | |
Devlin
2014/07/09 23:03:32
I'd prefer you use |failures_| for this (even thou
gpdavis
2014/07/10 00:59:26
Fair enough. I chose to use failures just because
| |
117 this.show_(); | |
118 }, | |
69 | 119 |
70 manifest.message = reason; | 120 /** |
121 * Remove a failure from |failures_| array. If this was the last failure, | |
122 * hide the error UI. If this was the last additional failure, hide | |
123 * the additional failures UI. | |
124 * @private | |
125 */ | |
126 remove_: function() { | |
127 this.additional_.removeChild( | |
128 this.failures_[this.failures_.length - 1].listElement); | |
129 this.failures_.pop(); | |
130 if (this.failures_.length > 0) | |
Devlin
2014/07/09 23:03:32
Why three ifs?
if (this.failures_.length > 0) {
gpdavis
2014/07/10 00:59:26
Good point... this is the result of adding conditi
| |
131 this.failures_[this.failures_.length - 1].listElement.hidden = true; | |
132 if (this.failures_.length == 0) | |
133 this.hidden = true; | |
134 else | |
135 this.show_(); | |
136 }, | |
137 | |
138 /** | |
139 * Display the load error to the user. The last failure gets its manifest | |
140 * and error displayed, while additional failures have their path names | |
141 * displayed in the additional failures element. | |
142 * @private | |
143 */ | |
144 show_: function() { | |
145 assert(this.failures_.length >= 1); | |
146 var failure = this.failures_[this.failures_.length - 1]; | |
147 this.path_.textContent = failure.path; | |
148 this.reason_.textContent = failure.reason; | |
149 | |
150 failure.manifest.message = failure.reason; | |
71 this.manifest_.populate( | 151 this.manifest_.populate( |
72 manifest, | 152 failure.manifest, |
73 loadTimeData.getString('extensionLoadCouldNotLoadManifest')); | 153 loadTimeData.getString('extensionLoadCouldNotLoadManifest')); |
74 this.hidden = false; | 154 this.hidden = false; |
75 this.manifest_.scrollToError(); | 155 this.manifest_.scrollToError(); |
76 }, | |
77 | 156 |
78 /** | 157 if (this.failures_.length == 1) |
Devlin
2014/07/09 23:03:32
this.additional_.hidden = this.failures_.length ==
gpdavis
2014/07/10 00:59:25
Nice.
| |
79 * Hide the extension load error. | 158 this.additional_.hidden = true; |
80 * @private | 159 else |
81 */ | 160 this.additional_.hidden = false; |
82 hide_: function() { | |
83 this.hidden = true; | |
84 } | 161 } |
85 }; | 162 }; |
86 | 163 |
87 /** | 164 /** |
88 * The ExtensionLoader is the class in charge of loading unpacked extensions. | 165 * The ExtensionLoader is the class in charge of loading unpacked extensions. |
89 * @constructor | 166 * @constructor |
90 */ | 167 */ |
91 function ExtensionLoader() { | 168 function ExtensionLoader() { |
92 /** | 169 /** |
93 * The ExtensionLoadError to show any errors from loading an unpacked | 170 * The ExtensionLoadError to show any errors from loading an unpacked |
(...skipping 10 matching lines...) Expand all Loading... | |
104 /** | 181 /** |
105 * Begin the sequence of loading an unpacked extension. If an error is | 182 * Begin the sequence of loading an unpacked extension. If an error is |
106 * encountered, this object will get notified via notifyFailed(). | 183 * encountered, this object will get notified via notifyFailed(). |
107 */ | 184 */ |
108 loadUnpacked: function() { | 185 loadUnpacked: function() { |
109 chrome.send('extensionLoaderLoadUnpacked'); | 186 chrome.send('extensionLoaderLoadUnpacked'); |
110 }, | 187 }, |
111 | 188 |
112 /** | 189 /** |
113 * Notify the ExtensionLoader that loading an unpacked extension failed. | 190 * Notify the ExtensionLoader that loading an unpacked extension failed. |
114 * Show the ExtensionLoadError. | 191 * Add the failure to failures_ and show the ExtensionLoadError. |
115 * @param {string} filePath The path to the unpacked extension. | 192 * @param {Array.<Object>} failures Array of failures containing paths, |
116 * @param {string} reason The reason the extension failed to load. | 193 * errors, manifests, and listElements. |
Devlin
2014/07/09 23:03:32
It doesn't contain listElements, though, right? (
gpdavis
2014/07/10 00:59:26
Oops. You're right; these objects aren't yet Fail
| |
117 * @param {Object} manifest An object with three strings: beforeHighlight, | |
118 * afterHighlight, and highlight. These represent three portions of the | |
119 * file's content to display - the portion which is most relevant and | |
120 * should be emphasized (highlight), and the parts both before and after | |
121 * this portion. These may be empty. | |
122 */ | 194 */ |
123 notifyFailed: function(filePath, reason, manifest) { | 195 notifyFailed: function(failures) { |
124 this.loadError_.show(filePath, reason, manifest); | 196 this.loadError_.add_(failures); |
125 } | 197 }, |
126 }; | 198 }; |
127 | 199 |
128 /* | 200 /* |
129 * A static forwarding function for ExtensionLoader.notifyFailed. | 201 * A static forwarding function for ExtensionLoader.notifyFailed. |
130 * @param {string} filePath The path to the unpacked extension. | 202 * @param {Array.<Object>} failures Array of failures containing paths, |
131 * @param {string} reason The reason the extension failed to load. | 203 * errors, manifests, and listElements. |
132 * @param {Object} manifest The manifest of the failed extension. | |
133 * @see ExtensionLoader.notifyFailed | 204 * @see ExtensionLoader.notifyFailed |
134 */ | 205 */ |
135 ExtensionLoader.notifyLoadFailed = function(filePath, reason, manifest) { | 206 ExtensionLoader.notifyLoadFailed = function(failures) { |
136 ExtensionLoader.getInstance().notifyFailed(filePath, reason, manifest); | 207 ExtensionLoader.getInstance().notifyFailed(failures); |
137 }; | 208 }; |
138 | 209 |
139 return { | 210 return { |
140 ExtensionLoader: ExtensionLoader | 211 ExtensionLoader: ExtensionLoader |
141 }; | 212 }; |
142 }); | 213 }); |
OLD | NEW |