Bug 1892941 - Add a "Always Show" sidebar visibility setting r=sidebar-reviewers,fluent-reviewers,sessionstore-reviewers,bolsson,sclements,reusable-components-reviewers,mstriemer
Differential Revision: https://phabricator.services.mozilla.com/D212285
This commit is contained in:
@@ -1916,6 +1916,7 @@ pref("sidebar.position_start", true);
|
||||
pref("sidebar.revamp", false);
|
||||
pref("sidebar.main.tools", "history,syncedtabs");
|
||||
pref("sidebar.verticalTabs", false);
|
||||
pref("sidebar.visibility", "always-show");
|
||||
|
||||
pref("browser.ml.chat.enabled", false);
|
||||
pref("browser.ml.chat.hideLocalhost", true);
|
||||
|
||||
@@ -48,6 +48,13 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
||||
false
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"sidebarRevampEnabled",
|
||||
"sidebar.revamp",
|
||||
false
|
||||
);
|
||||
|
||||
function setAttributes(aNode, aAttrs) {
|
||||
let doc = aNode.ownerDocument;
|
||||
for (let [name, value] of Object.entries(aAttrs)) {
|
||||
@@ -281,14 +288,15 @@ export const CustomizableWidgets = [
|
||||
defaultArea: "nav-bar",
|
||||
_introducedByPref: "sidebar.revamp",
|
||||
onCommand(aEvent) {
|
||||
let { SidebarController } = aEvent.target.ownerGlobal;
|
||||
if (SidebarController.sidebarRevampEnabled) {
|
||||
SidebarController.toggleExpanded();
|
||||
const { SidebarController } = aEvent.target.ownerGlobal;
|
||||
if (lazy.sidebarRevampEnabled) {
|
||||
SidebarController.handleToolbarButtonClick();
|
||||
} else {
|
||||
SidebarController.toggle();
|
||||
}
|
||||
},
|
||||
onCreated(aNode) {
|
||||
if (!lazy.sidebarRevampEnabled) {
|
||||
// Add an observer so the button is checked while the sidebar is open
|
||||
let doc = aNode.ownerDocument;
|
||||
let obChecked = doc.createXULElement("observes");
|
||||
@@ -300,6 +308,7 @@ export const CustomizableWidgets = [
|
||||
|
||||
aNode.appendChild(obChecked);
|
||||
aNode.appendChild(obPosition);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4553,6 +4553,12 @@ var SessionStoreInternal = {
|
||||
delete winData.sidebar.command;
|
||||
}
|
||||
|
||||
if (aWindow.SidebarController.sidebarRevampEnabled) {
|
||||
winData.sidebar = Object.assign(winData.sidebar || {}, {
|
||||
expanded: aWindow.SidebarController.sidebarMain.expanded,
|
||||
});
|
||||
}
|
||||
|
||||
let workspaceID = aWindow.getWorkspaceID();
|
||||
if (workspaceID) {
|
||||
winData.workspaceID = workspaceID;
|
||||
@@ -5609,6 +5615,9 @@ var SessionStoreInternal = {
|
||||
sidebarBox.setAttribute("style", aSidebar.style);
|
||||
}
|
||||
}
|
||||
if (aSidebar?.expanded) {
|
||||
aWindow.SidebarController.sidebarMain.expanded = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -6303,7 +6312,7 @@ var SessionStoreInternal = {
|
||||
}
|
||||
|
||||
// We want to preserve the sidebar if previously open in the window
|
||||
if (window.sidebar?.command) {
|
||||
if (window.sidebar) {
|
||||
newWindowState.sidebar = window.sidebar;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,3 +108,40 @@ class TestSessionRestore(SessionStoreTestCase):
|
||||
"viewHistorySidebar",
|
||||
"Correct sidebar category has been restored.",
|
||||
)
|
||||
|
||||
def test_revamp_restore(self):
|
||||
self.marionette.execute_script(
|
||||
"""
|
||||
Services.prefs.setBoolPref("sidebar.revamp", true);
|
||||
"""
|
||||
)
|
||||
self.marionette.restart()
|
||||
self.marionette.set_context("chrome")
|
||||
|
||||
self.assertEqual(
|
||||
len(self.marionette.chrome_window_handles),
|
||||
1,
|
||||
msg="Should have 1 window open.",
|
||||
)
|
||||
self.assertTrue(
|
||||
self.marionette.execute_script(
|
||||
"""
|
||||
const window = BrowserWindowTracker.getTopWindow();
|
||||
window.SidebarController.toggleExpanded();
|
||||
return window.SidebarController.sidebarMain.expanded;
|
||||
"""
|
||||
),
|
||||
"Sidebar is expanded before window is closed.",
|
||||
)
|
||||
|
||||
self.marionette.restart()
|
||||
|
||||
self.assertTrue(
|
||||
self.marionette.execute_script(
|
||||
"""
|
||||
const window = BrowserWindowTracker.getTopWindow();
|
||||
return window.SidebarController.sidebarMain.expanded;
|
||||
"""
|
||||
),
|
||||
"Sidebar expanded state has been restored.",
|
||||
)
|
||||
|
||||
@@ -211,6 +211,20 @@ var SidebarController = {
|
||||
return this._inited;
|
||||
},
|
||||
|
||||
get sidebarMain() {
|
||||
if (!this._sidebarMain) {
|
||||
this._sidebarMain = document.querySelector("sidebar-main");
|
||||
}
|
||||
return this._sidebarMain;
|
||||
},
|
||||
|
||||
get toolbarButton() {
|
||||
if (!this._toolbarButton) {
|
||||
this._toolbarButton = document.getElementById("sidebar-button");
|
||||
}
|
||||
return this._toolbarButton;
|
||||
},
|
||||
|
||||
async init() {
|
||||
this._box = document.getElementById("sidebar-box");
|
||||
this._splitter = document.getElementById("sidebar-splitter");
|
||||
@@ -242,8 +256,7 @@ var SidebarController = {
|
||||
await import("chrome://browser/content/sidebar/sidebar-main.mjs");
|
||||
document.getElementById("sidebar-main").hidden = !window.toolbar.visible;
|
||||
document.getElementById("sidebar-header").hidden = true;
|
||||
this._sidebarMain = document.querySelector("sidebar-main");
|
||||
mainResizeObserver.observe(this._sidebarMain);
|
||||
mainResizeObserver.observe(this.sidebarMain);
|
||||
|
||||
if (this.sidebarVerticalTabsEnabled) {
|
||||
this.toggleTabstrip();
|
||||
@@ -479,6 +492,10 @@ var SidebarController = {
|
||||
this._box.setAttribute("sidebarcommand", commandID);
|
||||
}
|
||||
|
||||
if (this.sidebarRevampEnabled) {
|
||||
this.sidebarMain.expanded = sourceController.sidebarMain.expanded;
|
||||
}
|
||||
|
||||
if (sourceController._box.hidden) {
|
||||
// just hidden means we have adopted the hidden state.
|
||||
return true;
|
||||
@@ -633,11 +650,16 @@ var SidebarController = {
|
||||
return this.show(commandID, triggerNode);
|
||||
},
|
||||
|
||||
handleToolbarButtonClick() {
|
||||
// TODO (Bug 1892430) This behavior is subject to change based on visibility setting.
|
||||
this.toggleExpanded();
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle the expansion state of the sidebar.
|
||||
*/
|
||||
toggleExpanded() {
|
||||
this._sidebarMain.expanded = !this._sidebarMain.expanded;
|
||||
this.sidebarMain.expanded = !this.sidebarMain.expanded;
|
||||
},
|
||||
|
||||
_loadSidebarExtension(commandID) {
|
||||
@@ -946,6 +968,11 @@ var SidebarController = {
|
||||
this._box.dispatchEvent(
|
||||
new CustomEvent("sidebar-show", { detail: { viewId: commandID } })
|
||||
);
|
||||
// Whenever a panel is shown, the sidebar is collapsed. Upon hiding
|
||||
// that panel afterwards, `expanded` reverts back to what it was prior
|
||||
// to calling `show()`. Thus, we store the expanded state at this point.
|
||||
this._previousExpandedState = this.sidebarMain.expanded;
|
||||
this.sidebarMain.expanded = false;
|
||||
} else {
|
||||
this.hideSwitcherPanel();
|
||||
}
|
||||
@@ -1019,6 +1046,7 @@ var SidebarController = {
|
||||
this.hideSwitcherPanel();
|
||||
if (this.sidebarRevampEnabled) {
|
||||
this._box.dispatchEvent(new CustomEvent("sidebar-hide"));
|
||||
this.sidebarMain.expanded = this._previousExpandedState;
|
||||
}
|
||||
this.selectMenuItem("");
|
||||
|
||||
|
||||
6
browser/components/sidebar/content/sidebar-expanded.svg
Normal file
6
browser/components/sidebar/content/sidebar-expanded.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<!-- 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/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill" fill-opacity="context-fill-opacity">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2C0.895786 2 0 2.89579 0 4V12C0 13.1042 0.895786 14 2 14H14C15.1042 14 16 13.1042 16 12V4C16 2.89579 15.1042 2 14 2H2ZM6 12.5H14C14.2758 12.5 14.5 12.2758 14.5 12V4C14.5 3.72421 14.2758 3.5 14 3.5H6V12.5Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 619 B |
6
browser/components/sidebar/content/sidebar-hidden.svg
Normal file
6
browser/components/sidebar/content/sidebar-hidden.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<!-- 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/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill" fill-opacity="context-fill-opacity">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 3.5C1.72421 3.5 1.5 3.72421 1.5 4V12C1.5 12.2758 1.72421 12.5 2 12.5H14C14.2758 12.5 14.5 12.2758 14.5 12V4C14.5 3.72421 14.2758 3.5 14 3.5H2ZM0 4C0 2.89579 0.895786 2 2 2H14C15.1042 2 16 2.89579 16 4V12C16 13.1042 15.1042 14 14 14H2C0.895786 14 0 13.1042 0 12V4Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 678 B |
@@ -17,3 +17,5 @@ browser.jar:
|
||||
content/browser/sidebar/sidebar-syncedtabs.html
|
||||
content/browser/sidebar/sidebar-syncedtabs.mjs
|
||||
content/browser/sidebar/sidebar.css
|
||||
content/browser/sidebar/sidebar-expanded.svg (content/sidebar-expanded.svg)
|
||||
content/browser/sidebar/sidebar-hidden.svg (content/sidebar-hidden.svg)
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
moz-radio-group {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#manage-settings {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -14,21 +14,28 @@ const l10nMap = new Map([
|
||||
["viewTabsSidebar", "sidebar-menu-synced-tabs-label"],
|
||||
["viewBookmarksSidebar", "sidebar-menu-bookmarks-label"],
|
||||
]);
|
||||
const VISIBILITY_SETTING_PREF = "sidebar.visibility";
|
||||
|
||||
export class SidebarCustomize extends SidebarPage {
|
||||
constructor() {
|
||||
super();
|
||||
this.activeExtIndex = 0;
|
||||
this.visibility = Services.prefs.getStringPref(
|
||||
VISIBILITY_SETTING_PREF,
|
||||
"always-show"
|
||||
);
|
||||
}
|
||||
|
||||
static properties = {
|
||||
activeExtIndex: { type: Number },
|
||||
visibility: { type: String },
|
||||
};
|
||||
|
||||
static queries = {
|
||||
toolInputs: { all: ".customize-firefox-tools moz-checkbox" },
|
||||
extensionLinks: { all: ".extension-link" },
|
||||
positionInputs: { all: ".position-setting" },
|
||||
visibilityInputs: { all: ".visibility-setting" },
|
||||
};
|
||||
|
||||
connectedCallback() {
|
||||
@@ -37,6 +44,7 @@ export class SidebarCustomize extends SidebarPage {
|
||||
this.getWindow().addEventListener("SidebarItemChanged", this);
|
||||
this.getWindow().addEventListener("SidebarItemRemoved", this);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.getWindow().removeEventListener("SidebarItemAdded", this);
|
||||
@@ -178,10 +186,28 @@ export class SidebarCustomize extends SidebarPage {
|
||||
</div>
|
||||
</div>`
|
||||
)}
|
||||
<h5 data-l10n-id="sidebar-customize-settings"></h5>
|
||||
<moz-radio-group
|
||||
@change=${this.#handleVisibilityChange}
|
||||
name="visibility"
|
||||
data-l10n-id="sidebar-customize-settings"
|
||||
>
|
||||
<moz-radio
|
||||
class="visibility-setting"
|
||||
value="always-show"
|
||||
?checked=${this.visibility === "always-show"}
|
||||
iconsrc="chrome://browser/content/sidebar/sidebar-expanded.svg"
|
||||
data-l10n-id="sidebar-visibility-always-show"
|
||||
></moz-radio>
|
||||
<moz-radio
|
||||
class="visibility-setting"
|
||||
value="hide-sidebar"
|
||||
?checked=${this.visibility === "hide-sidebar"}
|
||||
iconsrc="chrome://browser/content/sidebar/sidebar-hidden.svg"
|
||||
data-l10n-id="sidebar-visibility-hide-sidebar"
|
||||
></moz-radio>
|
||||
</moz-radio-group>
|
||||
<hr>
|
||||
<moz-radio-group
|
||||
class="customize-settings"
|
||||
@change=${this.reversePosition}
|
||||
name="position">
|
||||
<moz-radio
|
||||
@@ -218,6 +244,11 @@ export class SidebarCustomize extends SidebarPage {
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
#handleVisibilityChange({ target: { value } }) {
|
||||
this.visibility = value;
|
||||
Services.prefs.setStringPref(VISIBILITY_SETTING_PREF, value);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("sidebar-customize", SidebarCustomize);
|
||||
|
||||
@@ -83,6 +83,15 @@ export default class SidebarMain extends MozLitElement {
|
||||
window.removeEventListener("SidebarItemRemoved", this);
|
||||
}
|
||||
|
||||
updated(changedProperties) {
|
||||
if (
|
||||
changedProperties.has("expanded") &&
|
||||
window.SidebarController.toolbarButton
|
||||
) {
|
||||
window.SidebarController.toolbarButton.checked = this.expanded;
|
||||
}
|
||||
}
|
||||
|
||||
onSidebarPopupShowing(event) {
|
||||
// Store the context menu target which holds the id required for managing sidebar items
|
||||
this.contextMenuTarget =
|
||||
|
||||
@@ -30,7 +30,6 @@ sidebar-search-results-header =
|
||||
sidebar-customize-firefox-tools =
|
||||
.label = { -brand-product-name } tools
|
||||
sidebar-customize-firefox-settings = Manage { -brand-short-name } settings
|
||||
sidebar-customize-settings = Sidebar settings
|
||||
sidebar-position-left =
|
||||
.label = Show on the left
|
||||
sidebar-position-right =
|
||||
@@ -81,3 +80,10 @@ sidebar-menu-history-header =
|
||||
.heading = History
|
||||
sidebar-menu-syncedtabs-header =
|
||||
.heading = Tabs from other devices
|
||||
|
||||
sidebar-customize-settings =
|
||||
.label = Sidebar settings
|
||||
sidebar-visibility-always-show =
|
||||
.label = Always show
|
||||
sidebar-visibility-hide-sidebar =
|
||||
.label = Hide sidebar
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
add_setup(() => SpecialPowers.pushPrefEnv({ set: [["sidebar.revamp", true]] }));
|
||||
|
||||
async function showCustomizePanel(win) {
|
||||
@@ -10,7 +12,7 @@ async function showCustomizePanel(win) {
|
||||
const document = win.SidebarController.browser.contentDocument;
|
||||
return TestUtils.waitForCondition(async () => {
|
||||
const component = document.querySelector("sidebar-customize");
|
||||
if (!component?.positionInputs) {
|
||||
if (!component?.positionInputs || !component?.visibilityInputs) {
|
||||
return false;
|
||||
}
|
||||
return component;
|
||||
@@ -189,3 +191,25 @@ add_task(async function test_customize_position_setting() {
|
||||
await BrowserTestUtils.closeWindow(newWin);
|
||||
Services.prefs.clearUserPref("sidebar.position_start");
|
||||
});
|
||||
|
||||
add_task(async function test_customize_visibility_setting() {
|
||||
const win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
const panel = await showCustomizePanel(win);
|
||||
const [showInput, hideInput] = panel.visibilityInputs;
|
||||
ok(showInput.checked, "Always show is enabled by default.");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
hideInput,
|
||||
{},
|
||||
win.SidebarController.browser.contentWindow
|
||||
);
|
||||
ok(hideInput.checked, "Hide sidebar is enabled.");
|
||||
|
||||
const newWin = await BrowserTestUtils.openNewBrowserWindow();
|
||||
const newPanel = await showCustomizePanel(newWin);
|
||||
const [, newHideInput] = newPanel.visibilityInputs;
|
||||
ok(newHideInput.checked, "Visibility setting persists.");
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
await BrowserTestUtils.closeWindow(newWin);
|
||||
Services.prefs.clearUserPref("sidebar.visibility");
|
||||
});
|
||||
|
||||
@@ -93,3 +93,68 @@ add_task(async function test_toolbar_sidebar_button() {
|
||||
);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
||||
add_task(async function test_expanded_state_for_always_show() {
|
||||
const win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
const {
|
||||
SidebarController: { sidebarMain, toolbarButton },
|
||||
} = win;
|
||||
|
||||
const checkExpandedState = async (
|
||||
expanded,
|
||||
component = sidebarMain,
|
||||
button = toolbarButton
|
||||
) => {
|
||||
await TestUtils.waitForCondition(
|
||||
() => Boolean(component.expanded) == expanded,
|
||||
expanded ? "Sidebar is expanded." : "Sidebar is collapsed."
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() => Boolean(button.checked) == expanded,
|
||||
expanded
|
||||
? "Toolbar button is highlighted."
|
||||
: "Toolbar button is not highlighted."
|
||||
);
|
||||
};
|
||||
|
||||
info("Check default expanded state.");
|
||||
await checkExpandedState(false);
|
||||
|
||||
info("Toggle expanded state via toolbar button.");
|
||||
EventUtils.synthesizeMouseAtCenter(toolbarButton, {}, win);
|
||||
await checkExpandedState(true);
|
||||
EventUtils.synthesizeMouseAtCenter(toolbarButton, {}, win);
|
||||
await checkExpandedState(false);
|
||||
|
||||
info("Collapse the sidebar by loading a tool.");
|
||||
sidebarMain.expanded = true;
|
||||
await sidebarMain.updateComplete;
|
||||
const toolButton = sidebarMain.toolButtons[0];
|
||||
EventUtils.synthesizeMouseAtCenter(toolButton, {}, win);
|
||||
await checkExpandedState(false);
|
||||
|
||||
info("Restore the sidebar back to its previous state.");
|
||||
EventUtils.synthesizeMouseAtCenter(toolButton, {}, win);
|
||||
await checkExpandedState(true);
|
||||
|
||||
info("Load and unload a tool with the sidebar collapsed to begin with.");
|
||||
sidebarMain.expanded = false;
|
||||
await sidebarMain.updateComplete;
|
||||
EventUtils.synthesizeMouseAtCenter(toolButton, {}, win);
|
||||
await checkExpandedState(false);
|
||||
EventUtils.synthesizeMouseAtCenter(toolButton, {}, win);
|
||||
await checkExpandedState(false);
|
||||
|
||||
info("Check expanded state on a new window.");
|
||||
sidebarMain.expanded = true;
|
||||
await sidebarMain.updateComplete;
|
||||
const newWin = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await checkExpandedState(
|
||||
true,
|
||||
newWin.SidebarController.sidebarMain,
|
||||
newWin.SidebarController.toolbarButton
|
||||
);
|
||||
|
||||
await BrowserTestUtils.closeWindow(newWin);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user