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

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: Delegate Created 5 years, 8 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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 /** 165 /**
166 * Creates a new list of extensions. 166 * Creates a new list of extensions.
167 * @param {ExtensionList.Delegate} delegate
Devlin 2015/04/27 18:28:30 This causes a Closure Compiler error (ExtensionLis
Dan Beam 2015/04/27 18:47:59 ExtensionList.Delegate -> ExtensionListDelegate (t
167 * @constructor 168 * @constructor
168 * @extends {HTMLDivElement} 169 * @extends {HTMLDivElement}
169 */ 170 */
170 function ExtensionList() { 171 function ExtensionList(delegate) {
171 var div = document.createElement('div'); 172 var div = document.createElement('div');
172 div.__proto__ = ExtensionList.prototype; 173 div.__proto__ = ExtensionList.prototype;
173 div.initialize(); 174 div.initialize(delegate);
174 return div; 175 return div;
175 } 176 }
176 177
178 /** @interface */
179 ExtensionList.Delegate = function() {};
180
181 ExtensionList.Delegate.prototype = {
182 /**
183 * Called when the number of extensions in the list has changed.
184 */
185 onExtensionCountChanged: assertNotReached,
186 };
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 = {};
184 195
185 ExtensionList.prototype = { 196 ExtensionList.prototype = {
186 __proto__: HTMLDivElement.prototype, 197 __proto__: HTMLDivElement.prototype,
(...skipping 36 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 {!ExtensionList.Delegate} 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 {!ExtensionList.Delegate} */
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)
Dan Beam 2015/04/27 18:47:59 curlies
Devlin 2015/04/27 20:02:03 Done.
289 this.delegate_.onExtensionCountChanged();
269 }.bind(this)); 290 }.bind(this));
270 }, 291 },
271 292
272 /** 293 /**
273 * Updates the extensions on the page. 294 * Updates the extensions on the page.
274 * @param {boolean} incognitoAvailable Whether or not incognito is allowed. 295 * @param {boolean} incognitoAvailable Whether or not incognito is allowed.
275 * @param {boolean} enableAppInfoDialog Whether or not the app info dialog 296 * @param {boolean} enableAppInfoDialog Whether or not the app info dialog
276 * is enabled. 297 * is enabled.
277 * @return {Promise} A promise that is resolved once the extensions data is 298 * @return {Promise} A promise that is resolved once the extensions data is
278 * fully updated. 299 * fully updated.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 var idToOpenOptions = this.getOptionsQueryParam_(); 348 var idToOpenOptions = this.getOptionsQueryParam_();
328 if (idToOpenOptions && $(idToOpenOptions)) 349 if (idToOpenOptions && $(idToOpenOptions))
329 this.showEmbeddedExtensionOptions_(idToOpenOptions, true); 350 this.showEmbeddedExtensionOptions_(idToOpenOptions, true);
330 }, 351 },
331 352
332 /** @return {number} The number of extensions being displayed. */ 353 /** @return {number} The number of extensions being displayed. */
333 getNumExtensions: function() { 354 getNumExtensions: function() {
334 return this.extensions_.length; 355 return this.extensions_.length;
335 }, 356 },
336 357
358 /**
359 * @param {string} id The id of the extension.
360 * @return {number} The index of the extension with the given id.
361 * @private
362 */
363 getIndexOfExtension_: function(id) {
364 for (var i = 0; i < this.extensions_.length; ++i) {
365 if (this.extensions_[i].id == id)
366 return i;
367 }
368 return -1;
369 },
370
337 getIdQueryParam_: function() { 371 getIdQueryParam_: function() {
338 return parseQueryParams(document.location)['id']; 372 return parseQueryParams(document.location)['id'];
339 }, 373 },
340 374
341 getOptionsQueryParam_: function() { 375 getOptionsQueryParam_: function() {
342 return parseQueryParams(document.location)['options']; 376 return parseQueryParams(document.location)['options'];
343 }, 377 },
344 378
345 /** 379 /**
346 * Creates or updates all extension items from scratch. 380 * Creates or updates all extension items from scratch.
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 overlay.setInitialFocus(); 1090 overlay.setInitialFocus();
1057 }, 1091 },
1058 1092
1059 /** 1093 /**
1060 * Updates the node for the extension. 1094 * Updates the node for the extension.
1061 * @param {!ExtensionInfo} extension The information about the extension to 1095 * @param {!ExtensionInfo} extension The information about the extension to
1062 * update. 1096 * update.
1063 * @private 1097 * @private
1064 */ 1098 */
1065 updateExtension_: function(extension) { 1099 updateExtension_: function(extension) {
1066 var currIndex = -1; 1100 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) { 1101 if (currIndex != -1) {
1074 // If there is a current version of the extension, update it with the 1102 // If there is a current version of the extension, update it with the
1075 // new version. 1103 // new version.
1076 this.extensions_[currIndex] = extension; 1104 this.extensions_[currIndex] = extension;
1077 } else { 1105 } else {
1078 // If the extension isn't found, push it back and sort. Technically, we 1106 // 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 1107 // could optimize by inserting it at the right location, but since this
1080 // only happens on extension install, it's not worth it. 1108 // only happens on extension install, it's not worth it.
1081 this.extensions_.push(extension); 1109 this.extensions_.push(extension);
1082 this.extensions_.sort(compareExtensions); 1110 this.extensions_.sort(compareExtensions);
1083 } 1111 }
1084 1112
1085 var node = /** @type {ExtensionFocusRow} */ ($(extension.id)); 1113 var node = /** @type {ExtensionFocusRow} */ ($(extension.id));
1086 if (node) { 1114 if (node) {
1087 this.updateNode_(extension, node); 1115 this.updateNode_(extension, node);
1088 } else { 1116 } else {
1089 var nextExt = this.extensions_[this.extensions_.indexOf(extension) + 1]; 1117 var nextExt = this.extensions_[this.extensions_.indexOf(extension) + 1];
1090 this.createNode_(extension, nextExt ? $(nextExt.id) : null); 1118 this.createNode_(extension, nextExt ? $(nextExt.id) : null);
1091 } 1119 }
1092 } 1120 }
1093 }; 1121 };
1094 1122
1095 return { 1123 return {
1096 ExtensionList: ExtensionList 1124 ExtensionList: ExtensionList
1097 }; 1125 };
1098 }); 1126 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698