Bug 1920489 - Set up pref branch for introducing tools to users r=sidebar-reviewers,Gijs
Differential Revision: https://phabricator.services.mozilla.com/D237763
This commit is contained in:
@@ -2097,6 +2097,9 @@ pref("sidebar.revamp.round-content-area", false);
|
|||||||
pref("sidebar.animation.enabled", true);
|
pref("sidebar.animation.enabled", true);
|
||||||
pref("sidebar.animation.duration-ms", 200);
|
pref("sidebar.animation.duration-ms", 200);
|
||||||
pref("sidebar.animation.expand-on-hover.duration-ms", 400);
|
pref("sidebar.animation.expand-on-hover.duration-ms", 400);
|
||||||
|
// The sidebar.main.tools pref cannot be changed.
|
||||||
|
// Use the sidebar.newTool.migration. pref branch to introduce a new "tool" to the sidebar launcher;
|
||||||
|
// see https://firefox-source-docs.mozilla.org/browser/components/sidebar/docs/index.html for instructions.
|
||||||
pref("sidebar.main.tools", "aichat,syncedtabs,history");
|
pref("sidebar.main.tools", "aichat,syncedtabs,history");
|
||||||
pref("sidebar.verticalTabs", false);
|
pref("sidebar.verticalTabs", false);
|
||||||
pref("sidebar.visibility", "always-show");
|
pref("sidebar.visibility", "always-show");
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
|||||||
|
|
||||||
const BACKUP_STATE_PREF = "sidebar.backupState";
|
const BACKUP_STATE_PREF = "sidebar.backupState";
|
||||||
const VISIBILITY_SETTING_PREF = "sidebar.visibility";
|
const VISIBILITY_SETTING_PREF = "sidebar.visibility";
|
||||||
|
const SIDEBAR_TOOLS = "sidebar.main.tools";
|
||||||
|
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
@@ -31,6 +32,16 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
|
lazy,
|
||||||
|
"sidebarRevampEnabled",
|
||||||
|
"sidebar.revamp",
|
||||||
|
false,
|
||||||
|
() => SidebarManager.updateDefaultTools()
|
||||||
|
);
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyPreferenceGetter(lazy, "sidebarTools", SIDEBAR_TOOLS);
|
||||||
|
|
||||||
export const SidebarManager = {
|
export const SidebarManager = {
|
||||||
/**
|
/**
|
||||||
* Handle startup tasks like telemetry, adding listeners.
|
* Handle startup tasks like telemetry, adding listeners.
|
||||||
@@ -78,6 +89,12 @@ export const SidebarManager = {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Services.prefs.addObserver(
|
||||||
|
"sidebar.newTool.migration.",
|
||||||
|
this.updateDefaultTools.bind(this)
|
||||||
|
);
|
||||||
|
this.updateDefaultTools();
|
||||||
|
|
||||||
// if there's no user visibility pref, we may need to update it to the default value for the tab orientation
|
// if there's no user visibility pref, we may need to update it to the default value for the tab orientation
|
||||||
const shouldResetVisibility = !Services.prefs.prefHasUserValue(
|
const shouldResetVisibility = !Services.prefs.prefHasUserValue(
|
||||||
VISIBILITY_SETTING_PREF
|
VISIBILITY_SETTING_PREF
|
||||||
@@ -101,6 +118,55 @@ export const SidebarManager = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends any new tools defined on the sidebar.newTool.migration pref branch
|
||||||
|
* to the sidebar.main.tools pref one time as a way of introducing a new tool
|
||||||
|
* to the launcher without overwriting what a user had previously customized.
|
||||||
|
*/
|
||||||
|
updateDefaultTools() {
|
||||||
|
if (!lazy.sidebarRevampEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tools = lazy.sidebarTools;
|
||||||
|
for (const pref of Services.prefs.getChildList(
|
||||||
|
"sidebar.newTool.migration."
|
||||||
|
)) {
|
||||||
|
try {
|
||||||
|
let options = JSON.parse(Services.prefs.getStringPref(pref));
|
||||||
|
let newTool = pref.split(".")[3];
|
||||||
|
|
||||||
|
// ensure we only add this tool once
|
||||||
|
if (options?.alreadyShown || lazy.sidebarTools.includes(newTool)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.visibilityPref) {
|
||||||
|
// Will only add the tool to the launcher if the panel governing a panels sidebar visibility
|
||||||
|
// is first enabled
|
||||||
|
let visibilityPrefValue = Services.prefs.getBoolPref(
|
||||||
|
options.visibilityPref
|
||||||
|
);
|
||||||
|
if (!visibilityPrefValue) {
|
||||||
|
Services.prefs.addObserver(
|
||||||
|
options.visibilityPref,
|
||||||
|
this.updateDefaultTools.bind(this)
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tools = tools + "," + newTool;
|
||||||
|
options.alreadyShown = true;
|
||||||
|
Services.prefs.setStringPref(pref, JSON.stringify(options));
|
||||||
|
} catch (ex) {
|
||||||
|
console.error("Failed to handle pref " + pref, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tools.length > lazy.sidebarTools.length) {
|
||||||
|
Services.prefs.setStringPref(SIDEBAR_TOOLS, tools);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide a system-level "backup" state to be stored for those using "Never
|
* Provide a system-level "backup" state to be stored for those using "Never
|
||||||
* remember history" or "Clear history when browser closes".
|
* remember history" or "Clear history when browser closes".
|
||||||
|
|||||||
20
browser/components/sidebar/docs/index.rst
Normal file
20
browser/components/sidebar/docs/index.rst
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.. _components/sidebar:
|
||||||
|
|
||||||
|
=========
|
||||||
|
Sidebar
|
||||||
|
=========
|
||||||
|
|
||||||
|
The new sidebar builds on existing legacy sidebar code treating ``browser-sidebar.js`` as a `SidebarController`. As part of the new sidebar and vertical tabs project, we've added new components including top-level system module `SidebarManager.sys.mjs` and a per window state manager, `SidebarState.sys.ms`. We've added new UI components that use a combination of moz components and custom lit components. The sidebar team maintains the existing synced tabs and history panels.
|
||||||
|
|
||||||
|
Introducing a new panel
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Every panel that is registered and enabled in ``browser-sidebar.js``` and the ```defaultTools``` map will show as an option in the Customize Sidebar menu (which is a sidebar panel that contains settings).
|
||||||
|
|
||||||
|
The launcher is a container for tools (ie, icons that when clicked open or close the associated panel). Registering a panel - which should be behind a pref until it is ready to be introduced - does not automatically add a new icon to the launcher.
|
||||||
|
|
||||||
|
A tool can be added once for all users by adding it to the designated pref branch ``sidebar.newTool.migration.`` in ``profile/firefox.js``. So an example would be ``pref("sidebar.newTool.migration.bookmarks", '{}')``. The pref suffix (``bookmarks`` in this example) is the ``toolID`` that should match what you added as the value portion of the relevant entry in the ``defaultTools`` map in ``browser-sidebar.js``. It's important to note that if you have a pref governing the visibility of your sidebar panel, it will need to be enabled at the same time in order to be shown in a user's launcher - either via a nimbus rollout or in-tree.
|
||||||
|
|
||||||
|
If you only want to add this item if the pref governing visibility is true, you can pass the pref you want to observe, e.g. ``pref("sidebar.newTool.migration.reviewchecker", '{ "visibilityPref": "browser.shopping.experience2023.integratedSidebar"}')`` where ``browser.shopping.experience2023.integratedSidebar`` is the pref controlling the visibility of the review checker panel.
|
||||||
|
|
||||||
|
In both cases, the tool will be introduced to the launcher one time (appended to a user's customized list of tools) and any customization after that (ie, removing it) takes precedence. If it's not removed, it will persist after that session.
|
||||||
@@ -16,3 +16,5 @@ EXTRA_JS_MODULES += [
|
|||||||
]
|
]
|
||||||
|
|
||||||
XPCSHELL_TESTS_MANIFESTS += ["tests/unit/xpcshell.toml"]
|
XPCSHELL_TESTS_MANIFESTS += ["tests/unit/xpcshell.toml"]
|
||||||
|
|
||||||
|
SPHINX_TREES["docs"] = "docs"
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ skip-if = [
|
|||||||
"os == 'win' && os_version == '11.26100' && opt", # Bug 1898739
|
"os == 'win' && os_version == '11.26100' && opt", # Bug 1898739
|
||||||
]
|
]
|
||||||
|
|
||||||
|
["browser_tools_migration.js"]
|
||||||
|
|
||||||
["browser_tools_overflow.js"]
|
["browser_tools_overflow.js"]
|
||||||
|
|
||||||
["browser_verticalTabs_widget_placements.js"]
|
["browser_verticalTabs_widget_placements.js"]
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
add_setup(async () => {
|
||||||
|
await SpecialPowers.pushPrefEnv({
|
||||||
|
set: [
|
||||||
|
["sidebar.main.tools", "syncedtabs,history"],
|
||||||
|
["sidebar.newTool.migration.bookmarks", "{}"],
|
||||||
|
["browser.ml.chat.enabled", false],
|
||||||
|
[
|
||||||
|
"sidebar.newTool.migration.aichat",
|
||||||
|
JSON.stringify({
|
||||||
|
visibilityPref: "browser.ml.chat.enabled",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_one_time_tool_migration() {
|
||||||
|
const sidebar = document.querySelector("sidebar-main");
|
||||||
|
let tools = Services.prefs.getStringPref("sidebar.main.tools");
|
||||||
|
is(
|
||||||
|
tools.split(",").length,
|
||||||
|
3,
|
||||||
|
"Three tools are in the sidebar.main.tools pref"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
sidebar.toolButtons.length,
|
||||||
|
3,
|
||||||
|
"Three default tools are visible in the launcher"
|
||||||
|
);
|
||||||
|
|
||||||
|
await toggleSidebarPanel(window, "viewCustomizeSidebar");
|
||||||
|
let customizeDocument = window.SidebarController.browser.contentDocument;
|
||||||
|
const customizeComponent =
|
||||||
|
customizeDocument.querySelector("sidebar-customize");
|
||||||
|
let bookmarksInput = Array.from(customizeComponent.toolInputs).find(
|
||||||
|
input => input.name === "viewBookmarksSidebar"
|
||||||
|
);
|
||||||
|
ok(
|
||||||
|
bookmarksInput.checked,
|
||||||
|
"The bookmarks input is checked in the Customize Sidebar menu."
|
||||||
|
);
|
||||||
|
let prefValue = JSON.parse(
|
||||||
|
Services.prefs.getStringPref("sidebar.newTool.migration.bookmarks")
|
||||||
|
);
|
||||||
|
bookmarksInput.click();
|
||||||
|
|
||||||
|
await BrowserTestUtils.waitForMutationCondition(
|
||||||
|
bookmarksInput,
|
||||||
|
{ attributes: true, attributeFilter: ["checked"] },
|
||||||
|
() => !bookmarksInput.checked
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(
|
||||||
|
prefValue.alreadyShown,
|
||||||
|
"Pref property has been updated after being added to tools."
|
||||||
|
);
|
||||||
|
|
||||||
|
is(sidebar.toolButtons.length, 2, "Two tools are now shown in the launcher");
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_check_visibility_enabled() {
|
||||||
|
const sidebar = document.querySelector("sidebar-main");
|
||||||
|
let tools = Services.prefs.getStringPref("sidebar.main.tools");
|
||||||
|
is(
|
||||||
|
tools.split(",").length,
|
||||||
|
2,
|
||||||
|
"Two tools are in the sidebar.main.tools pref"
|
||||||
|
);
|
||||||
|
|
||||||
|
is(sidebar.toolButtons.length, 2, "Two tools are shown in the launcher");
|
||||||
|
|
||||||
|
let prefValue = JSON.parse(
|
||||||
|
Services.prefs.getStringPref("sidebar.newTool.migration.aichat")
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(!prefValue.alreadyShown, "aichat pref property was not already shown.");
|
||||||
|
|
||||||
|
// enable aichat panel visibility
|
||||||
|
await SpecialPowers.pushPrefEnv({
|
||||||
|
set: [["browser.ml.chat.enabled", true]],
|
||||||
|
});
|
||||||
|
|
||||||
|
let customizeDocument = window.SidebarController.browser.contentDocument;
|
||||||
|
const customizeComponent =
|
||||||
|
customizeDocument.querySelector("sidebar-customize");
|
||||||
|
|
||||||
|
let aichatInput = Array.from(customizeComponent.toolInputs).find(
|
||||||
|
input => input.name === "viewGenaiChatSidebar"
|
||||||
|
);
|
||||||
|
|
||||||
|
await BrowserTestUtils.waitForMutationCondition(
|
||||||
|
aichatInput,
|
||||||
|
{ attributes: true, attributeFilter: ["checked"] },
|
||||||
|
() => aichatInput.checked
|
||||||
|
);
|
||||||
|
|
||||||
|
let bookmarksInput = Array.from(customizeComponent.toolInputs).find(
|
||||||
|
input => input.name === "viewBookmarksSidebar"
|
||||||
|
);
|
||||||
|
ok(
|
||||||
|
!bookmarksInput.checked,
|
||||||
|
"The bookmarks input is not checked in the Customize Sidebar menu."
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
sidebar.toolButtons.length,
|
||||||
|
3,
|
||||||
|
"Three tools are now shown in the launcher"
|
||||||
|
);
|
||||||
|
|
||||||
|
prefValue = JSON.parse(
|
||||||
|
Services.prefs.getStringPref("sidebar.newTool.migration.aichat")
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(
|
||||||
|
prefValue.alreadyShown,
|
||||||
|
"aichat pref property is now marked as already shown."
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -37,3 +37,4 @@ This is the nascent documentation of the Firefox front-end code.
|
|||||||
/toolkit/themes/shared/design-system/docs/README.design-tokens.stories
|
/toolkit/themes/shared/design-system/docs/README.design-tokens.stories
|
||||||
/toolkit/themes/shared/design-system/docs/README.json-design-tokens.stories
|
/toolkit/themes/shared/design-system/docs/README.json-design-tokens.stories
|
||||||
components/backup/docs/index
|
components/backup/docs/index
|
||||||
|
components/sidebar/docs/index
|
||||||
|
|||||||
Reference in New Issue
Block a user