Bug 727668 - Show bookmarks toolbar on the new tab page. r=Gijs,fluent-reviewers,marionette-reviewers,whimboo
authorJared Wein <jwein@mozilla.com>
Mon, 26 Oct 2020 02:32:07 +0000
changeset 554356 45bbeabb0c89cf73d644b59898cb207e4462f147
parent 554355 a4853e82ea7a0f42cebd8b5ca5d769222befaada
child 554357 9cf73428357c3679bf6dfff0e1e0c1bc24d5c0e9
push id37893
push userbtara@mozilla.com
push dateMon, 26 Oct 2020 09:28:34 +0000
treeherdermozilla-central@b1a74943bc51 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, fluent-reviewers, marionette-reviewers, whimboo
bugs727668
milestone84.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 727668 - Show bookmarks toolbar on the new tab page. r=Gijs,fluent-reviewers,marionette-reviewers,whimboo This adds the ability to force the bookmarks toolbar to appear on all pages. The checkbox in the toolbar context menu will reflect if the toolbar will appear outside of the newtab page. The toolbar will always appear on the newtab page. Profiles that already had the toolbar showing will have a migration to keep their experience unchanged. Differential Revision: https://phabricator.services.mozilla.com/D89222
browser/app/profile/firefox.js
browser/base/content/browser-places.js
browser/base/content/browser-sets.inc
browser/base/content/browser.js
browser/base/content/browser.xhtml
browser/base/content/test/about/browser.ini
browser/base/content/test/about/browser_aboutNewTab_bookmarksToolbar.js
browser/base/content/test/about/browser_aboutNewTab_bookmarksToolbarPrefs.js
browser/base/content/test/about/head.js
browser/base/content/test/keyboard/browser_bookmarks_shortcut.js
browser/base/content/test/keyboard/browser_toolbarKeyNav.js
browser/base/content/test/performance/browser_tabclose.js
browser/base/content/test/performance/browser_tabclose_grow.js
browser/base/content/test/performance/browser_tabopen.js
browser/base/content/test/performance/browser_tabopen_squeeze.js
browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js
browser/base/content/test/performance/browser_tabswitch.js
browser/base/content/test/performance/browser_windowopen.js
browser/base/content/test/performance/head.js
browser/components/BrowserGlue.jsm
browser/components/customizableui/CustomizableUI.jsm
browser/components/customizableui/test/browser.ini
browser/components/customizableui/test/browser_bookmarks_toolbar_collapsed_restore_default.js
browser/components/enterprisepolicies/Policies.jsm
browser/components/extensions/test/browser/head.js
browser/components/places/content/editBookmark.js
browser/components/places/tests/browser/browser_enable_toolbar_sidebar.js
browser/components/places/tests/browser/browser_toolbar_overflow.js
browser/components/places/tests/browser/head.js
browser/locales/en-US/browser/toolbarContextMenu.ftl
browser/modules/BrowserUsageTelemetry.jsm
browser/modules/test/browser/browser_UsageTelemetry_interaction.js
browser/modules/test/browser/browser_UsageTelemetry_toolbars.js
browser/themes/shared/browser.inc.css
testing/marionette/client/marionette_driver/geckoinstance.py
testing/marionette/components/marionette.js
testing/profiles/web-platform/user.js
toolkit/components/extensions/test/browser/browser_ext_themes_theme_transition.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -2038,16 +2038,21 @@ pref("browser.discovery.containers.enabl
 pref("browser.discovery.sites", "addons.mozilla.org");
 
 pref("browser.engagement.recent_visited_origins.expiry", 86400); // 24 * 60 * 60 (24 hours in seconds)
 
 pref("browser.aboutConfig.showWarning", true);
 
 pref("browser.toolbars.keyboard_navigation", true);
 
+// The visibility of the bookmarks toolbar.
+// "newtab": Show on the New Tab Page
+// "always": Always show
+// "never": Never show
+pref("browser.toolbars.bookmarks.visibility", "newtab");
 // When true, this pref will always show the bookmarks bar on
 // the New Tab Page, allowing showing/hiding via keyboard shortcut,
 // and other functionality to improve the usage of the Bookmarks Toolbar.
 #ifdef NIGHTLY_BUILD
 pref("browser.toolbars.bookmarks.2h2020", true);
 #else
 pref("browser.toolbars.bookmarks.2h2020", false);
 #endif
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -8,16 +8,22 @@
 XPCOMUtils.defineLazyScriptGetter(
   this,
   ["PlacesToolbar", "PlacesMenu", "PlacesPanelview", "PlacesPanelMenuView"],
   "chrome://browser/content/places/browserPlacesViews.js"
 );
 XPCOMUtils.defineLazyModuleGetters(this, {
   BookmarkPanelHub: "resource://activity-stream/lib/BookmarkPanelHub.jsm",
 });
+XPCOMUtils.defineLazyPreferenceGetter(
+  this,
+  "NEWTAB_ENABLED",
+  "browser.newtabpage.enabled",
+  false
+);
 ChromeUtils.defineModuleGetter(
   this,
   "PanelMultiView",
   "resource:///modules/PanelMultiView.jsm"
 );
 
 var StarUI = {
   _itemGuids: null,
@@ -1514,27 +1520,101 @@ var BookmarkingUI = {
     let element = PanelMultiView.getViewNode(document, elementId);
     element.setAttribute(
       "label",
       element.getAttribute(visible ? "label-hide" : "label-show")
     );
   },
 
   toggleBookmarksToolbar(reason) {
-    CustomizableUI.setToolbarVisibility(
-      "PersonalToolbar",
-      document.getElementById("PersonalToolbar").collapsed
+    let toolbar = document.getElementById("PersonalToolbar");
+    let newState = toolbar.collapsed ? "always" : "never";
+    Services.prefs.setCharPref(
+      "browser.toolbars.bookmarks.visibility",
+      // See firefox.js for possible values
+      newState
     );
+
+    CustomizableUI.setToolbarVisibility("PersonalToolbar", newState, false);
     BrowserUsageTelemetry.recordToolbarVisibility(
       "PersonalToolbar",
-      document.getElementById("PersonalToolbar").collapsed,
+      newState,
       reason
     );
   },
 
+  isOnNewTabPage({ currentURI, isNullPrincipal }) {
+    if (!NEWTAB_ENABLED && currentURI?.spec == "about:blank") {
+      return isNullPrincipal;
+    }
+    // Prevent loading AboutNewTab.jsm during startup path if it
+    // is only the newTabURL getter we are interested in.
+    let newTabURL = Cu.isModuleLoaded("resource:///modules/AboutNewTab.jsm")
+      ? AboutNewTab.newTabURL
+      : "about:newtab";
+    let newTabURLs = [newTabURL, "about:home"];
+    if (PrivateBrowsingUtils.isWindowPrivate(window)) {
+      newTabURLs.push("about:privatebrowsing");
+    }
+    return newTabURLs.some(uri => currentURI?.spec.startsWith(uri));
+  },
+
+  buildBookmarksToolbarSubmenu(toolbar) {
+    let alwaysShowMenuItem = document.createXULElement("menuitem");
+    let alwaysHideMenuItem = document.createXULElement("menuitem");
+    let showOnNewTabMenuItem = document.createXULElement("menuitem");
+    let menuPopup = document.createXULElement("menupopup");
+    menuPopup.append(
+      alwaysShowMenuItem,
+      alwaysHideMenuItem,
+      showOnNewTabMenuItem
+    );
+    let menu = document.createXULElement("menu");
+    menu.appendChild(menuPopup);
+
+    menu.setAttribute("label", toolbar.getAttribute("toolbarname"));
+    menu.setAttribute("id", "toggle_" + toolbar.id);
+    menu.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
+    menu.setAttribute("toolbarId", toolbar.id);
+    let menuItems = [
+      [
+        showOnNewTabMenuItem,
+        "toolbar-context-menu-bookmarks-toolbar-on-new-tab",
+        "newtab",
+      ],
+      [
+        alwaysShowMenuItem,
+        "toolbar-context-menu-bookmarks-toolbar-always-show",
+        "always",
+      ],
+      [
+        alwaysHideMenuItem,
+        "toolbar-context-menu-bookmarks-toolbar-never-show",
+        "never",
+      ],
+    ];
+    menuItems.map(([menuItem, l10nId, visibilityEnum]) => {
+      document.l10n.setAttributes(menuItem, l10nId);
+      menuItem.setAttribute("type", "checkbox");
+      // The persisted state of the PersonalToolbar is stored in
+      // "browser.toolbars.bookmarks.visibility".
+      menuItem.setAttribute(
+        "checked",
+        gBookmarksToolbarVisibility == visibilityEnum
+      );
+      // Identify these items for "onViewToolbarCommand" so
+      // we know to check the visibilityEnum value.
+      menuItem.dataset.bookmarksToolbarVisibility = true;
+      menuItem.dataset.visibilityEnum = visibilityEnum;
+      menuItem.addEventListener("command", onViewToolbarCommand);
+    });
+
+    return menu;
+  },
+
   attachPlacesView(event, node) {
     // If the view is already there, bail out early.
     if (node.parentNode._placesView) {
       return;
     }
 
     new PlacesMenu(event, `place:parent=${PlacesUtils.bookmarks.menuGuid}`, {
       extraClasses: {
@@ -2117,33 +2197,8 @@ var BookmarkingUI = {
 
     // The view gets broken by being removed and reinserted. Uninit
     // here so popupshowing will generate a new one:
     this._uninitView();
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsINavBookmarkObserver"]),
 };
-
-var AutoShowBookmarksToolbar = {
-  init() {
-    Services.obs.addObserver(this, "autoshow-bookmarks-toolbar");
-  },
-
-  uninit() {
-    Services.obs.removeObserver(this, "autoshow-bookmarks-toolbar");
-  },
-
-  observe(subject, topic, data) {
-    let toolbar = document.getElementById("PersonalToolbar");
-    if (!toolbar.collapsed) {
-      return;
-    }
-
-    let placement = CustomizableUI.getPlacementOfWidget("personal-bookmarks");
-    let area = placement && placement.area;
-    if (area != CustomizableUI.AREA_BOOKMARKS) {
-      return;
-    }
-
-    setToolbarVisibility(toolbar, true);
-  },
-};
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -267,17 +267,17 @@
          modifiers="accel,shift"/>
     <key id="manBookmarkKb" data-l10n-id="bookmark-show-library-shortcut" command="Browser:ShowAllBookmarks" modifiers="accel,shift"/>
     <key id="viewBookmarksSidebarKb"
          data-l10n-id="bookmark-show-sidebar-shortcut"
          modifiers="accel"
          oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
     <key id="viewBookmarksToolbarKb"
          data-l10n-id="bookmark-show-toolbar-shortcut"
-         oncommand="toggleBookmarksToolbar()"
+         oncommand="toggleBookmarksToolbarViaKeyboardShortcut()"
          modifiers="accel,shift"/>
 
     <key id="key_stop" keycode="VK_ESCAPE" command="Browser:Stop"/>
 
 #ifdef XP_MACOSX
     <key id="key_stop_mac" modifiers="accel" data-l10n-id="nav-stop-shortcut" command="Browser:Stop"/>
 #endif
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -479,16 +479,29 @@ XPCOMUtils.defineLazyPreferenceGetter(
     } else {
       ToolbarKeyboardNavigator.uninit();
     }
   }
 );
 
 XPCOMUtils.defineLazyPreferenceGetter(
   this,
+  "gBookmarksToolbar2h2020",
+  "browser.toolbars.bookmarks.2h2020",
+  false
+);
+XPCOMUtils.defineLazyPreferenceGetter(
+  this,
+  "gBookmarksToolbarVisibility",
+  "browser.toolbars.bookmarks.visibility",
+  "newtab"
+);
+
+XPCOMUtils.defineLazyPreferenceGetter(
+  this,
   "gFxaToolbarEnabled",
   "identity.fxaccounts.toolbar.enabled",
   false,
   (aPref, aOldVal, aNewVal) => {
     updateFxaToolbarMenu(aNewVal);
   }
 );
 
@@ -1784,16 +1797,24 @@ var gBrowserInit = {
       "BrowserToolbarPalette"
     ).content;
     let areas = CustomizableUI.areas;
     areas.splice(areas.indexOf(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL), 1);
     for (let area of areas) {
       let node = document.getElementById(area);
       CustomizableUI.registerToolbarNode(node);
     }
+    setToolbarVisibility(
+      gNavToolbox.querySelector("#PersonalToolbar"),
+      gBookmarksToolbar2h2020
+        ? gBookmarksToolbarVisibility
+        : gBookmarksToolbarVisibility == "always",
+      false,
+      false
+    );
     BrowserSearch.initPlaceHolder();
 
     // Hack to ensure that the various initial pages favicon is loaded
     // instantaneously, to avoid flickering and improve perceived performance.
     this._callWithURIToLoad(uriToLoad => {
       let url;
       try {
         url = Services.io.newURI(uriToLoad);
@@ -1979,17 +2000,16 @@ var gBrowserInit = {
     PanelUI.init();
 
     SiteSpecificBrowserUI.init();
 
     UpdateUrlbarSearchSplitterState();
 
     BookmarkingUI.init();
     BrowserSearch.delayedStartupInit();
-    AutoShowBookmarksToolbar.init();
     gProtectionsHandler.init();
     HomePage.delayedStartup().catch(Cu.reportError);
 
     let safeMode = document.getElementById("helpSafeMode");
     if (Services.appinfo.inSafeMode) {
       document.l10n.setAttributes(safeMode, "menu-help-safe-mode-with-addons");
     }
 
@@ -2585,17 +2605,16 @@ var gBrowserInit = {
       if (AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
         MenuTouchModeObserver.uninit();
       }
       BrowserOffline.uninit();
       IndexedDBPromptHelper.uninit();
       CanvasPermissionPromptHelper.uninit();
       WebAuthnPromptHelper.uninit();
       PanelUI.uninit();
-      AutoShowBookmarksToolbar.uninit();
     }
 
     // Final window teardown, do this last.
     gBrowser.destroy();
     window.XULBrowserWindow = null;
     window.docShell.treeOwner
       .QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIAppWindow).XULBrowserWindow = null;
@@ -5368,16 +5387,25 @@ var XULBrowserWindow = {
 
       // We want to update the popup visibility if we received this notification
       // via simulated locationchange events such as switching between tabs, however
       // if this is a document navigation then PopupNotifications will be updated
       // via TabsProgressListener.onLocationChange and we do not want it called twice
       gURLBar.setURI(aLocationURI, aIsSimulated);
 
       BookmarkingUI.onLocationChange();
+      if (gBookmarksToolbar2h2020) {
+        let bookmarksToolbar = gNavToolbox.querySelector("#PersonalToolbar");
+        setToolbarVisibility(
+          bookmarksToolbar,
+          gBookmarksToolbarVisibility,
+          false,
+          false
+        );
+      }
 
       gIdentityHandler.onLocationChange();
 
       gProtectionsHandler.onLocationChange();
 
       BrowserPageActions.onLocationChange();
 
       SafeBrowsingNotificationBox.onLocationChange(aLocationURI);
@@ -6380,44 +6408,47 @@ function onViewToolbarsPopupShowing(aEve
   // Empty the menu
   for (var i = popup.children.length - 1; i >= 0; --i) {
     var deadItem = popup.children[i];
     if (deadItem.hasAttribute("toolbarId")) {
       popup.removeChild(deadItem);
     }
   }
 
-  var firstMenuItem = aInsertPoint || popup.firstElementChild;
-
+  MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl");
+  let firstMenuItem = aInsertPoint || popup.firstElementChild;
   let toolbarNodes = gNavToolbox.querySelectorAll("toolbar");
-
   for (let toolbar of toolbarNodes) {
     if (!toolbar.hasAttribute("toolbarname")) {
       continue;
     }
 
-    let menuItem = document.createXULElement("menuitem");
-    let hidingAttribute =
-      toolbar.getAttribute("type") == "menubar" ? "autohide" : "collapsed";
-    menuItem.setAttribute("id", "toggle_" + toolbar.id);
-    menuItem.setAttribute("toolbarId", toolbar.id);
-    menuItem.setAttribute("type", "checkbox");
-    menuItem.setAttribute("label", toolbar.getAttribute("toolbarname"));
-    menuItem.setAttribute(
-      "checked",
-      toolbar.getAttribute(hidingAttribute) != "true"
-    );
-    menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
-    if (popup.id != "toolbar-context-menu") {
-      menuItem.setAttribute("key", toolbar.getAttribute("key"));
-    }
-
-    popup.insertBefore(menuItem, firstMenuItem);
-
-    menuItem.addEventListener("command", onViewToolbarCommand);
+    if (toolbar.id == "PersonalToolbar" && gBookmarksToolbar2h2020) {
+      let menu = BookmarkingUI.buildBookmarksToolbarSubmenu(toolbar);
+      popup.insertBefore(menu, firstMenuItem);
+    } else {
+      let menuItem = document.createXULElement("menuitem");
+      menuItem.setAttribute("id", "toggle_" + toolbar.id);
+      menuItem.setAttribute("toolbarId", toolbar.id);
+      menuItem.setAttribute("type", "checkbox");
+      menuItem.setAttribute("label", toolbar.getAttribute("toolbarname"));
+      let hidingAttribute =
+        toolbar.getAttribute("type") == "menubar" ? "autohide" : "collapsed";
+      menuItem.setAttribute(
+        "checked",
+        toolbar.getAttribute(hidingAttribute) != "true"
+      );
+      menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
+      if (popup.id != "toolbar-context-menu") {
+        menuItem.setAttribute("key", toolbar.getAttribute("key"));
+      }
+
+      popup.insertBefore(menuItem, firstMenuItem);
+      menuItem.addEventListener("command", onViewToolbarCommand);
+    }
   }
 
   let moveToPanel = popup.querySelector(".customize-context-moveToPanel");
   let removeFromToolbar = popup.querySelector(
     ".customize-context-removeFromToolbar"
   );
   // View -> Toolbars menu doesn't have the moveToPanel or removeFromToolbar items.
   if (!moveToPanel || !removeFromToolbar) {
@@ -6453,17 +6484,16 @@ function onViewToolbarsPopupShowing(aEve
   )) {
     node.hidden = showTabStripItems;
   }
 
   for (let node of popup.querySelectorAll('menuitem[contexttype="tabbar"]')) {
     node.hidden = !showTabStripItems;
   }
 
-  MozXULElement.insertFTLIfNeeded("browser/toolbarContextMenu.ftl");
   document
     .getElementById("toolbar-context-menu")
     .querySelectorAll("[data-lazy-l10n-id]")
     .forEach(el => {
       el.setAttribute("data-l10n-id", el.getAttribute("data-lazy-l10n-id"));
       el.removeAttribute("data-lazy-l10n-id");
     });
 
@@ -6503,62 +6533,111 @@ function onViewToolbarsPopupShowing(aEve
   } else {
     moveToPanel.setAttribute("disabled", true);
     removeFromToolbar.setAttribute("disabled", true);
   }
 }
 
 function onViewToolbarCommand(aEvent) {
   let node = aEvent.originalTarget;
-  let menuId = node.parentNode.id;
-  let toolbarId = node.getAttribute("toolbarId");
-  let isVisible = node.getAttribute("checked") == "true";
+  let menuId;
+  let toolbarId;
+  let isVisible;
+  if (node.dataset.bookmarksToolbarVisibility) {
+    isVisible = node.dataset.visibilityEnum;
+    toolbarId = "PersonalToolbar";
+    menuId = node.parentNode.parentNode.parentNode.id;
+    Services.prefs.setCharPref(
+      "browser.toolbars.bookmarks.visibility",
+      isVisible
+    );
+  } else {
+    menuId = node.parentNode.id;
+    toolbarId = node.getAttribute("toolbarId");
+    isVisible = node.getAttribute("checked") == "true";
+  }
   CustomizableUI.setToolbarVisibility(toolbarId, isVisible);
   BrowserUsageTelemetry.recordToolbarVisibility(toolbarId, isVisible, menuId);
-  updateToggleControlLabel(node);
 }
 
-function toggleBookmarksToolbar() {
+function toggleBookmarksToolbarViaKeyboardShortcut() {
   // We only show the bookmarks toolbar if the shortcut is enabled.
   const shortcutEnabled = Services.prefs.getBoolPref(
     "browser.toolbars.bookmarks.2h2020",
     false
   );
 
   if (!shortcutEnabled) {
+    // The shortcut was previously used to open the Library,
+    // so if the shortcut is disabled then return to opening the Library.
     PlacesCommandHook.showPlacesOrganizer("UnfiledBookmarks");
     return;
   }
 
-  let toolbar = document.getElementById("PersonalToolbar");
-  let isVisible = toolbar.getAttribute("collapsed") === "true";
-
-  CustomizableUI.setToolbarVisibility("PersonalToolbar", isVisible);
-  BrowserUsageTelemetry.recordToolbarVisibility(
-    "PersonalToolbar",
-    isVisible,
-    "shortcut"
-  );
+  BookmarkingUI.toggleBookmarksToolbar("shortcut");
 }
 
-function setToolbarVisibility(toolbar, isVisible, persist = true) {
+function setToolbarVisibility(
+  toolbar,
+  isVisible,
+  persist = true,
+  animated = true
+) {
   let hidingAttribute;
   if (toolbar.getAttribute("type") == "menubar") {
     hidingAttribute = "autohide";
     if (AppConstants.platform == "linux") {
       Services.prefs.setBoolPref("ui.key.menuAccessKeyFocuses", !isVisible);
     }
   } else {
     hidingAttribute = "collapsed";
   }
 
+  if (persist) {
+    if (toolbar.id == "PersonalToolbar") {
+      let prefValue;
+      if (typeof isVisible == "string") {
+        prefValue = isVisible;
+      } else {
+        prefValue = isVisible ? "always" : "never";
+      }
+      Services.prefs.setCharPref(
+        "browser.toolbars.bookmarks.visibility",
+        prefValue
+      );
+    } else {
+      Services.xulStore.persist(toolbar, hidingAttribute);
+    }
+  }
+
+  if (typeof isVisible == "string") {
+    switch (isVisible) {
+      case "always":
+        isVisible = true;
+        break;
+      case "never":
+        isVisible = false;
+        break;
+      case "newtab":
+        isVisible = BookmarkingUI.isOnNewTabPage({
+          currentURI: gBrowser.currentURI,
+          isNullPrincipal: gBrowser.contentPrincipal.isNullPrincipal,
+        });
+        break;
+    }
+  }
+
+  if (toolbar.getAttribute(hidingAttribute) == (!isVisible).toString()) {
+    // If this call will not result in a visibility change, return early
+    // since dispatching toolbarvisibilitychange will cause views to get rebuilt.
+    return;
+  }
+
+  toolbar.classList.toggle("instant", !animated);
   toolbar.setAttribute(hidingAttribute, !isVisible);
-  if (persist) {
-    Services.xulStore.persist(toolbar, hidingAttribute);
-  }
 
   let eventParams = {
     detail: {
       visible: isVisible,
     },
     bubbles: true,
   };
   let event = new CustomEvent("toolbarvisibilitychange", eventParams);
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -2037,17 +2037,16 @@
     </toolbar>
 
     <toolbar id="PersonalToolbar"
              mode="icons"
              class="browser-toolbar chromeclass-directories"
              context="toolbar-context-menu"
              toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
              aria-label="&personalbar.accessibleLabel;"
-             collapsed="true"
              customizable="true">
       <toolbartabstop skipintoolbarset="true"/>
 
       <toolbaritem id="personal-bookmarks"
                    title="&bookmarksToolbarItem.label;"
                    cui-areatype="toolbar"
                    removable="true">
         <toolbarbutton id="bookmarks-toolbar-placeholder"
--- a/browser/base/content/test/about/browser.ini
+++ b/browser/base/content/test/about/browser.ini
@@ -29,16 +29,18 @@ skip-if = os == "mac" || (os == "linux" 
 [browser_aboutNetError_csp_iframe.js]
 support-files =
   iframe_page_csp.html
   csp_iframe.sjs
 [browser_aboutNetError_xfo_iframe.js]
 support-files =
   iframe_page_xfo.html
   xfo_iframe.sjs
+[browser_aboutNewTab_bookmarksToolbar.js]
+[browser_aboutNewTab_bookmarksToolbarPrefs.js]
 [browser_aboutNewTab_defaultBrowserNotification.js]
 skip-if = debug || asan || ccov # Default browser checks are skipped on debug builds, bug 1660723
 [browser_aboutStopReload.js]
 [browser_aboutSupport.js]
 [browser_aboutSupport_newtab_security_state.js]
 [browser_bug435325.js]
 skip-if = verify && !debug && os == 'mac'
 [browser_bug633691.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/about/browser_aboutNewTab_bookmarksToolbar.js
@@ -0,0 +1,305 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function bookmarks_toolbar_shown_on_newtab() {
+  for (let featureEnabled of [true, false]) {
+    info(
+      "Testing with the feature " + (featureEnabled ? "enabled" : "disabled")
+    );
+    await SpecialPowers.pushPrefEnv({
+      set: [["browser.toolbars.bookmarks.2h2020", featureEnabled]],
+    });
+    let newtab = await BrowserTestUtils.openNewForegroundTab({
+      gBrowser,
+      opening: "about:newtab",
+      waitForLoad: false,
+    });
+
+    // 1: Test that the toolbar is shown in a newly opened foreground about:newtab
+    if (featureEnabled) {
+      await waitForBookmarksToolbarVisibility({ visible: true });
+    }
+    is(
+      isBookmarksToolbarVisible(),
+      featureEnabled,
+      "Toolbar should be visible on newtab if enabled"
+    );
+
+    // 2: Test that the toolbar is hidden when the browser is navigated away from newtab
+    await BrowserTestUtils.loadURI(newtab.linkedBrowser, "https://example.com");
+    await BrowserTestUtils.browserLoaded(newtab.linkedBrowser);
+    if (featureEnabled) {
+      await waitForBookmarksToolbarVisibility({ visible: false });
+    }
+    ok(
+      !isBookmarksToolbarVisible(),
+      "Toolbar should not be visible on newtab after example.com is loaded within"
+    );
+
+    // 3: Re-load about:newtab in the browser for the following tests and confirm toolbar reappears
+    await BrowserTestUtils.loadURI(newtab.linkedBrowser, "about:newtab");
+    await BrowserTestUtils.browserLoaded(newtab.linkedBrowser);
+    if (featureEnabled) {
+      await waitForBookmarksToolbarVisibility({ visible: true });
+    }
+    is(
+      isBookmarksToolbarVisible(),
+      featureEnabled,
+      "Toolbar should be visible on newtab"
+    );
+
+    // 4: Toolbar should get hidden when opening a new tab to example.com
+    let example = await BrowserTestUtils.openNewForegroundTab({
+      gBrowser,
+      opening: "https://example.com",
+    });
+    await waitForBookmarksToolbarVisibility({ visible: false });
+    ok(!isBookmarksToolbarVisible(), "Toolbar should be hidden on example.com");
+
+    // 5: Toolbar should become visible when switching tabs to newtab
+    await BrowserTestUtils.switchTab(gBrowser, newtab);
+    if (featureEnabled) {
+      await waitForBookmarksToolbarVisibility({ visible: true });
+    }
+    is(
+      isBookmarksToolbarVisible(),
+      featureEnabled,
+      "Toolbar is visible with switch to newtab if enabled"
+    );
+
+    // 6: Toolbar should become hidden when switching tabs to example.com
+    await BrowserTestUtils.switchTab(gBrowser, example);
+    await waitForBookmarksToolbarVisibility({ visible: false });
+    ok(
+      !isBookmarksToolbarVisible(),
+      "Toolbar is hidden with switch to example"
+    );
+
+    // 7: Similar to #3 above, loading about:newtab in example should show toolbar
+    await BrowserTestUtils.loadURI(example.linkedBrowser, "about:newtab");
+    await BrowserTestUtils.browserLoaded(example.linkedBrowser);
+    if (featureEnabled) {
+      await waitForBookmarksToolbarVisibility({ visible: true });
+    }
+    is(
+      isBookmarksToolbarVisible(),
+      featureEnabled,
+      "Toolbar is visible with newtab load if enabled"
+    );
+
+    // 8: Switching back and forth between two browsers showing about:newtab will still show the toolbar
+    await BrowserTestUtils.switchTab(gBrowser, newtab);
+    is(
+      isBookmarksToolbarVisible(),
+      featureEnabled,
+      "Toolbar is visible with switch to newtab if enabled"
+    );
+    await BrowserTestUtils.switchTab(gBrowser, example);
+    is(
+      isBookmarksToolbarVisible(),
+      featureEnabled,
+      "Toolbar is visible with switch to example(newtab) if enabled"
+    );
+
+    // 9: With custom newtab URL, toolbar isn't shown on about:newtab but is shown on custom URL
+    let oldNewTab = AboutNewTab.newTabURL;
+    AboutNewTab.newTabURL = "https://example.com/2";
+    await BrowserTestUtils.switchTab(gBrowser, newtab);
+    await waitForBookmarksToolbarVisibility({ visible: false });
+    ok(!isBookmarksToolbarVisible(), "Toolbar should hide with custom newtab");
+    await BrowserTestUtils.loadURI(
+      example.linkedBrowser,
+      AboutNewTab.newTabURL
+    );
+    await BrowserTestUtils.browserLoaded(example.linkedBrowser);
+    await BrowserTestUtils.switchTab(gBrowser, example);
+    if (featureEnabled) {
+      await waitForBookmarksToolbarVisibility({ visible: true });
+    }
+    is(
+      isBookmarksToolbarVisible(),
+      featureEnabled,
+      "Toolbar is visible with switch to custom newtab if enabled"
+    );
+
+    await BrowserTestUtils.removeTab(newtab);
+    await BrowserTestUtils.removeTab(example);
+    AboutNewTab.newTabURL = oldNewTab;
+  }
+});
+
+add_task(async function bookmarks_toolbar_open_persisted() {
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.2h2020", true]],
+  });
+  let newtab = await BrowserTestUtils.openNewForegroundTab({
+    gBrowser,
+    opening: "about:newtab",
+    waitForLoad: false,
+  });
+  let example = await BrowserTestUtils.openNewForegroundTab({
+    gBrowser,
+    opening: "https://example.com",
+  });
+  let isToolbarPersistedOpen = () =>
+    Services.prefs.getCharPref("browser.toolbars.bookmarks.visibility") ==
+    "always";
+
+  ok(!isBookmarksToolbarVisible(), "Toolbar is hidden");
+  await BrowserTestUtils.switchTab(gBrowser, newtab);
+  await waitForBookmarksToolbarVisibility({ visible: true });
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+  await BrowserTestUtils.switchTab(gBrowser, example);
+  await waitForBookmarksToolbarVisibility({ visible: false });
+  ok(!isBookmarksToolbarVisible(), "Toolbar is hidden");
+  ok(!isToolbarPersistedOpen(), "Toolbar is not persisted open");
+
+  let contextMenu = document.querySelector("#toolbar-context-menu");
+  let popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+  let menuButton = document.getElementById("PanelUI-menu-button");
+  EventUtils.synthesizeMouseAtCenter(
+    menuButton,
+    { type: "contextmenu" },
+    window
+  );
+  await popupShown;
+  let bookmarksToolbarMenu = document.querySelector("#toggle_PersonalToolbar");
+  let subMenu = bookmarksToolbarMenu.querySelector("menupopup");
+  popupShown = BrowserTestUtils.waitForEvent(subMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(bookmarksToolbarMenu, {});
+  await popupShown;
+  let alwaysMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="always"]'
+  );
+  let neverMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="never"]'
+  );
+  let newTabMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="newtab"]'
+  );
+  is(alwaysMenuItem.getAttribute("checked"), "false", "Menuitem isn't checked");
+  is(neverMenuItem.getAttribute("checked"), "false", "Menuitem isn't checked");
+  is(newTabMenuItem.getAttribute("checked"), "true", "Menuitem is checked");
+
+  EventUtils.synthesizeMouseAtCenter(alwaysMenuItem, {});
+
+  await waitForBookmarksToolbarVisibility({ visible: true });
+  popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(
+    menuButton,
+    { type: "contextmenu" },
+    window
+  );
+  await popupShown;
+  bookmarksToolbarMenu = document.querySelector("#toggle_PersonalToolbar");
+  EventUtils.synthesizeMouseAtCenter(bookmarksToolbarMenu, {});
+  subMenu = bookmarksToolbarMenu.querySelector("menupopup");
+  popupShown = BrowserTestUtils.waitForEvent(subMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(bookmarksToolbarMenu, {});
+  await popupShown;
+  alwaysMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="always"]'
+  );
+  neverMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="never"]'
+  );
+  newTabMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="newtab"]'
+  );
+  is(alwaysMenuItem.getAttribute("checked"), "true", "Menuitem is checked");
+  is(neverMenuItem.getAttribute("checked"), "false", "Menuitem isn't checked");
+  is(newTabMenuItem.getAttribute("checked"), "false", "Menuitem isn't checked");
+  contextMenu.hidePopup();
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+  ok(isToolbarPersistedOpen(), "Toolbar is persisted open");
+  await BrowserTestUtils.switchTab(gBrowser, newtab);
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+  await BrowserTestUtils.switchTab(gBrowser, example);
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+
+  popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(
+    menuButton,
+    { type: "contextmenu" },
+    window
+  );
+  await popupShown;
+  bookmarksToolbarMenu = document.querySelector("#toggle_PersonalToolbar");
+  EventUtils.synthesizeMouseAtCenter(bookmarksToolbarMenu, {});
+  subMenu = bookmarksToolbarMenu.querySelector("menupopup");
+  popupShown = BrowserTestUtils.waitForEvent(subMenu, "popupshown");
+  EventUtils.synthesizeMouseAtCenter(bookmarksToolbarMenu, {});
+  await popupShown;
+  alwaysMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="always"]'
+  );
+  neverMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="never"]'
+  );
+  newTabMenuItem = document.querySelector(
+    'menuitem[data-visibility-enum="newtab"]'
+  );
+  is(alwaysMenuItem.getAttribute("checked"), "true", "Menuitem is checked");
+  is(neverMenuItem.getAttribute("checked"), "false", "Menuitem isn't checked");
+  is(newTabMenuItem.getAttribute("checked"), "false", "Menuitem isn't checked");
+  EventUtils.synthesizeMouseAtCenter(newTabMenuItem, {});
+  await waitForBookmarksToolbarVisibility({ visible: false });
+  ok(!isBookmarksToolbarVisible(), "Toolbar is hidden");
+  await BrowserTestUtils.switchTab(gBrowser, newtab);
+  await waitForBookmarksToolbarVisibility({ visible: true });
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+  await BrowserTestUtils.switchTab(gBrowser, example);
+  await waitForBookmarksToolbarVisibility({ visible: false });
+  ok(!isBookmarksToolbarVisible(), "Toolbar is hidden");
+
+  await BrowserTestUtils.removeTab(newtab);
+  await BrowserTestUtils.removeTab(example);
+});
+
+add_task(async function test_with_newtabpage_disabled() {
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.2h2020", true]],
+  });
+  let newtab = await BrowserTestUtils.openNewForegroundTab({
+    gBrowser,
+    opening: "about:newtab",
+    waitForLoad: false,
+  });
+  await waitForBookmarksToolbarVisibility({ visible: true });
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+
+  let blank = await BrowserTestUtils.openNewForegroundTab({
+    gBrowser,
+    opening: "about:blank",
+    waitForLoad: false,
+  });
+  await waitForBookmarksToolbarVisibility({ visible: false });
+  ok(!isBookmarksToolbarVisible(), "Toolbar is hidden");
+
+  let example = await BrowserTestUtils.openNewForegroundTab({
+    gBrowser,
+    opening: "https://example.com",
+  });
+  ok(!isBookmarksToolbarVisible(), "Toolbar is hidden");
+
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.newtabpage.enabled", false]],
+  });
+  await BrowserTestUtils.switchTab(gBrowser, blank);
+  await waitForBookmarksToolbarVisibility({ visible: true });
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+  await BrowserTestUtils.switchTab(gBrowser, example);
+  await waitForBookmarksToolbarVisibility({ visible: false });
+  ok(!isBookmarksToolbarVisible(), "Toolbar is hidden");
+  await BrowserTestUtils.switchTab(gBrowser, newtab);
+  await waitForBookmarksToolbarVisibility({ visible: true });
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+  await BrowserTestUtils.switchTab(gBrowser, blank);
+  ok(isBookmarksToolbarVisible(), "Toolbar is visible");
+
+  await BrowserTestUtils.removeTab(newtab);
+  await BrowserTestUtils.removeTab(blank);
+  await BrowserTestUtils.removeTab(example);
+});
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/about/browser_aboutNewTab_bookmarksToolbarPrefs.js
@@ -0,0 +1,100 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+requestLongerTimeout(3);
+
+add_task(async function test_with_different_pref_states() {
+  // [prefName, prefValue, toolbarVisibleExampleCom, toolbarVisibleNewTab]
+  let bookmarksFeatureStates = [
+    ["browser.toolbars.bookmarks.2h2020", true],
+    ["browser.toolbars.bookmarks.2h2020", false],
+  ];
+  let bookmarksToolbarVisibilityStates = [
+    ["browser.toolbars.bookmarks.visibility", "newtab"],
+    ["browser.toolbars.bookmarks.visibility", "always"],
+    ["browser.toolbars.bookmarks.visibility", "never"],
+  ];
+  let newTabEnabledStates = [
+    ["browser.newtabpage.enabled", true],
+    ["browser.newtabpage.enabled", false],
+  ];
+
+  for (let featureState of bookmarksFeatureStates) {
+    for (let visibilityState of bookmarksToolbarVisibilityStates) {
+      for (let newTabEnabledState of newTabEnabledStates) {
+        await SpecialPowers.pushPrefEnv({
+          set: [featureState, visibilityState, newTabEnabledState],
+        });
+
+        for (let privateWin of [true, false]) {
+          info(
+            `Testing with ${featureState}, ${visibilityState}, and ${newTabEnabledState} in a ${
+              privateWin ? "private" : "non-private"
+            } window`
+          );
+          let win = await BrowserTestUtils.openNewBrowserWindow({
+            private: privateWin,
+          });
+          is(
+            win.gBrowser.currentURI.spec,
+            privateWin ? "about:privatebrowsing" : "about:blank",
+            "Expecting about:privatebrowsing or about:blank as URI of new window"
+          );
+
+          if (!privateWin) {
+            await waitForBookmarksToolbarVisibility({
+              win,
+              visible:
+                visibilityState[1] == "always" ||
+                (!newTabEnabledState[1] &&
+                  visibilityState[1] == "newtab" &&
+                  featureState[1]),
+              message:
+                "Toolbar should be visible only if visibilityState is 'always'. State: " +
+                visibilityState[1],
+            });
+            await BrowserTestUtils.openNewForegroundTab({
+              gBrowser: win.gBrowser,
+              opening: "about:newtab",
+              waitForLoad: false,
+            });
+          }
+
+          if (featureState[1]) {
+            await waitForBookmarksToolbarVisibility({
+              win,
+              visible:
+                visibilityState[1] == "newtab" ||
+                visibilityState[1] == "always",
+              message:
+                "Toolbar should be visible as long as visibilityState isn't set to 'never'. State: " +
+                visibilityState[1],
+            });
+          } else {
+            await waitForBookmarksToolbarVisibility({
+              win,
+              visible: visibilityState[1] == "always",
+              message:
+                "Toolbar should be visible only if visibilityState is 'always'. State: " +
+                visibilityState[1],
+            });
+          }
+          await BrowserTestUtils.openNewForegroundTab({
+            gBrowser: win.gBrowser,
+            opening: "http://example.com",
+          });
+          await waitForBookmarksToolbarVisibility({
+            win,
+            visible: visibilityState[1] == "always",
+            message:
+              "Toolbar should be visible only if visibilityState is 'always'. State: " +
+              visibilityState[1],
+          });
+          await BrowserTestUtils.closeWindow(win);
+        }
+      }
+    }
+  }
+});
--- a/browser/base/content/test/about/head.js
+++ b/browser/base/content/test/about/head.js
@@ -230,8 +230,24 @@ async function promiseNewEngine(basename
       await Services.search.removeEngine(engine);
     } catch (ex) {
       /* Can't remove the engine more than once */
     }
   });
 
   return engine;
 }
