1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,615 @@ 1.4 +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 +'use strict'; 1.9 + 1.10 +Cu.import("resource://gre/modules/Services.jsm"); 1.11 +let gAppUpdater; 1.12 + 1.13 +let AboutFlyoutPanel = { 1.14 + init: function() { 1.15 + if (this._isInitialized) { 1.16 + Cu.reportError("Attempted to initialize AboutFlyoutPanel more than once"); 1.17 + } 1.18 + 1.19 + this._isInitialized = true; 1.20 + 1.21 + let self = this; 1.22 + this._elements = {}; 1.23 + [ 1.24 + ['versionLabel', 'about-version-label'], 1.25 + ['AboutFlyoutPanel', 'about-flyoutpanel'], 1.26 + ].forEach(function(aElement) { 1.27 + let [name, id] = aElement; 1.28 + XPCOMUtils.defineLazyGetter(self._elements, name, function() { 1.29 + return document.getElementById(id); 1.30 + }); 1.31 + }); 1.32 + 1.33 + this._topmostElement = this._elements.AboutFlyoutPanel; 1.34 + 1.35 + // Include the build ID if this is an "a#" (nightly or aurora) build 1.36 + let version = Services.appinfo.version; 1.37 + if (/a\d+$/.test(version)) { 1.38 + let buildID = Services.appinfo.appBuildID; 1.39 + let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + 1.40 + "-" + buildID.slice(6,8); 1.41 + this._elements.versionLabel.textContent +=" (" + buildDate + ")"; 1.42 + } 1.43 + 1.44 + window.addEventListener('MozFlyoutPanelShowing', this, false); 1.45 + window.addEventListener('MozFlyoutPanelHiding', this, false); 1.46 + 1.47 +#if MOZ_UPDATE_CHANNEL != release 1.48 + let defaults = Services.prefs.getDefaultBranch(""); 1.49 + let channelLabel = document.getElementById("currentChannel"); 1.50 + channelLabel.value = defaults.getCharPref("app.update.channel"); 1.51 +#endif 1.52 + }, 1.53 + 1.54 + onPolicyClick: function(aEvent) { 1.55 + if (aEvent.button != 0) { 1.56 + return; 1.57 + } 1.58 + let url = Services.urlFormatter.formatURLPref("app.privacyURL"); 1.59 + BrowserUI.addAndShowTab(url, Browser.selectedTab); 1.60 + }, 1.61 + 1.62 + handleEvent: function(aEvent) { 1.63 + switch (aEvent.type) { 1.64 + case 'MozFlyoutPanelShowing': 1.65 +#ifdef MOZ_UPDATER 1.66 + this.appUpdater = new appUpdater(); 1.67 + gAppUpdater = this.appUpdater; 1.68 +#endif 1.69 + break; 1.70 + case 'MozFlyoutPanelHiding': 1.71 +#ifdef MOZ_UPDATER 1.72 + onUnload(); 1.73 +#endif 1.74 + break; 1.75 + } 1.76 + } 1.77 +}; 1.78 + 1.79 +#ifdef MOZ_UPDATER 1.80 +function onUnload(aEvent) { 1.81 + if (!gAppUpdater) { 1.82 + return; 1.83 + } 1.84 + 1.85 + if (gAppUpdater.isChecking) 1.86 + gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK); 1.87 + // Safe to call even when there isn't a download in progress. 1.88 + gAppUpdater.removeDownloadListener(); 1.89 + gAppUpdater = null; 1.90 + AboutFlyoutPanel.appUpdater = null; 1.91 +} 1.92 + 1.93 +function appUpdater() 1.94 +{ 1.95 + this.updateDeck = document.getElementById("updateDeck"); 1.96 + 1.97 + XPCOMUtils.defineLazyServiceGetter(this, "aus", 1.98 + "@mozilla.org/updates/update-service;1", 1.99 + "nsIApplicationUpdateService"); 1.100 + XPCOMUtils.defineLazyServiceGetter(this, "checker", 1.101 + "@mozilla.org/updates/update-checker;1", 1.102 + "nsIUpdateChecker"); 1.103 + XPCOMUtils.defineLazyServiceGetter(this, "um", 1.104 + "@mozilla.org/updates/update-manager;1", 1.105 + "nsIUpdateManager"); 1.106 + 1.107 + this.bundle = Services.strings. 1.108 + createBundle("chrome://browser/locale/browser.properties"); 1.109 + 1.110 + this.updateBtn = document.getElementById("updateButton"); 1.111 + 1.112 + // The button label value must be set so its height is correct. 1.113 + this.setupUpdateButton("update.checkInsideButton"); 1.114 + 1.115 + let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual"); 1.116 + let manualLink = document.getElementById("manualLink"); 1.117 + manualLink.value = manualURL; 1.118 + manualLink.href = manualURL; 1.119 + document.getElementById("failedLink").href = manualURL; 1.120 + 1.121 + if (this.updateDisabledAndLocked) { 1.122 + this.selectPanel("adminDisabled"); 1.123 + return; 1.124 + } 1.125 + 1.126 + if (this.isPending || this.isApplied) { 1.127 + this.setupUpdateButton("update.restart." + 1.128 + (this.isMajor ? "upgradeButton" : "updateButton")); 1.129 + return; 1.130 + } 1.131 + 1.132 + if (this.aus.isOtherInstanceHandlingUpdates) { 1.133 + this.selectPanel("otherInstanceHandlingUpdates"); 1.134 + return; 1.135 + } 1.136 + 1.137 + if (this.isDownloading) { 1.138 + this.startDownload(); 1.139 + return; 1.140 + } 1.141 + 1.142 + if (this.updateEnabled && this.updateAuto) { 1.143 + this.selectPanel("checkingForUpdates"); 1.144 + this.isChecking = true; 1.145 + this.checker.checkForUpdates(this.updateCheckListener, true); 1.146 + return; 1.147 + } 1.148 +} 1.149 + 1.150 +appUpdater.prototype = 1.151 +{ 1.152 + // true when there is an update check in progress. 1.153 + isChecking: false, 1.154 + 1.155 + // true when there is an update already staged / ready to be applied. 1.156 + get isPending() { 1.157 + if (this.update) { 1.158 + return this.update.state == "pending" || 1.159 + this.update.state == "pending-service"; 1.160 + } 1.161 + return this.um.activeUpdate && 1.162 + (this.um.activeUpdate.state == "pending" || 1.163 + this.um.activeUpdate.state == "pending-service"); 1.164 + }, 1.165 + 1.166 + // true when there is an update already installed in the background. 1.167 + get isApplied() { 1.168 + if (this.update) 1.169 + return this.update.state == "applied" || 1.170 + this.update.state == "applied-service"; 1.171 + return this.um.activeUpdate && 1.172 + (this.um.activeUpdate.state == "applied" || 1.173 + this.um.activeUpdate.state == "applied-service"); 1.174 + }, 1.175 + 1.176 + // true when there is an update download in progress. 1.177 + get isDownloading() { 1.178 + if (this.update) 1.179 + return this.update.state == "downloading"; 1.180 + return this.um.activeUpdate && 1.181 + this.um.activeUpdate.state == "downloading"; 1.182 + }, 1.183 + 1.184 + // true when the update type is major. 1.185 + get isMajor() { 1.186 + if (this.update) 1.187 + return this.update.type == "major"; 1.188 + return this.um.activeUpdate.type == "major"; 1.189 + }, 1.190 + 1.191 + // true when updating is disabled by an administrator. 1.192 + get updateDisabledAndLocked() { 1.193 + return !this.updateEnabled && 1.194 + Services.prefs.prefIsLocked("app.update.enabled"); 1.195 + }, 1.196 + 1.197 + // true when updating is enabled. 1.198 + get updateEnabled() { 1.199 + let updatesEnabled = true; 1.200 + try { 1.201 + updatesEnabled = Services.prefs.getBoolPref("app.update.metro.enabled"); 1.202 + } 1.203 + catch (e) { } 1.204 + if (!updatesEnabled) { 1.205 + return false; 1.206 + } 1.207 + 1.208 + try { 1.209 + updatesEnabled = Services.prefs.getBoolPref("app.update.enabled") 1.210 + } 1.211 + catch (e) { } 1.212 + 1.213 + return updatesEnabled; 1.214 + }, 1.215 + 1.216 + // true when updating in background is enabled. 1.217 + get backgroundUpdateEnabled() { 1.218 + return this.updateEnabled && 1.219 + gAppUpdater.aus.canStageUpdates; 1.220 + }, 1.221 + 1.222 + // true when updating is automatic. 1.223 + get updateAuto() { 1.224 + try { 1.225 + return Services.prefs.getBoolPref("app.update.auto"); 1.226 + } 1.227 + catch (e) { } 1.228 + return true; // Firefox default is true 1.229 + }, 1.230 + 1.231 + /** 1.232 + * Sets the deck's selected panel. 1.233 + * 1.234 + * @param aChildID 1.235 + * The id of the deck's child to select. 1.236 + */ 1.237 + selectPanel: function(aChildID) { 1.238 + this.updateDeck.selectedPanel = document.getElementById(aChildID); 1.239 + this.updateBtn.disabled = (aChildID != "updateButtonBox"); 1.240 + }, 1.241 + 1.242 + /** 1.243 + * Sets the update button's label and accesskey. 1.244 + * 1.245 + * @param aKeyPrefix 1.246 + * The prefix for the properties file entry to use for setting the 1.247 + * label and accesskey. 1.248 + */ 1.249 + setupUpdateButton: function(aKeyPrefix) { 1.250 + this.updateBtn.label = this.bundle.GetStringFromName(aKeyPrefix + ".label"); 1.251 + this.updateBtn.accessKey = this.bundle.GetStringFromName(aKeyPrefix + ".accesskey"); 1.252 + if (!document.commandDispatcher.focusedElement || 1.253 + document.commandDispatcher.focusedElement == this.updateBtn) 1.254 + this.updateBtn.focus(); 1.255 + }, 1.256 + 1.257 + /** 1.258 + * Handles oncommand for the update button. 1.259 + */ 1.260 + buttonOnCommand: function() { 1.261 + if (this.isPending || this.isApplied) { 1.262 + // Notify all windows that an application quit has been requested. 1.263 + let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]. 1.264 + createInstance(Components.interfaces.nsISupportsPRBool); 1.265 + Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); 1.266 + 1.267 + // Something aborted the quit process. 1.268 + if (cancelQuit.data) 1.269 + return; 1.270 + 1.271 + let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]. 1.272 + getService(Components.interfaces.nsIAppStartup); 1.273 + 1.274 + // If already in safe mode restart in safe mode (bug 327119) 1.275 + if (Services.appinfo.inSafeMode) { 1.276 + appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit); 1.277 + return; 1.278 + } 1.279 + 1.280 + Services.metro.updatePending = true; 1.281 + appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit | 1.282 + Components.interfaces.nsIAppStartup.eRestartTouchEnvironment); 1.283 + return; 1.284 + } 1.285 + 1.286 + // XXX We can't create dialogs in metro, and we currently don't support addons, so 1.287 + // commenting this out for now. 1.288 + /* const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul"; 1.289 + // Firefox no longer displays a license for updates and the licenseURL check 1.290 + // is just in case a distibution does. 1.291 + if (this.update && (this.update.billboardURL || this.update.licenseURL || 1.292 + this.addons.length != 0)) { 1.293 + var ary = null; 1.294 + ary = Components.classes["@mozilla.org/supports-array;1"]. 1.295 + createInstance(Components.interfaces.nsISupportsArray); 1.296 + ary.AppendElement(this.update); 1.297 + var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no"; 1.298 + Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary); 1.299 + window.close(); 1.300 + return; 1.301 + }*/ 1.302 + 1.303 + this.selectPanel("checkingForUpdates"); 1.304 + this.isChecking = true; 1.305 + this.checker.checkForUpdates(this.updateCheckListener, true); 1.306 + }, 1.307 + 1.308 + /** 1.309 + * Implements nsIUpdateCheckListener. The methods implemented by 1.310 + * nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload 1.311 + * to make it clear which are used by each interface. 1.312 + */ 1.313 + updateCheckListener: { 1.314 + /** 1.315 + * See nsIUpdateService.idl 1.316 + */ 1.317 + onCheckComplete: function(aRequest, aUpdates, aUpdateCount) { 1.318 + gAppUpdater.isChecking = false; 1.319 + gAppUpdater.update = gAppUpdater.aus. 1.320 + selectUpdate(aUpdates, aUpdates.length); 1.321 + if (!gAppUpdater.update) { 1.322 + gAppUpdater.selectPanel("noUpdatesFound"); 1.323 + return; 1.324 + } 1.325 + 1.326 + if (!gAppUpdater.aus.canApplyUpdates) { 1.327 + gAppUpdater.selectPanel("manualUpdate"); 1.328 + return; 1.329 + } 1.330 + 1.331 + // Firefox no longer displays a license for updates and the licenseURL 1.332 + // check is just in case a distibution does. 1.333 + if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) { 1.334 + gAppUpdater.selectPanel("updateButtonBox"); 1.335 + gAppUpdater.setupUpdateButton("update.openUpdateUI." + 1.336 + (this.isMajor ? "upgradeButton" 1.337 + : "applyButton")); 1.338 + return; 1.339 + } 1.340 + 1.341 + if (!gAppUpdater.update.appVersion || 1.342 + Services.vc.compare(gAppUpdater.update.appVersion, 1.343 + Services.appinfo.version) == 0) { 1.344 + gAppUpdater.startDownload(); 1.345 + return; 1.346 + } 1.347 + 1.348 + gAppUpdater.checkAddonCompatibility(); 1.349 + }, 1.350 + 1.351 + /** 1.352 + * See nsIUpdateService.idl 1.353 + */ 1.354 + onError: function(aRequest, aUpdate) { 1.355 + // Errors in the update check are treated as no updates found. If the 1.356 + // update check fails repeatedly without a success the user will be 1.357 + // notified with the normal app update user interface so this is safe. 1.358 + gAppUpdater.isChecking = false; 1.359 + gAppUpdater.selectPanel("noUpdatesFound"); 1.360 + }, 1.361 + 1.362 + /** 1.363 + * See nsISupports.idl 1.364 + */ 1.365 + QueryInterface: function(aIID) { 1.366 + if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) && 1.367 + !aIID.equals(Components.interfaces.nsISupports)) 1.368 + throw Components.results.NS_ERROR_NO_INTERFACE; 1.369 + return this; 1.370 + } 1.371 + }, 1.372 + 1.373 + /** 1.374 + * Checks the compatibility of add-ons for the application update. 1.375 + */ 1.376 + checkAddonCompatibility: function() { 1.377 + try { 1.378 + var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID); 1.379 + } 1.380 + catch (e) { } 1.381 + 1.382 + var self = this; 1.383 + AddonManager.getAllAddons(function(aAddons) { 1.384 + self.addons = []; 1.385 + self.addonsCheckedCount = 0; 1.386 + aAddons.forEach(function(aAddon) { 1.387 + // Protect against code that overrides the add-ons manager and doesn't 1.388 + // implement the isCompatibleWith or the findUpdates method. 1.389 + if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) { 1.390 + let errMsg = "Add-on doesn't implement either the isCompatibleWith " + 1.391 + "or the findUpdates method!"; 1.392 + if (aAddon.id) 1.393 + errMsg += " Add-on ID: " + aAddon.id; 1.394 + Components.utils.reportError(errMsg); 1.395 + return; 1.396 + } 1.397 + 1.398 + // If an add-on isn't appDisabled and isn't userDisabled then it is 1.399 + // either active now or the user expects it to be active after the 1.400 + // restart. If that is the case and the add-on is not installed by the 1.401 + // application and is not compatible with the new application version 1.402 + // then the user should be warned that the add-on will become 1.403 + // incompatible. If an addon's type equals plugin it is skipped since 1.404 + // checking plugins compatibility information isn't supported and 1.405 + // getting the scope property of a plugin breaks in some environments 1.406 + // (see bug 566787). The hotfix add-on is also ignored as it shouldn't 1.407 + // block the user from upgrading. 1.408 + try { 1.409 + if (aAddon.type != "plugin" && aAddon.id != hotfixID && 1.410 + !aAddon.appDisabled && !aAddon.userDisabled && 1.411 + aAddon.scope != AddonManager.SCOPE_APPLICATION && 1.412 + aAddon.isCompatible && 1.413 + !aAddon.isCompatibleWith(self.update.appVersion, 1.414 + self.update.platformVersion)) 1.415 + self.addons.push(aAddon); 1.416 + } 1.417 + catch (e) { 1.418 + Components.utils.reportError(e); 1.419 + } 1.420 + }); 1.421 + self.addonsTotalCount = self.addons.length; 1.422 + if (self.addonsTotalCount == 0) { 1.423 + self.startDownload(); 1.424 + return; 1.425 + } 1.426 + 1.427 + self.checkAddonsForUpdates(); 1.428 + }); 1.429 + }, 1.430 + 1.431 + /** 1.432 + * Checks if there are updates for add-ons that are incompatible with the 1.433 + * application update. 1.434 + */ 1.435 + checkAddonsForUpdates: function() { 1.436 + this.addons.forEach(function(aAddon) { 1.437 + aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, 1.438 + this.update.appVersion, 1.439 + this.update.platformVersion); 1.440 + }, this); 1.441 + }, 1.442 + 1.443 + /** 1.444 + * See XPIProvider.jsm 1.445 + */ 1.446 + onCompatibilityUpdateAvailable: function(aAddon) { 1.447 + for (var i = 0; i < this.addons.length; ++i) { 1.448 + if (this.addons[i].id == aAddon.id) { 1.449 + this.addons.splice(i, 1); 1.450 + break; 1.451 + } 1.452 + } 1.453 + }, 1.454 + 1.455 + /** 1.456 + * See XPIProvider.jsm 1.457 + */ 1.458 + onUpdateAvailable: function(aAddon, aInstall) { 1.459 + if (!Services.blocklist.isAddonBlocklisted(aAddon, 1.460 + this.update.appVersion, 1.461 + this.update.platformVersion)) { 1.462 + // Compatibility or new version updates mean the same thing here. 1.463 + this.onCompatibilityUpdateAvailable(aAddon); 1.464 + } 1.465 + }, 1.466 + 1.467 + /** 1.468 + * See XPIProvider.jsm 1.469 + */ 1.470 + onUpdateFinished: function(aAddon) { 1.471 + ++this.addonsCheckedCount; 1.472 + 1.473 + if (this.addonsCheckedCount < this.addonsTotalCount) 1.474 + return; 1.475 + 1.476 + if (this.addons.length == 0) { 1.477 + // Compatibility updates or new version updates were found for all add-ons 1.478 + this.startDownload(); 1.479 + return; 1.480 + } 1.481 + 1.482 + this.selectPanel("updateButtonBox"); 1.483 + this.setupUpdateButton("update.openUpdateUI." + 1.484 + (this.isMajor ? "upgradeButton" : "applyButton")); 1.485 + }, 1.486 + 1.487 + /** 1.488 + * Starts the download of an update mar. 1.489 + */ 1.490 + startDownload: function() { 1.491 + if (!this.update) 1.492 + this.update = this.um.activeUpdate; 1.493 + this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag); 1.494 + this.update.setProperty("foregroundDownload", "true"); 1.495 + 1.496 + this.aus.pauseDownload(); 1.497 + let state = this.aus.downloadUpdate(this.update, false); 1.498 + if (state == "failed") { 1.499 + this.selectPanel("downloadFailed"); 1.500 + return; 1.501 + } 1.502 + 1.503 + this.setupDownloadingUI(); 1.504 + }, 1.505 + 1.506 + /** 1.507 + * Switches to the UI responsible for tracking the download. 1.508 + */ 1.509 + setupDownloadingUI: function() { 1.510 + this.downloadStatus = document.getElementById("downloadStatus"); 1.511 + this.downloadStatus.textContent = 1.512 + DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size); 1.513 + this.selectPanel("downloading"); 1.514 + this.aus.addDownloadListener(this); 1.515 + }, 1.516 + 1.517 + removeDownloadListener: function() { 1.518 + if (this.aus) { 1.519 + this.aus.removeDownloadListener(this); 1.520 + } 1.521 + }, 1.522 + 1.523 + /** 1.524 + * See nsIRequestObserver.idl 1.525 + */ 1.526 + onStartRequest: function(aRequest, aContext) { 1.527 + }, 1.528 + 1.529 + /** 1.530 + * See nsIRequestObserver.idl 1.531 + */ 1.532 + onStopRequest: function(aRequest, aContext, aStatusCode) { 1.533 + switch (aStatusCode) { 1.534 + case Components.results.NS_ERROR_UNEXPECTED: 1.535 + if (this.update.selectedPatch.state == "download-failed" && 1.536 + (this.update.isCompleteUpdate || this.update.patchCount != 2)) { 1.537 + // Verification error of complete patch, informational text is held in 1.538 + // the update object. 1.539 + this.removeDownloadListener(); 1.540 + this.selectPanel("downloadFailed"); 1.541 + break; 1.542 + } 1.543 + // Verification failed for a partial patch, complete patch is now 1.544 + // downloading so return early and do NOT remove the download listener! 1.545 + break; 1.546 + case Components.results.NS_BINDING_ABORTED: 1.547 + // Do not remove UI listener since the user may resume downloading again. 1.548 + break; 1.549 + case Components.results.NS_OK: 1.550 + this.removeDownloadListener(); 1.551 + if (this.backgroundUpdateEnabled) { 1.552 + this.selectPanel("applying"); 1.553 + let update = this.um.activeUpdate; 1.554 + let self = this; 1.555 + Services.obs.addObserver(function updateStaged(aSubject, aTopic, aData) { 1.556 + // Update the UI when the background updater is finished 1.557 + let status = aData; 1.558 + if (status == "applied" || status == "applied-service" || 1.559 + status == "pending" || status == "pending-service") { 1.560 + // If the update is successfully applied, or if the updater has 1.561 + // fallen back to non-staged updates, show the Restart to Update 1.562 + // button. 1.563 + self.selectPanel("updateButtonBox"); 1.564 + self.setupUpdateButton("update.restart." + 1.565 + (self.isMajor ? "upgradeButton" : "updateButton")); 1.566 + } else if (status == "failed") { 1.567 + // Background update has failed, let's show the UI responsible for 1.568 + // prompting the user to update manually. 1.569 + self.selectPanel("downloadFailed"); 1.570 + } else if (status == "downloading") { 1.571 + // We've fallen back to downloading the full update because the 1.572 + // partial update failed to get staged in the background. 1.573 + // Therefore we need to keep our observer. 1.574 + self.setupDownloadingUI(); 1.575 + return; 1.576 + } 1.577 + Services.obs.removeObserver(updateStaged, "update-staged"); 1.578 + }, "update-staged", false); 1.579 + } else { 1.580 + this.selectPanel("updateButtonBox"); 1.581 + this.setupUpdateButton("update.restart." + 1.582 + (this.isMajor ? "upgradeButton" : "updateButton")); 1.583 + } 1.584 + break; 1.585 + default: 1.586 + this.removeDownloadListener(); 1.587 + this.selectPanel("downloadFailed"); 1.588 + break; 1.589 + } 1.590 + 1.591 + }, 1.592 + 1.593 + /** 1.594 + * See nsIProgressEventSink.idl 1.595 + */ 1.596 + onStatus: function(aRequest, aContext, aStatus, aStatusArg) { 1.597 + }, 1.598 + 1.599 + /** 1.600 + * See nsIProgressEventSink.idl 1.601 + */ 1.602 + onProgress: function(aRequest, aContext, aProgress, aProgressMax) { 1.603 + this.downloadStatus.textContent = 1.604 + DownloadUtils.getTransferTotal(aProgress, aProgressMax); 1.605 + }, 1.606 + 1.607 + /** 1.608 + * See nsISupports.idl 1.609 + */ 1.610 + QueryInterface: function(aIID) { 1.611 + if (!aIID.equals(Components.interfaces.nsIProgressEventSink) && 1.612 + !aIID.equals(Components.interfaces.nsIRequestObserver) && 1.613 + !aIID.equals(Components.interfaces.nsISupports)) 1.614 + throw Components.results.NS_ERROR_NO_INTERFACE; 1.615 + return this; 1.616 + } 1.617 +}; 1.618 +#endif