mobile/android/chrome/content/aboutAddons.js

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict";
michael@0 6
michael@0 7 let Ci = Components.interfaces, Cc = Components.classes, Cu = Components.utils;
michael@0 8
michael@0 9 Cu.import("resource://gre/modules/Services.jsm")
michael@0 10 Cu.import("resource://gre/modules/AddonManager.jsm");
michael@0 11 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 12
michael@0 13 const AMO_ICON = "chrome://browser/skin/images/amo-logo.png";
michael@0 14
michael@0 15 let gStringBundle = Services.strings.createBundle("chrome://browser/locale/aboutAddons.properties");
michael@0 16
michael@0 17 XPCOMUtils.defineLazyGetter(window, "gChromeWin", function()
michael@0 18 window.QueryInterface(Ci.nsIInterfaceRequestor)
michael@0 19 .getInterface(Ci.nsIWebNavigation)
michael@0 20 .QueryInterface(Ci.nsIDocShellTreeItem)
michael@0 21 .rootTreeItem
michael@0 22 .QueryInterface(Ci.nsIInterfaceRequestor)
michael@0 23 .getInterface(Ci.nsIDOMWindow)
michael@0 24 .QueryInterface(Ci.nsIDOMChromeWindow));
michael@0 25
michael@0 26 var ContextMenus = {
michael@0 27 target: null,
michael@0 28
michael@0 29 init: function() {
michael@0 30 document.addEventListener("contextmenu", this, false);
michael@0 31
michael@0 32 document.getElementById("contextmenu-enable").addEventListener("click", ContextMenus.enable.bind(this), false);
michael@0 33 document.getElementById("contextmenu-disable").addEventListener("click", ContextMenus.disable.bind(this), false);
michael@0 34 document.getElementById("contextmenu-uninstall").addEventListener("click", ContextMenus.uninstall.bind(this), false);
michael@0 35
michael@0 36 // XXX - Hack to fix bug 985867 for now
michael@0 37 document.addEventListener("touchstart", function() { });
michael@0 38 },
michael@0 39
michael@0 40 handleEvent: function(event) {
michael@0 41 // store the target of context menu events so that we know which app to act on
michael@0 42 this.target = event.target;
michael@0 43 while (!this.target.hasAttribute("contextmenu")) {
michael@0 44 this.target = this.target.parentNode;
michael@0 45 }
michael@0 46
michael@0 47 if (!this.target) {
michael@0 48 document.getElementById("contextmenu-enable").setAttribute("hidden", "true");
michael@0 49 document.getElementById("contextmenu-disable").setAttribute("hidden", "true");
michael@0 50 document.getElementById("contextmenu-uninstall").setAttribute("hidden", "true");
michael@0 51 return;
michael@0 52 }
michael@0 53
michael@0 54 let addon = this.target.addon;
michael@0 55 if (addon.scope == AddonManager.SCOPE_APPLICATION) {
michael@0 56 document.getElementById("contextmenu-uninstall").setAttribute("hidden", "true");
michael@0 57 } else {
michael@0 58 document.getElementById("contextmenu-uninstall").removeAttribute("hidden");
michael@0 59 }
michael@0 60
michael@0 61 let enabled = this.target.getAttribute("isDisabled") != "true";
michael@0 62 if (enabled) {
michael@0 63 document.getElementById("contextmenu-enable").setAttribute("hidden", "true");
michael@0 64 document.getElementById("contextmenu-disable").removeAttribute("hidden");
michael@0 65 } else {
michael@0 66 document.getElementById("contextmenu-enable").removeAttribute("hidden");
michael@0 67 document.getElementById("contextmenu-disable").setAttribute("hidden", "true");
michael@0 68 }
michael@0 69 },
michael@0 70
michael@0 71 enable: function(event) {
michael@0 72 Addons.setEnabled(true, this.target.addon);
michael@0 73 this.target = null;
michael@0 74 },
michael@0 75
michael@0 76 disable: function (event) {
michael@0 77 Addons.setEnabled(false, this.target.addon);
michael@0 78 this.target = null;
michael@0 79 },
michael@0 80
michael@0 81 uninstall: function (event) {
michael@0 82 Addons.uninstall(this.target.addon);
michael@0 83 this.target = null;
michael@0 84 }
michael@0 85 }
michael@0 86
michael@0 87 function init() {
michael@0 88 window.addEventListener("popstate", onPopState, false);
michael@0 89
michael@0 90 AddonManager.addInstallListener(Addons);
michael@0 91 AddonManager.addAddonListener(Addons);
michael@0 92 Addons.init();
michael@0 93 showList();
michael@0 94 ContextMenus.init();
michael@0 95
michael@0 96 document.getElementById("header-button").addEventListener("click", openLink, false);
michael@0 97 }
michael@0 98
michael@0 99
michael@0 100 function uninit() {
michael@0 101 AddonManager.removeInstallListener(Addons);
michael@0 102 AddonManager.removeAddonListener(Addons);
michael@0 103 }
michael@0 104
michael@0 105 function openLink(aEvent) {
michael@0 106 try {
michael@0 107 let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
michael@0 108
michael@0 109 let url = formatter.formatURLPref(aEvent.currentTarget.getAttribute("pref"));
michael@0 110 let BrowserApp = gChromeWin.BrowserApp;
michael@0 111 BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id });
michael@0 112 } catch (ex) {}
michael@0 113 }
michael@0 114
michael@0 115 function onPopState(aEvent) {
michael@0 116 // Called when back/forward is used to change the state of the page
michael@0 117 if (aEvent.state) {
michael@0 118 // Show the detail page for an addon
michael@0 119 Addons.showDetails(Addons._getElementForAddon(aEvent.state.id));
michael@0 120 } else {
michael@0 121 // Clear any previous detail addon
michael@0 122 let detailItem = document.querySelector("#addons-details > .addon-item");
michael@0 123 detailItem.addon = null;
michael@0 124
michael@0 125 showList();
michael@0 126 }
michael@0 127 }
michael@0 128
michael@0 129 function showList() {
michael@0 130 // Hide the detail page and show the list
michael@0 131 let details = document.querySelector("#addons-details");
michael@0 132 details.style.display = "none";
michael@0 133 let list = document.querySelector("#addons-list");
michael@0 134 list.style.display = "block";
michael@0 135 }
michael@0 136
michael@0 137 var Addons = {
michael@0 138 _restartCount: 0,
michael@0 139
michael@0 140 _createItem: function _createItem(aAddon) {
michael@0 141 let outer = document.createElement("div");
michael@0 142 outer.setAttribute("addonID", aAddon.id);
michael@0 143 outer.className = "addon-item list-item";
michael@0 144 outer.setAttribute("role", "button");
michael@0 145 outer.setAttribute("contextmenu", "addonmenu");
michael@0 146 outer.addEventListener("click", function() {
michael@0 147 this.showDetails(outer);
michael@0 148 history.pushState({ id: aAddon.id }, document.title);
michael@0 149 }.bind(this), true);
michael@0 150
michael@0 151 let img = document.createElement("img");
michael@0 152 img.className = "icon";
michael@0 153 img.setAttribute("src", aAddon.iconURL || AMO_ICON);
michael@0 154 outer.appendChild(img);
michael@0 155
michael@0 156 let inner = document.createElement("div");
michael@0 157 inner.className = "inner";
michael@0 158
michael@0 159 let details = document.createElement("div");
michael@0 160 details.className = "details";
michael@0 161 inner.appendChild(details);
michael@0 162
michael@0 163 let titlePart = document.createElement("div");
michael@0 164 titlePart.textContent = aAddon.name;
michael@0 165 titlePart.className = "title";
michael@0 166 details.appendChild(titlePart);
michael@0 167
michael@0 168 let versionPart = document.createElement("div");
michael@0 169 versionPart.textContent = aAddon.version;
michael@0 170 versionPart.className = "version";
michael@0 171 details.appendChild(versionPart);
michael@0 172
michael@0 173 if ("description" in aAddon) {
michael@0 174 let descPart = document.createElement("div");
michael@0 175 descPart.textContent = aAddon.description;
michael@0 176 descPart.className = "description";
michael@0 177 inner.appendChild(descPart);
michael@0 178 }
michael@0 179
michael@0 180 outer.appendChild(inner);
michael@0 181 return outer;
michael@0 182 },
michael@0 183
michael@0 184 _createBrowseItem: function _createBrowseItem() {
michael@0 185 let outer = document.createElement("div");
michael@0 186 outer.className = "addon-item list-item";
michael@0 187 outer.setAttribute("role", "button");
michael@0 188 outer.setAttribute("pref", "extensions.getAddons.browseAddons");
michael@0 189 outer.addEventListener("click", openLink, true);
michael@0 190
michael@0 191 let img = document.createElement("img");
michael@0 192 img.className = "icon";
michael@0 193 img.setAttribute("src", AMO_ICON);
michael@0 194 outer.appendChild(img);
michael@0 195
michael@0 196 let inner = document.createElement("div");
michael@0 197 inner.className = "inner";
michael@0 198
michael@0 199 let title = document.createElement("div");
michael@0 200 title.id = "browse-title";
michael@0 201 title.className = "title";
michael@0 202 title.textContent = gStringBundle.GetStringFromName("addons.browseAll");
michael@0 203 inner.appendChild(title);
michael@0 204
michael@0 205 outer.appendChild(inner);
michael@0 206 return outer;
michael@0 207 },
michael@0 208
michael@0 209 _createItemForAddon: function _createItemForAddon(aAddon) {
michael@0 210 let appManaged = (aAddon.scope == AddonManager.SCOPE_APPLICATION);
michael@0 211 let opType = this._getOpTypeForOperations(aAddon.pendingOperations);
michael@0 212 let updateable = (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE) > 0;
michael@0 213 let uninstallable = (aAddon.permissions & AddonManager.PERM_CAN_UNINSTALL) > 0;
michael@0 214
michael@0 215 let blocked = "";
michael@0 216 switch(aAddon.blocklistState) {
michael@0 217 case Ci.nsIBlocklistService.STATE_BLOCKED:
michael@0 218 blocked = "blocked";
michael@0 219 break;
michael@0 220 case Ci.nsIBlocklistService.STATE_SOFTBLOCKED:
michael@0 221 blocked = "softBlocked";
michael@0 222 break;
michael@0 223 case Ci.nsIBlocklistService.STATE_OUTDATED:
michael@0 224 blocked = "outdated";
michael@0 225 break;
michael@0 226 }
michael@0 227
michael@0 228 let item = this._createItem(aAddon);
michael@0 229 item.setAttribute("isDisabled", !aAddon.isActive);
michael@0 230 item.setAttribute("opType", opType);
michael@0 231 item.setAttribute("updateable", updateable);
michael@0 232 if (blocked)
michael@0 233 item.setAttribute("blockedStatus", blocked);
michael@0 234 item.setAttribute("optionsURL", aAddon.optionsURL || "");
michael@0 235 item.addon = aAddon;
michael@0 236
michael@0 237 return item;
michael@0 238 },
michael@0 239
michael@0 240 _getElementForAddon: function(aKey) {
michael@0 241 let list = document.getElementById("addons-list");
michael@0 242 let element = list.querySelector("div[addonID=" + aKey.quote() + "]");
michael@0 243 return element;
michael@0 244 },
michael@0 245
michael@0 246 init: function init() {
michael@0 247 let self = this;
michael@0 248 AddonManager.getAddonsByTypes(["extension", "theme", "locale"], function(aAddons) {
michael@0 249 // Clear all content before filling the addons
michael@0 250 let list = document.getElementById("addons-list");
michael@0 251 list.innerHTML = "";
michael@0 252
michael@0 253 for (let i=0; i<aAddons.length; i++) {
michael@0 254 let item = self._createItemForAddon(aAddons[i]);
michael@0 255 list.appendChild(item);
michael@0 256 }
michael@0 257
michael@0 258 // Add a "Browse all Firefox Add-ons" item to the bottom of the list.
michael@0 259 let browseItem = self._createBrowseItem();
michael@0 260 list.appendChild(browseItem);
michael@0 261 });
michael@0 262
michael@0 263 document.getElementById("uninstall-btn").addEventListener("click", Addons.uninstallCurrent.bind(this), false);
michael@0 264 document.getElementById("cancel-btn").addEventListener("click", Addons.cancelUninstall.bind(this), false);
michael@0 265 document.getElementById("disable-btn").addEventListener("click", Addons.disable.bind(this), false);
michael@0 266 document.getElementById("enable-btn").addEventListener("click", Addons.enable.bind(this), false);
michael@0 267 },
michael@0 268
michael@0 269 _getOpTypeForOperations: function _getOpTypeForOperations(aOperations) {
michael@0 270 if (aOperations & AddonManager.PENDING_UNINSTALL)
michael@0 271 return "needs-uninstall";
michael@0 272 if (aOperations & AddonManager.PENDING_ENABLE)
michael@0 273 return "needs-enable";
michael@0 274 if (aOperations & AddonManager.PENDING_DISABLE)
michael@0 275 return "needs-disable";
michael@0 276 return "";
michael@0 277 },
michael@0 278
michael@0 279 showDetails: function showDetails(aListItem) {
michael@0 280 // This function removes and returns the text content of aNode without
michael@0 281 // removing any child elements. Removing the text nodes ensures any XBL
michael@0 282 // bindings apply properly.
michael@0 283 function stripTextNodes(aNode) {
michael@0 284 var text = "";
michael@0 285 for (var i = 0; i < aNode.childNodes.length; i++) {
michael@0 286 if (aNode.childNodes[i].nodeType != document.ELEMENT_NODE) {
michael@0 287 text += aNode.childNodes[i].textContent;
michael@0 288 aNode.removeChild(aNode.childNodes[i--]);
michael@0 289 } else {
michael@0 290 text += stripTextNodes(aNode.childNodes[i]);
michael@0 291 }
michael@0 292 }
michael@0 293 return text;
michael@0 294 }
michael@0 295
michael@0 296 let detailItem = document.querySelector("#addons-details > .addon-item");
michael@0 297 detailItem.setAttribute("isDisabled", aListItem.getAttribute("isDisabled"));
michael@0 298 detailItem.setAttribute("opType", aListItem.getAttribute("opType"));
michael@0 299 detailItem.setAttribute("optionsURL", aListItem.getAttribute("optionsURL"));
michael@0 300 let addon = detailItem.addon = aListItem.addon;
michael@0 301
michael@0 302 let favicon = document.querySelector("#addons-details > .addon-item .icon");
michael@0 303 favicon.setAttribute("src", addon.iconURL || AMO_ICON);
michael@0 304
michael@0 305 detailItem.querySelector(".title").textContent = addon.name;
michael@0 306 detailItem.querySelector(".version").textContent = addon.version;
michael@0 307 detailItem.querySelector(".description-full").textContent = addon.description;
michael@0 308 detailItem.querySelector(".status-uninstalled").textContent =
michael@0 309 gStringBundle.formatStringFromName("addonStatus.uninstalled", [addon.name], 1);
michael@0 310
michael@0 311 let enableBtn = document.getElementById("enable-btn");
michael@0 312 if (addon.appDisabled)
michael@0 313 enableBtn.setAttribute("disabled", "true");
michael@0 314 else
michael@0 315 enableBtn.removeAttribute("disabled");
michael@0 316
michael@0 317 let uninstallBtn = document.getElementById("uninstall-btn");
michael@0 318 if (addon.scope == AddonManager.SCOPE_APPLICATION)
michael@0 319 uninstallBtn.setAttribute("disabled", "true");
michael@0 320 else
michael@0 321 uninstallBtn.removeAttribute("disabled");
michael@0 322
michael@0 323 let box = document.querySelector("#addons-details > .addon-item .options-box");
michael@0 324 box.innerHTML = "";
michael@0 325
michael@0 326 // Retrieve the extensions preferences
michael@0 327 try {
michael@0 328 let optionsURL = aListItem.getAttribute("optionsURL");
michael@0 329 let xhr = new XMLHttpRequest();
michael@0 330 xhr.open("GET", optionsURL, false);
michael@0 331 xhr.send();
michael@0 332 if (xhr.responseXML) {
michael@0 333 // Only allow <setting> for now
michael@0 334 let settings = xhr.responseXML.querySelectorAll(":root > setting");
michael@0 335 if (settings.length > 0) {
michael@0 336 for (let i = 0; i < settings.length; i++) {
michael@0 337 var setting = settings[i];
michael@0 338 var desc = stripTextNodes(setting).trim();
michael@0 339 if (!setting.hasAttribute("desc"))
michael@0 340 setting.setAttribute("desc", desc);
michael@0 341 box.appendChild(setting);
michael@0 342 }
michael@0 343 // Send an event so add-ons can prepopulate any non-preference based
michael@0 344 // settings
michael@0 345 let event = document.createEvent("Events");
michael@0 346 event.initEvent("AddonOptionsLoad", true, false);
michael@0 347 window.dispatchEvent(event);
michael@0 348
michael@0 349 // Also send a notification to match the behavior of desktop Firefox
michael@0 350 let id = aListItem.getAttribute("addonID");
michael@0 351 Services.obs.notifyObservers(document, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED, id);
michael@0 352 } else {
michael@0 353 // No options, so hide the header and reset the list item
michael@0 354 detailItem.setAttribute("optionsURL", "");
michael@0 355 aListItem.setAttribute("optionsURL", "");
michael@0 356 }
michael@0 357 }
michael@0 358 } catch (e) { }
michael@0 359
michael@0 360 let list = document.querySelector("#addons-list");
michael@0 361 list.style.display = "none";
michael@0 362 let details = document.querySelector("#addons-details");
michael@0 363 details.style.display = "block";
michael@0 364 },
michael@0 365
michael@0 366 setEnabled: function setEnabled(aValue, aAddon) {
michael@0 367 let detailItem = document.querySelector("#addons-details > .addon-item");
michael@0 368 let addon = aAddon || detailItem.addon;
michael@0 369 if (!addon)
michael@0 370 return;
michael@0 371
michael@0 372 let listItem = this._getElementForAddon(addon.id);
michael@0 373
michael@0 374 let opType;
michael@0 375 if (addon.type == "theme") {
michael@0 376 if (aValue) {
michael@0 377 // We can have only one theme enabled, so disable the current one if any
michael@0 378 let list = document.getElementById("addons-list");
michael@0 379 let item = list.firstElementChild;
michael@0 380 while (item) {
michael@0 381 if (item.addon && (item.addon.type == "theme") && (item.addon.isActive)) {
michael@0 382 item.addon.userDisabled = true;
michael@0 383 item.setAttribute("isDisabled", true);
michael@0 384 break;
michael@0 385 }
michael@0 386 item = item.nextSibling;
michael@0 387 }
michael@0 388 }
michael@0 389 addon.userDisabled = !aValue;
michael@0 390 } else if (addon.type == "locale") {
michael@0 391 addon.userDisabled = !aValue;
michael@0 392 } else {
michael@0 393 addon.userDisabled = !aValue;
michael@0 394 opType = this._getOpTypeForOperations(addon.pendingOperations);
michael@0 395
michael@0 396 if ((addon.pendingOperations & AddonManager.PENDING_ENABLE) ||
michael@0 397 (addon.pendingOperations & AddonManager.PENDING_DISABLE)) {
michael@0 398 this.showRestart();
michael@0 399 } else if (listItem && /needs-(enable|disable)/.test(listItem.getAttribute("opType"))) {
michael@0 400 this.hideRestart();
michael@0 401 }
michael@0 402 }
michael@0 403
michael@0 404 if (addon == detailItem.addon) {
michael@0 405 detailItem.setAttribute("isDisabled", !aValue);
michael@0 406 if (opType)
michael@0 407 detailItem.setAttribute("opType", opType);
michael@0 408 else
michael@0 409 detailItem.removeAttribute("opType");
michael@0 410 }
michael@0 411
michael@0 412 // Sync to the list item
michael@0 413 if (listItem) {
michael@0 414 listItem.setAttribute("isDisabled", !aValue);
michael@0 415 if (opType)
michael@0 416 listItem.setAttribute("opType", opType);
michael@0 417 else
michael@0 418 listItem.removeAttribute("opType");
michael@0 419 }
michael@0 420 },
michael@0 421
michael@0 422 enable: function enable() {
michael@0 423 this.setEnabled(true);
michael@0 424 },
michael@0 425
michael@0 426 disable: function disable() {
michael@0 427 this.setEnabled(false);
michael@0 428 },
michael@0 429
michael@0 430 uninstallCurrent: function uninstallCurrent() {
michael@0 431 let detailItem = document.querySelector("#addons-details > .addon-item");
michael@0 432
michael@0 433 let addon = detailItem.addon;
michael@0 434 if (!addon)
michael@0 435 return;
michael@0 436
michael@0 437 this.uninstall(addon);
michael@0 438 },
michael@0 439
michael@0 440 uninstall: function uninstall(aAddon) {
michael@0 441 let list = document.getElementById("addons-list");
michael@0 442
michael@0 443 if (!aAddon) {
michael@0 444 return;
michael@0 445 }
michael@0 446
michael@0 447 let listItem = this._getElementForAddon(aAddon.id);
michael@0 448
michael@0 449 aAddon.uninstall();
michael@0 450 if (aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
michael@0 451 this.showRestart();
michael@0 452
michael@0 453 // A disabled addon doesn't need a restart so it has no pending ops and
michael@0 454 // can't be cancelled
michael@0 455 let opType = this._getOpTypeForOperations(aAddon.pendingOperations);
michael@0 456 if (!aAddon.isActive && opType == "")
michael@0 457 opType = "needs-uninstall";
michael@0 458
michael@0 459 detailItem.setAttribute("opType", opType);
michael@0 460 listItem.setAttribute("opType", opType);
michael@0 461 } else {
michael@0 462 list.removeChild(listItem);
michael@0 463 history.back();
michael@0 464 }
michael@0 465 },
michael@0 466
michael@0 467 cancelUninstall: function ev_cancelUninstall() {
michael@0 468 let detailItem = document.querySelector("#addons-details > .addon-item");
michael@0 469 let addon = detailItem.addon;
michael@0 470 if (!addon)
michael@0 471 return;
michael@0 472
michael@0 473 addon.cancelUninstall();
michael@0 474 this.hideRestart();
michael@0 475
michael@0 476 let opType = this._getOpTypeForOperations(addon.pendingOperations);
michael@0 477 detailItem.setAttribute("opType", opType);
michael@0 478
michael@0 479 let listItem = this._getElementForAddon(addon.id);
michael@0 480 listItem.setAttribute("opType", opType);
michael@0 481 },
michael@0 482
michael@0 483 showRestart: function showRestart() {
michael@0 484 this._restartCount++;
michael@0 485 gChromeWin.XPInstallObserver.showRestartPrompt();
michael@0 486 },
michael@0 487
michael@0 488 hideRestart: function hideRestart() {
michael@0 489 this._restartCount--;
michael@0 490 if (this._restartCount == 0)
michael@0 491 gChromeWin.XPInstallObserver.hideRestartPrompt();
michael@0 492 },
michael@0 493
michael@0 494 onEnabled: function(aAddon) {
michael@0 495 let listItem = this._getElementForAddon(aAddon.id);
michael@0 496 if (!listItem)
michael@0 497 return;
michael@0 498
michael@0 499 // Reload the details to pick up any options now that it's enabled.
michael@0 500 listItem.setAttribute("optionsURL", aAddon.optionsURL || "");
michael@0 501 let detailItem = document.querySelector("#addons-details > .addon-item");
michael@0 502 if (aAddon == detailItem.addon)
michael@0 503 this.showDetails(listItem);
michael@0 504 },
michael@0 505
michael@0 506 onInstallEnded: function(aInstall, aAddon) {
michael@0 507 let needsRestart = false;
michael@0 508 if (aInstall.existingAddon && (aInstall.existingAddon.pendingOperations & AddonManager.PENDING_UPGRADE))
michael@0 509 needsRestart = true;
michael@0 510 else if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL)
michael@0 511 needsRestart = true;
michael@0 512
michael@0 513 let list = document.getElementById("addons-list");
michael@0 514 let element = this._getElementForAddon(aAddon.id);
michael@0 515 if (!element) {
michael@0 516 element = this._createItemForAddon(aAddon);
michael@0 517 list.insertBefore(element, list.firstElementChild);
michael@0 518 }
michael@0 519
michael@0 520 if (needsRestart)
michael@0 521 element.setAttribute("opType", "needs-restart");
michael@0 522 },
michael@0 523
michael@0 524 onInstallFailed: function(aInstall) {
michael@0 525 },
michael@0 526
michael@0 527 onDownloadProgress: function xpidm_onDownloadProgress(aInstall) {
michael@0 528 },
michael@0 529
michael@0 530 onDownloadFailed: function(aInstall) {
michael@0 531 },
michael@0 532
michael@0 533 onDownloadCancelled: function(aInstall) {
michael@0 534 }
michael@0 535 }
michael@0 536
michael@0 537 window.addEventListener("load", init, false);
michael@0 538 window.addEventListener("unload", uninit, false);

mercurial