author | Jared Wein <jwein@mozilla.com> |
Mon, 26 Oct 2020 02:32:07 +0000 (2020-10-26) | |
changeset 554356 | 45bbeabb0c89cf73d644b59898cb207e4462f147 |
parent 554355 | a4853e82ea7a0f42cebd8b5ca5d769222befaada |
child 554357 | 9cf73428357c3679bf6dfff0e1e0c1bc24d5c0e9 |
push id | 37893 |
push user | btara@mozilla.com |
push date | Mon, 26 Oct 2020 09:28:34 +0000 (2020-10-26) |
treeherder | mozilla-central@b1a74943bc51 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Gijs, fluent-reviewers, marionette-reviewers, whimboo |
bugs | 727668 |
milestone | 84.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
|
--- 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" );