--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -240,17 +240,17 @@ pref("browser.shell.mostRecentDateSetAsD
pref("browser.shell.skipDefaultBrowserCheckOnFirstRun", true);
pref("browser.shell.didSkipDefaultBrowserCheckOnFirstRun", false);
pref("browser.shell.defaultBrowserCheckCount", 0);
pref("browser.defaultbrowser.notificationbar", false);
// 0 = blank, 1 = home (browser.startup.homepage), 2 = last visited page, 3 = resume previous browser session
// The behavior of option 3 is detailed at: http://wiki.mozilla.org/Session_Restore
pref("browser.startup.page", 1);
-pref("browser.startup.homepage", "chrome://branding/locale/browserconfig.properties");
+pref("browser.startup.homepage", "about:home");
// Whether we should skip the homepage when opening the first-run page
pref("browser.startup.firstrunSkipsHomepage", true);
// Show an about:blank window as early as possible for quick startup feedback.
// Held to nightly on Linux due to bug 1450626.
// Disabled on Mac because the bouncing dock icon already provides feedback.
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) && defined(NIGHTLY_BUILD)
pref("browser.startup.blankWindow", true);
--- a/browser/base/content/browser-customization.js
+++ b/browser/base/content/browser-customization.js
@@ -41,18 +41,16 @@ var CustomizationHandler = {
PlacesToolbarHelper.customizeStart();
},
_customizationEnding(aDetails) {
// Update global UI elements that may have been added or removed
if (aDetails.changed) {
gURLBar = document.getElementById("urlbar");
- gHomeButton.updateTooltip();
-
if (AppConstants.platform != "macosx")
updateEditUIVisibility();
// Hacky: update the PopupNotifications' object's reference to the iconBox,
// if it already exists, since it may have changed if the URL bar was
// added/removed.
if (!window.__lookupGetter__("PopupNotifications")) {
PopupNotifications.iconBox =
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -25,16 +25,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
CustomizableUI: "resource:///modules/CustomizableUI.jsm",
Deprecated: "resource://gre/modules/Deprecated.jsm",
DownloadsCommon: "resource:///modules/DownloadsCommon.jsm",
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm",
+ HomePage: "resource:///modules/HomePage.jsm",
LightweightThemeConsumer: "resource://gre/modules/LightweightThemeConsumer.jsm",
LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
Log: "resource://gre/modules/Log.jsm",
LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
NetUtil: "resource://gre/modules/NetUtil.jsm",
NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm",
PageActions: "resource:///modules/PageActions.jsm",
@@ -1467,21 +1468,16 @@ var gBrowserInit = {
PanelUI.init();
UpdateUrlbarSearchSplitterState();
BookmarkingUI.init();
BrowserSearch.delayedStartupInit();
AutoShowBookmarksToolbar.init();
- Services.prefs.addObserver(gHomeButton.prefDomain, gHomeButton);
-
- var homeButton = document.getElementById("home-button");
- gHomeButton.updateTooltip(homeButton);
-
let safeMode = document.getElementById("helpSafeMode");
if (Services.appinfo.inSafeMode) {
safeMode.label = safeMode.getAttribute("stoplabel");
safeMode.accesskey = safeMode.getAttribute("stopaccesskey");
}
// BiDi UI
gBidiUI = isBidiEnabled();
@@ -1918,22 +1914,16 @@ var gBrowserInit = {
Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-origin-blocked");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-confirmation");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
window.messageManager.removeMessageListener("Browser:URIFixup", gKeywordURIFixup);
window.messageManager.removeMessageListener("Browser:LoadURI", RedirectLoad);
- try {
- Services.prefs.removeObserver(gHomeButton.prefDomain, gHomeButton);
- } catch (ex) {
- Cu.reportError(ex);
- }
-
if (AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
MenuTouchModeObserver.uninit();
}
BrowserOffline.uninit();
IndexedDBPromptHelper.uninit();
CanvasPermissionPromptHelper.uninit();
WebAuthnPromptHelper.uninit();
PanelUI.uninit();
@@ -2231,17 +2221,17 @@ function BrowserReloadSkipCache() {
}
var BrowserHome = BrowserGoHome;
function BrowserGoHome(aEvent) {
if (aEvent && "button" in aEvent &&
aEvent.button == 2) // right-click: do nothing
return;
- var homePage = gHomeButton.getHomePage();
+ var homePage = HomePage.get();
var where = whereToOpenLink(aEvent, false, true);
var urls;
var notifyObservers;
// Home page should open in a new tab when current tab is an app tab
if (where == "current" &&
gBrowser &&
gBrowser.selectedTab.pinned)
@@ -3308,29 +3298,23 @@ function goBackFromErrorPage() {
}
}
/**
* Return the default start page for the cases when the user's own homepage is
* infected, so we can get them somewhere safe.
*/
function getDefaultHomePage() {
- // Get the start page from the *default* pref branch, not the user's
- var prefs = Services.prefs.getDefaultBranch(null);
- var url = BROWSER_NEW_TAB_URL;
+ let url = BROWSER_NEW_TAB_URL;
if (PrivateBrowsingUtils.isWindowPrivate(window))
return url;
- try {
- url = prefs.getComplexValue("browser.startup.homepage",
- Ci.nsIPrefLocalizedString).data;
- // If url is a pipe-delimited set of pages, just take the first one.
- if (url.includes("|"))
- url = url.split("|")[0];
- } catch (e) {
- Cu.reportError("Couldn't get homepage pref: " + e);
+ url = HomePage.getDefault();
+ // If url is a pipe-delimited set of pages, just take the first one.
+ if (url.includes("|")) {
+ url = url.split("|")[0];
}
return url;
}
function BrowserFullScreen() {
window.fullScreen = !window.fullScreen;
}
@@ -3663,17 +3647,17 @@ function openHomeDialog(aURL) {
}
var pressedVal = Services.prompt.confirmEx(window, promptTitle, promptMsg,
Services.prompt.STD_YES_NO_BUTTONS,
null, null, null, null, {value: 0});
if (pressedVal == 0) {
try {
- Services.prefs.setStringPref("browser.startup.homepage", aURL);
+ HomePage.set(aURL);
} catch (ex) {
dump("Failed to set the home page.\n" + ex + "\n");
}
}
}
var newTabButtonObserver = {
onDragOver(aEvent) {
@@ -4432,17 +4416,17 @@ function OpenBrowserWindow(options) {
} else {
// forget about the charset information.
win = window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no" + extraFeatures, defaultArgs);
}
win.addEventListener("MozAfterPaint", () => {
TelemetryStopwatch.finish("FX_NEW_WINDOW_MS", telemetryObj);
if (Services.prefs.getIntPref("browser.startup.page") == 1
- && defaultArgs == handler.startPage) {
+ && defaultArgs == HomePage.get()) {
// A notification for when a user has triggered their homepage. This is used
// to display a doorhanger explaining that an extension has modified the
// homepage, if necessary.
Services.obs.notifyObservers(win, "browser-open-homepage-start");
}
}, {once: true});
return win;
@@ -5932,57 +5916,16 @@ var gUIDensity = {
}
}
TabsInTitlebar.update();
gBrowser.tabContainer.uiDensityChanged();
},
};
-var gHomeButton = {
- prefDomain: "browser.startup.homepage",
- observe(aSubject, aTopic, aPrefName) {
- if (aTopic != "nsPref:changed" || aPrefName != this.prefDomain)
- return;
-
- this.updateTooltip();
- },
-
- updateTooltip(homeButton) {
- if (!homeButton)
- homeButton = document.getElementById("home-button");
- if (homeButton) {
- var homePage = this.getHomePage();
- homePage = homePage.replace(/\|/g, ", ");
- if (["about:home", "about:newtab"].includes(homePage.toLowerCase()))
- homeButton.setAttribute("tooltiptext", homeButton.getAttribute("aboutHomeOverrideTooltip"));
- else
- homeButton.setAttribute("tooltiptext", homePage);
- }
- },
-
- getHomePage() {
- var url;
- try {
- url = Services.prefs.getComplexValue(this.prefDomain,
- Ci.nsIPrefLocalizedString).data;
- } catch (e) {
- }
-
- // use this if we can't find the pref
- if (!url) {
- var configBundle = Services.strings
- .createBundle("chrome://branding/locale/browserconfig.properties");
- url = configBundle.GetStringFromName(this.prefDomain);
- }
-
- return url;
- },
-};
-
const nodeToTooltipMap = {
"bookmarks-menu-button": "bookmarksMenuButton.tooltip",
"context-reload": "reloadButton.tooltip",
"context-stop": "stopButton.tooltip",
"downloads-button": "downloads.tooltip",
"fullscreen-button": "fullscreenButton.tooltip",
"appMenu-fullscreen-button": "fullscreenButton.tooltip",
"new-window-button": "newWindowButton.tooltip",
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -761,17 +761,17 @@
label="&homeButton.label;"
ondragover="homeButtonObserver.onDragOver(event)"
ondragenter="homeButtonObserver.onDragOver(event)"
ondrop="homeButtonObserver.onDrop(event)"
ondragexit="homeButtonObserver.onDragExit(event)"
key="goHome"
onclick="BrowserGoHome(event);"
cui-areatype="toolbar"
- aboutHomeOverrideTooltip="&homeButton.defaultPage.tooltip;"/>
+ tooltiptext="&homeButton.defaultPage.tooltip;"/>
<toolbarspring cui-areatype="toolbar" class="chromeclass-toolbar-additional"/>
<toolbaritem id="urlbar-container" flex="400" persist="width"
removable="false"
class="chromeclass-location" overflows="false">
<textbox id="urlbar" flex="1"
placeholder="&urlbar.placeholder2;"
defaultPlaceholder="&urlbar.placeholder2;"
focused="true"
--- a/browser/base/content/test/general/browser_homeDrop.js
+++ b/browser/base/content/test/general/browser_homeDrop.js
@@ -1,18 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
let HOMEPAGE_PREF = "browser.startup.homepage";
- let homepageStr = Cc["@mozilla.org/supports-string;1"]
- .createInstance(Ci.nsISupportsString);
- homepageStr.data = "about:mozilla";
- await pushPrefs([HOMEPAGE_PREF, homepageStr, Ci.nsISupportsString]);
+ await pushPrefs([HOMEPAGE_PREF, "about:mozilla"]);
let EventUtils = {};
Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
// Since synthesizeDrop triggers the srcElement, need to use another button.
let dragSrcElement = document.getElementById("downloads-button");
ok(dragSrcElement, "Downloads button exists");
let homeButton = document.getElementById("home-button");
deleted file mode 100644
--- a/browser/branding/aurora/locales/browserconfig.properties
+++ /dev/null
@@ -1,6 +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/.
-
-# Do NOT localize or otherwise change these values
-browser.startup.homepage=about:home
--- a/browser/branding/aurora/locales/jar.mn
+++ b/browser/branding/aurora/locales/jar.mn
@@ -6,9 +6,8 @@
[localization] @AB_CD@.jar:
branding (en-US/**/*.ftl)
@AB_CD@.jar:
% locale branding @AB_CD@ %locale/branding/
# Aurora branding only exists in en-US
locale/branding/brand.dtd (en-US/brand.dtd)
locale/branding/brand.properties (en-US/brand.properties)
- locale/branding/browserconfig.properties
deleted file mode 100644
--- a/browser/branding/nightly/locales/browserconfig.properties
+++ /dev/null
@@ -1,6 +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/.
-
-# Do NOT localize or otherwise change these values
-browser.startup.homepage=about:home
--- a/browser/branding/nightly/locales/jar.mn
+++ b/browser/branding/nightly/locales/jar.mn
@@ -6,9 +6,8 @@
[localization] @AB_CD@.jar:
branding (en-US/**/*.ftl)
@AB_CD@.jar:
% locale branding @AB_CD@ %locale/branding/
# Nightly branding only exists in en-US
locale/branding/brand.dtd (en-US/brand.dtd)
locale/branding/brand.properties (en-US/brand.properties)
- locale/branding/browserconfig.properties
deleted file mode 100644
--- a/browser/branding/official/locales/browserconfig.properties
+++ /dev/null
@@ -1,6 +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/.
-
-# Do NOT localize or otherwise change these values
-browser.startup.homepage=about:home
--- a/browser/branding/official/locales/jar.mn
+++ b/browser/branding/official/locales/jar.mn
@@ -5,9 +5,8 @@
[localization] @AB_CD@.jar:
branding (%*.ftl)
@AB_CD@.jar:
% locale branding @AB_CD@ %locale/branding/
locale/branding/brand.dtd (%brand.dtd)
locale/branding/brand.properties (%brand.properties)
- locale/branding/browserconfig.properties
deleted file mode 100644
--- a/browser/branding/unofficial/locales/browserconfig.properties
+++ /dev/null
@@ -1,6 +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/.
-
-# Do NOT localize or otherwise change these values
-browser.startup.homepage=about:home
--- a/browser/branding/unofficial/locales/jar.mn
+++ b/browser/branding/unofficial/locales/jar.mn
@@ -6,9 +6,8 @@
[localization] @AB_CD@.jar:
branding (en-US/**/*.ftl)
@AB_CD@.jar:
% locale branding @AB_CD@ %locale/branding/
# Unofficial branding only exists in en-US
locale/branding/brand.dtd (en-US/brand.dtd)
locale/branding/brand.properties (en-US/brand.properties)
- locale/branding/browserconfig.properties
--- a/browser/components/enterprisepolicies/tests/browser/browser_policy_set_homepage.js
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policy_set_homepage.js
@@ -1,22 +1,25 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
+ChromeUtils.defineModuleGetter(this, "HomePage",
+ "resource:///modules/HomePage.jsm");
+
registerCleanupFunction(function restore_pref_values() {
// These two prefs are set as user prefs in case the "Locked"
// option from this policy was not used. In this case, it won't
// be tracked nor restored by the PoliciesPrefTracker.
Services.prefs.clearUserPref("browser.startup.homepage");
Services.prefs.clearUserPref("browser.startup.page");
});
async function check_homepage({expectedURL, expectedPageVal = 1, locked = false}) {
- is(gHomeButton.getHomePage(),
+ is(HomePage.get(),
expectedURL, "Homepage URL should match expected");
is(Services.prefs.getIntPref("browser.startup.page", -1), expectedPageVal,
"Pref page value should match expected");
is(Services.prefs.prefIsLocked("browser.startup.homepage"), locked,
"Lock status of browser.startup.homepage should match expected");
is(Services.prefs.prefIsLocked("browser.startup.page"), locked,
"Lock status of browser.startup.page should match expected");
--- a/browser/components/extensions/test/browser/browser_ext_chrome_settings_overrides_home.js
+++ b/browser/components/extensions/test/browser/browser_ext_chrome_settings_overrides_home.js
@@ -17,18 +17,17 @@ const HOME_URI_4 = "http://example.net/"
const CONTROLLED_BY_THIS = "controlled_by_this_extension";
const CONTROLLED_BY_OTHER = "controlled_by_other_extensions";
const NOT_CONTROLLABLE = "not_controllable";
const HOMEPAGE_URL_PREF = "browser.startup.homepage";
const getHomePageURL = () => {
- return Services.prefs.getComplexValue(
- HOMEPAGE_URL_PREF, Ci.nsIPrefLocalizedString).data;
+ return Services.prefs.getStringPref(HOMEPAGE_URL_PREF);
};
function isConfirmed(id) {
let item = ExtensionSettingsStore.getSetting("homepageNotification", id);
return !!(item && item.value);
}
add_task(async function test_multiple_extensions_overriding_home_page() {
--- a/browser/components/extensions/test/xpcshell/test_ext_chrome_settings_overrides_update.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_chrome_settings_overrides_update.js
@@ -1,13 +1,14 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm");
+ChromeUtils.import("resource:///modules/HomePage.jsm");
const {
createAppInfo,
promiseShutdownManager,
promiseStartupManager,
} = AddonTestUtils;
AddonTestUtils.init(this);
@@ -20,25 +21,20 @@ add_task(async function test_overrides_u
* search_provider are removed between updates and therefore the
* settings are expected to revert. */
const EXTENSION_ID = "test_overrides_update@tests.mozilla.org";
const HOMEPAGE_URI = "webext-homepage-1.html";
const HOMEPAGE_URL_PREF = "browser.startup.homepage";
- const getHomePageURL = () => {
- return Services.prefs.getComplexValue(
- HOMEPAGE_URL_PREF, Ci.nsIPrefLocalizedString).data;
- };
-
function promisePrefChanged(value) {
return new Promise((resolve, reject) => {
Services.prefs.addObserver(HOMEPAGE_URL_PREF, function observer() {
- if (getHomePageURL().endsWith(value)) {
+ if (HomePage.get().endsWith(value)) {
Services.prefs.removeObserver(HOMEPAGE_URL_PREF, observer);
resolve();
}
});
});
}
await promiseStartupManager();
@@ -59,25 +55,25 @@ add_task(async function test_overrides_u
"search_url": "https://example.com/?q={searchTerms}",
"is_default": true,
},
},
},
};
let extension = ExtensionTestUtils.loadExtension(extensionInfo);
- let defaultHomepageURL = getHomePageURL();
+ let defaultHomepageURL = HomePage.get();
let defaultEngineName = Services.search.currentEngine.name;
let prefPromise = promisePrefChanged(HOMEPAGE_URI);
await extension.startup();
await prefPromise;
equal(extension.version, "1.0", "The installed addon has the expected version.");
- ok(getHomePageURL().endsWith(HOMEPAGE_URI),
+ ok(HomePage.get().endsWith(HOMEPAGE_URI),
"Home page url is overridden by the extension.");
equal(Services.search.currentEngine.name,
"DuckDuckGo",
"Default engine is overridden by the extension");
extensionInfo.manifest = {
"version": "2.0",
"applications": {
@@ -87,17 +83,17 @@ add_task(async function test_overrides_u
},
};
prefPromise = promisePrefChanged(defaultHomepageURL);
await extension.upgrade(extensionInfo);
await prefPromise;
equal(extension.version, "2.0", "The updated addon has the expected version.");
- equal(getHomePageURL(),
+ equal(HomePage.get(),
defaultHomepageURL,
"Home page url reverted to the default after update.");
equal(Services.search.currentEngine.name,
defaultEngineName,
"Default engine reverted to the default after update.");
await extension.unload();
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -4,16 +4,17 @@
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
HeadlessShell: "resource:///modules/HeadlessShell.jsm",
+ HomePage: "resource:///modules/HomePage.jsm",
LaterRun: "resource:///modules/LaterRun.jsm",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
ShellService: "resource:///modules/ShellService.jsm",
UpdatePing: "resource://gre/modules/UpdatePing.jsm"
});
XPCOMUtils.defineLazyServiceGetter(this, "WindowsUIUtils",
"@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils");
@@ -549,17 +550,17 @@ nsBrowserContentHandler.prototype = {
overridePage = additionalPage;
}
}
var startPage = "";
try {
var choice = prefb.getIntPref("browser.startup.page");
if (choice == 1 || choice == 3)
- startPage = this.startPage;
+ startPage = HomePage.get();
} catch (e) {
Cu.reportError(e);
}
if (startPage == "about:blank")
startPage = "";
let skipStartPage = override == OVERRIDE_NEW_PROFILE &&
@@ -567,27 +568,16 @@ nsBrowserContentHandler.prototype = {
// Only show the startPage if we're not restoring an update session and are
// not set to skip the start page on this profile
if (overridePage && startPage && !willRestoreSession && !skipStartPage)
return overridePage + "|" + startPage;
return overridePage || startPage || "about:blank";
},
- get startPage() {
- var uri = Services.prefs.getComplexValue("browser.startup.homepage",
- Ci.nsIPrefLocalizedString).data;
- if (!uri) {
- Services.prefs.clearUserPref("browser.startup.homepage");
- uri = Services.prefs.getComplexValue("browser.startup.homepage",
- Ci.nsIPrefLocalizedString).data;
- }
- return uri;
- },
-
mFeatures: null,
getFeatures: function bch_features(cmdLine) {
if (this.mFeatures === null) {
this.mFeatures = "";
try {
var width = cmdLine.handleFlagWithParam("width", false);
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -101,16 +101,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
CustomizableUI: "resource:///modules/CustomizableUI.jsm",
DateTimePickerParent: "resource://gre/modules/DateTimePickerParent.jsm",
ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
Feeds: "resource:///modules/Feeds.jsm",
FileSource: "resource://gre/modules/L10nRegistry.jsm",
FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
FxAccounts: "resource://gre/modules/FxAccounts.jsm",
+ HomePage: "resource:///modules/HomePage.jsm",
HybridContentTelemetry: "resource://gre/modules/HybridContentTelemetry.jsm",
Integration: "resource://gre/modules/Integration.jsm",
L10nRegistry: "resource://gre/modules/L10nRegistry.jsm",
LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm",
LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
LoginHelper: "resource://gre/modules/LoginHelper.jsm",
LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
@@ -397,18 +398,17 @@ BrowserGlue.prototype = {
} else if (aboutNewTabService.newTabURL.startsWith("moz-extension://")) {
newTabSetting = 2;
} else if (!Services.prefs.getBoolPref("browser.newtabpage.enabled")) {
newTabSetting = 1;
} else {
newTabSetting = 3;
}
- const homePageURL = Services.prefs.getComplexValue("browser.startup.homepage",
- Ci.nsIPrefLocalizedString).data;
+ const homePageURL = HomePage.get();
if (homePageURL === "about:home") {
homePageSetting = 0;
} else if (homePageURL === "about:blank") {
homePageSetting = 1;
} else if (homePageURL.startsWith("moz-extension://")) {
homePageSetting = 2;
} else {
homePageSetting = 3;
--- a/browser/components/preferences/in-content/tests/browser_extension_controlled.js
+++ b/browser/components/preferences/in-content/tests/browser_extension_controlled.js
@@ -261,18 +261,19 @@ add_task(async function testPrefLockedHo
is(homePageInput.value, "", "The homepage is empty");
is(homePageInput.disabled, false, "The homepage is enabled after clearing lock");
is(homeModeEl.disabled, false, "Homepage menulist is enabled after clearing lock");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, false, `The ${pref} button is enabled when unlocked`);
});
// Lock the prefs without an extension.
+ let mutationsDone = waitForAllMutations();
lockPrefs();
- await waitForAllMutations();
+ await mutationsDone;
// Check that everything is now disabled.
is(getHomepage(), lockedHomepage, "The reported homepage is set by the pref");
is(homePageInput.value, lockedHomepage, "The homepage is set by the pref");
is(homePageInput.disabled, true, "The homepage is disabed when the pref is locked");
is(homeModeEl.disabled, true, "Homepage menulist is disabled when prefis locked");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `The ${pref} button is disabled when locked`);
--- a/browser/components/preferences/in-content/tests/browser_homepages_filter_aboutpreferences.js
+++ b/browser/components/preferences/in-content/tests/browser_homepages_filter_aboutpreferences.js
@@ -1,21 +1,23 @@
+ChromeUtils.import("resource:///modules/HomePage.jsm");
+
add_task(async function testSetHomepageUseCurrent() {
is(gBrowser.currentURI.spec, "about:blank", "Test starts with about:blank open");
await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home");
await openPreferencesViaOpenPreferencesAPI("paneHome", {leaveOpen: true});
// eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = gBrowser.contentDocument;
is(gBrowser.currentURI.spec, "about:preferences#home",
"#home should be in the URI for about:preferences");
- let oldHomepagePref = Services.prefs.getCharPref("browser.startup.homepage");
+ let oldHomepage = HomePage.get();
let useCurrent = doc.getElementById("useCurrentBtn");
useCurrent.click();
is(gBrowser.tabs.length, 3, "Three tabs should be open");
- is(Services.prefs.getCharPref("browser.startup.homepage"), "about:blank|about:home",
+ is(HomePage.get(), "about:blank|about:home",
"about:blank and about:home should be the only homepages set");
- Services.prefs.setCharPref("browser.startup.homepage", oldHomepagePref);
+ HomePage.set(oldHomepage);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -169,16 +169,17 @@ XPCOMUtils.defineLazyServiceGetters(this
});
XPCOMUtils.defineLazyModuleGetters(this, {
AppConstants: "resource://gre/modules/AppConstants.jsm",
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
DevToolsShim: "chrome://devtools-startup/content/DevToolsShim.jsm",
GlobalState: "resource:///modules/sessionstore/GlobalState.jsm",
+ HomePage: "resource:///modules/HomePage.jsm",
PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
RunState: "resource:///modules/sessionstore/RunState.jsm",
SessionCookies: "resource:///modules/sessionstore/SessionCookies.jsm",
SessionFile: "resource:///modules/sessionstore/SessionFile.jsm",
SessionSaver: "resource:///modules/sessionstore/SessionSaver.jsm",
TabAttributes: "resource:///modules/sessionstore/TabAttributes.jsm",
TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm",
@@ -3128,17 +3129,17 @@ var SessionStoreInternal = {
// home pages then we'll end up overwriting all of them. Otherwise we'll
// just close the tabs that match home pages. Tabs with the about:blank
// URI will always be overwritten.
let homePages = ["about:blank"];
let removableTabs = [];
let tabbrowser = aWindow.gBrowser;
let startupPref = this._prefBranch.getIntPref("startup.page");
if (startupPref == 1)
- homePages = homePages.concat(aWindow.gHomeButton.getHomePage().split("|"));
+ homePages = homePages.concat(HomePage.get().split("|"));
for (let i = tabbrowser._numPinnedTabs; i < tabbrowser.tabs.length; i++) {
let tab = tabbrowser.tabs[i];
if (homePages.includes(tab.linkedBrowser.currentURI.spec)) {
removableTabs.push(tab);
}
}
new file mode 100644
--- /dev/null
+++ b/browser/modules/HomePage.jsm
@@ -0,0 +1,65 @@
+/* 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/. */
+
+/* globals ChromeUtils, Services */
+/* exported HomePage */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["HomePage"];
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+const kPrefName = "browser.startup.homepage";
+
+function getHomepagePref(useDefault) {
+ let homePage;
+ let prefs = Services.prefs;
+ if (useDefault) {
+ prefs = prefs.getDefaultBranch(null);
+ }
+ try {
+ // Historically, this was a localizable pref, but default Firefox builds
+ // don't use this.
+ // Distributions and local customizations might still use this, so let's
+ // keep it.
+ homePage = prefs.getComplexValue(kPrefName,
+ Ci.nsIPrefLocalizedString).data;
+ } catch (ex) {}
+
+ if (!homePage) {
+ homePage = prefs.getStringPref(kPrefName);
+ }
+
+ // Apparently at some point users ended up with blank home pages somehow.
+ // If that happens, reset the pref and read it again.
+ if (!homePage && !useDefault) {
+ Services.prefs.clearUserPref(kPrefName);
+ homePage = getHomepagePref(true);
+ }
+
+ return homePage;
+}
+
+let HomePage = {
+ get() {
+ return getHomepagePref();
+ },
+
+ getDefault() {
+ return getHomepagePref(true);
+ },
+
+ get overridden() {
+ return Services.prefs.prefHasUserValue(kPrefName);
+ },
+
+ set(value) {
+ Services.prefs.setStringPref(kPrefName, value);
+ },
+
+ reset() {
+ Services.prefs.clearUserPref(kPrefName);
+ }
+};
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -152,16 +152,17 @@ EXTRA_JS_MODULES += [
'ContentObservers.js',
'ContentSearch.jsm',
'ContentWebRTC.jsm',
'ContextMenu.jsm',
'ExtensionsUI.jsm',
'Feeds.jsm',
'FormSubmitObserver.jsm',
'FormValidationHandler.jsm',
+ 'HomePage.jsm',
'LaterRun.jsm',
'LightweightThemeChildListener.jsm',
'LightWeightThemeWebInstallListener.jsm',
'NetErrorContent.jsm',
'OpenInTabsUtils.jsm',
'PageActions.jsm',
'PageInfoListener.jsm',
'PageStyleHandler.jsm',
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/unit/test_HomePage.js
@@ -0,0 +1,43 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/* globals ChromeUtils, Services, Cc, Ci, HomePage, Assert, add_task */
+"use strict";
+
+ChromeUtils.import("resource:///modules/HomePage.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+add_task(function testHomePage() {
+ Assert.ok(!HomePage.overridden, "Homepage should not be overriden by default.");
+ let newvalue = "about:blank|about:newtab";
+ HomePage.set(newvalue);
+ Assert.ok(HomePage.overridden, "Homepage should be overriden after set()");
+ Assert.equal(HomePage.get(), newvalue, "Homepage should be ${newvalue}");
+ Assert.notEqual(HomePage.getDefault(), newvalue, "Homepage should be ${newvalue}");
+ HomePage.reset();
+ Assert.ok(!HomePage.overridden, "Homepage should not be overriden by after reset.");
+ Assert.equal(HomePage.get(), HomePage.getDefault(),
+ "Homepage and default should be equal after reset.");
+});
+
+add_task(function readLocalizedHomepage() {
+ let newvalue = "data:text/plain,browser.startup.homepage%3Dabout%3Alocalized";
+ let complexvalue = Cc["@mozilla.org/pref-localizedstring;1"]
+ .createInstance(Ci.nsIPrefLocalizedString);
+ complexvalue.data = newvalue;
+ Services.prefs.getDefaultBranch(null).setComplexValue(
+ "browser.startup.homepage",
+ Ci.nsIPrefLocalizedString,
+ complexvalue);
+ Assert.ok(!HomePage.overridden, "Complex value only works as default");
+ Assert.equal(HomePage.get(), "about:localized", "Get value from bundle");
+});
+
+add_task(function recoverEmptyHomepage() {
+ Assert.ok(!HomePage.overridden, "Homepage should not be overriden by default.");
+ Services.prefs.setStringPref("browser.startup.homepage", "");
+ Assert.ok(HomePage.overridden, "Homepage is overriden with empty string.");
+ Assert.equal(HomePage.get(), HomePage.getDefault(), "Recover is default");
+ Assert.ok(!HomePage.overridden, "Recover should have set default");
+});
--- a/browser/modules/test/unit/xpcshell.ini
+++ b/browser/modules/test/unit/xpcshell.ini
@@ -1,11 +1,12 @@
[DEFAULT]
head =
firefox-appdir = browser
skip-if = toolkit == 'android'
[test_AttributionCode.js]
skip-if = os != 'win'
[test_E10SUtils_nested_URIs.js]
+[test_HomePage.js]
[test_Sanitizer_interrupted.js]
[test_SitePermissions.js]
[test_LaterRun.js]
--- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/ui/browser/window.py
@@ -30,17 +30,16 @@ class BrowserWindow(BaseWindow):
'chrome://branding/locale/brand.dtd',
'chrome://browser/locale/aboutPrivateBrowsing.dtd',
'chrome://browser/locale/browser.dtd',
'chrome://browser/locale/netError.dtd',
]
properties = [
'chrome://branding/locale/brand.properties',
- 'chrome://branding/locale/browserconfig.properties',
'chrome://browser/locale/browser.properties',
'chrome://browser/locale/preferences/preferences.properties',
'chrome://global/locale/browser.properties',
]
def __init__(self, *args, **kwargs):
super(BrowserWindow, self).__init__(*args, **kwargs)
@@ -48,18 +47,17 @@ class BrowserWindow(BaseWindow):
self._tabbar = None
@property
def default_homepage(self):
"""The default homepage as used by the current locale.
:returns: The default homepage for the current locale.
"""
- return self.marionette.get_pref('browser.startup.homepage',
- value_type='nsIPrefLocalizedString')
+ return self.marionette.get_pref('browser.startup.homepage')
@property
def is_private(self):
"""Returns True if this is a Private Browsing window."""
self.switch_to()
with self.marionette.using_context('chrome'):
return self.marionette.execute_script("""
--- a/toolkit/components/extensions/parent/ext-browserSettings.js
+++ b/toolkit/components/extensions/parent/ext-browserSettings.js
@@ -212,18 +212,17 @@ this.browserSettings = class extends Ext
return ExtensionPreferencesManager.setSetting(
extension.id, "contextMenuShowEvent", details.value);
},
}
),
homepageOverride: getSettingsAPI(
extension.id, HOMEPAGE_OVERRIDE_SETTING,
() => {
- return Services.prefs.getComplexValue(
- HOMEPAGE_URL_PREF, Ci.nsIPrefLocalizedString).data;
+ return Services.prefs.getStringPref(HOMEPAGE_URL_PREF);
}, undefined, true),
imageAnimationBehavior: getSettingsAPI(
extension.id, "imageAnimationBehavior",
() => {
return Services.prefs.getCharPref("image.animation_mode");
}),
newTabPosition: getSettingsAPI(
extension.id, "newTabPosition",
--- a/toolkit/components/extensions/test/xpcshell/test_ext_browserSettings_homepage.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_browserSettings_homepage.js
@@ -10,18 +10,17 @@ add_task(async function test_homepage_ge
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
permissions: ["browserSettings"],
},
});
- let defaultHomepage = Services.prefs.getComplexValue(
- "browser.startup.homepage", Ci.nsIPrefLocalizedString).data;
+ let defaultHomepage = Services.prefs.getStringPref("browser.startup.homepage");
await extension.startup();
let homepage = await extension.awaitMessage("homepage");
equal(homepage.value, defaultHomepage,
"The homepageOverride setting has the expected value.");
equal(homepage.levelOfControl, "not_controllable",
"The homepageOverride setting has the expected levelOfControl.");