deleted file mode 100644
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/update.dtd
+++ /dev/null
@@ -1,65 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!ENTITY updateWizard.title "&brandShortName; Update">
-
-<!ENTITY offline.title "&brandShortName; is working offline">
-<!ENTITY offline.description "&brandShortName; needs to go online in order to see if updates
- are available for your add-ons to make them compatible with this
- version.">
-<!ENTITY offline.toggleOffline.label "Go online now.">
-<!ENTITY offline.toggleOffline.accesskey "G">
-
-<!ENTITY mismatch.win.title "Incompatible Add-ons">
-<!ENTITY mismatch.top.label "The following add-ons are not compatible with this version of
- &brandShortName; and have been disabled:">
-<!ENTITY mismatch.bottom.label "&brandShortName; can check if there are compatible versions
- of these add-ons available.">
-
-<!ENTITY checking.wizard.title "Checking for Compatible Add-ons">
-<!ENTITY checking.top.label "Checking your incompatible add-ons for updates…">
-<!ENTITY checking.status "This may take a few minutes…">
-
-<!ENTITY found.wizard.title "Found Compatible Add-ons">
-<!ENTITY found.top.label "Select the add-ons you would like to install:">
-<!ENTITY found.disabledXPinstall.label "These updates can’t be installed because software installation is currently
- disabled. You can change this setting below.">
-<!ENTITY found.enableXPInstall.label "Allow websites to install software">
-<!ENTITY found.enableXPInstall.accesskey "A">
-
-<!ENTITY installing.wizard.title "Installing Compatible Add-ons">
-<!ENTITY installing.top.label "Downloading and installing updates to your add-ons…">
-
-<!ENTITY noupdates.wizard.title "No Compatible Add-ons Found">
-<!ENTITY noupdates.intro.desc "&brandShortName; was unable to find updates to your
- incompatible add-ons.">
-<!ENTITY noupdates.error.desc "Some problems were encountered when trying to find updates.">
-<!ENTITY noupdates.checkEnabled.desc "&brandShortName; will check periodically and inform you
- when compatible updates for these add-ons are found.">
-
-<!ENTITY finished.wizard.title "Compatible Add-ons Installed">
-<!ENTITY finished.top.label "&brandShortName; has installed the updates to your add-ons.">
-<!ENTITY finished.checkDisabled.desc "&brandShortName; can check periodically and inform you
- when updates for add-ons are found.">
-<!ENTITY finished.checkEnabled.desc "&brandShortName; will check periodically and inform you
- when updates for add-ons are found.">
-
-<!ENTITY adminDisabled.wizard.title "Unable to Check for Updates">
-<!ENTITY adminDisabled.warning.label "It is not possible to check for updates to incompatible add-ons
- because software installation for &brandShortName; has been disabled.
- Please contact your System Administrator for assistance.">
-
-<!ENTITY versioninfo.wizard.title "Checking Compatibility of Add-ons">
-<!ENTITY versioninfo.top.label "Checking your add-ons for compatibility with this
- version of &brandShortName;.">
-<!ENTITY versioninfo.waiting "This may take a few minutes…">
-
-<!ENTITY installerrors.wizard.title "Problems Installing Updates">
-<!ENTITY installerrors.intro.label "&brandShortName; encountered problems when updating
- some of your add-ons.">
-
-<!-- general strings used by several of the finish pages -->
-<!ENTITY clickFinish.label "Click Finish to continue starting &brandShortName;.">
-<!ENTITY clickFinish.labelMac "Click Done to continue starting &brandShortName;.">
-<!ENTITY enableChecking.label "Allow &brandShortName; to check for updates.">
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/update.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/update.properties
@@ -1,21 +1,17 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-mismatchCheckNow=Check Now
-mismatchCheckNowAccesskey=C
-mismatchDontCheck=Don’t Check
-mismatchDontCheckAccesskey=D
-installButtonText=Install Now
-installButtonTextAccesskey=I
-nextButtonText=Next >
-nextButtonTextAccesskey=N
-cancelButtonText=Cancel
-cancelButtonTextAccesskey=C
-statusPrefix=Finished checking %S
-downloadingPrefix=Downloading: %S
-installingPrefix=Installing: %S
-closeButton=Close
-installErrors=%S was unable to install updates for the following add-ons:
-checkingErrors=%S was unable to check for updates for the following add-ons:
-installErrorItemFormat=%S (%S)
+# LOCALIZATION NOTE (addonUpdateHeader)
+# %S will be replace with the localized name of the application
+addonUpdateTitle=%S Update
+
+# LOCALIZATION NOTE (addonUpdateMessage)
+# %S will be replace with the localized name of the application
+addonUpdateMessage=%S is updating your extensions…
+
+addonUpdateCancelMessage=Still updating. Want to wait?
+
+# LOCALIZATION NOTE (addonUpdateCancelButton)
+# %S will be replace with the localized name of the application
+addonUpdateCancelButton=Stop update and launch %S
--- a/toolkit/locales/jar.mn
+++ b/toolkit/locales/jar.mn
@@ -105,17 +105,16 @@
locale/@AB_CD@/mozapps/downloads/unknownContentType.dtd (%chrome/mozapps/downloads/unknownContentType.dtd)
locale/@AB_CD@/mozapps/downloads/settingsChange.dtd (%chrome/mozapps/downloads/settingsChange.dtd)
locale/@AB_CD@/mozapps/downloads/downloads.properties (%chrome/mozapps/downloads/downloads.properties)
locale/@AB_CD@/mozapps/extensions/extensions.dtd (%chrome/mozapps/extensions/extensions.dtd)
#ifndef MOZ_FENNEC
locale/@AB_CD@/mozapps/extensions/extensions.properties (%chrome/mozapps/extensions/extensions.properties)
locale/@AB_CD@/mozapps/extensions/blocklist.dtd (%chrome/mozapps/extensions/blocklist.dtd)
locale/@AB_CD@/mozapps/extensions/about.dtd (%chrome/mozapps/extensions/about.dtd)
- locale/@AB_CD@/mozapps/extensions/update.dtd (%chrome/mozapps/extensions/update.dtd)
locale/@AB_CD@/mozapps/extensions/update.properties (%chrome/mozapps/extensions/update.properties)
locale/@AB_CD@/mozapps/extensions/newaddon.dtd (%chrome/mozapps/extensions/newaddon.dtd)
locale/@AB_CD@/mozapps/extensions/newaddon.properties (%chrome/mozapps/extensions/newaddon.properties)
#endif
locale/@AB_CD@/mozapps/handling/handling.dtd (%chrome/mozapps/handling/handling.dtd)
locale/@AB_CD@/mozapps/handling/handling.properties (%chrome/mozapps/handling/handling.properties)
locale/@AB_CD@/mozapps/preferences/changemp.dtd (%chrome/mozapps/preferences/changemp.dtd)
locale/@AB_CD@/mozapps/preferences/removemp.dtd (%chrome/mozapps/preferences/removemp.dtd)
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/content/update.css
@@ -0,0 +1,26 @@
+body {
+ font: message-box;
+ min-width: 480px;
+}
+
+#message {
+ font-size: 14px;
+}
+
+#message, #cancel-section {
+ margin: 10px 5px;
+}
+
+#progress {
+ width: calc(100% - 10px);
+ margin: 0 5px;
+}
+
+#cancel-section {
+ display: flex;
+ justify-content: space-between;
+}
+
+#cancel-message {
+ vertical-align: middle;
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/content/update.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script src="update.js"></script>
+ <link rel="stylesheet" href="chrome://mozapps/content/extensions/update.css">
+ </head>
+ <body>
+ <div>
+ <div id="message"></div>
+
+ <progress id="progress" val="0" max="1"></progress>
+
+ <div id="cancel-section">
+ <span id="cancel-message"></span>
+ <button id="cancel-btn"></button>
+ </div>
+ </div>
+ </body>
+</html>
--- a/toolkit/mozapps/extensions/content/update.js
+++ b/toolkit/mozapps/extensions/content/update.js
@@ -1,633 +1,24 @@
-// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
-
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// This UI is only opened from the Extension Manager when the app is upgraded.
-
"use strict";
-/* exported gAdminDisabledPage, gFinishedPage, gFoundPage, gInstallErrorsPage,
- * gNoUpdatesPage, gOfflinePage, gUpdatePage */
-
-const PREF_UPDATE_EXTENSIONS_ENABLED = "extensions.update.enabled";
-const PREF_XPINSTALL_ENABLED = "xpinstall.enabled";
-
-// timeout (in milliseconds) to wait for response to the metadata ping
-const METADATA_TIMEOUT = 30000;
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate", "resource://gre/modules/AddonManager.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository", "resource://gre/modules/addons/AddonRepository.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/Log.jsm");
-var logger = null;
-
-var gUpdateWizard = {
- // When synchronizing app compatibility info this contains all installed
- // add-ons. When checking for compatible versions this contains only
- // incompatible add-ons.
- addons: [],
- // Contains a Set of IDs for add-on that were disabled by the application update.
- affectedAddonIDs: null,
- // The add-ons that we found updates available for
- addonsToUpdate: [],
- shouldSuggestAutoChecking: false,
- shouldAutoCheck: false,
- xpinstallEnabled: true,
- xpinstallLocked: false,
- // cached AddonInstall entries for add-ons we might want to update,
- // keyed by add-on ID
- addonInstalls: new Map(),
- shuttingDown: false,
- // Count the add-ons disabled by this update, enabled/disabled by
- // metadata checks, and upgraded.
- disabled: 0,
- metadataEnabled: 0,
- metadataDisabled: 0,
- upgraded: 0,
- upgradeFailed: 0,
- upgradeDeclined: 0,
-
- init() {
- logger = Log.repository.getLogger("addons.update-dialog");
- // XXX could we pass the addons themselves rather than the IDs?
- this.affectedAddonIDs = new Set(window.arguments[0]);
-
- try {
- this.shouldSuggestAutoChecking =
- !Services.prefs.getBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED);
- } catch (e) {
- }
-
- try {
- this.xpinstallEnabled = Services.prefs.getBoolPref(PREF_XPINSTALL_ENABLED);
- this.xpinstallLocked = Services.prefs.prefIsLocked(PREF_XPINSTALL_ENABLED);
- } catch (e) {
- }
-
- if (Services.io.offline)
- document.documentElement.currentPage = document.getElementById("offline");
- else
- document.documentElement.currentPage = document.getElementById("versioninfo");
- },
-
- onWizardFinish: function gUpdateWizard_onWizardFinish() {
- if (this.shouldSuggestAutoChecking)
- Services.prefs.setBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED, this.shouldAutoCheck);
- },
-
- _setUpButton(aButtonID, aButtonKey, aDisabled) {
- var strings = document.getElementById("updateStrings");
- var button = document.documentElement.getButton(aButtonID);
- if (aButtonKey) {
- button.label = strings.getString(aButtonKey);
- try {
- button.setAttribute("accesskey", strings.getString(aButtonKey + "Accesskey"));
- } catch (e) {
- }
- }
- button.disabled = aDisabled;
- },
-
- setButtonLabels(aBackButton, aBackButtonIsDisabled,
- aNextButton, aNextButtonIsDisabled,
- aCancelButton, aCancelButtonIsDisabled) {
- this._setUpButton("back", aBackButton, aBackButtonIsDisabled);
- this._setUpButton("next", aNextButton, aNextButtonIsDisabled);
- this._setUpButton("cancel", aCancelButton, aCancelButtonIsDisabled);
- },
-
- // Update Errors
- errorItems: [],
-
- checkForErrors(aElementIDToShow) {
- if (this.errorItems.length > 0)
- document.getElementById(aElementIDToShow).hidden = false;
- },
-
- onWizardClose(aEvent) {
- return this.onWizardCancel();
- },
-
- onWizardCancel() {
- gUpdateWizard.shuttingDown = true;
- // Allow add-ons to continue downloading and installing
- // in the background, though some may require a later restart
- // Pages that are waiting for user input go into the background
- // on cancel
- if (gMismatchPage.waiting) {
- logger.info("Dialog closed in mismatch page");
- if (gUpdateWizard.addonInstalls.size > 0) {
- gInstallingPage.startInstalls(
- Array.from(gUpdateWizard.addonInstalls.values()));
- }
- return true;
- }
-
- // Pages that do asynchronous things will just keep running and check
- // gUpdateWizard.shuttingDown to trigger background behaviour
- if (!gInstallingPage.installing) {
- logger.info("Dialog closed while waiting for updated compatibility information");
- } else {
- logger.info("Dialog closed while downloading and installing updates");
- }
- return true;
- }
-};
-
-var gOfflinePage = {
- onPageAdvanced() {
- Services.io.offline = false;
- return true;
- },
-
- toggleOffline() {
- var nextbtn = document.documentElement.getButton("next");
- nextbtn.disabled = !nextbtn.disabled;
- }
-}
-
-// Addon listener to count addons enabled/disabled by metadata checks
-var listener = {
- onDisabled(aAddon) {
- gUpdateWizard.affectedAddonIDs.add(aAddon.id);
- gUpdateWizard.metadataDisabled++;
- },
- onEnabled(aAddon) {
- gUpdateWizard.affectedAddonIDs.delete(aAddon.id);
- gUpdateWizard.metadataEnabled++;
- }
-};
+Components.utils.import("resource://gre/modules/Services.jsm");
-var gVersionInfoPage = {
- _completeCount: 0,
- _totalCount: 0,
- _versionInfoDone: false,
- async onPageShow() {
- gUpdateWizard.setButtonLabels(null, true,
- "nextButtonText", true,
- "cancelButtonText", false);
-
- gUpdateWizard.disabled = gUpdateWizard.affectedAddonIDs.size;
-
- // Ensure compatibility overrides are up to date before checking for
- // individual addon updates.
- AddonManager.addAddonListener(listener);
- if (AddonRepository.isMetadataStale()) {
- // Do the metadata ping, listening for any newly enabled/disabled add-ons.
- await AddonRepository.repopulateCache(METADATA_TIMEOUT);
- if (gUpdateWizard.shuttingDown) {
- logger.debug("repopulateCache completed after dialog closed");
- }
- }
- // Fetch the add-ons that are still affected by this update,
- // excluding the hotfix add-on.
- let idlist = Array.from(gUpdateWizard.affectedAddonIDs).filter(
- a => a.id != AddonManager.hotfixID);
- if (idlist.length < 1) {
- gVersionInfoPage.onAllUpdatesFinished();
- return;
- }
-
- logger.debug("Fetching affected addons " + idlist.toSource());
- let fetchedAddons = await AddonManager.getAddonsByIDs(idlist);
- // We shouldn't get nulls here, but let's be paranoid...
- gUpdateWizard.addons = fetchedAddons.filter(a => a);
- if (gUpdateWizard.addons.length < 1) {
- gVersionInfoPage.onAllUpdatesFinished();
- return;
- }
-
- gVersionInfoPage._totalCount = gUpdateWizard.addons.length;
-
- for (let addon of gUpdateWizard.addons) {
- logger.debug("VersionInfo Finding updates for ${id}", addon);
- addon.findUpdates(gVersionInfoPage, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
- }
- },
-
- onAllUpdatesFinished() {
- AddonManager.removeAddonListener(listener);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_disabled",
- gUpdateWizard.disabled);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_enabled",
- gUpdateWizard.metadataEnabled);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_metadata_disabled",
- gUpdateWizard.metadataDisabled);
- // Record 0 for these here in case we exit early; values will be replaced
- // later if we actually upgrade any.
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded", 0);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed", 0);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined", 0);
- // Filter out any add-ons that are now enabled.
- let addonList = gUpdateWizard.addons.map(a => a.id + ":" + a.appDisabled);
- logger.debug("VersionInfo updates finished: found " + addonList.toSource());
- let filteredAddons = [];
- for (let a of gUpdateWizard.addons) {
- if (a.appDisabled) {
- logger.debug("Continuing with add-on " + a.id);
- filteredAddons.push(a);
- } else if (gUpdateWizard.addonInstalls.has(a.id)) {
- gUpdateWizard.addonInstalls.get(a.id).cancel();
- gUpdateWizard.addonInstalls.delete(a.id);
- }
- }
- gUpdateWizard.addons = filteredAddons;
+let BRAND_PROPS = "chrome://branding/locale/brand.properties";
+let UPDATE_PROPS = "chrome://mozapps/locale/extensions/update.properties";
- if (gUpdateWizard.shuttingDown) {
- // jump directly to updating auto-update add-ons in the background
- if (gUpdateWizard.addonInstalls.size > 0) {
- let installs = Array.from(gUpdateWizard.addonInstalls.values());
- gInstallingPage.startInstalls(installs);
- }
- return;
- }
-
- if (filteredAddons.length > 0) {
- if (!gUpdateWizard.xpinstallEnabled && gUpdateWizard.xpinstallLocked) {
- document.documentElement.currentPage = document.getElementById("adminDisabled");
- return;
- }
- document.documentElement.currentPage = document.getElementById("mismatch");
- } else {
- logger.info("VersionInfo: No updates require further action");
- // VersionInfo compatibility updates resolved all compatibility problems,
- // close this window and continue starting the application...
- // XXX Bug 314754 - We need to use setTimeout to close the window due to
- // the EM using xmlHttpRequest when checking for updates.
- setTimeout(close, 0);
- }
- },
-
- // UpdateListener
- onUpdateFinished(aAddon, status) {
- ++this._completeCount;
-
- if (status != AddonManager.UPDATE_STATUS_NO_ERROR) {
- logger.debug("VersionInfo update " + this._completeCount + " of " + this._totalCount +
- " failed for " + aAddon.id + ": " + status);
- gUpdateWizard.errorItems.push(aAddon);
- } else {
- logger.debug("VersionInfo update " + this._completeCount + " of " + this._totalCount +
- " finished for " + aAddon.id);
- }
-
- // If we're not in the background, just make a list of add-ons that have
- // updates available
- if (!gUpdateWizard.shuttingDown) {
- // If we're still in the update check window and the add-on is now active
- // then it won't have been disabled by startup
- if (aAddon.active) {
- AddonManagerPrivate.removeStartupChange(AddonManager.STARTUP_CHANGE_DISABLED, aAddon.id);
- gUpdateWizard.metadataEnabled++;
- }
-
- // Update the status text and progress bar
- var updateStrings = document.getElementById("updateStrings");
- var statusElt = document.getElementById("versioninfo.status");
- var statusString = updateStrings.getFormattedString("statusPrefix", [aAddon.name]);
- statusElt.setAttribute("value", statusString);
-
- // Update the status text and progress bar
- var progress = document.getElementById("versioninfo.progress");
- progress.mode = "normal";
- progress.value = Math.ceil((this._completeCount / this._totalCount) * 100);
- }
-
- if (this._completeCount == this._totalCount)
- this.onAllUpdatesFinished();
- },
-
- onUpdateAvailable(aAddon, aInstall) {
- logger.debug("VersionInfo got an install for " + aAddon.id + ": " + aAddon.version);
- gUpdateWizard.addonInstalls.set(aAddon.id, aInstall);
- },
-};
-
-var gMismatchPage = {
- waiting: false,
-
- onPageShow() {
- gMismatchPage.waiting = true;
- gUpdateWizard.setButtonLabels(null, true,
- "mismatchCheckNow", false,
- "mismatchDontCheck", false);
- document.documentElement.getButton("next").focus();
+let appName = Services.strings.createBundle(BRAND_PROPS)
+ .GetStringFromName("brandShortName");
+let bundle = Services.strings.createBundle(UPDATE_PROPS);
- var incompatible = document.getElementById("mismatch.incompatible");
- for (let addon of gUpdateWizard.addons) {
- var listitem = document.createElement("listitem");
- listitem.setAttribute("label", addon.name + " " + addon.version);
- incompatible.appendChild(listitem);
- }
- }
-};
-
-var gUpdatePage = {
- _totalCount: 0,
- _completeCount: 0,
- onPageShow() {
- gMismatchPage.waiting = false;
- gUpdateWizard.setButtonLabels(null, true,
- "nextButtonText", true,
- "cancelButtonText", false);
- document.documentElement.getButton("next").focus();
-
- gUpdateWizard.errorItems = [];
-
- this._totalCount = gUpdateWizard.addons.length;
- for (let addon of gUpdateWizard.addons) {
- logger.debug("UpdatePage requesting update for " + addon.id);
- // Redundant call to find updates again here when we already got them
- // in the VersionInfo page: https://bugzilla.mozilla.org/show_bug.cgi?id=960597
- addon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
- }
- },
-
- onAllUpdatesFinished() {
- if (gUpdateWizard.shuttingDown)
- return;
-
- var nextPage = document.getElementById("noupdates");
- if (gUpdateWizard.addonsToUpdate.length > 0)
- nextPage = document.getElementById("found");
- document.documentElement.currentPage = nextPage;
- },
-
- // UpdateListener
- onUpdateAvailable(aAddon, aInstall) {
- logger.debug("UpdatePage got an update for " + aAddon.id + ": " + aAddon.version);
- gUpdateWizard.addonsToUpdate.push(aInstall);
- },
-
- onUpdateFinished(aAddon, status) {
- if (status != AddonManager.UPDATE_STATUS_NO_ERROR)
- gUpdateWizard.errorItems.push(aAddon);
-
- ++this._completeCount;
-
- if (!gUpdateWizard.shuttingDown) {
- // Update the status text and progress bar
- var updateStrings = document.getElementById("updateStrings");
- var statusElt = document.getElementById("checking.status");
- var statusString = updateStrings.getFormattedString("statusPrefix", [aAddon.name]);
- statusElt.setAttribute("value", statusString);
-
- var progress = document.getElementById("checking.progress");
- progress.value = Math.ceil((this._completeCount / this._totalCount) * 100);
- }
-
- if (this._completeCount == this._totalCount)
- this.onAllUpdatesFinished()
- },
-};
-
-var gFoundPage = {
- onPageShow() {
- gUpdateWizard.setButtonLabels(null, true,
- "installButtonText", false,
- null, false);
+let titleText = bundle.formatStringFromName("addonUpdateTitle", [appName], 1);
+let messageText = bundle.formatStringFromName("addonUpdateMessage", [appName], 1);
+let cancelText = bundle.GetStringFromName("addonUpdateCancelMessage");
+let cancelButtonText = bundle.formatStringFromName("addonUpdateCancelButton", [appName], 1);
- var foundUpdates = document.getElementById("found.updates");
- for (let install of gUpdateWizard.addonsToUpdate) {
- let listItem = foundUpdates.appendItem(install.name + " " + install.version);
- listItem.setAttribute("type", "checkbox");
- listItem.setAttribute("checked", "true");
- listItem.install = install;
- }
-
- if (!gUpdateWizard.xpinstallEnabled) {
- document.getElementById("xpinstallDisabledAlert").hidden = false;
- document.getElementById("enableXPInstall").focus();
- document.documentElement.getButton("next").disabled = true;
- } else {
- document.documentElement.getButton("next").focus();
- document.documentElement.getButton("next").disabled = false;
- }
- },
-
- toggleXPInstallEnable(aEvent) {
- var enabled = aEvent.target.checked;
- gUpdateWizard.xpinstallEnabled = enabled;
- var pref = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- pref.setBoolPref(PREF_XPINSTALL_ENABLED, enabled);
- this.updateNextButton();
- },
-
- updateNextButton() {
- if (!gUpdateWizard.xpinstallEnabled) {
- document.documentElement.getButton("next").disabled = true;
- return;
- }
-
- var oneChecked = false;
- var foundUpdates = document.getElementById("found.updates");
- var updates = foundUpdates.getElementsByTagName("listitem");
- for (let update of updates) {
- if (!update.checked)
- continue;
- oneChecked = true;
- break;
- }
-
- gUpdateWizard.setButtonLabels(null, true,
- "installButtonText", true,
- null, false);
- document.getElementById("found").setAttribute("next", "installing");
- document.documentElement.getButton("next").disabled = !oneChecked;
- }
-};
-
-var gInstallingPage = {
- _installs: [],
- _errors: [],
- _strings: null,
- _currentInstall: -1,
- _installing: false,
-
- // Initialize fields we need for installing and tracking progress,
- // and start iterating through the installations
- startInstalls(aInstallList) {
- if (!gUpdateWizard.xpinstallEnabled) {
- return;
- }
-
- let installs = Array.from(aInstallList).map(a => a.existingAddon.id);
- logger.debug("Start installs for " + installs.toSource());
- this._errors = [];
- this._installs = aInstallList;
- this._installing = true;
- this.startNextInstall();
- },
-
- onPageShow() {
- gUpdateWizard.setButtonLabels(null, true,
- "nextButtonText", true,
- null, true);
+document.title = titleText;
- var foundUpdates = document.getElementById("found.updates");
- var updates = foundUpdates.getElementsByTagName("listitem");
- let toInstall = [];
- for (let update of updates) {
- if (!update.checked) {
- logger.info("User chose to cancel update of " + update.label);
- gUpdateWizard.upgradeDeclined++;
- update.install.cancel();
- continue;
- }
- toInstall.push(update.install);
- }
- this._strings = document.getElementById("updateStrings");
-
- this.startInstalls(toInstall);
- },
-
- startNextInstall() {
- if (this._currentInstall >= 0) {
- this._installs[this._currentInstall].removeListener(this);
- }
-
- this._currentInstall++;
-
- if (this._installs.length == this._currentInstall) {
- Services.obs.notifyObservers(null, "TEST:all-updates-done");
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgraded",
- gUpdateWizard.upgraded);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeFailed",
- gUpdateWizard.upgradeFailed);
- AddonManagerPrivate.recordSimpleMeasure("appUpdate_upgradeDeclined",
- gUpdateWizard.upgradeDeclined);
- this._installing = false;
- if (gUpdateWizard.shuttingDown) {
- return;
- }
- var nextPage = this._errors.length > 0 ? "installerrors" : "finished";
- document.getElementById("installing").setAttribute("next", nextPage);
- document.documentElement.advance();
- return;
- }
-
- let install = this._installs[this._currentInstall];
-
- if (gUpdateWizard.shuttingDown && !AddonManager.shouldAutoUpdate(install.existingAddon)) {
- logger.debug("Don't update " + install.existingAddon.id + " in background");
- gUpdateWizard.upgradeDeclined++;
- install.cancel();
- this.startNextInstall();
- return;
- }
- install.addListener(this);
- install.install();
- },
-
- // InstallListener
- onDownloadStarted(aInstall) {
- if (gUpdateWizard.shuttingDown) {
- return;
- }
- var strings = document.getElementById("updateStrings");
- var label = strings.getFormattedString("downloadingPrefix", [aInstall.name]);
- var actionItem = document.getElementById("actionItem");
- actionItem.value = label;
- },
-
- onDownloadProgress(aInstall) {
- if (gUpdateWizard.shuttingDown) {
- return;
- }
- var downloadProgress = document.getElementById("downloadProgress");
- downloadProgress.value = Math.ceil(100 * aInstall.progress / aInstall.maxProgress);
- },
-
- onDownloadEnded(aInstall) {
- },
-
- onDownloadFailed(aInstall) {
- this._errors.push(aInstall);
-
- gUpdateWizard.upgradeFailed++;
- this.startNextInstall();
- },
-
- onInstallStarted(aInstall) {
- if (gUpdateWizard.shuttingDown) {
- return;
- }
- var strings = document.getElementById("updateStrings");
- var label = strings.getFormattedString("installingPrefix", [aInstall.name]);
- var actionItem = document.getElementById("actionItem");
- actionItem.value = label;
- },
-
- onInstallEnded(aInstall, aAddon) {
- if (!gUpdateWizard.shuttingDown) {
- // Remember that this add-on was updated during startup
- AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED,
- aAddon.id);
- }
-
- gUpdateWizard.upgraded++;
- this.startNextInstall();
- },
-
- onInstallFailed(aInstall) {
- this._errors.push(aInstall);
-
- gUpdateWizard.upgradeFailed++;
- this.startNextInstall();
- }
-};
-
-var gInstallErrorsPage = {
- onPageShow() {
- gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
- document.documentElement.getButton("finish").focus();
- },
-};
-
-// Displayed when there are incompatible add-ons and the xpinstall.enabled
-// pref is false and locked.
-var gAdminDisabledPage = {
- onPageShow() {
- gUpdateWizard.setButtonLabels(null, true, null, true,
- "cancelButtonText", true);
- document.documentElement.getButton("finish").focus();
- }
-};
-
-// Displayed when selected add-on updates have been installed without error.
-// There can still be add-ons that are not compatible and don't have an update.
-var gFinishedPage = {
- onPageShow() {
- gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
- document.documentElement.getButton("finish").focus();
-
- if (gUpdateWizard.shouldSuggestAutoChecking) {
- document.getElementById("finishedCheckDisabled").hidden = false;
- gUpdateWizard.shouldAutoCheck = true;
- } else
- document.getElementById("finishedCheckEnabled").hidden = false;
-
- document.documentElement.getButton("finish").focus();
- }
-};
-
-// Displayed when there are incompatible add-ons and there are no available
-// updates.
-var gNoUpdatesPage = {
- onPageShow(aEvent) {
- gUpdateWizard.setButtonLabels(null, true, null, true, null, true);
- if (gUpdateWizard.shouldSuggestAutoChecking) {
- document.getElementById("noupdatesCheckDisabled").hidden = false;
- gUpdateWizard.shouldAutoCheck = true;
- } else
- document.getElementById("noupdatesCheckEnabled").hidden = false;
-
- gUpdateWizard.checkForErrors("updateCheckErrorNotFound");
- document.documentElement.getButton("finish").focus();
- }
-};
+window.addEventListener("load", e => {
+ document.getElementById("message").textContent = messageText;
+ document.getElementById("cancel-message").textContent = cancelText;
+ document.getElementById("cancel-btn").textContent = cancelButtonText;
+ window.sizeToContent();
+});
deleted file mode 100644
--- a/toolkit/mozapps/extensions/content/update.xul
+++ /dev/null
@@ -1,194 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://mozapps/skin/extensions/update.css" type="text/css"?>
-
-<!DOCTYPE wizard [
-<!ENTITY % updateDTD SYSTEM "chrome://mozapps/locale/extensions/update.dtd">
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
-%updateDTD;
-%brandDTD;
-]>
-
-<wizard id="updateWizard"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&updateWizard.title;"
- windowtype="Addons:Compatibility"
- branded="true"
- onload="gUpdateWizard.init();"
- onwizardfinish="gUpdateWizard.onWizardFinish();"
- onwizardcancel="return gUpdateWizard.onWizardCancel();"
- onclose="return gUpdateWizard.onWizardClose(event);"
- buttons="accept,cancel">
-
- <script type="application/javascript" src="chrome://mozapps/content/extensions/update.js"/>
-
- <stringbundleset id="updateSet">
- <stringbundle id="brandStrings" src="chrome://branding/locale/brand.properties"/>
- <stringbundle id="updateStrings" src="chrome://mozapps/locale/extensions/update.properties"/>
- </stringbundleset>
-
- <wizardpage id="dummy" pageid="dummy"/>
-
- <wizardpage id="offline" pageid="offline" next="versioninfo"
- label="&offline.title;"
- onpageadvanced="return gOfflinePage.onPageAdvanced();">
- <description>&offline.description;</description>
- <checkbox id="toggleOffline"
- checked="true"
- label="&offline.toggleOffline.label;"
- accesskey="&offline.toggleOffline.accesskey;"
- oncommand="gOfflinePage.toggleOffline();"/>
- </wizardpage>
-
- <wizardpage id="versioninfo" pageid="versioninfo" next="mismatch"
- label="&versioninfo.wizard.title;"
- onpageshow="gVersionInfoPage.onPageShow();">
- <label>&versioninfo.top.label;</label>
- <separator class="thin"/>
- <progressmeter id="versioninfo.progress" mode="undetermined"/>
- <hbox align="center">
- <image id="versioninfo.throbber" class="throbber"/>
- <label flex="1" id="versioninfo.status" crop="right">&versioninfo.waiting;</label>
- </hbox>
- <separator/>
- </wizardpage>
-
- <wizardpage id="mismatch" pageid="mismatch" next="checking"
- label="&mismatch.win.title;"
- onpageshow="gMismatchPage.onPageShow();">
- <label>&mismatch.top.label;</label>
- <separator class="thin"/>
- <listbox id="mismatch.incompatible" flex="1"/>
- <separator class="thin"/>
- <label>&mismatch.bottom.label;</label>
- </wizardpage>
-
- <wizardpage id="checking" pageid="checking" next="noupdates"
- label="&checking.wizard.title;"
- onpageshow="gUpdatePage.onPageShow();">
- <label>&checking.top.label;</label>
- <separator class="thin"/>
- <progressmeter id="checking.progress"/>
- <hbox align="center">
- <image id="checking.throbber" class="throbber"/>
- <label id="checking.status" flex="1" crop="right">&checking.status;</label>
- </hbox>
- </wizardpage>
-
- <wizardpage id="noupdates" pageid="noupdates"
- label="&noupdates.wizard.title;"
- onpageshow="gNoUpdatesPage.onPageShow();">
- <description>&noupdates.intro.desc;</description>
- <separator class="thin"/>
- <hbox id="updateCheckErrorNotFound" class="alertBox" hidden="true" align="top">
- <description flex="1">&noupdates.error.desc;</description>
- </hbox>
- <separator class="thin"/>
- <description id="noupdatesCheckEnabled" hidden="true">
- &noupdates.checkEnabled.desc;
- </description>
- <vbox id="noupdatesCheckDisabled" hidden="true">
- <description>&finished.checkDisabled.desc;</description>
- <checkbox label="&enableChecking.label;" checked="true"
- oncommand="gUpdateWizard.shouldAutoCheck = this.checked;"/>
- </vbox>
- <separator flex="1"/>
-#ifndef XP_MACOSX
- <label>&clickFinish.label;</label>
-#else
- <label>&clickFinish.labelMac;</label>
-#endif
- <separator class="thin"/>
- </wizardpage>
-
- <wizardpage id="found" pageid="found" next="installing"
- label="&found.wizard.title;"
- onpageshow="gFoundPage.onPageShow();">
- <label>&found.top.label;</label>
- <separator class="thin"/>
- <listbox id="found.updates" flex="1" seltype="multiple"
- onclick="gFoundPage.updateNextButton();"/>
- <separator class="thin"/>
- <vbox align="left" id="xpinstallDisabledAlert" hidden="true">
- <description>&found.disabledXPinstall.label;</description>
- <checkbox label="&found.enableXPInstall.label;"
- id="enableXPInstall"
- accesskey="&found.enableXPInstall.accesskey;"
- oncommand="gFoundPage.toggleXPInstallEnable(event);"/>
- </vbox>
- </wizardpage>
-
- <wizardpage id="installing" pageid="installing" next="finished"
- label="&installing.wizard.title;"
- onpageshow="gInstallingPage.onPageShow();">
- <label>&installing.top.label;</label>
- <progressmeter id="downloadProgress"/>
- <hbox align="center">
- <image id="installing.throbber" class="throbber"/>
- <label id="actionItem" flex="1" crop="right"/>
- </hbox>
- <separator/>
- </wizardpage>
-
- <wizardpage id="installerrors" pageid="installerrors"
- label="&installerrors.wizard.title;"
- onpageshow="gInstallErrorsPage.onPageShow();">
- <hbox align="top" class="alertBox">
- <description flex="1">&installerrors.intro.label;</description>
- </hbox>
- <separator flex="1"/>
-#ifndef XP_MACOSX
- <label>&clickFinish.label;</label>
-#else
- <label>&clickFinish.labelMac;</label>
-#endif
- <separator class="thin"/>
- </wizardpage>
-
- <wizardpage id="adminDisabled" pageid="adminDisabled"
- label="&adminDisabled.wizard.title;"
- onpageshow="gAdminDisabledPage.onPageShow();">
- <separator/>
- <hbox class="alertBox" align="top">
- <description flex="1">&adminDisabled.warning.label;</description>
- </hbox>
- <separator flex="1"/>
-#ifndef XP_MACOSX
- <label>&clickFinish.label;</label>
-#else
- <label>&clickFinish.labelMac;</label>
-#endif
- <separator class="thin"/>
- </wizardpage>
-
- <wizardpage id="finished" pageid="finished"
- label="&finished.wizard.title;"
- onpageshow="gFinishedPage.onPageShow();">
-
- <label>&finished.top.label;</label>
- <separator/>
- <description id="finishedCheckEnabled" hidden="true">
- &finished.checkEnabled.desc;
- </description>
- <vbox id="finishedCheckDisabled" hidden="true">
- <description>&finished.checkDisabled.desc;</description>
- <checkbox label="&enableChecking.label;" checked="true"
- oncommand="gUpdateWizard.shouldAutoCheck = this.checked;"/>
- </vbox>
- <separator flex="1"/>
-#ifndef XP_MACOSX
- <label>&clickFinish.label;</label>
-#else
- <label>&clickFinish.labelMac;</label>
-#endif
- <separator class="thin"/>
- </wizardpage>
-
-</wizard>
-
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -31,16 +31,18 @@ XPCOMUtils.defineLazyModuleGetters(this,
PermissionsUtils: "resource://gre/modules/PermissionsUtils.jsm",
OS: "resource://gre/modules/osfile.jsm",
ConsoleAPI: "resource://gre/modules/Console.jsm",
ProductAddonChecker: "resource://gre/modules/addons/ProductAddonChecker.jsm",
UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
isAddonPartOfE10SRollout: "resource://gre/modules/addons/E10SAddonsRollout.jsm",
JSONFile: "resource://gre/modules/JSONFile.jsm",
LegacyExtensionsUtils: "resource://gre/modules/LegacyExtensionsUtils.jsm",
+ setTimeout: "resource://gre/modules/Timer.jsm",
+ clearTimeout: "resource://gre/modules/Timer.jsm",
DownloadAddonInstall: "resource://gre/modules/addons/XPIInstall.jsm",
LocalAddonInstall: "resource://gre/modules/addons/XPIInstall.jsm",
StagedAddonInstall: "resource://gre/modules/addons/XPIInstall.jsm",
UpdateChecker: "resource://gre/modules/addons/XPIInstall.jsm",
loadManifestFromFile: "resource://gre/modules/addons/XPIInstall.jsm",
verifyBundleSignedState: "resource://gre/modules/addons/XPIInstall.jsm",
});
@@ -102,17 +104,16 @@ const PREF_EM_LAST_APP_BUILD_ID =
const OBSOLETE_PREFERENCES = [
"extensions.bootstrappedAddons",
"extensions.enabledAddons",
"extensions.xpiState",
"extensions.installCache",
];
-const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties";
const DIR_EXTENSIONS = "extensions";
const DIR_SYSTEM_ADDONS = "features";
const DIR_STAGE = "staged";
const DIR_TRASH = "trash";
const FILE_XPI_STATES = "addonStartup.json.lz4";
@@ -768,16 +769,30 @@ function canRunInSafeMode(aAddon) {
// in safe mode. assuming for now that they are.
if (aAddon._installLocation.name == KEY_APP_TEMPORARY)
return true;
return aAddon._installLocation.isSystem;
}
/**
+ * Determine if this addon should be disabled due to being legacy
+ *
+ * @param {Addon} addon The addon to check
+ *
+ * @returns {boolean} Whether the addon should be disabled for being legacy
+ */
+function isDisabledLegacy(addon) {
+ return (!AddonSettings.ALLOW_LEGACY_EXTENSIONS &&
+ LEGACY_TYPES.has(addon.type) &&
+ !addon._installLocation.isSystem &&
+ addon.signedState !== AddonManager.SIGNEDSTATE_PRIVILEGED);
+}
+
+/**
* Calculates whether an add-on should be appDisabled or not.
*
* @param aAddon
* The add-on to check
* @return true if the add-on should not be appDisabled
*/
function isUsableAddon(aAddon) {
// Hack to ensure the default theme is always usable
@@ -823,19 +838,17 @@ function isUsableAddon(aAddon) {
let active = XPIProvider.activeAddons.get(id);
return active && !active.disable;
};
if (aAddon.dependencies.some(id => !isActive(id)))
return false;
}
- if (!AddonSettings.ALLOW_LEGACY_EXTENSIONS && LEGACY_TYPES.has(aAddon.type) &&
- !aAddon._installLocation.isSystem &&
- aAddon.signedState !== AddonManager.SIGNEDSTATE_PRIVILEGED) {
+ if (isDisabledLegacy(aAddon)) {
logger.warn(`disabling legacy extension ${aAddon.id}`);
return false;
}
if (!ALLOW_NON_MPC && aAddon.type == "extension" &&
aAddon.multiprocessCompatible !== true) {
logger.warn(`disabling ${aAddon.id} since it is not multiprocess compatible`);
return false;
@@ -2155,20 +2168,21 @@ this.XPIProvider = {
aOldPlatformVersion);
// Changes to installed extensions may have changed which theme is selected
this.applyThemeChange();
AddonManagerPrivate.markProviderSafe(this);
if (aAppChanged && !this.allAppGlobal &&
- Services.prefs.getBoolPref(PREF_EM_SHOW_MISMATCH_UI, true)) {
+ Services.prefs.getBoolPref(PREF_EM_SHOW_MISMATCH_UI, true) &&
+ AddonManager.updateEnabled) {
let addonsToUpdate = this.shouldForceUpdateCheck(aAppChanged);
if (addonsToUpdate) {
- this.showUpgradeUI(addonsToUpdate);
+ this.noLegacyStartupCheck(addonsToUpdate);
flushCaches = true;
}
}
if (flushCaches) {
Services.obs.notifyObservers(null, "startupcache-invalidate");
// UI displayed early in startup (like the compatibility UI) may have
// caused us to cache parts of the skin or locale in memory. These must
@@ -2190,16 +2204,22 @@ this.XPIProvider = {
} catch (e) { }
this.addAddonsToCrashReporter();
}
try {
AddonManagerPrivate.recordTimestamp("XPI_bootstrap_addons_begin");
for (let addon of this.sortBootstrappedAddons()) {
+ // The startup update check above may have already started some
+ // extensions, make sure not to try to start them twice.
+ let activeAddon = this.activeAddons.get(addon.id);
+ if (activeAddon && activeAddon.started) {
+ continue;
+ }
try {
let reason = BOOTSTRAP_REASONS.APP_STARTUP;
// Eventually set INSTALLED reason when a bootstrap addon
// is dropped in profile folder and automatically installed
if (AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_INSTALLED)
.indexOf(addon.id) !== -1)
reason = BOOTSTRAP_REASONS.ADDON_INSTALL;
this.callBootstrapMethod(createAddonDetails(addon.id, addon),
@@ -2410,76 +2430,158 @@ this.XPIProvider = {
Services.prefs.clearUserPref(PREF_SKIN_SWITCHPENDING);
},
/**
* If the application has been upgraded and there are add-ons outside the
* application directory then we may need to synchronize compatibility
* information but only if the mismatch UI isn't disabled.
*
- * @returns False if no update check is needed, otherwise an array of add-on
- * IDs to check for updates. Array may be empty if no add-ons can be/need
- * to be updated, but the metadata check needs to be performed.
+ * @returns null if no update check is needed, otherwise an array of add-on
+ * IDs to check for updates.
*/
shouldForceUpdateCheck(aAppChanged) {
AddonManagerPrivate.recordSimpleMeasure("XPIDB_metadata_age", AddonRepository.metadataAge());
let startupChanges = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
logger.debug("shouldForceUpdateCheck startupChanges: " + startupChanges.toSource());
AddonManagerPrivate.recordSimpleMeasure("XPIDB_startup_disabled", startupChanges.length);
let forceUpdate = [];
if (startupChanges.length > 0) {
let addons = XPIDatabase.getAddons();
for (let addon of addons) {
if ((startupChanges.indexOf(addon.id) != -1) &&
(addon.permissions() & AddonManager.PERM_CAN_UPGRADE) &&
- !addon.isCompatible) {
+ (!addon.isCompatible || isDisabledLegacy(addon))) {
logger.debug("shouldForceUpdateCheck: can upgrade disabled add-on " + addon.id);
forceUpdate.push(addon.id);
}
}
}
- if (AddonRepository.isMetadataStale()) {
- logger.debug("shouldForceUpdateCheck: metadata is stale");
- return forceUpdate;
- }
if (forceUpdate.length > 0) {
return forceUpdate;
}
- return false;
+ return null;
},
/**
- * Shows the "Compatibility Updates" UI.
+ * Perform startup check for updates of legacy extensions.
+ * This runs during startup when an app update has made some add-ons
+ * incompatible and legacy add-on support is diasabled.
+ * In this case, we just do a quiet update check.
*
- * @param aAddonIDs
- * Array opf addon IDs that were disabled by the application update, and
- * should therefore be checked for updates.
+ * @param {Array<string>} ids The ids of the addons to check for updates.
+ *
+ * @returns {Set<string>} The ids of any addons that were updated. These
+ * addons will have been started by the update
+ * process so they should not be started by the
+ * regular bootstrap startup code.
*/
- showUpgradeUI(aAddonIDs) {
- logger.debug("XPI_showUpgradeUI: " + aAddonIDs.toSource());
- Services.telemetry.getHistogramById("ADDON_MANAGER_UPGRADE_UI_SHOWN").add(1);
-
- // Flip a flag to indicate that we interrupted startup with an interactive prompt
- Services.startup.interrupted = true;
-
- var variant = Cc["@mozilla.org/variant;1"].
- createInstance(Ci.nsIWritableVariant);
- variant.setFromVariant(aAddonIDs);
-
- // This *must* be modal as it has to block startup.
- var features = "chrome,centerscreen,dialog,titlebar,modal";
- var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Ci.nsIWindowWatcher);
- ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant);
-
- Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, false);
+ noLegacyStartupCheck(ids) {
+ let started = new Set();
+ const DIALOG = "chrome://mozapps/content/extensions/update.html";
+ const SHOW_DIALOG_DELAY = 1000;
+ const SHOW_CANCEL_DELAY = 30000;
+
+ // Keep track of a value between 0 and 1 indicating the progress
+ // for each addon. Just combine these linearly into a single
+ // value for the progress bar in the update dialog.
+ let updateProgress = val => {};
+ let progressByID = new Map();
+ function setProgress(id, val) {
+ progressByID.set(id, val);
+ updateProgress(Array.from(progressByID.values()).reduce((a, b) => a + b) / progressByID.size);
+ }
+
+ // Do an update check for one addon and try to apply the update if
+ // there is one. Progress for the check is arbitrarily defined as
+ // 10% done when the update check is done, between 10-90% during the
+ // download, then 100% when the update has been installed.
+ let checkOne = async (id) => {
+ logger.debug(`Checking for updates to disabled addon ${id}\n`);
+
+ setProgress(id, 0);
+
+ let addon = await AddonManager.getAddonByID(id);
+ let install = await new Promise(resolve => addon.findUpdates({
+ onUpdateFinished() { resolve(null); },
+ onUpdateAvailable(addon, install) { resolve(install); },
+ }, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED));
+
+ if (!install) {
+ setProgress(id, 1);
+ return;
+ }
+
+ setProgress(id, 0.1);
+
+ let installPromise = new Promise(resolve => {
+ let finish = () => {
+ setProgress(id, 1);
+ resolve();
+ };
+ install.addListener({
+ onDownloadProgress() {
+ if (install.maxProgress != 0) {
+ setProgress(id, 0.1 + 0.8 * install.progress / install.maxProgress);
+ }
+ },
+ onDownloadEnded() {
+ setProgress(id, 0.9);
+ },
+ onDownloadFailed: finish,
+ onInstallFailed: finish,
+ onInstallEnded() {
+ started.add(id);
+ AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED, id);
+ finish();
+ },
+ });
+ });
+ install.install();
+ await installPromise;
+ };
+
+ let finished = false;
+ Promise.all(ids.map(checkOne)).then(() => { finished = true; });
+
+ let window;
+ let timer = setTimeout(() => {
+ const FEATURES = "chrome,dialog,centerscreen,scrollbars=no";
+ window = Services.ww.openWindow(null, DIALOG, "", FEATURES, null);
+
+ let cancelDiv;
+ window.addEventListener("DOMContentLoaded", e => {
+ let progress = window.document.getElementById("progress");
+ updateProgress = val => { progress.value = val; };
+
+ cancelDiv = window.document.getElementById("cancel-section");
+ cancelDiv.setAttribute("style", "display: none;");
+
+ let cancelBtn = window.document.getElementById("cancel-btn");
+ cancelBtn.addEventListener("click", e => { finished = true; });
+ });
+
+ timer = setTimeout(() => {
+ cancelDiv.removeAttribute("style");
+ window.sizeToContent();
+ }, SHOW_CANCEL_DELAY - SHOW_DIALOG_DELAY);
+ }, SHOW_DIALOG_DELAY);
+
+ Services.tm.spinEventLoopUntil(() => finished);
+
+ clearTimeout(timer);
+ if (window) {
+ window.close();
+ }
+
+ return started;
},
async updateSystemAddons() {
let systemAddonLocation = XPIProvider.installLocationsByName[KEY_APP_SYSTEM_ADDONS];
if (!systemAddonLocation)
return;
// Don't do anything in safe mode
@@ -4176,16 +4278,17 @@ this.XPIProvider = {
*/
loadBootstrapScope(aId, aFile, aVersion, aType,
aMultiprocessCompatible, aRunInSafeMode,
aDependencies, hasEmbeddedWebExtension) {
this.activeAddons.set(aId, {
bootstrapScope: null,
// a Symbol passed to this add-on, which it can use to identify itself
instanceID: Symbol(aId),
+ started: false,
});
// Mark the add-on as active for the crash reporter before loading
this.addAddonsToCrashReporter();
let activeAddon = this.activeAddons.get(aId);
// Locales only contain chrome and can't have bootstrap scripts
@@ -4332,22 +4435,28 @@ this.XPIProvider = {
let scope = activeAddon.bootstrapScope;
try {
method = scope[aMethod] || Cu.evalInSandbox(`${aMethod};`, scope);
} catch (e) {
// An exception will be caught if the expected method is not defined.
// That will be logged below.
}
- // Extensions are automatically deinitialized in the correct order at shutdown.
- if (aMethod == "shutdown" && aReason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
- activeAddon.disable = true;
- for (let addon of this.getDependentAddons(aAddon)) {
- if (addon.active)
- this.updateAddonDisabledState(addon);
+ if (aMethod == "startup") {
+ activeAddon.started = true;
+ } else if (aMethod == "shutdown") {
+ activeAddon.started = false;
+
+ // Extensions are automatically deinitialized in the correct order at shutdown.
+ if (aReason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
+ activeAddon.disable = true;
+ for (let addon of this.getDependentAddons(aAddon)) {
+ if (addon.active)
+ this.updateAddonDisabledState(addon);
+ }
}
}
let params = {
id: aAddon.id,
version: aAddon.version,
installPath: aFile.clone(),
resourceURI: getURIForResourceInFile(aFile, "")
--- a/toolkit/mozapps/extensions/jar.mn
+++ b/toolkit/mozapps/extensions/jar.mn
@@ -11,18 +11,19 @@ toolkit.jar:
* content/mozapps/extensions/extensions.xml (content/extensions.xml)
content/mozapps/extensions/updateinfo.xsl (content/updateinfo.xsl)
content/mozapps/extensions/about.xul (content/about.xul)
content/mozapps/extensions/about.js (content/about.js)
content/mozapps/extensions/blocklist.xul (content/blocklist.xul)
content/mozapps/extensions/blocklist.js (content/blocklist.js)
content/mozapps/extensions/blocklist.css (content/blocklist.css)
content/mozapps/extensions/blocklist.xml (content/blocklist.xml)
-* content/mozapps/extensions/update.xul (content/update.xul)
+ content/mozapps/extensions/update.html (content/update.html)
content/mozapps/extensions/update.js (content/update.js)
+ content/mozapps/extensions/update.css (content/update.css)
content/mozapps/extensions/eula.xul (content/eula.xul)
content/mozapps/extensions/eula.js (content/eula.js)
content/mozapps/extensions/newaddon.xul (content/newaddon.xul)
content/mozapps/extensions/newaddon.js (content/newaddon.js)
content/mozapps/extensions/pluginPrefs.xul (content/pluginPrefs.xul)
content/mozapps/extensions/gmpPrefs.xul (content/gmpPrefs.xul)
content/mozapps/extensions/OpenH264-license.txt (content/OpenH264-license.txt)
#endif
deleted file mode 100644
--- a/toolkit/themes/osx/mozapps/extensions/update.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-.throbber {
- list-style-image: url("chrome://global/skin/icons/loading.png");
- width: 16px;
- height: 16px;
- margin-top: 5px;
- margin-bottom: 5px;
- margin-inline-start: 5px;
- margin-inline-end: 2px;
-}
-
-@media (min-resolution: 2dppx) {
- .throbber {
- list-style-image: url("chrome://global/skin/icons/loading@2x.png");
- }
-}
-
-.alertBox {
- background-color: InfoBackground;
- color: InfoText;
- border: 1px outset InfoBackground;
- margin-left: 3px;
- margin-right: 3px;
- padding: 5px;
-}
--- a/toolkit/themes/osx/mozapps/jar.mn
+++ b/toolkit/themes/osx/mozapps/jar.mn
@@ -10,17 +10,16 @@ toolkit.jar:
skin/classic/mozapps/extensions/discover-logo.png (extensions/discover-logo.png)
skin/classic/mozapps/extensions/rating-won.png (extensions/rating-won.png)
skin/classic/mozapps/extensions/rating-not-won.png (extensions/rating-not-won.png)
skin/classic/mozapps/extensions/cancel.png (extensions/cancel.png)
skin/classic/mozapps/extensions/toolbarbutton-dropmarker.png (extensions/toolbarbutton-dropmarker.png)
skin/classic/mozapps/extensions/heart.png (extensions/heart.png)
skin/classic/mozapps/extensions/about.css (extensions/about.css)
* skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
- skin/classic/mozapps/extensions/update.css (extensions/update.css)
skin/classic/mozapps/extensions/eula.css (extensions/eula.css)
skin/classic/mozapps/extensions/blocklist.css (extensions/blocklist.css)
* skin/classic/mozapps/extensions/newaddon.css (extensions/newaddon.css)
skin/classic/mozapps/plugins/notifyPluginGeneric.png (plugins/notifyPluginGeneric.png)
skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png)
skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png)
skin/classic/mozapps/plugins/pluginBlocked-64.png (plugins/pluginBlocked-64.png)
skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png)
--- a/toolkit/themes/shared/non-mac.jar.inc.mn
+++ b/toolkit/themes/shared/non-mac.jar.inc.mn
@@ -56,17 +56,16 @@
skin/classic/global/tree/sort-dsc.png (../../windows/global/tree/sort-dsc.png)
skin/classic/global/tree/sort-asc-classic.png (../../windows/global/tree/sort-asc-classic.png)
skin/classic/global/tree/sort-dsc-classic.png (../../windows/global/tree/sort-dsc-classic.png)
skin/classic/mozapps/downloads/downloadButtons.png (../../windows/mozapps/downloads/downloadButtons.png)
skin/classic/mozapps/downloads/unknownContentType.css (../../windows/mozapps/downloads/unknownContentType.css)
skin/classic/mozapps/extensions/about.css (../../windows/mozapps/extensions/about.css)
skin/classic/mozapps/extensions/blocklist.css (../../windows/mozapps/extensions/blocklist.css)
- skin/classic/mozapps/extensions/update.css (../../windows/mozapps/extensions/update.css)
skin/classic/mozapps/extensions/discover-logo.png (../../windows/mozapps/extensions/discover-logo.png)
skin/classic/mozapps/extensions/rating-won.png (../../windows/mozapps/extensions/rating-won.png)
skin/classic/mozapps/extensions/rating-not-won.png (../../windows/mozapps/extensions/rating-not-won.png)
skin/classic/mozapps/extensions/cancel.png (../../windows/mozapps/extensions/cancel.png)
skin/classic/mozapps/extensions/eula.css (../../windows/mozapps/extensions/eula.css)
skin/classic/mozapps/handling/handling.css (../../windows/mozapps/handling/handling.css)
skin/classic/mozapps/plugins/pluginBlocked-64.png (../../windows/mozapps/plugins/pluginBlocked-64.png)
skin/classic/mozapps/plugins/pluginHelp-16.png (../../windows/mozapps/plugins/pluginHelp-16.png)
deleted file mode 100644
--- a/toolkit/themes/windows/mozapps/extensions/update.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-.throbber {
- list-style-image: url("chrome://global/skin/icons/loading.png");
- width: 16px;
- height: 16px;
- margin-top: 5px;
- margin-bottom: 5px;
- margin-inline-start: 5px;
- margin-inline-end: 2px;
-}
-
-@media (min-resolution: 1.1dppx) {
- .throbber {
- list-style-image: url("chrome://global/skin/icons/loading@2x.png");
- }
-}
-
-.alertBox {
- background-color: InfoBackground;
- color: InfoText;
- border: 1px outset InfoBackground;
- margin-left: 3px;
- margin-right: 3px;
- padding: 5px;
-}