Verified Commit 3dc2eb51 authored by henry's avatar henry Committed by ma1
Browse files

BB 41736: Customize toolbar for base-browser.

parent 938369bd
Loading
Loading
Loading
Loading
+184 −4
Original line number Diff line number Diff line
@@ -68,6 +68,12 @@ const kSubviewEvents = ["ViewShowing", "ViewHiding"];
 */
var kVersion = 22;

/**
 * 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
@@ -305,6 +311,7 @@ var CustomizableUIInternal = {
    this.updateForNewVersion();
    this.updateForNewProtonVersion();
    this.markObsoleteBuiltinButtonsSeen();
    this.updateForBaseBrowser();

    this.registerArea(
      CustomizableUI.AREA_FIXED_OVERFLOW_PANEL,
@@ -334,11 +341,16 @@ var CustomizableUIInternal = {
      Services.policies.isAllowed("removeHomeButtonByDefault")
        ? null
        : "home-button",
      "spring",
      // Don't want springs either side of the urlbar. tor-browser#41736
      "vertical-spacer",
      "urlbar-container",
      "spring",
      "save-to-pocket-button",
      // save-to-pocket-button is entirely disabled. See tor-browser#18886 and
      // tor-browser#31602.
      // 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",
@@ -359,6 +371,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(
@@ -937,6 +953,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
@@ -3489,6 +3654,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;
@@ -3785,6 +3954,7 @@ var CustomizableUIInternal = {
      seen: gSeenWidgets,
      dirtyAreaCache: gDirtyAreaCache,
      currentVersion: kVersion,
      currentVersionBaseBrowser: kVersionBaseBrowser,
      newElementCount: gNewElementCount,
    };

@@ -4547,7 +4717,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
        );
      }
    }
  },