Index: chrome/browser/resources/extensions/extension_list.js |
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js |
index bb126d5ed769c804c0932181d9687850108bec9a..5318883f8aa003c85cefad278901cf532391169a 100644 |
--- a/chrome/browser/resources/extensions/extension_list.js |
+++ b/chrome/browser/resources/extensions/extension_list.js |
@@ -235,6 +235,16 @@ cr.define('extensions', function() { |
/** @private {!Array<ExtensionInfo>} */ |
this.extensions_ = []; |
+ /** |
+ * |loadFinished| should be used for testing purposes and will be |
+ * fulfilled when this list has finished loading the first time. |
+ * @type {Promise} |
+ * */ |
+ this.loadFinished = new Promise(function(resolve, reject) { |
+ /** @private {function(?)} */ |
+ this.resolveLoadFinished_ = resolve; |
+ }.bind(this)); |
+ |
chrome.developerPrivate.onItemStateChanged.addListener( |
function(eventData) { |
var EventType = chrome.developerPrivate.EventType; |
@@ -282,11 +292,42 @@ cr.define('extensions', function() { |
this.extensions_ = extensions; |
this.showExtensionNodes_(); |
resolve(); |
+ |
+ // |resolve| is async so it's necessary to use |then| here in order to |
+ // do work after other |then|s have finished. This is important so |
+ // elements are visible when these updates happen. |
+ this.extensionsUpdated_.then(function() { |
+ this.onUpdateFinished_(); |
+ this.resolveLoadFinished_(); |
+ }.bind(this)); |
}.bind(this)); |
}.bind(this)); |
return this.extensionsUpdated_; |
}, |
+ /** |
+ * Updates elements that need to be visible in order to update properly. |
+ * @private |
+ */ |
+ onUpdateFinished_: function() { |
+ // Cannot focus or highlight a extension if there are none. |
+ if (this.extensions_.length == 0) |
+ return; |
+ |
+ assert(!this.hidden); |
+ assert(!this.parentElement.hidden); |
+ |
+ this.updateFocusableElements(); |
+ |
+ var idToHighlight = this.getIdQueryParam_(); |
+ if (idToHighlight && $(idToHighlight)) |
+ this.scrollToNode_(idToHighlight); |
+ |
+ var idToOpenOptions = this.getOptionsQueryParam_(); |
+ if (idToOpenOptions && $(idToOpenOptions)) |
+ this.showEmbeddedExtensionOptions_(idToOpenOptions, true); |
+ }, |
+ |
/** @return {number} The number of extensions being displayed. */ |
getNumExtensions: function() { |
return this.extensions_.length; |
@@ -336,14 +377,6 @@ cr.define('extensions', function() { |
assertInstanceof(node, ExtensionFocusRow).destroy(); |
} |
} |
- |
- var idToHighlight = this.getIdQueryParam_(); |
- if (idToHighlight && $(idToHighlight)) |
- this.scrollToNode_(idToHighlight); |
- |
- var idToOpenOptions = this.getOptionsQueryParam_(); |
- if (idToOpenOptions && $(idToOpenOptions)) |
- this.showEmbeddedExtensionOptions_(idToOpenOptions, true); |
}, |
/** Updates each row's focusable elements without rebuilding the grid. */ |