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

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

Issue 1105683003: [Extensions Page] Add a listener on extension list for "hasExtensions" changing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <include src="extension_error.js"> 5 <include src="extension_error.js">
6 6
7 /////////////////////////////////////////////////////////////////////////////// 7 ///////////////////////////////////////////////////////////////////////////////
8 // ExtensionFocusRow: 8 // ExtensionFocusRow:
9 9
10 /** 10 /**
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 return -1; 155 return -1;
156 if (y.location == chrome.developerPrivate.Location.UNPACKED) 156 if (y.location == chrome.developerPrivate.Location.UNPACKED)
157 return 1; 157 return 1;
158 return 0; 158 return 0;
159 } 159 }
160 return compareLocation(a, b) || 160 return compareLocation(a, b) ||
161 compare(a.name.toLowerCase(), b.name.toLowerCase()) || 161 compare(a.name.toLowerCase(), b.name.toLowerCase()) ||
162 compare(a.id, b.id); 162 compare(a.id, b.id);
163 } 163 }
164 164
165 /** @interface */
166 function ExtensionListDelegate() {}
167
168 ExtensionListDelegate.prototype = {
169 /**
170 * Called when the number of extensions in the list has changed.
171 */
172 onExtensionCountChanged: assertNotReached,
173 };
174
165 /** 175 /**
166 * Creates a new list of extensions. 176 * Creates a new list of extensions.
177 * @param {ExtensionListDelegate} delegate
Devlin 2015/04/27 20:02:03 Strangely, this (and also lines 244 and 250, as we
Dan Beam 2015/04/27 21:02:27 this will work: extensions.ExtensionListDelegate
Devlin 2015/04/27 21:11:54 Bummer indeed. Odd that it worked fine when putti
Devlin 2015/04/27 22:19:47 Fixed better, from offline conversation.
167 * @constructor 178 * @constructor
168 * @extends {HTMLDivElement} 179 * @extends {HTMLDivElement}
169 */ 180 */
170 function ExtensionList() { 181 function ExtensionList(delegate) {
171 var div = document.createElement('div'); 182 var div = document.createElement('div');
172 div.__proto__ = ExtensionList.prototype; 183 div.__proto__ = ExtensionList.prototype;
173 div.initialize(); 184 div.initialize(delegate);
174 return div; 185 return div;
175 } 186 }
176 187
177 /** 188 /**
178 * @type {Object<string, number>} A map from extension id to last reloaded 189 * @type {Object<string, number>} A map from extension id to last reloaded
179 * timestamp. The timestamp is recorded when the user click the 'Reload' 190 * timestamp. The timestamp is recorded when the user click the 'Reload'
180 * link. It is used to refresh the icon of an unpacked extension. 191 * link. It is used to refresh the icon of an unpacked extension.
181 * This persists between calls to decorate. 192 * This persists between calls to decorate.
182 */ 193 */
183 var extensionReloadedTimestamp = {}; 194 var extensionReloadedTimestamp = {};
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 incognitoAvailable_: false, 234 incognitoAvailable_: false,
224 235
225 /** 236 /**
226 * Whether or not the app info dialog is enabled. 237 * Whether or not the app info dialog is enabled.
227 * @private {boolean} 238 * @private {boolean}
228 */ 239 */
229 enableAppInfoDialog_: false, 240 enableAppInfoDialog_: false,
230 241
231 /** 242 /**
232 * Initializes the list. 243 * Initializes the list.
244 * @param {!ExtensionListDelegate} delegate
233 */ 245 */
234 initialize: function() { 246 initialize: function(delegate) {
235 /** @private {!Array<ExtensionInfo>} */ 247 /** @private {!Array<ExtensionInfo>} */
236 this.extensions_ = []; 248 this.extensions_ = [];
237 249
250 /** @private {!ExtensionListDelegate} */
251 this.delegate_ = delegate;
252
238 /** 253 /**
239 * |loadFinished| should be used for testing purposes and will be 254 * |loadFinished| should be used for testing purposes and will be
240 * fulfilled when this list has finished loading the first time. 255 * fulfilled when this list has finished loading the first time.
241 * @type {Promise} 256 * @type {Promise}
242 * */ 257 * */
243 this.loadFinished = new Promise(function(resolve, reject) { 258 this.loadFinished = new Promise(function(resolve, reject) {
244 /** @private {function(?)} */ 259 /** @private {function(?)} */
245 this.resolveLoadFinished_ = resolve; 260 this.resolveLoadFinished_ = resolve;
246 }.bind(this)); 261 }.bind(this));
247 262
248 chrome.developerPrivate.onItemStateChanged.addListener( 263 chrome.developerPrivate.onItemStateChanged.addListener(
249 function(eventData) { 264 function(eventData) {
250 var EventType = chrome.developerPrivate.EventType; 265 var EventType = chrome.developerPrivate.EventType;
251 switch (eventData.event_type) { 266 switch (eventData.event_type) {
252 case EventType.VIEW_REGISTERED: 267 case EventType.VIEW_REGISTERED:
253 case EventType.VIEW_UNREGISTERED: 268 case EventType.VIEW_UNREGISTERED:
254 case EventType.INSTALLED: 269 case EventType.INSTALLED:
255 case EventType.LOADED: 270 case EventType.LOADED:
256 case EventType.UNLOADED: 271 case EventType.UNLOADED:
257 case EventType.ERROR_ADDED: 272 case EventType.ERROR_ADDED:
258 case EventType.PREFS_CHANGED: 273 case EventType.PREFS_CHANGED:
259 if (eventData.extensionInfo) 274 if (eventData.extensionInfo)
260 this.updateExtension_(eventData.extensionInfo); 275 this.updateExtension_(eventData.extensionInfo);
261 break; 276 break;
262 case EventType.UNINSTALLED: 277 case EventType.UNINSTALLED:
278 var index = this.getIndexOfExtension_(eventData.item_id);
279 this.extensions_.splice(index, 1);
263 var childNode = $(eventData.item_id); 280 var childNode = $(eventData.item_id);
264 childNode.parentNode.removeChild(childNode); 281 childNode.parentNode.removeChild(childNode);
265 break; 282 break;
266 default: 283 default:
267 assertNotReached(); 284 assertNotReached();
268 } 285 }
286
287 if (eventData.event_type == EventType.INSTALLED ||
288 eventData.event_type == EventType.UNINSTALLED) {
289 this.delegate_.onExtensionCountChanged();
290 }
269 }.bind(this)); 291 }.bind(this));
270 }, 292 },
271 293
272 /** 294 /**
273 * Updates the extensions on the page. 295 * Updates the extensions on the page.
274 * @param {boolean} incognitoAvailable Whether or not incognito is allowed. 296 * @param {boolean} incognitoAvailable Whether or not incognito is allowed.
275 * @param {boolean} enableAppInfoDialog Whether or not the app info dialog 297 * @param {boolean} enableAppInfoDialog Whether or not the app info dialog
276 * is enabled. 298 * is enabled.
277 * @return {Promise} A promise that is resolved once the extensions data is 299 * @return {Promise} A promise that is resolved once the extensions data is
278 * fully updated. 300 * fully updated.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 var idToOpenOptions = this.getOptionsQueryParam_(); 349 var idToOpenOptions = this.getOptionsQueryParam_();
328 if (idToOpenOptions && $(idToOpenOptions)) 350 if (idToOpenOptions && $(idToOpenOptions))
329 this.showEmbeddedExtensionOptions_(idToOpenOptions, true); 351 this.showEmbeddedExtensionOptions_(idToOpenOptions, true);
330 }, 352 },
331 353
332 /** @return {number} The number of extensions being displayed. */ 354 /** @return {number} The number of extensions being displayed. */
333 getNumExtensions: function() { 355 getNumExtensions: function() {
334 return this.extensions_.length; 356 return this.extensions_.length;
335 }, 357 },
336 358
359 /**
360 * @param {string} id The id of the extension.
361 * @return {number} The index of the extension with the given id.
362 * @private
363 */
364 getIndexOfExtension_: function(id) {
365 for (var i = 0; i < this.extensions_.length; ++i) {
366 if (this.extensions_[i].id == id)
367 return i;
368 }
369 return -1;
370 },
371
337 getIdQueryParam_: function() { 372 getIdQueryParam_: function() {
338 return parseQueryParams(document.location)['id']; 373 return parseQueryParams(document.location)['id'];
339 }, 374 },
340 375
341 getOptionsQueryParam_: function() { 376 getOptionsQueryParam_: function() {
342 return parseQueryParams(document.location)['options']; 377 return parseQueryParams(document.location)['options'];
343 }, 378 },
344 379
345 /** 380 /**
346 * Creates or updates all extension items from scratch. 381 * Creates or updates all extension items from scratch.
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 overlay.setInitialFocus(); 1091 overlay.setInitialFocus();
1057 }, 1092 },
1058 1093
1059 /** 1094 /**
1060 * Updates the node for the extension. 1095 * Updates the node for the extension.
1061 * @param {!ExtensionInfo} extension The information about the extension to 1096 * @param {!ExtensionInfo} extension The information about the extension to
1062 * update. 1097 * update.
1063 * @private 1098 * @private
1064 */ 1099 */
1065 updateExtension_: function(extension) { 1100 updateExtension_: function(extension) {
1066 var currIndex = -1; 1101 var currIndex = this.getIndexOfExtension_(extension.id);
1067 for (var i = 0; i < this.extensions_.length; ++i) {
1068 if (this.extensions_[i].id == extension.id) {
1069 currIndex = i;
1070 break;
1071 }
1072 }
1073 if (currIndex != -1) { 1102 if (currIndex != -1) {
1074 // If there is a current version of the extension, update it with the 1103 // If there is a current version of the extension, update it with the
1075 // new version. 1104 // new version.
1076 this.extensions_[currIndex] = extension; 1105 this.extensions_[currIndex] = extension;
1077 } else { 1106 } else {
1078 // If the extension isn't found, push it back and sort. Technically, we 1107 // If the extension isn't found, push it back and sort. Technically, we
1079 // could optimize by inserting it at the right location, but since this 1108 // could optimize by inserting it at the right location, but since this
1080 // only happens on extension install, it's not worth it. 1109 // only happens on extension install, it's not worth it.
1081 this.extensions_.push(extension); 1110 this.extensions_.push(extension);
1082 this.extensions_.sort(compareExtensions); 1111 this.extensions_.sort(compareExtensions);
1083 } 1112 }
1084 1113
1085 var node = /** @type {ExtensionFocusRow} */ ($(extension.id)); 1114 var node = /** @type {ExtensionFocusRow} */ ($(extension.id));
1086 if (node) { 1115 if (node) {
1087 this.updateNode_(extension, node); 1116 this.updateNode_(extension, node);
1088 } else { 1117 } else {
1089 var nextExt = this.extensions_[this.extensions_.indexOf(extension) + 1]; 1118 var nextExt = this.extensions_[this.extensions_.indexOf(extension) + 1];
1090 this.createNode_(extension, nextExt ? $(nextExt.id) : null); 1119 this.createNode_(extension, nextExt ? $(nextExt.id) : null);
1091 } 1120 }
1092 } 1121 }
1093 }; 1122 };
1094 1123
1095 return { 1124 return {
1096 ExtensionList: ExtensionList 1125 ExtensionList: ExtensionList
1097 }; 1126 };
1098 }); 1127 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698