Bug 732303 - Redesign safe mode dialog with the profile reset option. r=dolske, ui-r=limi
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1137,14 +1137,14 @@ pref("full-screen-api.enabled", true);
// True if the fullscreen API requires approval upon a domain entering fullscreen.
// Domains that have already had fullscreen permission granted won't re-request
// approval.
pref("full-screen-api.approval-required", true);
// Startup Crash Tracking
// number of startup crashes that can occur before starting into safe mode automatically
// (this pref has no effect if more than 6 hours have passed since the last crash)
-pref("toolkit.startup.max_resumed_crashes", 2);
+pref("toolkit.startup.max_resumed_crashes", 3);
// The maximum amount of decoded image data we'll willingly keep around (we
// might keep around more than this, but we'll try to get down to this value).
// (This is intentionally on the high side; see bug 746055.)
pref("image.mem.max_decoded_image_kb", 256000);
new file mode 100644
--- /dev/null
+++ b/browser/base/content/safeMode.css
@@ -0,0 +1,8 @@
+/* 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/. */
+
+#resetProfileFooter {
+ font-weight: bold;
+}
+
--- a/browser/base/content/safeMode.js
+++ b/browser/base/content/safeMode.js
@@ -1,126 +1,86 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/.
-Components.utils.import("resource://gre/modules/AddonManager.jsm");
+let Cc = Components.classes;
+let Ci = Components.interfaces;
+let Cu = Components.utils;
+
+const appStartup = Services.startup;
+
+let defaultToReset = false;
function restartApp() {
- var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
- .getService(Components.interfaces.nsIAppStartup);
appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
}
-function clearAllPrefs() {
- var prefService = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService);
- prefService.resetUserPrefs();
-
- // Remove the pref-overrides dir, if it exists
- try {
- var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties);
- const NS_APP_PREFS_OVERRIDE_DIR = "PrefDOverride";
- var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
- Components.interfaces.nsIFile);
- prefOverridesDir.remove(true);
- } catch (ex) {
- Components.utils.reportError(ex);
- }
+function resetProfile() {
+ // Set the reset profile environment variable.
+ let env = Cc["@mozilla.org/process/environment;1"]
+ .getService(Ci.nsIEnvironment);
+ env.set("MOZ_RESET_PROFILE_RESTART", "1");
}
-function restoreDefaultBookmarks() {
- var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- prefBranch.setBoolPref("browser.bookmarks.restore_default_bookmarks", true);
+function showResetDialog() {
+ // Prompt the user to confirm the reset.
+ let retVals = {
+ reset: false,
+ };
+ window.openDialog("chrome://global/content/resetProfile.xul", null,
+ "chrome,modal,centerscreen,titlebar,dialog=yes", retVals);
+ if (!retVals.reset)
+ return;
+ resetProfile();
+ restartApp();
}
-function deleteLocalstore() {
- const nsIDirectoryServiceContractID = "@mozilla.org/file/directory_service;1";
- const nsIProperties = Components.interfaces.nsIProperties;
- var directoryService = Components.classes[nsIDirectoryServiceContractID]
- .getService(nsIProperties);
- var localstoreFile = directoryService.get("LStoreS", Components.interfaces.nsIFile);
- try {
- localstoreFile.remove(false);
- } catch(e) {
- Components.utils.reportError(e);
+function onDefaultButton() {
+ if (defaultToReset) {
+ // Restart to reset the profile.
+ resetProfile();
+ restartApp();
+ // Return false to prevent starting into safe mode while restarting.
+ return false;
+ } else {
+ // Continue in safe mode. No restart needed.
+ return true;
}
}
-function disableAddons() {
- AddonManager.getAllAddons(function(aAddons) {
- aAddons.forEach(function(aAddon) {
- if (aAddon.type == "theme") {
- // Setting userDisabled to false on the default theme activates it,
- // disables all other themes and deactivates the applied persona, if
- // any.
- const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
- if (aAddon.id == DEFAULT_THEME_ID)
- aAddon.userDisabled = false;
- }
- else {
- aAddon.userDisabled = true;
- }
- });
-
- restartApp();
- });
+function onCancel() {
+ appStartup.quit(appStartup.eForceQuit);
}
-function restoreDefaultSearchEngines() {
- var searchService = Components.classes["@mozilla.org/browser/search-service;1"]
- .getService(Components.interfaces.nsIBrowserSearchService);
-
- searchService.restoreDefaultEngines();
-}
-
-function onOK() {
- try {
- if (document.getElementById("resetUserPrefs").checked)
- clearAllPrefs();
- if (document.getElementById("deleteBookmarks").checked)
- restoreDefaultBookmarks();
- if (document.getElementById("resetToolbars").checked)
- deleteLocalstore();
- if (document.getElementById("restoreSearch").checked)
- restoreDefaultSearchEngines();
- if (document.getElementById("disableAddons").checked) {
- disableAddons();
- // disableAddons will asynchronously restart the application
- return false;
- }
- } catch(e) {
+function onExtra1() {
+ if (defaultToReset) {
+ // Continue in safe mode
+ window.close();
+ return true;
+ } else {
+ // The reset dialog will handle starting the reset process if the user confirms.
+ showResetDialog();
}
-
- restartApp();
return false;
}
-function onCancel() {
- var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
- .getService(Components.interfaces.nsIAppStartup);
- appStartup.quit(appStartup.eForceQuit);
-}
-
function onLoad() {
- var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
- .getService(Components.interfaces.nsIAppStartup);
-
+ let dialog = document.documentElement;
if (appStartup.automaticSafeModeNecessary) {
document.getElementById("autoSafeMode").hidden = false;
- document.getElementById("manualSafeMode").hidden = true;
+ document.getElementById("safeMode").hidden = true;
+ if (resetSupported()) {
+ populateResetPane("resetProfileItems");
+ document.getElementById("resetProfile").hidden = false;
+ } else {
+ // Hide the reset button is it's not supported.
+ document.documentElement.getButton("extra1").hidden = true;
+ }
+ } else {
+ if (!resetSupported()) {
+ // Hide the reset button and text if it's not supported.
+ document.documentElement.getButton("extra1").hidden = true;
+ document.getElementById("resetProfileInstead").hidden = true;
+ }
}
-
- document.getElementById("tasks")
- .addEventListener("CheckboxStateChange", UpdateOKButtonState, false);
}
-
-function UpdateOKButtonState() {
- document.documentElement.getButton("accept").disabled =
- !document.getElementById("resetUserPrefs").checked &&
- !document.getElementById("deleteBookmarks").checked &&
- !document.getElementById("resetToolbars").checked &&
- !document.getElementById("disableAddons").checked &&
- !document.getElementById("restoreSearch").checked;
-}
--- a/browser/base/content/safeMode.xul
+++ b/browser/base/content/safeMode.xul
@@ -5,56 +5,59 @@
# 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/.
<!DOCTYPE prefwindow [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % safeModeDTD SYSTEM "chrome://browser/locale/safeMode.dtd" >
%safeModeDTD;
-<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
-%browserDTD;
+<!ENTITY % resetProfileDTD SYSTEM "chrome://global/locale/resetProfile.dtd" >
+%resetProfileDTD;
]>
<?xml-stylesheet href="chrome://global/skin/"?>
+<?xml-stylesheet href="chrome://browser/content/safeMode.css"?>
<dialog id="safeModeDialog"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&safeModeDialog.title;"
- buttons="accept,cancel,extra1"
- buttonlabelaccept="&changeAndRestartButton.label;"
-#ifdef XP_WIN
- buttonlabelcancel="&quitApplicationCmdWin.label;"
-#else
- buttonlabelcancel="&quitApplicationCmd.label;"
-#endif
- buttonlabelextra1="&continueButton.label;"
- width="&window.width;"
- ondialogaccept="return onOK()"
- ondialogcancel="onCancel()"
- ondialogextra1="window.close()"
- onload="onLoad();"
- buttondisabledaccept="true">
+ buttons="accept,extra1"
+ buttonlabelaccept="&startSafeMode.label;"
+ buttonlabelextra1="&resetProfile.label;"
+ maxwidth="&window.maxWidth;"
+ ondialogaccept="return onDefaultButton()"
+ ondialogcancel="onCancel();"
+ ondialogextra1="return onExtra1()"
+ onload="onLoad()">
+ <script type="application/javascript" src="chrome://global/content/resetProfile.js"/>
<script type="application/javascript" src="chrome://browser/content/safeMode.js"/>
- <stringbundle id="preferencesBundle" src="chrome://browser/locale/preferences/preferences.properties"/>
-
<vbox id="autoSafeMode" hidden="true">
- <label class="header plain" value="&autoSafeModeIntro.label;"/>
- <description>&autoSafeModeDescription.label;</description>
+ <description>&autoSafeModeDescription2.label;</description>
+ </vbox>
+
+ <vbox id ="safeMode">
+ <label>&safeModeDescription3.label;</label>
+ <separator class="thin"/>
+ <label>&safeModeDescription4.label;</label>
+ <separator class="thin"/>
+ <label id="resetProfileInstead">&resetProfileInstead.label;</label>
</vbox>
- <description id="manualSafeMode">&safeModeDescription.label;</description>
+ <vbox id="resetProfile" hidden="true">
+ <label>&resetProfile.dialog.items2.label;</label>
+
+ <vbox id="resetProfileItems" class="indent">
+ </vbox>
+
+ <separator class="thin"/>
+
+ <label id="resetProfileFooter">&resetProfileFooter.label;</label>
+
+ <label>&safeModeInstead.label;</label>
+
+ <separator/>
+ </vbox>
<separator class="thin"/>
-
- <label value="&safeModeDescription2.label;"/>
- <vbox id="tasks">
- <checkbox id="disableAddons" label="&disableAddons.label;" accesskey="&disableAddons.accesskey;"/>
- <checkbox id="resetToolbars" label="&resetToolbars.label;" accesskey="&resetToolbars.accesskey;"/>
- <checkbox id="deleteBookmarks" label="&deleteBookmarks.label;" accesskey="&deleteBookmarks.accesskey;"/>
- <checkbox id="resetUserPrefs" label="&resetUserPrefs.label;" accesskey="&resetUserPrefs.accesskey;"/>
- <checkbox id="restoreSearch" label="&restoreSearch.label;" accesskey="&restoreSearch.accesskey;"/>
- </vbox>
-
- <separator class="thin"/>
</dialog>
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -66,16 +66,17 @@ browser.jar:
* content/browser/sync/quota.xul (content/sync/quota.xul)
content/browser/sync/quota.js (content/sync/quota.js)
content/browser/sync/utils.js (content/sync/utils.js)
content/browser/sync/progress.js (content/sync/progress.js)
* content/browser/sync/progress.xhtml (content/sync/progress.xhtml)
#endif
* content/browser/openLocation.js (content/openLocation.js)
* content/browser/openLocation.xul (content/openLocation.xul)
+* content/browser/safeMode.css (content/safeMode.css)
* content/browser/safeMode.js (content/safeMode.js)
* content/browser/safeMode.xul (content/safeMode.xul)
* content/browser/sanitize.js (content/sanitize.js)
* content/browser/sanitize.xul (content/sanitize.xul)
* content/browser/sanitizeDialog.js (content/sanitizeDialog.js)
content/browser/sanitizeDialog.css (content/sanitizeDialog.css)
* content/browser/tabbrowser.css (content/tabbrowser.css)
* content/browser/tabbrowser.xml (content/tabbrowser.xml)
--- a/browser/locales/en-US/chrome/browser/safeMode.dtd
+++ b/browser/locales/en-US/chrome/browser/safeMode.dtd
@@ -1,30 +1,19 @@
<!-- 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 safeModeDialog.title "&brandShortName; Safe Mode">
-<!ENTITY window.width "37em">
-
-<!ENTITY autoSafeModeIntro.label "&brandShortName; Closed Unexpectedly While Starting">
-<!ENTITY autoSafeModeDescription.label "We sincerely apologize for the inconvenience. &brandShortName; is now running in Safe Mode, which temporarily disables your custom settings, themes, and extensions.">
+<!ENTITY window.maxWidth "400">
-<!ENTITY safeModeDescription.label "&brandShortName; is now running in Safe Mode, which temporarily disables your custom settings, themes, and extensions.">
-<!ENTITY safeModeDescription2.label "You can make some or all of these changes permanent:">
-
-<!ENTITY disableAddons.label "Disable all add-ons">
-<!ENTITY disableAddons.accesskey "D">
+<!ENTITY startSafeMode.label "Start in Safe Mode">
+<!ENTITY resetProfile.label "Reset &brandShortName;">
-<!ENTITY resetToolbars.label "Reset toolbars and controls">
-<!ENTITY resetToolbars.accesskey "R">
+<!ENTITY safeModeDescription3.label "Safe Mode is a special mode of &brandShortName; that can be used to troubleshoot issues.">
+<!ENTITY safeModeDescription4.label "Your add-ons and custom settings will be temporarily disabled.">
-<!ENTITY deleteBookmarks.label "Delete all bookmarks except for backups">
-<!ENTITY deleteBookmarks.accesskey "b">
+<!ENTITY resetProfileInstead.label "You can also Reset &brandShortName; if you want to start fresh.">
-<!ENTITY resetUserPrefs.label "Reset all user preferences to &brandShortName; defaults">
-<!ENTITY resetUserPrefs.accesskey "p">
-
-<!ENTITY restoreSearch.label "Restore default search engines">
-<!ENTITY restoreSearch.accesskey "s">
-
-<!ENTITY changeAndRestartButton.label "Make Changes and Restart">
-<!ENTITY continueButton.label "Continue in Safe Mode">
+<!-- LOCALIZATION NOTE (autoSafeModeDescription2.label safeModeInstead.label resetProfileFooter.label): Shown on the safe mode dialog after multiple startup crashes. See also chrome/global/resetProfile.dtd -->
+<!ENTITY autoSafeModeDescription2.label "&brandShortName; closed unexpectedly while starting. This might be caused by add-ons or other problems. You can try to resolve the problem by resetting &brandShortName; to its default state or troubleshooting in Safe Mode.">
+<!ENTITY resetProfileFooter.label "Everything else will be reset to factory defaults.">
+<!ENTITY safeModeInstead.label "If you don't want this, you can continue in Safe Mode to do your own troubleshooting with your add-ons and custom settings temporarily disabled.">
--- a/toolkit/content/aboutSupport.js
+++ b/toolkit/content/aboutSupport.js
@@ -1,16 +1,16 @@
# -*- Mode: js2; indent-tabs-mode: nil; js2-basic-offset: 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/.
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+let Cc = Components.classes;
+let Ci = Components.interfaces;
+let Cu = Components.utils;
Components.utils.import("resource://gre/modules/AddonManager.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
const ELLIPSIS = Services.prefs.getComplexValue("intl.ellipsis",
Ci.nsIPrefLocalizedString).data;
// We use a preferences whitelist to make sure we only show preferences that
@@ -574,33 +574,18 @@ function openProfileDirectory() {
"nsILocalFile", "initWithPath");
new nsLocalFile(profileDir).reveal();
}
/**
* Profile reset is only supported for the default profile if the appropriate migrator exists.
*/
function populateResetBox() {
- let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]
- .getService(Ci.nsIToolkitProfileService);
- let currentProfileDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
-
-#expand const MOZ_APP_NAME = "__MOZ_APP_NAME__";
-#expand const MOZ_BUILD_APP = "__MOZ_BUILD_APP__";
-
- // Only show the reset box for the default profile if the self-migrator used for reset exists.
- try {
- if (!currentProfileDir.equals(profileService.selectedProfile.rootDir) ||
- !("@mozilla.org/profile/migrator;1?app=" + MOZ_BUILD_APP + "&type=" + MOZ_APP_NAME in Cc))
- return;
+ if (resetSupported())
document.getElementById("reset-box").style.visibility = "visible";
- } catch (e) {
- // Catch exception when there is no selected profile.
- Cu.reportError(e);
- }
}
/**
* Restart the application to reset the profile.
*/
function resetProfileAndRestart() {
let branding = Services.strings.createBundle("chrome://branding/locale/brand.properties");
let brandShortName = branding.GetStringFromName("brandShortName");
--- a/toolkit/content/aboutSupport.xhtml
+++ b/toolkit/content/aboutSupport.xhtml
@@ -16,16 +16,18 @@
<head>
<title>&aboutSupport.pageTitle;</title>
<link rel="stylesheet" href="chrome://global/skin/aboutSupport.css"
type="text/css"/>
<script type="application/javascript;version=1.7"
src="chrome://global/content/aboutSupport.js"/>
+ <script type="application/javascript;version=1.7"
+ src="chrome://global/content/resetProfile.js"/>
</head>
<body dir="&locale.dir;">
<div id="reset-box" style="visibility: hidden">
<h3>&resetProfile.title;</h3>
<p>&resetProfile.description;</p>
<button onclick="resetProfileAndRestart()">
--- a/toolkit/content/resetProfile.js
+++ b/toolkit/content/resetProfile.js
@@ -1,35 +1,80 @@
/* 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/. */
Components.utils.import("resource://gre/modules/Services.jsm");
+let Cc = Components.classes;
+let Ci = Components.interfaces;
+
// based on onImportItemsPageShow from migration.js
+function populateResetPane(aContainerID) {
+ let resetProfileItems = document.getElementById(aContainerID);
+ try {
+ let dataTypes = getMigratedData();
+ for (let dataType of dataTypes) {
+ let label = document.createElement("label");
+ label.setAttribute("value", dataType);
+ resetProfileItems.appendChild(label);
+ }
+ } catch (ex) {
+ Cu.reportError(ex);
+ }
+}
+
function onResetProfileLoad() {
+ populateResetPane("migratedItems");
+}
+
+/**
+ * Check if reset is supported for the currently running profile.
+ *
+ * @return boolean whether reset is supported.
+ */
+function resetSupported() {
+ let profileService = Cc["@mozilla.org/toolkit/profile-service;1"].
+ getService(Ci.nsIToolkitProfileService);
+ let currentProfileDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
+
+#expand const MOZ_APP_NAME = "__MOZ_APP_NAME__";
+#expand const MOZ_BUILD_APP = "__MOZ_BUILD_APP__";
+
+ // Reset is only supported for the default profile if the self-migrator used for reset exists.
+ try {
+ return currentProfileDir.equals(profileService.selectedProfile.rootDir) &&
+ ("@mozilla.org/profile/migrator;1?app=" + MOZ_BUILD_APP + "&type=" + MOZ_APP_NAME in Cc);
+ } catch (e) {
+ // Catch exception when there is no selected profile.
+ Cu.reportError(e);
+ }
+ return false;
+}
+
+function getMigratedData() {
#expand const MOZ_BUILD_APP = "__MOZ_BUILD_APP__";
#expand const MOZ_APP_NAME = "__MOZ_APP_NAME__";
const MAX_MIGRATED_TYPES = 16;
- var migratedItems = document.getElementById("migratedItems");
- var bundle = Services.strings.createBundle("chrome://" + MOZ_BUILD_APP +
+ let bundle = Services.strings.createBundle("chrome://" + MOZ_BUILD_APP +
"/locale/migration/migration.properties");
// Loop over possible data to migrate to give the user a list of what will be preserved. This
- // assumes that if the string for the data exists then it will be migrated since calling
+ // assumes that if the string for the data exists, then it will be migrated because calling
// getMigrateData now won't give the correct result.
- for (var i = 1; i < MAX_MIGRATED_TYPES; ++i) {
- var itemID = Math.pow(2, i);
+ let dataTypes = [];
+ for (let i = 1; i < MAX_MIGRATED_TYPES; ++i) {
+ let itemID = Math.pow(2, i);
try {
- var checkbox = document.createElement("label");
- checkbox.setAttribute("value", bundle.GetStringFromName(itemID + "_" + MOZ_APP_NAME));
- migratedItems.appendChild(checkbox);
+ let typeName = bundle.GetStringFromName(itemID + "_" + MOZ_APP_NAME);
+ dataTypes.push(typeName);
} catch (x) {
// Catch exceptions when the string for a data type doesn't exist because it's not migrated
}
}
+ return dataTypes;
}
function onResetProfileAccepted() {
- var retVals = window.arguments[0];
+ let retVals = window.arguments[0];
retVals.reset = true;
}
--- a/toolkit/content/resetProfile.xul
+++ b/toolkit/content/resetProfile.xul
@@ -22,15 +22,15 @@
ondialogaccept="return onResetProfileAccepted();"
ondialogcancel="window.close();"
onload="onResetProfileLoad();">
<script type="application/javascript" src="chrome://global/content/resetProfile.js"/>
<description>&resetProfile.dialog.description;</description>
- <label value="&resetProfile.dialog.items.label;"/>
+ <label value="&resetProfile.dialog.items2.label;"/>
<vbox id="migratedItems">
</vbox>
<label id="resetProfileFooter" value="&resetProfile.dialog.footer.label;"/>
</dialog>
--- a/toolkit/locales/en-US/chrome/global/resetProfile.dtd
+++ b/toolkit/locales/en-US/chrome/global/resetProfile.dtd
@@ -1,13 +1,13 @@
<!-- 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 resetProfile.dialog.title "Reset &brandShortName;">
<!ENTITY resetProfile.dialog.description "Are you sure you want to reset &brandShortName; to its initial state?">
-<!ENTITY resetProfile.dialog.items.label "The following will be preserved:">
+<!ENTITY resetProfile.dialog.items2.label "&brandShortName; will try to preserve your:">
<!ENTITY resetProfile.dialog.footer.label "&brandShortName; will restart and everything else will be removed.">
<!ENTITY resetProfile.dialog.button.label "Reset &brandShortName;">
<!ENTITY resetProfile.title "Reset &brandShortName; to its default state">
<!ENTITY resetProfile.description "If you're having major problems which you can't resolve, start fresh with only your essential information.">
<!ENTITY resetProfile.button.label "Reset &brandShortName;">