commit 3b71b187df97540f5fce156888f7c97a23835870
parent 75ac156647d6a4c1a9c93ce80941b48dba2aa13a
Author: Henry Wilkes <henry@torproject.org>
Date: Wed, 19 Apr 2023 14:22:18 +0100
BB 41736: Customize toolbar for base-browser.
Diffstat:
1 file changed, 182 insertions(+), 3 deletions(-)
diff --git a/browser/components/customizableui/CustomizableUI.sys.mjs b/browser/components/customizableui/CustomizableUI.sys.mjs
@@ -71,6 +71,12 @@ const kSubviewEvents = ["ViewShowing", "ViewHiding"];
var kVersion = 23;
/**
+ * The current version for base browser.
+ */
+var kVersionBaseBrowser = 2;
+const NoScriptId = "_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action";
+
+/**
* Buttons removed from built-ins by version they were removed. kVersion must be
* bumped any time a new id is added to this. Use the button id as key, and
* version the button is removed in as the value. e.g. "pocket-button": 5
@@ -310,6 +316,7 @@ var CustomizableUIInternal = {
this.updateForNewVersion();
this.updateForNewProtonVersion();
this.markObsoleteBuiltinButtonsSeen();
+ this.updateForBaseBrowser();
this.registerArea(
CustomizableUI.AREA_FIXED_OVERFLOW_PANEL,
@@ -339,10 +346,14 @@ var CustomizableUIInternal = {
Services.policies.isAllowed("removeHomeButtonByDefault")
? null
: "home-button",
- "spring",
"vertical-spacer",
"urlbar-container",
- "spring",
+ // Don't want springs either side of the urlbar. tor-browser#41736
+ // Base-browser additions tor-browser#41736. If you want to add to, remove
+ // from, or rearrange this list, then bump the kVersionBaseBrowser and
+ // update existing saved states in _updateForBaseBrowser.
+ "security-level-button",
+ "new-identity-button",
"downloads-button",
AppConstants.MOZ_DEV_EDITION ? "developer-button" : null,
"fxa-toolbar-menu-button",
@@ -363,6 +374,10 @@ var CustomizableUIInternal = {
},
true
);
+ // navbarPlacements does not match the initial default XHTML layout.
+ // Therefore we always need to rebuild the navbar area when
+ // registerToolbarNode is called. tor-browser#41736
+ gDirtyAreaCache.add(CustomizableUI.AREA_NAVBAR);
if (!Services.appinfo.nativeMenubar) {
this.registerArea(
@@ -917,6 +932,155 @@ var CustomizableUIInternal = {
}
},
+ updateForBaseBrowser() {
+ if (!gSavedState) {
+ // Use the defaults.
+ return;
+ }
+
+ const currentVersion = gSavedState.currentVersionBaseBrowser;
+
+ if (currentVersion < 1) {
+ // NOTE: In base-browser/tor-browser version 12.5a5, and earlier, the
+ // toolbar was configured by setting the full JSON string for the default
+ // "browser.uiCustomization.state" preference value. The disadvantage is
+ // that we could not update this value in a way that existing users (who
+ // would have non-default preference values) would also get the desired
+ // change (e.g. for adding or removing a button).
+ //
+ // With tor-browser#41736 we want to switch to changing the toolbar
+ // dynamically like firefox. Therefore, this first version transfer simply
+ // gets the toolbar into the same state we wanted before, away from the
+ // default firefox state.
+ //
+ // If an existing user state aligned with the previous default
+ // "browser.uiCustomization.state" then this shouldn't visibly change
+ // anything.
+ // If a user explicitly customized the toolbar to go back to the firefox
+ // default, then this may undo those changes.
+ const navbarPlacements =
+ gSavedState.placements[CustomizableUI.AREA_NAVBAR];
+ if (navbarPlacements) {
+ const getBeforeAfterUrlbar = () => {
+ // NOTE: The urlbar is non-removable from the navbar, so should have
+ // an index.
+ const index = navbarPlacements.indexOf("urlbar-container");
+ let after = index + 1;
+ if (
+ after < navbarPlacements.length &&
+ navbarPlacements[after] === "search-container"
+ ) {
+ // Skip past the search-container.
+ after++;
+ }
+ return { before: index - 1, after };
+ };
+
+ // Remove the urlbar springs either side of the urlbar.
+ const { before, after } = getBeforeAfterUrlbar();
+ if (
+ after < navbarPlacements.length &&
+ this.matchingSpecials(navbarPlacements[after], "spring")
+ ) {
+ // Remove the spring after.
+ navbarPlacements.splice(after, 1);
+ // NOTE: The `before` index does not change.
+ }
+ if (
+ before >= 0 &&
+ this.matchingSpecials(navbarPlacements[before], "spring")
+ ) {
+ // Remove the spring before.
+ navbarPlacements.splice(before, 1);
+ }
+
+ // Make sure the security-level-button and new-identity-button appears
+ // in the toolbar.
+ for (const id of ["new-identity-button", "security-level-button"]) {
+ let alreadyAdded = false;
+ for (const placements of Object.values(gSavedState.placements)) {
+ if (placements.includes(id)) {
+ alreadyAdded = true;
+ break;
+ }
+ }
+ if (alreadyAdded) {
+ continue;
+ }
+
+ // Add to the nav-bar, after the urlbar-container.
+ // NOTE: We have already removed the spring after the urlbar.
+ navbarPlacements.splice(getBeforeAfterUrlbar().after, 0, id);
+ }
+ }
+
+ // Remove save-to-pocket-button. See tor-browser#18886 and
+ // tor-browser#31602.
+ for (const placements of Object.values(gSavedState.placements)) {
+ let buttonIndex = placements.indexOf("save-to-pocket-button");
+ if (buttonIndex != -1) {
+ placements.splice(buttonIndex, 1);
+ }
+ }
+
+ // Remove unused fields that used to be part of
+ // "browser.uiCustomization.state".
+ delete gSavedState.placements["PanelUI-contents"];
+ delete gSavedState.placements["addon-bar"];
+ }
+
+ if (currentVersion < 2) {
+ // Matches against kVersion 19, i.e. when the unified-extensions-button
+ // was introduced and extensions were moved from the palette to
+ // AREA_ADDONS.
+ // For base browser, we want the NoScript addon to be moved from the
+ // default palette to AREA_NAVBAR, so that if it becomes shown through the
+ // preference extensions.hideNoScript it will appear in the toolbar.
+ // If the NoScript addon is already in AREA_NAVBAR, we instead flip the
+ // extensions.hideNoScript preference so that it remains visible.
+ // See tor-browser#41581.
+ const navbarPlacements =
+ gSavedState.placements[CustomizableUI.AREA_NAVBAR];
+ if (navbarPlacements) {
+ let noScriptVisible = false;
+ for (const [area, placements] of Object.entries(
+ gSavedState.placements
+ )) {
+ const index = placements.indexOf(NoScriptId);
+ if (index === -1) {
+ continue;
+ }
+ if (area === CustomizableUI.AREA_ADDONS) {
+ // Has been placed in the ADDONS area.
+ // Most likely, this is an alpha or nightly user who received the
+ // firefox update in a run before this one. In this case, we want to
+ // match the same behaviour as a stable user: hide the button and
+ // move it to the NAVBAR instead.
+ placements.splice(index, 1);
+ } else {
+ // It is in an area other than the ADDON (and not in the palette).
+ noScriptVisible = true;
+ }
+ }
+ if (noScriptVisible) {
+ // Keep the button where it is and make sure it is visible.
+ Services.prefs.setBoolPref("extensions.hideNoScript", false);
+ } else {
+ // Should appear just before unified-extensions-button, which is
+ // currently not part of the default placements.
+ const placeIndex = navbarPlacements.indexOf(
+ "unified-extensions-button"
+ );
+ if (placeIndex === -1) {
+ navbarPlacements.push(NoScriptId);
+ } else {
+ navbarPlacements.splice(placeIndex, 0, NoScriptId);
+ }
+ }
+ }
+ }
+ },
+
/**
* If a new area was defined, or new default widgets for an area are defined,
* this reconciles the placements of those new default widgets with the
@@ -3464,6 +3628,10 @@ var CustomizableUIInternal = {
gSavedState.currentVersion = 0;
}
+ if (!("currentVersionBaseBrowser" in gSavedState)) {
+ gSavedState.currentVersionBaseBrowser = 0;
+ }
+
gSeenWidgets = new Set(gSavedState.seen || []);
gDirtyAreaCache = new Set(gSavedState.dirtyAreaCache || []);
gNewElementCount = gSavedState.newElementCount || 0;
@@ -3760,6 +3928,7 @@ var CustomizableUIInternal = {
seen: gSeenWidgets,
dirtyAreaCache: gDirtyAreaCache,
currentVersion: kVersion,
+ currentVersionBaseBrowser: kVersionBaseBrowser,
newElementCount: gNewElementCount,
};
@@ -4522,7 +4691,17 @@ var CustomizableUIInternal = {
CustomizableUI.isWebExtensionWidget(widgetId) &&
!oldAddonPlacements.includes(widgetId)
) {
- this.addWidgetToArea(widgetId, CustomizableUI.AREA_ADDONS);
+ // When resetting, NoScript goes to the toolbar instead. This matches
+ // its initial placement anyway. And since the button may be hidden by
+ // default by extensions.hideNoScript, we want to make sure that if it
+ // becomes unhidden it is shown rather than in the unified extensions
+ // panel. See tor-browser#41581.
+ this.addWidgetToArea(
+ widgetId,
+ widgetId === NoScriptId
+ ? CustomizableUI.AREA_NAVBAR
+ : CustomizableUI.AREA_ADDONS
+ );
}
}
},