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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/extensions/extension_loader.js
diff --git a/chrome/browser/resources/extensions/extension_loader.js b/chrome/browser/resources/extensions/extension_loader.js
index fb57c18b139075cba35b00c733df28187052c4c9..7413c397e829b5fc21cbec2ee85320627eca09d2 100644
--- a/chrome/browser/resources/extensions/extension_loader.js
+++ b/chrome/browser/resources/extensions/extension_loader.js
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+window.addEventListener('beforeunload', function() {
+ chrome.send('extensionLoaderSetDisplayLoading');
+});
+
cr.define('extensions', function() {
'use strict';
@@ -16,6 +20,23 @@ cr.define('extensions', function() {
return div;
}
+ /**
+ * Construct a Failure.
+ * @param {string} filePath The path to the unpacked extension.
+ * @param {string} reason The reason the extension failed to load.
+ * @param {Object} manifest An object with three strings: beforeHighlight,
+ * afterHighlight, and highlight. These represent three portions of the
+ * file's content to display - the portion which is most relevant and
+ * should be emphasized (highlight), and the parts both before and after
+ * this portion. These may be empty.
+ * @constructor
+ */
+ function Failure(filePath, reason, manifest) {
+ this.path = filePath;
+ this.reason = reason;
+ this.manifest = manifest;
+ }
+
ExtensionLoadError.prototype = {
__proto__: HTMLDivElement.prototype,
@@ -45,42 +66,100 @@ cr.define('extensions', function() {
this.manifest_ = new extensions.ExtensionCode(
this.querySelector('#extension-load-error-manifest'));
+ /**
+ * The element which displays information about additional errors.
+ * @type {HTMLPreElement}
+ * @private
+ */
+ this.additional_ = this.querySelector('#extension-load-error-additional');
+
+ /**
+ * An array of Failures for keeping track of multiple active failures.
+ * @type {Array.<Failure>}
+ * @private
+ */
+ this.failures_ = [];
+
this.querySelector('#extension-load-error-retry-button').addEventListener(
'click', function(e) {
chrome.send('extensionLoaderRetry');
- this.hide_();
+ this.remove_();
}.bind(this));
this.querySelector('#extension-load-error-give-up-button').
addEventListener('click', function(e) {
- this.hide_();
+ chrome.send('extensionLoaderIgnoreFailure');
+ this.remove_();
}.bind(this));
+
+ chrome.send('extensionLoaderDisplayFailures');
},
/**
- * Display the load error to the user.
+ * Add a failure to failures_ array. If there is already a displayed
+ * failure, display the additional failures element.
* @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.
* @param {string} reason The reason the extension failed to load.
* @param {string} manifest The manifest object, with highlighted regions.
+ * @private
*/
- show: function(path, reason, manifest) {
- this.path_.textContent = path;
- this.reason_.textContent = reason;
+ add_: function(failures) {
+ // If a failure is already being displayed, unhide the last item.
+ 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.
+ 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.
+ }
+ var listItem;
Devlin 2014/07/09 19:53:17 initialize.
gpdavis 2014/07/09 21:16:25 Done.
+ for (var i = 0; i < failures.length; ++i) {
+ this.failures_.push(failures[i]);
+ listItem = document.createElement('li');
+ 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.
+ 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
+ failures[i].listElement = listItem;
+ }
+ // Hide the last item because the UI is displaying its information.
+ listItem.hidden = true;
+ this.show_();
+ },
- manifest.message = reason;
- this.manifest_.populate(
- manifest,
- loadTimeData.getString('extensionLoadCouldNotLoadManifest'));
- this.hidden = false;
- this.manifest_.scrollToError();
+ /**
+ * Remove a failure from |failures_| array. If this was the last failure,
+ * hide the error UI. If this was the last additional failure, hide
+ * the additional failures UI.
+ * @private
+ */
+ remove_: function() {
+ this.failures_.pop();
+ if (this.failures_.length > 0)
+ this.failures_[this.failures_.length - 1].listElement.hidden = true;
+ if (this.failures_.length == 0)
+ this.hidden = true;
+ else
+ this.show_();
},
/**
- * Hide the extension load error.
+ * Display the load error to the user. The last failure gets its manifest
+ * and error displayed, while additional failures have their path names
+ * displayed in the additional failures element.
* @private
*/
- hide_: function() {
- this.hidden = true;
+ show_: function() {
+ assert(this.failures_.length >= 1);
+ var failure = this.failures_[this.failures_.length - 1];
+ this.path_.textContent = failure.path;
+ this.reason_.textContent = failure.reason;
+
+ failure.manifest.message = failure.reason;
+ this.manifest_.populate(
+ failure.manifest,
+ loadTimeData.getString('extensionLoadCouldNotLoadManifest'));
+ this.hidden = false;
+ this.manifest_.scrollToError();
+
+ if (this.failures_.length == 1)
+ this.additional_.hidden = true;
+ else
+ this.additional_.hidden = false;
}
};
@@ -111,29 +190,23 @@ cr.define('extensions', function() {
/**
* Notify the ExtensionLoader that loading an unpacked extension failed.
- * Show the ExtensionLoadError.
- * @param {string} filePath The path to the unpacked extension.
- * @param {string} reason The reason the extension failed to load.
- * @param {Object} manifest An object with three strings: beforeHighlight,
- * afterHighlight, and highlight. These represent three portions of the
- * file's content to display - the portion which is most relevant and
- * should be emphasized (highlight), and the parts both before and after
- * this portion. These may be empty.
+ * Add the failure to failures_ and show the ExtensionLoadError.
+ * @param {Array.<Object>} failures Array of failures containing paths,
+ * errors, and manifests.
*/
- notifyFailed: function(filePath, reason, manifest) {
- this.loadError_.show(filePath, reason, manifest);
- }
+ notifyFailed: function(failures) {
+ this.loadError_.add_(failures);
+ },
};
/*
* A static forwarding function for ExtensionLoader.notifyFailed.
- * @param {string} filePath The path to the unpacked extension.
- * @param {string} reason The reason the extension failed to load.
- * @param {Object} manifest The manifest of the failed extension.
+ * @param {Array.<Object>} failures Array of failures containing paths,
+ * errors, and manifests.
* @see ExtensionLoader.notifyFailed
*/
- ExtensionLoader.notifyLoadFailed = function(filePath, reason, manifest) {
- ExtensionLoader.getInstance().notifyFailed(filePath, reason, manifest);
+ ExtensionLoader.notifyLoadFailed = function(failures) {
+ ExtensionLoader.getInstance().notifyFailed(failures);
};
return {

Powered by Google App Engine
This is Rietveld 408576698