+
+async function waitForBookmarksToolbarVisibility({
+  win = window,
+  visible,
+  message,
+}) {
+  return TestUtils.waitForCondition(() => {
+    let toolbar = win.gNavToolbox.querySelector("#PersonalToolbar");
+    return visible ? !toolbar.collapsed : toolbar.collapsed;
+  }, message || "waiting for toolbar to become " + (visible ? "visible" : "hidden"));
+}
+
+function isBookmarksToolbarVisible(win = window) {
+  let toolbar = win.gNavToolbox.querySelector("#PersonalToolbar");
+  return !toolbar.collapsed;
+}
--- a/browser/base/content/test/keyboard/browser_bookmarks_shortcut.js
+++ b/browser/base/content/test/keyboard/browser_bookmarks_shortcut.js
@@ -30,25 +30,25 @@ add_task(async function testEnabledBookm
     "Toolbar bar should already be collapsed"
   );
 
   EventUtils.synthesizeKey("b", { shiftKey: true, accelKey: true });
   toolbar = document.getElementById("PersonalToolbar");
   await BrowserTestUtils.waitForAttribute("collapsed", toolbar, "false");
   ok(true, "bookmarks toolbar is visible");
 
-  await testIsBookmarksMenuItemStateChecked("true");
+  await testIsBookmarksMenuItemStateChecked("always");
 
   info("Toggle toolbar visibility off");
   EventUtils.synthesizeKey("b", { shiftKey: true, accelKey: true });
   toolbar = document.getElementById("PersonalToolbar");
   await BrowserTestUtils.waitForAttribute("collapsed", toolbar, "true");
   ok(true, "bookmarks toolbar is not visible");
 
