Pier Angelo Vendrame pushed to branch base-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
88684e4d by Henry Wilkes at 2023-10-05T22:40:35+02:00
fixup! Bug 41736: Customize toolbar for base-browser.
Bug 41736: Stop placing the NoScript button in the palette, and let it
go to the toolbar by default when shown.
- - - - -
7d1513ca by Henry Wilkes at 2023-10-05T22:40:37+02:00
fixup! Bug 41598: Prevent NoScript from being removed/disabled.
Bug 41736: Add a isNoScript property to Extension class.
- - - - -
4bf92938 by Henry Wilkes at 2023-10-05T22:40:37+02:00
Bug 41736: Hide NoScript extension's toolbar button by default.
This hides it from both the toolbar and the unified extensions panel.
We also hide the unified-extension-button if the panel would be empty:
not including the NoScript button when it is hidden. As a result, this
will be hidden by default until a user installs another extension (or
shows the NoScript button and unpins it).
- - - - -
e5331a5f by Henry Wilkes at 2023-10-05T22:40:37+02:00
fixup! Firefox preference overrides.
Bug 41736: Hide NoScript extension by default.
We also hide the unified-extension-button if it would be empty.
- - - - -
2b9948b2 by Henry Wilkes at 2023-10-05T22:40:38+02:00
fixup! Bug 41736: Customize toolbar for base-browser.
Bug 41581: Keep NoScript button in the toolbar (but hidden) by default.
Also includes some migration.
- - - - -
f0f9f20e by Henry Wilkes at 2023-10-05T22:40:38+02:00
fixup! Base Browser strings
Bug 41581: Add strings for changing the visibility of the NoScript
toolbar button.
- - - - -
9 changed files:
- browser/app/profile/001-base-profile.js
- browser/base/content/browser-addons.js
- browser/components/customizableui/CustomizableUI.sys.mjs
- browser/components/extensions/parent/ext-browserAction.js
- browser/locales/en-US/browser/base-browser.ftl
- browser/themes/shared/addons/unified-extensions.css
- toolkit/components/extensions/Extension.sys.mjs
- toolkit/mozapps/extensions/content/aboutaddons.html
- toolkit/mozapps/extensions/content/aboutaddons.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -220,6 +220,10 @@ pref("privacy.annotate_channels.strict_list.enabled", false);
// Disable the Pocket extension (Bug #18886 and #31602)
pref("extensions.pocket.enabled", false);
+// Custom extensions preferences tor-browser#41581
+pref("extensions.hideNoScript", true);
+pref("extensions.hideUnifiedWhenEmpty", true);
+
// Disable activity stream/"Recommended by Pocket" in about:home (Bug #41029)
pref("browser.newtabpage.activity-stream.discoverystream.enabled", false);
pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
=====================================
browser/base/content/browser-addons.js
=====================================
@@ -26,6 +26,9 @@ XPCOMUtils.defineLazyGetter(lazy, "l10n", function () {
);
});
+const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+const HIDE_UNIFIED_WHEN_EMPTY_PREF = "extensions.hideUnifiedWhenEmpty";
+
/**
* Mapping of error code -> [error-id, local-error-id]
*
@@ -1186,6 +1189,18 @@ var gUnifiedExtensions = {
gNavToolbox.addEventListener("customizationstarting", this);
CustomizableUI.addListener(this);
+ // Listen out for changes in extensions.hideNoScript and
+ // extension.hideUnifiedWhenEmpty, which can effect the visibility of the
+ // unified-extensions-button.
+ // See tor-browser#41581.
+ this._hideNoScriptObserver = () => this._updateVisibility();
+ Services.prefs.addObserver(HIDE_NO_SCRIPT_PREF, this._hideNoScriptObserver);
+ Services.prefs.addObserver(
+ HIDE_UNIFIED_WHEN_EMPTY_PREF,
+ this._hideNoScriptObserver
+ );
+ this._updateVisibility();
+
this._initialized = true;
},
@@ -1201,6 +1216,15 @@ var gUnifiedExtensions = {
gNavToolbox.removeEventListener("customizationstarting", this);
CustomizableUI.removeListener(this);
+
+ Services.prefs.removeObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._hideNoScriptObserver
+ );
+ Services.prefs.removeObserver(
+ HIDE_UNIFIED_WHEN_EMPTY_PREF,
+ this._hideNoScriptObserver
+ );
},
onLocationChange(browser, webProgress, _request, _uri, flags) {
@@ -1278,6 +1302,15 @@ var gUnifiedExtensions = {
return false;
}
+ // When an extensions is about to be removed, it may still appear in
+ // getActiveExtensions.
+ // This is needed for hasExtensionsInPanel, when called through
+ // onWidgetDestroy when an extension is being removed.
+ // See tor-browser#41581.
+ if (extension.hasShutdown) {
+ return false;
+ }
+
// Ignore hidden and extensions that cannot access the current window
// (because of PB mode when we are in a private window), since users
// cannot do anything with those extensions anyway.
@@ -1292,6 +1325,20 @@ var gUnifiedExtensions = {
return policies;
},
+ /**
+ * Potentially hide the unified-extensions-button if it would be empty.
+ */
+ // See tor-browser#41581.
+ // The behaviour overlaps with a proposal in mozilla Bug 1778684, which has
+ // not been implemented, or had much recent activity as of 5th October 2023.
+ _updateVisibility() {
+ this.button.classList.toggle(
+ "hide-empty",
+ Services.prefs.getBoolPref(HIDE_UNIFIED_WHEN_EMPTY_PREF, true) &&
+ !this.hasExtensionsInPanel()
+ );
+ },
+
/**
* Returns true when there are active extensions listed/shown in the unified
* extensions panel, and false otherwise (e.g. when extensions are pinned in
@@ -1300,7 +1347,13 @@ var gUnifiedExtensions = {
* @returns {boolean} Whether there are extensions listed in the panel.
*/
hasExtensionsInPanel() {
- const policies = this.getActivePolicies();
+ let policies = this.getActivePolicies();
+ // If the NoScript button is hidden, we won't count it towards the list of
+ // extensions in the panel.
+ // See tor-browser#41581.
+ if (Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true)) {
+ policies = policies.filter(policy => !policy.extension?.isNoScript);
+ }
return !!policies
.map(policy => this.browserActionFor(policy)?.widget)
@@ -1795,7 +1848,17 @@ var gUnifiedExtensions = {
}
},
+ onWidgetRemoved() {
+ this._updateVisibility();
+ },
+
+ onWidgetDestroyed() {
+ this._updateVisibility();
+ },
+
onWidgetAdded(aWidgetId, aArea, aPosition) {
+ this._updateVisibility();
+
// When we pin a widget to the toolbar from a narrow window, the widget
// will be overflowed directly. In this case, we do not want to change the
// class name since it is going to be changed by `onWidgetOverflow()`
@@ -1811,6 +1874,8 @@ var gUnifiedExtensions = {
},
onWidgetOverflow(aNode, aContainer) {
+ this._updateVisibility();
+
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
@@ -1821,6 +1886,8 @@ var gUnifiedExtensions = {
},
onWidgetUnderflow(aNode, aContainer) {
+ this._updateVisibility();
+
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
=====================================
browser/components/customizableui/CustomizableUI.sys.mjs
=====================================
@@ -65,7 +65,8 @@ var kVersion = 19;
/**
* The current version for base browser.
*/
-var kVersionBaseBrowser = 1;
+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
@@ -850,6 +851,57 @@ var CustomizableUIInternal = {
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);
+ }
+ }
+ }
+ }
},
_placeNewDefaultWidgetsInArea(aArea) {
@@ -3409,7 +3461,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
+ );
}
}
},
=====================================
browser/components/extensions/parent/ext-browserAction.js
=====================================
@@ -176,10 +176,6 @@ this.browserAction = class extends ExtensionAPIPersistent {
}
build() {
- // The extension ID for NoScript (WebExtension)
- const isNoScript =
- this.extension.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
-
let { extension } = this;
let widgetId = makeWidgetId(extension.id);
let widget = CustomizableUI.createWidget({
@@ -190,11 +186,7 @@ this.browserAction = class extends ExtensionAPIPersistent {
removable: true,
label: this.action.getProperty(null, "title"),
tooltiptext: this.action.getProperty(null, "title"),
- // Do not want to add the NoScript extension to the toolbar by default.
- // tor-browser#41736
- defaultArea: isNoScript
- ? null
- : browserAreas[this.action.getDefaultArea()],
+ defaultArea: browserAreas[this.action.getDefaultArea()],
showInPrivateBrowsing: extension.privateBrowsingAllowed,
disallowSubView: true,
@@ -282,6 +274,22 @@ this.browserAction = class extends ExtensionAPIPersistent {
node.append(button, menuButton);
node.viewButton = button;
+ if (extension.isNoScript) {
+ // Hide NoScript by default.
+ // See tor-browser#41581.
+ const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+ const changeNoScriptVisibility = () => {
+ node.hidden = Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true);
+ };
+ // Since we expect the NoScript widget to only be destroyed on exit,
+ // we do not set up to remove the observer.
+ Services.prefs.addObserver(
+ HIDE_NO_SCRIPT_PREF,
+ changeNoScriptVisibility
+ );
+ changeNoScriptVisibility();
+ }
+
return node;
},
=====================================
browser/locales/en-US/browser/base-browser.ftl
=====================================
@@ -24,6 +24,11 @@ basebrowser-rfp-restore-window-size-button-ak = R
basebrowser-addon-badge-recommended = Mozilla only recommends extensions that meet their standards for security and performance
basebrowser-addon-badge-verified = Mozilla has reviewed this extension to meet their standards for security and performance
+## Option to show or hide the NoScript extension button/item.
+basebrowser-addon-noscript-visibility-label = Toolbar button
+basebrowser-addon-noscript-visibility-show = Show
+basebrowser-addon-noscript-visibility-hide = Hide
+
## About dialog
# "Mozilla Firefox" should be treated like a brand and it should be neither translated nor transliterated.
=====================================
browser/themes/shared/addons/unified-extensions.css
=====================================
@@ -238,3 +238,21 @@ unified-extensions-item > .subviewbutton {
border-color: transparent;
}
}
+
+/* Extra rule for tor-browser. See tor-browser#41581.
+ * We want to hide the unified-extensions-button when it is empty.
+ * However, this button is needed as an anchor for addon notifications. E.g.
+ * when installing another addon and permissions pop up.
+ * If we simply marked it as "hidden" then it would not be used as an anchor, so
+ * the popup would fall back to using the identity button as an anchor instead.
+ * So instead, we use "visibility: collapse" whilst it is empty *and* it is not
+ * being used as an anchor (the open attribute is missing). */
+#unified-extensions-button.hide-empty:not([open]) {
+ visibility: collapse;
+ /* Ensure getBoundingClientRect().width returns 0.
+ * Even though this button is collapsed, and therefore should not take up any
+ * layout space, getBoundingClientRect will still measure the padding.
+ * If this was not zero, OverflowableToolbar#getOverflowInfo would
+ * over-measure the children width and would always overflow. */
+ padding-inline: 0;
+}
=====================================
toolkit/components/extensions/Extension.sys.mjs
=====================================
@@ -765,6 +765,15 @@ export class ExtensionData {
this.eventPagesEnabled = lazy.eventPagesEnabled;
}
+ /**
+ * Whether this is the NoScript extension.
+ *
+ * @type {boolean}
+ */
+ get isNoScript() {
+ return this.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
+ }
+
/**
* A factory function that allows the construction of ExtensionData, with
* the isPrivileged flag computed asynchronously.
@@ -3498,7 +3507,7 @@ export class Extension extends ExtensionData {
}
// Bug 40253: Explicitly allow NoScript in Private Browsing mode.
- if (this.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}") {
+ if (this.isNoScript) {
lazy.ExtensionPermissions.add(this.id, {
permissions: [PRIVATE_ALLOWED_PERMISSION],
origins: [],
=====================================
toolkit/mozapps/extensions/content/aboutaddons.html
=====================================
@@ -508,6 +508,32 @@
<div class="addon-detail-sitepermissions">
<addon-sitepermissions-list></addon-sitepermissions-list>
</div>
+ <!-- Add an option to show the NoScript toolbar button, if this is the
+ - NoScript addon. See tor-browser#41581. -->
+ <div
+ class="addon-detail-row addon-detail-row-noscript-visibility"
+ role="radiogroup"
+ hidden="hidden"
+ >
+ <span
+ class="addon-noscript-visibility-label"
+ data-l10n-id="basebrowser-addon-noscript-visibility-label"
+ ></span>
+ <div class="addon-detail-actions">
+ <label class="radio-container-with-text">
+ <input type="radio" name="noscript-visibility" value="show" />
+ <span
+ data-l10n-id="basebrowser-addon-noscript-visibility-show"
+ ></span>
+ </label>
+ <label class="radio-container-with-text">
+ <input type="radio" name="noscript-visibility" value="hide" />
+ <span
+ data-l10n-id="basebrowser-addon-noscript-visibility-hide"
+ ></span>
+ </label>
+ </div>
+ </div>
<div class="addon-detail-row addon-detail-row-updates">
<label data-l10n-id="addon-detail-updates-label"></label>
<div class="addon-detail-actions">
=====================================
toolkit/mozapps/extensions/content/aboutaddons.js
=====================================
@@ -2063,6 +2063,8 @@ class AddonSitePermissionsList extends HTMLElement {
}
customElements.define("addon-sitepermissions-list", AddonSitePermissionsList);
+const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+
class AddonDetails extends HTMLElement {
connectedCallback() {
if (!this.children.length) {
@@ -2070,12 +2072,61 @@ class AddonDetails extends HTMLElement {
}
this.deck.addEventListener("view-changed", this);
this.descriptionShowMoreButton.addEventListener("click", this);
+
+ // If this is for the NoScript extension, we listen for changes in the
+ // visibility of its toolbar button.
+ // See tor-browser#41581.
+ // NOTE: The addon should be set before being connected, so isNoScript will
+ // return a correct value.
+ if (this.isNoScript && !this._noScriptVisibilityObserver) {
+ this._noScriptVisibilityObserver = () => this.updateNoScriptVisibility();
+ Services.prefs.addObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._noScriptVisibilityObserver
+ );
+ }
}
disconnectedCallback() {
this.inlineOptions.destroyBrowser();
this.deck.removeEventListener("view-changed", this);
this.descriptionShowMoreButton.removeEventListener("click", this);
+
+ if (this._noScriptVisibilityObserver) {
+ Services.prefs.removeObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._noScriptVisibilityObserver
+ );
+ // Clear in case this is called again, or if connectedCallback is called.
+ delete this._noScriptVisibilityObserver;
+ }
+ }
+
+ /**
+ * Whether this is a description for the NoScript extension.
+ *
+ * @type {boolean}
+ */
+ get isNoScript() {
+ return this.addon?.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
+ }
+
+ /**
+ * Update the shown visibility value for the NoScript extension's toolbar
+ * button.
+ */
+ updateNoScriptVisibility() {
+ if (!this.isNoScript) {
+ return;
+ }
+ const visibility = Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true)
+ ? "hide"
+ : "show";
+ for (const input of this.querySelectorAll(
+ ".addon-detail-row-noscript-visibility input"
+ )) {
+ input.checked = input.value === visibility;
+ }
}
handleEvent(e) {
@@ -2271,6 +2322,27 @@ class AddonDetails extends HTMLElement {
"upgrade"
);
+ // If this is the NoScript extension, we want to show an option to change
+ // the visibility of its toolbar button.
+ // See tor-browser#41581.
+ const visibilityRow = this.querySelector(
+ ".addon-detail-row-noscript-visibility"
+ );
+ visibilityRow.hidden = !this.isNoScript;
+ if (this.isNoScript) {
+ // Set up the aria-label for the role="radiogroup".
+ const visibilityLabel = visibilityRow.querySelector(
+ ".addon-noscript-visibility-label"
+ );
+ visibilityLabel.id = ExtensionCommon.makeWidgetId(
+ `${addon.id}-noscript-visibility-label`
+ );
+ visibilityRow.setAttribute("aria-labelledby", visibilityLabel.id);
+
+ // Set the initial displayed value.
+ this.updateNoScriptVisibility();
+ }
+
if (addon.type != "extension") {
// Don't show any private browsing related section for non-extension
// addon types, because not relevant or they are either always allowed
@@ -2662,6 +2734,11 @@ class AddonCard extends HTMLElement {
// Update the card if the add-on isn't active.
this.update();
}
+ } else if (name == "noscript-visibility") {
+ // Update the NoScript toolbar button visibility.
+ // See tor-browser#41581.
+ const hide = e.target.value !== "show";
+ Services.prefs.setBoolPref(HIDE_NO_SCRIPT_PREF, hide);
}
} else if (e.type == "mousedown") {
// Open panel on mousedown when the mouse is used.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/e8fd5d…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/e8fd5d…
You're receiving this email because of your account on gitlab.torproject.org.
Pier Angelo Vendrame pushed to branch mullvad-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
1d2c3ecd by Henry Wilkes at 2023-10-05T22:40:06+02:00
fixup! Bug 41736: Customize toolbar for base-browser.
Bug 41736: Stop placing the NoScript button in the palette, and let it
go to the toolbar by default when shown.
- - - - -
e1a841b6 by Henry Wilkes at 2023-10-05T22:40:07+02:00
fixup! Bug 41598: Prevent NoScript from being removed/disabled.
Bug 41736: Add a isNoScript property to Extension class.
- - - - -
4fb23317 by Henry Wilkes at 2023-10-05T22:40:08+02:00
Bug 41736: Hide NoScript extension's toolbar button by default.
This hides it from both the toolbar and the unified extensions panel.
We also hide the unified-extension-button if the panel would be empty:
not including the NoScript button when it is hidden. As a result, this
will be hidden by default until a user installs another extension (or
shows the NoScript button and unpins it).
- - - - -
d7477bb4 by Henry Wilkes at 2023-10-05T22:40:08+02:00
fixup! Firefox preference overrides.
Bug 41736: Hide NoScript extension by default.
We also hide the unified-extension-button if it would be empty.
- - - - -
3c39c8a3 by Henry Wilkes at 2023-10-05T22:40:09+02:00
fixup! Bug 41736: Customize toolbar for base-browser.
Bug 41581: Keep NoScript button in the toolbar (but hidden) by default.
Also includes some migration.
- - - - -
8fded311 by Henry Wilkes at 2023-10-05T22:40:09+02:00
fixup! Base Browser strings
Bug 41581: Add strings for changing the visibility of the NoScript
toolbar button.
- - - - -
9 changed files:
- browser/app/profile/001-base-profile.js
- browser/base/content/browser-addons.js
- browser/components/customizableui/CustomizableUI.sys.mjs
- browser/components/extensions/parent/ext-browserAction.js
- browser/locales/en-US/browser/base-browser.ftl
- browser/themes/shared/addons/unified-extensions.css
- toolkit/components/extensions/Extension.sys.mjs
- toolkit/mozapps/extensions/content/aboutaddons.html
- toolkit/mozapps/extensions/content/aboutaddons.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -220,6 +220,10 @@ pref("privacy.annotate_channels.strict_list.enabled", false);
// Disable the Pocket extension (Bug #18886 and #31602)
pref("extensions.pocket.enabled", false);
+// Custom extensions preferences tor-browser#41581
+pref("extensions.hideNoScript", true);
+pref("extensions.hideUnifiedWhenEmpty", true);
+
// Disable activity stream/"Recommended by Pocket" in about:home (Bug #41029)
pref("browser.newtabpage.activity-stream.discoverystream.enabled", false);
pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
=====================================
browser/base/content/browser-addons.js
=====================================
@@ -26,6 +26,9 @@ XPCOMUtils.defineLazyGetter(lazy, "l10n", function () {
);
});
+const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+const HIDE_UNIFIED_WHEN_EMPTY_PREF = "extensions.hideUnifiedWhenEmpty";
+
/**
* Mapping of error code -> [error-id, local-error-id]
*
@@ -1186,6 +1189,18 @@ var gUnifiedExtensions = {
gNavToolbox.addEventListener("customizationstarting", this);
CustomizableUI.addListener(this);
+ // Listen out for changes in extensions.hideNoScript and
+ // extension.hideUnifiedWhenEmpty, which can effect the visibility of the
+ // unified-extensions-button.
+ // See tor-browser#41581.
+ this._hideNoScriptObserver = () => this._updateVisibility();
+ Services.prefs.addObserver(HIDE_NO_SCRIPT_PREF, this._hideNoScriptObserver);
+ Services.prefs.addObserver(
+ HIDE_UNIFIED_WHEN_EMPTY_PREF,
+ this._hideNoScriptObserver
+ );
+ this._updateVisibility();
+
this._initialized = true;
},
@@ -1201,6 +1216,15 @@ var gUnifiedExtensions = {
gNavToolbox.removeEventListener("customizationstarting", this);
CustomizableUI.removeListener(this);
+
+ Services.prefs.removeObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._hideNoScriptObserver
+ );
+ Services.prefs.removeObserver(
+ HIDE_UNIFIED_WHEN_EMPTY_PREF,
+ this._hideNoScriptObserver
+ );
},
onLocationChange(browser, webProgress, _request, _uri, flags) {
@@ -1278,6 +1302,15 @@ var gUnifiedExtensions = {
return false;
}
+ // When an extensions is about to be removed, it may still appear in
+ // getActiveExtensions.
+ // This is needed for hasExtensionsInPanel, when called through
+ // onWidgetDestroy when an extension is being removed.
+ // See tor-browser#41581.
+ if (extension.hasShutdown) {
+ return false;
+ }
+
// Ignore hidden and extensions that cannot access the current window
// (because of PB mode when we are in a private window), since users
// cannot do anything with those extensions anyway.
@@ -1292,6 +1325,20 @@ var gUnifiedExtensions = {
return policies;
},
+ /**
+ * Potentially hide the unified-extensions-button if it would be empty.
+ */
+ // See tor-browser#41581.
+ // The behaviour overlaps with a proposal in mozilla Bug 1778684, which has
+ // not been implemented, or had much recent activity as of 5th October 2023.
+ _updateVisibility() {
+ this.button.classList.toggle(
+ "hide-empty",
+ Services.prefs.getBoolPref(HIDE_UNIFIED_WHEN_EMPTY_PREF, true) &&
+ !this.hasExtensionsInPanel()
+ );
+ },
+
/**
* Returns true when there are active extensions listed/shown in the unified
* extensions panel, and false otherwise (e.g. when extensions are pinned in
@@ -1300,7 +1347,13 @@ var gUnifiedExtensions = {
* @returns {boolean} Whether there are extensions listed in the panel.
*/
hasExtensionsInPanel() {
- const policies = this.getActivePolicies();
+ let policies = this.getActivePolicies();
+ // If the NoScript button is hidden, we won't count it towards the list of
+ // extensions in the panel.
+ // See tor-browser#41581.
+ if (Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true)) {
+ policies = policies.filter(policy => !policy.extension?.isNoScript);
+ }
return !!policies
.map(policy => this.browserActionFor(policy)?.widget)
@@ -1795,7 +1848,17 @@ var gUnifiedExtensions = {
}
},
+ onWidgetRemoved() {
+ this._updateVisibility();
+ },
+
+ onWidgetDestroyed() {
+ this._updateVisibility();
+ },
+
onWidgetAdded(aWidgetId, aArea, aPosition) {
+ this._updateVisibility();
+
// When we pin a widget to the toolbar from a narrow window, the widget
// will be overflowed directly. In this case, we do not want to change the
// class name since it is going to be changed by `onWidgetOverflow()`
@@ -1811,6 +1874,8 @@ var gUnifiedExtensions = {
},
onWidgetOverflow(aNode, aContainer) {
+ this._updateVisibility();
+
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
@@ -1821,6 +1886,8 @@ var gUnifiedExtensions = {
},
onWidgetUnderflow(aNode, aContainer) {
+ this._updateVisibility();
+
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
=====================================
browser/components/customizableui/CustomizableUI.sys.mjs
=====================================
@@ -65,7 +65,8 @@ var kVersion = 19;
/**
* The current version for base browser.
*/
-var kVersionBaseBrowser = 1;
+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
@@ -850,6 +851,57 @@ var CustomizableUIInternal = {
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);
+ }
+ }
+ }
+ }
},
_placeNewDefaultWidgetsInArea(aArea) {
@@ -3409,7 +3461,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
+ );
}
}
},
=====================================
browser/components/extensions/parent/ext-browserAction.js
=====================================
@@ -176,10 +176,6 @@ this.browserAction = class extends ExtensionAPIPersistent {
}
build() {
- // The extension ID for NoScript (WebExtension)
- const isNoScript =
- this.extension.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
-
let { extension } = this;
let widgetId = makeWidgetId(extension.id);
let widget = CustomizableUI.createWidget({
@@ -190,11 +186,7 @@ this.browserAction = class extends ExtensionAPIPersistent {
removable: true,
label: this.action.getProperty(null, "title"),
tooltiptext: this.action.getProperty(null, "title"),
- // Do not want to add the NoScript extension to the toolbar by default.
- // tor-browser#41736
- defaultArea: isNoScript
- ? null
- : browserAreas[this.action.getDefaultArea()],
+ defaultArea: browserAreas[this.action.getDefaultArea()],
showInPrivateBrowsing: extension.privateBrowsingAllowed,
disallowSubView: true,
@@ -282,6 +274,22 @@ this.browserAction = class extends ExtensionAPIPersistent {
node.append(button, menuButton);
node.viewButton = button;
+ if (extension.isNoScript) {
+ // Hide NoScript by default.
+ // See tor-browser#41581.
+ const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+ const changeNoScriptVisibility = () => {
+ node.hidden = Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true);
+ };
+ // Since we expect the NoScript widget to only be destroyed on exit,
+ // we do not set up to remove the observer.
+ Services.prefs.addObserver(
+ HIDE_NO_SCRIPT_PREF,
+ changeNoScriptVisibility
+ );
+ changeNoScriptVisibility();
+ }
+
return node;
},
=====================================
browser/locales/en-US/browser/base-browser.ftl
=====================================
@@ -24,6 +24,11 @@ basebrowser-rfp-restore-window-size-button-ak = R
basebrowser-addon-badge-recommended = Mozilla only recommends extensions that meet their standards for security and performance
basebrowser-addon-badge-verified = Mozilla has reviewed this extension to meet their standards for security and performance
+## Option to show or hide the NoScript extension button/item.
+basebrowser-addon-noscript-visibility-label = Toolbar button
+basebrowser-addon-noscript-visibility-show = Show
+basebrowser-addon-noscript-visibility-hide = Hide
+
## About dialog
# "Mozilla Firefox" should be treated like a brand and it should be neither translated nor transliterated.
=====================================
browser/themes/shared/addons/unified-extensions.css
=====================================
@@ -238,3 +238,21 @@ unified-extensions-item > .subviewbutton {
border-color: transparent;
}
}
+
+/* Extra rule for tor-browser. See tor-browser#41581.
+ * We want to hide the unified-extensions-button when it is empty.
+ * However, this button is needed as an anchor for addon notifications. E.g.
+ * when installing another addon and permissions pop up.
+ * If we simply marked it as "hidden" then it would not be used as an anchor, so
+ * the popup would fall back to using the identity button as an anchor instead.
+ * So instead, we use "visibility: collapse" whilst it is empty *and* it is not
+ * being used as an anchor (the open attribute is missing). */
+#unified-extensions-button.hide-empty:not([open]) {
+ visibility: collapse;
+ /* Ensure getBoundingClientRect().width returns 0.
+ * Even though this button is collapsed, and therefore should not take up any
+ * layout space, getBoundingClientRect will still measure the padding.
+ * If this was not zero, OverflowableToolbar#getOverflowInfo would
+ * over-measure the children width and would always overflow. */
+ padding-inline: 0;
+}
=====================================
toolkit/components/extensions/Extension.sys.mjs
=====================================
@@ -765,6 +765,15 @@ export class ExtensionData {
this.eventPagesEnabled = lazy.eventPagesEnabled;
}
+ /**
+ * Whether this is the NoScript extension.
+ *
+ * @type {boolean}
+ */
+ get isNoScript() {
+ return this.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
+ }
+
/**
* A factory function that allows the construction of ExtensionData, with
* the isPrivileged flag computed asynchronously.
@@ -3498,7 +3507,7 @@ export class Extension extends ExtensionData {
}
// Bug 40253: Explicitly allow NoScript in Private Browsing mode.
- if (this.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}") {
+ if (this.isNoScript) {
lazy.ExtensionPermissions.add(this.id, {
permissions: [PRIVATE_ALLOWED_PERMISSION],
origins: [],
=====================================
toolkit/mozapps/extensions/content/aboutaddons.html
=====================================
@@ -508,6 +508,32 @@
<div class="addon-detail-sitepermissions">
<addon-sitepermissions-list></addon-sitepermissions-list>
</div>
+ <!-- Add an option to show the NoScript toolbar button, if this is the
+ - NoScript addon. See tor-browser#41581. -->
+ <div
+ class="addon-detail-row addon-detail-row-noscript-visibility"
+ role="radiogroup"
+ hidden="hidden"
+ >
+ <span
+ class="addon-noscript-visibility-label"
+ data-l10n-id="basebrowser-addon-noscript-visibility-label"
+ ></span>
+ <div class="addon-detail-actions">
+ <label class="radio-container-with-text">
+ <input type="radio" name="noscript-visibility" value="show" />
+ <span
+ data-l10n-id="basebrowser-addon-noscript-visibility-show"
+ ></span>
+ </label>
+ <label class="radio-container-with-text">
+ <input type="radio" name="noscript-visibility" value="hide" />
+ <span
+ data-l10n-id="basebrowser-addon-noscript-visibility-hide"
+ ></span>
+ </label>
+ </div>
+ </div>
<div class="addon-detail-row addon-detail-row-updates">
<label data-l10n-id="addon-detail-updates-label"></label>
<div class="addon-detail-actions">
=====================================
toolkit/mozapps/extensions/content/aboutaddons.js
=====================================
@@ -2063,6 +2063,8 @@ class AddonSitePermissionsList extends HTMLElement {
}
customElements.define("addon-sitepermissions-list", AddonSitePermissionsList);
+const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+
class AddonDetails extends HTMLElement {
connectedCallback() {
if (!this.children.length) {
@@ -2070,12 +2072,61 @@ class AddonDetails extends HTMLElement {
}
this.deck.addEventListener("view-changed", this);
this.descriptionShowMoreButton.addEventListener("click", this);
+
+ // If this is for the NoScript extension, we listen for changes in the
+ // visibility of its toolbar button.
+ // See tor-browser#41581.
+ // NOTE: The addon should be set before being connected, so isNoScript will
+ // return a correct value.
+ if (this.isNoScript && !this._noScriptVisibilityObserver) {
+ this._noScriptVisibilityObserver = () => this.updateNoScriptVisibility();
+ Services.prefs.addObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._noScriptVisibilityObserver
+ );
+ }
}
disconnectedCallback() {
this.inlineOptions.destroyBrowser();
this.deck.removeEventListener("view-changed", this);
this.descriptionShowMoreButton.removeEventListener("click", this);
+
+ if (this._noScriptVisibilityObserver) {
+ Services.prefs.removeObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._noScriptVisibilityObserver
+ );
+ // Clear in case this is called again, or if connectedCallback is called.
+ delete this._noScriptVisibilityObserver;
+ }
+ }
+
+ /**
+ * Whether this is a description for the NoScript extension.
+ *
+ * @type {boolean}
+ */
+ get isNoScript() {
+ return this.addon?.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
+ }
+
+ /**
+ * Update the shown visibility value for the NoScript extension's toolbar
+ * button.
+ */
+ updateNoScriptVisibility() {
+ if (!this.isNoScript) {
+ return;
+ }
+ const visibility = Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true)
+ ? "hide"
+ : "show";
+ for (const input of this.querySelectorAll(
+ ".addon-detail-row-noscript-visibility input"
+ )) {
+ input.checked = input.value === visibility;
+ }
}
handleEvent(e) {
@@ -2271,6 +2322,27 @@ class AddonDetails extends HTMLElement {
"upgrade"
);
+ // If this is the NoScript extension, we want to show an option to change
+ // the visibility of its toolbar button.
+ // See tor-browser#41581.
+ const visibilityRow = this.querySelector(
+ ".addon-detail-row-noscript-visibility"
+ );
+ visibilityRow.hidden = !this.isNoScript;
+ if (this.isNoScript) {
+ // Set up the aria-label for the role="radiogroup".
+ const visibilityLabel = visibilityRow.querySelector(
+ ".addon-noscript-visibility-label"
+ );
+ visibilityLabel.id = ExtensionCommon.makeWidgetId(
+ `${addon.id}-noscript-visibility-label`
+ );
+ visibilityRow.setAttribute("aria-labelledby", visibilityLabel.id);
+
+ // Set the initial displayed value.
+ this.updateNoScriptVisibility();
+ }
+
if (addon.type != "extension") {
// Don't show any private browsing related section for non-extension
// addon types, because not relevant or they are either always allowed
@@ -2662,6 +2734,11 @@ class AddonCard extends HTMLElement {
// Update the card if the add-on isn't active.
this.update();
}
+ } else if (name == "noscript-visibility") {
+ // Update the NoScript toolbar button visibility.
+ // See tor-browser#41581.
+ const hide = e.target.value !== "show";
+ Services.prefs.setBoolPref(HIDE_NO_SCRIPT_PREF, hide);
}
} else if (e.type == "mousedown") {
// Open panel on mousedown when the mouse is used.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/2a…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/2a…
You're receiving this email because of your account on gitlab.torproject.org.
Pier Angelo Vendrame pushed to branch mullvad-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
2aa3828e by Pier Angelo Vendrame at 2023-10-05T22:38:50+02:00
fixup! MB 39: Add home page about:mullvad-browser
MB 243: Make sure about:mullvad-browser is treated as a new tab page
- - - - -
1 changed file:
- browser/base/content/browser-places.js
Changes:
=====================================
browser/base/content/browser-places.js
=====================================
@@ -1431,7 +1431,7 @@ var BookmarkingUI = {
if (newTabURL == "about:blank") {
newTabURL = "about:newtab";
}
- let newTabURLs = [newTabURL, "about:home"];
+ let newTabURLs = [newTabURL, "about:home", "about:mullvad-browser"];
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
newTabURLs.push("about:privatebrowsing");
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/2aa…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/2aa…
You're receiving this email because of your account on gitlab.torproject.org.
Pier Angelo Vendrame pushed to branch mullvad-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
caf1a83b by Pier Angelo Vendrame at 2023-10-05T22:10:10+02:00
fixup! MB 1: Mullvad Browser branding
MB 244: Fix the link to Mullvad Browser Support
- - - - -
1 changed file:
- toolkit/content/widgets/moz-support-link/moz-support-link.mjs
Changes:
=====================================
toolkit/content/widgets/moz-support-link/moz-support-link.mjs
=====================================
@@ -103,6 +103,12 @@ export default class MozSupportLink extends HTMLAnchorElement {
#setHref() {
let supportPage = this.getAttribute("support-page") ?? "";
+ // Customize the link in about:preferences.
+ // See mullvad-browser#244 and tor-browser#41910.
+ if (supportPage === "preferences") {
+ this.href = "https://mullvad.net/en/help/";
+ return;
+ }
let base = MozSupportLink.SUPPORT_URL + supportPage;
this.href = this.hasAttribute("utm-content")
? formatUTMParams(this.getAttribute("utm-content"), base)
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/caf…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/caf…
You're receiving this email because of your account on gitlab.torproject.org.
Pier Angelo Vendrame pushed to branch tor-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
197b6fdd by Henry Wilkes at 2023-10-05T20:20:02+01:00
fixup! Bug 41736: Customize toolbar for base-browser.
Bug 41736: Stop placing the NoScript button in the palette, and let it
go to the toolbar by default when shown.
- - - - -
45b58e5a by Henry Wilkes at 2023-10-05T20:20:03+01:00
fixup! Bug 41598: Prevent NoScript from being removed/disabled.
Bug 41736: Add a isNoScript property to Extension class.
- - - - -
ddd31383 by Henry Wilkes at 2023-10-05T20:20:03+01:00
Bug 41736: Hide NoScript extension's toolbar button by default.
This hides it from both the toolbar and the unified extensions panel.
We also hide the unified-extension-button if the panel would be empty:
not including the NoScript button when it is hidden. As a result, this
will be hidden by default until a user installs another extension (or
shows the NoScript button and unpins it).
- - - - -
96e80ac1 by Henry Wilkes at 2023-10-05T20:20:04+01:00
fixup! Firefox preference overrides.
Bug 41736: Hide NoScript extension by default.
We also hide the unified-extension-button if it would be empty.
- - - - -
db17a989 by Henry Wilkes at 2023-10-05T21:20:52+01:00
fixup! Bug 41736: Customize toolbar for base-browser.
Bug 41581: Keep NoScript button in the toolbar (but hidden) by default.
Also includes some migration.
- - - - -
9db5d46d by Henry Wilkes at 2023-10-05T21:20:53+01:00
fixup! Base Browser strings
Bug 41581: Add strings for changing the visibility of the NoScript
toolbar button.
- - - - -
9 changed files:
- browser/app/profile/001-base-profile.js
- browser/base/content/browser-addons.js
- browser/components/customizableui/CustomizableUI.sys.mjs
- browser/components/extensions/parent/ext-browserAction.js
- browser/locales/en-US/browser/base-browser.ftl
- browser/themes/shared/addons/unified-extensions.css
- toolkit/components/extensions/Extension.sys.mjs
- toolkit/mozapps/extensions/content/aboutaddons.html
- toolkit/mozapps/extensions/content/aboutaddons.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -220,6 +220,10 @@ pref("privacy.annotate_channels.strict_list.enabled", false);
// Disable the Pocket extension (Bug #18886 and #31602)
pref("extensions.pocket.enabled", false);
+// Custom extensions preferences tor-browser#41581
+pref("extensions.hideNoScript", true);
+pref("extensions.hideUnifiedWhenEmpty", true);
+
// Disable activity stream/"Recommended by Pocket" in about:home (Bug #41029)
pref("browser.newtabpage.activity-stream.discoverystream.enabled", false);
pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
=====================================
browser/base/content/browser-addons.js
=====================================
@@ -26,6 +26,9 @@ XPCOMUtils.defineLazyGetter(lazy, "l10n", function () {
);
});
+const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+const HIDE_UNIFIED_WHEN_EMPTY_PREF = "extensions.hideUnifiedWhenEmpty";
+
/**
* Mapping of error code -> [error-id, local-error-id]
*
@@ -1186,6 +1189,18 @@ var gUnifiedExtensions = {
gNavToolbox.addEventListener("customizationstarting", this);
CustomizableUI.addListener(this);
+ // Listen out for changes in extensions.hideNoScript and
+ // extension.hideUnifiedWhenEmpty, which can effect the visibility of the
+ // unified-extensions-button.
+ // See tor-browser#41581.
+ this._hideNoScriptObserver = () => this._updateVisibility();
+ Services.prefs.addObserver(HIDE_NO_SCRIPT_PREF, this._hideNoScriptObserver);
+ Services.prefs.addObserver(
+ HIDE_UNIFIED_WHEN_EMPTY_PREF,
+ this._hideNoScriptObserver
+ );
+ this._updateVisibility();
+
this._initialized = true;
},
@@ -1201,6 +1216,15 @@ var gUnifiedExtensions = {
gNavToolbox.removeEventListener("customizationstarting", this);
CustomizableUI.removeListener(this);
+
+ Services.prefs.removeObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._hideNoScriptObserver
+ );
+ Services.prefs.removeObserver(
+ HIDE_UNIFIED_WHEN_EMPTY_PREF,
+ this._hideNoScriptObserver
+ );
},
onLocationChange(browser, webProgress, _request, _uri, flags) {
@@ -1278,6 +1302,15 @@ var gUnifiedExtensions = {
return false;
}
+ // When an extensions is about to be removed, it may still appear in
+ // getActiveExtensions.
+ // This is needed for hasExtensionsInPanel, when called through
+ // onWidgetDestroy when an extension is being removed.
+ // See tor-browser#41581.
+ if (extension.hasShutdown) {
+ return false;
+ }
+
// Ignore hidden and extensions that cannot access the current window
// (because of PB mode when we are in a private window), since users
// cannot do anything with those extensions anyway.
@@ -1292,6 +1325,20 @@ var gUnifiedExtensions = {
return policies;
},
+ /**
+ * Potentially hide the unified-extensions-button if it would be empty.
+ */
+ // See tor-browser#41581.
+ // The behaviour overlaps with a proposal in mozilla Bug 1778684, which has
+ // not been implemented, or had much recent activity as of 5th October 2023.
+ _updateVisibility() {
+ this.button.classList.toggle(
+ "hide-empty",
+ Services.prefs.getBoolPref(HIDE_UNIFIED_WHEN_EMPTY_PREF, true) &&
+ !this.hasExtensionsInPanel()
+ );
+ },
+
/**
* Returns true when there are active extensions listed/shown in the unified
* extensions panel, and false otherwise (e.g. when extensions are pinned in
@@ -1300,7 +1347,13 @@ var gUnifiedExtensions = {
* @returns {boolean} Whether there are extensions listed in the panel.
*/
hasExtensionsInPanel() {
- const policies = this.getActivePolicies();
+ let policies = this.getActivePolicies();
+ // If the NoScript button is hidden, we won't count it towards the list of
+ // extensions in the panel.
+ // See tor-browser#41581.
+ if (Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true)) {
+ policies = policies.filter(policy => !policy.extension?.isNoScript);
+ }
return !!policies
.map(policy => this.browserActionFor(policy)?.widget)
@@ -1795,7 +1848,17 @@ var gUnifiedExtensions = {
}
},
+ onWidgetRemoved() {
+ this._updateVisibility();
+ },
+
+ onWidgetDestroyed() {
+ this._updateVisibility();
+ },
+
onWidgetAdded(aWidgetId, aArea, aPosition) {
+ this._updateVisibility();
+
// When we pin a widget to the toolbar from a narrow window, the widget
// will be overflowed directly. In this case, we do not want to change the
// class name since it is going to be changed by `onWidgetOverflow()`
@@ -1811,6 +1874,8 @@ var gUnifiedExtensions = {
},
onWidgetOverflow(aNode, aContainer) {
+ this._updateVisibility();
+
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
@@ -1821,6 +1886,8 @@ var gUnifiedExtensions = {
},
onWidgetUnderflow(aNode, aContainer) {
+ this._updateVisibility();
+
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
=====================================
browser/components/customizableui/CustomizableUI.sys.mjs
=====================================
@@ -65,7 +65,8 @@ var kVersion = 19;
/**
* The current version for base browser.
*/
-var kVersionBaseBrowser = 1;
+var kVersionBaseBrowser = 2;
+const NoScriptId = "_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action";
/**
* The current version for tor browser.
@@ -858,6 +859,57 @@ var CustomizableUIInternal = {
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);
+ }
+ }
+ }
+ }
},
_updateForTorBrowser() {
@@ -3441,7 +3493,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
+ );
}
}
},
=====================================
browser/components/extensions/parent/ext-browserAction.js
=====================================
@@ -176,10 +176,6 @@ this.browserAction = class extends ExtensionAPIPersistent {
}
build() {
- // The extension ID for NoScript (WebExtension)
- const isNoScript =
- this.extension.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
-
let { extension } = this;
let widgetId = makeWidgetId(extension.id);
let widget = CustomizableUI.createWidget({
@@ -190,11 +186,7 @@ this.browserAction = class extends ExtensionAPIPersistent {
removable: true,
label: this.action.getProperty(null, "title"),
tooltiptext: this.action.getProperty(null, "title"),
- // Do not want to add the NoScript extension to the toolbar by default.
- // tor-browser#41736
- defaultArea: isNoScript
- ? null
- : browserAreas[this.action.getDefaultArea()],
+ defaultArea: browserAreas[this.action.getDefaultArea()],
showInPrivateBrowsing: extension.privateBrowsingAllowed,
disallowSubView: true,
@@ -282,6 +274,22 @@ this.browserAction = class extends ExtensionAPIPersistent {
node.append(button, menuButton);
node.viewButton = button;
+ if (extension.isNoScript) {
+ // Hide NoScript by default.
+ // See tor-browser#41581.
+ const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+ const changeNoScriptVisibility = () => {
+ node.hidden = Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true);
+ };
+ // Since we expect the NoScript widget to only be destroyed on exit,
+ // we do not set up to remove the observer.
+ Services.prefs.addObserver(
+ HIDE_NO_SCRIPT_PREF,
+ changeNoScriptVisibility
+ );
+ changeNoScriptVisibility();
+ }
+
return node;
},
=====================================
browser/locales/en-US/browser/base-browser.ftl
=====================================
@@ -24,6 +24,11 @@ basebrowser-rfp-restore-window-size-button-ak = R
basebrowser-addon-badge-recommended = Mozilla only recommends extensions that meet their standards for security and performance
basebrowser-addon-badge-verified = Mozilla has reviewed this extension to meet their standards for security and performance
+## Option to show or hide the NoScript extension button/item.
+basebrowser-addon-noscript-visibility-label = Toolbar button
+basebrowser-addon-noscript-visibility-show = Show
+basebrowser-addon-noscript-visibility-hide = Hide
+
## About dialog
# "Mozilla Firefox" should be treated like a brand and it should be neither translated nor transliterated.
=====================================
browser/themes/shared/addons/unified-extensions.css
=====================================
@@ -238,3 +238,21 @@ unified-extensions-item > .subviewbutton {
border-color: transparent;
}
}
+
+/* Extra rule for tor-browser. See tor-browser#41581.
+ * We want to hide the unified-extensions-button when it is empty.
+ * However, this button is needed as an anchor for addon notifications. E.g.
+ * when installing another addon and permissions pop up.
+ * If we simply marked it as "hidden" then it would not be used as an anchor, so
+ * the popup would fall back to using the identity button as an anchor instead.
+ * So instead, we use "visibility: collapse" whilst it is empty *and* it is not
+ * being used as an anchor (the open attribute is missing). */
+#unified-extensions-button.hide-empty:not([open]) {
+ visibility: collapse;
+ /* Ensure getBoundingClientRect().width returns 0.
+ * Even though this button is collapsed, and therefore should not take up any
+ * layout space, getBoundingClientRect will still measure the padding.
+ * If this was not zero, OverflowableToolbar#getOverflowInfo would
+ * over-measure the children width and would always overflow. */
+ padding-inline: 0;
+}
=====================================
toolkit/components/extensions/Extension.sys.mjs
=====================================
@@ -765,6 +765,15 @@ export class ExtensionData {
this.eventPagesEnabled = lazy.eventPagesEnabled;
}
+ /**
+ * Whether this is the NoScript extension.
+ *
+ * @type {boolean}
+ */
+ get isNoScript() {
+ return this.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
+ }
+
/**
* A factory function that allows the construction of ExtensionData, with
* the isPrivileged flag computed asynchronously.
@@ -3498,7 +3507,7 @@ export class Extension extends ExtensionData {
}
// Bug 40253: Explicitly allow NoScript in Private Browsing mode.
- if (this.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}") {
+ if (this.isNoScript) {
lazy.ExtensionPermissions.add(this.id, {
permissions: [PRIVATE_ALLOWED_PERMISSION],
origins: [],
=====================================
toolkit/mozapps/extensions/content/aboutaddons.html
=====================================
@@ -508,6 +508,32 @@
<div class="addon-detail-sitepermissions">
<addon-sitepermissions-list></addon-sitepermissions-list>
</div>
+ <!-- Add an option to show the NoScript toolbar button, if this is the
+ - NoScript addon. See tor-browser#41581. -->
+ <div
+ class="addon-detail-row addon-detail-row-noscript-visibility"
+ role="radiogroup"
+ hidden="hidden"
+ >
+ <span
+ class="addon-noscript-visibility-label"
+ data-l10n-id="basebrowser-addon-noscript-visibility-label"
+ ></span>
+ <div class="addon-detail-actions">
+ <label class="radio-container-with-text">
+ <input type="radio" name="noscript-visibility" value="show" />
+ <span
+ data-l10n-id="basebrowser-addon-noscript-visibility-show"
+ ></span>
+ </label>
+ <label class="radio-container-with-text">
+ <input type="radio" name="noscript-visibility" value="hide" />
+ <span
+ data-l10n-id="basebrowser-addon-noscript-visibility-hide"
+ ></span>
+ </label>
+ </div>
+ </div>
<div class="addon-detail-row addon-detail-row-updates">
<label data-l10n-id="addon-detail-updates-label"></label>
<div class="addon-detail-actions">
=====================================
toolkit/mozapps/extensions/content/aboutaddons.js
=====================================
@@ -2063,6 +2063,8 @@ class AddonSitePermissionsList extends HTMLElement {
}
customElements.define("addon-sitepermissions-list", AddonSitePermissionsList);
+const HIDE_NO_SCRIPT_PREF = "extensions.hideNoScript";
+
class AddonDetails extends HTMLElement {
connectedCallback() {
if (!this.children.length) {
@@ -2070,12 +2072,61 @@ class AddonDetails extends HTMLElement {
}
this.deck.addEventListener("view-changed", this);
this.descriptionShowMoreButton.addEventListener("click", this);
+
+ // If this is for the NoScript extension, we listen for changes in the
+ // visibility of its toolbar button.
+ // See tor-browser#41581.
+ // NOTE: The addon should be set before being connected, so isNoScript will
+ // return a correct value.
+ if (this.isNoScript && !this._noScriptVisibilityObserver) {
+ this._noScriptVisibilityObserver = () => this.updateNoScriptVisibility();
+ Services.prefs.addObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._noScriptVisibilityObserver
+ );
+ }
}
disconnectedCallback() {
this.inlineOptions.destroyBrowser();
this.deck.removeEventListener("view-changed", this);
this.descriptionShowMoreButton.removeEventListener("click", this);
+
+ if (this._noScriptVisibilityObserver) {
+ Services.prefs.removeObserver(
+ HIDE_NO_SCRIPT_PREF,
+ this._noScriptVisibilityObserver
+ );
+ // Clear in case this is called again, or if connectedCallback is called.
+ delete this._noScriptVisibilityObserver;
+ }
+ }
+
+ /**
+ * Whether this is a description for the NoScript extension.
+ *
+ * @type {boolean}
+ */
+ get isNoScript() {
+ return this.addon?.id === "{73a6fe31-595d-460b-a920-fcc0f8843232}";
+ }
+
+ /**
+ * Update the shown visibility value for the NoScript extension's toolbar
+ * button.
+ */
+ updateNoScriptVisibility() {
+ if (!this.isNoScript) {
+ return;
+ }
+ const visibility = Services.prefs.getBoolPref(HIDE_NO_SCRIPT_PREF, true)
+ ? "hide"
+ : "show";
+ for (const input of this.querySelectorAll(
+ ".addon-detail-row-noscript-visibility input"
+ )) {
+ input.checked = input.value === visibility;
+ }
}
handleEvent(e) {
@@ -2271,6 +2322,27 @@ class AddonDetails extends HTMLElement {
"upgrade"
);
+ // If this is the NoScript extension, we want to show an option to change
+ // the visibility of its toolbar button.
+ // See tor-browser#41581.
+ const visibilityRow = this.querySelector(
+ ".addon-detail-row-noscript-visibility"
+ );
+ visibilityRow.hidden = !this.isNoScript;
+ if (this.isNoScript) {
+ // Set up the aria-label for the role="radiogroup".
+ const visibilityLabel = visibilityRow.querySelector(
+ ".addon-noscript-visibility-label"
+ );
+ visibilityLabel.id = ExtensionCommon.makeWidgetId(
+ `${addon.id}-noscript-visibility-label`
+ );
+ visibilityRow.setAttribute("aria-labelledby", visibilityLabel.id);
+
+ // Set the initial displayed value.
+ this.updateNoScriptVisibility();
+ }
+
if (addon.type != "extension") {
// Don't show any private browsing related section for non-extension
// addon types, because not relevant or they are either always allowed
@@ -2662,6 +2734,11 @@ class AddonCard extends HTMLElement {
// Update the card if the add-on isn't active.
this.update();
}
+ } else if (name == "noscript-visibility") {
+ // Update the NoScript toolbar button visibility.
+ // See tor-browser#41581.
+ const hide = e.target.value !== "show";
+ Services.prefs.setBoolPref(HIDE_NO_SCRIPT_PREF, hide);
}
} else if (e.type == "mousedown") {
// Open panel on mousedown when the mouse is used.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/8ec6aa…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/8ec6aa…
You're receiving this email because of your account on gitlab.torproject.org.
Pier Angelo Vendrame pushed to branch base-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
e8fd5db4 by Pier Angelo Vendrame at 2023-10-05T21:57:51+02:00
fixup! Firefox preference overrides.
Bug 41576: Make sure weather and addon suggestions stay off.
Better to set them already for the next ESR.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -143,6 +143,12 @@ pref("browser.search.suggest.enabled.private", false);
pref("browser.urlbar.suggest.searches", false);
pref("browser.urlbar.suggest.quicksuggest.nonsponsored", false);
pref("browser.urlbar.suggest.quicksuggest.sponsored", false);
+// tor-browser#41576: Do not suggest weather and addons.
+pref("browser.urlbar.suggest.addons", false);
+pref("browser.urlbar.addons.featureGate", false);
+pref("browser.urlbar.suggest.weather", false);
+pref("browser.urlbar.weather.featureGate", false);
+// tor-browser#41691: Hide "Firefox Suggets" in the UI
pref("browser.urlbar.groupLabels.enabled", false);
pref("browser.safebrowsing.malware.enabled", false);
pref("browser.safebrowsing.phishing.enabled", false);
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/e8fd5db…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/e8fd5db…
You're receiving this email because of your account on gitlab.torproject.org.
Pier Angelo Vendrame pushed to branch mullvad-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
3c403c7b by Pier Angelo Vendrame at 2023-10-05T21:56:05+02:00
fixup! Firefox preference overrides.
Bug 41576: Make sure weather and addon suggestions stay off.
Better to set them already for the next ESR.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -143,6 +143,12 @@ pref("browser.search.suggest.enabled.private", false);
pref("browser.urlbar.suggest.searches", false);
pref("browser.urlbar.suggest.quicksuggest.nonsponsored", false);
pref("browser.urlbar.suggest.quicksuggest.sponsored", false);
+// tor-browser#41576: Do not suggest weather and addons.
+pref("browser.urlbar.suggest.addons", false);
+pref("browser.urlbar.addons.featureGate", false);
+pref("browser.urlbar.suggest.weather", false);
+pref("browser.urlbar.weather.featureGate", false);
+// tor-browser#41691: Hide "Firefox Suggets" in the UI
pref("browser.urlbar.groupLabels.enabled", false);
pref("browser.safebrowsing.malware.enabled", false);
pref("browser.safebrowsing.phishing.enabled", false);
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/3c4…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/3c4…
You're receiving this email because of your account on gitlab.torproject.org.
ma1 pushed to branch mullvad-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
56b44ebf by hackademix at 2023-10-05T19:06:10+02:00
fixup! Bug 40926: Implemented the New Identity feature
Bug 41765: Force about:privatebrowsing in new identity window.
- - - - -
2 changed files:
- browser/base/content/browser.js
- browser/components/newidentity/content/newidentity.js
Changes:
=====================================
browser/base/content/browser.js
=====================================
@@ -4523,7 +4523,7 @@ function OpenBrowserWindow(options) {
var extraFeatures = "";
if (options && options.private && PrivateBrowsingUtils.enabled) {
extraFeatures = ",private";
- if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
+ if (!PrivateBrowsingUtils.permanentPrivateBrowsing || options.private === "no-home") {
// Force the new window to load about:privatebrowsing instead of the default home page
defaultArgs = "about:privatebrowsing";
}
=====================================
browser/components/newidentity/content/newidentity.js
=====================================
@@ -433,11 +433,8 @@ XPCOMUtils.defineLazyGetter(this, "NewIdentityButton", () => {
openNewWindow() {
logger.info("Opening a new window");
return new Promise(resolve => {
- // Open a new window with the default homepage
- // We could pass {private: true} but we do not because we enforce
- // browser.privatebrowsing.autostart = true.
- // What about users that change settings?
- const win = OpenBrowserWindow();
+ // Open a new window forcing the about:privatebrowsing page (tor-browser#41765)
+ const win = OpenBrowserWindow({private: "no-home"});
// This mechanism to know when the new window is ready is used by
// OpenBrowserWindow itself (see its definition in browser.js).
win.addEventListener("MozAfterPaint", () => resolve(), { once: true });
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/56b…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/56b…
You're receiving this email because of your account on gitlab.torproject.org.
ma1 pushed to branch base-browser-115.3.1esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
b5574131 by hackademix at 2023-10-05T19:03:10+02:00
fixup! Bug 40926: Implemented the New Identity feature
Bug 41765: Force about:privatebrowsing in new identity window.
- - - - -
2 changed files:
- browser/base/content/browser.js
- browser/components/newidentity/content/newidentity.js
Changes:
=====================================
browser/base/content/browser.js
=====================================
@@ -4521,7 +4521,7 @@ function OpenBrowserWindow(options) {
var extraFeatures = "";
if (options && options.private && PrivateBrowsingUtils.enabled) {
extraFeatures = ",private";
- if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
+ if (!PrivateBrowsingUtils.permanentPrivateBrowsing || options.private === "no-home") {
// Force the new window to load about:privatebrowsing instead of the default home page
defaultArgs = "about:privatebrowsing";
}
=====================================
browser/components/newidentity/content/newidentity.js
=====================================
@@ -433,11 +433,8 @@ XPCOMUtils.defineLazyGetter(this, "NewIdentityButton", () => {
openNewWindow() {
logger.info("Opening a new window");
return new Promise(resolve => {
- // Open a new window with the default homepage
- // We could pass {private: true} but we do not because we enforce
- // browser.privatebrowsing.autostart = true.
- // What about users that change settings?
- const win = OpenBrowserWindow();
+ // Open a new window forcing the about:privatebrowsing page (tor-browser#41765)
+ const win = OpenBrowserWindow({private: "no-home"});
// This mechanism to know when the new window is ready is used by
// OpenBrowserWindow itself (see its definition in browser.js).
win.addEventListener("MozAfterPaint", () => resolve(), { once: true });
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b557413…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b557413…
You're receiving this email because of your account on gitlab.torproject.org.