OLD | NEW |
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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 'use strict'; | 139 'use strict'; |
140 | 140 |
141 /** | 141 /** |
142 * Creates a new list of extensions. | 142 * Creates a new list of extensions. |
143 * @constructor | 143 * @constructor |
144 * @extends {HTMLDivElement} | 144 * @extends {HTMLDivElement} |
145 */ | 145 */ |
146 function ExtensionList() { | 146 function ExtensionList() { |
147 var div = document.createElement('div'); | 147 var div = document.createElement('div'); |
148 div.__proto__ = ExtensionList.prototype; | 148 div.__proto__ = ExtensionList.prototype; |
149 /** @private {!Array<ExtensionInfo>} */ | 149 div.initialize(); |
150 div.extensions_ = []; | |
151 return div; | 150 return div; |
152 } | 151 } |
153 | 152 |
154 /** | 153 /** |
155 * @type {Object<string, number>} A map from extension id to last reloaded | 154 * @type {Object<string, number>} A map from extension id to last reloaded |
156 * timestamp. The timestamp is recorded when the user click the 'Reload' | 155 * timestamp. The timestamp is recorded when the user click the 'Reload' |
157 * link. It is used to refresh the icon of an unpacked extension. | 156 * link. It is used to refresh the icon of an unpacked extension. |
158 * This persists between calls to decorate. | 157 * This persists between calls to decorate. |
159 */ | 158 */ |
160 var extensionReloadedTimestamp = {}; | 159 var extensionReloadedTimestamp = {}; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 */ | 198 */ |
200 incognitoAvailable_: false, | 199 incognitoAvailable_: false, |
201 | 200 |
202 /** | 201 /** |
203 * Whether or not the app info dialog is enabled. | 202 * Whether or not the app info dialog is enabled. |
204 * @private {boolean} | 203 * @private {boolean} |
205 */ | 204 */ |
206 enableAppInfoDialog_: false, | 205 enableAppInfoDialog_: false, |
207 | 206 |
208 /** | 207 /** |
| 208 * Initializes the list. |
| 209 */ |
| 210 initialize: function() { |
| 211 /** @private {!Array<ExtensionInfo>} */ |
| 212 this.extensions_ = []; |
| 213 |
| 214 chrome.developerPrivate.onItemStateChanged.addListener( |
| 215 function(eventData) { |
| 216 var EventType = chrome.developerPrivate.EventType; |
| 217 switch (eventData.event_type) { |
| 218 case EventType.VIEW_REGISTERED: |
| 219 case EventType.VIEW_UNREGISTERED: |
| 220 // For now, view notifications are handled through the WebUI. |
| 221 // TODO(devlin): Transition these. |
| 222 break; |
| 223 case EventType.INSTALLED: |
| 224 case EventType.LOADED: |
| 225 case EventType.UNLOADED: |
| 226 case EventType.ERROR_ADDED: |
| 227 if (eventData.extensionInfo) |
| 228 this.updateExtension_(eventData.extensionInfo); |
| 229 break; |
| 230 case EventType.UNINSTALLED: |
| 231 var childNode = $(eventData.item_id); |
| 232 childNode.parentNode.removeChild(childNode); |
| 233 break; |
| 234 default: |
| 235 assertNotReached(); |
| 236 } |
| 237 }.bind(this)); |
| 238 }, |
| 239 |
| 240 /** |
209 * Updates the extensions on the page. | 241 * Updates the extensions on the page. |
210 * @param {boolean} incognitoAvailable Whether or not incognito is allowed. | 242 * @param {boolean} incognitoAvailable Whether or not incognito is allowed. |
211 * @param {boolean} enableAppInfoDialog Whether or not the app info dialog | 243 * @param {boolean} enableAppInfoDialog Whether or not the app info dialog |
212 * is enabled. | 244 * is enabled. |
213 * @return {Promise} A promise that is resolved once the extensions data is | 245 * @return {Promise} A promise that is resolved once the extensions data is |
214 * fully updated. | 246 * fully updated. |
215 */ | 247 */ |
216 updateExtensionsData: function(incognitoAvailable, enableAppInfoDialog) { | 248 updateExtensionsData: function(incognitoAvailable, enableAppInfoDialog) { |
217 // If we start to need more information about the extension configuration, | 249 // If we start to need more information about the extension configuration, |
218 // consider passing in the full object from the ExtensionSettings. | 250 // consider passing in the full object from the ExtensionSettings. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 * @private | 295 * @private |
264 */ | 296 */ |
265 showExtensionNodes_: function() { | 297 showExtensionNodes_: function() { |
266 // Remove the rows from |focusGrid_| without destroying them. | 298 // Remove the rows from |focusGrid_| without destroying them. |
267 this.focusGrid_.rows.length = 0; | 299 this.focusGrid_.rows.length = 0; |
268 | 300 |
269 // Any node that is not updated will be removed. | 301 // Any node that is not updated will be removed. |
270 var seenIds = []; | 302 var seenIds = []; |
271 | 303 |
272 // Iterate over the extension data and add each item to the list. | 304 // Iterate over the extension data and add each item to the list. |
273 this.extensions_.forEach(function(extension, i) { | 305 this.extensions_.forEach(function(extension) { |
274 var nextExt = this.extensions_[i + 1]; | |
275 var node = $(extension.id); | |
276 seenIds.push(extension.id); | 306 seenIds.push(extension.id); |
277 | 307 this.updateExtension_(extension); |
278 if (node) | |
279 this.updateNode_(extension, node); | |
280 else | |
281 this.createNode_(extension, nextExt ? $(nextExt.id) : null); | |
282 }, this); | 308 }, this); |
283 | 309 |
284 // Remove extensions that are no longer installed. | 310 // Remove extensions that are no longer installed. |
285 var nodes = document.querySelectorAll('.extension-list-item-wrapper[id]'); | 311 var nodes = document.querySelectorAll('.extension-list-item-wrapper[id]'); |
286 for (var i = 0; i < nodes.length; ++i) { | 312 for (var i = 0; i < nodes.length; ++i) { |
287 var node = nodes[i]; | 313 var node = nodes[i]; |
288 if (seenIds.indexOf(node.id) < 0) { | 314 if (seenIds.indexOf(node.id) < 0) { |
289 if (node.contains(document.activeElement)) { | 315 if (node.contains(document.activeElement)) { |
290 var focusableNode = nodes[i + 1] || nodes[i - 1]; | 316 var focusableNode = nodes[i + 1] || nodes[i - 1]; |
291 if (focusableNode) { | 317 if (focusableNode) { |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 var self = this; | 1003 var self = this; |
978 $('overlay').addEventListener('cancelOverlay', function f() { | 1004 $('overlay').addEventListener('cancelOverlay', function f() { |
979 self.optionsShown_ = false; | 1005 self.optionsShown_ = false; |
980 $('overlay').removeEventListener('cancelOverlay', f); | 1006 $('overlay').removeEventListener('cancelOverlay', f); |
981 }); | 1007 }); |
982 | 1008 |
983 // TODO(dbeam): why do we need to focus <extensionoptions> before and | 1009 // TODO(dbeam): why do we need to focus <extensionoptions> before and |
984 // after its showing animation? Makes very little sense to me. | 1010 // after its showing animation? Makes very little sense to me. |
985 overlay.setInitialFocus(); | 1011 overlay.setInitialFocus(); |
986 }, | 1012 }, |
| 1013 |
| 1014 /** |
| 1015 * Updates the node for the extension. |
| 1016 * @param {!ExtensionInfo} extension The information about the extension to |
| 1017 * update. |
| 1018 * @private |
| 1019 */ |
| 1020 updateExtension_: function(extension) { |
| 1021 var node = /** @type {ExtensionFocusRow} */ ($(extension.id)); |
| 1022 if (node) { |
| 1023 this.updateNode_(extension, node); |
| 1024 } else { |
| 1025 var nextExt = this.extensions_[this.extensions_.indexOf(extension) + 1]; |
| 1026 this.createNode_(extension, nextExt ? $(nextExt.id) : null); |
| 1027 } |
| 1028 } |
987 }; | 1029 }; |
988 | 1030 |
989 return { | 1031 return { |
990 ExtensionList: ExtensionList | 1032 ExtensionList: ExtensionList |
991 }; | 1033 }; |
992 }); | 1034 }); |
OLD | NEW |