--- a/browser/components/enterprisepolicies/tests/browser/browser_policy_set_homepage.js
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policy_set_homepage.js
@@ -152,19 +152,24 @@ add_task(async function homepage_test_lo
is(Services.prefs.prefIsLocked("browser.startup.page"), true,
"Start page type pref should be locked");
// Test that UI is disabled when the Locked property is enabled
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
await ContentTask.spawn(tab.linkedBrowser, null, async function() {
is(content.document.getElementById("browserStartupPage").disabled, true,
"When homepage is locked, the startup page choice controls should be locked");
- is(content.document.getElementById("browserHomePage").disabled, true,
- "Homepage input should be disabled");
- is(content.document.getElementById("useCurrent").disabled, true,
+ });
+ await BrowserTestUtils.loadURI(tab.linkedBrowser, "about:preferences#home");
+ await ContentTask.spawn(tab.linkedBrowser, null, async function() {
+ is(content.document.getElementById("homeMode").disabled, true,
+ "Homepage menulist should be disabled");
+ is(content.document.getElementById("homePageUrl").disabled, true,
+ "Homepage custom input should be disabled");
+ is(content.document.getElementById("useCurrentBtn").disabled, true,
"\"Use Current Page\" button should be disabled");
- is(content.document.getElementById("useBookmark").disabled, true,
+ is(content.document.getElementById("useBookmarkBtn").disabled, true,
"\"Use Bookmark...\" button should be disabled");
- is(content.document.getElementById("restoreDefaultHomePage").disabled, true,
+ is(content.document.getElementById("restoreDefaultHomePageBtn").disabled, true,
"\"Restore to Default\" button should be disabled");
});
BrowserTestUtils.removeTab(tab);
});
--- a/browser/components/preferences/in-content/home.js
+++ b/browser/components/preferences/in-content/home.js
@@ -1,7 +1,337 @@
/* 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/. */
+ /* import-globals-from extensionControlled.js */
+ /* import-globals-from preferences.js */
+
+ // HOME PAGE
+
+ /*
+ * Preferences:
+ *
+ * browser.startup.homepage
+ * - the user's home page, as a string; if the home page is a set of tabs,
+ * this will be those URLs separated by the pipe character "|"
+ * browser.newtabpage.enabled
+ * - determines that is shown on the user's new tab page.
+ * true = Activity Stream is shown,
+ * false = about:blank is shown
+ */
+
+Preferences.addAll([
+ { id: "browser.startup.homepage", type: "wstring" },
+ { id: "pref.browser.homepage.disable_button.current_page", type: "bool" },
+ { id: "pref.browser.homepage.disable_button.bookmark_page", type: "bool" },
+ { id: "pref.browser.homepage.disable_button.restore_default", type: "bool" },
+ { id: "browser.newtabpage.enabled", type: "bool" }
+]);
+
+const HOMEPAGE_OVERRIDE_KEY = "homepage_override";
+const URL_OVERRIDES_TYPE = "url_overrides";
+const NEW_TAB_KEY = "newTabURL";
+const NEW_TAB_STRING_ID = "extensionControlled.newTabURL2";
+
let gHomePane = {
- init() {}
+ HOME_MODE_FIREFOX_HOME: "0",
+ HOME_MODE_BLANK: "1",
+ HOME_MODE_CUSTOM: "2",
+ NEWTAB_ENABLED_PREF: "browser.newtabpage.enabled",
+
+ /**
+ * _handleNewTabOverrides: disables new tab settings UI. Called by
+ * an observer in ._watchNewTab that watches for new tab url changes
+ */
+ async _handleNewTabOverrides() {
+ const isControlled = await handleControllingExtension(
+ URL_OVERRIDES_TYPE, NEW_TAB_KEY, NEW_TAB_STRING_ID);
+ const el = document.getElementById("newTabMode");
+ el.disabled = isControlled;
+ },
+
+ /**
+ * watchNewTab: Listen for changes to the new tab url and disable appropriate
+ * areas of the UI
+ */
+ watchNewTab() {
+ this._handleNewTabOverrides();
+ let newTabObserver = {
+ observe: this._handleNewTabOverrides.bind(this)
+ };
+ Services.obs.addObserver(newTabObserver, "newtab-url-changed");
+ window.addEventListener("unload", () => {
+ Services.obs.removeObserver(newTabObserver, "newtab-url-changed");
+ });
+ },
+
+ /**
+ * _renderCustomSettings: Hides or shows the UI for setting a custom
+ * homepage URL
+ * @param {bool} shouldShow Should the custom UI be shown?
+ */
+ _renderCustomSettings(shouldShow) {
+ const customSettingsContainerEl = document.getElementById("customSettings");
+ const customUrlEl = document.getElementById("homePageUrl");
+ const isHomepageCustom = !this._isHomePageDefaultValue() && !this._isHomePageBlank();
+ if (typeof shouldShow === "undefined") shouldShow = isHomepageCustom;
+
+ customSettingsContainerEl.hidden = !shouldShow;
+ if (isHomepageCustom) {
+ customUrlEl.value = Preferences.get("browser.startup.homepage").value;
+ } else {
+ customUrlEl.value = "";
+ }
+ },
+
+ /**
+ * _isHomePageDefaultValue
+ * @returns {bool} Is the homepage set to the default pref value?
+ */
+ _isHomePageDefaultValue() {
+ const homePref = Preferences.get("browser.startup.homepage");
+ return homePref.value === homePref.defaultValue;
+ },
+
+ /**
+ * _isHomePageBlank
+ * @returns {bool} Is the homepage set to about:blank?
+ */
+ _isHomePageBlank() {
+ const homePref = Preferences.get("browser.startup.homepage");
+ return homePref.value === "about:blank" || homePref.value === "";
+ },
+
+ /**
+ * _isTabAboutPreferences: Is a given tab set to about:preferences?
+ * @param {Element} aTab A tab element
+ * @returns {bool} Is the linkedBrowser of aElement set to about:preferences?
+ */
+ _isTabAboutPreferences(aTab) {
+ return aTab.linkedBrowser.currentURI.spec.startsWith("about:preferences");
+ },
+
+ /**
+ * _getTabsForHomePage
+ * @returns {Array} An array of current tabs
+ */
+ _getTabsForHomePage() {
+ let tabs = [];
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+
+ // We should only include visible & non-pinned tabs
+ if (win && win.document.documentElement.getAttribute("windowtype") === "navigator:browser") {
+ tabs = win.gBrowser.visibleTabs.slice(win.gBrowser._numPinnedTabs);
+ tabs = tabs.filter(tab => !this._isTabAboutPreferences(tab));
+ // XXX: Bug 1441637 - Fix tabbrowser to report tab.closing before it blurs it
+ tabs = tabs.filter(tab => !tab.closing);
+ }
+
+ return tabs;
+ },
+
+ _renderHomepageMode() {
+ const isDefault = this._isHomePageDefaultValue();
+ const isBlank = this._isHomePageBlank();
+ const el = document.getElementById("homeMode");
+
+ if (isDefault) {
+ el.value = this.HOME_MODE_FIREFOX_HOME;
+ } else if (isBlank) {
+ el.value = this.HOME_MODE_BLANK;
+ } else {
+ el.value = this.HOME_MODE_CUSTOM;
+ }
+ },
+
+ _setInputDisabledStates(isControlled) {
+ let tabCount = this._getTabsForHomePage().length;
+
+ // Disable or enable the inputs based on if this is controlled by an extension.
+ document.querySelectorAll(".check-home-page-controlled")
+ .forEach((element) => {
+ let isDisabled;
+ let pref = element.getAttribute("preference") || element.getAttribute("data-preference-related");
+ if (!pref) {
+ throw new Error(`Element with id ${element.id} did not have preference or data-preference-related attribute defined.`);
+ }
+ isDisabled = Preferences.get(pref).locked || isControlled;
+
+ if (pref === "pref.browser.disable_button.current_page") {
+ // Special case for current_page to disable it if tabCount is 0
+ isDisabled = isDisabled || tabCount < 1;
+ }
+
+ element.disabled = isDisabled;
+ });
+ },
+
+ async _handleHomePageOverrides() {
+ const homePref = Preferences.get("browser.startup.homepage");
+ if (homePref.locked) {
+ // An extension can't control these settings if they're locked.
+ hideControllingExtension(HOMEPAGE_OVERRIDE_KEY);
+ this._setInputDisabledStates(false);
+ } else {
+ // Asynchronously update the extension controlled UI.
+ const isHomePageControlled = await handleControllingExtension(
+ PREF_SETTING_TYPE, HOMEPAGE_OVERRIDE_KEY, "extensionControlled.homepage_override2");
+ this._setInputDisabledStates(isHomePageControlled);
+ }
+ },
+
+ syncFromHomePref() {
+ // Set the "Use Current Page(s)" button's text and enabled state.
+ this._updateUseCurrentButton();
+ this._renderCustomSettings();
+ this._renderHomepageMode();
+ this._handleHomePageOverrides();
+ },
+
+ syncFromNewTabPref() {
+ const newtabPref = Preferences.get(this.NEWTAB_ENABLED_PREF);
+ return newtabPref.value ? this.HOME_MODE_FIREFOX_HOME : this.HOME_MODE_BLANK;
+ },
+
+ syncToNewTabPref(value) {
+ return value !== this.HOME_MODE_BLANK;
+ },
+
+ onMenuChange(event) {
+ const {value} = event.target;
+ const homePref = Preferences.get("browser.startup.homepage");
+ switch (value) {
+ case this.HOME_MODE_FIREFOX_HOME:
+ if (homePref.value !== homePref.defaultValue) {
+ homePref.value = homePref.defaultValue;
+ } else {
+ this._renderCustomSettings(false);
+ }
+ break;
+ case this.HOME_MODE_BLANK:
+ if (homePref.value !== "about:blank") {
+ homePref.value = "about:blank";
+ } else {
+ this._renderCustomSettings(false);
+ }
+ break;
+ case this.HOME_MODE_CUSTOM:
+ this._renderCustomSettings(true);
+ break;
+ }
+ },
+
+ /**
+ * Switches the "Use Current Page" button between its singular and plural
+ * forms.
+ */
+ async _updateUseCurrentButton() {
+ let useCurrent = document.getElementById("useCurrentBtn");
+ let tabs = this._getTabsForHomePage();
+ const tabCount = tabs.length;
+ document.l10n.setAttributes(useCurrent, "use-current-pages", { tabCount });
+
+ // If the homepage is controlled by an extension then you can't use this.
+ if (await getControllingExtensionInfo(PREF_SETTING_TYPE, HOMEPAGE_OVERRIDE_KEY)) {
+ return;
+ }
+
+ // In this case, the button's disabled state is set by preferences.xml.
+ let prefName = "pref.browser.homepage.disable_button.current_page";
+ if (Preferences.get(prefName).locked)
+ return;
+
+ useCurrent.disabled = tabCount < 1;
+ },
+
+ /**
+ * Sets the home page to the URL(s) of any currently opened tab(s),
+ * updating about:preferences#home UI to reflect this.
+ */
+ setHomePageToCurrent() {
+ let homePage = Preferences.get("browser.startup.homepage");
+ let tabs = this._getTabsForHomePage();
+ function getTabURI(t) {
+ return t.linkedBrowser.currentURI.spec;
+ }
+
+ // FIXME Bug 244192: using dangerous "|" joiner!
+ if (tabs.length) {
+ homePage.value = tabs.map(getTabURI).join("|");
+ }
+
+ Services.telemetry.scalarAdd("preferences.use_current_page", 1);
+ },
+
+ _setHomePageToBookmarkClosed(rv, aEvent) {
+ if (aEvent.detail.button != "accept")
+ return;
+ if (rv.urls && rv.names) {
+ let homePage = Preferences.get("browser.startup.homepage");
+
+ // XXX still using dangerous "|" joiner!
+ homePage.value = rv.urls.join("|");
+ }
+ },
+
+ /**
+ * Displays a dialog in which the user can select a bookmark to use as home
+ * page. If the user selects a bookmark, that bookmark's name is displayed in
+ * UI and the bookmark's address is stored to the home page preference.
+ */
+ setHomePageToBookmark() {
+ const rv = { urls: null, names: null };
+ gSubDialog.open("chrome://browser/content/preferences/selectBookmark.xul",
+ "resizable=yes, modal=yes", rv,
+ this._setHomePageToBookmarkClosed.bind(this, rv));
+ Services.telemetry.scalarAdd("preferences.use_bookmark", 1);
+ },
+
+ restoreDefaultHomePage() {
+ const homePref = Preferences.get("browser.startup.homepage");
+ const newtabPref = Preferences.get(this.NEWTAB_ENABLED_PREF);
+ homePref.value = homePref.defaultValue;
+ newtabPref.value = newtabPref.defaultValue;
+ },
+
+ onCustomHomePageInput(event) {
+ if (this._telemetryHomePageTimer) {
+ clearTimeout(this._telemetryHomePageTimer);
+ }
+ let browserHomePage = event.target.value;
+ // The length of the home page URL string should be more then four,
+ // and it should contain at least one ".", for example, "https://mozilla.org".
+ if (browserHomePage.length > 4 && browserHomePage.includes(".")) {
+ this._telemetryHomePageTimer = setTimeout(() => {
+ let homePageNumber = browserHomePage.split("|").length;
+ Services.telemetry.scalarAdd("preferences.browser_home_page_change", 1);
+ Services.telemetry.keyedScalarAdd("preferences.browser_home_page_count", homePageNumber, 1);
+ }, 3000);
+ }
+ },
+
+ onCustomHomePageChange(event) {
+ const homePref = Preferences.get("browser.startup.homepage");
+ const value = event.target.value || homePref.defaultValue;
+ homePref.value = value;
+ },
+
+ init() {
+ // Event Listeners
+ document.getElementById("homeMode").addEventListener("command", this.onMenuChange.bind(this));
+ document.getElementById("homePageUrl").addEventListener("change", this.onCustomHomePageChange.bind(this));
+ document.getElementById("homePageUrl").addEventListener("input", this.onCustomHomePageInput.bind(this));
+ document.getElementById("useCurrentBtn").addEventListener("command", this.setHomePageToCurrent.bind(this));
+ document.getElementById("useBookmarkBtn").addEventListener("command", this.setHomePageToBookmark.bind(this));
+ document.getElementById("restoreDefaultHomePageBtn").addEventListener("command", this.restoreDefaultHomePage.bind(this));
+
+ this._updateUseCurrentButton();
+ window.addEventListener("focus", this._updateUseCurrentButton.bind(this));
+
+ // Extension/override-related events
+ this.watchNewTab();
+ document.getElementById("disableHomePageExtension").addEventListener("command",
+ makeDisableControllingExtension(PREF_SETTING_TYPE, HOMEPAGE_OVERRIDE_KEY));
+ document.getElementById("disableNewTabExtension").addEventListener("command",
+ makeDisableControllingExtension(URL_OVERRIDES_TYPE, NEW_TAB_KEY));
+ }
};
--- a/browser/components/preferences/in-content/home.xul
+++ b/browser/components/preferences/in-content/home.xul
@@ -8,8 +8,96 @@
src="chrome://browser/content/preferences/in-content/home.js"/>
<hbox id="firefoxHomeCategory"
class="subcategory"
hidden="true"
data-category="paneHome">
<label class="header-name" flex="1" data-l10n-id="pane-home-title" />
</hbox>
+
+<groupbox id="homepageGroup"
+ data-category="paneHome"
+ hidden="true">
+ <hbox>
+ <caption flex="1"><label data-l10n-id="home-new-windows-tabs-header" /></caption>
+ <button id="restoreDefaultHomePageBtn"
+ class="homepage-button check-home-page-controlled"
+ data-preference-related="browser.startup.homepage"
+ data-l10n-id="home-restore-defaults"
+ preference="pref.browser.homepage.disable_button.restore_default"/>
+ </hbox>
+ <description data-l10n-id="home-new-windows-tabs-description" />
+
+ <groupbox>
+ <hbox id="homepageAndNewWindowsOption">
+ <label control="homeMode" data-l10n-id="home-homepage-mode-label" flex="1" />
+
+ <vbox class="homepageMenuItemContainer" flex="1">
+ <textbox id="homePrefHidden"
+ preference="browser.startup.homepage"
+ onsyncfrompreference="return gHomePane.syncFromHomePref();"
+ hidden="true" />
+ <menulist id="homeMode"
+ class="check-home-page-controlled"
+ data-preference-related="browser.startup.homepage">
+ <menupopup>
+ <menuitem value="0" data-l10n-id="home-mode-choice-default" />
+ <menuitem value="2" data-l10n-id="home-mode-choice-custom" />
+ <menuitem value="1" data-l10n-id="home-mode-choice-blank" />
+ </menupopup>
+ </menulist>
+
+ <vbox id="customSettings" hidden="true">
+ <textbox id="homePageUrl"
+ class="uri-element check-home-page-controlled"
+ data-preference-related="browser.startup.homepage"
+ type="autocomplete"
+ data-l10n-id="home-homepage-custom-url"
+ autocompletesearch="unifiedcomplete" />
+ <hbox class="homepage-buttons">
+ <button id="useCurrentBtn"
+ flex="1"
+ class="homepage-button check-home-page-controlled"
+ data-l10n-id="use-current-pages"
+ data-l10n-args='{"tabCount": 0}'
+ disabled="true"
+ preference="pref.browser.homepage.disable_button.current_page"/>
+ <button id="useBookmarkBtn"
+ flex="1"
+ class="homepage-button check-home-page-controlled"
+ data-l10n-id="choose-bookmark"
+ preference="pref.browser.homepage.disable_button.bookmark_page"
+ searchkeywords="&selectBookmark.title; &selectBookmark.label;"/>
+ </hbox>
+ </vbox>
+ </vbox>
+ </hbox>
+ <hbox id="newTabsOption">
+ <label control="newTabMode" data-l10n-id="home-newtabs-mode-label" flex="1" />
+
+ <menulist id="newTabMode"
+ flex="1"
+ preference="browser.newtabpage.enabled"
+ onsyncfrompreference="return gHomePane.syncFromNewTabPref();"
+ onsynctopreference="return gHomePane.syncToNewTabPref(this.value);">
+ <menupopup>
+ <menuitem value="0" data-l10n-id="home-mode-choice-default" />
+ <menuitem value="1" data-l10n-id="home-mode-choice-blank" />
+ </menupopup>
+ </menulist>
+ </hbox>
+
+ <hbox id="browserHomePageExtensionContent" align="center" hidden="true">
+ <description control="disableHomePageExtension" flex="1" />
+ <button id="disableHomePageExtension"
+ class="extension-controlled-button accessory-button"
+ data-l10n-id="disable-extension" />
+ </hbox>
+ <hbox id="browserNewTabExtensionContent" align="center" hidden="true">
+ <description control="disableNewTabExtension" flex="1" />
+ <button id="disableNewTabExtension"
+ class="extension-controlled-button accessory-button"
+ data-l10n-id="disable-extension" />
+ </hbox>
+
+ </groupbox>
+</groupbox>
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -33,20 +33,16 @@ const PREF_CONTAINERS_EXTENSION = "priva
// Preferences that affect which entries to show in the list.
const PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
"browser.download.hide_plugins_without_extensions";
// Strings to identify ExtensionSettingsStore overrides
const CONTAINERS_KEY = "privacy.containers";
-const HOMEPAGE_OVERRIDE_KEY = "homepage_override";
-const URL_OVERRIDES_TYPE = "url_overrides";
-const NEW_TAB_KEY = "newTabURL";
-const NEW_TAB_STRING_ID = "extensionControlled.newTabURL2";
/*
* Preferences where we store handling information about the feed type.
*
* browser.feeds.handler
* - "bookmarks", "reader" (clarified further using the .default preference),
* or "ask" -- indicates the default handler being used to process feeds;
* "bookmarks" is obsolete; to specify that the handler is bookmarks,
@@ -103,22 +99,16 @@ if (AppConstants.MOZ_DEV_EDITION) {
"resource://gre/modules/FxAccounts.jsm");
ChromeUtils.defineModuleGetter(this, "FxAccounts",
"resource://gre/modules/FxAccounts.jsm");
}
Preferences.addAll([
// Startup
{ id: "browser.startup.page", type: "int" },
- { id: "browser.startup.homepage", type: "wstring" },
-
- { id: "pref.browser.homepage.disable_button.current_page", type: "bool" },
- { id: "pref.browser.homepage.disable_button.bookmark_page", type: "bool" },
- { id: "pref.browser.homepage.disable_button.restore_default", type: "bool" },
-
{ id: "browser.privatebrowsing.autostart", type: "bool" },
// Downloads
{ id: "browser.download.useDownloadDir", type: "bool" },
{ id: "browser.download.folderList", type: "int" },
{ id: "browser.download.dir", type: "file" },
/* Tab preferences
@@ -349,35 +339,18 @@ var gMainPane = {
let defaultPerformancePref =
Preferences.get("browser.preferences.defaultPerformanceSettings.enabled");
defaultPerformancePref.on("change", () => {
this.updatePerformanceSettingsBox({ duringChangeEvent: true });
});
this.updatePerformanceSettingsBox({ duringChangeEvent: false });
- // set up the "use current page" label-changing listener
- this._updateUseCurrentButton();
- window.addEventListener("focus", this._updateUseCurrentButton.bind(this));
-
this.updateBrowserStartupLastSession();
- handleControllingExtension(
- URL_OVERRIDES_TYPE, NEW_TAB_KEY, NEW_TAB_STRING_ID);
- let newTabObserver = {
- observe(subject, topic, data) {
- handleControllingExtension(
- URL_OVERRIDES_TYPE, NEW_TAB_KEY, NEW_TAB_STRING_ID);
- },
- };
- Services.obs.addObserver(newTabObserver, "newtab-url-changed");
- window.addEventListener("unload", () => {
- Services.obs.removeObserver(newTabObserver, "newtab-url-changed");
- });
-
let connectionSettingsLink = document.getElementById("connectionSettingsLearnMore");
let connectionSettingsUrl = Services.urlFormatter.formatURLPref("app.support.baseURL") +
"prefs-connection-settings";
connectionSettingsLink.setAttribute("href", connectionSettingsUrl);
this.updateProxySettingsUI();
initializeProxyUI(gMainPane);
if (AppConstants.platform == "win") {
@@ -399,28 +372,18 @@ var gMainPane = {
document.getElementById("warnOpenMany").hidden = true;
Preferences.get("browser.privatebrowsing.autostart").on("change",
gMainPane.updateBrowserStartupLastSession.bind(gMainPane));
if (AppConstants.HAVE_SHELL_SERVICE) {
setEventListener("setDefaultButton", "command",
gMainPane.setDefaultBrowser);
}
- setEventListener("useCurrent", "command",
- gMainPane.setHomePageToCurrent);
- setEventListener("useBookmark", "command",
- gMainPane.setHomePageToBookmark);
- setEventListener("restoreDefaultHomePage", "command",
- gMainPane.restoreDefaultHomePage);
- setEventListener("disableHomePageExtension", "command",
- makeDisableControllingExtension(PREF_SETTING_TYPE, HOMEPAGE_OVERRIDE_KEY));
setEventListener("disableContainersExtension", "command",
makeDisableControllingExtension(PREF_SETTING_TYPE, CONTAINERS_KEY));
- setEventListener("disableNewTabExtension", "command",
- makeDisableControllingExtension(URL_OVERRIDES_TYPE, NEW_TAB_KEY));
setEventListener("chooseLanguage", "command",
gMainPane.showLanguages);
setEventListener("translationAttributionImage", "click",
gMainPane.openTranslationProviderAttribution);
setEventListener("translateButton", "command",
gMainPane.showTranslationExceptions);
Preferences.get("font.language.group").on("change",
gMainPane._rebuildFonts.bind(gMainPane));
@@ -431,18 +394,16 @@ var gMainPane = {
Preferences.get("layers.acceleration.disabled").on("change",
gMainPane.updateHardwareAcceleration.bind(gMainPane));
setEventListener("connectionSettings", "command",
gMainPane.showConnections);
setEventListener("browserContainersCheckbox", "command",
gMainPane.checkBrowserContainers);
setEventListener("browserContainersSettings", "command",
gMainPane.showContainerSettings);
- setEventListener("browserHomePage", "input",
- gMainPane.onBrowserHomePageChange);
// Initializes the fonts dropdowns displayed in this pane.
this._rebuildFonts();
this.updateOnScreenKeyboardVisibility();
// Show translation preferences if we may:
const prefName = "browser.translation.ui.show";
@@ -736,219 +697,32 @@ var gMainPane = {
return;
}
let url = await FxAccounts.config.promiseSignInURI("dev-edition-setup");
let accountsTab = win.gBrowser.addTab(url);
win.gBrowser.selectedTab = accountsTab;
},
// HOME PAGE
-
/*
* Preferences:
*
- * browser.startup.homepage
- * - the user's home page, as a string; if the home page is a set of tabs,
- * this will be those URLs separated by the pipe character "|"
* browser.startup.page
* - what page(s) to show when the user starts the application, as an integer:
*
* 0: a blank page
* 1: the home page (as set by the browser.startup.homepage pref)
* 2: the last page the user visited (DEPRECATED)
* 3: windows and tabs from the last session (a.k.a. session restore)
*
* The deprecated option is not exposed in UI; however, if the user has it
* selected and doesn't change the UI for this preference, the deprecated
* option is preserved.
*/
- syncFromHomePref() {
- let homePref = Preferences.get("browser.startup.homepage");
-
- // Set the "Use Current Page(s)" button's text and enabled state.
- this._updateUseCurrentButton();
-
- function setInputDisabledStates(isControlled) {
- let tabCount = this._getTabsForHomePage().length;
-
- // Disable or enable the inputs based on if this is controlled by an extension.
- document.querySelectorAll("#browserHomePage, .homepage-button")
- .forEach((element) => {
- let pref = element.getAttribute("preference");
-
- let isDisabled = Preferences.get(pref).locked || isControlled;
- if (pref == "pref.browser.disable_button.current_page") {
- // Special case for current_page to disable it if tabCount is 0
- isDisabled = isDisabled || tabCount < 1;
- }
-
- element.disabled = isDisabled;
- });
- }
-
- if (homePref.locked) {
- // An extension can't control these settings if they're locked.
- hideControllingExtension(HOMEPAGE_OVERRIDE_KEY);
- setInputDisabledStates.call(this, false);
- } else {
- // Asynchronously update the extension controlled UI.
- handleControllingExtension(
- PREF_SETTING_TYPE, HOMEPAGE_OVERRIDE_KEY, "extensionControlled.homepage_override2")
- .then(setInputDisabledStates.bind(this));
- }
-
- // If the pref is set to about:home or about:newtab, set the value to ""
- // to show the placeholder text (about:home title) rather than
- // exposing those URLs to users.
- let defaultBranch = Services.prefs.getDefaultBranch("");
- let defaultValue = defaultBranch.getComplexValue("browser.startup.homepage",
- Ci.nsIPrefLocalizedString).data;
- let currentValue = homePref.value.toLowerCase();
- if (currentValue == "about:home" ||
- (currentValue == defaultValue && currentValue == "about:newtab")) {
- return "";
- }
-
- // If the pref is actually "", show about:blank. The actual home page
- // loading code treats them the same, and we don't want the placeholder text
- // to be shown.
- if (homePref.value == "")
- return "about:blank";
-
- // Otherwise, show the actual pref value.
- return undefined;
- },
-
- syncToHomePref(value) {
- // If the value is "", use about:home.
- if (value == "")
- return "about:home";
-
- // Otherwise, use the actual textbox value.
- return undefined;
- },
-
- /**
- * Sets the home page to the current displayed page (or frontmost tab, if the
- * most recent browser window contains multiple tabs), updating preference
- * window UI to reflect this.
- */
- setHomePageToCurrent() {
- let homePage = Preferences.get("browser.startup.homepage");
- let tabs = this._getTabsForHomePage();
- function getTabURI(t) {
- return t.linkedBrowser.currentURI.spec;
- }
-
- // FIXME Bug 244192: using dangerous "|" joiner!
- if (tabs.length) {
- homePage.value = tabs.map(getTabURI).join("|");
- }
-
- Services.telemetry.scalarAdd("preferences.use_current_page", 1);
- },
-
- /**
- * Displays a dialog in which the user can select a bookmark to use as home
- * page. If the user selects a bookmark, that bookmark's name is displayed in
- * UI and the bookmark's address is stored to the home page preference.
- */
- setHomePageToBookmark() {
- var rv = { urls: null, names: null };
- gSubDialog.open("chrome://browser/content/preferences/selectBookmark.xul",
- "resizable=yes, modal=yes", rv,
- this._setHomePageToBookmarkClosed.bind(this, rv));
- Services.telemetry.scalarAdd("preferences.use_bookmark", 1);
- },
-
- onBrowserHomePageChange() {
- if (this.telemetryHomePageTimer) {
- clearTimeout(this.telemetryHomePageTimer);
- }
- let browserHomePage = document.querySelector("#browserHomePage").value;
- // The length of the home page URL string should be more then four,
- // and it should contain at least one ".", for example, "https://mozilla.org".
- if (browserHomePage.length > 4 && browserHomePage.includes(".")) {
- this.telemetryHomePageTimer = setTimeout(() => {
- let homePageNumber = browserHomePage.split("|").length;
- Services.telemetry.scalarAdd("preferences.browser_home_page_change", 1);
- Services.telemetry.keyedScalarAdd("preferences.browser_home_page_count", homePageNumber, 1);
- }, 3000);
- }
- },
-
- _setHomePageToBookmarkClosed(rv, aEvent) {
- if (aEvent.detail.button != "accept")
- return;
- if (rv.urls && rv.names) {
- var homePage = Preferences.get("browser.startup.homepage");
-
- // XXX still using dangerous "|" joiner!
- homePage.value = rv.urls.join("|");
- }
- },
-
- /**
- * Switches the "Use Current Page" button between its singular and plural
- * forms.
- */
- async _updateUseCurrentButton() {
- let useCurrent = document.getElementById("useCurrent");
- let tabs = this._getTabsForHomePage();
-
- const tabCount = tabs.length;
-
- document.l10n.setAttributes(useCurrent, "use-current-pages", { tabCount });
-
- // If the homepage is controlled by an extension then you can't use this.
- if (await getControllingExtensionInfo(PREF_SETTING_TYPE, HOMEPAGE_OVERRIDE_KEY)) {
- return;
- }
-
- // In this case, the button's disabled state is set by preferences.xml.
- let prefName = "pref.browser.homepage.disable_button.current_page";
- if (Preferences.get(prefName).locked)
- return;
-
- useCurrent.disabled = tabCount < 1;
- },
-
- _getTabsForHomePage() {
- var tabs = [];
- var win = Services.wm.getMostRecentWindow("navigator:browser");
-
- if (win && win.document.documentElement
- .getAttribute("windowtype") == "navigator:browser") {
- // We should only include visible & non-pinned tabs
-
- tabs = win.gBrowser.visibleTabs.slice(win.gBrowser._numPinnedTabs);
- tabs = tabs.filter(this.isNotAboutPreferences);
- // XXX: Bug 1441637 - Fix tabbrowser to report tab.closing before it blurs it
- tabs = tabs.filter(tab => !tab.closing);
- }
-
- return tabs;
- },
-
- /**
- * Check to see if a tab is not about:preferences
- */
- isNotAboutPreferences(aElement, aIndex, aArray) {
- return !aElement.linkedBrowser.currentURI.spec.startsWith("about:preferences");
- },
-
- /**
- * Restores the default home page as the user's home page.
- */
- restoreDefaultHomePage() {
- var homePage = Preferences.get("browser.startup.homepage");
- homePage.value = homePage.defaultValue;
- },
-
/**
* Utility function to enable/disable the button specified by aButtonID based
* on the value of the Boolean preference specified by aPreferenceID.
*/
updateButtons(aButtonID, aPreferenceID) {
var button = document.getElementById(aButtonID);
var preference = Preferences.get(aPreferenceID);
button.disabled = !preference.value;
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -74,71 +74,20 @@
id="browserStartupHomePage"/>
<radio data-l10n-id="startup-blank-page"
value="0"
id="browserStartupBlank"/>
<radio data-l10n-id="startup-prev-session"
value="3"
id="browserStartupLastSession"/>
</radiogroup>
- <hbox id="browserNewTabExtensionContent" align="center" hidden="true">
- <description control="disableNewTabExtension" flex="1" />
- <button id="disableNewTabExtension"
- class="extension-controlled-button accessory-button"
- data-l10n-id="disable-extension" />
- </hbox>
+
</vbox>
</groupbox>
-<!-- Home Page -->
-<groupbox id="homepageGroup"
- data-category="paneGeneral"
- hidden="true">
- <caption><label data-l10n-id="home-page-header"/></caption>
-
- <hbox id="browserHomePageExtensionContent" align="center" hidden="true">
- <description control="disableHomePageExtension" flex="1" />
- <button id="disableHomePageExtension"
- class="extension-controlled-button accessory-button"
- data-l10n-id="disable-extension" />
- </hbox>
-
- <vbox>
- <textbox id="browserHomePage"
- class="uri-element"
- type="autocomplete"
- autocompletesearch="unifiedcomplete"
- onsyncfrompreference="return gMainPane.syncFromHomePref();"
- onsynctopreference="return gMainPane.syncToHomePref(this.value);"
- placeholder="&abouthome.pageTitle;"
- preference="browser.startup.homepage"/>
- </vbox>
-
- <hbox class="homepage-buttons">
- <button id="useCurrent"
- flex="1"
- class="homepage-button"
- data-l10n-id="use-current-pages"
- data-l10n-args='{"tabCount": 0}'
- disabled="true"
- preference="pref.browser.homepage.disable_button.current_page"/>
- <button id="useBookmark"
- flex="1"
- class="homepage-button"
- data-l10n-id="choose-bookmark"
- preference="pref.browser.homepage.disable_button.bookmark_page"
- searchkeywords="&selectBookmark.title; &selectBookmark.label;"/>
- <button id="restoreDefaultHomePage"
- flex="1"
- class="homepage-button"
- data-l10n-id="restore-default"
- preference="pref.browser.homepage.disable_button.restore_default"/>
- </hbox>
-</groupbox>
-
<!-- Tab preferences -->
<groupbox data-category="paneGeneral"
hidden="true">
<caption><label data-l10n-id="tabs-group-header"/></caption>
<checkbox id="ctrlTabRecentlyUsedOrder" data-l10n-id="ctrl-tab-recently-used-order"
preference="browser.ctrlTab.previews"/>
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -140,17 +140,17 @@
<richlistitem id="category-home"
class="category"
value="paneHome"
helpTopic="prefs-home"
data-l10n-id="category-home"
data-l10n-attrs="tooltiptext"
align="center"
- hidden="true">
+ hidden="false">
<image class="category-icon"/>
<label class="category-name" flex="1" data-l10n-id="pane-home-title"></label>
</richlistitem>
<richlistitem id="category-search"
class="category"
value="paneSearch"
helpTopic="prefs-search"
--- a/browser/components/preferences/in-content/tests/browser_extension_controlled.js
+++ b/browser/components/preferences/in-content/tests/browser_extension_controlled.js
@@ -77,42 +77,47 @@ function waitForEnableMessage(messageId,
function waitForMessageContent(messageId, content, doc) {
return waitForMessageChange(
getElement(messageId, doc),
target => target.textContent === content,
{ childList: true });
}
add_task(async function testExtensionControlledHomepage() {
- await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+ await openPreferencesViaOpenPreferencesAPI("paneHome", {leaveOpen: true});
+ // eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = gBrowser.contentDocument;
- is(gBrowser.currentURI.spec, "about:preferences#general",
- "#general should be in the URI for about:preferences");
+ is(gBrowser.currentURI.spec, "about:preferences#home",
+ "#home should be in the URI for about:preferences");
let homepagePref = () => Services.prefs.getCharPref("browser.startup.homepage");
let originalHomepagePref = homepagePref();
let extensionHomepage = "https://developer.mozilla.org/";
let controlledContent = doc.getElementById("browserHomePageExtensionContent");
- // The homepage is set to the default and editable.
+ let homeModeEl = doc.getElementById("homeMode");
+ let customSettingsSection = doc.getElementById("customSettings");
+
+ // The homepage is set to the default and the custom settings section is hidden
ok(originalHomepagePref != extensionHomepage, "homepage is empty by default");
- is(doc.getElementById("browserHomePage").disabled, false, "The homepage input is enabled");
+ is(homeModeEl.disabled, false, "The homepage menulist is enabled");
+ is(customSettingsSection.hidden, true, "The custom settings element is hidden");
is(controlledContent.hidden, true, "The extension controlled row is hidden");
// Install an extension that will set the homepage.
await installAddon("set_homepage.xpi");
await waitForMessageShown("browserHomePageExtensionContent");
// The homepage has been set by the extension, the user is notified and it isn't editable.
let controlledLabel = controlledContent.querySelector("description");
is(homepagePref(), extensionHomepage, "homepage is set by extension");
// There are two spaces before "set_homepage" because it's " <image /> set_homepage".
is(controlledLabel.textContent, "An extension, set_homepage, is controlling your home page.",
"The user is notified that an extension is controlling the homepage");
is(controlledContent.hidden, false, "The extension controlled row is hidden");
- is(doc.getElementById("browserHomePage").disabled, true, "The homepage input is disabled");
+ is(homeModeEl.disabled, true, "The homepage input is disabled");
// Disable the extension.
let enableMessageShown = waitForEnableMessage(controlledContent.id);
doc.getElementById("disableHomePageExtension").click();
await enableMessageShown;
// The user is notified how to enable the extension.
is(controlledLabel.textContent, "To enable the extension go to Add-ons in the menu.",
@@ -120,53 +125,58 @@ add_task(async function testExtensionCon
// The user can dismiss the enable instructions.
let hidden = waitForMessageHidden("browserHomePageExtensionContent");
controlledLabel.querySelector("image:last-of-type").click();
await hidden;
// The homepage elements are reset to their original state.
is(homepagePref(), originalHomepagePref, "homepage is set back to default");
- is(doc.getElementById("browserHomePage").disabled, false, "The homepage input is enabled");
+ is(homeModeEl.disabled, false, "The homepage menulist is enabled");
is(controlledContent.hidden, true, "The extension controlled row is hidden");
// Cleanup the add-on and tab.
let addon = await AddonManager.getAddonByID("@set_homepage");
// Enable the extension so we get the UNINSTALL event, which is needed by
// ExtensionPreferencesManager to clean up properly.
// FIXME: See https://bugzilla.mozilla.org/show_bug.cgi?id=1408226.
addon.userDisabled = false;
await waitForMessageShown("browserHomePageExtensionContent");
// Do the uninstall now that the enable code has been run.
addon.uninstall();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function testPrefLockedHomepage() {
- await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+ await openPreferencesViaOpenPreferencesAPI("paneHome", {leaveOpen: true});
+ // eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = gBrowser.contentDocument;
- is(gBrowser.currentURI.spec, "about:preferences#general",
- "#general should be in the URI for about:preferences");
+ is(gBrowser.currentURI.spec, "about:preferences#home",
+ "#home should be in the URI for about:preferences");
let homePagePref = "browser.startup.homepage";
let buttonPrefs = [
"pref.browser.homepage.disable_button.current_page",
"pref.browser.homepage.disable_button.bookmark_page",
"pref.browser.homepage.disable_button.restore_default",
];
- let homePageInput = doc.getElementById("browserHomePage");
+ let homeModeEl = doc.getElementById("homeMode");
+ let homePageInput = doc.getElementById("homePageUrl");
let prefs = Services.prefs.getDefaultBranch(null);
let mutationOpts = {attributes: true, attributeFilter: ["disabled"]};
let controlledContent = doc.getElementById("browserHomePageExtensionContent");
// Helper functions.
let getButton = pref => doc.querySelector(`.homepage-button[preference="${pref}"`);
let waitForAllMutations = () => Promise.all(
buttonPrefs.map(pref => waitForMutation(getButton(pref), mutationOpts))
- .concat([waitForMutation(homePageInput, mutationOpts)]));
+ .concat([
+ waitForMutation(homeModeEl, mutationOpts),
+ waitForMutation(homePageInput, mutationOpts)
+ ]));
let getHomepage = () => Services.prefs.getCharPref("browser.startup.homepage");
let originalHomepage = getHomepage();
let extensionHomepage = "https://developer.mozilla.org/";
let lockedHomepage = "http://www.yahoo.com";
let lockPrefs = () => {
buttonPrefs.forEach(pref => {
@@ -191,96 +201,105 @@ add_task(async function testPrefLockedHo
// Install an extension that sets the homepage to MDN.
await installAddon("set_homepage.xpi");
await waitForMessageShown(controlledContent.id);
// Check that everything is still disabled, homepage didn't change.
is(getHomepage(), extensionHomepage, "The reported homepage is set by the extension");
is(homePageInput.value, extensionHomepage, "The homepage is set by the extension");
- is(homePageInput.disabled, true, "Homepage is disabled when set by extension");
+ is(homePageInput.disabled, true, "Homepage custom input is disabled when set by extension");
+ is(homeModeEl.disabled, true, "Homepage menulist is disabled when set by extension");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `${pref} is disabled when set by extension`);
});
is(controlledContent.hidden, false, "The extension controlled message is shown");
// Lock all of the prefs, wait for the UI to update.
let messageHidden = waitForMessageHidden(controlledContent.id);
+
lockPrefs();
await messageHidden;
// 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 the pref is locked");
+
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `The ${pref} button is disabled when locked`);
});
is(controlledContent.hidden, true, "The extension controlled message is hidden when locked");
// Unlock the prefs, wait for the UI to update.
let messageShown = waitForMessageShown(controlledContent.id);
unlockPrefs();
await messageShown;
// Verify that the UI is showing the extension's settings.
is(homePageInput.value, extensionHomepage, "The homepage is set by the extension");
is(homePageInput.disabled, true, "Homepage is disabled when set by extension");
+ is(homeModeEl.disabled, true, "Homepage menulist is disabled when set by extension");
buttonPrefs.forEach(pref => {
is(getButton(pref).disabled, true, `${pref} is disabled when set by extension`);
});
is(controlledContent.hidden, false, "The extension controlled message is shown when unlocked");
// Uninstall the add-on.
let addon = await AddonManager.getAddonByID("@set_homepage");
addon.uninstall();
await waitForEnableMessage(controlledContent.id);
// Check that everything is now enabled again.
is(getHomepage(), originalHomepage, "The reported homepage is reset to original value");
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.
lockPrefs();
await waitForAllMutations();
// 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`);
});
// Unlock the prefs without an extension.
unlockPrefs();
await waitForAllMutations();
// Check that everything is enabled again.
is(getHomepage(), originalHomepage, "The homepage is reset to the original value");
is(homePageInput.value, "", "The homepage is clear after being unlocked");
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`);
});
is(controlledContent.hidden, true,
"The extension controlled message is hidden when unlocked with no extension");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function testExtensionControlledNewTab() {
- await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+ await openPreferencesViaOpenPreferencesAPI("paneHome", {leaveOpen: true});
+ // eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = gBrowser.contentDocument;
- is(gBrowser.currentURI.spec, "about:preferences#general",
- "#general should be in the URI for about:preferences");
+ is(gBrowser.currentURI.spec, "about:preferences#home",
+ "#home should be in the URI for about:preferences");
let controlledContent = doc.getElementById("browserNewTabExtensionContent");
// The new tab is set to the default and message is hidden.
ok(!aboutNewTabService.newTabURL.startsWith("moz-extension:"), "new tab is not set");
is(controlledContent.hidden, true, "The extension controlled row is hidden");
// Install an extension that will set the new tab page.
@@ -411,26 +430,27 @@ add_task(async function testExtensionCon
await originalExtension.unload();
await updatedExtension.unload();
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function testExtensionControlledHomepageUninstalledAddon() {
async function checkHomepageEnabled() {
- await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+ await openPreferencesViaOpenPreferencesAPI("paneHome", {leaveOpen: true});
+ // eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = gBrowser.contentDocument;
- is(gBrowser.currentURI.spec, "about:preferences#general",
- "#general should be in the URI for about:preferences");
+ is(gBrowser.currentURI.spec, "about:preferences#home",
+ "#home should be in the URI for about:preferences");
let controlledContent = doc.getElementById("browserHomePageExtensionContent");
// The homepage is enabled.
- let homepageInut = doc.getElementById("browserHomePage");
- is(homepageInut.disabled, false, "The homepage input is enabled");
- is(homepageInut.value, "", "The homepage input is empty");
+ let homepageInput = doc.getElementById("homePageUrl");
+ is(homepageInput.disabled, false, "The homepage input is enabled");
+ is(homepageInput.value, "", "The homepage input is empty");
is(controlledContent.hidden, true, "The extension controlled row is hidden");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
}
await ExtensionSettingsStore.initialize();
// Verify the setting isn't reported as controlled and the inputs are enabled.
--- 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,18 +1,19 @@
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("paneGeneral", {leaveOpen: true});
+ await openPreferencesViaOpenPreferencesAPI("paneHome", {leaveOpen: true});
+ // eslint-disable-next-line mozilla/no-cpows-in-tests
let doc = gBrowser.contentDocument;
- is(gBrowser.currentURI.spec, "about:preferences#general",
- "#general should be in the URI for about:preferences");
+ 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 useCurrent = doc.getElementById("useCurrent");
+ 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",
"about:blank and about:home should be the only homepages set");
Services.prefs.setCharPref("browser.startup.homepage", oldHomepagePref);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
--- a/browser/components/preferences/in-content/tests/browser_search_subdialogs_within_preferences_1.js
+++ b/browser/components/preferences/in-content/tests/browser_search_subdialogs_within_preferences_1.js
@@ -6,17 +6,21 @@
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.preferences.search", true]]});
});
/**
* Test for searching for the "Set Home Page" subdialog.
*/
add_task(async function() {
- await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+ await openPreferencesViaOpenPreferencesAPI("paneHome", {leaveOpen: true});
+
+ // Set custom URL so bookmark button will be shown on the page (otherwise it is hidden)
+ await SpecialPowers.pushPrefEnv({"set": [["browser.startup.homepage", "about:robots"]]});
+
await evaluateSearchResults("Set Home Page", "homepageGroup");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
/**
* Test for searching for the "Languages" subdialog.
*/
add_task(async function() {
--- a/browser/components/preferences/in-content/tests/browser_search_within_preferences_1.js
+++ b/browser/components/preferences/in-content/tests/browser_search_within_preferences_1.js
@@ -105,17 +105,16 @@ add_task(async function() {
}
await searchCompletedPromise;
// Checks if back to generalPane
for (let i = 0; i < mainPrefTag.childElementCount; i++) {
let child = mainPrefTag.children[i];
if (child.id == "paneGeneral"
|| child.id == "startupGroup"
- || child.id == "homepageGroup"
|| child.id == "languagesGroup"
|| child.id == "fontsGroup"
|| child.id == "downloadsGroup"
|| child.id == "applicationsGroup"
|| child.id == "drmGroup"
|| child.id == "updateApp"
|| child.id == "browsingGroup"
|| child.id == "performanceGroup"
--- a/browser/locales/en-US/browser/preferences/preferences.ftl
+++ b/browser/locales/en-US/browser/preferences/preferences.ftl
@@ -125,38 +125,16 @@ startup-user-homepage =
startup-blank-page =
.label = Show a blank page
startup-prev-session =
.label = Show your windows and tabs from last time
disable-extension =
.label = Disable Extension
-home-page-header = Home page
-
-# This string has a special case for '1' and [other] (default). If necessary for
-# your language, you can add {$tabCount} to your translations and use the
-# standard CLDR forms, or only use the form for [other] if both strings should
-# be identical.
-use-current-pages =
- .label =
- { $tabCount ->
- [1] Use Current Page
- *[other] Use Current Pages
- }
- .accesskey = C
-
-choose-bookmark =
- .label = Use Bookmark…
- .accesskey = B
-
-restore-default =
- .label = Restore to Default
- .accesskey = R
-
tabs-group-header = Tabs
ctrl-tab-recently-used-order =
.label = Ctrl+Tab cycles through tabs in recently used order
.accesskey = T
open-new-link-as-tabs =
.label = Open links in tabs instead of new windows
@@ -378,16 +356,62 @@ browsing-search-on-start-typing =
network-proxy-title = Network Proxy
network-proxy-connection-learn-more = Learn More
network-proxy-connection-settings =
.label = Settings…
.accesskey = e
+## Home Section
+
+home-new-windows-tabs-header = New Windows and Tabs
+
+home-new-windows-tabs-description = Choose what you see when you open your homepage, new windows, and new tabs
+
+## Home Section - Home Page Customization
+
+home-homepage-mode-label = Homepage and new windows
+
+home-newtabs-mode-label = New tabs
+
+home-restore-defaults =
+ .label = Restore Defaults
+ .accesskey = R
+
+# "Firefox" should be treated as a brand and kept in English,
+# while "Home" and "(Default)" can be localized.
+home-mode-choice-default =
+ .label = Firefox Home (Default)
+
+home-mode-choice-custom =
+ .label = Custom URLs…
+
+home-mode-choice-blank =
+ .label = Blank Page
+
+home-homepage-custom-url =
+ .placeholder = Paste a URL…
+
+# This string has a special case for '1' and [other] (default). If necessary for
+# your language, you can add {$tabCount} to your translations and use the
+# standard CLDR forms, or only use the form for [other] if both strings should
+# be identical.
+use-current-pages =
+ .label =
+ { $tabCount ->
+ [1] Use Current Page
+ *[other] Use Current Pages
+ }
+ .accesskey = C
+
+choose-bookmark =
+ .label = Use Bookmark…
+ .accesskey = B
+
## Search Section
search-bar-header = Search Bar
search-bar-hidden =
.label = Use the address bar for search and navigation
search-bar-shown =
.label = Add search bar in toolbar
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -183,30 +183,16 @@ button > hbox > label {
#isDefaultLabel {
font-weight: 600;
}
#startupPageBox {
padding-top: 32px;
}
-#browserHomePage {
- margin-inline-start: 0;
- margin-inline-end: 0;
- margin-bottom: 4px;
-}
-
-.homepage-button:first-of-type {
- margin-inline-start: 0;
-}
-
-.homepage-button:last-of-type {
- margin-inline-end: 0;
-}
-
.extension-controlled-icon {
height: 20px;
margin: 2px 0 6px;
vertical-align: middle;
width: 20px;
}
.extension-controlled-disabled {
@@ -230,21 +216,16 @@ button > hbox > label {
#getStarted {
font-size: 90%;
}
#downloadFolder {
margin-inline-start: 0;
}
-#browserHomePage:-moz-locale-dir(rtl) input {
- unicode-bidi: plaintext;
- direction: rtl;
-}
-
#updateApp > .groupbox-body > label {
margin: 0 0 4px;
}
#updateApp > .groupbox-body > description {
margin: 0;
}
@@ -310,16 +291,32 @@ button > hbox > label {
.actionsMenu > menupopup > menuitem {
padding-inline-start: 10px !important;
}
.actionsMenu > menupopup > menuitem > .menu-iconic-left {
margin-inline-end: 8px !important;
}
+/* Home Pane */
+#homepageGroup menulist,
+#homepageGroup textbox {
+ margin: 5px 0;
+}
+#homepageGroup:-moz-locale-dir(rtl) input {
+ unicode-bidi: plaintext;
+ direction: rtl;
+}
+.homepage-button:first-of-type {
+ margin-inline-start: 0;
+}
+.homepage-button:last-of-type {
+ margin-inline-end: 0;
+}
+
/* Search Pane */
#engineList {
margin: 2px 0 5px;
}
#engineList > treechildren::-moz-tree-image(engineShown, checked),
#blocklistsTree > treechildren::-moz-tree-image(selectionCol, checked) {