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

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

Issue 342003005: Show alert failure for reloading unpacked extensions with bad manifest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added ReloadExtensionImpl, enhanced loader handler to send ListValue of failures Created 6 years, 5 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
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 window.addEventListener('beforeunload', function() {
Devlin 2014/07/07 20:44:21 Didn't we have a way of potentially getting rid of
gpdavis 2014/07/09 01:35:57 I gave it a shot, and it didn't seem to work prope
Devlin 2014/07/09 19:53:17 I highly doubt that this is the best solution. Th
gpdavis 2014/07/09 21:16:25 Well, I figured out what I attempted before, but t
6 chrome.send('extensionLoaderSetDisplayLoading');
7 });
8
5 cr.define('extensions', function() { 9 cr.define('extensions', function() {
6 'use strict'; 10 'use strict';
7 11
8 /** 12 /**
9 * Construct an ExtensionLoadError around the given |div|. 13 * Construct an ExtensionLoadError around the given |div|.
10 * @param {HTMLDivElement} div The HTML div for the extension load error. 14 * @param {HTMLDivElement} div The HTML div for the extension load error.
11 * @constructor 15 * @constructor
12 */ 16 */
13 function ExtensionLoadError(div) { 17 function ExtensionLoadError(div) {
14 div.__proto__ = ExtensionLoadError.prototype; 18 div.__proto__ = ExtensionLoadError.prototype;
15 div.init(); 19 div.init();
16 return div; 20 return div;
17 } 21 }
18 22
23 /**
24 * Construct a Failure.
25 * @param {string} filePath The path to the unpacked extension.
26 * @param {string} reason The reason the extension failed to load.
27 * @param {Object} manifest The manifest of the failed extension.
28 * @constructor
29 */
30 function Failure(filePath, reason, manifest) {
31 this.path = filePath;
32 this.reason = reason;
33 this.manifest = manifest;
34 }
35
19 ExtensionLoadError.prototype = { 36 ExtensionLoadError.prototype = {
20 __proto__: HTMLDivElement.prototype, 37 __proto__: HTMLDivElement.prototype,
21 38
22 /** 39 /**
23 * Initialize the ExtensionLoadError div. 40 * Initialize the ExtensionLoadError div.
24 */ 41 */
25 init: function() { 42 init: function() {
26 /** 43 /**
27 * The element which displays the path of the extension. 44 * The element which displays the path of the extension.
28 * @type {HTMLSpanElement} 45 * @type {HTMLSpanElement}
29 * @private 46 * @private
30 */ 47 */
31 this.path_ = this.querySelector('#extension-load-error-path'); 48 this.path_ = this.querySelector('#extension-load-error-path');
32 49
33 /** 50 /**
34 * The element which displays the reason the extension failed to load. 51 * The element which displays the reason the extension failed to load.
35 * @type {HTMLSpanElement} 52 * @type {HTMLSpanElement}
36 * @private 53 * @private
37 */ 54 */
38 this.reason_ = this.querySelector('#extension-load-error-reason'); 55 this.reason_ = this.querySelector('#extension-load-error-reason');
39 56
40 /** 57 /**
41 * The element which displays the manifest code. 58 * The element which displays the manifest code.
42 * @type {ExtensionCode} 59 * @type {ExtensionCode}
43 * @private 60 * @private
44 */ 61 */
45 this.manifest_ = new extensions.ExtensionCode( 62 this.manifest_ = new extensions.ExtensionCode(
46 this.querySelector('#extension-load-error-manifest')); 63 this.querySelector('#extension-load-error-manifest'));
47 64
65 /**
66 * The element which displays information about additional errors.
67 * @type {HTMLPreElement}
68 * @private
69 */
70 this.additional_ = this.querySelector('#extension-load-error-additional');
71
72 /**
73 * An array of Failures for keeping track of multiple active failures.
74 * @type {Array.<Failure>}
75 * @private
76 */
77 this.failures_ = [];
78
48 this.querySelector('#extension-load-error-retry-button').addEventListener( 79 this.querySelector('#extension-load-error-retry-button').addEventListener(
49 'click', function(e) { 80 'click', function(e) {
50 chrome.send('extensionLoaderRetry'); 81 chrome.send('extensionLoaderRetry');
51 this.hide_(); 82 this.remove_();
52 }.bind(this)); 83 }.bind(this));
53 84
54 this.querySelector('#extension-load-error-give-up-button'). 85 this.querySelector('#extension-load-error-give-up-button').
55 addEventListener('click', function(e) { 86 addEventListener('click', function(e) {
56 this.hide_(); 87 chrome.send('extensionLoaderIgnoreFailure');
88 this.remove_();
57 }.bind(this)); 89 }.bind(this));
90
91 chrome.send('extensionLoaderDisplayFailures');
58 }, 92 },
59 93
60 /** 94 /**
61 * Display the load error to the user. 95 * Add a failure to failures_ array. If there is already a displayed
96 * failure, display the additional failures element.
62 * @param {string} path The path from which the extension was loaded. 97 * @param {string} path The path from which the extension was loaded.
63 * @param {string} reason The reason the extension failed to load. 98 * @param {string} reason The reason the extension failed to load.
64 * @param {string} manifest The manifest object, with highlighted regions. 99 * @param {string} manifest The manifest object, with highlighted regions.
65 */ 100 */
66 show: function(path, reason, manifest) { 101 add: function(path, reason, manifest) {
Devlin 2014/07/07 20:44:21 Can this be private?
gpdavis 2014/07/09 01:35:56 Done.
67 this.path_.textContent = path; 102 this.failures_.push(new Failure(path, reason, manifest));
68 this.reason_.textContent = reason; 103 this.show_();
104 },
69 105
70 manifest.message = reason; 106 /**
107 * Remove a failure from failures_ array. If this was the last failure,
Devlin 2014/07/07 20:44:21 nit: |failures_| nit: 1 space after period.
gpdavis 2014/07/09 01:35:57 Done.
108 * hide the error UI. If this was the last additional failure, hide
109 * the additional failures UI.
110 * @private
111 */
112 remove_: function() {
113 this.failures_.pop();
114 if (this.failures_.length == 0) {
Devlin 2014/07/07 20:44:21 nit: no brackets for one-line ifs.
gpdavis 2014/07/09 01:35:57 Done.
115 this.hidden = true;
116 } else {
117 this.show_();
118 }
119 },
120
121 /**
122 * Display the load error to the user. The last failure gets its manifest
123 * and error displayed, while additional failures have their path names
124 * displayed in the additional failures element.
125 * @private
126 */
127 show_: function() {
128 var failure = this.failures_[this.failures_.length - 1];
Devlin 2014/07/07 20:44:21 We should assert that there is at least one failur
gpdavis 2014/07/09 01:35:56 Done.
129 this.path_.textContent = failure.path;
130 this.reason_.textContent = failure.reason;
131
132 failure.manifest.message = failure.reason;
71 this.manifest_.populate( 133 this.manifest_.populate(
72 manifest, 134 failure.manifest,
73 loadTimeData.getString('extensionLoadCouldNotLoadManifest')); 135 loadTimeData.getString('extensionLoadCouldNotLoadManifest'));
74 this.hidden = false; 136 this.hidden = false;
75 this.manifest_.scrollToError(); 137 this.manifest_.scrollToError();
76 },
77 138
78 /** 139 if (this.failures_.length == 1) {
79 * Hide the extension load error. 140 this.additional_.hidden = true;
80 * @private 141 } else if (this.failures_.length > 1) {
Devlin 2014/07/07 20:44:21 We can know that there is >= 1 failure, so a simpl
gpdavis 2014/07/09 01:35:57 Done.
81 */ 142 this.additional_.hidden = false;
82 hide_: function() { 143 this.additional_.textContent =
Devlin 2014/07/07 20:44:21 I think it would be cleaner to have this be a list
gpdavis 2014/07/09 01:35:56 Done.
83 this.hidden = true; 144 loadTimeData.getString('extensionLoadAdditionalFailures');
145 for (var i = 0; i < this.failures_.length - 1; ++i)
146 this.additional_.textContent += '\n' + this.failures_[i].path;
147 }
84 } 148 }
85 }; 149 };
86 150
87 /** 151 /**
88 * The ExtensionLoader is the class in charge of loading unpacked extensions. 152 * The ExtensionLoader is the class in charge of loading unpacked extensions.
89 * @constructor 153 * @constructor
90 */ 154 */
91 function ExtensionLoader() { 155 function ExtensionLoader() {
92 /** 156 /**
93 * The ExtensionLoadError to show any errors from loading an unpacked 157 * The ExtensionLoadError to show any errors from loading an unpacked
(...skipping 10 matching lines...) Expand all
104 /** 168 /**
105 * Begin the sequence of loading an unpacked extension. If an error is 169 * Begin the sequence of loading an unpacked extension. If an error is
106 * encountered, this object will get notified via notifyFailed(). 170 * encountered, this object will get notified via notifyFailed().
107 */ 171 */
108 loadUnpacked: function() { 172 loadUnpacked: function() {
109 chrome.send('extensionLoaderLoadUnpacked'); 173 chrome.send('extensionLoaderLoadUnpacked');
110 }, 174 },
111 175
112 /** 176 /**
113 * Notify the ExtensionLoader that loading an unpacked extension failed. 177 * Notify the ExtensionLoader that loading an unpacked extension failed.
114 * Show the ExtensionLoadError. 178 * Add the failure to failures_ and show the ExtensionLoadError.
115 * @param {string} filePath The path to the unpacked extension. 179 * @param {string} filePath The path to the unpacked extension.
116 * @param {string} reason The reason the extension failed to load. 180 * @param {string} reason The reason the extension failed to load.
117 * @param {Object} manifest An object with three strings: beforeHighlight, 181 * @param {Object} manifest An object with three strings: beforeHighlight,
118 * afterHighlight, and highlight. These represent three portions of the 182 * afterHighlight, and highlight. These represent three portions of the
119 * file's content to display - the portion which is most relevant and 183 * file's content to display - the portion which is most relevant and
120 * should be emphasized (highlight), and the parts both before and after 184 * should be emphasized (highlight), and the parts both before and after
121 * this portion. These may be empty. 185 * this portion. These may be empty.
122 */ 186 */
123 notifyFailed: function(filePath, reason, manifest) { 187 notifyFailed: function(filePath, reason, manifest) {
124 this.loadError_.show(filePath, reason, manifest); 188 this.loadError_.add(filePath, reason, manifest);
125 } 189 },
126 }; 190 };
127 191
128 /* 192 /*
129 * A static forwarding function for ExtensionLoader.notifyFailed. 193 * A static forwarding function for ExtensionLoader.notifyFailed.
130 * @param {string} filePath The path to the unpacked extension. 194 * @param {Array.<Object>} failures Array of failures containing paths,
131 * @param {string} reason The reason the extension failed to load. 195 * errors, and manifests.
132 * @param {Object} manifest The manifest of the failed extension.
133 * @see ExtensionLoader.notifyFailed 196 * @see ExtensionLoader.notifyFailed
134 */ 197 */
135 ExtensionLoader.notifyLoadFailed = function(filePath, reason, manifest) { 198 ExtensionLoader.notifyLoadFailed = function(failures) {
136 ExtensionLoader.getInstance().notifyFailed(filePath, reason, manifest); 199 for (var i = 0; i < failures.length; ++i)
200 ExtensionLoader.getInstance().notifyFailed(failures[i].path,
Devlin 2014/07/07 20:44:21 We should add these in batches, because otherwise
gpdavis 2014/07/09 01:35:57 Done.
201 failures[i].error,
202 failures[i].manifest);
137 }; 203 };
138 204
139 return { 205 return {
140 ExtensionLoader: ExtensionLoader 206 ExtensionLoader: ExtensionLoader
141 }; 207 };
142 }); 208 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698