diff --git a/browser/components/preferences/in-content/main.js b/browser/components/preferences/in-content/main.js
index e6605011e4e..fefff1c53ab 100644
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -97,6 +97,19 @@ var gMainPane = {
e10sCheckbox.checked = e10sPref.value || e10sTempPref.value;
#endif
+#ifdef MOZ_DEV_EDITION
+ Cu.import("resource://gre/modules/osfile.jsm");
+ let uAppData = OS.Constants.Path.userApplicationDataDir;
+ let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile");
+
+ setEventListener("separateProfileMode", "command", gMainPane.separateProfileModeChange);
+ let separateProfileModeCheckbox = document.getElementById("separateProfileMode");
+ setEventListener("getStarted", "click", gMainPane.onGetStarted);
+
+ OS.File.stat(ignoreSeparateProfile).then(() => separateProfileModeCheckbox.checked = false,
+ () => separateProfileModeCheckbox.checked = true);
+#endif
+
// Notify observers that the UI is now ready
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService)
@@ -154,6 +167,66 @@ var gMainPane = {
},
#endif
+#ifdef MOZ_DEV_EDITION
+ separateProfileModeChange: function ()
+ {
+ function quitApp() {
+ Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
+ }
+ function revertCheckbox(error) {
+ separateProfileModeCheckbox.checked = !separateProfileModeCheckbox.checked;
+ if (error) {
+ Cu.reportError("Failed to toggle separate profile mode: " + error);
+ }
+ }
+
+ const Cc = Components.classes, Ci = Components.interfaces;
+ let separateProfileModeCheckbox = document.getElementById("separateProfileMode");
+ let brandName = document.getElementById("bundleBrand").getString("brandShortName");
+ let bundle = document.getElementById("bundlePreferences");
+ let msg = bundle.getFormattedString(separateProfileModeCheckbox.checked ?
+ "featureEnableRequiresRestart" : "featureDisableRequiresRestart",
+ [brandName]);
+ let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
+ let shouldProceed = Services.prompt.confirm(window, title, msg)
+ if (shouldProceed) {
+ let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
+ .createInstance(Ci.nsISupportsPRBool);
+ Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
+ "restart");
+ shouldProceed = !cancelQuit.data;
+
+ if (shouldProceed) {
+ Cu.import("resource://gre/modules/osfile.jsm");
+ let uAppData = OS.Constants.Path.userApplicationDataDir;
+ let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile");
+
+ if (separateProfileModeCheckbox.checked) {
+ OS.File.remove(ignoreSeparateProfile).then(quitApp, revertCheckbox);
+ } else {
+ OS.File.writeAtomic(ignoreSeparateProfile, new Uint8Array()).then(quitApp, revertCheckbox);
+ }
+ return;
+ }
+ }
+
+ // Revert the checkbox in case we didn't quit
+ revertCheckbox();
+ },
+
+ onGetStarted: function (aEvent) {
+ const Cc = Components.classes, Ci = Components.interfaces;
+ let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Ci.nsIWindowMediator);
+ let win = wm.getMostRecentWindow("navigator:browser");
+
+ if (win) {
+ let accountsTab = win.gBrowser.addTab("about:accounts?action=migrateToDevEdition");
+ win.gBrowser.selectedTab = accountsTab;
+ }
+ },
+#endif
+
// HOME PAGE
/*
diff --git a/browser/components/preferences/in-content/main.xul b/browser/components/preferences/in-content/main.xul
index 78c4416fefb..c9c57e73590 100644
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -117,6 +117,17 @@
hidden="true">
+#ifdef MOZ_DEV_EDITION
+
+
+
+
+
+
+
+#endif
+
#ifdef E10S_TESTING_ONLY
@@ -126,13 +137,13 @@
+ label="&alwaysCheckDefault2.label;" accesskey="&alwaysCheckDefault2.accesskey;"/>
diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js
index 937479948dc..e8c46692e10 100644
--- a/browser/components/preferences/main.js
+++ b/browser/components/preferences/main.js
@@ -60,12 +60,87 @@ var gMainPane = {
this.updateBrowserStartupLastSession();
+#ifdef MOZ_DEV_EDITION
+ let separateProfileModeCheckbox = document.getElementById("separateProfileMode");
+ let listener = gMainPane.separateProfileModeChange.bind(gMainPane);
+ separateProfileModeCheckbox.addEventListener("command", listener);
+
+ let getStartedLink = document.getElementById("getStarted");
+ let syncListener = gMainPane.onGetStarted.bind(gMainPane);
+ getStartedLink.addEventListener("click", syncListener);
+
+ Cu.import("resource://gre/modules/osfile.jsm");
+ let uAppData = OS.Constants.Path.userApplicationDataDir;
+ let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile");
+
+ OS.File.stat(ignoreSeparateProfile).then(() => separateProfileModeCheckbox.checked = false,
+ () => separateProfileModeCheckbox.checked = true);
+#endif
+
// Notify observers that the UI is now ready
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService)
.notifyObservers(window, "main-pane-loaded", null);
},
+#ifdef MOZ_DEV_EDITION
+ separateProfileModeChange: function ()
+ {
+ function quitApp() {
+ Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
+ }
+ function revertCheckbox(error) {
+ separateProfileModeCheckbox.checked = !separateProfileModeCheckbox.checked;
+ if (error) {
+ Cu.reportError("Failed to toggle separate profile mode: " + error);
+ }
+ }
+
+ let separateProfileModeCheckbox = document.getElementById("separateProfileMode");
+ let brandName = document.getElementById("bundleBrand").getString("brandShortName");
+ let bundle = document.getElementById("bundlePreferences");
+ let msg = bundle.getFormattedString(separateProfileModeCheckbox.checked ?
+ "featureEnableRequiresRestart" : "featureDisableRequiresRestart",
+ [brandName]);
+ let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
+ let shouldProceed = Services.prompt.confirm(window, title, msg)
+ if (shouldProceed) {
+ let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
+ .createInstance(Ci.nsISupportsPRBool);
+ Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
+ "restart");
+ shouldProceed = !cancelQuit.data;
+
+ if (shouldProceed) {
+ Cu.import("resource://gre/modules/osfile.jsm");
+ let uAppData = OS.Constants.Path.userApplicationDataDir;
+ let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile");
+
+ if (separateProfileModeCheckbox.checked) {
+ OS.File.remove(ignoreSeparateProfile).then(quitApp, revertCheckbox);
+ } else {
+ OS.File.writeAtomic(ignoreSeparateProfile, new Uint8Array()).then(quitApp, revertCheckbox);
+ }
+ }
+ }
+
+ // Revert the checkbox in case we didn't quit
+ revertCheckbox();
+ },
+
+ onGetStarted: function (aEvent) {
+ const Cc = Components.classes, Ci = Components.interfaces;
+ let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Ci.nsIWindowMediator);
+ let win = wm.getMostRecentWindow("navigator:browser");
+
+ if (win) {
+ let accountsTab = win.gBrowser.addTab("about:accounts?action=migrateToDevEdition");
+ win.gBrowser.selectedTab = accountsTab;
+ }
+ },
+#endif
+
// HOME PAGE
/*
diff --git a/browser/components/preferences/main.xul b/browser/components/preferences/main.xul
index 8c27b8c8848..cd5d4508a96 100644
--- a/browser/components/preferences/main.xul
+++ b/browser/components/preferences/main.xul
@@ -77,17 +77,28 @@
+#ifdef MOZ_DEV_EDITION
+
+
+
+
+
+
+
+#endif
+
#ifdef HAVE_SHELL_SERVICE
+ label="&alwaysCheckDefault2.label;" accesskey="&alwaysCheckDefault2.accesskey;"/>
diff --git a/browser/locales/en-US/chrome/browser/preferences/main.dtd b/browser/locales/en-US/chrome/browser/preferences/main.dtd
index 2951b15dc36..95a44981fc7 100644
--- a/browser/locales/en-US/chrome/browser/preferences/main.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/main.dtd
@@ -31,10 +31,13 @@
-
+
-
-
+
+
+
+
+
diff --git a/browser/themes/linux/preferences/preferences.css b/browser/themes/linux/preferences/preferences.css
index f0565f955cf..947a5407c70 100644
--- a/browser/themes/linux/preferences/preferences.css
+++ b/browser/themes/linux/preferences/preferences.css
@@ -55,6 +55,11 @@ label.small {
}
/* General Pane */
+#useFirefoxSync,
+#getStarted {
+ font-size: 90%;
+}
+
#isNotDefaultLabel {
font-weight: bold;
}
diff --git a/browser/themes/osx/preferences/preferences.css b/browser/themes/osx/preferences/preferences.css
index 06d418f3c35..ffaf8de103a 100644
--- a/browser/themes/osx/preferences/preferences.css
+++ b/browser/themes/osx/preferences/preferences.css
@@ -169,6 +169,11 @@ caption {
/* General Pane */
+#useFirefoxSync,
+#getStarted {
+ font-size: 90%;
+}
+
#isNotDefaultLabel {
font-weight: bold;
}
diff --git a/browser/themes/shared/incontentprefs/preferences.css b/browser/themes/shared/incontentprefs/preferences.css
index ce284b6039f..644589605bd 100644
--- a/browser/themes/shared/incontentprefs/preferences.css
+++ b/browser/themes/shared/incontentprefs/preferences.css
@@ -110,6 +110,15 @@ treecol {
/* General Pane */
+#useFirefoxSync {
+ font-size: 90%;
+ -moz-margin-end: 8px !important;
+}
+
+#getStarted {
+ font-size: 90%;
+}
+
#isNotDefaultLabel {
font-weight: bold;
}
diff --git a/browser/themes/windows/preferences/preferences.css b/browser/themes/windows/preferences/preferences.css
index 1aa2deaa3b0..f63a5613e1a 100644
--- a/browser/themes/windows/preferences/preferences.css
+++ b/browser/themes/windows/preferences/preferences.css
@@ -55,6 +55,11 @@ label.small {
/* General Pane */
+#useFirefoxSync,
+#getStarted {
+ font-size: 90%;
+}
+
#isNotDefaultLabel {
font-weight: bold;
}
diff --git a/toolkit/profile/nsIToolkitProfileService.idl b/toolkit/profile/nsIToolkitProfileService.idl
index 316e8b05f77..bc0606ca1fe 100644
--- a/toolkit/profile/nsIToolkitProfileService.idl
+++ b/toolkit/profile/nsIToolkitProfileService.idl
@@ -29,6 +29,12 @@ interface nsIToolkitProfileService : nsISupports
* browser if no other profile is specified at runtime). This is the profile
* marked with Default=1 in profiles.ini and is usually the same as
* selectedProfile, except on Developer Edition.
+ *
+ * Developer Edition uses a profile named "dev-edition-default" as the
+ * default profile (which it creates if it doesn't exist), unless a special
+ * empty file named "ignore-dev-edition-profile" is present next to
+ * profiles.ini. In that case Developer Edition behaves the same as any
+ * other build of Firefox.
*/
attribute nsIToolkitProfile defaultProfile;
diff --git a/toolkit/profile/nsToolkitProfileService.cpp b/toolkit/profile/nsToolkitProfileService.cpp
index f6afd4a9989..47fb53ccdd1 100644
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -424,6 +424,22 @@ nsToolkitProfileService::Init()
nsToolkitProfile* currentProfile = nullptr;
+#ifdef MOZ_DEV_EDITION
+ nsCOMPtr ignoreSeparateProfile;
+ rv = mAppData->Clone(getter_AddRefs(ignoreSeparateProfile));
+ if (NS_FAILED(rv))
+ return rv;
+
+ rv = ignoreSeparateProfile->AppendNative(NS_LITERAL_CSTRING("ignore-dev-edition-profile"));
+ if (NS_FAILED(rv))
+ return rv;
+
+ bool shouldIgnoreSeparateProfile;
+ rv = ignoreSeparateProfile->Exists(&shouldIgnoreSeparateProfile);
+ if (NS_FAILED(rv))
+ return rv;
+#endif
+
unsigned int c = 0;
bool foundAuroraDefault = false;
for (c = 0; true; ++c) {
@@ -485,8 +501,9 @@ nsToolkitProfileService::Init()
this->SetDefaultProfile(currentProfile);
}
#ifdef MOZ_DEV_EDITION
- // Use the dev-edition-default profile if this is an Aurora build.
- if (name.EqualsLiteral("dev-edition-default")) {
+ // Use the dev-edition-default profile if this is an Aurora build and
+ // ignore-dev-edition-profile is not present.
+ if (name.EqualsLiteral("dev-edition-default") && !shouldIgnoreSeparateProfile) {
mChosen = currentProfile;
foundAuroraDefault = true;
}
@@ -498,7 +515,7 @@ nsToolkitProfileService::Init()
// on webapprt.
bool isFirefox = strcmp(gAppData->ID,
"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}") == 0;
- if (!foundAuroraDefault && isFirefox) {
+ if (!foundAuroraDefault && isFirefox && !shouldIgnoreSeparateProfile) {
// If a single profile exists, it may not be already marked as default.
// Do it now to avoid problems when we create the dev-edition-default profile.
if (!mChosen && mFirst && !mFirst->mNext)