-  await testIsBookmarksMenuItemStateChecked("false");
+  await testIsBookmarksMenuItemStateChecked("never");
 
   await BrowserTestUtils.removeTab(blankTab);
 });
 
 // Test that the bookmarks toolbar remains collapsed when the
 // bookmarks-shortcut pref is disabled.
 add_task(async function testDisabledBookmarksShortcutPref() {
   await SpecialPowers.pushPrefEnv({
@@ -114,21 +114,26 @@ add_task(async function testNewBookmarks
  */
 async function testIsBookmarksMenuItemStateChecked(expected) {
   info("Test that the toolbar menuitem state is correct.");
   let contextMenu = document.getElementById("toolbar-context-menu");
   let target = document.getElementById("PanelUI-menu-button");
 
   await openContextMenu(contextMenu, target);
 
-  let menuitem = document.getElementById("toggle_PersonalToolbar");
+  let menuitems = ["always", "never", "newtab"].map(e =>
+    document.querySelector(`menuitem[data-visibility-enum="${e}"]`)
+  );
+
+  let checkedItem = menuitems.filter(m => m.getAttribute("checked") == "true");
+  is(checkedItem.length, 1, "should have only one menuitem checked");
   is(
-    menuitem.getAttribute("checked"),
+    checkedItem[0].dataset.visibilityEnum,
     expected,
-    `checked state for menuitem should be ${expected}.`
+    `checked menuitem should be ${expected}`
   );
 
   await closeContextMenu(contextMenu);
 }
 
 /**
  * Returns a promise for opening the bookmarks library.
  */
@@ -148,16 +153,20 @@ async function promiseOpenBookmarksLibra
  * Helper for opening the context menu.
  */
 async function openContextMenu(contextMenu, target) {
   info("Opening context menu.");
   EventUtils.synthesizeMouseAtCenter(target, {
     type: "contextmenu",
   });
   await BrowserTestUtils.waitForPopupEvent(contextMenu, "shown");
+  let bookmarksToolbarMenu = document.querySelector("#toggle_PersonalToolbar");
+  let subMenu = bookmarksToolbarMenu.querySelector("menupopup");
+  EventUtils.synthesizeMouseAtCenter(bookmarksToolbarMenu, {});
+  await BrowserTestUtils.waitForPopupEvent(subMenu, "shown");
 }
 
 /**
  * Helper for closing the context menu.
  */
 async function closeContextMenu(contextMenu) {
   info("Closing context menu.");
   contextMenu.hidePopup();
--- a/browser/base/content/test/keyboard/browser_toolbarKeyNav.js
+++ b/browser/base/content/test/keyboard/browser_toolbarKeyNav.js
@@ -298,20 +298,22 @@ add_task(async function testArrowsRtl() 
   await expectFocusAfterKey("ArrowLeft", "sidebar-button", false, win);
   await BrowserTestUtils.closeWindow(win);
   await SpecialPowers.popPrefEnv();
 });
 
 // Test that right arrow reaches the overflow menu button on the Bookmarks
 // toolbar when it is visible.
 add_task(async function testArrowsBookmarksOverflowButton() {
-  let toolbar = document.getElementById("PersonalToolbar");
-  let transitionEnded = BrowserTestUtils.waitForEvent(toolbar, "transitionend");
+  let toolbarOpened = TestUtils.waitForCondition(() => {
+    let toolbar = gNavToolbox.querySelector("#PersonalToolbar");
+    return !toolbar.collapsed;
+  }, "waiting for toolbar to become visible");
   CustomizableUI.setToolbarVisibility("PersonalToolbar", true);
-  await transitionEnded;
+  await toolbarOpened;
   let items = document.getElementById("PlacesToolbarItems").children;
   let lastVisible;
   for (let item of items) {
     if (item.style.visibility == "hidden") {
       break;
     }
     lastVisible = item;
   }
--- a/browser/base/content/test/performance/browser_tabclose.js
+++ b/browser/base/content/test/performance/browser_tabclose.js
@@ -20,16 +20,23 @@ const EXPECTED_REFLOWS = [
  */
 add_task(async function() {
   // Force-enable tab animations
   gReduceMotionOverride = false;
 
   await ensureNoPreloadedBrowser();
   await disableFxaBadge();
 
+  // The test starts on about:blank and opens an about:blank
+  // tab which triggers opening the toolbar since
+  // ensureNoPreloadedBrowser sets AboutNewTab.newTabURL to about:blank.
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.visibility", "never"]],
+  });
+
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
   await TestUtils.waitForCondition(() => tab._fullyOpen);
 
   let tabStripRect = gBrowser.tabContainer.arrowScrollbox.getBoundingClientRect();
   let newTabButtonRect = gBrowser.tabContainer.newTabButton.getBoundingClientRect();
   let inRange = (val, min, max) => min <= val && val <= max;
 
   // Add a reflow observer and open a new tab.
--- a/browser/base/content/test/performance/browser_tabclose_grow.js
+++ b/browser/base/content/test/performance/browser_tabclose_grow.js
@@ -21,16 +21,23 @@ const EXPECTED_REFLOWS = [
  */
 add_task(async function() {
   // Force-enable tab animations
   gReduceMotionOverride = false;
 
   await ensureNoPreloadedBrowser();
   await disableFxaBadge();
 
+  // The test starts on about:blank and opens an about:blank
+  // tab which triggers opening the toolbar since
+  // ensureNoPreloadedBrowser sets AboutNewTab.newTabURL to about:blank.
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.visibility", "never"]],
+  });
+
   // At the time of writing, there are no reflows on tab closing with
   // tab growth. Mochitest will fail if we have no assertions, so we
   // add one here to make sure nobody adds any new ones.
   Assert.equal(
     EXPECTED_REFLOWS.length,
     0,
     "We shouldn't have added any new expected reflows."
   );
--- a/browser/base/content/test/performance/browser_tabopen.js
+++ b/browser/base/content/test/performance/browser_tabopen.js
@@ -23,21 +23,29 @@ const EXPECTED_REFLOWS = [
  */
 add_task(async function() {
   // Force-enable tab animations
   gReduceMotionOverride = false;
 
   await ensureNoPreloadedBrowser();
   await disableFxaBadge();
 
+  // The test starts on about:blank and opens an about:blank
+  // tab which triggers opening the toolbar since
+  // ensureNoPreloadedBrowser sets AboutNewTab.newTabURL to about:blank.
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.visibility", "never"]],
+  });
+
   // Prepare the window to avoid flicker and reflow that's unrelated to our
   // tab opening operation.
   gURLBar.focus();
 
   let tabStripRect = gBrowser.tabContainer.arrowScrollbox.getBoundingClientRect();
+
   let firstTabRect = gBrowser.selectedTab.getBoundingClientRect();
   let firstTabLabelRect = gBrowser.selectedTab.textLabel.getBoundingClientRect();
   let textBoxRect = gURLBar
     .querySelector("moz-input-box")
     .getBoundingClientRect();
 
   let inRange = (val, min, max) => min <= val && val <= max;
 
--- a/browser/base/content/test/performance/browser_tabopen_squeeze.js
+++ b/browser/base/content/test/performance/browser_tabopen_squeeze.js
@@ -21,16 +21,23 @@ const EXPECTED_REFLOWS = [
  */
 add_task(async function() {
   // Force-enable tab animations
   gReduceMotionOverride = false;
 
   await ensureNoPreloadedBrowser();
   await disableFxaBadge();
 
+  // The test starts on about:blank and opens an about:blank
+  // tab which triggers opening the toolbar since
+  // ensureNoPreloadedBrowser sets AboutNewTab.newTabURL to about:blank.
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.visibility", "never"]],
+  });
+
   // Compute the number of tabs we can put into the strip without
   // overflowing, and remove one, so that we can create
   // TAB_COUNT_FOR_SQUEEE tabs, and then one more, which should
   // cause the tab to squeeze to a smaller size rather than overflow.
   const TAB_COUNT_FOR_SQUEEZE = computeMaxTabCount() - 1;
 
   await createTabs(TAB_COUNT_FOR_SQUEEZE);
 
--- a/browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js
+++ b/browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js
@@ -29,16 +29,23 @@ const EXPECTED_UNDERFLOW_REFLOWS = [
  * underflow.
  */
 add_task(async function() {
   // Force-enable tab animations
   gReduceMotionOverride = false;
 
   await ensureNoPreloadedBrowser();
 
+  // The test starts on about:blank and opens an about:blank
+  // tab which triggers opening the toolbar since
+  // ensureNoPreloadedBrowser sets AboutNewTab.newTabURL to about:blank.
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.visibility", "never"]],
+  });
+
   const TAB_COUNT_FOR_OVERFLOW = computeMaxTabCount();
 
   await createTabs(TAB_COUNT_FOR_OVERFLOW);
 
   gURLBar.focus();
   await disableFxaBadge();
 
   let tabStripRect = gBrowser.tabContainer.arrowScrollbox.getBoundingClientRect();
--- a/browser/base/content/test/performance/browser_tabswitch.js
+++ b/browser/base/content/test/performance/browser_tabswitch.js
@@ -21,16 +21,23 @@ const EXPECTED_REFLOWS = [
  * This test ensures that there are no unexpected
  * uninterruptible reflows when switching between two
  * tabs that are both fully visible.
  */
 add_task(async function() {
   await ensureNoPreloadedBrowser();
   await disableFxaBadge();
 
+  // The test starts on about:blank and opens an about:blank
+  // tab which triggers opening the toolbar since
+  // ensureNoPreloadedBrowser sets AboutNewTab.newTabURL to about:blank.
+  await SpecialPowers.pushPrefEnv({
+    set: [["browser.toolbars.bookmarks.visibility", "never"]],
+  });
+
   // At the time of writing, there are no reflows on simple tab switching.
   // Mochitest will fail if we have no assertions, so we add one here
   // to make sure nobody adds any new ones.
   Assert.equal(
     EXPECTED_REFLOWS.length,
     0,
     "We shouldn't have added any new expected reflows."
   );
--- a/browser/base/content/test/performance/browser_windowopen.js
+++ b/browser/base/content/test/performance/browser_windowopen.js
@@ -49,16 +49,18 @@ add_task(async function() {
     AppConstants.BROWSER_CHROME_URL,
     "_blank",
     "chrome,all,dialog=no,remote,suppressanimation",
     "about:home"
   );
 
   await disableFxaBadge();
 
+  let bookmarksToolbarRect = await getBookmarksToolbarRect();
+
   let alreadyFocused = false;
   let inRange = (val, min, max) => min <= val && val <= max;
   let expectations = {
     expectedReflows: EXPECTED_REFLOWS,
     frames: {
       filter(rects, frame, previousFrame) {
         // The first screenshot we get in OSX / Windows shows an unfocused browser
         // window for some reason. See bug 1445161.
@@ -93,16 +95,24 @@ add_task(async function() {
                 (AppConstants.platform == "linux" && AppConstants.ASAN)) &&
               r.x1 >= inputFieldRect.left &&
               r.x2 <= inputFieldRect.right &&
               r.y1 >= inputFieldRect.top &&
               r.y2 <= inputFieldRect.bottom
             );
           },
         },
+        {
+          name: "bug 1667237 - the bookmarks toolbar shouldn't flicker",
+          condition: r =>
+            r.y1 >= bookmarksToolbarRect.top &&
+            r.y2 <= bookmarksToolbarRect.bottom &&
+            r.x1 >= bookmarksToolbarRect.left &&
+            r.x2 <= bookmarksToolbarRect.right,
+        },
       ],
     },
   };
 
   await withPerfObserver(
     async function() {
       // Avoid showing the remotecontrol UI.
       await new Promise(resolve => {
--- a/browser/base/content/test/performance/head.js
+++ b/browser/base/content/test/performance/head.js
@@ -264,16 +264,38 @@ function disableFxaBadge() {
   ToolbarBadgeHub.removeAllNotifications();
 
   // Also prevent a new timer from being set
   return SpecialPowers.pushPrefEnv({
     set: [["identity.fxaccounts.toolbar.accessed", true]],
   });
 }
 
+async function getBookmarksToolbarRect() {
+  // Temporarily open the bookmarks toolbar to measure its rect
+  let bookmarksToolbar = gNavToolbox.querySelector("#PersonalToolbar");
+  let wasVisible = !bookmarksToolbar.collapsed;
+  if (!wasVisible) {
+    setToolbarVisibility(bookmarksToolbar, true, false, false);
+    await TestUtils.waitForCondition(
+      () => bookmarksToolbar.getBoundingClientRect().height > 0,
+      "wait for non-zero bookmarks toolbar height"
+    );
+  }
+  let bookmarksToolbarRect = bookmarksToolbar.getBoundingClientRect();
+  if (!wasVisible) {
+    setToolbarVisibility(bookmarksToolbar, false, false, false);
+    await TestUtils.waitForCondition(
+      () => bookmarksToolbar.getBoundingClientRect().height == 0,
+      "wait for zero bookmarks toolbar height"
+    );
+  }
+  return bookmarksToolbarRect;
+}
+
 async function prepareSettledWindow() {
   let win = await BrowserTestUtils.openNewBrowserWindow();
   await ensureNoPreloadedBrowser(win);
   return win;
 }
 
 /**
  * Calculate and return how many additional tabs can be fit into the
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -3321,17 +3321,17 @@ BrowserGlue.prototype = {
       );
     });
   },
 
   // eslint-disable-next-line complexity
   _migrateUI: function BG__migrateUI() {
     // Use an increasing number to keep track of the current migration state.
     // Completely unrelated to the current Firefox release number.
-    const UI_VERSION = 99;
+    const UI_VERSION = 100;
     const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
 
     if (!Services.prefs.prefHasUserValue("browser.migration.version")) {
       // This is a new profile, nothing to migrate.
       Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
       this._isNewProfile = true;
       return;
     }
@@ -3957,16 +3957,40 @@ BrowserGlue.prototype = {
     if (currentUIVersion < 98) {
       Services.prefs.clearUserPref("browser.search.cohort");
     }
 
     if (currentUIVersion < 99) {
       Services.prefs.clearUserPref("security.tls.version.enable-deprecated");
     }
 
+    // Set a pref if the bookmarks toolbar was already visible,
+    // so we can keep it visible when navigating away from newtab
+    if (currentUIVersion < 100) {
+      let bookmarksToolbarWasVisible =
+        Services.xulStore.getValue(
+          BROWSER_DOCURL,
+          "PersonalToolbar",
+          "collapsed"
+        ) == "false";
+      if (bookmarksToolbarWasVisible) {
+        // Migrate the user to the "always visible" value. See firefox.js for
+        // the other possible states.
+        Services.prefs.setCharPref(
+          "browser.toolbars.bookmarks.visibility",
+          "always"
+        );
+      }
+      Services.xulStore.removeValue(
+        BROWSER_DOCURL,
+        "PersonalToolbar",
+        "collapsed"
+      );
+    }
+
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _maybeShowDefaultBrowserPrompt() {
     DefaultBrowserCheck.willCheckDefaultBrowser(/* isStartupCheck */ true).then(
       async willPrompt => {
         let { DefaultBrowserNotification } = ChromeUtils.import(
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -32,16 +32,23 @@ XPCOMUtils.defineLazyGetter(this, "gWidg
 
 XPCOMUtils.defineLazyServiceGetter(
   this,
   "gELS",
   "@mozilla.org/eventlistenerservice;1",
   "nsIEventListenerService"
 );
 
+XPCOMUtils.defineLazyPreferenceGetter(
+  this,
+  "gBookmarksToolbar2h2020",
+  "browser.toolbars.bookmarks.2h2020",
+  false
+);
+
 const kDefaultThemeID = "default-theme@mozilla.org";
 
 const kSpecialWidgetPfx = "customizableui-special-";
 
 const kPrefCustomizationState = "browser.uiCustomization.state";
 const kPrefCustomizationAutoAdd = "browser.uiCustomization.autoAdd";
 const kPrefCustomizationDebug = "browser.uiCustomization.debug";
 const kPrefDrawInTitlebar = "browser.tabs.drawInTitlebar";
@@ -272,17 +279,17 @@ var CustomizableUIInternal = {
       },
       true
     );
     this.registerArea(
       CustomizableUI.AREA_BOOKMARKS,
       {
         type: CustomizableUI.TYPE_TOOLBAR,
         defaultPlacements: ["personal-bookmarks"],
-        defaultCollapsed: true,
+        defaultCollapsed: gBookmarksToolbar2h2020 ? "newtab" : true,
       },
       true
     );
 
     SearchWidgetTracker.init();
 
     Services.obs.addObserver(this, "browser-set-toolbar-visibility");
   },
@@ -3035,17 +3042,19 @@ var CustomizableUIInternal = {
 
         let area = gAreas.get(areaId);
         if (area.get("type") == CustomizableUI.TYPE_TOOLBAR) {
           let defaultCollapsed = area.get("defaultCollapsed");
           let win = areaNode.ownerGlobal;
           if (defaultCollapsed !== null) {
             win.setToolbarVisibility(
               areaNode,
-              !defaultCollapsed,
+              typeof defaultCollapsed == "string"
+                ? defaultCollapsed
+                : !defaultCollapsed,
               isFirstChangedToolbar
             );
           }
         }
         isFirstChangedToolbar = false;
       }
     }
   },
@@ -3267,23 +3276,38 @@ var CustomizableUIInternal = {
         } else {
           currentPlacements = currentPlacements.filter(item => {
             let itemNode = container.getElementsByAttribute("id", item)[0];
             return itemNode && removableOrDefault(itemNode || item);
           });
         }
 
         if (props.get("type") == CustomizableUI.TYPE_TOOLBAR) {
-          let attribute =
-            container.getAttribute("type") == "menubar"
-              ? "autohide"
-              : "collapsed";
-          let collapsed = container.getAttribute(attribute) == "true";
+          let collapsed = null;
           let defaultCollapsed = props.get("defaultCollapsed");
-          if (defaultCollapsed !== null && collapsed != defaultCollapsed) {
+          let nondefaultState = false;
+          if (
+            areaId == CustomizableUI.AREA_BOOKMARKS &&
+            gBookmarksToolbar2h2020
+          ) {
+            collapsed = Services.prefs.getCharPref(
+              "browser.toolbars.bookmarks.visibility"
+            );
+            nondefaultState = Services.prefs.prefHasUserValue(
+              "browser.toolbars.bookmarks.visibility"
+            );
+          } else {
+            let attribute =
+              container.getAttribute("type") == "menubar"
+                ? "autohide"
+                : "collapsed";
+            collapsed = container.getAttribute(attribute) == "true";
+            nondefaultState = collapsed != defaultCollapsed;
+          }
+          if (defaultCollapsed !== null && nondefaultState) {
             log.debug(
               "Found " +
                 areaId +
                 " had non-default toolbar visibility" +
                 "(expected " +
                 defaultCollapsed +
                 ", was " +
                 collapsed +
--- a/browser/components/customizableui/test/browser.ini
+++ b/browser/components/customizableui/test/browser.ini
@@ -130,16 +130,17 @@ tags = fullscreen
 skip-if = os == "mac"
 [browser_1087303_button_preferences.js]
 [browser_1089591_still_customizable_after_reset.js]
 [browser_1096763_seen_widgets_post_reset.js]
 [browser_1161838_inserted_new_default_buttons.js]
 skip-if = verify
 [browser_1484275_PanelMultiView_toggle_with_other_popup.js]
 [browser_allow_dragging_removable_false.js]
+[browser_bookmarks_toolbar_collapsed_restore_default.js]
 [browser_bootstrapped_custom_toolbar.js]
 [browser_character_encoding_ctrl_click.js]
 [browser_ctrl_click_panel_opening.js]
 [browser_currentset_post_reset.js]
 [browser_customizemode_contextmenu_menubuttonstate.js]
 skip-if = os == "win" && bits == 64 # 1526429
 [browser_customizemode_dragspace.js]
 skip-if = os == "linux" # linux doesn't get drag space (no tabsintitlebar)
new file mode 100644
--- /dev/null
+++ b/browser/components/customizableui/test/browser_bookmarks_toolbar_collapsed_restore_default.js
@@ -0,0 +1,40 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+"use strict";
+
+// Restoring default should set Bookmarks Toolbar back to "newtab"
+add_task(async function() {
+  if (!Services.prefs.getBoolPref("browser.toolbars.bookmarks.2h2020", false)) {
+    ok(true, "Skip as behavior only changes when the feature is enabled");
+    return;
+  }
+
+  let prefName = "browser.toolbars.bookmarks.visibility";
+  let toolbar = document.querySelector("#PersonalToolbar");
+  for (let state of ["always", "never"]) {
+    info(`Testing setting toolbar state to '${state}'`);
+
+    await resetCustomization();
+    ok(CustomizableUI.inDefaultState, "Default state to begin");
+
+    setToolbarVisibility(toolbar, state, true, false);
+
+    is(
+      Services.prefs.getCharPref(prefName),
+      state,
+      "Pref updated to: " + state
+    );
+    ok(!CustomizableUI.inDefaultState, "Not in default state");
+
+    await resetCustomization();
+
+    ok(CustomizableUI.inDefaultState, "Back in default state after reset");
+    is(
+      Services.prefs.getCharPref(prefName),
+      "newtab",
+      "Pref should get reset to 'newtab'"
+    );
+  }
+});
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -724,16 +724,26 @@ var Policies = {
 
   DisplayBookmarksToolbar: {
     onBeforeUIStartup(manager, param) {
       let value = (!param).toString();
       // This policy is meant to change the default behavior, not to force it.
       // If this policy was alreay applied and the user chose to re-hide the
       // bookmarks toolbar, do not show it again.
       runOncePerModification("displayBookmarksToolbar", value, () => {
+        // Set the preference to keep the bookmarks bar open and also
+        // declaratively open the bookmarks toolbar. Otherwise, default
+        // to showing it on the New Tab Page.
+        let visibilityPref = "browser.toolbars.bookmarks.visibility";
+        let bookmarksFeaturePref = "browser.toolbars.bookmarks.2h2020";
+        let visibility = param ? "always" : "never";
+        if (Services.prefs.getBoolPref(bookmarksFeaturePref, false)) {
+          visibility = param ? "always" : "newtab";
+        }
+        Services.prefs.setCharPref(visibilityPref, visibility);
         gXulStore.setValue(
           BROWSER_DOCUMENT_URL,
           "PersonalToolbar",
           "collapsed",
           value
         );
       });
     },
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -431,24 +431,22 @@ function closeBrowserAction(extension, w
 function openBrowserActionPanel(extension, win = window, awaitLoad = false) {
   clickBrowserAction(extension, win);
 
   return awaitExtensionPanel(extension, win, awaitLoad);
 }
 
 async function toggleBookmarksToolbar(visible = true) {
   let bookmarksToolbar = document.getElementById("PersonalToolbar");
-  let transitionPromise = BrowserTestUtils.waitForEvent(
-    bookmarksToolbar,
-    "transitionend",
-    e => e.propertyName == "max-height"
-  );
+  let visibilityToggledPromise = TestUtils.waitForCondition(() => {
+    return visible ? !bookmarksToolbar.collapsed : bookmarksToolbar.collapsed;
+  }, "waiting for toolbar to become " + (visible ? "visible" : "hidden"));
 
   setToolbarVisibility(bookmarksToolbar, visible);
-  await transitionPromise;
+  await visibilityToggledPromise;
 }
 
 async function openContextMenuInPopup(extension, selector = "body") {
   let contentAreaContextMenu = document.getElementById(
     "contentAreaContextMenu"
   );
   let browser = await awaitExtensionPanel(extension);
 
--- a/browser/components/places/content/editBookmark.js
+++ b/browser/components/places/content/editBookmark.js
@@ -1,16 +1,20 @@
 /* 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/. */
 
 var { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 
+XPCOMUtils.defineLazyModuleGetters(this, {
+  CustomizableUI: "resource:///modules/CustomizableUI.jsm",
+});
+
 var gEditItemOverlay = {
   // Array of PlacesTransactions accumulated by internal changes. It can be used
   // to wait for completion.
   transactionPromises: null,
   _observersAdded: false,
   _staticFoldersListBuilt: false,
 
   _paneInfo: null,
@@ -872,33 +876,49 @@ var gEditItemOverlay = {
         guid: this._paneInfo.itemGuid,
         newParentGuid: containerGuid,
       }).transact();
       this.transactionPromises.push(promise.catch(Cu.reportError));
       await promise;
 
       // Auto-show the bookmarks toolbar when adding / moving an item there.
       if (containerGuid == PlacesUtils.bookmarks.toolbarGuid) {
-        Services.obs.notifyObservers(null, "autoshow-bookmarks-toolbar");
+        this._autoshowBookmarksToolbar();
       }
     }
 
     // Update folder-tree selection
     var folderTreeRow = this._element("folderTreeRow");
     if (!folderTreeRow.collapsed) {
       var selectedNode = this._folderTree.selectedNode;
       if (
         !selectedNode ||
         PlacesUtils.getConcreteItemGuid(selectedNode) != containerGuid
       ) {
         this._folderTree.selectItems([containerGuid]);
       }
     }
   },
 
+  _autoshowBookmarksToolbar() {
+    let toolbar = document.getElementById("PersonalToolbar");
+    if (!toolbar.collapsed) {
+      return;
+    }
+
+    let placement = CustomizableUI.getPlacementOfWidget("personal-bookmarks");
+    let area = placement && placement.area;
+    if (area != CustomizableUI.AREA_BOOKMARKS) {
+      return;
+    }
+
+    // Show the toolbar but don't persist it permanently open
+    setToolbarVisibility(toolbar, true, false);
+  },
+
   onFolderTreeSelect() {
     // Ignore this event when the folder tree is hidden, even if the tree is
     // alive, it's clearly not a user activated action.
     if (this._element("folderTreeRow").collapsed) {
       return;
     }
 
     var selectedNode = this._folderTree.selectedNode;
--- a/browser/components/places/tests/browser/browser_enable_toolbar_sidebar.js
+++ b/browser/components/places/tests/browser/browser_enable_toolbar_sidebar.js
@@ -34,30 +34,31 @@ async function openBookmarkingToolsPanel
   await selectAppMenuView(
     "panelMenu_bookmarkingTools",
     "PanelUI-bookmarkingTools"
   );
 }
 
 add_task(async function test_enable_toolbar() {
   await openBookmarkingToolsPanelInLibraryToolbarButton();
+  let toolbar = document.getElementById("PersonalToolbar");
+  Assert.ok(toolbar.collapsed, "Bookmarks Toolbar is hidden");
 
   let viewBookmarksToolbarBtn;
   await BrowserTestUtils.waitForCondition(() => {
     viewBookmarksToolbarBtn = document.getElementById(
       "panelMenu_viewBookmarksToolbar"
     );
     return viewBookmarksToolbarBtn;
   }, "Should have the library 'View Bookmarks Toolbar' button.");
   viewBookmarksToolbarBtn.click();
-  let toolbar;
-  await BrowserTestUtils.waitForCondition(() => {
-    toolbar = document.getElementById("PersonalToolbar");
-    return !toolbar.collapsed;
-  }, "Should have the Bookmarks Toolbar enabled.");
+  await BrowserTestUtils.waitForCondition(
+    () => !toolbar.collapsed,
+    "Should have the Bookmarks Toolbar enabled."
+  );
   Assert.ok(!toolbar.collapsed, "Bookmarks Toolbar is enabled");
 });
 
 add_task(async function test_enable_sidebar() {
   await openBookmarkingToolsPanelInLibraryToolbarButton();
 
   let viewBookmarksSidebarBtn;
   await BrowserTestUtils.waitForCondition(() => {
--- a/browser/components/places/tests/browser/browser_toolbar_overflow.js
+++ b/browser/components/places/tests/browser/browser_toolbar_overflow.js
@@ -142,16 +142,17 @@ add_task(async function test_separator_f
 
   await PlacesUtils.bookmarks.remove(bm);
 });
 
 add_task(async function test_newWindow_noOverflow() {
   info(
     "Check toolbar in a new widow when it was already visible and not overflowed"
   );
+  ok(!gToolbar.collapsed, "Toolbar is not collapsed in original window");
   await PlacesUtils.bookmarks.eraseEverything();
   // Add a single bookmark.
   await PlacesUtils.bookmarks.insert({
     parentGuid: PlacesUtils.bookmarks.toolbarGuid,
     url: "http://toolbar.overflow/",
     title: "Example",
   });
   // Add a favicon for the bookmark.
--- a/browser/components/places/tests/browser/head.js
+++ b/browser/components/places/tests/browser/head.js
@@ -124,42 +124,24 @@ function synthesizeClickOnSelectedTreeCe
  *        True to make the toolbar visible, false to make it hidden.
  *
  * @return {Promise}
  * @resolves Any animation associated with updating the toolbar's visibility has
  *           finished.
  * @rejects Never.
  */
 function promiseSetToolbarVisibility(aToolbar, aVisible, aCallback) {
-  return new Promise((resolve, reject) => {
-    function listener(event) {
-      if (event.propertyName == "max-height") {
-        aToolbar.removeEventListener("transitionend", listener);
-        resolve();
-      }
-    }
-
-    let transitionProperties = window
-      .getComputedStyle(aToolbar)
-      .transitionProperty.split(", ");
-    if (
-      isToolbarVisible(aToolbar) != aVisible &&
-      transitionProperties.some(prop => prop == "max-height" || prop == "all")
-    ) {
-      // Just because max-height is a transitionable property doesn't mean
-      // a transition will be triggered, but it's more likely.
-      aToolbar.addEventListener("transitionend", listener);
-      setToolbarVisibility(aToolbar, aVisible);
-      return;
-    }
-
-    // No animation to wait for
-    setToolbarVisibility(aToolbar, aVisible);
-    resolve();
-  });
+  if (isToolbarVisible(aToolbar) != aVisible) {
+    let visibilityChanged = TestUtils.waitForCondition(
+      () => aToolbar.collapsed != aVisible
+    );
+    setToolbarVisibility(aToolbar, aVisible, undefined, false);
+    return visibilityChanged;
+  }
+  return Promise.resolve();
 }
 
 /**
  * Helper function to determine if the given toolbar is in the visible
  * state according to its autohide/collapsed attribute.
  *
  * @aToolbar The toolbar to query.
  *
--- a/browser/locales/en-US/browser/toolbarContextMenu.ftl
+++ b/browser/locales/en-US/browser/toolbarContextMenu.ftl
@@ -49,8 +49,18 @@ toolbar-context-menu-auto-hide-downloads
     .label = Auto-Hide in Toolbar
     .accesskey = A
 toolbar-context-menu-remove-from-toolbar =
     .label = Remove from Toolbar
     .accesskey = R
 toolbar-context-menu-view-customize-toolbar =
     .label = Customize…
     .accesskey = C
+
+toolbar-context-menu-bookmarks-toolbar-always-show =
+    .label = Always
+    .accesskey = A
+toolbar-context-menu-bookmarks-toolbar-never-show =
+    .label = Never
+    .accesskey = N
+toolbar-context-menu-bookmarks-toolbar-on-new-tab =
+    .label = Only on New Tab
+    .accesskey = O
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -860,21 +860,31 @@ let BrowserUsageTelemetry = {
       counts.winCount
     );
   },
 
   _buildWidgetPositions() {
     let widgetMap = new Map();
 
     const toolbarState = nodeId => {
-      let value = Services.xulStore.getValue(
-        AppConstants.BROWSER_CHROME_URL,
-        nodeId,
-        "collapsed"
-      );
+      let value;
+      if (nodeId == "PersonalToolbar") {
+        value = Services.prefs.getCharPref(
+          "browser.toolbars.bookmarks.visibility",
+          "newtab"
+        );
+        value = (value == "never").toString();
+      } else {
+        value = Services.xulStore.getValue(
+          AppConstants.BROWSER_CHROME_URL,
+          nodeId,
+          "collapsed"
+        );
+      }
+
       if (value) {
         return value == "true" ? "off" : "on";
       }
       return "off";
     };
 
     widgetMap.set(
       BROWSER_UI_CONTAINER_IDS.PersonalToolbar,
@@ -1146,19 +1156,22 @@ let BrowserUsageTelemetry = {
 
       this._recordWidgetChange(widgetId, newPos, reason);
     } catch (e) {
       console.error(e);
     }
   },
 
   recordToolbarVisibility(toolbarId, newState, reason) {
+    if (typeof newState != "string") {
+      newState = newState ? "on" : "off";
+    }
     this._recordWidgetChange(
       BROWSER_UI_CONTAINER_IDS[toolbarId],
-      newState ? "on" : "off",
+      newState,
       reason
     );
   },
 
   _recordWidgetChange(widgetId, newPos, reason) {
     // In some cases (like when add-ons are detected during startup) this gets
     // called before we've reported the initial positions. Ignore such cases.
     if (!this.widgetMap) {
--- a/browser/modules/test/browser/browser_UsageTelemetry_interaction.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_interaction.js
@@ -73,24 +73,25 @@ add_task(async function toolbarButtons()
       });
     });
 
     Services.telemetry.getSnapshotForKeyedScalars("main", true);
 
     let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
     let tabClose = BrowserTestUtils.waitForTabClosing(newTab);
 
-    let transition = BrowserTestUtils.waitForTransition(
-      elem("PersonalToolbar")
-    );
+    let bookmarksToolbarVisible = TestUtils.waitForCondition(() => {
+      let toolbar = gNavToolbox.querySelector("#PersonalToolbar");
+      return toolbar.getAttribute("collapsed") != "true";
+    }, "waiting for toolbar to become visible");
     CustomizableUI.setToolbarVisibility("PersonalToolbar", true);
     registerCleanupFunction(() => {
       CustomizableUI.setToolbarVisibility("PersonalToolbar", false);
     });
-    await transition;
+    await bookmarksToolbarVisible;
 
     let tabs = elem("tabbrowser-tabs");
     if (!tabs.hasAttribute("overflow")) {
       tabs.setAttribute("overflow", "true");
       registerCleanupFunction(() => {
         tabs.removeAttribute("overflow");
       });
     }
--- a/browser/modules/test/browser/browser_UsageTelemetry_toolbars.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_toolbars.js
@@ -229,179 +229,231 @@ add_task(async function widgetPositions(
     "new-tab-button_pinned_bookmarks-bar",
     "developer-button_pinned_bookmarks-bar",
   ]);
 
   CustomizableUI.reset();
 });
 
 add_task(async function customizeMode() {
-  // Create a default state.
-  organizeToolbars({
-    PersonalToolbar: ["personal-bookmarks"],
+  for (let bookmarksFeatureEnabled of [true, false]) {
+    await SpecialPowers.pushPrefEnv({
+      set: [["browser.toolbars.bookmarks.2h2020", bookmarksFeatureEnabled]],
+    });
 
-    TabsToolbar: ["tabbrowser-tabs", "new-tab-button"],
+    // Create a default state.
+    organizeToolbars({
+      PersonalToolbar: ["personal-bookmarks"],
+
+      TabsToolbar: ["tabbrowser-tabs", "new-tab-button"],
 
-    "nav-bar": [
-      "back-button",
-      "forward-button",
-      "stop-reload-button",
-      "urlbar-container",
-      "home-button",
-      "library-button",
-    ],
-  });
+      "nav-bar": [
+        "back-button",
+        "forward-button",
+        "stop-reload-button",
+        "urlbar-container",
+        "home-button",
+        "library-button",
+      ],
+    });
 
-  BrowserUsageTelemetry._recordUITelemetry();
+    BrowserUsageTelemetry._recordUITelemetry();
 
-  assertVisibilityScalars([
-    "drag-space_pinned_off",
-    "menu-toolbar_pinned_off",
-    "titlebar_pinned_off",
-    "bookmarks-bar_pinned_off",
+    assertVisibilityScalars([
+      "drag-space_pinned_off",
+      "menu-toolbar_pinned_off",
+      "titlebar_pinned_off",
+      "bookmarks-bar_pinned_off",
 
-    "tabbrowser-tabs_pinned_tabs-bar",
-    "new-tab-button_pinned_tabs-bar",
-    "alltabs-button_pinned_tabs-bar",
+      "tabbrowser-tabs_pinned_tabs-bar",
+      "new-tab-button_pinned_tabs-bar",
+      "alltabs-button_pinned_tabs-bar",
+
+      "back-button_pinned_nav-bar-start",
+      "forward-button_pinned_nav-bar-start",
+      "stop-reload-button_pinned_nav-bar-start",
+      "home-button_pinned_nav-bar-end",
+      "library-button_pinned_nav-bar-end",
 
-    "back-button_pinned_nav-bar-start",
-    "forward-button_pinned_nav-bar-start",
-    "stop-reload-button_pinned_nav-bar-start",
-    "home-button_pinned_nav-bar-end",
-    "library-button_pinned_nav-bar-end",
+      "personal-bookmarks_pinned_bookmarks-bar",
+    ]);
+
+    let win = await BrowserTestUtils.openNewBrowserWindow();
+
+    await enterCustomizationMode(win);
 
-    "personal-bookmarks_pinned_bookmarks-bar",
-  ]);
-
-  let win = await BrowserTestUtils.openNewBrowserWindow();
-
-  await enterCustomizationMode(win);
+    let toolbarButton = win.document.getElementById(
+      "customization-toolbar-visibility-button"
+    );
+    let toolbarPopup = win.document.getElementById(
+      "customization-toolbar-menu"
+    );
+    let popupShown = BrowserTestUtils.waitForEvent(toolbarPopup, "popupshown");
+    EventUtils.synthesizeMouseAtCenter(toolbarButton, {}, win);
+    await popupShown;
 
-  let toolbarButton = win.document.getElementById(
-    "customization-toolbar-visibility-button"
-  );
-  let toolbarPopup = win.document.getElementById("customization-toolbar-menu");
-  let popupShown = BrowserTestUtils.waitForEvent(toolbarPopup, "popupshown");
-  EventUtils.synthesizeMouseAtCenter(toolbarButton, {}, win);
-  await popupShown;
+    let barMenu = win.document.getElementById("toggle_PersonalToolbar");
+    let popupHidden = BrowserTestUtils.waitForEvent(
+      toolbarPopup,
+      "popuphidden"
+    );
+    if (bookmarksFeatureEnabled) {
+      let subMenu = barMenu.querySelector("menupopup");
+      popupShown = BrowserTestUtils.waitForEvent(subMenu, "popupshown");
+      EventUtils.synthesizeMouseAtCenter(barMenu, {}, win);
+      await popupShown;
+      let alwaysButton = barMenu.querySelector(
+        '*[data-visibility-enum="always"]'
+      );
+      EventUtils.synthesizeMouseAtCenter(alwaysButton, {}, win);
+    } else {
+      EventUtils.synthesizeMouseAtCenter(barMenu, {}, win);
+    }
+    await popupHidden;
 
-  let popupHidden = BrowserTestUtils.waitForEvent(toolbarPopup, "popuphidden");
-  let barButton = win.document.getElementById("toggle_PersonalToolbar");
-  EventUtils.synthesizeMouseAtCenter(barButton, {}, win);
-  await popupHidden;
-
-  let navbar = CustomizableUI.getCustomizationTarget(
-    win.document.getElementById("nav-bar")
-  );
-  let bookmarksBar = CustomizableUI.getCustomizationTarget(
-    win.document.getElementById("PersonalToolbar")
-  );
-  let tabBar = CustomizableUI.getCustomizationTarget(
-    win.document.getElementById("TabsToolbar")
-  );
+    let navbar = CustomizableUI.getCustomizationTarget(
+      win.document.getElementById("nav-bar")
+    );
+    let bookmarksBar = CustomizableUI.getCustomizationTarget(
+      win.document.getElementById("PersonalToolbar")
+    );
+    let tabBar = CustomizableUI.getCustomizationTarget(
+      win.document.getElementById("TabsToolbar")
+    );
 
-  simulateItemDrag(win.document.getElementById("home-button"), navbar, "start");
-  simulateItemDrag(win.document.getElementById("library-button"), bookmarksBar);
-  simulateItemDrag(win.document.getElementById("stop-reload-button"), tabBar);
-  simulateItemDrag(
-    win.document.getElementById("stop-reload-button"),
-    navbar,
-    "start"
-  );
-  simulateItemDrag(win.document.getElementById("stop-reload-button"), tabBar);
-
-  await leaveCustomizationMode(win);
+    simulateItemDrag(
+      win.document.getElementById("home-button"),
+      navbar,
+      "start"
+    );
+    simulateItemDrag(
+      win.document.getElementById("library-button"),
+      bookmarksBar
+    );
+    simulateItemDrag(win.document.getElementById("stop-reload-button"), tabBar);
+    simulateItemDrag(
+      win.document.getElementById("stop-reload-button"),
+      navbar,
+      "start"
+    );
+    simulateItemDrag(win.document.getElementById("stop-reload-button"), tabBar);
 
-  await BrowserTestUtils.closeWindow(win);
+    await leaveCustomizationMode(win);
+
+    await BrowserTestUtils.closeWindow(win);
 
-  assertCustomizeScalars({
-    "home-button_move_nav-bar-end_nav-bar-start_drag": 1,
-    "library-button_move_nav-bar-end_bookmarks-bar_drag": 1,
-    "stop-reload-button_move_nav-bar-start_tabs-bar_drag": 2,
-    "stop-reload-button_move_tabs-bar_nav-bar-start_drag": 1,
-    "bookmarks-bar_move_off_on_customization-toolbar-menu": 1,
-  });
+    let bookmarksBarTelemetryScalar = bookmarksFeatureEnabled
+      ? "bookmarks-bar_move_off_always_customization-toolbar-menu"
+      : "bookmarks-bar_move_off_on_customization-toolbar-menu";
+    assertCustomizeScalars({
+      "home-button_move_nav-bar-end_nav-bar-start_drag": 1,
+      "library-button_move_nav-bar-end_bookmarks-bar_drag": 1,
+      "stop-reload-button_move_nav-bar-start_tabs-bar_drag": 2,
+      "stop-reload-button_move_tabs-bar_nav-bar-start_drag": 1,
+      [bookmarksBarTelemetryScalar]: 1,
+    });
 
-  CustomizableUI.reset();
+    CustomizableUI.reset();
+  }
 });
 
 add_task(async function contextMenus() {
-  // Create a default state.
-  organizeToolbars({
-    PersonalToolbar: ["personal-bookmarks"],
+  for (let bookmarksFeatureEnabled of [true, false]) {
+    await SpecialPowers.pushPrefEnv({
+      set: [["browser.toolbars.bookmarks.2h2020", bookmarksFeatureEnabled]],
+    });
 
-    TabsToolbar: ["tabbrowser-tabs", "new-tab-button"],
+    // Create a default state.
+    organizeToolbars({
+      PersonalToolbar: ["personal-bookmarks"],
 
-    "nav-bar": [
-      "back-button",
-      "forward-button",
-      "stop-reload-button",
-      "urlbar-container",
-      "home-button",
-      "library-button",
-    ],
-  });
+      TabsToolbar: ["tabbrowser-tabs", "new-tab-button"],
 
-  BrowserUsageTelemetry._recordUITelemetry();
+      "nav-bar": [
+        "back-button",
+        "forward-button",
+        "stop-reload-button",
+        "urlbar-container",
+        "home-button",
+        "library-button",
+      ],
+    });
 
-  assertVisibilityScalars([
-    "drag-space_pinned_off",
-    "menu-toolbar_pinned_off",
-    "titlebar_pinned_off",
-    "bookmarks-bar_pinned_off",
+    BrowserUsageTelemetry._recordUITelemetry();
+
+    assertVisibilityScalars([
+      "drag-space_pinned_off",
+      "menu-toolbar_pinned_off",
+      "titlebar_pinned_off",
+      "bookmarks-bar_pinned_off",
 
-    "tabbrowser-tabs_pinned_tabs-bar",
-    "new-tab-button_pinned_tabs-bar",
-    "alltabs-button_pinned_tabs-bar",
+      "tabbrowser-tabs_pinned_tabs-bar",
+      "new-tab-button_pinned_tabs-bar",
+      "alltabs-button_pinned_tabs-bar",
 
-    "back-button_pinned_nav-bar-start",
-    "forward-button_pinned_nav-bar-start",
-    "stop-reload-button_pinned_nav-bar-start",
-    "home-button_pinned_nav-bar-end",
-    "library-button_pinned_nav-bar-end",
+      "back-button_pinned_nav-bar-start",
+      "forward-button_pinned_nav-bar-start",
+      "stop-reload-button_pinned_nav-bar-start",
+      "home-button_pinned_nav-bar-end",
+      "library-button_pinned_nav-bar-end",
 
-    "personal-bookmarks_pinned_bookmarks-bar",
-  ]);
+      "personal-bookmarks_pinned_bookmarks-bar",
+    ]);
 
-  let menu = document.getElementById("toolbar-context-menu");
-  let popupShown = BrowserTestUtils.waitForEvent(menu, "popupshown");
-  let button = document.getElementById("stop-reload-button");
-  EventUtils.synthesizeMouseAtCenter(
-    button,
-    { type: "contextmenu", button: 2 },
-    window
-  );
-  await popupShown;
+    let menu = document.getElementById("toolbar-context-menu");
+    let popupShown = BrowserTestUtils.waitForEvent(menu, "popupshown");
+    let button = document.getElementById("stop-reload-button");
+    EventUtils.synthesizeMouseAtCenter(
+      button,
+      { type: "contextmenu", button: 2 },
+      window
+    );
+    await popupShown;
 
-  let popupHidden = BrowserTestUtils.waitForEvent(menu, "popuphidden");
-  let barButton = document.getElementById("toggle_PersonalToolbar");
-  EventUtils.synthesizeMouseAtCenter(barButton, {}, window);
-  await popupHidden;
+    let barMenu = document.getElementById("toggle_PersonalToolbar");
+    let popupHidden = BrowserTestUtils.waitForEvent(menu, "popuphidden");
+    if (bookmarksFeatureEnabled) {
+      let subMenu = barMenu.querySelector("menupopup");
+      popupShown = BrowserTestUtils.waitForEvent(subMenu, "popupshown");
+      EventUtils.synthesizeMouseAtCenter(barMenu, {});
+      await popupShown;
+      let alwaysButton = barMenu.querySelector(
+        '*[data-visibility-enum="always"]'
+      );
+      EventUtils.synthesizeMouseAtCenter(alwaysButton, {});
+    } else {
+      EventUtils.synthesizeMouseAtCenter(barMenu, {});
+    }
+    await popupHidden;
 
-  popupShown = BrowserTestUtils.waitForEvent(menu, "popupshown");
-  EventUtils.synthesizeMouseAtCenter(
-    button,
-    { type: "contextmenu", button: 2 },
-    window
-  );
-  await popupShown;
+    popupShown = BrowserTestUtils.waitForEvent(menu, "popupshown");
+    EventUtils.synthesizeMouseAtCenter(
+      button,
+      { type: "contextmenu", button: 2 },
+      window
+    );
+    await popupShown;
 
-  popupHidden = BrowserTestUtils.waitForEvent(menu, "popuphidden");
-  let removeButton = document.querySelector(
-    "#toolbar-context-menu .customize-context-removeFromToolbar"
-  );
-  EventUtils.synthesizeMouseAtCenter(removeButton, {}, window);
-  await popupHidden;
+    popupHidden = BrowserTestUtils.waitForEvent(menu, "popuphidden");
+    let removeButton = document.querySelector(
+      "#toolbar-context-menu .customize-context-removeFromToolbar"
+    );
+    EventUtils.synthesizeMouseAtCenter(removeButton, {}, window);
+    await popupHidden;
 
-  assertCustomizeScalars({
-    "bookmarks-bar_move_off_on_toolbar-context-menu": 1,
-    "stop-reload-button_remove_nav-bar-start_na_toolbar-context-menu": 1,
-  });
+    let bookmarksBarTelemetryScalar = bookmarksFeatureEnabled
+      ? "bookmarks-bar_move_off_always_toolbar-context-menu"
+      : "bookmarks-bar_move_off_on_toolbar-context-menu";
+    assertCustomizeScalars({
+      [bookmarksBarTelemetryScalar]: 1,
+      "stop-reload-button_remove_nav-bar-start_na_toolbar-context-menu": 1,
+    });
 
-  CustomizableUI.reset();
+    CustomizableUI.reset();
+  }
 });
 
 add_task(async function pageActions() {
   // The page action button is only visible when a page is loaded.
   await BrowserTestUtils.withNewTab("http://example.com", async () => {
     // Create a default state.
     organizeToolbars({
       PersonalToolbar: ["personal-bookmarks"],
--- a/browser/themes/shared/browser.inc.css
+++ b/browser/themes/shared/browser.inc.css
@@ -63,29 +63,33 @@
   max-height: 4em;
   padding: 2px 6px;
 }
 
 :root[uidensity=compact] #PersonalToolbar {
   padding-inline: 2px;
 }
 
-:root[sessionrestored] #PersonalToolbar {
+:root[sessionrestored] #PersonalToolbar:not(.instant) {
   transition: min-height 170ms ease-out, max-height 170ms ease-out, @themeTransition@;
 }
 
 #PersonalToolbar[collapsed=true] {
   min-height: 0.1px;
   max-height: 0;
 }
 
-:root[sessionrestored] #PersonalToolbar[collapsed=true] {
+:root[sessionrestored] #PersonalToolbar:not(.instant)[collapsed=true] {
   transition: min-height 170ms ease-out, max-height 170ms ease-out, visibility 170ms linear;
 }
 
+#PersonalToolbar[collapsed=true].instant {
+  visibility: collapse;
+}
+
 #PersonalToolbar[customizing] {
   outline: 1px dashed;
   outline-offset: -3px;
   -moz-outline-radius: 2px;
 }
 
 #PersonalToolbar[customizing]:empty {
   /* Avoid the toolbar having no height when there's no items in it */
--- a/testing/marionette/client/marionette_driver/geckoinstance.py
+++ b/testing/marionette/client/marionette_driver/geckoinstance.py
@@ -580,16 +580,20 @@ class DesktopInstance(GeckoInstance):
 
         # Do not warn when closing all open tabs
         "browser.tabs.warnOnClose": False,
         # Do not warn when closing all other open tabs
         "browser.tabs.warnOnCloseOtherTabs": False,
         # Do not warn when multiple tabs will be opened
         "browser.tabs.warnOnOpen": False,
 
+        # Don't show the Bookmarks Toolbar on any tab (the above pref that
+        # disables the New Tab Page ends up showing the toolbar on about:blank).
+        "browser.toolbars.bookmarks.visibility": "never",
+
         # Disable the UI tour
         "browser.uitour.enabled": False,
 
         # Turn off search suggestions in the location bar so as not to trigger network
         # connections.
         "browser.urlbar.suggest.searches": False,
 
         # Don't warn when exiting the browser
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -150,16 +150,20 @@ const RECOMMENDED_PREFS = new Map([
   ["browser.tabs.warnOnClose", false],
 
   // Do not warn when closing all other open tabs
   ["browser.tabs.warnOnCloseOtherTabs", false],
 
   // Do not warn when multiple tabs will be opened
   ["browser.tabs.warnOnOpen", false],
 
+  // Don't show the Bookmarks Toolbar on any tab (the above pref that
+  // disables the New Tab Page ends up showing the toolbar on about:blank).
+  ["browser.toolbars.bookmarks.visibility", "never"],
+
   // Disable first run splash page on Windows 10
   ["browser.usedOnWindows10.introURL", ""],
 
   // Disable the UI tour.
   //
   // Should be set in profile.
   ["browser.uitour.enabled", false],
 
--- a/testing/profiles/web-platform/user.js
+++ b/testing/profiles/web-platform/user.js
@@ -1,14 +1,17 @@
 // Base preferences file for web-platform-tests.
 /* globals user_pref */
 // Don't use the new tab page but about:blank for opened tabs
 user_pref("browser.newtabpage.enabled", false);
 // Don't restore the last open set of tabs if the browser has crashed
 user_pref("browser.sessionstore.resume_from_crash", false);
+// Don't show the Bookmarks Toolbar on any tab (the above pref that
+// disables the New Tab Page ends up showing the toolbar on about:blank).
+user_pref("browser.toolbars.bookmarks.visibility", "never");
 // Only install add-ons from the profile and the application scope
 // Also ensure that those are not getting disabled.
 // see: https://developer.mozilla.org/en/Installing_extensions
 user_pref("extensions.autoDisableScopes", 10);
 // Don't open a dialog to show available add-on updates
 user_pref("extensions.update.notifyUser", false);
 // Enable test mode to run multiple tests in parallel
 user_pref("focusmanager.testmode", true);
--- a/toolkit/components/extensions/test/browser/browser_ext_themes_theme_transition.js
+++ b/toolkit/components/extensions/test/browser/browser_ext_themes_theme_transition.js
@@ -29,17 +29,17 @@ add_task(async function test_theme_trans
   Assert.ok(
     navbarCS
       .getPropertyValue("transition-property")
       .includes(TRANSITION_PROPERTY),
     "Transition property set for #nav-bar"
   );
 
   let bookmarksBar = document.querySelector("#PersonalToolbar");
-  bookmarksBar.setAttribute("collapsed", "false");
+  setToolbarVisibility(bookmarksBar, true, false, true);
   let bookmarksBarCS = window.getComputedStyle(bookmarksBar);
 
   Assert.ok(
     bookmarksBarCS
       .getPropertyValue("transition-property")
       .includes(TRANSITION_PROPERTY),
     "Transition property set for #PersonalToolbar"
   );