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

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

Powered by Google App Engine
This is Rietveld 408576698