tbb-commits
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 19495 discussions
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.4.0esr-15.0-1] 12 commits: fixup! BB 41919: Letterboxing, add temporarily visible web content-size...
by henry (ï¼ henry) 15 Oct '25
by henry (ï¼ henry) 15 Oct '25
15 Oct '25
henry pushed to branch mullvad-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
81be023b by Henry Wilkes at 2025-10-15T18:07:04+01:00
fixup! BB 41919: Letterboxing, add temporarily visible web content-size indicator on window resizing.
TB 44214: Fix letterboxing status indicator for RTL.
- - - - -
deed64ab by Henry Wilkes at 2025-10-15T18:07:05+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop unnecessary CSS rules.
- - - - -
f18fc8f5 by Henry Wilkes at 2025-10-15T18:07:06+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS logical positions for the status panel, rather than
"left" and "right".
- - - - -
77ea2cff by Henry Wilkes at 2025-10-15T18:07:06+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop upstream's rules for placing content.
- - - - -
725f9b44 by Henry Wilkes at 2025-10-15T18:07:07+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop letterboxing gradient.
- - - - -
c5acc4f7 by Henry Wilkes at 2025-10-15T18:07:08+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Separate out the essential --letterboxing-width and
--letterboxing-height rules into their own .letterboxing block, to have
the property values set on.
- - - - -
d3f14e86 by Henry Wilkes at 2025-10-15T18:07:09+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS nesting. Part 1.
- - - - -
f622ced5 by Henry Wilkes at 2025-10-15T18:07:09+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS nesting. Part 2.
- - - - -
9bd8b0b8 by Henry Wilkes at 2025-10-15T18:07:10+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Move the letterboxing classes one element up from tabpanels to
tabbox.
This is because we need to restyle the tabbox.
- - - - -
f6b94a03 by Henry Wilkes at 2025-10-15T18:07:11+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use a CSS class to show/hide the letterboxing border, rather
than setting the border-radius in javascript.
- - - - -
9f0d03ed by Henry Wilkes at 2025-10-15T18:07:12+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Rename CSS variable from top-radius to radius-top. This is
closer to what upstream has done recently for tokens, where higher
specificity is appended.
- - - - -
a11336fe by Henry Wilkes at 2025-10-15T18:07:12+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Update letterboxing styling for ESR 140.
- - - - -
4 changed files:
- browser/base/content/browser-fullScreenAndPointerLock.js
- browser/themes/shared/tabbrowser/content-area.css
- toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
- toolkit/components/resistfingerprinting/content/letterboxing.css
Changes:
=====================================
browser/base/content/browser-fullScreenAndPointerLock.js
=====================================
@@ -879,7 +879,13 @@ var FullScreen = {
}
this._isChromeCollapsed = false;
- Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "shown");
+ // Need a subject to know which window this applies to.
+ // Base browser patch can be dropped after bugzilla bug 1992036.
+ Services.obs.notifyObservers(
+ gNavToolbox,
+ "fullscreen-nav-toolbox",
+ "shown"
+ );
},
hideNavToolbox(aAnimate = false) {
@@ -943,7 +949,13 @@ var FullScreen = {
gNavToolbox.style.marginTop =
-gNavToolbox.getBoundingClientRect().height + "px";
this._isChromeCollapsed = true;
- Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "hidden");
+ // Need a subject to know which window this applies to.
+ // Base browser patch can be dropped after bugzilla bug 1880918.
+ Services.obs.notifyObservers(
+ gNavToolbox,
+ "fullscreen-nav-toolbox",
+ "hidden"
+ );
MousePosTracker.removeListener(this);
},
=====================================
browser/themes/shared/tabbrowser/content-area.css
=====================================
@@ -242,13 +242,17 @@
}
}
-#statuspanel[type=letterboxingStatus] > #statuspanel-label,
-#statuspanel[previoustype=letterboxingStatus][inactive] > #statuspanel-label {
+#statuspanel:is([type=letterboxingStatus], [previoustype=letterboxingStatus][inactive]) > #statuspanel-label {
background-image: url("chrome://browser/skin/window.svg");
background-size: 1em;
background-repeat: no-repeat;
- background-position-x: .5em;
background-position-y: center;
+ background-position-x: left .5em;
+
+ &:-moz-locale-dir(rtl) {
+ background-position-x: right .5em;
+ }
+
padding-inline-start: 2em;
-moz-context-properties: fill;
fill: var(--color-accent-primary);
=====================================
toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
=====================================
@@ -18,8 +18,6 @@ const kPrefLetterboxingTesting =
"privacy.resistFingerprinting.letterboxing.testing";
const kPrefLetterboxingVcenter =
"privacy.resistFingerprinting.letterboxing.vcenter";
-const kPrefLetterboxingGradient =
- "privacy.resistFingerprinting.letterboxing.gradient";
const kPrefLetterboxingDidForceSize =
"privacy.resistFingerprinting.letterboxing.didForceSize";
const kPrefLetterboxingRememberSize =
@@ -28,10 +26,17 @@ const kPrefLetterboxingRememberSize =
const kTopicDOMWindowOpened = "domwindowopened";
const kTopicDOMWindowClosed = "domwindowclosed";
+const kTopicFullscreenNavToolbox = "fullscreen-nav-toolbox";
+
const kPrefResizeWarnings = "privacy.resistFingerprinting.resizeWarnings";
+const kPrefVerticalTabs = "sidebar.verticalTabs";
+
const lazy = {};
+ChromeUtils.defineESModuleGetters(lazy, {
+ Color: "resource://gre/modules/Color.sys.mjs",
+});
ChromeUtils.defineLazyGetter(lazy, "logConsole", () =>
console.createInstance({
prefix: "RFPHelper",
@@ -155,7 +160,8 @@ class _RFPHelper {
Services.prefs.addObserver(kPrefResistFingerprinting, this);
Services.prefs.addObserver(kPrefLetterboxing, this);
Services.prefs.addObserver(kPrefLetterboxingVcenter, this);
- Services.prefs.addObserver(kPrefLetterboxingGradient, this);
+ Services.prefs.addObserver(kPrefVerticalTabs, this);
+ Services.obs.addObserver(this, kTopicFullscreenNavToolbox);
XPCOMUtils.defineLazyPreferenceGetter(
this,
@@ -188,9 +194,10 @@ class _RFPHelper {
// Remove unconditional observers
Services.prefs.removeObserver(kPrefResistFingerprinting, this);
- Services.prefs.removeObserver(kPrefLetterboxingGradient, this);
Services.prefs.removeObserver(kPrefLetterboxingVcenter, this);
Services.prefs.removeObserver(kPrefLetterboxing, this);
+ Services.prefs.removeObserver(kPrefVerticalTabs, this);
+ Services.obs.removeObserver(this, kTopicFullscreenNavToolbox);
// Remove the RFP observers, swallowing exceptions if they weren't present
this._removeLanguagePrefObservers();
}
@@ -212,6 +219,15 @@ class _RFPHelper {
case kTopicDOMWindowClosed:
this._handleDOMWindowClosed(subject);
break;
+ case kTopicFullscreenNavToolbox:
+ // The `subject` is the gNavToolbox.
+ // Record whether the toobox has been hidden when the browser (not
+ // content) is in fullscreen.
+ subject.ownerGlobal.gBrowser.tabbox.classList.toggle(
+ "letterboxing-nav-toolbox-hidden",
+ data === "hidden"
+ );
+ break;
default:
break;
}
@@ -226,6 +242,13 @@ class _RFPHelper {
resizeObserver.observe(browser.parentElement);
break;
}
+ case "nativethemechange":
+ // NOTE: "nativethemechange" seems to always be sent after
+ // "windowlwthemeupdate". So all the lwtheme CSS properties should be
+ // set to the new theme's values already, so we don't need to wait for
+ // windowlwthemeupdate.
+ this._updateLetterboxingColors(aMessage.currentTarget, true);
+ break;
default:
break;
}
@@ -245,9 +268,13 @@ class _RFPHelper {
Services.prefs.clearUserPref(kPrefLetterboxingDidForceSize);
// fall-through
case kPrefLetterboxingVcenter:
- case kPrefLetterboxingGradient:
this._handleLetterboxingPrefChanged();
break;
+ case kPrefVerticalTabs:
+ if (this.letterboxingEnabled) {
+ forEachWindow(win => this._updateLetterboxingColors(win));
+ }
+ break;
default:
break;
}
@@ -452,7 +479,7 @@ class _RFPHelper {
// If not already cached on the document object, traverse the CSSOM and
// find the rule applying the default letterboxing styles to browsers
// preemptively in order to beat race conditions on tab/window creation
- return (document._letterboxingMarginsRule ||= (() => {
+ return (document._letterboxingDefaultRule ||= (() => {
const LETTERBOX_CSS_SELECTOR = ".letterboxing";
const LETTERBOX_CSS_URL =
"chrome://global/content/resistfingerprinting/letterboxing.css";
@@ -688,26 +715,22 @@ class _RFPHelper {
if (lastRoundedSize) {
// Check whether the letterboxing margin is less than the border radius,
- // and if so flatten the borders.
- let borderRadius = parseInt(
- win
- .getComputedStyle(browserContainer)
- .getPropertyValue("--letterboxing-border-radius")
+ // and if so do not show an outline.
+ const gapVertical = parentHeight - lastRoundedSize.height;
+ const gapHorizontal = parentWidth - lastRoundedSize.width;
+ browserParent.classList.toggle(
+ "letterboxing-show-outline",
+ gapVertical >= this._letterboxingBorderRadius ||
+ gapHorizontal >= this._letterboxingBorderRadius
+ );
+ // When the Letterboxing area is top-aligned, only show the sidebar corner
+ // if there is enough horizontal space.
+ // The factor of 4 is from the horizontal centre-alignment and wanting
+ // enough space for twice the corner radius.
+ browserParent.classList.toggle(
+ "letterboxing-show-sidebar-corner",
+ gapHorizontal >= 4 * this._letterboxingBorderRadius
);
- if (
- borderRadius &&
- parentWidth - lastRoundedSize.width < borderRadius &&
- parentHeight - lastRoundedSize.height < borderRadius
- ) {
- borderRadius = 0;
- } else {
- borderRadius = "";
- }
- styleChanges.queueIfNeeded(browserParent, {
- "--letterboxing-decorator-visibility":
- borderRadius === 0 ? "hidden" : "",
- "--letterboxing-border-radius": borderRadius,
- });
if (win.gBrowser.selectedBrowser == aBrowser) {
const updateStatus = async args => {
win.XULBrowserWindow.letterboxingStatus = args
@@ -769,20 +792,31 @@ class _RFPHelper {
_resetContentSize(aBrowser) {
aBrowser.parentElement.classList.add("exclude-letterboxing");
+ aBrowser.parentElement.classList.remove(
+ "letterboxing-show-outline",
+ "letterboxing-show-sidebar-corner"
+ );
}
_updateSizeForTabsInWindow(aWindow) {
let tabBrowser = aWindow.gBrowser;
- tabBrowser.tabpanels?.classList.add("letterboxing");
- tabBrowser.tabpanels?.classList.toggle(
+ tabBrowser.tabbox.classList.add("letterboxing");
+ tabBrowser.tabbox.classList.toggle(
"letterboxing-vcenter",
Services.prefs.getBoolPref(kPrefLetterboxingVcenter, false)
);
- tabBrowser.tabpanels?.classList.toggle(
- "letterboxing-gradient",
- Services.prefs.getBoolPref(kPrefLetterboxingGradient, false)
- );
+ if (this._letterboxingBorderRadius === undefined && tabBrowser.tabbox) {
+ // Cache the value since it is not expected to change in a session for any
+ // window.
+ this._letterboxingBorderRadius = Math.ceil(
+ parseFloat(
+ aWindow
+ .getComputedStyle(tabBrowser.tabbox)
+ .getPropertyValue("--letterboxing-border-radius")
+ )
+ );
+ }
for (let tab of tabBrowser.tabs) {
let browser = tab.linkedBrowser;
@@ -791,7 +825,7 @@ class _RFPHelper {
// We need to add this class late because otherwise new windows get
// maximized.
aWindow.setTimeout(() => {
- tabBrowser.tabpanels?.classList.add("letterboxing-ready");
+ tabBrowser.tabbox.classList.add("letterboxing-ready");
if (!aWindow._rfpOriginalSize) {
this._recordWindowSize(aWindow);
}
@@ -869,6 +903,247 @@ class _RFPHelper {
this._resizeObservers.set(aWindow, resizeObserver);
// Rounding the content viewport.
this._updateSizeForTabsInWindow(aWindow);
+
+ this._updateLetterboxingColors(aWindow, true);
+ aWindow.addEventListener("nativethemechange", this);
+ }
+
+ /**
+ * Convert a CSS property to its RGBA value.
+ *
+ * @param {Window} win - The window for the element.
+ * @param {CSSStyleDeclaration} style - The computed style for the element we
+ * want to grab the color from.
+ * @param {string} property - The name of the property we want.
+ *
+ * @returns {InspectorRGBATuple} - The RGBA color. The "r", "g", "b" fields
+ * are relative to the 0-255 color range. The "a" field is in the 0-1 range.
+ */
+ _convertToRGBA(win, style, property) {
+ let cssColor = style.getPropertyValue(property);
+ if (!cssColor) {
+ lazy.logConsole.error(`Missing color "${property}"`);
+ return { r: 0, g: 0, b: 0, a: 0 };
+ }
+ const currentColorRegex =
+ /(^|[^a-zA-Z0-9_-])currentColor($|[^a-zA-Z0-9_-])/g;
+ if (currentColorRegex.test(cssColor)) {
+ const currentColor = style.color;
+ cssColor = cssColor.replace(currentColorRegex, (_, pre, post) => {
+ return pre + currentColor + post;
+ });
+ lazy.logConsole.debug(
+ "Replaced currentColor.",
+ property,
+ currentColor,
+ cssColor
+ );
+ }
+ /* Can drop the document argument after bugzilla bug 1973684 (142). */
+ const colorRGBA = win.InspectorUtils.colorToRGBA(cssColor, win.document);
+ if (!colorRGBA) {
+ lazy.logConsole.error(
+ `Failed to convert "${property}" color (${cssColor}) to RGBA`
+ );
+ return { r: 0, g: 0, b: 0, a: 0 };
+ }
+ return colorRGBA;
+ }
+
+ /**
+ * Compose two colors with alpha values on top of each other.
+ *
+ * @param {InspectorRGBATuple} topRGBA - The color to place on the top.
+ * @param {InspectorRGBATuple} bottomRGBA - The color to place on the bottom.
+ *
+ * @returns {InspectorRGBATuple} - The composed color.
+ */
+ _composeRGBA(topRGBA, bottomRGBA) {
+ const topA = Math.max(0, Math.min(1, topRGBA.a));
+ const bottomA = Math.max(0, Math.min(1, bottomRGBA.a));
+ const a = topA + bottomA - topA * bottomA; // Should be 1 if either is 1.
+ if (a === 0) {
+ return { r: 0, g: 0, b: 0, a };
+ }
+ const ret = { a };
+ for (const field of ["r", "g", "b"]) {
+ ret[field] =
+ (topRGBA[field] * topA + bottomRGBA[field] * bottomA * (1 - topA)) / a;
+ }
+ return ret;
+ }
+
+ /**
+ * Calculate the urlbar's container opaque background color, removing any
+ * transparency.
+ *
+ * @param {Window} win - The window to calculate the color for.
+ * @param {CSSStyleDeclaration} style - The computed style for the #nav-bar
+ * element.
+ *
+ * @returns {InspectorRGBATuple} - The calculated color, which will be opaque.
+ */
+ _calculateUrlbarContainerColor(win, style) {
+ let colorRGBA;
+ if (!Services.prefs.getBoolPref(kPrefVerticalTabs)) {
+ lazy.logConsole.debug("Toolbar background used.");
+ colorRGBA = this._convertToRGBA(win, style, "--toolbar-bgcolor");
+ if (colorRGBA.a === 1) {
+ return colorRGBA;
+ }
+ } else {
+ // The urlbar only has the toolbox colour.
+ colorRGBA = { r: 0, g: 0, b: 0, a: 0 };
+ }
+ let toolboxHasBackgroundImage = false;
+ const isLwTheme = win.document.documentElement.hasAttribute("lwtheme");
+ if (isLwTheme) {
+ for (const prop of ["--lwt-header-image", "--lwt-additional-images"]) {
+ const headerImage = style.getPropertyValue(prop);
+ if (headerImage && headerImage !== "none") {
+ // The theme sets a background image behind the urlbar. No easy way to
+ // derive a single colour from this.
+ toolboxHasBackgroundImage = true;
+ lazy.logConsole.debug(
+ "Toolbox has background image.",
+ prop,
+ headerImage
+ );
+ break;
+ }
+ }
+ }
+ if (!toolboxHasBackgroundImage) {
+ lazy.logConsole.debug("Toolbox background used.");
+ colorRGBA = this._composeRGBA(
+ colorRGBA,
+ this._convertToRGBA(win, style, "--toolbox-bgcolor")
+ );
+ if (colorRGBA.a === 1) {
+ return colorRGBA;
+ }
+ }
+
+ // Determine whether the urlbar is dark.
+ // At this point, the urlbar background has some transparency, likely on top
+ // of an image.
+ // We use the theme's text colour to figure out whether the urlbar
+ // background is overall meant to be light or dark. Unlike the urlbar, we
+ // expect this colour to be (almost) opaque.
+ const textRGBA = this._convertToRGBA(win, style, "--toolbar-field-color");
+ const textColor = new lazy.Color(textRGBA.r, textRGBA.g, textRGBA.b);
+ if (textColor.relativeLuminance >= 0.5) {
+ // Light text, so assume it has a dark background.
+ // Combine with a generic opaque dark colour. Copied from "frame" for the
+ // built-in dark theme.
+ lazy.logConsole.debug("Generic dark background used.");
+ const darkFrameRGBA = { r: 28, g: 27, b: 34, a: 1 };
+ return this._composeRGBA(colorRGBA, darkFrameRGBA);
+ }
+ // Combine with an opaque light colour. Copied from "frame" for the built-in
+ // light theme.
+ lazy.logConsole.debug("Generic light background used.");
+ const lightFrameRGBA = { r: 234, g: 234, b: 237, a: 1 };
+ return this._composeRGBA(colorRGBA, lightFrameRGBA);
+ }
+
+ /**
+ * Update the Letterboxing colors and related classes, or clear them if
+ * Letterboxing is not enabled.
+ *
+ * @param {Window} win - The window to update the colors for.
+ * @param {boolean} letterboxingEnabled - Whether Letterboxing is enabled.
+ */
+ _updateLetterboxingColors(win, letterboxingEnabled) {
+ let urlbarBackgroundRGBA;
+ let urlbarTextRGBA;
+ let contentSeparatorRGBA;
+ let urlbarBackgroundDark = false;
+ let lowBackgroundOutlineContrast = false;
+
+ if (letterboxingEnabled) {
+ // Want the effective colour of various elements without any alpha values
+ // so they can be used consistently.
+ const navbarStyle = win.getComputedStyle(
+ win.document.getElementById("nav-bar")
+ );
+ const containerRGBA = this._calculateUrlbarContainerColor(
+ win,
+ navbarStyle
+ );
+ urlbarBackgroundRGBA = this._composeRGBA(
+ this._convertToRGBA(
+ win,
+ navbarStyle,
+ "--toolbar-field-background-color"
+ ),
+ containerRGBA
+ );
+ urlbarTextRGBA = this._composeRGBA(
+ this._convertToRGBA(win, navbarStyle, "--toolbar-field-color"),
+ urlbarBackgroundRGBA
+ );
+ /* Separator between the urlbar container #nav-bar and the tabbox. */
+ const tabboxStyle = win.getComputedStyle(win.gBrowser.tabbox);
+ contentSeparatorRGBA = this._composeRGBA(
+ this._convertToRGBA(
+ win,
+ tabboxStyle,
+ "--chrome-content-separator-color"
+ ),
+ containerRGBA
+ );
+ const bgColor = new lazy.Color(
+ urlbarBackgroundRGBA.r,
+ urlbarBackgroundRGBA.g,
+ urlbarBackgroundRGBA.b
+ );
+ const outlineColor = new lazy.Color(
+ contentSeparatorRGBA.r,
+ contentSeparatorRGBA.g,
+ contentSeparatorRGBA.b
+ );
+ const contrastRatio = bgColor.contrastRatio(outlineColor);
+ lazy.logConsole.debug(
+ "Outline-background contrast ratio.",
+ contrastRatio
+ );
+ urlbarBackgroundDark = bgColor.relativeLuminance < 0.5;
+ /* Very low contrast ratio. For reference the default light theme has
+ * a contrast ratio of ~1.1. */
+ lowBackgroundOutlineContrast = contrastRatio < 1.05;
+ }
+ for (const { name, colorRGBA } of [
+ {
+ name: "--letterboxing-urlbar-text-color",
+ colorRGBA: urlbarTextRGBA,
+ },
+ {
+ name: "--letterboxing-urlbar-background-color",
+ colorRGBA: urlbarBackgroundRGBA,
+ },
+ {
+ name: "--letterboxing-content-separator-color",
+ colorRGBA: contentSeparatorRGBA,
+ },
+ ]) {
+ if (letterboxingEnabled) {
+ win.gBrowser.tabbox.style.setProperty(
+ name,
+ `rgb(${colorRGBA.r}, ${colorRGBA.g}, ${colorRGBA.b})`
+ );
+ } else {
+ win.gBrowser.tabbox.style.removeProperty(name);
+ }
+ }
+ win.gBrowser.tabbox.classList.toggle(
+ "letterboxing-urlbar-background-dark",
+ urlbarBackgroundDark
+ );
+ win.gBrowser.tabbox.classList.toggle(
+ "letterboxing-low-background-outline-contrast",
+ lowBackgroundOutlineContrast
+ );
}
_detachWindow(aWindow) {
@@ -886,7 +1161,7 @@ class _RFPHelper {
aWindow.removeEventListener("TabOpen", this);
// revert tabpanel's style to default
- tabBrowser.tabpanels?.classList.remove("letterboxing");
+ tabBrowser.tabbox.classList.remove("letterboxing");
// and restore default size on each browser element
for (let tab of tabBrowser.tabs) {
@@ -896,6 +1171,9 @@ class _RFPHelper {
aWindow.removeEventListener("dblclick", this._onWindowDoubleClick);
delete aWindow.shrinkToLetterbox;
aWindow.removeEventListener("sizemodechange", windowResizeHandler);
+
+ aWindow.removeEventListener("nativethemechange", this);
+ this._updateLetterboxingColors(aWindow, false);
}
_handleDOMWindowOpened(win) {
=====================================
toolkit/components/resistfingerprinting/content/letterboxing.css
=====================================
@@ -7,17 +7,106 @@
* RFPHelper.sys.mjs (LETTERBOX_CSS_SELECTOR and LETTERBOX_CSS_URL,
* respectively), where --letterboxing-width & --letterboxing-height are
* actually set.
+ * Keep this block first and separate to the rules that do not necessarily
+ * require --letterboxing-width or --letterboxing-height.
*/
.letterboxing {
- --letterboxing-bgcolor: var(--tabpanel-background-color);
- --letterboxing-border-radius: 8px;
- --letterboxing-border-top-radius: 0;
+ .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
+ width: var(--letterboxing-width) !important;
+ height: var(--letterboxing-height) !important;
+ }
+}
+
+#tabbrowser-tabbox.letterboxing {
+ --letterboxing-bgcolor: var(--background-color-canvas);
+ /* Match the border radius used for the sidebar. */
+ --letterboxing-border-radius: var(--border-radius-medium);
+ --letterboxing-border-radius-top: 0;
--letterboxing-vertical-alignment: start;
- --letterboxing-shadow-color: rgba(12, 12, 13, 0.10);
- --letterboxing-gradient-color1: var(--letterboxing-bgcolor);
- --letterboxing-gradient-color2: color-mix(in srgb, var(--chrome-content-separator-color) 50%, var(--letterboxing-bgcolor));
- --letterboxing-border-color: var(--letterboxing-bgcolor);
- --letterboxing-decorator-visibility: visible;
+ --letterboxing-shadow: none;
+ --letterboxing-outline-color: var(--border-color);
+ --letterboxing-outline-width: 1px;
+
+ @media not ((prefers-contrast) or (forced-colors)) {
+ /* Match the #sidebar outline width. */
+ --letterboxing-outline-width: 0.5px;
+ --letterboxing-shadow-color: rgba(58, 57, 68, 0.20);
+ --letterboxing-shadow: 0 2px 14px 0 var(--letterboxing-shadow-color);
+
+ /* Match the effective urlbar background colour. */
+ --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
+ /* Match the effective colour of the separator between the urlbar container
+ * and the content. */
+ --letterboxing-outline-color: var(--letterboxing-content-separator-color);
+
+ &.letterboxing-urlbar-background-dark {
+ --letterboxing-shadow-color: #15141a;
+ }
+
+ &.letterboxing-low-background-outline-contrast {
+ /* The default content separator colour has insufficient contrast. */
+ --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, black);
+
+ &.letterboxing-urlbar-background-dark {
+ /* Lighten the colour. */
+ --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, white);
+ }
+ }
+ }
+
+ @media (prefers-contrast) and (not (forced-colors)) {
+ :root[lwtheme] & {
+ /* User with prefers-contrast coming from the system settings, but also an
+ * installed theme. */
+ --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
+ /* Presumably a user with prefers-contrast and a custom theme has chosen
+ * a theme where the contrast between the urlbar and the text is
+ * sufficiently high or low. */
+ --letterboxing-outline-color: var(--letterboxing-urlbar-text-color);
+ }
+ }
+
+ background: var(--letterboxing-bgcolor);
+
+ &:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline) {
+ /* Letterboxing outline is visible for the current tab. Replace the usual
+ * outline to match the Letterboxing outline. For most scenarios, this
+ * should be mostly the same colour as when Letterboxing is not visible. But
+ * it may make a difference for some theme combinations. */
+ outline-color: var(--letterboxing-outline-color);
+ outline-width: var(--letterboxing-outline-width);
+ }
+
+ #tabbrowser-tabpanels {
+ /* Override the --tabpanel-background-color.
+ * Also, make sure this remains transparent, otherwise it will overlap the
+ * parent's corner's border-radius due to it's "position: relative" rule. */
+ /* TODO: FIX this for newtab pages. tor-browser#44085 */
+ background: transparent;
+ }
+
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media -moz-pref("sidebar.revamp") {
+ :root:not([inDOMFullscreen]) &[sidebar-shown]:not(.letterboxing-nav-toolbox-hidden):is(
+ /* When the Letterboxing area is aligned to the top, show the rounded
+ * corner if there is enough vertical space between the sidebar and the
+ * browser element, which is not rounded at the top. */
+ :not(.letterboxing-vcenter):has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-sidebar-corner),
+ /* When the Letterboxing area is aligned to the centre, show the rounded
+ * corner if the Letterboxing border is shown. */
+ .letterboxing-vcenter:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline)
+ ) {
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media -moz-pref("sidebar.position_start") {
+ border-start-start-radius: var(--letterboxing-border-radius);
+ }
+
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media not -moz-pref("sidebar.position_start") {
+ border-start-end-radius: var(--letterboxing-border-radius);
+ }
+ }
+ }
.browserContainer {
/*
@@ -26,101 +115,71 @@
* doesn't get notified on horizontal shrinking.
*/
overflow: hidden;
- background: var(--letterboxing-bgcolor);
}
- .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
- box-shadow: 0 4px 8px 0 var(--letterboxing-shadow-color);
- border-radius: var(--letterboxing-border-radius);
- border-top-left-radius: var(--letterboxing-border-top-radius);
- border-top-right-radius: var(--letterboxing-border-top-radius);
- width: var(--letterboxing-width) !important;
- height: var(--letterboxing-height) !important;
- background: var(--letterboxing-gradient-color2);
+ &.letterboxing-vcenter {
+ --letterboxing-border-radius-top: var(--letterboxing-border-radius);
+ --letterboxing-vertical-alignment: center;
}
}
-:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing) {
- place-content: start center;
-}
-
-.browserDecorator {
- display: none;
- pointer-events: none;
- background: transparent;
- position: relative;
- z-index: 1;
-}
+.browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
+ :root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready & {
+ place-content: var(--letterboxing-vertical-alignment) center;
+ }
-.letterboxing.letterboxing-vcenter .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
- --letterboxing-border-top-radius: var(--letterboxing-border-radius);
- --letterboxing-vertical-alignment: center;
-}
+ :root:not([inDOMFullscreen]) .letterboxing &.letterboxing-show-outline {
+ browser {
+ /* We use clip-path rather than border-radius because border-radius on its
+ * own leads to rendering artefacts in the corners (tested with GNOME).
+ * See tor-browser#44214 (comment 3262962). */
+ /* TODO: Use border-radius once bugzilla bug 1991874 is resolved. */
+ clip-path: rect(auto auto auto auto round var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius));
+ }
-.letterboxing.letterboxing-gradient .browserContainer {
- background: linear-gradient(283deg, var(--letterboxing-gradient-color1) 0%, var(--letterboxing-gradient-color2) 100%), var(--letterboxing-bgcolor);
-}
+ .browserDecorator {
+ /* Need a separate browserDecorator element because the clip-path on the
+ * browser would exclude the outline and box-shadow. */
+ /* TODO: Move these rules to the browser element once bugzilla bug 1991874
+ * is resolved, and drop browserDecorator. */
+ display: block;
+ border-radius: var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius);
+ /* NOTE: The top outline will not be visible when this is aligned to the
+ * top. */
+ outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
+ box-shadow: var(--letterboxing-shadow);
+ }
-:root:not([inDOMFullscreen]) .letterboxing .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing)
- > .browserDecorator {
- display: initial;
- visibility: var(--letterboxing-decorator-visibility);
- border-radius: var(--letterboxing-border-radius);
- border-top-left-radius: var(--letterboxing-border-top-radius);
- border-top-right-radius: var(--letterboxing-border-top-radius);
- box-shadow: var(--letterboxing-border-color) 0 0 .1px inset, var(--letterboxing-border-color) 0 0 .1px;
- border: .1px solid var(--letterboxing-border-color);
- outline: .1px solid var(--letterboxing-bgcolor);
- height: calc(var(--letterboxing-height) + 1px);
- top: -1px;
-}
+ #statuspanel:not([mirror]) #statuspanel-label {
+ border-end-start-radius: var(--letterboxing-border-radius);
+ }
-.letterboxing-vcenter .browserDecorator {
- height: auto !important;
- top: 0 !important;
-}
+ #statuspanel[mirror] #statuspanel-label {
+ border-end-end-radius: var(--letterboxing-border-radius);
+ }
+ }
-/*
- Align status bar with content.
- TODO: switch to nested CSS selectors for conciseness when available (Firefox >= 117)
-*/
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel:not([hidden]) {
- position: relative;
- place-self: end left;
- left: 0;
- right: 0;
- z-index: 2;
- --letterboxing-status-left-radius: var(--letterboxing-border-radius);
- --letterboxing-status-right-radius: 0;
-}
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel:not([mirror]):-moz-locale-dir(rtl),
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel[mirror]:-moz-locale-dir(ltr) {
- left: 0;
- right: 0;
- --letterboxing-status-right-radius: var(--letterboxing-border-radius);
- --letterboxing-status-left-radius: 0;
- justify-self: right;
-}
+ #statuspanel {
+ position: relative;
+ place-self: end start;
+ z-index: 2;
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
-#statuspanel-label {
- border-radius: 0 0 var(--letterboxing-status-right-radius) var(--letterboxing-status-left-radius);
- margin: 0;
- border: 1px solid var(--letterboxing-border-color);
- max-width: calc(var(--letterboxing-width) * .5);
-}
+ &[mirror] {
+ justify-self: end;
+ }
+ }
-browser:fullscreen {
- --letterboxing-border-top-radius: 0;
- --letterboxing-border-radius: 0;
+ #statuspanel-label {
+ margin: 0;
+ outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
+ max-width: calc(var(--letterboxing-width) * .5);
+ }
}
-:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing) {
- place-content: var(--letterboxing-vertical-alignment) center;
+.browserDecorator {
+ display: none;
+ pointer-events: none;
+ background: transparent;
+ position: relative;
+ z-index: 1;
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/42…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/42…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-140.4.0esr-15.0-1] 12 commits: fixup! BB 41919: Letterboxing, add temporarily visible web content-size...
by henry (ï¼ henry) 15 Oct '25
by henry (ï¼ henry) 15 Oct '25
15 Oct '25
henry pushed to branch base-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
a8d9aeef by Henry Wilkes at 2025-10-15T18:01:07+01:00
fixup! BB 41919: Letterboxing, add temporarily visible web content-size indicator on window resizing.
TB 44214: Fix letterboxing status indicator for RTL.
- - - - -
73862bbd by Henry Wilkes at 2025-10-15T18:01:08+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop unnecessary CSS rules.
- - - - -
09abf933 by Henry Wilkes at 2025-10-15T18:01:09+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS logical positions for the status panel, rather than
"left" and "right".
- - - - -
943bae35 by Henry Wilkes at 2025-10-15T18:01:09+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop upstream's rules for placing content.
- - - - -
9b4b135b by Henry Wilkes at 2025-10-15T18:01:10+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop letterboxing gradient.
- - - - -
4d9307d1 by Henry Wilkes at 2025-10-15T18:01:11+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Separate out the essential --letterboxing-width and
--letterboxing-height rules into their own .letterboxing block, to have
the property values set on.
- - - - -
e4d77eb2 by Henry Wilkes at 2025-10-15T18:01:12+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS nesting. Part 1.
- - - - -
261e8522 by Henry Wilkes at 2025-10-15T18:01:12+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS nesting. Part 2.
- - - - -
2282a161 by Henry Wilkes at 2025-10-15T18:01:13+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Move the letterboxing classes one element up from tabpanels to
tabbox.
This is because we need to restyle the tabbox.
- - - - -
f48a8536 by Henry Wilkes at 2025-10-15T18:01:14+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use a CSS class to show/hide the letterboxing border, rather
than setting the border-radius in javascript.
- - - - -
26d1b64a by Henry Wilkes at 2025-10-15T18:01:15+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Rename CSS variable from top-radius to radius-top. This is
closer to what upstream has done recently for tokens, where higher
specificity is appended.
- - - - -
940d5e2c by Henry Wilkes at 2025-10-15T18:01:15+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Update letterboxing styling for ESR 140.
- - - - -
4 changed files:
- browser/base/content/browser-fullScreenAndPointerLock.js
- browser/themes/shared/tabbrowser/content-area.css
- toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
- toolkit/components/resistfingerprinting/content/letterboxing.css
Changes:
=====================================
browser/base/content/browser-fullScreenAndPointerLock.js
=====================================
@@ -879,7 +879,13 @@ var FullScreen = {
}
this._isChromeCollapsed = false;
- Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "shown");
+ // Need a subject to know which window this applies to.
+ // Base browser patch can be dropped after bugzilla bug 1992036.
+ Services.obs.notifyObservers(
+ gNavToolbox,
+ "fullscreen-nav-toolbox",
+ "shown"
+ );
},
hideNavToolbox(aAnimate = false) {
@@ -943,7 +949,13 @@ var FullScreen = {
gNavToolbox.style.marginTop =
-gNavToolbox.getBoundingClientRect().height + "px";
this._isChromeCollapsed = true;
- Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "hidden");
+ // Need a subject to know which window this applies to.
+ // Base browser patch can be dropped after bugzilla bug 1880918.
+ Services.obs.notifyObservers(
+ gNavToolbox,
+ "fullscreen-nav-toolbox",
+ "hidden"
+ );
MousePosTracker.removeListener(this);
},
=====================================
browser/themes/shared/tabbrowser/content-area.css
=====================================
@@ -242,13 +242,17 @@
}
}
-#statuspanel[type=letterboxingStatus] > #statuspanel-label,
-#statuspanel[previoustype=letterboxingStatus][inactive] > #statuspanel-label {
+#statuspanel:is([type=letterboxingStatus], [previoustype=letterboxingStatus][inactive]) > #statuspanel-label {
background-image: url("chrome://browser/skin/window.svg");
background-size: 1em;
background-repeat: no-repeat;
- background-position-x: .5em;
background-position-y: center;
+ background-position-x: left .5em;
+
+ &:-moz-locale-dir(rtl) {
+ background-position-x: right .5em;
+ }
+
padding-inline-start: 2em;
-moz-context-properties: fill;
fill: var(--color-accent-primary);
=====================================
toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
=====================================
@@ -18,8 +18,6 @@ const kPrefLetterboxingTesting =
"privacy.resistFingerprinting.letterboxing.testing";
const kPrefLetterboxingVcenter =
"privacy.resistFingerprinting.letterboxing.vcenter";
-const kPrefLetterboxingGradient =
- "privacy.resistFingerprinting.letterboxing.gradient";
const kPrefLetterboxingDidForceSize =
"privacy.resistFingerprinting.letterboxing.didForceSize";
const kPrefLetterboxingRememberSize =
@@ -28,10 +26,17 @@ const kPrefLetterboxingRememberSize =
const kTopicDOMWindowOpened = "domwindowopened";
const kTopicDOMWindowClosed = "domwindowclosed";
+const kTopicFullscreenNavToolbox = "fullscreen-nav-toolbox";
+
const kPrefResizeWarnings = "privacy.resistFingerprinting.resizeWarnings";
+const kPrefVerticalTabs = "sidebar.verticalTabs";
+
const lazy = {};
+ChromeUtils.defineESModuleGetters(lazy, {
+ Color: "resource://gre/modules/Color.sys.mjs",
+});
ChromeUtils.defineLazyGetter(lazy, "logConsole", () =>
console.createInstance({
prefix: "RFPHelper",
@@ -155,7 +160,8 @@ class _RFPHelper {
Services.prefs.addObserver(kPrefResistFingerprinting, this);
Services.prefs.addObserver(kPrefLetterboxing, this);
Services.prefs.addObserver(kPrefLetterboxingVcenter, this);
- Services.prefs.addObserver(kPrefLetterboxingGradient, this);
+ Services.prefs.addObserver(kPrefVerticalTabs, this);
+ Services.obs.addObserver(this, kTopicFullscreenNavToolbox);
XPCOMUtils.defineLazyPreferenceGetter(
this,
@@ -188,9 +194,10 @@ class _RFPHelper {
// Remove unconditional observers
Services.prefs.removeObserver(kPrefResistFingerprinting, this);
- Services.prefs.removeObserver(kPrefLetterboxingGradient, this);
Services.prefs.removeObserver(kPrefLetterboxingVcenter, this);
Services.prefs.removeObserver(kPrefLetterboxing, this);
+ Services.prefs.removeObserver(kPrefVerticalTabs, this);
+ Services.obs.removeObserver(this, kTopicFullscreenNavToolbox);
// Remove the RFP observers, swallowing exceptions if they weren't present
this._removeLanguagePrefObservers();
}
@@ -212,6 +219,15 @@ class _RFPHelper {
case kTopicDOMWindowClosed:
this._handleDOMWindowClosed(subject);
break;
+ case kTopicFullscreenNavToolbox:
+ // The `subject` is the gNavToolbox.
+ // Record whether the toobox has been hidden when the browser (not
+ // content) is in fullscreen.
+ subject.ownerGlobal.gBrowser.tabbox.classList.toggle(
+ "letterboxing-nav-toolbox-hidden",
+ data === "hidden"
+ );
+ break;
default:
break;
}
@@ -226,6 +242,13 @@ class _RFPHelper {
resizeObserver.observe(browser.parentElement);
break;
}
+ case "nativethemechange":
+ // NOTE: "nativethemechange" seems to always be sent after
+ // "windowlwthemeupdate". So all the lwtheme CSS properties should be
+ // set to the new theme's values already, so we don't need to wait for
+ // windowlwthemeupdate.
+ this._updateLetterboxingColors(aMessage.currentTarget, true);
+ break;
default:
break;
}
@@ -245,9 +268,13 @@ class _RFPHelper {
Services.prefs.clearUserPref(kPrefLetterboxingDidForceSize);
// fall-through
case kPrefLetterboxingVcenter:
- case kPrefLetterboxingGradient:
this._handleLetterboxingPrefChanged();
break;
+ case kPrefVerticalTabs:
+ if (this.letterboxingEnabled) {
+ forEachWindow(win => this._updateLetterboxingColors(win));
+ }
+ break;
default:
break;
}
@@ -452,7 +479,7 @@ class _RFPHelper {
// If not already cached on the document object, traverse the CSSOM and
// find the rule applying the default letterboxing styles to browsers
// preemptively in order to beat race conditions on tab/window creation
- return (document._letterboxingMarginsRule ||= (() => {
+ return (document._letterboxingDefaultRule ||= (() => {
const LETTERBOX_CSS_SELECTOR = ".letterboxing";
const LETTERBOX_CSS_URL =
"chrome://global/content/resistfingerprinting/letterboxing.css";
@@ -688,26 +715,22 @@ class _RFPHelper {
if (lastRoundedSize) {
// Check whether the letterboxing margin is less than the border radius,
- // and if so flatten the borders.
- let borderRadius = parseInt(
- win
- .getComputedStyle(browserContainer)
- .getPropertyValue("--letterboxing-border-radius")
+ // and if so do not show an outline.
+ const gapVertical = parentHeight - lastRoundedSize.height;
+ const gapHorizontal = parentWidth - lastRoundedSize.width;
+ browserParent.classList.toggle(
+ "letterboxing-show-outline",
+ gapVertical >= this._letterboxingBorderRadius ||
+ gapHorizontal >= this._letterboxingBorderRadius
+ );
+ // When the Letterboxing area is top-aligned, only show the sidebar corner
+ // if there is enough horizontal space.
+ // The factor of 4 is from the horizontal centre-alignment and wanting
+ // enough space for twice the corner radius.
+ browserParent.classList.toggle(
+ "letterboxing-show-sidebar-corner",
+ gapHorizontal >= 4 * this._letterboxingBorderRadius
);
- if (
- borderRadius &&
- parentWidth - lastRoundedSize.width < borderRadius &&
- parentHeight - lastRoundedSize.height < borderRadius
- ) {
- borderRadius = 0;
- } else {
- borderRadius = "";
- }
- styleChanges.queueIfNeeded(browserParent, {
- "--letterboxing-decorator-visibility":
- borderRadius === 0 ? "hidden" : "",
- "--letterboxing-border-radius": borderRadius,
- });
if (win.gBrowser.selectedBrowser == aBrowser) {
const updateStatus = async args => {
win.XULBrowserWindow.letterboxingStatus = args
@@ -769,20 +792,31 @@ class _RFPHelper {
_resetContentSize(aBrowser) {
aBrowser.parentElement.classList.add("exclude-letterboxing");
+ aBrowser.parentElement.classList.remove(
+ "letterboxing-show-outline",
+ "letterboxing-show-sidebar-corner"
+ );
}
_updateSizeForTabsInWindow(aWindow) {
let tabBrowser = aWindow.gBrowser;
- tabBrowser.tabpanels?.classList.add("letterboxing");
- tabBrowser.tabpanels?.classList.toggle(
+ tabBrowser.tabbox.classList.add("letterboxing");
+ tabBrowser.tabbox.classList.toggle(
"letterboxing-vcenter",
Services.prefs.getBoolPref(kPrefLetterboxingVcenter, false)
);
- tabBrowser.tabpanels?.classList.toggle(
- "letterboxing-gradient",
- Services.prefs.getBoolPref(kPrefLetterboxingGradient, false)
- );
+ if (this._letterboxingBorderRadius === undefined && tabBrowser.tabbox) {
+ // Cache the value since it is not expected to change in a session for any
+ // window.
+ this._letterboxingBorderRadius = Math.ceil(
+ parseFloat(
+ aWindow
+ .getComputedStyle(tabBrowser.tabbox)
+ .getPropertyValue("--letterboxing-border-radius")
+ )
+ );
+ }
for (let tab of tabBrowser.tabs) {
let browser = tab.linkedBrowser;
@@ -791,7 +825,7 @@ class _RFPHelper {
// We need to add this class late because otherwise new windows get
// maximized.
aWindow.setTimeout(() => {
- tabBrowser.tabpanels?.classList.add("letterboxing-ready");
+ tabBrowser.tabbox.classList.add("letterboxing-ready");
if (!aWindow._rfpOriginalSize) {
this._recordWindowSize(aWindow);
}
@@ -869,6 +903,247 @@ class _RFPHelper {
this._resizeObservers.set(aWindow, resizeObserver);
// Rounding the content viewport.
this._updateSizeForTabsInWindow(aWindow);
+
+ this._updateLetterboxingColors(aWindow, true);
+ aWindow.addEventListener("nativethemechange", this);
+ }
+
+ /**
+ * Convert a CSS property to its RGBA value.
+ *
+ * @param {Window} win - The window for the element.
+ * @param {CSSStyleDeclaration} style - The computed style for the element we
+ * want to grab the color from.
+ * @param {string} property - The name of the property we want.
+ *
+ * @returns {InspectorRGBATuple} - The RGBA color. The "r", "g", "b" fields
+ * are relative to the 0-255 color range. The "a" field is in the 0-1 range.
+ */
+ _convertToRGBA(win, style, property) {
+ let cssColor = style.getPropertyValue(property);
+ if (!cssColor) {
+ lazy.logConsole.error(`Missing color "${property}"`);
+ return { r: 0, g: 0, b: 0, a: 0 };
+ }
+ const currentColorRegex =
+ /(^|[^a-zA-Z0-9_-])currentColor($|[^a-zA-Z0-9_-])/g;
+ if (currentColorRegex.test(cssColor)) {
+ const currentColor = style.color;
+ cssColor = cssColor.replace(currentColorRegex, (_, pre, post) => {
+ return pre + currentColor + post;
+ });
+ lazy.logConsole.debug(
+ "Replaced currentColor.",
+ property,
+ currentColor,
+ cssColor
+ );
+ }
+ /* Can drop the document argument after bugzilla bug 1973684 (142). */
+ const colorRGBA = win.InspectorUtils.colorToRGBA(cssColor, win.document);
+ if (!colorRGBA) {
+ lazy.logConsole.error(
+ `Failed to convert "${property}" color (${cssColor}) to RGBA`
+ );
+ return { r: 0, g: 0, b: 0, a: 0 };
+ }
+ return colorRGBA;
+ }
+
+ /**
+ * Compose two colors with alpha values on top of each other.
+ *
+ * @param {InspectorRGBATuple} topRGBA - The color to place on the top.
+ * @param {InspectorRGBATuple} bottomRGBA - The color to place on the bottom.
+ *
+ * @returns {InspectorRGBATuple} - The composed color.
+ */
+ _composeRGBA(topRGBA, bottomRGBA) {
+ const topA = Math.max(0, Math.min(1, topRGBA.a));
+ const bottomA = Math.max(0, Math.min(1, bottomRGBA.a));
+ const a = topA + bottomA - topA * bottomA; // Should be 1 if either is 1.
+ if (a === 0) {
+ return { r: 0, g: 0, b: 0, a };
+ }
+ const ret = { a };
+ for (const field of ["r", "g", "b"]) {
+ ret[field] =
+ (topRGBA[field] * topA + bottomRGBA[field] * bottomA * (1 - topA)) / a;
+ }
+ return ret;
+ }
+
+ /**
+ * Calculate the urlbar's container opaque background color, removing any
+ * transparency.
+ *
+ * @param {Window} win - The window to calculate the color for.
+ * @param {CSSStyleDeclaration} style - The computed style for the #nav-bar
+ * element.
+ *
+ * @returns {InspectorRGBATuple} - The calculated color, which will be opaque.
+ */
+ _calculateUrlbarContainerColor(win, style) {
+ let colorRGBA;
+ if (!Services.prefs.getBoolPref(kPrefVerticalTabs)) {
+ lazy.logConsole.debug("Toolbar background used.");
+ colorRGBA = this._convertToRGBA(win, style, "--toolbar-bgcolor");
+ if (colorRGBA.a === 1) {
+ return colorRGBA;
+ }
+ } else {
+ // The urlbar only has the toolbox colour.
+ colorRGBA = { r: 0, g: 0, b: 0, a: 0 };
+ }
+ let toolboxHasBackgroundImage = false;
+ const isLwTheme = win.document.documentElement.hasAttribute("lwtheme");
+ if (isLwTheme) {
+ for (const prop of ["--lwt-header-image", "--lwt-additional-images"]) {
+ const headerImage = style.getPropertyValue(prop);
+ if (headerImage && headerImage !== "none") {
+ // The theme sets a background image behind the urlbar. No easy way to
+ // derive a single colour from this.
+ toolboxHasBackgroundImage = true;
+ lazy.logConsole.debug(
+ "Toolbox has background image.",
+ prop,
+ headerImage
+ );
+ break;
+ }
+ }
+ }
+ if (!toolboxHasBackgroundImage) {
+ lazy.logConsole.debug("Toolbox background used.");
+ colorRGBA = this._composeRGBA(
+ colorRGBA,
+ this._convertToRGBA(win, style, "--toolbox-bgcolor")
+ );
+ if (colorRGBA.a === 1) {
+ return colorRGBA;
+ }
+ }
+
+ // Determine whether the urlbar is dark.
+ // At this point, the urlbar background has some transparency, likely on top
+ // of an image.
+ // We use the theme's text colour to figure out whether the urlbar
+ // background is overall meant to be light or dark. Unlike the urlbar, we
+ // expect this colour to be (almost) opaque.
+ const textRGBA = this._convertToRGBA(win, style, "--toolbar-field-color");
+ const textColor = new lazy.Color(textRGBA.r, textRGBA.g, textRGBA.b);
+ if (textColor.relativeLuminance >= 0.5) {
+ // Light text, so assume it has a dark background.
+ // Combine with a generic opaque dark colour. Copied from "frame" for the
+ // built-in dark theme.
+ lazy.logConsole.debug("Generic dark background used.");
+ const darkFrameRGBA = { r: 28, g: 27, b: 34, a: 1 };
+ return this._composeRGBA(colorRGBA, darkFrameRGBA);
+ }
+ // Combine with an opaque light colour. Copied from "frame" for the built-in
+ // light theme.
+ lazy.logConsole.debug("Generic light background used.");
+ const lightFrameRGBA = { r: 234, g: 234, b: 237, a: 1 };
+ return this._composeRGBA(colorRGBA, lightFrameRGBA);
+ }
+
+ /**
+ * Update the Letterboxing colors and related classes, or clear them if
+ * Letterboxing is not enabled.
+ *
+ * @param {Window} win - The window to update the colors for.
+ * @param {boolean} letterboxingEnabled - Whether Letterboxing is enabled.
+ */
+ _updateLetterboxingColors(win, letterboxingEnabled) {
+ let urlbarBackgroundRGBA;
+ let urlbarTextRGBA;
+ let contentSeparatorRGBA;
+ let urlbarBackgroundDark = false;
+ let lowBackgroundOutlineContrast = false;
+
+ if (letterboxingEnabled) {
+ // Want the effective colour of various elements without any alpha values
+ // so they can be used consistently.
+ const navbarStyle = win.getComputedStyle(
+ win.document.getElementById("nav-bar")
+ );
+ const containerRGBA = this._calculateUrlbarContainerColor(
+ win,
+ navbarStyle
+ );
+ urlbarBackgroundRGBA = this._composeRGBA(
+ this._convertToRGBA(
+ win,
+ navbarStyle,
+ "--toolbar-field-background-color"
+ ),
+ containerRGBA
+ );
+ urlbarTextRGBA = this._composeRGBA(
+ this._convertToRGBA(win, navbarStyle, "--toolbar-field-color"),
+ urlbarBackgroundRGBA
+ );
+ /* Separator between the urlbar container #nav-bar and the tabbox. */
+ const tabboxStyle = win.getComputedStyle(win.gBrowser.tabbox);
+ contentSeparatorRGBA = this._composeRGBA(
+ this._convertToRGBA(
+ win,
+ tabboxStyle,
+ "--chrome-content-separator-color"
+ ),
+ containerRGBA
+ );
+ const bgColor = new lazy.Color(
+ urlbarBackgroundRGBA.r,
+ urlbarBackgroundRGBA.g,
+ urlbarBackgroundRGBA.b
+ );
+ const outlineColor = new lazy.Color(
+ contentSeparatorRGBA.r,
+ contentSeparatorRGBA.g,
+ contentSeparatorRGBA.b
+ );
+ const contrastRatio = bgColor.contrastRatio(outlineColor);
+ lazy.logConsole.debug(
+ "Outline-background contrast ratio.",
+ contrastRatio
+ );
+ urlbarBackgroundDark = bgColor.relativeLuminance < 0.5;
+ /* Very low contrast ratio. For reference the default light theme has
+ * a contrast ratio of ~1.1. */
+ lowBackgroundOutlineContrast = contrastRatio < 1.05;
+ }
+ for (const { name, colorRGBA } of [
+ {
+ name: "--letterboxing-urlbar-text-color",
+ colorRGBA: urlbarTextRGBA,
+ },
+ {
+ name: "--letterboxing-urlbar-background-color",
+ colorRGBA: urlbarBackgroundRGBA,
+ },
+ {
+ name: "--letterboxing-content-separator-color",
+ colorRGBA: contentSeparatorRGBA,
+ },
+ ]) {
+ if (letterboxingEnabled) {
+ win.gBrowser.tabbox.style.setProperty(
+ name,
+ `rgb(${colorRGBA.r}, ${colorRGBA.g}, ${colorRGBA.b})`
+ );
+ } else {
+ win.gBrowser.tabbox.style.removeProperty(name);
+ }
+ }
+ win.gBrowser.tabbox.classList.toggle(
+ "letterboxing-urlbar-background-dark",
+ urlbarBackgroundDark
+ );
+ win.gBrowser.tabbox.classList.toggle(
+ "letterboxing-low-background-outline-contrast",
+ lowBackgroundOutlineContrast
+ );
}
_detachWindow(aWindow) {
@@ -886,7 +1161,7 @@ class _RFPHelper {
aWindow.removeEventListener("TabOpen", this);
// revert tabpanel's style to default
- tabBrowser.tabpanels?.classList.remove("letterboxing");
+ tabBrowser.tabbox.classList.remove("letterboxing");
// and restore default size on each browser element
for (let tab of tabBrowser.tabs) {
@@ -896,6 +1171,9 @@ class _RFPHelper {
aWindow.removeEventListener("dblclick", this._onWindowDoubleClick);
delete aWindow.shrinkToLetterbox;
aWindow.removeEventListener("sizemodechange", windowResizeHandler);
+
+ aWindow.removeEventListener("nativethemechange", this);
+ this._updateLetterboxingColors(aWindow, false);
}
_handleDOMWindowOpened(win) {
=====================================
toolkit/components/resistfingerprinting/content/letterboxing.css
=====================================
@@ -7,17 +7,106 @@
* RFPHelper.sys.mjs (LETTERBOX_CSS_SELECTOR and LETTERBOX_CSS_URL,
* respectively), where --letterboxing-width & --letterboxing-height are
* actually set.
+ * Keep this block first and separate to the rules that do not necessarily
+ * require --letterboxing-width or --letterboxing-height.
*/
.letterboxing {
- --letterboxing-bgcolor: var(--tabpanel-background-color);
- --letterboxing-border-radius: 8px;
- --letterboxing-border-top-radius: 0;
+ .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
+ width: var(--letterboxing-width) !important;
+ height: var(--letterboxing-height) !important;
+ }
+}
+
+#tabbrowser-tabbox.letterboxing {
+ --letterboxing-bgcolor: var(--background-color-canvas);
+ /* Match the border radius used for the sidebar. */
+ --letterboxing-border-radius: var(--border-radius-medium);
+ --letterboxing-border-radius-top: 0;
--letterboxing-vertical-alignment: start;
- --letterboxing-shadow-color: rgba(12, 12, 13, 0.10);
- --letterboxing-gradient-color1: var(--letterboxing-bgcolor);
- --letterboxing-gradient-color2: color-mix(in srgb, var(--chrome-content-separator-color) 50%, var(--letterboxing-bgcolor));
- --letterboxing-border-color: var(--letterboxing-bgcolor);
- --letterboxing-decorator-visibility: visible;
+ --letterboxing-shadow: none;
+ --letterboxing-outline-color: var(--border-color);
+ --letterboxing-outline-width: 1px;
+
+ @media not ((prefers-contrast) or (forced-colors)) {
+ /* Match the #sidebar outline width. */
+ --letterboxing-outline-width: 0.5px;
+ --letterboxing-shadow-color: rgba(58, 57, 68, 0.20);
+ --letterboxing-shadow: 0 2px 14px 0 var(--letterboxing-shadow-color);
+
+ /* Match the effective urlbar background colour. */
+ --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
+ /* Match the effective colour of the separator between the urlbar container
+ * and the content. */
+ --letterboxing-outline-color: var(--letterboxing-content-separator-color);
+
+ &.letterboxing-urlbar-background-dark {
+ --letterboxing-shadow-color: #15141a;
+ }
+
+ &.letterboxing-low-background-outline-contrast {
+ /* The default content separator colour has insufficient contrast. */
+ --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, black);
+
+ &.letterboxing-urlbar-background-dark {
+ /* Lighten the colour. */
+ --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, white);
+ }
+ }
+ }
+
+ @media (prefers-contrast) and (not (forced-colors)) {
+ :root[lwtheme] & {
+ /* User with prefers-contrast coming from the system settings, but also an
+ * installed theme. */
+ --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
+ /* Presumably a user with prefers-contrast and a custom theme has chosen
+ * a theme where the contrast between the urlbar and the text is
+ * sufficiently high or low. */
+ --letterboxing-outline-color: var(--letterboxing-urlbar-text-color);
+ }
+ }
+
+ background: var(--letterboxing-bgcolor);
+
+ &:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline) {
+ /* Letterboxing outline is visible for the current tab. Replace the usual
+ * outline to match the Letterboxing outline. For most scenarios, this
+ * should be mostly the same colour as when Letterboxing is not visible. But
+ * it may make a difference for some theme combinations. */
+ outline-color: var(--letterboxing-outline-color);
+ outline-width: var(--letterboxing-outline-width);
+ }
+
+ #tabbrowser-tabpanels {
+ /* Override the --tabpanel-background-color.
+ * Also, make sure this remains transparent, otherwise it will overlap the
+ * parent's corner's border-radius due to it's "position: relative" rule. */
+ /* TODO: FIX this for newtab pages. tor-browser#44085 */
+ background: transparent;
+ }
+
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media -moz-pref("sidebar.revamp") {
+ :root:not([inDOMFullscreen]) &[sidebar-shown]:not(.letterboxing-nav-toolbox-hidden):is(
+ /* When the Letterboxing area is aligned to the top, show the rounded
+ * corner if there is enough vertical space between the sidebar and the
+ * browser element, which is not rounded at the top. */
+ :not(.letterboxing-vcenter):has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-sidebar-corner),
+ /* When the Letterboxing area is aligned to the centre, show the rounded
+ * corner if the Letterboxing border is shown. */
+ .letterboxing-vcenter:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline)
+ ) {
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media -moz-pref("sidebar.position_start") {
+ border-start-start-radius: var(--letterboxing-border-radius);
+ }
+
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media not -moz-pref("sidebar.position_start") {
+ border-start-end-radius: var(--letterboxing-border-radius);
+ }
+ }
+ }
.browserContainer {
/*
@@ -26,101 +115,71 @@
* doesn't get notified on horizontal shrinking.
*/
overflow: hidden;
- background: var(--letterboxing-bgcolor);
}
- .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
- box-shadow: 0 4px 8px 0 var(--letterboxing-shadow-color);
- border-radius: var(--letterboxing-border-radius);
- border-top-left-radius: var(--letterboxing-border-top-radius);
- border-top-right-radius: var(--letterboxing-border-top-radius);
- width: var(--letterboxing-width) !important;
- height: var(--letterboxing-height) !important;
- background: var(--letterboxing-gradient-color2);
+ &.letterboxing-vcenter {
+ --letterboxing-border-radius-top: var(--letterboxing-border-radius);
+ --letterboxing-vertical-alignment: center;
}
}
-:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing) {
- place-content: start center;
-}
-
-.browserDecorator {
- display: none;
- pointer-events: none;
- background: transparent;
- position: relative;
- z-index: 1;
-}
+.browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
+ :root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready & {
+ place-content: var(--letterboxing-vertical-alignment) center;
+ }
-.letterboxing.letterboxing-vcenter .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
- --letterboxing-border-top-radius: var(--letterboxing-border-radius);
- --letterboxing-vertical-alignment: center;
-}
+ :root:not([inDOMFullscreen]) .letterboxing &.letterboxing-show-outline {
+ browser {
+ /* We use clip-path rather than border-radius because border-radius on its
+ * own leads to rendering artefacts in the corners (tested with GNOME).
+ * See tor-browser#44214 (comment 3262962). */
+ /* TODO: Use border-radius once bugzilla bug 1991874 is resolved. */
+ clip-path: rect(auto auto auto auto round var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius));
+ }
-.letterboxing.letterboxing-gradient .browserContainer {
- background: linear-gradient(283deg, var(--letterboxing-gradient-color1) 0%, var(--letterboxing-gradient-color2) 100%), var(--letterboxing-bgcolor);
-}
+ .browserDecorator {
+ /* Need a separate browserDecorator element because the clip-path on the
+ * browser would exclude the outline and box-shadow. */
+ /* TODO: Move these rules to the browser element once bugzilla bug 1991874
+ * is resolved, and drop browserDecorator. */
+ display: block;
+ border-radius: var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius);
+ /* NOTE: The top outline will not be visible when this is aligned to the
+ * top. */
+ outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
+ box-shadow: var(--letterboxing-shadow);
+ }
-:root:not([inDOMFullscreen]) .letterboxing .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing)
- > .browserDecorator {
- display: initial;
- visibility: var(--letterboxing-decorator-visibility);
- border-radius: var(--letterboxing-border-radius);
- border-top-left-radius: var(--letterboxing-border-top-radius);
- border-top-right-radius: var(--letterboxing-border-top-radius);
- box-shadow: var(--letterboxing-border-color) 0 0 .1px inset, var(--letterboxing-border-color) 0 0 .1px;
- border: .1px solid var(--letterboxing-border-color);
- outline: .1px solid var(--letterboxing-bgcolor);
- height: calc(var(--letterboxing-height) + 1px);
- top: -1px;
-}
+ #statuspanel:not([mirror]) #statuspanel-label {
+ border-end-start-radius: var(--letterboxing-border-radius);
+ }
-.letterboxing-vcenter .browserDecorator {
- height: auto !important;
- top: 0 !important;
-}
+ #statuspanel[mirror] #statuspanel-label {
+ border-end-end-radius: var(--letterboxing-border-radius);
+ }
+ }
-/*
- Align status bar with content.
- TODO: switch to nested CSS selectors for conciseness when available (Firefox >= 117)
-*/
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel:not([hidden]) {
- position: relative;
- place-self: end left;
- left: 0;
- right: 0;
- z-index: 2;
- --letterboxing-status-left-radius: var(--letterboxing-border-radius);
- --letterboxing-status-right-radius: 0;
-}
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel:not([mirror]):-moz-locale-dir(rtl),
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel[mirror]:-moz-locale-dir(ltr) {
- left: 0;
- right: 0;
- --letterboxing-status-right-radius: var(--letterboxing-border-radius);
- --letterboxing-status-left-radius: 0;
- justify-self: right;
-}
+ #statuspanel {
+ position: relative;
+ place-self: end start;
+ z-index: 2;
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
-#statuspanel-label {
- border-radius: 0 0 var(--letterboxing-status-right-radius) var(--letterboxing-status-left-radius);
- margin: 0;
- border: 1px solid var(--letterboxing-border-color);
- max-width: calc(var(--letterboxing-width) * .5);
-}
+ &[mirror] {
+ justify-self: end;
+ }
+ }
-browser:fullscreen {
- --letterboxing-border-top-radius: 0;
- --letterboxing-border-radius: 0;
+ #statuspanel-label {
+ margin: 0;
+ outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
+ max-width: calc(var(--letterboxing-width) * .5);
+ }
}
-:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing) {
- place-content: var(--letterboxing-vertical-alignment) center;
+.browserDecorator {
+ display: none;
+ pointer-events: none;
+ background: transparent;
+ position: relative;
+ z-index: 1;
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/29c65a…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/29c65a…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.4.0esr-15.0-1] 13 commits: dropme! fixup! TB 41917: Change letterboxing styling for Tor Browser.
by henry (ï¼ henry) 15 Oct '25
by henry (ï¼ henry) 15 Oct '25
15 Oct '25
henry pushed to branch tor-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
0dddcb33 by Henry Wilkes at 2025-10-15T15:59:48+01:00
dropme! fixup! TB 41917: Change letterboxing styling for Tor Browser.
TB 44214: Drop letterboxing changes for Tor Browser only.
The commit "TB 41917: Change letterboxing styling for Tor Browser."
should be entirely dropped.
- - - - -
fdc52857 by Henry Wilkes at 2025-10-15T15:59:49+01:00
fixup! BB 41919: Letterboxing, add temporarily visible web content-size indicator on window resizing.
TB 44214: Fix letterboxing status indicator for RTL.
- - - - -
f00744fe by Henry Wilkes at 2025-10-15T15:59:50+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop unnecessary CSS rules.
- - - - -
805650c4 by Henry Wilkes at 2025-10-15T15:59:51+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS logical positions for the status panel, rather than
"left" and "right".
- - - - -
bfe8d56b by Henry Wilkes at 2025-10-15T15:59:52+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop upstream's rules for placing content.
- - - - -
b8a35ecc by Henry Wilkes at 2025-10-15T15:59:53+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Drop letterboxing gradient.
- - - - -
999bb9f2 by Henry Wilkes at 2025-10-15T15:59:53+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Separate out the essential --letterboxing-width and
--letterboxing-height rules into their own .letterboxing block, to have
the property values set on.
- - - - -
31b90c2e by Henry Wilkes at 2025-10-15T15:59:54+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS nesting. Part 1.
- - - - -
58d4acdc by Henry Wilkes at 2025-10-15T15:59:55+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use CSS nesting. Part 2.
- - - - -
317b197e by Henry Wilkes at 2025-10-15T15:59:56+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Move the letterboxing classes one element up from tabpanels to
tabbox.
This is because we need to restyle the tabbox.
- - - - -
cb287829 by Henry Wilkes at 2025-10-15T15:59:57+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Use a CSS class to show/hide the letterboxing border, rather
than setting the border-radius in javascript.
- - - - -
ff6fdbef by Henry Wilkes at 2025-10-15T15:59:58+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Rename CSS variable from top-radius to radius-top. This is
closer to what upstream has done recently for tokens, where higher
specificity is appended.
- - - - -
196110ba by Henry Wilkes at 2025-10-15T17:19:07+01:00
fixup! BB 32308: Use direct browser sizing for letterboxing.
TB 44214: Update letterboxing styling for ESR 140.
- - - - -
4 changed files:
- browser/base/content/browser-fullScreenAndPointerLock.js
- browser/themes/shared/tabbrowser/content-area.css
- toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
- toolkit/components/resistfingerprinting/content/letterboxing.css
Changes:
=====================================
browser/base/content/browser-fullScreenAndPointerLock.js
=====================================
@@ -879,7 +879,13 @@ var FullScreen = {
}
this._isChromeCollapsed = false;
- Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "shown");
+ // Need a subject to know which window this applies to.
+ // Base browser patch can be dropped after bugzilla bug 1992036.
+ Services.obs.notifyObservers(
+ gNavToolbox,
+ "fullscreen-nav-toolbox",
+ "shown"
+ );
},
hideNavToolbox(aAnimate = false) {
@@ -943,7 +949,13 @@ var FullScreen = {
gNavToolbox.style.marginTop =
-gNavToolbox.getBoundingClientRect().height + "px";
this._isChromeCollapsed = true;
- Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "hidden");
+ // Need a subject to know which window this applies to.
+ // Base browser patch can be dropped after bugzilla bug 1880918.
+ Services.obs.notifyObservers(
+ gNavToolbox,
+ "fullscreen-nav-toolbox",
+ "hidden"
+ );
MousePosTracker.removeListener(this);
},
=====================================
browser/themes/shared/tabbrowser/content-area.css
=====================================
@@ -242,13 +242,17 @@
}
}
-#statuspanel[type=letterboxingStatus] > #statuspanel-label,
-#statuspanel[previoustype=letterboxingStatus][inactive] > #statuspanel-label {
+#statuspanel:is([type=letterboxingStatus], [previoustype=letterboxingStatus][inactive]) > #statuspanel-label {
background-image: url("chrome://browser/skin/window.svg");
background-size: 1em;
background-repeat: no-repeat;
- background-position-x: .5em;
background-position-y: center;
+ background-position-x: left .5em;
+
+ &:-moz-locale-dir(rtl) {
+ background-position-x: right .5em;
+ }
+
padding-inline-start: 2em;
-moz-context-properties: fill;
fill: var(--color-accent-primary);
=====================================
toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
=====================================
@@ -18,8 +18,6 @@ const kPrefLetterboxingTesting =
"privacy.resistFingerprinting.letterboxing.testing";
const kPrefLetterboxingVcenter =
"privacy.resistFingerprinting.letterboxing.vcenter";
-const kPrefLetterboxingGradient =
- "privacy.resistFingerprinting.letterboxing.gradient";
const kPrefLetterboxingDidForceSize =
"privacy.resistFingerprinting.letterboxing.didForceSize";
const kPrefLetterboxingRememberSize =
@@ -28,10 +26,17 @@ const kPrefLetterboxingRememberSize =
const kTopicDOMWindowOpened = "domwindowopened";
const kTopicDOMWindowClosed = "domwindowclosed";
+const kTopicFullscreenNavToolbox = "fullscreen-nav-toolbox";
+
const kPrefResizeWarnings = "privacy.resistFingerprinting.resizeWarnings";
+const kPrefVerticalTabs = "sidebar.verticalTabs";
+
const lazy = {};
+ChromeUtils.defineESModuleGetters(lazy, {
+ Color: "resource://gre/modules/Color.sys.mjs",
+});
ChromeUtils.defineLazyGetter(lazy, "logConsole", () =>
console.createInstance({
prefix: "RFPHelper",
@@ -155,7 +160,8 @@ class _RFPHelper {
Services.prefs.addObserver(kPrefResistFingerprinting, this);
Services.prefs.addObserver(kPrefLetterboxing, this);
Services.prefs.addObserver(kPrefLetterboxingVcenter, this);
- Services.prefs.addObserver(kPrefLetterboxingGradient, this);
+ Services.prefs.addObserver(kPrefVerticalTabs, this);
+ Services.obs.addObserver(this, kTopicFullscreenNavToolbox);
XPCOMUtils.defineLazyPreferenceGetter(
this,
@@ -188,9 +194,10 @@ class _RFPHelper {
// Remove unconditional observers
Services.prefs.removeObserver(kPrefResistFingerprinting, this);
- Services.prefs.removeObserver(kPrefLetterboxingGradient, this);
Services.prefs.removeObserver(kPrefLetterboxingVcenter, this);
Services.prefs.removeObserver(kPrefLetterboxing, this);
+ Services.prefs.removeObserver(kPrefVerticalTabs, this);
+ Services.obs.removeObserver(this, kTopicFullscreenNavToolbox);
// Remove the RFP observers, swallowing exceptions if they weren't present
this._removeLanguagePrefObservers();
}
@@ -212,6 +219,15 @@ class _RFPHelper {
case kTopicDOMWindowClosed:
this._handleDOMWindowClosed(subject);
break;
+ case kTopicFullscreenNavToolbox:
+ // The `subject` is the gNavToolbox.
+ // Record whether the toobox has been hidden when the browser (not
+ // content) is in fullscreen.
+ subject.ownerGlobal.gBrowser.tabbox.classList.toggle(
+ "letterboxing-nav-toolbox-hidden",
+ data === "hidden"
+ );
+ break;
default:
break;
}
@@ -226,6 +242,13 @@ class _RFPHelper {
resizeObserver.observe(browser.parentElement);
break;
}
+ case "nativethemechange":
+ // NOTE: "nativethemechange" seems to always be sent after
+ // "windowlwthemeupdate". So all the lwtheme CSS properties should be
+ // set to the new theme's values already, so we don't need to wait for
+ // windowlwthemeupdate.
+ this._updateLetterboxingColors(aMessage.currentTarget, true);
+ break;
default:
break;
}
@@ -245,9 +268,13 @@ class _RFPHelper {
Services.prefs.clearUserPref(kPrefLetterboxingDidForceSize);
// fall-through
case kPrefLetterboxingVcenter:
- case kPrefLetterboxingGradient:
this._handleLetterboxingPrefChanged();
break;
+ case kPrefVerticalTabs:
+ if (this.letterboxingEnabled) {
+ forEachWindow(win => this._updateLetterboxingColors(win));
+ }
+ break;
default:
break;
}
@@ -452,7 +479,7 @@ class _RFPHelper {
// If not already cached on the document object, traverse the CSSOM and
// find the rule applying the default letterboxing styles to browsers
// preemptively in order to beat race conditions on tab/window creation
- return (document._letterboxingMarginsRule ||= (() => {
+ return (document._letterboxingDefaultRule ||= (() => {
const LETTERBOX_CSS_SELECTOR = ".letterboxing";
const LETTERBOX_CSS_URL =
"chrome://global/content/resistfingerprinting/letterboxing.css";
@@ -688,26 +715,22 @@ class _RFPHelper {
if (lastRoundedSize) {
// Check whether the letterboxing margin is less than the border radius,
- // and if so flatten the borders.
- let borderRadius = parseInt(
- win
- .getComputedStyle(browserContainer)
- .getPropertyValue("--letterboxing-border-radius")
+ // and if so do not show an outline.
+ const gapVertical = parentHeight - lastRoundedSize.height;
+ const gapHorizontal = parentWidth - lastRoundedSize.width;
+ browserParent.classList.toggle(
+ "letterboxing-show-outline",
+ gapVertical >= this._letterboxingBorderRadius ||
+ gapHorizontal >= this._letterboxingBorderRadius
+ );
+ // When the Letterboxing area is top-aligned, only show the sidebar corner
+ // if there is enough horizontal space.
+ // The factor of 4 is from the horizontal centre-alignment and wanting
+ // enough space for twice the corner radius.
+ browserParent.classList.toggle(
+ "letterboxing-show-sidebar-corner",
+ gapHorizontal >= 4 * this._letterboxingBorderRadius
);
- if (
- borderRadius &&
- parentWidth - lastRoundedSize.width < borderRadius &&
- parentHeight - lastRoundedSize.height < borderRadius
- ) {
- borderRadius = 0;
- } else {
- borderRadius = "";
- }
- styleChanges.queueIfNeeded(browserParent, {
- "--letterboxing-decorator-visibility":
- borderRadius === 0 ? "hidden" : "",
- "--letterboxing-border-radius": borderRadius,
- });
if (win.gBrowser.selectedBrowser == aBrowser) {
const updateStatus = async args => {
win.XULBrowserWindow.letterboxingStatus = args
@@ -769,20 +792,31 @@ class _RFPHelper {
_resetContentSize(aBrowser) {
aBrowser.parentElement.classList.add("exclude-letterboxing");
+ aBrowser.parentElement.classList.remove(
+ "letterboxing-show-outline",
+ "letterboxing-show-sidebar-corner"
+ );
}
_updateSizeForTabsInWindow(aWindow) {
let tabBrowser = aWindow.gBrowser;
- tabBrowser.tabpanels?.classList.add("letterboxing");
- tabBrowser.tabpanels?.classList.toggle(
+ tabBrowser.tabbox.classList.add("letterboxing");
+ tabBrowser.tabbox.classList.toggle(
"letterboxing-vcenter",
Services.prefs.getBoolPref(kPrefLetterboxingVcenter, false)
);
- tabBrowser.tabpanels?.classList.toggle(
- "letterboxing-gradient",
- Services.prefs.getBoolPref(kPrefLetterboxingGradient, false)
- );
+ if (this._letterboxingBorderRadius === undefined && tabBrowser.tabbox) {
+ // Cache the value since it is not expected to change in a session for any
+ // window.
+ this._letterboxingBorderRadius = Math.ceil(
+ parseFloat(
+ aWindow
+ .getComputedStyle(tabBrowser.tabbox)
+ .getPropertyValue("--letterboxing-border-radius")
+ )
+ );
+ }
for (let tab of tabBrowser.tabs) {
let browser = tab.linkedBrowser;
@@ -791,7 +825,7 @@ class _RFPHelper {
// We need to add this class late because otherwise new windows get
// maximized.
aWindow.setTimeout(() => {
- tabBrowser.tabpanels?.classList.add("letterboxing-ready");
+ tabBrowser.tabbox.classList.add("letterboxing-ready");
if (!aWindow._rfpOriginalSize) {
this._recordWindowSize(aWindow);
}
@@ -869,6 +903,247 @@ class _RFPHelper {
this._resizeObservers.set(aWindow, resizeObserver);
// Rounding the content viewport.
this._updateSizeForTabsInWindow(aWindow);
+
+ this._updateLetterboxingColors(aWindow, true);
+ aWindow.addEventListener("nativethemechange", this);
+ }
+
+ /**
+ * Convert a CSS property to its RGBA value.
+ *
+ * @param {Window} win - The window for the element.
+ * @param {CSSStyleDeclaration} style - The computed style for the element we
+ * want to grab the color from.
+ * @param {string} property - The name of the property we want.
+ *
+ * @returns {InspectorRGBATuple} - The RGBA color. The "r", "g", "b" fields
+ * are relative to the 0-255 color range. The "a" field is in the 0-1 range.
+ */
+ _convertToRGBA(win, style, property) {
+ let cssColor = style.getPropertyValue(property);
+ if (!cssColor) {
+ lazy.logConsole.error(`Missing color "${property}"`);
+ return { r: 0, g: 0, b: 0, a: 0 };
+ }
+ const currentColorRegex =
+ /(^|[^a-zA-Z0-9_-])currentColor($|[^a-zA-Z0-9_-])/g;
+ if (currentColorRegex.test(cssColor)) {
+ const currentColor = style.color;
+ cssColor = cssColor.replace(currentColorRegex, (_, pre, post) => {
+ return pre + currentColor + post;
+ });
+ lazy.logConsole.debug(
+ "Replaced currentColor.",
+ property,
+ currentColor,
+ cssColor
+ );
+ }
+ /* Can drop the document argument after bugzilla bug 1973684 (142). */
+ const colorRGBA = win.InspectorUtils.colorToRGBA(cssColor, win.document);
+ if (!colorRGBA) {
+ lazy.logConsole.error(
+ `Failed to convert "${property}" color (${cssColor}) to RGBA`
+ );
+ return { r: 0, g: 0, b: 0, a: 0 };
+ }
+ return colorRGBA;
+ }
+
+ /**
+ * Compose two colors with alpha values on top of each other.
+ *
+ * @param {InspectorRGBATuple} topRGBA - The color to place on the top.
+ * @param {InspectorRGBATuple} bottomRGBA - The color to place on the bottom.
+ *
+ * @returns {InspectorRGBATuple} - The composed color.
+ */
+ _composeRGBA(topRGBA, bottomRGBA) {
+ const topA = Math.max(0, Math.min(1, topRGBA.a));
+ const bottomA = Math.max(0, Math.min(1, bottomRGBA.a));
+ const a = topA + bottomA - topA * bottomA; // Should be 1 if either is 1.
+ if (a === 0) {
+ return { r: 0, g: 0, b: 0, a };
+ }
+ const ret = { a };
+ for (const field of ["r", "g", "b"]) {
+ ret[field] =
+ (topRGBA[field] * topA + bottomRGBA[field] * bottomA * (1 - topA)) / a;
+ }
+ return ret;
+ }
+
+ /**
+ * Calculate the urlbar's container opaque background color, removing any
+ * transparency.
+ *
+ * @param {Window} win - The window to calculate the color for.
+ * @param {CSSStyleDeclaration} style - The computed style for the #nav-bar
+ * element.
+ *
+ * @returns {InspectorRGBATuple} - The calculated color, which will be opaque.
+ */
+ _calculateUrlbarContainerColor(win, style) {
+ let colorRGBA;
+ if (!Services.prefs.getBoolPref(kPrefVerticalTabs)) {
+ lazy.logConsole.debug("Toolbar background used.");
+ colorRGBA = this._convertToRGBA(win, style, "--toolbar-bgcolor");
+ if (colorRGBA.a === 1) {
+ return colorRGBA;
+ }
+ } else {
+ // The urlbar only has the toolbox colour.
+ colorRGBA = { r: 0, g: 0, b: 0, a: 0 };
+ }
+ let toolboxHasBackgroundImage = false;
+ const isLwTheme = win.document.documentElement.hasAttribute("lwtheme");
+ if (isLwTheme) {
+ for (const prop of ["--lwt-header-image", "--lwt-additional-images"]) {
+ const headerImage = style.getPropertyValue(prop);
+ if (headerImage && headerImage !== "none") {
+ // The theme sets a background image behind the urlbar. No easy way to
+ // derive a single colour from this.
+ toolboxHasBackgroundImage = true;
+ lazy.logConsole.debug(
+ "Toolbox has background image.",
+ prop,
+ headerImage
+ );
+ break;
+ }
+ }
+ }
+ if (!toolboxHasBackgroundImage) {
+ lazy.logConsole.debug("Toolbox background used.");
+ colorRGBA = this._composeRGBA(
+ colorRGBA,
+ this._convertToRGBA(win, style, "--toolbox-bgcolor")
+ );
+ if (colorRGBA.a === 1) {
+ return colorRGBA;
+ }
+ }
+
+ // Determine whether the urlbar is dark.
+ // At this point, the urlbar background has some transparency, likely on top
+ // of an image.
+ // We use the theme's text colour to figure out whether the urlbar
+ // background is overall meant to be light or dark. Unlike the urlbar, we
+ // expect this colour to be (almost) opaque.
+ const textRGBA = this._convertToRGBA(win, style, "--toolbar-field-color");
+ const textColor = new lazy.Color(textRGBA.r, textRGBA.g, textRGBA.b);
+ if (textColor.relativeLuminance >= 0.5) {
+ // Light text, so assume it has a dark background.
+ // Combine with a generic opaque dark colour. Copied from "frame" for the
+ // built-in dark theme.
+ lazy.logConsole.debug("Generic dark background used.");
+ const darkFrameRGBA = { r: 28, g: 27, b: 34, a: 1 };
+ return this._composeRGBA(colorRGBA, darkFrameRGBA);
+ }
+ // Combine with an opaque light colour. Copied from "frame" for the built-in
+ // light theme.
+ lazy.logConsole.debug("Generic light background used.");
+ const lightFrameRGBA = { r: 234, g: 234, b: 237, a: 1 };
+ return this._composeRGBA(colorRGBA, lightFrameRGBA);
+ }
+
+ /**
+ * Update the Letterboxing colors and related classes, or clear them if
+ * Letterboxing is not enabled.
+ *
+ * @param {Window} win - The window to update the colors for.
+ * @param {boolean} letterboxingEnabled - Whether Letterboxing is enabled.
+ */
+ _updateLetterboxingColors(win, letterboxingEnabled) {
+ let urlbarBackgroundRGBA;
+ let urlbarTextRGBA;
+ let contentSeparatorRGBA;
+ let urlbarBackgroundDark = false;
+ let lowBackgroundOutlineContrast = false;
+
+ if (letterboxingEnabled) {
+ // Want the effective colour of various elements without any alpha values
+ // so they can be used consistently.
+ const navbarStyle = win.getComputedStyle(
+ win.document.getElementById("nav-bar")
+ );
+ const containerRGBA = this._calculateUrlbarContainerColor(
+ win,
+ navbarStyle
+ );
+ urlbarBackgroundRGBA = this._composeRGBA(
+ this._convertToRGBA(
+ win,
+ navbarStyle,
+ "--toolbar-field-background-color"
+ ),
+ containerRGBA
+ );
+ urlbarTextRGBA = this._composeRGBA(
+ this._convertToRGBA(win, navbarStyle, "--toolbar-field-color"),
+ urlbarBackgroundRGBA
+ );
+ /* Separator between the urlbar container #nav-bar and the tabbox. */
+ const tabboxStyle = win.getComputedStyle(win.gBrowser.tabbox);
+ contentSeparatorRGBA = this._composeRGBA(
+ this._convertToRGBA(
+ win,
+ tabboxStyle,
+ "--chrome-content-separator-color"
+ ),
+ containerRGBA
+ );
+ const bgColor = new lazy.Color(
+ urlbarBackgroundRGBA.r,
+ urlbarBackgroundRGBA.g,
+ urlbarBackgroundRGBA.b
+ );
+ const outlineColor = new lazy.Color(
+ contentSeparatorRGBA.r,
+ contentSeparatorRGBA.g,
+ contentSeparatorRGBA.b
+ );
+ const contrastRatio = bgColor.contrastRatio(outlineColor);
+ lazy.logConsole.debug(
+ "Outline-background contrast ratio.",
+ contrastRatio
+ );
+ urlbarBackgroundDark = bgColor.relativeLuminance < 0.5;
+ /* Very low contrast ratio. For reference the default light theme has
+ * a contrast ratio of ~1.1. */
+ lowBackgroundOutlineContrast = contrastRatio < 1.05;
+ }
+ for (const { name, colorRGBA } of [
+ {
+ name: "--letterboxing-urlbar-text-color",
+ colorRGBA: urlbarTextRGBA,
+ },
+ {
+ name: "--letterboxing-urlbar-background-color",
+ colorRGBA: urlbarBackgroundRGBA,
+ },
+ {
+ name: "--letterboxing-content-separator-color",
+ colorRGBA: contentSeparatorRGBA,
+ },
+ ]) {
+ if (letterboxingEnabled) {
+ win.gBrowser.tabbox.style.setProperty(
+ name,
+ `rgb(${colorRGBA.r}, ${colorRGBA.g}, ${colorRGBA.b})`
+ );
+ } else {
+ win.gBrowser.tabbox.style.removeProperty(name);
+ }
+ }
+ win.gBrowser.tabbox.classList.toggle(
+ "letterboxing-urlbar-background-dark",
+ urlbarBackgroundDark
+ );
+ win.gBrowser.tabbox.classList.toggle(
+ "letterboxing-low-background-outline-contrast",
+ lowBackgroundOutlineContrast
+ );
}
_detachWindow(aWindow) {
@@ -886,7 +1161,7 @@ class _RFPHelper {
aWindow.removeEventListener("TabOpen", this);
// revert tabpanel's style to default
- tabBrowser.tabpanels?.classList.remove("letterboxing");
+ tabBrowser.tabbox.classList.remove("letterboxing");
// and restore default size on each browser element
for (let tab of tabBrowser.tabs) {
@@ -896,6 +1171,9 @@ class _RFPHelper {
aWindow.removeEventListener("dblclick", this._onWindowDoubleClick);
delete aWindow.shrinkToLetterbox;
aWindow.removeEventListener("sizemodechange", windowResizeHandler);
+
+ aWindow.removeEventListener("nativethemechange", this);
+ this._updateLetterboxingColors(aWindow, false);
}
_handleDOMWindowOpened(win) {
=====================================
toolkit/components/resistfingerprinting/content/letterboxing.css
=====================================
@@ -7,30 +7,106 @@
* RFPHelper.sys.mjs (LETTERBOX_CSS_SELECTOR and LETTERBOX_CSS_URL,
* respectively), where --letterboxing-width & --letterboxing-height are
* actually set.
+ * Keep this block first and separate to the rules that do not necessarily
+ * require --letterboxing-width or --letterboxing-height.
*/
.letterboxing {
- --letterboxing-bgcolor: var(--tabpanel-background-color);
- --letterboxing-border-radius: 8px;
- --letterboxing-border-top-radius: 0;
+ .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
+ width: var(--letterboxing-width) !important;
+ height: var(--letterboxing-height) !important;
+ }
+}
+
+#tabbrowser-tabbox.letterboxing {
+ --letterboxing-bgcolor: var(--background-color-canvas);
+ /* Match the border radius used for the sidebar. */
+ --letterboxing-border-radius: var(--border-radius-medium);
+ --letterboxing-border-radius-top: 0;
--letterboxing-vertical-alignment: start;
- --letterboxing-shadow-color: rgba(12, 12, 13, 0.10);
- --letterboxing-gradient-color1: var(--letterboxing-bgcolor);
- --letterboxing-gradient-color2: color-mix(in srgb, var(--chrome-content-separator-color) 50%, var(--letterboxing-bgcolor));
- --letterboxing-border-color: var(--letterboxing-bgcolor);
- --letterboxing-decorator-visibility: visible;
-
- /* Re-styling for Tor Browser. */
- /* stylelint-disable declaration-block-no-duplicate-custom-properties */
- --letterboxing-bgcolor: light-dark(#F0F0F4, #52525E);
- --letterboxing-gradient-color1: light-dark(
- rgba(0, 219, 222, 0.02),
- rgba(0, 219, 222, 0.06)
- );
- --letterboxing-gradient-color2: light-dark(
- rgba(252, 0, 255, 0.02),
- rgba(252, 0, 255, 0.06)
- );
- /* stylelint-enable declaration-block-no-duplicate-custom-properties */
+ --letterboxing-shadow: none;
+ --letterboxing-outline-color: var(--border-color);
+ --letterboxing-outline-width: 1px;
+
+ @media not ((prefers-contrast) or (forced-colors)) {
+ /* Match the #sidebar outline width. */
+ --letterboxing-outline-width: 0.5px;
+ --letterboxing-shadow-color: rgba(58, 57, 68, 0.20);
+ --letterboxing-shadow: 0 2px 14px 0 var(--letterboxing-shadow-color);
+
+ /* Match the effective urlbar background colour. */
+ --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
+ /* Match the effective colour of the separator between the urlbar container
+ * and the content. */
+ --letterboxing-outline-color: var(--letterboxing-content-separator-color);
+
+ &.letterboxing-urlbar-background-dark {
+ --letterboxing-shadow-color: #15141a;
+ }
+
+ &.letterboxing-low-background-outline-contrast {
+ /* The default content separator colour has insufficient contrast. */
+ --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, black);
+
+ &.letterboxing-urlbar-background-dark {
+ /* Lighten the colour. */
+ --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, white);
+ }
+ }
+ }
+
+ @media (prefers-contrast) and (not (forced-colors)) {
+ :root[lwtheme] & {
+ /* User with prefers-contrast coming from the system settings, but also an
+ * installed theme. */
+ --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
+ /* Presumably a user with prefers-contrast and a custom theme has chosen
+ * a theme where the contrast between the urlbar and the text is
+ * sufficiently high or low. */
+ --letterboxing-outline-color: var(--letterboxing-urlbar-text-color);
+ }
+ }
+
+ background: var(--letterboxing-bgcolor);
+
+ &:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline) {
+ /* Letterboxing outline is visible for the current tab. Replace the usual
+ * outline to match the Letterboxing outline. For most scenarios, this
+ * should be mostly the same colour as when Letterboxing is not visible. But
+ * it may make a difference for some theme combinations. */
+ outline-color: var(--letterboxing-outline-color);
+ outline-width: var(--letterboxing-outline-width);
+ }
+
+ #tabbrowser-tabpanels {
+ /* Override the --tabpanel-background-color.
+ * Also, make sure this remains transparent, otherwise it will overlap the
+ * parent's corner's border-radius due to it's "position: relative" rule. */
+ /* TODO: FIX this for newtab pages. tor-browser#44085 */
+ background: transparent;
+ }
+
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media -moz-pref("sidebar.revamp") {
+ :root:not([inDOMFullscreen]) &[sidebar-shown]:not(.letterboxing-nav-toolbox-hidden):is(
+ /* When the Letterboxing area is aligned to the top, show the rounded
+ * corner if there is enough vertical space between the sidebar and the
+ * browser element, which is not rounded at the top. */
+ :not(.letterboxing-vcenter):has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-sidebar-corner),
+ /* When the Letterboxing area is aligned to the centre, show the rounded
+ * corner if the Letterboxing border is shown. */
+ .letterboxing-vcenter:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline)
+ ) {
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media -moz-pref("sidebar.position_start") {
+ border-start-start-radius: var(--letterboxing-border-radius);
+ }
+
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media not -moz-pref("sidebar.position_start") {
+ border-start-end-radius: var(--letterboxing-border-radius);
+ }
+ }
+ }
.browserContainer {
/*
@@ -39,101 +115,71 @@
* doesn't get notified on horizontal shrinking.
*/
overflow: hidden;
- background: var(--letterboxing-bgcolor);
}
- .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
- box-shadow: 0 4px 8px 0 var(--letterboxing-shadow-color);
- border-radius: var(--letterboxing-border-radius);
- border-top-left-radius: var(--letterboxing-border-top-radius);
- border-top-right-radius: var(--letterboxing-border-top-radius);
- width: var(--letterboxing-width) !important;
- height: var(--letterboxing-height) !important;
- background: var(--letterboxing-gradient-color2);
+ &.letterboxing-vcenter {
+ --letterboxing-border-radius-top: var(--letterboxing-border-radius);
+ --letterboxing-vertical-alignment: center;
}
}
-:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing) {
- place-content: start center;
-}
-
-.browserDecorator {
- display: none;
- pointer-events: none;
- background: transparent;
- position: relative;
- z-index: 1;
-}
+.browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
+ :root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready & {
+ place-content: var(--letterboxing-vertical-alignment) center;
+ }
-.letterboxing.letterboxing-vcenter .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
- --letterboxing-border-top-radius: var(--letterboxing-border-radius);
- --letterboxing-vertical-alignment: center;
-}
+ :root:not([inDOMFullscreen]) .letterboxing &.letterboxing-show-outline {
+ browser {
+ /* We use clip-path rather than border-radius because border-radius on its
+ * own leads to rendering artefacts in the corners (tested with GNOME).
+ * See tor-browser#44214 (comment 3262962). */
+ /* TODO: Use border-radius once bugzilla bug 1991874 is resolved. */
+ clip-path: rect(auto auto auto auto round var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius));
+ }
-.letterboxing.letterboxing-gradient .browserContainer {
- background: linear-gradient(283deg, var(--letterboxing-gradient-color1) 0%, var(--letterboxing-gradient-color2) 100%), var(--letterboxing-bgcolor);
-}
+ .browserDecorator {
+ /* Need a separate browserDecorator element because the clip-path on the
+ * browser would exclude the outline and box-shadow. */
+ /* TODO: Move these rules to the browser element once bugzilla bug 1991874
+ * is resolved, and drop browserDecorator. */
+ display: block;
+ border-radius: var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius);
+ /* NOTE: The top outline will not be visible when this is aligned to the
+ * top. */
+ outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
+ box-shadow: var(--letterboxing-shadow);
+ }
-:root:not([inDOMFullscreen]) .letterboxing .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing)
- > .browserDecorator {
- display: initial;
- visibility: var(--letterboxing-decorator-visibility);
- border-radius: var(--letterboxing-border-radius);
- border-top-left-radius: var(--letterboxing-border-top-radius);
- border-top-right-radius: var(--letterboxing-border-top-radius);
- box-shadow: var(--letterboxing-border-color) 0 0 .1px inset, var(--letterboxing-border-color) 0 0 .1px;
- border: .1px solid var(--letterboxing-border-color);
- outline: .1px solid var(--letterboxing-bgcolor);
- height: calc(var(--letterboxing-height) + 1px);
- top: -1px;
-}
+ #statuspanel:not([mirror]) #statuspanel-label {
+ border-end-start-radius: var(--letterboxing-border-radius);
+ }
-.letterboxing-vcenter .browserDecorator {
- height: auto !important;
- top: 0 !important;
-}
+ #statuspanel[mirror] #statuspanel-label {
+ border-end-end-radius: var(--letterboxing-border-radius);
+ }
+ }
-/*
- Align status bar with content.
- TODO: switch to nested CSS selectors for conciseness when available (Firefox >= 117)
-*/
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel:not([hidden]) {
- position: relative;
- place-self: end left;
- left: 0;
- right: 0;
- z-index: 2;
- --letterboxing-status-left-radius: var(--letterboxing-border-radius);
- --letterboxing-status-right-radius: 0;
-}
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel:not([mirror]):-moz-locale-dir(rtl),
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
- > #statuspanel[mirror]:-moz-locale-dir(ltr) {
- left: 0;
- right: 0;
- --letterboxing-status-right-radius: var(--letterboxing-border-radius);
- --letterboxing-status-left-radius: 0;
- justify-self: right;
-}
+ #statuspanel {
+ position: relative;
+ place-self: end start;
+ z-index: 2;
-.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
-#statuspanel-label {
- border-radius: 0 0 var(--letterboxing-status-right-radius) var(--letterboxing-status-left-radius);
- margin: 0;
- border: 1px solid var(--letterboxing-border-color);
- max-width: calc(var(--letterboxing-width) * .5);
-}
+ &[mirror] {
+ justify-self: end;
+ }
+ }
-browser:fullscreen {
- --letterboxing-border-top-radius: 0;
- --letterboxing-border-radius: 0;
+ #statuspanel-label {
+ margin: 0;
+ outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
+ max-width: calc(var(--letterboxing-width) * .5);
+ }
}
-:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
- > .browserStack:not(.exclude-letterboxing) {
- place-content: var(--letterboxing-vertical-alignment) center;
+.browserDecorator {
+ display: none;
+ pointer-events: none;
+ background: transparent;
+ position: relative;
+ z-index: 1;
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/be15e4…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/be15e4…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/mullvad-browser][mullvad-browser-128.14.0esr-14.5-1] fixup! BB 40925: Implemented the Security Level component
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch mullvad-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Mullvad Browser
Commits:
accaaaf6 by hackademix at 2025-10-15T15:57:20+02:00
fixup! BB 40925: Implemented the Security Level component
BB 44242: Hand over Security Level's WebAssembly controls to NoScript
- - - - -
1 changed file:
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
Changes:
=====================================
toolkit/components/securitylevel/SecurityLevel.sys.mjs
=====================================
@@ -79,6 +79,7 @@ const max_caps = [
"object",
"other",
"script",
+ "wasm",
"webgl",
"noscript",
];
@@ -259,7 +260,6 @@ var initializeNoScriptControl = () => {
// for each security setting. Note that 2-m and 3-m are identical,
// corresponding to the old 2-medium-high setting. We also separately
// bind NoScript settings to the browser.security_level.security_slider
-// (see noscript-control.js).
/* eslint-disable */
// prettier-ignore
const kSecuritySettings = {
@@ -272,7 +272,9 @@ const kSecuritySettings = {
"gfx.font_rendering.opentype_svg.enabled": [, false, false, false, true ],
"svg.disabled": [, true, false, false, false],
"javascript.options.asmjs": [, false, false, false, true ],
- "javascript.options.wasm": [, false, false, false, true ],
+ // tor-browser#44234, tor-browser#44242: this interferes with the correct
+ // functioning of the browser. So, WASM is also handled by NoScript now.
+ "javascript.options.wasm": [, true, true, true, true ],
};
/* eslint-enable */
@@ -339,16 +341,19 @@ var write_setting_to_prefs = function (settingIndex) {
// security settings matches. Otherwise return null.
var read_setting_from_prefs = function (prefNames) {
prefNames = prefNames || Object.keys(kSecuritySettings);
- for (let settingIndex of [1, 2, 3, 4]) {
+ for (const settingIndex of [1, 2, 3, 4]) {
let possibleSetting = true;
// For the given settingIndex, check if all current pref values
// match the setting.
- for (let prefName of prefNames) {
- if (
- kSecuritySettings[prefName][settingIndex] !==
- Services.prefs.getBoolPref(prefName)
- ) {
+ for (const prefName of prefNames) {
+ const wanted = kSecuritySettings[prefName][settingIndex];
+ const actual = Services.prefs.getBoolPref(prefName);
+ if (wanted !== actual) {
possibleSetting = false;
+ logger.info(
+ `${prefName} does not match level ${settingIndex}: ${actual}, should be ${wanted}!`
+ );
+ break;
}
}
if (possibleSetting) {
@@ -373,7 +378,7 @@ var initializeSecurityPrefs = function () {
if (initializedSecPrefs) {
return;
}
- logger.info("Initializing security-prefs.js");
+ logger.info("Initializing security level");
initializedSecPrefs = true;
const wasCustom = Services.prefs.getBoolPref(kCustomPref, false);
@@ -381,6 +386,21 @@ var initializeSecurityPrefs = function () {
// and it should not be custom.
let desiredIndex = Services.prefs.getIntPref(kSliderPref, 4);
desiredIndex = fixupIndex(desiredIndex);
+
+ if (!(wasCustom && desiredIndex == 4)) {
+ // The current level is non-customized Standard, or
+ // Safer / Safest (either customized or not): the global
+ // javascript.options.wasm pref interferes with the correct
+ // functioning of the browser, so instead we rely on NoScript
+ // to disable WebAssembly now (tor-browser#44234, tor-browser#44242).
+ // We skip flipping in customized Standard, because if its value was
+ // found false under such as circumstance, that would suggest
+ // an intentional user choice we don't want to interfere with.
+ // Unlike other javascript.options.* preferences, this one is safe
+ // to flip without a browser restart because it's checked whenever a
+ // context is created.
+ Services.prefs.setBoolPref("javascript.options.wasm", true);
+ }
// Make sure the user has a set preference user value.
Services.prefs.setIntPref(kSliderPref, desiredIndex);
Services.prefs.setBoolPref(kCustomPref, wasCustom);
@@ -453,7 +473,7 @@ var initializeSecurityPrefs = function () {
});
}
- logger.info("security-prefs.js initialization complete");
+ logger.info("Security level initialization complete");
};
// tor-browser#41460: we changed preference names in 12.0.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/acc…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/acc…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-128.14.0esr-14.5-1] fixup! BB 40925: Implemented the Security Level component
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch base-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
14084797 by hackademix at 2025-10-15T15:57:13+02:00
fixup! BB 40925: Implemented the Security Level component
BB 44242: Hand over Security Level's WebAssembly controls to NoScript
- - - - -
1 changed file:
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
Changes:
=====================================
toolkit/components/securitylevel/SecurityLevel.sys.mjs
=====================================
@@ -79,6 +79,7 @@ const max_caps = [
"object",
"other",
"script",
+ "wasm",
"webgl",
"noscript",
];
@@ -247,7 +248,6 @@ var initializeNoScriptControl = () => {
// for each security setting. Note that 2-m and 3-m are identical,
// corresponding to the old 2-medium-high setting. We also separately
// bind NoScript settings to the browser.security_level.security_slider
-// (see noscript-control.js).
/* eslint-disable */
// prettier-ignore
const kSecuritySettings = {
@@ -260,7 +260,9 @@ const kSecuritySettings = {
"gfx.font_rendering.opentype_svg.enabled": [, false, false, false, true ],
"svg.disabled": [, true, false, false, false],
"javascript.options.asmjs": [, false, false, false, true ],
- "javascript.options.wasm": [, false, false, false, true ],
+ // tor-browser#44234, tor-browser#44242: this interferes with the correct
+ // functioning of the browser. So, WASM is also handled by NoScript now.
+ "javascript.options.wasm": [, true, true, true, true ],
};
/* eslint-enable */
@@ -327,16 +329,19 @@ var write_setting_to_prefs = function (settingIndex) {
// security settings matches. Otherwise return null.
var read_setting_from_prefs = function (prefNames) {
prefNames = prefNames || Object.keys(kSecuritySettings);
- for (let settingIndex of [1, 2, 3, 4]) {
+ for (const settingIndex of [1, 2, 3, 4]) {
let possibleSetting = true;
// For the given settingIndex, check if all current pref values
// match the setting.
- for (let prefName of prefNames) {
- if (
- kSecuritySettings[prefName][settingIndex] !==
- Services.prefs.getBoolPref(prefName)
- ) {
+ for (const prefName of prefNames) {
+ const wanted = kSecuritySettings[prefName][settingIndex];
+ const actual = Services.prefs.getBoolPref(prefName);
+ if (wanted !== actual) {
possibleSetting = false;
+ logger.info(
+ `${prefName} does not match level ${settingIndex}: ${actual}, should be ${wanted}!`
+ );
+ break;
}
}
if (possibleSetting) {
@@ -361,7 +366,7 @@ var initializeSecurityPrefs = function () {
if (initializedSecPrefs) {
return;
}
- logger.info("Initializing security-prefs.js");
+ logger.info("Initializing security level");
initializedSecPrefs = true;
const wasCustom = Services.prefs.getBoolPref(kCustomPref, false);
@@ -369,6 +374,21 @@ var initializeSecurityPrefs = function () {
// and it should not be custom.
let desiredIndex = Services.prefs.getIntPref(kSliderPref, 4);
desiredIndex = fixupIndex(desiredIndex);
+
+ if (!(wasCustom && desiredIndex == 4)) {
+ // The current level is non-customized Standard, or
+ // Safer / Safest (either customized or not): the global
+ // javascript.options.wasm pref interferes with the correct
+ // functioning of the browser, so instead we rely on NoScript
+ // to disable WebAssembly now (tor-browser#44234, tor-browser#44242).
+ // We skip flipping in customized Standard, because if its value was
+ // found false under such as circumstance, that would suggest
+ // an intentional user choice we don't want to interfere with.
+ // Unlike other javascript.options.* preferences, this one is safe
+ // to flip without a browser restart because it's checked whenever a
+ // context is created.
+ Services.prefs.setBoolPref("javascript.options.wasm", true);
+ }
// Make sure the user has a set preference user value.
Services.prefs.setIntPref(kSliderPref, desiredIndex);
Services.prefs.setBoolPref(kCustomPref, wasCustom);
@@ -441,7 +461,7 @@ var initializeSecurityPrefs = function () {
});
}
- logger.info("security-prefs.js initialization complete");
+ logger.info("Security level initialization complete");
};
// tor-browser#41460: we changed preference names in 12.0.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/1408479…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/1408479…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-128.14.0esr-14.5-1] fixup! BB 40925: Implemented the Security Level component
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch tor-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
19fc83ce by hackademix at 2025-10-15T15:57:05+02:00
fixup! BB 40925: Implemented the Security Level component
BB 44242: Hand over Security Level's WebAssembly controls to NoScript
- - - - -
1 changed file:
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
Changes:
=====================================
toolkit/components/securitylevel/SecurityLevel.sys.mjs
=====================================
@@ -79,6 +79,7 @@ const max_caps = [
"object",
"other",
"script",
+ "wasm",
"webgl",
"noscript",
];
@@ -247,7 +248,6 @@ var initializeNoScriptControl = () => {
// for each security setting. Note that 2-m and 3-m are identical,
// corresponding to the old 2-medium-high setting. We also separately
// bind NoScript settings to the browser.security_level.security_slider
-// (see noscript-control.js).
/* eslint-disable */
// prettier-ignore
const kSecuritySettings = {
@@ -260,7 +260,9 @@ const kSecuritySettings = {
"gfx.font_rendering.opentype_svg.enabled": [, false, false, false, true ],
"svg.disabled": [, true, false, false, false],
"javascript.options.asmjs": [, false, false, false, true ],
- "javascript.options.wasm": [, false, false, false, true ],
+ // tor-browser#44234, tor-browser#44242: this interferes with the correct
+ // functioning of the browser. So, WASM is also handled by NoScript now.
+ "javascript.options.wasm": [, true, true, true, true ],
};
/* eslint-enable */
@@ -327,16 +329,19 @@ var write_setting_to_prefs = function (settingIndex) {
// security settings matches. Otherwise return null.
var read_setting_from_prefs = function (prefNames) {
prefNames = prefNames || Object.keys(kSecuritySettings);
- for (let settingIndex of [1, 2, 3, 4]) {
+ for (const settingIndex of [1, 2, 3, 4]) {
let possibleSetting = true;
// For the given settingIndex, check if all current pref values
// match the setting.
- for (let prefName of prefNames) {
- if (
- kSecuritySettings[prefName][settingIndex] !==
- Services.prefs.getBoolPref(prefName)
- ) {
+ for (const prefName of prefNames) {
+ const wanted = kSecuritySettings[prefName][settingIndex];
+ const actual = Services.prefs.getBoolPref(prefName);
+ if (wanted !== actual) {
possibleSetting = false;
+ logger.info(
+ `${prefName} does not match level ${settingIndex}: ${actual}, should be ${wanted}!`
+ );
+ break;
}
}
if (possibleSetting) {
@@ -361,7 +366,7 @@ var initializeSecurityPrefs = function () {
if (initializedSecPrefs) {
return;
}
- logger.info("Initializing security-prefs.js");
+ logger.info("Initializing security level");
initializedSecPrefs = true;
const wasCustom = Services.prefs.getBoolPref(kCustomPref, false);
@@ -369,6 +374,21 @@ var initializeSecurityPrefs = function () {
// and it should not be custom.
let desiredIndex = Services.prefs.getIntPref(kSliderPref, 4);
desiredIndex = fixupIndex(desiredIndex);
+
+ if (!(wasCustom && desiredIndex == 4)) {
+ // The current level is non-customized Standard, or
+ // Safer / Safest (either customized or not): the global
+ // javascript.options.wasm pref interferes with the correct
+ // functioning of the browser, so instead we rely on NoScript
+ // to disable WebAssembly now (tor-browser#44234, tor-browser#44242).
+ // We skip flipping in customized Standard, because if its value was
+ // found false under such as circumstance, that would suggest
+ // an intentional user choice we don't want to interfere with.
+ // Unlike other javascript.options.* preferences, this one is safe
+ // to flip without a browser restart because it's checked whenever a
+ // context is created.
+ Services.prefs.setBoolPref("javascript.options.wasm", true);
+ }
// Make sure the user has a set preference user value.
Services.prefs.setIntPref(kSliderPref, desiredIndex);
Services.prefs.setBoolPref(kCustomPref, wasCustom);
@@ -441,7 +461,7 @@ var initializeSecurityPrefs = function () {
});
}
- logger.info("security-prefs.js initialization complete");
+ logger.info("Security level initialization complete");
};
// tor-browser#41460: we changed preference names in 12.0.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/19fc83c…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/19fc83c…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.4.0esr-15.0-1] fixup! BB 40925: Implemented the Security Level component
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch mullvad-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
42b098c7 by hackademix at 2025-10-15T15:56:42+02:00
fixup! BB 40925: Implemented the Security Level component
BB 44242: Hand over Security Level's WebAssembly controls to NoScript
- - - - -
1 changed file:
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
Changes:
=====================================
toolkit/components/securitylevel/SecurityLevel.sys.mjs
=====================================
@@ -79,6 +79,7 @@ const max_caps = [
"object",
"other",
"script",
+ "wasm",
"webgl",
"noscript",
];
@@ -259,7 +260,6 @@ var initializeNoScriptControl = () => {
// for each security setting. Note that 2-m and 3-m are identical,
// corresponding to the old 2-medium-high setting. We also separately
// bind NoScript settings to the browser.security_level.security_slider
-// (see noscript-control.js).
/* eslint-disable */
// prettier-ignore
const kSecuritySettings = {
@@ -272,7 +272,9 @@ const kSecuritySettings = {
"gfx.font_rendering.opentype_svg.enabled": [, false, false, false, true ],
"svg.disabled": [, true, false, false, false],
"javascript.options.asmjs": [, false, false, false, true ],
- "javascript.options.wasm": [, false, false, false, true ],
+ // tor-browser#44234, tor-browser#44242: this interferes with the correct
+ // functioning of the browser. So, WASM is also handled by NoScript now.
+ "javascript.options.wasm": [, true, true, true, true ],
};
/* eslint-enable */
@@ -339,16 +341,19 @@ var write_setting_to_prefs = function (settingIndex) {
// security settings matches. Otherwise return null.
var read_setting_from_prefs = function (prefNames) {
prefNames = prefNames || Object.keys(kSecuritySettings);
- for (let settingIndex of [1, 2, 3, 4]) {
+ for (const settingIndex of [1, 2, 3, 4]) {
let possibleSetting = true;
// For the given settingIndex, check if all current pref values
// match the setting.
- for (let prefName of prefNames) {
- if (
- kSecuritySettings[prefName][settingIndex] !==
- Services.prefs.getBoolPref(prefName)
- ) {
+ for (const prefName of prefNames) {
+ const wanted = kSecuritySettings[prefName][settingIndex];
+ const actual = Services.prefs.getBoolPref(prefName);
+ if (wanted !== actual) {
possibleSetting = false;
+ logger.info(
+ `${prefName} does not match level ${settingIndex}: ${actual}, should be ${wanted}!`
+ );
+ break;
}
}
if (possibleSetting) {
@@ -373,7 +378,7 @@ var initializeSecurityPrefs = function () {
if (initializedSecPrefs) {
return;
}
- logger.info("Initializing security-prefs.js");
+ logger.info("Initializing security level");
initializedSecPrefs = true;
const wasCustom = Services.prefs.getBoolPref(kCustomPref, false);
@@ -381,6 +386,21 @@ var initializeSecurityPrefs = function () {
// and it should not be custom.
let desiredIndex = Services.prefs.getIntPref(kSliderPref, 4);
desiredIndex = fixupIndex(desiredIndex);
+
+ if (!(wasCustom && desiredIndex == 4)) {
+ // The current level is non-customized Standard, or
+ // Safer / Safest (either customized or not): the global
+ // javascript.options.wasm pref interferes with the correct
+ // functioning of the browser, so instead we rely on NoScript
+ // to disable WebAssembly now (tor-browser#44234, tor-browser#44242).
+ // We skip flipping in customized Standard, because if its value was
+ // found false under such as circumstance, that would suggest
+ // an intentional user choice we don't want to interfere with.
+ // Unlike other javascript.options.* preferences, this one is safe
+ // to flip without a browser restart because it's checked whenever a
+ // context is created.
+ Services.prefs.setBoolPref("javascript.options.wasm", true);
+ }
// Make sure the user has a set preference user value.
Services.prefs.setIntPref(kSliderPref, desiredIndex);
Services.prefs.setBoolPref(kCustomPref, wasCustom);
@@ -460,7 +480,7 @@ var initializeSecurityPrefs = function () {
});
}
- logger.info("security-prefs.js initialization complete");
+ logger.info("Security level initialization complete");
};
// tor-browser#41460: we changed preference names in 12.0.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/42b…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/42b…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-140.4.0esr-15.0-1] fixup! BB 40925: Implemented the Security Level component
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch base-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
29c65ad8 by hackademix at 2025-10-15T15:56:35+02:00
fixup! BB 40925: Implemented the Security Level component
BB 44242: Hand over Security Level's WebAssembly controls to NoScript
- - - - -
1 changed file:
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
Changes:
=====================================
toolkit/components/securitylevel/SecurityLevel.sys.mjs
=====================================
@@ -79,6 +79,7 @@ const max_caps = [
"object",
"other",
"script",
+ "wasm",
"webgl",
"noscript",
];
@@ -247,7 +248,6 @@ var initializeNoScriptControl = () => {
// for each security setting. Note that 2-m and 3-m are identical,
// corresponding to the old 2-medium-high setting. We also separately
// bind NoScript settings to the browser.security_level.security_slider
-// (see noscript-control.js).
/* eslint-disable */
// prettier-ignore
const kSecuritySettings = {
@@ -260,7 +260,9 @@ const kSecuritySettings = {
"gfx.font_rendering.opentype_svg.enabled": [, false, false, false, true ],
"svg.disabled": [, true, false, false, false],
"javascript.options.asmjs": [, false, false, false, true ],
- "javascript.options.wasm": [, false, false, false, true ],
+ // tor-browser#44234, tor-browser#44242: this interferes with the correct
+ // functioning of the browser. So, WASM is also handled by NoScript now.
+ "javascript.options.wasm": [, true, true, true, true ],
};
/* eslint-enable */
@@ -327,16 +329,19 @@ var write_setting_to_prefs = function (settingIndex) {
// security settings matches. Otherwise return null.
var read_setting_from_prefs = function (prefNames) {
prefNames = prefNames || Object.keys(kSecuritySettings);
- for (let settingIndex of [1, 2, 3, 4]) {
+ for (const settingIndex of [1, 2, 3, 4]) {
let possibleSetting = true;
// For the given settingIndex, check if all current pref values
// match the setting.
- for (let prefName of prefNames) {
- if (
- kSecuritySettings[prefName][settingIndex] !==
- Services.prefs.getBoolPref(prefName)
- ) {
+ for (const prefName of prefNames) {
+ const wanted = kSecuritySettings[prefName][settingIndex];
+ const actual = Services.prefs.getBoolPref(prefName);
+ if (wanted !== actual) {
possibleSetting = false;
+ logger.info(
+ `${prefName} does not match level ${settingIndex}: ${actual}, should be ${wanted}!`
+ );
+ break;
}
}
if (possibleSetting) {
@@ -361,7 +366,7 @@ var initializeSecurityPrefs = function () {
if (initializedSecPrefs) {
return;
}
- logger.info("Initializing security-prefs.js");
+ logger.info("Initializing security level");
initializedSecPrefs = true;
const wasCustom = Services.prefs.getBoolPref(kCustomPref, false);
@@ -369,6 +374,21 @@ var initializeSecurityPrefs = function () {
// and it should not be custom.
let desiredIndex = Services.prefs.getIntPref(kSliderPref, 4);
desiredIndex = fixupIndex(desiredIndex);
+
+ if (!(wasCustom && desiredIndex == 4)) {
+ // The current level is non-customized Standard, or
+ // Safer / Safest (either customized or not): the global
+ // javascript.options.wasm pref interferes with the correct
+ // functioning of the browser, so instead we rely on NoScript
+ // to disable WebAssembly now (tor-browser#44234, tor-browser#44242).
+ // We skip flipping in customized Standard, because if its value was
+ // found false under such as circumstance, that would suggest
+ // an intentional user choice we don't want to interfere with.
+ // Unlike other javascript.options.* preferences, this one is safe
+ // to flip without a browser restart because it's checked whenever a
+ // context is created.
+ Services.prefs.setBoolPref("javascript.options.wasm", true);
+ }
// Make sure the user has a set preference user value.
Services.prefs.setIntPref(kSliderPref, desiredIndex);
Services.prefs.setBoolPref(kCustomPref, wasCustom);
@@ -448,7 +468,7 @@ var initializeSecurityPrefs = function () {
});
}
- logger.info("security-prefs.js initialization complete");
+ logger.info("Security level initialization complete");
};
// tor-browser#41460: we changed preference names in 12.0.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/29c65ad…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/29c65ad…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.4.0esr-15.0-1] 2 commits: BB 43869: Hide pens with RFP.
by morgan (ï¼ morgan) 15 Oct '25
by morgan (ï¼ morgan) 15 Oct '25
15 Oct '25
morgan pushed to branch mullvad-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
4517a0aa by Pier Angelo Vendrame at 2025-10-15T13:56:10+00:00
BB 43869: Hide pens with RFP.
- - - - -
1a3fdcf6 by Pier Angelo Vendrame at 2025-10-15T13:56:10+00:00
fixup! Firefox preference overrides.
BB 43869: Remove prefs for touch.
RFP now overrides them.
- - - - -
11 changed files:
- browser/app/profile/001-base-profile.js
- dom/base/Element.cpp
- dom/events/PointerEvent.cpp
- dom/events/PointerEvent.h
- dom/events/PointerEventHandler.cpp
- dom/events/TouchEvent.cpp
- dom/webidl/PointerEvent.webidl
- layout/base/PositionedEventTargeting.cpp
- toolkit/components/resistfingerprinting/RFPTargets.inc
- toolkit/components/resistfingerprinting/nsRFPService.cpp
- widget/WidgetEventImpl.cpp
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -497,12 +497,6 @@ pref("dom.webmidi.enabled", false); // Bug 41398: Disable Web MIDI API
// randomized IDs when this pref is true).
// Defense-in-depth (already the default value) from Firefox 119 or 120.
pref("media.devices.enumerate.legacy.enabled", false);
-// Touch events (tor-browser#10286, tor-browser#42069, tor-browser#44062)
-#if defined(XP_WIN) || defined(ANDROID)
-pref("dom.w3c_touch_events.enabled", 1);
-#else
-pref("dom.w3c_touch_events.enabled", 0);
-#endif
#ifndef ANDROID
// Bug 42138: Disable touch-based overscroll UX
pref("apz.overscroll.enabled", false);
=====================================
dom/base/Element.cpp
=====================================
@@ -302,11 +302,6 @@ nsDOMAttributeMap* Element::Attributes() {
}
void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
- if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
- aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
- aError.ThrowNotFoundError("Invalid pointer id");
- return;
- }
const PointerInfo* pointerInfo =
PointerEventHandler::GetPointerInfo(aPointerId);
if (!pointerInfo) {
@@ -334,11 +329,6 @@ void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
}
void Element::ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError) {
- if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
- aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
- aError.ThrowNotFoundError("Invalid pointer id");
- return;
- }
if (!PointerEventHandler::GetPointerInfo(aPointerId)) {
aError.ThrowNotFoundError("Invalid pointer id");
return;
=====================================
dom/events/PointerEvent.cpp
=====================================
@@ -224,39 +224,78 @@ NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
NS_IMPL_ADDREF_INHERITED(PointerEvent, MouseEvent)
NS_IMPL_RELEASE_INHERITED(PointerEvent, MouseEvent)
-void PointerEvent::GetPointerType(nsAString& aPointerType) {
+uint16_t PointerEvent::ResistantInputSource(CallerType aCallerType) const {
+ const uint16_t inputSource = mEvent->AsPointerEvent()->mInputSource;
+ if (!ShouldResistFingerprinting(aCallerType)) {
+ return inputSource;
+ }
+
+ MOZ_ASSERT(IsTrusted());
+
+ // Bug 1953665: Pen events are inconsistent between platforms.
+ // They might emit touch events on Windows and Android, but only mouse events
+ // in other platforms. In particular, touch is always disabled on macOS.
+#if defined(XP_WIN)
+ if (inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH ||
+ inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
+ return inputSource;
+ }
+ // Similar to nsWindow::DispatchTouchEventFromWMPointer.
+ switch (mEvent->mMessage) {
+ case ePointerMove:
+ return mEvent->AsPointerEvent()->mPressure == 0
+ ? MouseEvent_Binding::MOZ_SOURCE_MOUSE // hover
+ : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+ case ePointerUp:
+ case ePointerDown:
+ case ePointerCancel:
+ return MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+ default:
+ return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+ }
+#elif defined(MOZ_WIDGET_ANDROID)
+ return inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE
+ ? MouseEvent_Binding::MOZ_SOURCE_MOUSE
+ : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+#elif defined(MOZ_WIDGET_GTK)
+ return inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH
+ ? MouseEvent_Binding::MOZ_SOURCE_TOUCH
+ : MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+#elif defined(MOZ_WIDGET_COCOA)
+ return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+#else
+ return inputSource;
+#endif
+}
+
+void PointerEvent::GetPointerType(nsAString& aPointerType,
+ CallerType aCallerType) {
if (mPointerType.isSome()) {
aPointerType = mPointerType.value();
return;
}
-
-#if SPOOFED_MAX_TOUCH_POINTS <= 0
- if (ShouldResistFingerprinting()) {
- aPointerType.AssignLiteral("mouse");
- return;
- }
-#endif
-
- ConvertPointerTypeToString(mEvent->AsPointerEvent()->mInputSource,
- aPointerType);
+ ConvertPointerTypeToString(ResistantInputSource(aCallerType), aPointerType);
}
int32_t PointerEvent::PointerId() {
- return (ShouldResistFingerprinting(true))
- ? PointerEventHandler::GetSpoofedPointerIdForRFP()
- : mEvent->AsPointerEvent()->pointerId;
+ return mEvent->AsPointerEvent()->pointerId;
}
-double PointerEvent::Width() const {
- return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mWidth;
+double PointerEvent::Width(CallerType aCallerType) const {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 1.0
+ : mEvent->AsPointerEvent()->mWidth;
}
-double PointerEvent::Height() const {
- return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mHeight;
+double PointerEvent::Height(CallerType aCallerType) const {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 1.0
+ : mEvent->AsPointerEvent()->mHeight;
}
-float PointerEvent::Pressure() {
- if (mEvent->mMessage == ePointerUp || !ShouldResistFingerprinting()) {
+float PointerEvent::Pressure(CallerType aCallerType) {
+ if (mEvent->mMessage == ePointerUp ||
+ !ShouldResistFingerprinting(aCallerType)) {
return mEvent->AsPointerEvent()->mPressure;
}
@@ -273,14 +312,14 @@ float PointerEvent::Pressure() {
return spoofedPressure;
}
-float PointerEvent::TangentialPressure() {
- return ShouldResistFingerprinting()
+float PointerEvent::TangentialPressure(CallerType aCallerType) {
+ return ShouldResistFingerprinting(aCallerType)
? 0
: mEvent->AsPointerEvent()->tangentialPressure;
}
-int32_t PointerEvent::TiltX() {
- if (ShouldResistFingerprinting()) {
+int32_t PointerEvent::TiltX(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return 0;
}
if (mTiltX.isSome()) {
@@ -291,8 +330,8 @@ int32_t PointerEvent::TiltX() {
return *mTiltX;
}
-int32_t PointerEvent::TiltY() {
- if (ShouldResistFingerprinting()) {
+int32_t PointerEvent::TiltY(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return 0;
}
if (mTiltY.isSome()) {
@@ -303,12 +342,14 @@ int32_t PointerEvent::TiltY() {
return *mTiltY;
}
-int32_t PointerEvent::Twist() {
- return ShouldResistFingerprinting() ? 0 : mEvent->AsPointerEvent()->twist;
+int32_t PointerEvent::Twist(CallerType aCallerType) {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 0
+ : mEvent->AsPointerEvent()->twist;
}
-double PointerEvent::AltitudeAngle() {
- if (ShouldResistFingerprinting()) {
+double PointerEvent::AltitudeAngle(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return WidgetPointerHelper::GetDefaultAltitudeAngle();
}
if (mAltitudeAngle.isSome()) {
@@ -319,8 +360,8 @@ double PointerEvent::AltitudeAngle() {
return *mAltitudeAngle;
}
-double PointerEvent::AzimuthAngle() {
- if (ShouldResistFingerprinting()) {
+double PointerEvent::AzimuthAngle(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return WidgetPointerHelper::GetDefaultAzimuthAngle();
}
if (mAzimuthAngle.isSome()) {
@@ -421,22 +462,22 @@ void PointerEvent::GetPredictedEvents(
aPointerEvents.AppendElements(mPredictedEvents);
}
-bool PointerEvent::ShouldResistFingerprinting(bool aForPointerId) const {
- // There are three simple situations we don't need to spoof this pointer
+bool PointerEvent::ShouldResistFingerprinting(CallerType aCallerType) const {
+ // There are a few simple situations we don't need to spoof this pointer
// event.
- // 1. The pref privcy.resistFingerprinting' is false, we fast return here
- // since we don't need to do any QI of following codes.
- // 2. This event is generated by scripts.
- // 3. This event is a mouse pointer event.
+ // * We are being called by a System caller
+ // * The pref privcy.resistFingerprinting' is false, we fast return here
+ // since we don't need to do any QI of following codes.
+ // * This event is generated by scripts.
+ // * This event is a mouse pointer event.
// We don't need to check for the system group since pointer events won't be
// dispatched to the system group.
- RFPTarget target =
- aForPointerId ? RFPTarget::PointerId : RFPTarget::PointerEvents;
- if (!nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
+ RFPTarget target = RFPTarget::PointerEvents;
+ if (aCallerType == CallerType::System ||
+ !nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
!mEvent->IsTrusted() ||
- (mEvent->AsPointerEvent()->mInputSource ==
- MouseEvent_Binding::MOZ_SOURCE_MOUSE &&
- SPOOFED_MAX_TOUCH_POINTS == 0)) {
+ mEvent->AsPointerEvent()->mInputSource ==
+ MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
return false;
}
=====================================
dom/events/PointerEvent.h
=====================================
@@ -41,17 +41,19 @@ class PointerEvent : public MouseEvent {
PointerEvent* AsPointerEvent() final { return this; }
int32_t PointerId();
- double Width() const;
- double Height() const;
- float Pressure();
- float TangentialPressure();
- int32_t TiltX();
- int32_t TiltY();
- int32_t Twist();
- double AltitudeAngle();
- double AzimuthAngle();
+ double Width(CallerType aCallerType = CallerType::System) const;
+ double Height(CallerType aCallerType = CallerType::System) const;
+ float Pressure(CallerType aCallerType = CallerType::System);
+ float TangentialPressure(CallerType aCallerType = CallerType::System);
+ int32_t TiltX(CallerType aCallerType = CallerType::System);
+ int32_t TiltY(CallerType aCallerType = CallerType::System);
+ int32_t Twist(CallerType aCallerType = CallerType::System);
+ double AltitudeAngle(CallerType aCallerType = CallerType::System);
+ double AzimuthAngle(CallerType aCallerType = CallerType::System);
bool IsPrimary();
- void GetPointerType(nsAString& aPointerType);
+ void GetPointerType(
+ nsAString& aPointerType,
+ mozilla::dom::CallerType aCallerType = CallerType::System);
static bool EnableGetCoalescedEvents(JSContext* aCx, JSObject* aGlobal);
void GetCoalescedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
void GetPredictedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
@@ -62,7 +64,11 @@ class PointerEvent : public MouseEvent {
private:
// This method returns the boolean to indicate whether spoofing pointer
// event for fingerprinting resistance.
- bool ShouldResistFingerprinting(bool aForPointerId = false) const;
+ bool ShouldResistFingerprinting(
+ CallerType aCallerType = CallerType::System) const;
+
+ uint16_t ResistantInputSource(
+ CallerType aCallerType = CallerType::System) const;
// When the instance is a trusted `pointermove` event but the widget event
// does not have proper coalesced events (typically, the event is synthesized
=====================================
dom/events/PointerEventHandler.cpp
=====================================
@@ -421,32 +421,6 @@ void PointerEventHandler::CheckPointerCaptureState(WidgetPointerEvent* aEvent) {
PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aEvent->pointerId);
- // When fingerprinting resistance is enabled, we need to map other pointer
- // ids into the spoofed one. We don't have to do the mapping if the capture
- // info exists for the non-spoofed pointer id because of we won't allow
- // content to set pointer capture other than the spoofed one. Thus, it must be
- // from chrome if the capture info exists in this case. And we don't have to
- // do anything if the pointer id is the same as the spoofed one.
- if (nsContentUtils::ShouldResistFingerprinting("Efficiency Check",
- RFPTarget::PointerId) &&
- aEvent->pointerId != (uint32_t)GetSpoofedPointerIdForRFP() &&
- !captureInfo) {
- PointerCaptureInfo* spoofedCaptureInfo =
- GetPointerCaptureInfo(GetSpoofedPointerIdForRFP());
-
- // We need to check the target element's document should resist
- // fingerprinting. If not, we don't need to send a capture event
- // since the capture info of the original pointer id doesn't exist
- // in this case.
- if (!spoofedCaptureInfo || !spoofedCaptureInfo->mPendingElement ||
- !spoofedCaptureInfo->mPendingElement->OwnerDoc()
- ->ShouldResistFingerprinting(RFPTarget::PointerEvents)) {
- return;
- }
-
- captureInfo = spoofedCaptureInfo;
- }
-
if (!captureInfo ||
captureInfo->mPendingElement == captureInfo->mOverrideElement) {
return;
=====================================
dom/events/TouchEvent.cpp
=====================================
@@ -225,38 +225,40 @@ bool TouchEvent::PrefEnabled(nsIDocShell* aDocShell) {
} else if (touchEventsOverride ==
mozilla::dom::TouchEventsOverride::Disabled) {
enabled = false;
+ } else if (nsContentUtils::ShouldResistFingerprinting(
+ aDocShell, RFPTarget::PointerEvents)) {
+#ifdef MOZ_WIDGET_COCOA
+ enabled = false;
+#else
+ enabled = true;
+#endif
} else {
const int32_t prefValue = StaticPrefs::dom_w3c_touch_events_enabled();
if (prefValue == 2) {
- if (nsContentUtils::ShouldResistFingerprinting(
- aDocShell, RFPTarget::PointerEvents)) {
- enabled = SPOOFED_MAX_TOUCH_POINTS != 0;
- } else {
- enabled = PlatformSupportsTouch();
-
- static bool firstTime = true;
- // The touch screen data seems to be inaccurate in the parent process,
- // and we really need the crash annotation in child processes.
- if (firstTime && !XRE_IsParentProcess()) {
- CrashReporter::RecordAnnotationBool(
- CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
- firstTime = false;
- }
+ enabled = PlatformSupportsTouch();
+
+ static bool firstTime = true;
+ // The touch screen data seems to be inaccurate in the parent process,
+ // and we really need the crash annotation in child processes.
+ if (firstTime && !XRE_IsParentProcess()) {
+ CrashReporter::RecordAnnotationBool(
+ CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
+ firstTime = false;
+ }
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
- if (enabled && aDocShell) {
- // APZ might be disabled on this particular widget, in which case
- // TouchEvent support will also be disabled. Try to detect that.
- RefPtr<nsPresContext> pc = aDocShell->GetPresContext();
- if (pc) {
- nsCOMPtr<nsIWidget> widget = pc->GetRootWidget();
- if (widget) {
- enabled &= widget->AsyncPanZoomEnabled();
- }
+ if (enabled && aDocShell) {
+ // APZ might be disabled on this particular widget, in which case
+ // TouchEvent support will also be disabled. Try to detect that.
+ RefPtr<nsPresContext> pc = aDocShell->GetPresContext();
+ if (pc) {
+ nsCOMPtr<nsIWidget> widget = pc->GetRootWidget();
+ if (widget) {
+ enabled &= widget->AsyncPanZoomEnabled();
}
}
-#endif
}
+#endif
} else {
enabled = !!prefValue;
}
=====================================
dom/webidl/PointerEvent.webidl
=====================================
@@ -14,16 +14,26 @@ interface PointerEvent : MouseEvent
readonly attribute long pointerId;
+ [NeedsCallerType]
readonly attribute double width;
+ [NeedsCallerType]
readonly attribute double height;
+ [NeedsCallerType]
readonly attribute float pressure;
+ [NeedsCallerType]
readonly attribute float tangentialPressure;
+ [NeedsCallerType]
readonly attribute long tiltX;
+ [NeedsCallerType]
readonly attribute long tiltY;
+ [NeedsCallerType]
readonly attribute long twist;
+ [NeedsCallerType]
readonly attribute double altitudeAngle;
+ [NeedsCallerType]
readonly attribute double azimuthAngle;
+ [NeedsCallerType]
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
=====================================
layout/base/PositionedEventTargeting.cpp
=====================================
@@ -16,6 +16,7 @@
#include "mozilla/ToString.h"
#include "mozilla/ViewportUtils.h"
#include "mozilla/dom/MouseEventBinding.h"
+#include "mozilla/dom/TouchEvent.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsContainerFrame.h"
@@ -173,9 +174,7 @@ static bool HasTouchListener(const nsIContent* aContent) {
return false;
}
- // FIXME: Should this really use the pref rather than TouchEvent::PrefEnabled
- // or such?
- if (!StaticPrefs::dom_w3c_touch_events_enabled()) {
+ if (!TouchEvent::PrefEnabled(aContent->OwnerDoc()->GetDocShell())) {
return false;
}
=====================================
toolkit/components/resistfingerprinting/RFPTargets.inc
=====================================
@@ -34,7 +34,7 @@ ITEM_VALUE(NavigatorHWConcurrency, 16)
ITEM_VALUE(NavigatorOscpu, 17)
ITEM_VALUE(NavigatorPlatform, 18)
ITEM_VALUE(NavigatorUserAgent, 19)
-ITEM_VALUE(PointerId, 20)
+// We no longer use PointerId, it can renamed and reused
ITEM_VALUE(StreamVideoFacingMode, 21)
ITEM_VALUE(JSDateTimeUTC, 22)
ITEM_VALUE(JSMathFdlibm, 23)
@@ -104,6 +104,7 @@ ITEM_VALUE(DiskStorageLimit, 70)
ITEM_VALUE(WebCodecs, 71)
ITEM_VALUE(NavigatorHWConcurrencyTiered,74)
+// !!! Adding a new target? Rename PointerId and repurpose it.
// !!! Don't forget to update kDefaultFingerprintingProtections in nsRFPService.cpp
// if necessary.
=====================================
toolkit/components/resistfingerprinting/nsRFPService.cpp
=====================================
@@ -303,13 +303,6 @@ Maybe<bool> nsRFPService::HandleExeptionalRFPTargets(
StaticPrefs::privacy_spoof_english_DoNotUseDirectly() == 2);
}
- // We don't spoof the pointerId on multi-touch devices.
-#if SPOOFED_MAX_TOUCH_POINTS > 0
- if (aTarget == RFPTarget::PointerId) {
- return Some(false);
- }
-#endif
-
return Nothing();
}
=====================================
widget/WidgetEventImpl.cpp
=====================================
@@ -589,23 +589,6 @@ bool WidgetEvent::IsBlockedForFingerprintingResistance() const {
keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_Control ||
keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_AltGraph);
}
- case ePointerEventClass: {
- if (IsPointerEventMessageOriginallyMouseEventMessage(mMessage)) {
- return false;
- }
-
- if (SPOOFED_MAX_TOUCH_POINTS > 0) {
- return false;
- }
-
- const WidgetPointerEvent* pointerEvent = AsPointerEvent();
-
- // We suppress the pointer events if it is not primary for fingerprinting
- // resistance. It is because of that we want to spoof any pointer event
- // into a mouse pointer event and the mouse pointer event only has
- // isPrimary as true.
- return !pointerEvent->mIsPrimary;
- }
default:
return false;
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/fb…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/fb…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-140.4.0esr-15.0-1] 2 commits: BB 43869: Hide pens with RFP.
by morgan (ï¼ morgan) 15 Oct '25
by morgan (ï¼ morgan) 15 Oct '25
15 Oct '25
morgan pushed to branch base-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
822f61c9 by Pier Angelo Vendrame at 2025-10-15T13:54:52+00:00
BB 43869: Hide pens with RFP.
- - - - -
0ed3602b by Pier Angelo Vendrame at 2025-10-15T13:54:54+00:00
fixup! Firefox preference overrides.
BB 43869: Remove prefs for touch.
RFP now overrides them.
- - - - -
11 changed files:
- browser/app/profile/001-base-profile.js
- dom/base/Element.cpp
- dom/events/PointerEvent.cpp
- dom/events/PointerEvent.h
- dom/events/PointerEventHandler.cpp
- dom/events/TouchEvent.cpp
- dom/webidl/PointerEvent.webidl
- layout/base/PositionedEventTargeting.cpp
- toolkit/components/resistfingerprinting/RFPTargets.inc
- toolkit/components/resistfingerprinting/nsRFPService.cpp
- widget/WidgetEventImpl.cpp
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -497,12 +497,6 @@ pref("dom.webmidi.enabled", false); // Bug 41398: Disable Web MIDI API
// randomized IDs when this pref is true).
// Defense-in-depth (already the default value) from Firefox 119 or 120.
pref("media.devices.enumerate.legacy.enabled", false);
-// Touch events (tor-browser#10286, tor-browser#42069, tor-browser#44062)
-#if defined(XP_WIN) || defined(ANDROID)
-pref("dom.w3c_touch_events.enabled", 1);
-#else
-pref("dom.w3c_touch_events.enabled", 0);
-#endif
#ifndef ANDROID
// Bug 42138: Disable touch-based overscroll UX
pref("apz.overscroll.enabled", false);
=====================================
dom/base/Element.cpp
=====================================
@@ -302,11 +302,6 @@ nsDOMAttributeMap* Element::Attributes() {
}
void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
- if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
- aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
- aError.ThrowNotFoundError("Invalid pointer id");
- return;
- }
const PointerInfo* pointerInfo =
PointerEventHandler::GetPointerInfo(aPointerId);
if (!pointerInfo) {
@@ -334,11 +329,6 @@ void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
}
void Element::ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError) {
- if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
- aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
- aError.ThrowNotFoundError("Invalid pointer id");
- return;
- }
if (!PointerEventHandler::GetPointerInfo(aPointerId)) {
aError.ThrowNotFoundError("Invalid pointer id");
return;
=====================================
dom/events/PointerEvent.cpp
=====================================
@@ -224,39 +224,78 @@ NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
NS_IMPL_ADDREF_INHERITED(PointerEvent, MouseEvent)
NS_IMPL_RELEASE_INHERITED(PointerEvent, MouseEvent)
-void PointerEvent::GetPointerType(nsAString& aPointerType) {
+uint16_t PointerEvent::ResistantInputSource(CallerType aCallerType) const {
+ const uint16_t inputSource = mEvent->AsPointerEvent()->mInputSource;
+ if (!ShouldResistFingerprinting(aCallerType)) {
+ return inputSource;
+ }
+
+ MOZ_ASSERT(IsTrusted());
+
+ // Bug 1953665: Pen events are inconsistent between platforms.
+ // They might emit touch events on Windows and Android, but only mouse events
+ // in other platforms. In particular, touch is always disabled on macOS.
+#if defined(XP_WIN)
+ if (inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH ||
+ inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
+ return inputSource;
+ }
+ // Similar to nsWindow::DispatchTouchEventFromWMPointer.
+ switch (mEvent->mMessage) {
+ case ePointerMove:
+ return mEvent->AsPointerEvent()->mPressure == 0
+ ? MouseEvent_Binding::MOZ_SOURCE_MOUSE // hover
+ : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+ case ePointerUp:
+ case ePointerDown:
+ case ePointerCancel:
+ return MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+ default:
+ return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+ }
+#elif defined(MOZ_WIDGET_ANDROID)
+ return inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE
+ ? MouseEvent_Binding::MOZ_SOURCE_MOUSE
+ : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+#elif defined(MOZ_WIDGET_GTK)
+ return inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH
+ ? MouseEvent_Binding::MOZ_SOURCE_TOUCH
+ : MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+#elif defined(MOZ_WIDGET_COCOA)
+ return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+#else
+ return inputSource;
+#endif
+}
+
+void PointerEvent::GetPointerType(nsAString& aPointerType,
+ CallerType aCallerType) {
if (mPointerType.isSome()) {
aPointerType = mPointerType.value();
return;
}
-
-#if SPOOFED_MAX_TOUCH_POINTS <= 0
- if (ShouldResistFingerprinting()) {
- aPointerType.AssignLiteral("mouse");
- return;
- }
-#endif
-
- ConvertPointerTypeToString(mEvent->AsPointerEvent()->mInputSource,
- aPointerType);
+ ConvertPointerTypeToString(ResistantInputSource(aCallerType), aPointerType);
}
int32_t PointerEvent::PointerId() {
- return (ShouldResistFingerprinting(true))
- ? PointerEventHandler::GetSpoofedPointerIdForRFP()
- : mEvent->AsPointerEvent()->pointerId;
+ return mEvent->AsPointerEvent()->pointerId;
}
-double PointerEvent::Width() const {
- return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mWidth;
+double PointerEvent::Width(CallerType aCallerType) const {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 1.0
+ : mEvent->AsPointerEvent()->mWidth;
}
-double PointerEvent::Height() const {
- return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mHeight;
+double PointerEvent::Height(CallerType aCallerType) const {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 1.0
+ : mEvent->AsPointerEvent()->mHeight;
}
-float PointerEvent::Pressure() {
- if (mEvent->mMessage == ePointerUp || !ShouldResistFingerprinting()) {
+float PointerEvent::Pressure(CallerType aCallerType) {
+ if (mEvent->mMessage == ePointerUp ||
+ !ShouldResistFingerprinting(aCallerType)) {
return mEvent->AsPointerEvent()->mPressure;
}
@@ -273,14 +312,14 @@ float PointerEvent::Pressure() {
return spoofedPressure;
}
-float PointerEvent::TangentialPressure() {
- return ShouldResistFingerprinting()
+float PointerEvent::TangentialPressure(CallerType aCallerType) {
+ return ShouldResistFingerprinting(aCallerType)
? 0
: mEvent->AsPointerEvent()->tangentialPressure;
}
-int32_t PointerEvent::TiltX() {
- if (ShouldResistFingerprinting()) {
+int32_t PointerEvent::TiltX(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return 0;
}
if (mTiltX.isSome()) {
@@ -291,8 +330,8 @@ int32_t PointerEvent::TiltX() {
return *mTiltX;
}
-int32_t PointerEvent::TiltY() {
- if (ShouldResistFingerprinting()) {
+int32_t PointerEvent::TiltY(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return 0;
}
if (mTiltY.isSome()) {
@@ -303,12 +342,14 @@ int32_t PointerEvent::TiltY() {
return *mTiltY;
}
-int32_t PointerEvent::Twist() {
- return ShouldResistFingerprinting() ? 0 : mEvent->AsPointerEvent()->twist;
+int32_t PointerEvent::Twist(CallerType aCallerType) {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 0
+ : mEvent->AsPointerEvent()->twist;
}
-double PointerEvent::AltitudeAngle() {
- if (ShouldResistFingerprinting()) {
+double PointerEvent::AltitudeAngle(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return WidgetPointerHelper::GetDefaultAltitudeAngle();
}
if (mAltitudeAngle.isSome()) {
@@ -319,8 +360,8 @@ double PointerEvent::AltitudeAngle() {
return *mAltitudeAngle;
}
-double PointerEvent::AzimuthAngle() {
- if (ShouldResistFingerprinting()) {
+double PointerEvent::AzimuthAngle(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return WidgetPointerHelper::GetDefaultAzimuthAngle();
}
if (mAzimuthAngle.isSome()) {
@@ -421,22 +462,22 @@ void PointerEvent::GetPredictedEvents(
aPointerEvents.AppendElements(mPredictedEvents);
}
-bool PointerEvent::ShouldResistFingerprinting(bool aForPointerId) const {
- // There are three simple situations we don't need to spoof this pointer
+bool PointerEvent::ShouldResistFingerprinting(CallerType aCallerType) const {
+ // There are a few simple situations we don't need to spoof this pointer
// event.
- // 1. The pref privcy.resistFingerprinting' is false, we fast return here
- // since we don't need to do any QI of following codes.
- // 2. This event is generated by scripts.
- // 3. This event is a mouse pointer event.
+ // * We are being called by a System caller
+ // * The pref privcy.resistFingerprinting' is false, we fast return here
+ // since we don't need to do any QI of following codes.
+ // * This event is generated by scripts.
+ // * This event is a mouse pointer event.
// We don't need to check for the system group since pointer events won't be
// dispatched to the system group.
- RFPTarget target =
- aForPointerId ? RFPTarget::PointerId : RFPTarget::PointerEvents;
- if (!nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
+ RFPTarget target = RFPTarget::PointerEvents;
+ if (aCallerType == CallerType::System ||
+ !nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
!mEvent->IsTrusted() ||
- (mEvent->AsPointerEvent()->mInputSource ==
- MouseEvent_Binding::MOZ_SOURCE_MOUSE &&
- SPOOFED_MAX_TOUCH_POINTS == 0)) {
+ mEvent->AsPointerEvent()->mInputSource ==
+ MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
return false;
}
=====================================
dom/events/PointerEvent.h
=====================================
@@ -41,17 +41,19 @@ class PointerEvent : public MouseEvent {
PointerEvent* AsPointerEvent() final { return this; }
int32_t PointerId();
- double Width() const;
- double Height() const;
- float Pressure();
- float TangentialPressure();
- int32_t TiltX();
- int32_t TiltY();
- int32_t Twist();
- double AltitudeAngle();
- double AzimuthAngle();
+ double Width(CallerType aCallerType = CallerType::System) const;
+ double Height(CallerType aCallerType = CallerType::System) const;
+ float Pressure(CallerType aCallerType = CallerType::System);
+ float TangentialPressure(CallerType aCallerType = CallerType::System);
+ int32_t TiltX(CallerType aCallerType = CallerType::System);
+ int32_t TiltY(CallerType aCallerType = CallerType::System);
+ int32_t Twist(CallerType aCallerType = CallerType::System);
+ double AltitudeAngle(CallerType aCallerType = CallerType::System);
+ double AzimuthAngle(CallerType aCallerType = CallerType::System);
bool IsPrimary();
- void GetPointerType(nsAString& aPointerType);
+ void GetPointerType(
+ nsAString& aPointerType,
+ mozilla::dom::CallerType aCallerType = CallerType::System);
static bool EnableGetCoalescedEvents(JSContext* aCx, JSObject* aGlobal);
void GetCoalescedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
void GetPredictedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
@@ -62,7 +64,11 @@ class PointerEvent : public MouseEvent {
private:
// This method returns the boolean to indicate whether spoofing pointer
// event for fingerprinting resistance.
- bool ShouldResistFingerprinting(bool aForPointerId = false) const;
+ bool ShouldResistFingerprinting(
+ CallerType aCallerType = CallerType::System) const;
+
+ uint16_t ResistantInputSource(
+ CallerType aCallerType = CallerType::System) const;
// When the instance is a trusted `pointermove` event but the widget event
// does not have proper coalesced events (typically, the event is synthesized
=====================================
dom/events/PointerEventHandler.cpp
=====================================
@@ -421,32 +421,6 @@ void PointerEventHandler::CheckPointerCaptureState(WidgetPointerEvent* aEvent) {
PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aEvent->pointerId);
- // When fingerprinting resistance is enabled, we need to map other pointer
- // ids into the spoofed one. We don't have to do the mapping if the capture
- // info exists for the non-spoofed pointer id because of we won't allow
- // content to set pointer capture other than the spoofed one. Thus, it must be
- // from chrome if the capture info exists in this case. And we don't have to
- // do anything if the pointer id is the same as the spoofed one.
- if (nsContentUtils::ShouldResistFingerprinting("Efficiency Check",
- RFPTarget::PointerId) &&
- aEvent->pointerId != (uint32_t)GetSpoofedPointerIdForRFP() &&
- !captureInfo) {
- PointerCaptureInfo* spoofedCaptureInfo =
- GetPointerCaptureInfo(GetSpoofedPointerIdForRFP());
-
- // We need to check the target element's document should resist
- // fingerprinting. If not, we don't need to send a capture event
- // since the capture info of the original pointer id doesn't exist
- // in this case.
- if (!spoofedCaptureInfo || !spoofedCaptureInfo->mPendingElement ||
- !spoofedCaptureInfo->mPendingElement->OwnerDoc()
- ->ShouldResistFingerprinting(RFPTarget::PointerEvents)) {
- return;
- }
-
- captureInfo = spoofedCaptureInfo;
- }
-
if (!captureInfo ||
captureInfo->mPendingElement == captureInfo->mOverrideElement) {
return;
=====================================
dom/events/TouchEvent.cpp
=====================================
@@ -225,38 +225,40 @@ bool TouchEvent::PrefEnabled(nsIDocShell* aDocShell) {
} else if (touchEventsOverride ==
mozilla::dom::TouchEventsOverride::Disabled) {
enabled = false;
+ } else if (nsContentUtils::ShouldResistFingerprinting(
+ aDocShell, RFPTarget::PointerEvents)) {
+#ifdef MOZ_WIDGET_COCOA
+ enabled = false;
+#else
+ enabled = true;
+#endif
} else {
const int32_t prefValue = StaticPrefs::dom_w3c_touch_events_enabled();
if (prefValue == 2) {
- if (nsContentUtils::ShouldResistFingerprinting(
- aDocShell, RFPTarget::PointerEvents)) {
- enabled = SPOOFED_MAX_TOUCH_POINTS != 0;
- } else {
- enabled = PlatformSupportsTouch();
-
- static bool firstTime = true;
- // The touch screen data seems to be inaccurate in the parent process,
- // and we really need the crash annotation in child processes.
- if (firstTime && !XRE_IsParentProcess()) {
- CrashReporter::RecordAnnotationBool(
- CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
- firstTime = false;
- }
+ enabled = PlatformSupportsTouch();
+
+ static bool firstTime = true;
+ // The touch screen data seems to be inaccurate in the parent process,
+ // and we really need the crash annotation in child processes.
+ if (firstTime && !XRE_IsParentProcess()) {
+ CrashReporter::RecordAnnotationBool(
+ CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
+ firstTime = false;
+ }
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
- if (enabled && aDocShell) {
- // APZ might be disabled on this particular widget, in which case
- // TouchEvent support will also be disabled. Try to detect that.
- RefPtr<nsPresContext> pc = aDocShell->GetPresContext();
- if (pc) {
- nsCOMPtr<nsIWidget> widget = pc->GetRootWidget();
- if (widget) {
- enabled &= widget->AsyncPanZoomEnabled();
- }
+ if (enabled && aDocShell) {
+ // APZ might be disabled on this particular widget, in which case
+ // TouchEvent support will also be disabled. Try to detect that.
+ RefPtr<nsPresContext> pc = aDocShell->GetPresContext();
+ if (pc) {
+ nsCOMPtr<nsIWidget> widget = pc->GetRootWidget();
+ if (widget) {
+ enabled &= widget->AsyncPanZoomEnabled();
}
}
-#endif
}
+#endif
} else {
enabled = !!prefValue;
}
=====================================
dom/webidl/PointerEvent.webidl
=====================================
@@ -14,16 +14,26 @@ interface PointerEvent : MouseEvent
readonly attribute long pointerId;
+ [NeedsCallerType]
readonly attribute double width;
+ [NeedsCallerType]
readonly attribute double height;
+ [NeedsCallerType]
readonly attribute float pressure;
+ [NeedsCallerType]
readonly attribute float tangentialPressure;
+ [NeedsCallerType]
readonly attribute long tiltX;
+ [NeedsCallerType]
readonly attribute long tiltY;
+ [NeedsCallerType]
readonly attribute long twist;
+ [NeedsCallerType]
readonly attribute double altitudeAngle;
+ [NeedsCallerType]
readonly attribute double azimuthAngle;
+ [NeedsCallerType]
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
=====================================
layout/base/PositionedEventTargeting.cpp
=====================================
@@ -16,6 +16,7 @@
#include "mozilla/ToString.h"
#include "mozilla/ViewportUtils.h"
#include "mozilla/dom/MouseEventBinding.h"
+#include "mozilla/dom/TouchEvent.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsContainerFrame.h"
@@ -173,9 +174,7 @@ static bool HasTouchListener(const nsIContent* aContent) {
return false;
}
- // FIXME: Should this really use the pref rather than TouchEvent::PrefEnabled
- // or such?
- if (!StaticPrefs::dom_w3c_touch_events_enabled()) {
+ if (!TouchEvent::PrefEnabled(aContent->OwnerDoc()->GetDocShell())) {
return false;
}
=====================================
toolkit/components/resistfingerprinting/RFPTargets.inc
=====================================
@@ -34,7 +34,7 @@ ITEM_VALUE(NavigatorHWConcurrency, 16)
ITEM_VALUE(NavigatorOscpu, 17)
ITEM_VALUE(NavigatorPlatform, 18)
ITEM_VALUE(NavigatorUserAgent, 19)
-ITEM_VALUE(PointerId, 20)
+// We no longer use PointerId, it can renamed and reused
ITEM_VALUE(StreamVideoFacingMode, 21)
ITEM_VALUE(JSDateTimeUTC, 22)
ITEM_VALUE(JSMathFdlibm, 23)
@@ -104,6 +104,7 @@ ITEM_VALUE(DiskStorageLimit, 70)
ITEM_VALUE(WebCodecs, 71)
ITEM_VALUE(NavigatorHWConcurrencyTiered,74)
+// !!! Adding a new target? Rename PointerId and repurpose it.
// !!! Don't forget to update kDefaultFingerprintingProtections in nsRFPService.cpp
// if necessary.
=====================================
toolkit/components/resistfingerprinting/nsRFPService.cpp
=====================================
@@ -303,13 +303,6 @@ Maybe<bool> nsRFPService::HandleExeptionalRFPTargets(
StaticPrefs::privacy_spoof_english_DoNotUseDirectly() == 2);
}
- // We don't spoof the pointerId on multi-touch devices.
-#if SPOOFED_MAX_TOUCH_POINTS > 0
- if (aTarget == RFPTarget::PointerId) {
- return Some(false);
- }
-#endif
-
return Nothing();
}
=====================================
widget/WidgetEventImpl.cpp
=====================================
@@ -589,23 +589,6 @@ bool WidgetEvent::IsBlockedForFingerprintingResistance() const {
keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_Control ||
keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_AltGraph);
}
- case ePointerEventClass: {
- if (IsPointerEventMessageOriginallyMouseEventMessage(mMessage)) {
- return false;
- }
-
- if (SPOOFED_MAX_TOUCH_POINTS > 0) {
- return false;
- }
-
- const WidgetPointerEvent* pointerEvent = AsPointerEvent();
-
- // We suppress the pointer events if it is not primary for fingerprinting
- // resistance. It is because of that we want to spoof any pointer event
- // into a mouse pointer event and the mouse pointer event only has
- // isPrimary as true.
- return !pointerEvent->mIsPrimary;
- }
default:
return false;
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2c531e…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2c531e…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.4.0esr-15.0-1] 2 commits: BB 43869: Hide pens with RFP.
by morgan (ï¼ morgan) 15 Oct '25
by morgan (ï¼ morgan) 15 Oct '25
15 Oct '25
morgan pushed to branch tor-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
84fb1585 by Pier Angelo Vendrame at 2025-10-15T13:23:33+00:00
BB 43869: Hide pens with RFP.
- - - - -
be15e46e by Pier Angelo Vendrame at 2025-10-15T13:23:33+00:00
fixup! Firefox preference overrides.
BB 43869: Remove prefs for touch.
RFP now overrides them.
- - - - -
11 changed files:
- browser/app/profile/001-base-profile.js
- dom/base/Element.cpp
- dom/events/PointerEvent.cpp
- dom/events/PointerEvent.h
- dom/events/PointerEventHandler.cpp
- dom/events/TouchEvent.cpp
- dom/webidl/PointerEvent.webidl
- layout/base/PositionedEventTargeting.cpp
- toolkit/components/resistfingerprinting/RFPTargets.inc
- toolkit/components/resistfingerprinting/nsRFPService.cpp
- widget/WidgetEventImpl.cpp
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -497,12 +497,6 @@ pref("dom.webmidi.enabled", false); // Bug 41398: Disable Web MIDI API
// randomized IDs when this pref is true).
// Defense-in-depth (already the default value) from Firefox 119 or 120.
pref("media.devices.enumerate.legacy.enabled", false);
-// Touch events (tor-browser#10286, tor-browser#42069, tor-browser#44062)
-#if defined(XP_WIN) || defined(ANDROID)
-pref("dom.w3c_touch_events.enabled", 1);
-#else
-pref("dom.w3c_touch_events.enabled", 0);
-#endif
#ifndef ANDROID
// Bug 42138: Disable touch-based overscroll UX
pref("apz.overscroll.enabled", false);
=====================================
dom/base/Element.cpp
=====================================
@@ -302,11 +302,6 @@ nsDOMAttributeMap* Element::Attributes() {
}
void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
- if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
- aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
- aError.ThrowNotFoundError("Invalid pointer id");
- return;
- }
const PointerInfo* pointerInfo =
PointerEventHandler::GetPointerInfo(aPointerId);
if (!pointerInfo) {
@@ -334,11 +329,6 @@ void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
}
void Element::ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError) {
- if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
- aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
- aError.ThrowNotFoundError("Invalid pointer id");
- return;
- }
if (!PointerEventHandler::GetPointerInfo(aPointerId)) {
aError.ThrowNotFoundError("Invalid pointer id");
return;
=====================================
dom/events/PointerEvent.cpp
=====================================
@@ -224,39 +224,78 @@ NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
NS_IMPL_ADDREF_INHERITED(PointerEvent, MouseEvent)
NS_IMPL_RELEASE_INHERITED(PointerEvent, MouseEvent)
-void PointerEvent::GetPointerType(nsAString& aPointerType) {
+uint16_t PointerEvent::ResistantInputSource(CallerType aCallerType) const {
+ const uint16_t inputSource = mEvent->AsPointerEvent()->mInputSource;
+ if (!ShouldResistFingerprinting(aCallerType)) {
+ return inputSource;
+ }
+
+ MOZ_ASSERT(IsTrusted());
+
+ // Bug 1953665: Pen events are inconsistent between platforms.
+ // They might emit touch events on Windows and Android, but only mouse events
+ // in other platforms. In particular, touch is always disabled on macOS.
+#if defined(XP_WIN)
+ if (inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH ||
+ inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
+ return inputSource;
+ }
+ // Similar to nsWindow::DispatchTouchEventFromWMPointer.
+ switch (mEvent->mMessage) {
+ case ePointerMove:
+ return mEvent->AsPointerEvent()->mPressure == 0
+ ? MouseEvent_Binding::MOZ_SOURCE_MOUSE // hover
+ : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+ case ePointerUp:
+ case ePointerDown:
+ case ePointerCancel:
+ return MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+ default:
+ return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+ }
+#elif defined(MOZ_WIDGET_ANDROID)
+ return inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE
+ ? MouseEvent_Binding::MOZ_SOURCE_MOUSE
+ : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
+#elif defined(MOZ_WIDGET_GTK)
+ return inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH
+ ? MouseEvent_Binding::MOZ_SOURCE_TOUCH
+ : MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+#elif defined(MOZ_WIDGET_COCOA)
+ return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
+#else
+ return inputSource;
+#endif
+}
+
+void PointerEvent::GetPointerType(nsAString& aPointerType,
+ CallerType aCallerType) {
if (mPointerType.isSome()) {
aPointerType = mPointerType.value();
return;
}
-
-#if SPOOFED_MAX_TOUCH_POINTS <= 0
- if (ShouldResistFingerprinting()) {
- aPointerType.AssignLiteral("mouse");
- return;
- }
-#endif
-
- ConvertPointerTypeToString(mEvent->AsPointerEvent()->mInputSource,
- aPointerType);
+ ConvertPointerTypeToString(ResistantInputSource(aCallerType), aPointerType);
}
int32_t PointerEvent::PointerId() {
- return (ShouldResistFingerprinting(true))
- ? PointerEventHandler::GetSpoofedPointerIdForRFP()
- : mEvent->AsPointerEvent()->pointerId;
+ return mEvent->AsPointerEvent()->pointerId;
}
-double PointerEvent::Width() const {
- return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mWidth;
+double PointerEvent::Width(CallerType aCallerType) const {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 1.0
+ : mEvent->AsPointerEvent()->mWidth;
}
-double PointerEvent::Height() const {
- return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mHeight;
+double PointerEvent::Height(CallerType aCallerType) const {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 1.0
+ : mEvent->AsPointerEvent()->mHeight;
}
-float PointerEvent::Pressure() {
- if (mEvent->mMessage == ePointerUp || !ShouldResistFingerprinting()) {
+float PointerEvent::Pressure(CallerType aCallerType) {
+ if (mEvent->mMessage == ePointerUp ||
+ !ShouldResistFingerprinting(aCallerType)) {
return mEvent->AsPointerEvent()->mPressure;
}
@@ -273,14 +312,14 @@ float PointerEvent::Pressure() {
return spoofedPressure;
}
-float PointerEvent::TangentialPressure() {
- return ShouldResistFingerprinting()
+float PointerEvent::TangentialPressure(CallerType aCallerType) {
+ return ShouldResistFingerprinting(aCallerType)
? 0
: mEvent->AsPointerEvent()->tangentialPressure;
}
-int32_t PointerEvent::TiltX() {
- if (ShouldResistFingerprinting()) {
+int32_t PointerEvent::TiltX(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return 0;
}
if (mTiltX.isSome()) {
@@ -291,8 +330,8 @@ int32_t PointerEvent::TiltX() {
return *mTiltX;
}
-int32_t PointerEvent::TiltY() {
- if (ShouldResistFingerprinting()) {
+int32_t PointerEvent::TiltY(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return 0;
}
if (mTiltY.isSome()) {
@@ -303,12 +342,14 @@ int32_t PointerEvent::TiltY() {
return *mTiltY;
}
-int32_t PointerEvent::Twist() {
- return ShouldResistFingerprinting() ? 0 : mEvent->AsPointerEvent()->twist;
+int32_t PointerEvent::Twist(CallerType aCallerType) {
+ return ShouldResistFingerprinting(aCallerType)
+ ? 0
+ : mEvent->AsPointerEvent()->twist;
}
-double PointerEvent::AltitudeAngle() {
- if (ShouldResistFingerprinting()) {
+double PointerEvent::AltitudeAngle(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return WidgetPointerHelper::GetDefaultAltitudeAngle();
}
if (mAltitudeAngle.isSome()) {
@@ -319,8 +360,8 @@ double PointerEvent::AltitudeAngle() {
return *mAltitudeAngle;
}
-double PointerEvent::AzimuthAngle() {
- if (ShouldResistFingerprinting()) {
+double PointerEvent::AzimuthAngle(CallerType aCallerType) {
+ if (ShouldResistFingerprinting(aCallerType)) {
return WidgetPointerHelper::GetDefaultAzimuthAngle();
}
if (mAzimuthAngle.isSome()) {
@@ -421,22 +462,22 @@ void PointerEvent::GetPredictedEvents(
aPointerEvents.AppendElements(mPredictedEvents);
}
-bool PointerEvent::ShouldResistFingerprinting(bool aForPointerId) const {
- // There are three simple situations we don't need to spoof this pointer
+bool PointerEvent::ShouldResistFingerprinting(CallerType aCallerType) const {
+ // There are a few simple situations we don't need to spoof this pointer
// event.
- // 1. The pref privcy.resistFingerprinting' is false, we fast return here
- // since we don't need to do any QI of following codes.
- // 2. This event is generated by scripts.
- // 3. This event is a mouse pointer event.
+ // * We are being called by a System caller
+ // * The pref privcy.resistFingerprinting' is false, we fast return here
+ // since we don't need to do any QI of following codes.
+ // * This event is generated by scripts.
+ // * This event is a mouse pointer event.
// We don't need to check for the system group since pointer events won't be
// dispatched to the system group.
- RFPTarget target =
- aForPointerId ? RFPTarget::PointerId : RFPTarget::PointerEvents;
- if (!nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
+ RFPTarget target = RFPTarget::PointerEvents;
+ if (aCallerType == CallerType::System ||
+ !nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
!mEvent->IsTrusted() ||
- (mEvent->AsPointerEvent()->mInputSource ==
- MouseEvent_Binding::MOZ_SOURCE_MOUSE &&
- SPOOFED_MAX_TOUCH_POINTS == 0)) {
+ mEvent->AsPointerEvent()->mInputSource ==
+ MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
return false;
}
=====================================
dom/events/PointerEvent.h
=====================================
@@ -41,17 +41,19 @@ class PointerEvent : public MouseEvent {
PointerEvent* AsPointerEvent() final { return this; }
int32_t PointerId();
- double Width() const;
- double Height() const;
- float Pressure();
- float TangentialPressure();
- int32_t TiltX();
- int32_t TiltY();
- int32_t Twist();
- double AltitudeAngle();
- double AzimuthAngle();
+ double Width(CallerType aCallerType = CallerType::System) const;
+ double Height(CallerType aCallerType = CallerType::System) const;
+ float Pressure(CallerType aCallerType = CallerType::System);
+ float TangentialPressure(CallerType aCallerType = CallerType::System);
+ int32_t TiltX(CallerType aCallerType = CallerType::System);
+ int32_t TiltY(CallerType aCallerType = CallerType::System);
+ int32_t Twist(CallerType aCallerType = CallerType::System);
+ double AltitudeAngle(CallerType aCallerType = CallerType::System);
+ double AzimuthAngle(CallerType aCallerType = CallerType::System);
bool IsPrimary();
- void GetPointerType(nsAString& aPointerType);
+ void GetPointerType(
+ nsAString& aPointerType,
+ mozilla::dom::CallerType aCallerType = CallerType::System);
static bool EnableGetCoalescedEvents(JSContext* aCx, JSObject* aGlobal);
void GetCoalescedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
void GetPredictedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
@@ -62,7 +64,11 @@ class PointerEvent : public MouseEvent {
private:
// This method returns the boolean to indicate whether spoofing pointer
// event for fingerprinting resistance.
- bool ShouldResistFingerprinting(bool aForPointerId = false) const;
+ bool ShouldResistFingerprinting(
+ CallerType aCallerType = CallerType::System) const;
+
+ uint16_t ResistantInputSource(
+ CallerType aCallerType = CallerType::System) const;
// When the instance is a trusted `pointermove` event but the widget event
// does not have proper coalesced events (typically, the event is synthesized
=====================================
dom/events/PointerEventHandler.cpp
=====================================
@@ -421,32 +421,6 @@ void PointerEventHandler::CheckPointerCaptureState(WidgetPointerEvent* aEvent) {
PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aEvent->pointerId);
- // When fingerprinting resistance is enabled, we need to map other pointer
- // ids into the spoofed one. We don't have to do the mapping if the capture
- // info exists for the non-spoofed pointer id because of we won't allow
- // content to set pointer capture other than the spoofed one. Thus, it must be
- // from chrome if the capture info exists in this case. And we don't have to
- // do anything if the pointer id is the same as the spoofed one.
- if (nsContentUtils::ShouldResistFingerprinting("Efficiency Check",
- RFPTarget::PointerId) &&
- aEvent->pointerId != (uint32_t)GetSpoofedPointerIdForRFP() &&
- !captureInfo) {
- PointerCaptureInfo* spoofedCaptureInfo =
- GetPointerCaptureInfo(GetSpoofedPointerIdForRFP());
-
- // We need to check the target element's document should resist
- // fingerprinting. If not, we don't need to send a capture event
- // since the capture info of the original pointer id doesn't exist
- // in this case.
- if (!spoofedCaptureInfo || !spoofedCaptureInfo->mPendingElement ||
- !spoofedCaptureInfo->mPendingElement->OwnerDoc()
- ->ShouldResistFingerprinting(RFPTarget::PointerEvents)) {
- return;
- }
-
- captureInfo = spoofedCaptureInfo;
- }
-
if (!captureInfo ||
captureInfo->mPendingElement == captureInfo->mOverrideElement) {
return;
=====================================
dom/events/TouchEvent.cpp
=====================================
@@ -225,38 +225,40 @@ bool TouchEvent::PrefEnabled(nsIDocShell* aDocShell) {
} else if (touchEventsOverride ==
mozilla::dom::TouchEventsOverride::Disabled) {
enabled = false;
+ } else if (nsContentUtils::ShouldResistFingerprinting(
+ aDocShell, RFPTarget::PointerEvents)) {
+#ifdef MOZ_WIDGET_COCOA
+ enabled = false;
+#else
+ enabled = true;
+#endif
} else {
const int32_t prefValue = StaticPrefs::dom_w3c_touch_events_enabled();
if (prefValue == 2) {
- if (nsContentUtils::ShouldResistFingerprinting(
- aDocShell, RFPTarget::PointerEvents)) {
- enabled = SPOOFED_MAX_TOUCH_POINTS != 0;
- } else {
- enabled = PlatformSupportsTouch();
-
- static bool firstTime = true;
- // The touch screen data seems to be inaccurate in the parent process,
- // and we really need the crash annotation in child processes.
- if (firstTime && !XRE_IsParentProcess()) {
- CrashReporter::RecordAnnotationBool(
- CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
- firstTime = false;
- }
+ enabled = PlatformSupportsTouch();
+
+ static bool firstTime = true;
+ // The touch screen data seems to be inaccurate in the parent process,
+ // and we really need the crash annotation in child processes.
+ if (firstTime && !XRE_IsParentProcess()) {
+ CrashReporter::RecordAnnotationBool(
+ CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
+ firstTime = false;
+ }
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
- if (enabled && aDocShell) {
- // APZ might be disabled on this particular widget, in which case
- // TouchEvent support will also be disabled. Try to detect that.
- RefPtr<nsPresContext> pc = aDocShell->GetPresContext();
- if (pc) {
- nsCOMPtr<nsIWidget> widget = pc->GetRootWidget();
- if (widget) {
- enabled &= widget->AsyncPanZoomEnabled();
- }
+ if (enabled && aDocShell) {
+ // APZ might be disabled on this particular widget, in which case
+ // TouchEvent support will also be disabled. Try to detect that.
+ RefPtr<nsPresContext> pc = aDocShell->GetPresContext();
+ if (pc) {
+ nsCOMPtr<nsIWidget> widget = pc->GetRootWidget();
+ if (widget) {
+ enabled &= widget->AsyncPanZoomEnabled();
}
}
-#endif
}
+#endif
} else {
enabled = !!prefValue;
}
=====================================
dom/webidl/PointerEvent.webidl
=====================================
@@ -14,16 +14,26 @@ interface PointerEvent : MouseEvent
readonly attribute long pointerId;
+ [NeedsCallerType]
readonly attribute double width;
+ [NeedsCallerType]
readonly attribute double height;
+ [NeedsCallerType]
readonly attribute float pressure;
+ [NeedsCallerType]
readonly attribute float tangentialPressure;
+ [NeedsCallerType]
readonly attribute long tiltX;
+ [NeedsCallerType]
readonly attribute long tiltY;
+ [NeedsCallerType]
readonly attribute long twist;
+ [NeedsCallerType]
readonly attribute double altitudeAngle;
+ [NeedsCallerType]
readonly attribute double azimuthAngle;
+ [NeedsCallerType]
readonly attribute DOMString pointerType;
readonly attribute boolean isPrimary;
=====================================
layout/base/PositionedEventTargeting.cpp
=====================================
@@ -16,6 +16,7 @@
#include "mozilla/ToString.h"
#include "mozilla/ViewportUtils.h"
#include "mozilla/dom/MouseEventBinding.h"
+#include "mozilla/dom/TouchEvent.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsContainerFrame.h"
@@ -173,9 +174,7 @@ static bool HasTouchListener(const nsIContent* aContent) {
return false;
}
- // FIXME: Should this really use the pref rather than TouchEvent::PrefEnabled
- // or such?
- if (!StaticPrefs::dom_w3c_touch_events_enabled()) {
+ if (!TouchEvent::PrefEnabled(aContent->OwnerDoc()->GetDocShell())) {
return false;
}
=====================================
toolkit/components/resistfingerprinting/RFPTargets.inc
=====================================
@@ -34,7 +34,7 @@ ITEM_VALUE(NavigatorHWConcurrency, 16)
ITEM_VALUE(NavigatorOscpu, 17)
ITEM_VALUE(NavigatorPlatform, 18)
ITEM_VALUE(NavigatorUserAgent, 19)
-ITEM_VALUE(PointerId, 20)
+// We no longer use PointerId, it can renamed and reused
ITEM_VALUE(StreamVideoFacingMode, 21)
ITEM_VALUE(JSDateTimeUTC, 22)
ITEM_VALUE(JSMathFdlibm, 23)
@@ -104,6 +104,7 @@ ITEM_VALUE(DiskStorageLimit, 70)
ITEM_VALUE(WebCodecs, 71)
ITEM_VALUE(NavigatorHWConcurrencyTiered,74)
+// !!! Adding a new target? Rename PointerId and repurpose it.
// !!! Don't forget to update kDefaultFingerprintingProtections in nsRFPService.cpp
// if necessary.
=====================================
toolkit/components/resistfingerprinting/nsRFPService.cpp
=====================================
@@ -303,13 +303,6 @@ Maybe<bool> nsRFPService::HandleExeptionalRFPTargets(
StaticPrefs::privacy_spoof_english_DoNotUseDirectly() == 2);
}
- // We don't spoof the pointerId on multi-touch devices.
-#if SPOOFED_MAX_TOUCH_POINTS > 0
- if (aTarget == RFPTarget::PointerId) {
- return Some(false);
- }
-#endif
-
#ifdef ANDROID
if (aTarget == RFPTarget::FontVisibilityBaseSystem ||
aTarget == RFPTarget::FontVisibilityLangPack) {
=====================================
widget/WidgetEventImpl.cpp
=====================================
@@ -589,23 +589,6 @@ bool WidgetEvent::IsBlockedForFingerprintingResistance() const {
keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_Control ||
keyboardEvent->mKeyNameIndex == KEY_NAME_INDEX_AltGraph);
}
- case ePointerEventClass: {
- if (IsPointerEventMessageOriginallyMouseEventMessage(mMessage)) {
- return false;
- }
-
- if (SPOOFED_MAX_TOUCH_POINTS > 0) {
- return false;
- }
-
- const WidgetPointerEvent* pointerEvent = AsPointerEvent();
-
- // We suppress the pointer events if it is not primary for fingerprinting
- // resistance. It is because of that we want to spoof any pointer event
- // into a mouse pointer event and the mouse pointer event only has
- // isPrimary as true.
- return !pointerEvent->mIsPrimary;
- }
default:
return false;
}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/7966a2…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/7966a2…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser-update-responses][main] release: new version, 14.5.9 (Android-only, amended)
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch main at The Tor Project / Applications / Tor Browser update responses
Commits:
5e9c60ba by hackademix at 2025-10-15T15:18:57+02:00
release: new version, 14.5.9 (Android-only, amended)
- - - - -
2 changed files:
- + update_3/release/.htaccess
- + update_3/release/downloads.json
Changes:
=====================================
update_3/release/.htaccess
=====================================
@@ -0,0 +1,23 @@
+RewriteEngine On
+# bug 26570: Redirect pre-8.0 stable users to a separate update directory
+RewriteRule ^[^/]+/[4567]\..*/.* https://aus1.torproject.org/torbrowser/update_pre8.0/release/$0 [last]
+# tor-browser-build#40678: Force all <=11.5.7 users to update through 11.5.8 before 12.0
+RewriteRule ^[^/]+/[89]\..*/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
+RewriteRule ^[^/]+/10\..*/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
+RewriteRule ^[^/]+/11\.0.*/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
+RewriteRule ^[^/]+/11\.5/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
+RewriteRule ^[^/]+/11\.5\.[01234567]/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
+# tor-browser-build#41270: make 13.5.7 a watershed update
+RewriteRule ^[^/]+/1[12]\.[05].*/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
+RewriteRule ^[^/]+/13\.0.*/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
+RewriteRule ^[^/]+/13\.5/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
+RewriteRule ^[^/]+/13\.5\.[0123456]/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
+RewriteRule ^Linux_aarch64-gcc3/(.*) linux-aarch64/$1 [last]
+RewriteRule ^Linux_x86-gcc3/(.*) linux-i686/$1 [last]
+RewriteRule ^Linux_x86_64-gcc3/(.*) linux-x86_64/$1 [last]
+RewriteRule ^Darwin_x86_64-gcc3/(.*) macos/$1 [last]
+RewriteRule ^Darwin_aarch64-gcc3/(.*) macos/$1 [last]
+RewriteRule ^WINNT_x86-gcc3/(.*) windows-i686/$1 [last]
+RewriteRule ^WINNT_x86-gcc3-x86/(.*) windows-i686/$1 [last]
+RewriteRule ^WINNT_x86-gcc3-x64/(.*) windows-i686/$1 [last]
+RewriteRule ^WINNT_x86_64-gcc3-x64/(.*) windows-x86_64/$1 [last]
=====================================
update_3/release/downloads.json
=====================================
@@ -0,0 +1,37 @@
+{
+ "comment" : "This file is deprecated and should not be used. Please use the files download-$platform.json instead.",
+ "downloads" : {
+ "linux-i686" : {
+ "ALL" : {
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-i686-14.5.8…",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-i686-14.5.8…"
+ }
+ },
+ "linux-x86_64" : {
+ "ALL" : {
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-x86_64-14.5…",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-x86_64-14.5…"
+ }
+ },
+ "macos" : {
+ "ALL" : {
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-macos-14.5.8.dmg",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-macos-14.5.8.dmg.…"
+ }
+ },
+ "win32" : {
+ "ALL" : {
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-i686-port…",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-i686-port…"
+ }
+ },
+ "win64" : {
+ "ALL" : {
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-x86_64-po…",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-x86_64-po…"
+ }
+ }
+ },
+ "tag" : "tbb-14.5.8-build1",
+ "version" : "14.5.8"
+}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-update-responses…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-update-responses…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.4.0esr-15.0-1] fixup! [android] Disable features and functionality
by morgan (ï¼ morgan) 15 Oct '25
by morgan (ï¼ morgan) 15 Oct '25
15 Oct '25
morgan pushed to branch tor-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
7966a205 by Dan Ballard at 2025-10-15T13:18:10+00:00
fixup! [android] Disable features and functionality
Bug 43676: preemptively disable unified trust panel by default so we are tracking for next ESR
- - - - -
1 changed file:
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
Changes:
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
=====================================
@@ -2090,7 +2090,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
*/
var enableUnifiedTrustPanel by booleanPreference(
key = appContext.getPreferenceKey(R.string.pref_key_enable_unified_trust_panel),
- default = FeatureFlags.UNIFIED_TRUST_PANEL,
+ default = false
)
/**
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/7966a20…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/7966a20…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.4.0esr-15.0-1] fixup! BB 40925: Implemented the Security Level component
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch tor-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
373460c6 by hackademix at 2025-10-15T12:36:16+02:00
fixup! BB 40925: Implemented the Security Level component
BB 44242: Hand over Security Level's WebAssembly controls to NoScript
- - - - -
1 changed file:
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
Changes:
=====================================
toolkit/components/securitylevel/SecurityLevel.sys.mjs
=====================================
@@ -79,6 +79,7 @@ const max_caps = [
"object",
"other",
"script",
+ "wasm",
"webgl",
"noscript",
];
@@ -247,7 +248,6 @@ var initializeNoScriptControl = () => {
// for each security setting. Note that 2-m and 3-m are identical,
// corresponding to the old 2-medium-high setting. We also separately
// bind NoScript settings to the browser.security_level.security_slider
-// (see noscript-control.js).
/* eslint-disable */
// prettier-ignore
const kSecuritySettings = {
@@ -260,7 +260,9 @@ const kSecuritySettings = {
"gfx.font_rendering.opentype_svg.enabled": [, false, false, false, true ],
"svg.disabled": [, true, false, false, false],
"javascript.options.asmjs": [, false, false, false, true ],
- "javascript.options.wasm": [, false, false, false, true ],
+ // tor-browser#44234, tor-browser#44242: this interferes with the correct
+ // functioning of the browser. So, WASM is also handled by NoScript now.
+ "javascript.options.wasm": [, true, true, true, true ],
};
/* eslint-enable */
@@ -327,16 +329,19 @@ var write_setting_to_prefs = function (settingIndex) {
// security settings matches. Otherwise return null.
var read_setting_from_prefs = function (prefNames) {
prefNames = prefNames || Object.keys(kSecuritySettings);
- for (let settingIndex of [1, 2, 3, 4]) {
+ for (const settingIndex of [1, 2, 3, 4]) {
let possibleSetting = true;
// For the given settingIndex, check if all current pref values
// match the setting.
- for (let prefName of prefNames) {
- if (
- kSecuritySettings[prefName][settingIndex] !==
- Services.prefs.getBoolPref(prefName)
- ) {
+ for (const prefName of prefNames) {
+ const wanted = kSecuritySettings[prefName][settingIndex];
+ const actual = Services.prefs.getBoolPref(prefName);
+ if (wanted !== actual) {
possibleSetting = false;
+ logger.info(
+ `${prefName} does not match level ${settingIndex}: ${actual}, should be ${wanted}!`
+ );
+ break;
}
}
if (possibleSetting) {
@@ -361,7 +366,7 @@ var initializeSecurityPrefs = function () {
if (initializedSecPrefs) {
return;
}
- logger.info("Initializing security-prefs.js");
+ logger.info("Initializing security level");
initializedSecPrefs = true;
const wasCustom = Services.prefs.getBoolPref(kCustomPref, false);
@@ -369,6 +374,21 @@ var initializeSecurityPrefs = function () {
// and it should not be custom.
let desiredIndex = Services.prefs.getIntPref(kSliderPref, 4);
desiredIndex = fixupIndex(desiredIndex);
+
+ if (!(wasCustom && desiredIndex == 4)) {
+ // The current level is non-customized Standard, or
+ // Safer / Safest (either customized or not): the global
+ // javascript.options.wasm pref interferes with the correct
+ // functioning of the browser, so instead we rely on NoScript
+ // to disable WebAssembly now (tor-browser#44234, tor-browser#44242).
+ // We skip flipping in customized Standard, because if its value was
+ // found false under such as circumstance, that would suggest
+ // an intentional user choice we don't want to interfere with.
+ // Unlike other javascript.options.* preferences, this one is safe
+ // to flip without a browser restart because it's checked whenever a
+ // context is created.
+ Services.prefs.setBoolPref("javascript.options.wasm", true);
+ }
// Make sure the user has a set preference user value.
Services.prefs.setIntPref(kSliderPref, desiredIndex);
Services.prefs.setBoolPref(kCustomPref, wasCustom);
@@ -448,7 +468,7 @@ var initializeSecurityPrefs = function () {
});
}
- logger.info("security-prefs.js initialization complete");
+ logger.info("Security level initialization complete");
};
// tor-browser#41460: we changed preference names in 12.0.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/373460c…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/373460c…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser-update-responses][main] release: new version, 14.5.9
by ma1 (ï¼ ma1) 15 Oct '25
by ma1 (ï¼ ma1) 15 Oct '25
15 Oct '25
ma1 pushed to branch main at The Tor Project / Applications / Tor Browser update responses
Commits:
0425ffc6 by hackademix at 2025-10-15T08:55:28+02:00
release: new version, 14.5.9
- - - - -
6 changed files:
- − update_3/release/.htaccess
- update_3/release/download-android-aarch64.json
- update_3/release/download-android-armv7.json
- update_3/release/download-android-x86.json
- update_3/release/download-android-x86_64.json
- − update_3/release/downloads.json
Changes:
=====================================
update_3/release/.htaccess deleted
=====================================
@@ -1,23 +0,0 @@
-RewriteEngine On
-# bug 26570: Redirect pre-8.0 stable users to a separate update directory
-RewriteRule ^[^/]+/[4567]\..*/.* https://aus1.torproject.org/torbrowser/update_pre8.0/release/$0 [last]
-# tor-browser-build#40678: Force all <=11.5.7 users to update through 11.5.8 before 12.0
-RewriteRule ^[^/]+/[89]\..*/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
-RewriteRule ^[^/]+/10\..*/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
-RewriteRule ^[^/]+/11\.0.*/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
-RewriteRule ^[^/]+/11\.5/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
-RewriteRule ^[^/]+/11\.5\.[01234567]/.* https://aus1.torproject.org/torbrowser/update_pre12.0/release/$0 [last]
-# tor-browser-build#41270: make 13.5.7 a watershed update
-RewriteRule ^[^/]+/1[12]\.[05].*/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
-RewriteRule ^[^/]+/13\.0.*/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
-RewriteRule ^[^/]+/13\.5/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
-RewriteRule ^[^/]+/13\.5\.[0123456]/.* https://aus1.torproject.org/torbrowser/update_pre14.0/release/$0 [last]
-RewriteRule ^Linux_aarch64-gcc3/(.*) linux-aarch64/$1 [last]
-RewriteRule ^Linux_x86-gcc3/(.*) linux-i686/$1 [last]
-RewriteRule ^Linux_x86_64-gcc3/(.*) linux-x86_64/$1 [last]
-RewriteRule ^Darwin_x86_64-gcc3/(.*) macos/$1 [last]
-RewriteRule ^Darwin_aarch64-gcc3/(.*) macos/$1 [last]
-RewriteRule ^WINNT_x86-gcc3/(.*) windows-i686/$1 [last]
-RewriteRule ^WINNT_x86-gcc3-x86/(.*) windows-i686/$1 [last]
-RewriteRule ^WINNT_x86-gcc3-x64/(.*) windows-i686/$1 [last]
-RewriteRule ^WINNT_x86_64-gcc3-x64/(.*) windows-x86_64/$1 [last]
=====================================
update_3/release/download-android-aarch64.json
=====================================
@@ -1,6 +1,6 @@
{
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-aarch64-1…",
- "git_tag" : "tbb-14.5.8-build1",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-aarch64-1…",
- "version" : "14.5.8"
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-aarch64-1…",
+ "git_tag" : "tbb-14.5.9-build1",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-aarch64-1…",
+ "version" : "14.5.9"
}
=====================================
update_3/release/download-android-armv7.json
=====================================
@@ -1,6 +1,6 @@
{
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-armv7-14.…",
- "git_tag" : "tbb-14.5.8-build1",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-armv7-14.…",
- "version" : "14.5.8"
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-armv7-14.…",
+ "git_tag" : "tbb-14.5.9-build1",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-armv7-14.…",
+ "version" : "14.5.9"
}
=====================================
update_3/release/download-android-x86.json
=====================================
@@ -1,6 +1,6 @@
{
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-x86-14.5.…",
- "git_tag" : "tbb-14.5.8-build1",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-x86-14.5.…",
- "version" : "14.5.8"
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-x86-14.5.…",
+ "git_tag" : "tbb-14.5.9-build1",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-x86-14.5.…",
+ "version" : "14.5.9"
}
=====================================
update_3/release/download-android-x86_64.json
=====================================
@@ -1,6 +1,6 @@
{
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-x86_64-14…",
- "git_tag" : "tbb-14.5.8-build1",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-android-x86_64-14…",
- "version" : "14.5.8"
+ "binary" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-x86_64-14…",
+ "git_tag" : "tbb-14.5.9-build1",
+ "sig" : "https://dist.torproject.org/torbrowser/14.5.9/tor-browser-android-x86_64-14…",
+ "version" : "14.5.9"
}
=====================================
update_3/release/downloads.json deleted
=====================================
@@ -1,37 +0,0 @@
-{
- "comment" : "This file is deprecated and should not be used. Please use the files download-$platform.json instead.",
- "downloads" : {
- "linux-i686" : {
- "ALL" : {
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-i686-14.5.8…",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-i686-14.5.8…"
- }
- },
- "linux-x86_64" : {
- "ALL" : {
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-x86_64-14.5…",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-linux-x86_64-14.5…"
- }
- },
- "macos" : {
- "ALL" : {
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-macos-14.5.8.dmg",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-macos-14.5.8.dmg.…"
- }
- },
- "win32" : {
- "ALL" : {
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-i686-port…",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-i686-port…"
- }
- },
- "win64" : {
- "ALL" : {
- "binary" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-x86_64-po…",
- "sig" : "https://dist.torproject.org/torbrowser/14.5.8/tor-browser-windows-x86_64-po…"
- }
- }
- },
- "tag" : "tbb-14.5.8-build1",
- "version" : "14.5.8"
-}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-update-responses…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-update-responses…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser-build] Pushed new tag tbb-14.5.9-build1
by clairehurst (ï¼ clairehurst) 14 Oct '25
by clairehurst (ï¼ clairehurst) 14 Oct '25
14 Oct '25
clairehurst pushed new tag tbb-14.5.9-build1 at The Tor Project / Applications / tor-browser-build
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/tree/tbb…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser-build][maint-14.5] Bug 41598: Prepare Tor Browser 14.5.9 (Android only)
by morgan (ï¼ morgan) 14 Oct '25
by morgan (ï¼ morgan) 14 Oct '25
14 Oct '25
morgan pushed to branch maint-14.5 at The Tor Project / Applications / tor-browser-build
Commits:
d130eef7 by clairehurst at 2025-10-14T13:28:06-06:00
Bug 41598: Prepare Tor Browser 14.5.9 (Android only)
- - - - -
3 changed files:
- projects/browser/Bundle-Data/Docs-TBB/ChangeLog.txt
- projects/geckoview/config
- rbm.conf
Changes:
=====================================
projects/browser/Bundle-Data/Docs-TBB/ChangeLog.txt
=====================================
@@ -1,3 +1,7 @@
+Tor Browser 14.5.9 - October 15 2025
+ * Android
+ * Bug 44263: YEC does not display on Tor Browser 14.5.8 Android [tor-browser]
+
Tor Browser 14.5.8 - October 08 2025
* All Platforms
* Updated Tor to 0.4.8.19
=====================================
projects/geckoview/config
=====================================
@@ -23,7 +23,7 @@ var:
browser_series: '14.5'
browser_rebase: 1
browser_branch: '[% c("var/browser_series") %]-[% c("var/browser_rebase") %]'
- browser_build: 6
+ browser_build: 7
gitlab_project: https://gitlab.torproject.org/tpo/applications/tor-browser
git_commit: '[% exec("git rev-parse " _ c("git_hash") _ "^{commit}", { exec_noco => 1 }) %]'
deps:
=====================================
rbm.conf
=====================================
@@ -73,11 +73,11 @@ buildconf:
git_signtag_opt: '-s'
var:
- torbrowser_version: '14.5.8'
+ torbrowser_version: '14.5.9'
torbrowser_build: 'build1'
# This should be the date of when the build is started. For the build
# to be reproducible, browser_release_date should always be in the past.
- browser_release_date: '2025/10/13 14:00:00'
+ browser_release_date: '2025/10/14 19:00:00'
browser_release_date_timestamp: '[% USE date; date.format(c("var/browser_release_date"), "%s") %]'
browser_default_channel: release
browser_platforms:
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/d…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/d…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser] Pushed new tag tor-browser-128.14.0esr-14.5-1-build7
by clairehurst (ï¼ clairehurst) 14 Oct '25
by clairehurst (ï¼ clairehurst) 14 Oct '25
14 Oct '25
clairehurst pushed new tag tor-browser-128.14.0esr-14.5-1-build7 at The Tor Project / Applications / Tor Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/tor-brows…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-128.14.0esr-14.5-1] fixup! TB 44031 [android]: 2025 YEC
by Dan Ballard (ï¼ dan) 14 Oct '25
by Dan Ballard (ï¼ dan) 14 Oct '25
14 Oct '25
Dan Ballard pushed to branch tor-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
60be1522 by clairehurst at 2025-10-14T10:59:30-06:00
fixup! TB 44031 [android]: 2025 YEC
Fix BuildConfig import
- - - - -
1 changed file:
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorCampaignViewModel.kt
Changes:
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorCampaignViewModel.kt
=====================================
@@ -1,12 +1,12 @@
package org.mozilla.fenix.tor
+import android.util.Log
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.getValue
-import org.mozilla.geckoview.BuildConfig
class TorCampaignViewModel : ViewModel() {
val shouldInitiallyShowPromo: MutableState<Boolean> by lazy {
@@ -26,7 +26,9 @@ class TorCampaignViewModel : ViewModel() {
if (currentDate.before(startDate) || currentDate.after(endDate)) {
return false
}
- if (BuildConfig.BUILD_TYPE == "release") {
+
+ Log.d("TorCampaignViewModel", "org.mozilla.fenix.BuildConfig.BUILD_TYPE = ${org.mozilla.fenix.BuildConfig.BUILD_TYPE}")
+ if (org.mozilla.fenix.BuildConfig.BUILD_TYPE == "release") {
return true
}
return false
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/60be152…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/60be152…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-140.4.0esr-15.0-1] fixup! Firefox preference overrides.
by Pier Angelo Vendrame (ï¼ pierov) 14 Oct '25
by Pier Angelo Vendrame (ï¼ pierov) 14 Oct '25
14 Oct '25
Pier Angelo Vendrame pushed to branch base-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
2c531ea4 by Pier Angelo Vendrame at 2025-10-14T19:43:33+02:00
fixup! Firefox preference overrides.
BB 44227: Use Jigmo for CJK on Linux.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -975,7 +975,7 @@ pref("font.name-list.monospace.x-unicode", "Consolas, Noto Sans Balinese, Noto S
#endif
#ifdef XP_LINUX
-pref("font.system.whitelist", "Arimo, Cousine, Noto Color Emoji, Noto Naskh Arabic, Noto Sans Adlam, Noto Sans Armenian, Noto Sans Balinese, Noto Sans Bamum, Noto Sans Bassa Vah, Noto Sans Batak, Noto Sans Bengali, Noto Sans Buginese, Noto Sans Buhid, Noto Sans Canadian Aboriginal, Noto Sans Chakma, Noto Sans Cham, Noto Sans Cherokee, Noto Sans Coptic, Noto Sans Deseret, Noto Sans Devanagari, Noto Sans Elbasan, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Grantha, Noto Sans Gujarati, Noto Sans Gunjala Gondi, Noto Sans Gurmukhi, Noto Sans Hanifi Rohingya, Noto Sans Hanunoo, Noto Sans Hebrew, Noto Sans JP, Noto Sans Javanese, Noto Sans KR, Noto Sans Kannada, Noto Sans Kayah Li, Noto Sans Khmer, Noto Sans Khojki, Noto Sans Khudawadi, Noto Sans Lao, Noto Sans Lepcha, Noto Sans Limbu, Noto Sans Lisu, Noto Sans Mahajani, Noto Sans Malayalam, Noto Sans Mandaic, Noto Sans Masaram Gondi, Noto Sans Medefaidrin, Noto Sans Meetei Mayek, Noto Sans Mende Kikakui, Noto Sans Miao, Noto Sans Modi, Noto Sans Mongolian, Noto Sans Mro, Noto Sans Multani, Noto Sans NKo, Noto Sans New Tai Lue, Noto Sans Newa, Noto Sans Ol Chiki, Noto Sans Oriya, Noto Sans Osage, Noto Sans Osmanya, Noto Sans Pahawh Hmong, Noto Sans Pau Cin Hau, Noto Sans Rejang, Noto Sans Runic, Noto Sans SC, Noto Sans Samaritan, Noto Sans Saurashtra, Noto Sans Sharada, Noto Sans Shavian, Noto Sans Sinhala, Noto Sans Sora Sompeng, Noto Sans Soyombo, Noto Sans Sundanese, Noto Sans Syloti Nagri, Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans Syriac, Noto Sans TC, Noto Sans Tagalog, Noto Sans Tagbanwa, Noto Sans Tai Le, Noto Sans Tai Tham, Noto Sans Tai Viet, Noto Sans Takri, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tifinagh, Noto Sans Tifinagh APT, Noto Sans Tifinagh Adrar, Noto Sans Tifinagh Agraw Imazighen, Noto Sans Tifinagh Ahaggar, Noto Sans Tifinagh Air, Noto Sans Tifinagh Azawagh, Noto Sans Tifinagh Ghat, Noto Sans Tifinagh Hawad, Noto Sans Tifinagh Rhissa Ixa, Noto Sans Tifinagh SIL, Noto Sans Tifinagh Tawellemmet, Noto Sans Tirhuta, Noto Sans Vai, Noto Sans Wancho, Noto Sans Warang Citi, Noto Sans Yi, Noto Sans Zanabazar Square, Noto Serif Armenian, Noto Serif Balinese, Noto Serif Bengali, Noto Serif Devanagari, Noto Serif Dogra, Noto Serif Ethiopic, Noto Serif Georgian, Noto Serif Grantha, Noto Serif Gujarati, Noto Serif Gurmukhi, Noto Serif Hebrew, Noto Serif Kannada, Noto Serif Khmer, Noto Serif Khojki, Noto Serif Lao, Noto Serif Malayalam, Noto Serif Myanmar, Noto Serif NP Hmong, Noto Serif Sinhala, Noto Serif Tamil, Noto Serif Telugu, Noto Serif Thai, Noto Serif Tibetan, Noto Serif Yezidi, Pyidaungsu, STIX Two Math, Tinos, Twemoji Mozilla");
+pref("font.system.whitelist", "Arimo, Cousine, Jigmo, Jigmo2, Jigmo3, Noto Color Emoji, Noto Naskh Arabic, Noto Sans Adlam, Noto Sans Armenian, Noto Sans Balinese, Noto Sans Bamum, Noto Sans Bassa Vah, Noto Sans Batak, Noto Sans Bengali, Noto Sans Buginese, Noto Sans Buhid, Noto Sans Canadian Aboriginal, Noto Sans Chakma, Noto Sans Cham, Noto Sans Cherokee, Noto Sans Coptic, Noto Sans Deseret, Noto Sans Devanagari, Noto Sans Elbasan, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Grantha, Noto Sans Gujarati, Noto Sans Gunjala Gondi, Noto Sans Gurmukhi, Noto Sans Hanifi Rohingya, Noto Sans Hanunoo, Noto Sans Hebrew, Noto Sans Javanese, Noto Sans Kannada, Noto Sans Kayah Li, Noto Sans Khmer, Noto Sans Khojki, Noto Sans Khudawadi, Noto Sans Lao, Noto Sans Lepcha, Noto Sans Limbu, Noto Sans Lisu, Noto Sans Mahajani, Noto Sans Malayalam, Noto Sans Mandaic, Noto Sans Masaram Gondi, Noto Sans Medefaidrin, Noto Sans Meetei Mayek, Noto Sans Mende Kikakui, Noto Sans Miao, Noto Sans Modi, Noto Sans Mongolian, Noto Sans Mro, Noto Sans Multani, Noto Sans NKo, Noto Sans New Tai Lue, Noto Sans Newa, Noto Sans Ol Chiki, Noto Sans Oriya, Noto Sans Osage, Noto Sans Osmanya, Noto Sans Pahawh Hmong, Noto Sans Pau Cin Hau, Noto Sans Rejang, Noto Sans Runic, Noto Sans Samaritan, Noto Sans Saurashtra, Noto Sans Sharada, Noto Sans Shavian, Noto Sans Sinhala, Noto Sans Sora Sompeng, Noto Sans Soyombo, Noto Sans Sundanese, Noto Sans Syloti Nagri, Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans Syriac, Noto Sans Tagalog, Noto Sans Tagbanwa, Noto Sans Tai Le, Noto Sans Tai Tham, Noto Sans Tai Viet, Noto Sans Takri, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tifinagh, Noto Sans Tifinagh APT, Noto Sans Tifinagh Adrar, Noto Sans Tifinagh Agraw Imazighen, Noto Sans Tifinagh Ahaggar, Noto Sans Tifinagh Air, Noto Sans Tifinagh Azawagh, Noto Sans Tifinagh Ghat, Noto Sans Tifinagh Hawad, Noto Sans Tifinagh Rhissa Ixa, Noto Sans Tifinagh SIL, Noto Sans Tifinagh Tawellemmet, Noto Sans Tirhuta, Noto Sans Vai, Noto Sans Wancho, Noto Sans Warang Citi, Noto Sans Yi, Noto Sans Zanabazar Square, Noto Serif Armenian, Noto Serif Balinese, Noto Serif Bengali, Noto Serif Devanagari, Noto Serif Dogra, Noto Serif Ethiopic, Noto Serif Georgian, Noto Serif Grantha, Noto Serif Gujarati, Noto Serif Gurmukhi, Noto Serif Hebrew, Noto Serif Kannada, Noto Serif Khmer, Noto Serif Khojki, Noto Serif Lao, Noto Serif Malayalam, Noto Serif Myanmar, Noto Serif NP Hmong, Noto Serif Sinhala, Noto Serif Tamil, Noto Serif Telugu, Noto Serif Thai, Noto Serif Tibetan, Noto Serif Yezidi, Pyidaungsu, STIX Two Math, Tinos, Twemoji Mozilla");
pref("font.name-list.emoji", "Noto Color Emoji, Twemoji Mozilla");
// Arabic
@@ -999,13 +999,13 @@ pref("font.name-list.serif.zh-CN", "Noto Sans SC Regular, Tinos");
pref("font.name-list.sans-serif.zh-CN", "Noto Sans SC Regular, Arimo");
pref("font.name-list.monospace.zh-CN", "Noto Sans SC Regular, Cousine");
// ChineseHK
-pref("font.name-list.serif.zh-HK", "Noto Sans TC Regular, Tinos");
-pref("font.name-list.sans-serif.zh-HK", "Noto Sans TC Regular, Arimo");
-pref("font.name-list.monospace.zh-HK", "Noto Sans TC Regular, Cousine");
+pref("font.name-list.serif.zh-HK", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.zh-HK", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.zh-HK", "Jigmo, Jigmo2, Jigmo3, Cousine");
// ChineseTW
-pref("font.name-list.serif.zh-TW", "Noto Sans TC Regular, Tinos");
-pref("font.name-list.sans-serif.zh-TW", "Noto Sans TC Regular, Arimo");
-pref("font.name-list.monospace.zh-TW", "Noto Sans TC Regular, Cousine");
+pref("font.name-list.serif.zh-TW", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.zh-TW", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.zh-TW", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Cyrillic
pref("font.name-list.serif.x-cyrillic", "Tinos");
pref("font.name-list.sans-serif.x-cyrillic", "Arimo");
@@ -1039,9 +1039,9 @@ pref("font.name-list.serif.he", "Noto Serif Hebrew, Tinos");
pref("font.name-list.sans-serif.he", "Noto Sans Hebrew, Arimo");
pref("font.name-list.monospace.he", "Noto Sans Hebrew, Cousine");
// Japanese
-pref("font.name-list.serif.ja", "Noto Sans JP Regular, Tinos");
-pref("font.name-list.sans-serif.ja", "Noto Sans JP Regular, Arimo");
-pref("font.name-list.monospace.ja", "Noto Sans JP Regular, Cousine");
+pref("font.name-list.serif.ja", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.ja", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.ja", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Kannada
pref("font.name-list.serif.x-knda", "Noto Serif Kannada, Tinos");
pref("font.name-list.sans-serif.x-knda", "Noto Sans Kannada, Arimo");
@@ -1051,9 +1051,9 @@ pref("font.name-list.serif.x-khmr", "Noto Serif Khmer, Tinos");
pref("font.name-list.sans-serif.x-khmr", "Noto Sans Khmer, Arimo");
pref("font.name-list.monospace.x-khmr", "Noto Sans Khmer, Cousine");
// Korean
-pref("font.name-list.serif.ko", "Noto Sans KR Regular");
-pref("font.name-list.sans-serif.ko", "Noto Sans KR Regular");
-pref("font.name-list.monospace.ko", "Noto Sans KR Regular");
+pref("font.name-list.serif.ko", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.ko", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.ko", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Malayalam
pref("font.name-list.serif.x-mlym", "Noto Serif Malayalam, Tinos");
pref("font.name-list.sans-serif.x-mlym", "Noto Sans Malayalam, Arimo");
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/2c531ea…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/2c531ea…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.4.0esr-15.0-1] fixup! Firefox preference overrides.
by Pier Angelo Vendrame (ï¼ pierov) 14 Oct '25
by Pier Angelo Vendrame (ï¼ pierov) 14 Oct '25
14 Oct '25
Pier Angelo Vendrame pushed to branch mullvad-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
fb9da32e by Pier Angelo Vendrame at 2025-10-14T19:42:56+02:00
fixup! Firefox preference overrides.
BB 44227: Use Jigmo for CJK on Linux.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -971,7 +971,7 @@ pref("font.name-list.monospace.x-unicode", "Consolas, Noto Sans Balinese, Noto S
#endif
#ifdef XP_LINUX
-pref("font.system.whitelist", "Arimo, Cousine, Noto Color Emoji, Noto Naskh Arabic, Noto Sans Adlam, Noto Sans Armenian, Noto Sans Balinese, Noto Sans Bamum, Noto Sans Bassa Vah, Noto Sans Batak, Noto Sans Bengali, Noto Sans Buginese, Noto Sans Buhid, Noto Sans Canadian Aboriginal, Noto Sans Chakma, Noto Sans Cham, Noto Sans Cherokee, Noto Sans Coptic, Noto Sans Deseret, Noto Sans Devanagari, Noto Sans Elbasan, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Grantha, Noto Sans Gujarati, Noto Sans Gunjala Gondi, Noto Sans Gurmukhi, Noto Sans Hanifi Rohingya, Noto Sans Hanunoo, Noto Sans Hebrew, Noto Sans JP, Noto Sans Javanese, Noto Sans KR, Noto Sans Kannada, Noto Sans Kayah Li, Noto Sans Khmer, Noto Sans Khojki, Noto Sans Khudawadi, Noto Sans Lao, Noto Sans Lepcha, Noto Sans Limbu, Noto Sans Lisu, Noto Sans Mahajani, Noto Sans Malayalam, Noto Sans Mandaic, Noto Sans Masaram Gondi, Noto Sans Medefaidrin, Noto Sans Meetei Mayek, Noto Sans Mende Kikakui, Noto Sans Miao, Noto Sans Modi, Noto Sans Mongolian, Noto Sans Mro, Noto Sans Multani, Noto Sans NKo, Noto Sans New Tai Lue, Noto Sans Newa, Noto Sans Ol Chiki, Noto Sans Oriya, Noto Sans Osage, Noto Sans Osmanya, Noto Sans Pahawh Hmong, Noto Sans Pau Cin Hau, Noto Sans Rejang, Noto Sans Runic, Noto Sans SC, Noto Sans Samaritan, Noto Sans Saurashtra, Noto Sans Sharada, Noto Sans Shavian, Noto Sans Sinhala, Noto Sans Sora Sompeng, Noto Sans Soyombo, Noto Sans Sundanese, Noto Sans Syloti Nagri, Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans Syriac, Noto Sans TC, Noto Sans Tagalog, Noto Sans Tagbanwa, Noto Sans Tai Le, Noto Sans Tai Tham, Noto Sans Tai Viet, Noto Sans Takri, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tifinagh, Noto Sans Tifinagh APT, Noto Sans Tifinagh Adrar, Noto Sans Tifinagh Agraw Imazighen, Noto Sans Tifinagh Ahaggar, Noto Sans Tifinagh Air, Noto Sans Tifinagh Azawagh, Noto Sans Tifinagh Ghat, Noto Sans Tifinagh Hawad, Noto Sans Tifinagh Rhissa Ixa, Noto Sans Tifinagh SIL, Noto Sans Tifinagh Tawellemmet, Noto Sans Tirhuta, Noto Sans Vai, Noto Sans Wancho, Noto Sans Warang Citi, Noto Sans Yi, Noto Sans Zanabazar Square, Noto Serif Armenian, Noto Serif Balinese, Noto Serif Bengali, Noto Serif Devanagari, Noto Serif Dogra, Noto Serif Ethiopic, Noto Serif Georgian, Noto Serif Grantha, Noto Serif Gujarati, Noto Serif Gurmukhi, Noto Serif Hebrew, Noto Serif Kannada, Noto Serif Khmer, Noto Serif Khojki, Noto Serif Lao, Noto Serif Malayalam, Noto Serif Myanmar, Noto Serif NP Hmong, Noto Serif Sinhala, Noto Serif Tamil, Noto Serif Telugu, Noto Serif Thai, Noto Serif Tibetan, Noto Serif Yezidi, Pyidaungsu, STIX Two Math, Tinos, Twemoji Mozilla");
+pref("font.system.whitelist", "Arimo, Cousine, Jigmo, Jigmo2, Jigmo3, Noto Color Emoji, Noto Naskh Arabic, Noto Sans Adlam, Noto Sans Armenian, Noto Sans Balinese, Noto Sans Bamum, Noto Sans Bassa Vah, Noto Sans Batak, Noto Sans Bengali, Noto Sans Buginese, Noto Sans Buhid, Noto Sans Canadian Aboriginal, Noto Sans Chakma, Noto Sans Cham, Noto Sans Cherokee, Noto Sans Coptic, Noto Sans Deseret, Noto Sans Devanagari, Noto Sans Elbasan, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Grantha, Noto Sans Gujarati, Noto Sans Gunjala Gondi, Noto Sans Gurmukhi, Noto Sans Hanifi Rohingya, Noto Sans Hanunoo, Noto Sans Hebrew, Noto Sans Javanese, Noto Sans Kannada, Noto Sans Kayah Li, Noto Sans Khmer, Noto Sans Khojki, Noto Sans Khudawadi, Noto Sans Lao, Noto Sans Lepcha, Noto Sans Limbu, Noto Sans Lisu, Noto Sans Mahajani, Noto Sans Malayalam, Noto Sans Mandaic, Noto Sans Masaram Gondi, Noto Sans Medefaidrin, Noto Sans Meetei Mayek, Noto Sans Mende Kikakui, Noto Sans Miao, Noto Sans Modi, Noto Sans Mongolian, Noto Sans Mro, Noto Sans Multani, Noto Sans NKo, Noto Sans New Tai Lue, Noto Sans Newa, Noto Sans Ol Chiki, Noto Sans Oriya, Noto Sans Osage, Noto Sans Osmanya, Noto Sans Pahawh Hmong, Noto Sans Pau Cin Hau, Noto Sans Rejang, Noto Sans Runic, Noto Sans Samaritan, Noto Sans Saurashtra, Noto Sans Sharada, Noto Sans Shavian, Noto Sans Sinhala, Noto Sans Sora Sompeng, Noto Sans Soyombo, Noto Sans Sundanese, Noto Sans Syloti Nagri, Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans Syriac, Noto Sans Tagalog, Noto Sans Tagbanwa, Noto Sans Tai Le, Noto Sans Tai Tham, Noto Sans Tai Viet, Noto Sans Takri, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tifinagh, Noto Sans Tifinagh APT, Noto Sans Tifinagh Adrar, Noto Sans Tifinagh Agraw Imazighen, Noto Sans Tifinagh Ahaggar, Noto Sans Tifinagh Air, Noto Sans Tifinagh Azawagh, Noto Sans Tifinagh Ghat, Noto Sans Tifinagh Hawad, Noto Sans Tifinagh Rhissa Ixa, Noto Sans Tifinagh SIL, Noto Sans Tifinagh Tawellemmet, Noto Sans Tirhuta, Noto Sans Vai, Noto Sans Wancho, Noto Sans Warang Citi, Noto Sans Yi, Noto Sans Zanabazar Square, Noto Serif Armenian, Noto Serif Balinese, Noto Serif Bengali, Noto Serif Devanagari, Noto Serif Dogra, Noto Serif Ethiopic, Noto Serif Georgian, Noto Serif Grantha, Noto Serif Gujarati, Noto Serif Gurmukhi, Noto Serif Hebrew, Noto Serif Kannada, Noto Serif Khmer, Noto Serif Khojki, Noto Serif Lao, Noto Serif Malayalam, Noto Serif Myanmar, Noto Serif NP Hmong, Noto Serif Sinhala, Noto Serif Tamil, Noto Serif Telugu, Noto Serif Thai, Noto Serif Tibetan, Noto Serif Yezidi, Pyidaungsu, STIX Two Math, Tinos, Twemoji Mozilla");
pref("font.name-list.emoji", "Noto Color Emoji, Twemoji Mozilla");
// Arabic
@@ -995,13 +995,13 @@ pref("font.name-list.serif.zh-CN", "Noto Sans SC Regular, Tinos");
pref("font.name-list.sans-serif.zh-CN", "Noto Sans SC Regular, Arimo");
pref("font.name-list.monospace.zh-CN", "Noto Sans SC Regular, Cousine");
// ChineseHK
-pref("font.name-list.serif.zh-HK", "Noto Sans TC Regular, Tinos");
-pref("font.name-list.sans-serif.zh-HK", "Noto Sans TC Regular, Arimo");
-pref("font.name-list.monospace.zh-HK", "Noto Sans TC Regular, Cousine");
+pref("font.name-list.serif.zh-HK", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.zh-HK", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.zh-HK", "Jigmo, Jigmo2, Jigmo3, Cousine");
// ChineseTW
-pref("font.name-list.serif.zh-TW", "Noto Sans TC Regular, Tinos");
-pref("font.name-list.sans-serif.zh-TW", "Noto Sans TC Regular, Arimo");
-pref("font.name-list.monospace.zh-TW", "Noto Sans TC Regular, Cousine");
+pref("font.name-list.serif.zh-TW", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.zh-TW", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.zh-TW", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Cyrillic
pref("font.name-list.serif.x-cyrillic", "Tinos");
pref("font.name-list.sans-serif.x-cyrillic", "Arimo");
@@ -1035,9 +1035,9 @@ pref("font.name-list.serif.he", "Noto Serif Hebrew, Tinos");
pref("font.name-list.sans-serif.he", "Noto Sans Hebrew, Arimo");
pref("font.name-list.monospace.he", "Noto Sans Hebrew, Cousine");
// Japanese
-pref("font.name-list.serif.ja", "Noto Sans JP Regular, Tinos");
-pref("font.name-list.sans-serif.ja", "Noto Sans JP Regular, Arimo");
-pref("font.name-list.monospace.ja", "Noto Sans JP Regular, Cousine");
+pref("font.name-list.serif.ja", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.ja", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.ja", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Kannada
pref("font.name-list.serif.x-knda", "Noto Serif Kannada, Tinos");
pref("font.name-list.sans-serif.x-knda", "Noto Sans Kannada, Arimo");
@@ -1047,9 +1047,9 @@ pref("font.name-list.serif.x-khmr", "Noto Serif Khmer, Tinos");
pref("font.name-list.sans-serif.x-khmr", "Noto Sans Khmer, Arimo");
pref("font.name-list.monospace.x-khmr", "Noto Sans Khmer, Cousine");
// Korean
-pref("font.name-list.serif.ko", "Noto Sans KR Regular");
-pref("font.name-list.sans-serif.ko", "Noto Sans KR Regular");
-pref("font.name-list.monospace.ko", "Noto Sans KR Regular");
+pref("font.name-list.serif.ko", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.ko", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.ko", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Malayalam
pref("font.name-list.serif.x-mlym", "Noto Serif Malayalam, Tinos");
pref("font.name-list.sans-serif.x-mlym", "Noto Sans Malayalam, Arimo");
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/fb9…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/fb9…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.4.0esr-15.0-1] fixup! Firefox preference overrides.
by Pier Angelo Vendrame (ï¼ pierov) 14 Oct '25
by Pier Angelo Vendrame (ï¼ pierov) 14 Oct '25
14 Oct '25
Pier Angelo Vendrame pushed to branch tor-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
99706c4b by Pier Angelo Vendrame at 2025-10-14T17:38:11+00:00
fixup! Firefox preference overrides.
BB 44227: Use Jigmo for CJK on Linux.
- - - - -
1 changed file:
- browser/app/profile/001-base-profile.js
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -975,7 +975,7 @@ pref("font.name-list.monospace.x-unicode", "Consolas, Noto Sans Balinese, Noto S
#endif
#ifdef XP_LINUX
-pref("font.system.whitelist", "Arimo, Cousine, Noto Color Emoji, Noto Naskh Arabic, Noto Sans Adlam, Noto Sans Armenian, Noto Sans Balinese, Noto Sans Bamum, Noto Sans Bassa Vah, Noto Sans Batak, Noto Sans Bengali, Noto Sans Buginese, Noto Sans Buhid, Noto Sans Canadian Aboriginal, Noto Sans Chakma, Noto Sans Cham, Noto Sans Cherokee, Noto Sans Coptic, Noto Sans Deseret, Noto Sans Devanagari, Noto Sans Elbasan, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Grantha, Noto Sans Gujarati, Noto Sans Gunjala Gondi, Noto Sans Gurmukhi, Noto Sans Hanifi Rohingya, Noto Sans Hanunoo, Noto Sans Hebrew, Noto Sans JP, Noto Sans Javanese, Noto Sans KR, Noto Sans Kannada, Noto Sans Kayah Li, Noto Sans Khmer, Noto Sans Khojki, Noto Sans Khudawadi, Noto Sans Lao, Noto Sans Lepcha, Noto Sans Limbu, Noto Sans Lisu, Noto Sans Mahajani, Noto Sans Malayalam, Noto Sans Mandaic, Noto Sans Masaram Gondi, Noto Sans Medefaidrin, Noto Sans Meetei Mayek, Noto Sans Mende Kikakui, Noto Sans Miao, Noto Sans Modi, Noto Sans Mongolian, Noto Sans Mro, Noto Sans Multani, Noto Sans NKo, Noto Sans New Tai Lue, Noto Sans Newa, Noto Sans Ol Chiki, Noto Sans Oriya, Noto Sans Osage, Noto Sans Osmanya, Noto Sans Pahawh Hmong, Noto Sans Pau Cin Hau, Noto Sans Rejang, Noto Sans Runic, Noto Sans SC, Noto Sans Samaritan, Noto Sans Saurashtra, Noto Sans Sharada, Noto Sans Shavian, Noto Sans Sinhala, Noto Sans Sora Sompeng, Noto Sans Soyombo, Noto Sans Sundanese, Noto Sans Syloti Nagri, Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans Syriac, Noto Sans TC, Noto Sans Tagalog, Noto Sans Tagbanwa, Noto Sans Tai Le, Noto Sans Tai Tham, Noto Sans Tai Viet, Noto Sans Takri, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tifinagh, Noto Sans Tifinagh APT, Noto Sans Tifinagh Adrar, Noto Sans Tifinagh Agraw Imazighen, Noto Sans Tifinagh Ahaggar, Noto Sans Tifinagh Air, Noto Sans Tifinagh Azawagh, Noto Sans Tifinagh Ghat, Noto Sans Tifinagh Hawad, Noto Sans Tifinagh Rhissa Ixa, Noto Sans Tifinagh SIL, Noto Sans Tifinagh Tawellemmet, Noto Sans Tirhuta, Noto Sans Vai, Noto Sans Wancho, Noto Sans Warang Citi, Noto Sans Yi, Noto Sans Zanabazar Square, Noto Serif Armenian, Noto Serif Balinese, Noto Serif Bengali, Noto Serif Devanagari, Noto Serif Dogra, Noto Serif Ethiopic, Noto Serif Georgian, Noto Serif Grantha, Noto Serif Gujarati, Noto Serif Gurmukhi, Noto Serif Hebrew, Noto Serif Kannada, Noto Serif Khmer, Noto Serif Khojki, Noto Serif Lao, Noto Serif Malayalam, Noto Serif Myanmar, Noto Serif NP Hmong, Noto Serif Sinhala, Noto Serif Tamil, Noto Serif Telugu, Noto Serif Thai, Noto Serif Tibetan, Noto Serif Yezidi, Pyidaungsu, STIX Two Math, Tinos, Twemoji Mozilla");
+pref("font.system.whitelist", "Arimo, Cousine, Jigmo, Jigmo2, Jigmo3, Noto Color Emoji, Noto Naskh Arabic, Noto Sans Adlam, Noto Sans Armenian, Noto Sans Balinese, Noto Sans Bamum, Noto Sans Bassa Vah, Noto Sans Batak, Noto Sans Bengali, Noto Sans Buginese, Noto Sans Buhid, Noto Sans Canadian Aboriginal, Noto Sans Chakma, Noto Sans Cham, Noto Sans Cherokee, Noto Sans Coptic, Noto Sans Deseret, Noto Sans Devanagari, Noto Sans Elbasan, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Grantha, Noto Sans Gujarati, Noto Sans Gunjala Gondi, Noto Sans Gurmukhi, Noto Sans Hanifi Rohingya, Noto Sans Hanunoo, Noto Sans Hebrew, Noto Sans Javanese, Noto Sans Kannada, Noto Sans Kayah Li, Noto Sans Khmer, Noto Sans Khojki, Noto Sans Khudawadi, Noto Sans Lao, Noto Sans Lepcha, Noto Sans Limbu, Noto Sans Lisu, Noto Sans Mahajani, Noto Sans Malayalam, Noto Sans Mandaic, Noto Sans Masaram Gondi, Noto Sans Medefaidrin, Noto Sans Meetei Mayek, Noto Sans Mende Kikakui, Noto Sans Miao, Noto Sans Modi, Noto Sans Mongolian, Noto Sans Mro, Noto Sans Multani, Noto Sans NKo, Noto Sans New Tai Lue, Noto Sans Newa, Noto Sans Ol Chiki, Noto Sans Oriya, Noto Sans Osage, Noto Sans Osmanya, Noto Sans Pahawh Hmong, Noto Sans Pau Cin Hau, Noto Sans Rejang, Noto Sans Runic, Noto Sans Samaritan, Noto Sans Saurashtra, Noto Sans Sharada, Noto Sans Shavian, Noto Sans Sinhala, Noto Sans Sora Sompeng, Noto Sans Soyombo, Noto Sans Sundanese, Noto Sans Syloti Nagri, Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans Syriac, Noto Sans Tagalog, Noto Sans Tagbanwa, Noto Sans Tai Le, Noto Sans Tai Tham, Noto Sans Tai Viet, Noto Sans Takri, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tifinagh, Noto Sans Tifinagh APT, Noto Sans Tifinagh Adrar, Noto Sans Tifinagh Agraw Imazighen, Noto Sans Tifinagh Ahaggar, Noto Sans Tifinagh Air, Noto Sans Tifinagh Azawagh, Noto Sans Tifinagh Ghat, Noto Sans Tifinagh Hawad, Noto Sans Tifinagh Rhissa Ixa, Noto Sans Tifinagh SIL, Noto Sans Tifinagh Tawellemmet, Noto Sans Tirhuta, Noto Sans Vai, Noto Sans Wancho, Noto Sans Warang Citi, Noto Sans Yi, Noto Sans Zanabazar Square, Noto Serif Armenian, Noto Serif Balinese, Noto Serif Bengali, Noto Serif Devanagari, Noto Serif Dogra, Noto Serif Ethiopic, Noto Serif Georgian, Noto Serif Grantha, Noto Serif Gujarati, Noto Serif Gurmukhi, Noto Serif Hebrew, Noto Serif Kannada, Noto Serif Khmer, Noto Serif Khojki, Noto Serif Lao, Noto Serif Malayalam, Noto Serif Myanmar, Noto Serif NP Hmong, Noto Serif Sinhala, Noto Serif Tamil, Noto Serif Telugu, Noto Serif Thai, Noto Serif Tibetan, Noto Serif Yezidi, Pyidaungsu, STIX Two Math, Tinos, Twemoji Mozilla");
pref("font.name-list.emoji", "Noto Color Emoji, Twemoji Mozilla");
// Arabic
@@ -999,13 +999,13 @@ pref("font.name-list.serif.zh-CN", "Noto Sans SC Regular, Tinos");
pref("font.name-list.sans-serif.zh-CN", "Noto Sans SC Regular, Arimo");
pref("font.name-list.monospace.zh-CN", "Noto Sans SC Regular, Cousine");
// ChineseHK
-pref("font.name-list.serif.zh-HK", "Noto Sans TC Regular, Tinos");
-pref("font.name-list.sans-serif.zh-HK", "Noto Sans TC Regular, Arimo");
-pref("font.name-list.monospace.zh-HK", "Noto Sans TC Regular, Cousine");
+pref("font.name-list.serif.zh-HK", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.zh-HK", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.zh-HK", "Jigmo, Jigmo2, Jigmo3, Cousine");
// ChineseTW
-pref("font.name-list.serif.zh-TW", "Noto Sans TC Regular, Tinos");
-pref("font.name-list.sans-serif.zh-TW", "Noto Sans TC Regular, Arimo");
-pref("font.name-list.monospace.zh-TW", "Noto Sans TC Regular, Cousine");
+pref("font.name-list.serif.zh-TW", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.zh-TW", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.zh-TW", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Cyrillic
pref("font.name-list.serif.x-cyrillic", "Tinos");
pref("font.name-list.sans-serif.x-cyrillic", "Arimo");
@@ -1039,9 +1039,9 @@ pref("font.name-list.serif.he", "Noto Serif Hebrew, Tinos");
pref("font.name-list.sans-serif.he", "Noto Sans Hebrew, Arimo");
pref("font.name-list.monospace.he", "Noto Sans Hebrew, Cousine");
// Japanese
-pref("font.name-list.serif.ja", "Noto Sans JP Regular, Tinos");
-pref("font.name-list.sans-serif.ja", "Noto Sans JP Regular, Arimo");
-pref("font.name-list.monospace.ja", "Noto Sans JP Regular, Cousine");
+pref("font.name-list.serif.ja", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.ja", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.ja", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Kannada
pref("font.name-list.serif.x-knda", "Noto Serif Kannada, Tinos");
pref("font.name-list.sans-serif.x-knda", "Noto Sans Kannada, Arimo");
@@ -1051,9 +1051,9 @@ pref("font.name-list.serif.x-khmr", "Noto Serif Khmer, Tinos");
pref("font.name-list.sans-serif.x-khmr", "Noto Sans Khmer, Arimo");
pref("font.name-list.monospace.x-khmr", "Noto Sans Khmer, Cousine");
// Korean
-pref("font.name-list.serif.ko", "Noto Sans KR Regular");
-pref("font.name-list.sans-serif.ko", "Noto Sans KR Regular");
-pref("font.name-list.monospace.ko", "Noto Sans KR Regular");
+pref("font.name-list.serif.ko", "Jigmo, Jigmo2, Jigmo3, Tinos");
+pref("font.name-list.sans-serif.ko", "Jigmo, Jigmo2, Jigmo3, Arimo");
+pref("font.name-list.monospace.ko", "Jigmo, Jigmo2, Jigmo3, Cousine");
// Malayalam
pref("font.name-list.serif.x-mlym", "Noto Serif Malayalam, Tinos");
pref("font.name-list.sans-serif.x-mlym", "Noto Sans Malayalam, Arimo");
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/99706c4…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/99706c4…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][tor-browser-140.4.0esr-15.0-1] fixup! TB 44031 [android]: 2025 YEC
by Dan Ballard (ï¼ dan) 14 Oct '25
by Dan Ballard (ï¼ dan) 14 Oct '25
14 Oct '25
Dan Ballard pushed to branch tor-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
3e6266f7 by clairehurst at 2025-10-14T11:22:39-06:00
fixup! TB 44031 [android]: 2025 YEC
Fix BuildConfig import
- - - - -
1 changed file:
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorCampaignViewModel.kt
Changes:
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorCampaignViewModel.kt
=====================================
@@ -1,12 +1,12 @@
package org.mozilla.fenix.tor
+import android.util.Log
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.getValue
-import org.mozilla.geckoview.BuildConfig
class TorCampaignViewModel : ViewModel() {
val shouldInitiallyShowPromo: MutableState<Boolean> by lazy {
@@ -26,7 +26,8 @@ class TorCampaignViewModel : ViewModel() {
if (currentDate.before(startDate) || currentDate.after(endDate)) {
return false
}
- if (BuildConfig.BUILD_TYPE == "release") {
+ Log.d("TorCampaignViewModel", "org.mozilla.fenix.BuildConfig.BUILD_TYPE = ${org.mozilla.fenix.BuildConfig.BUILD_TYPE}")
+ if (org.mozilla.fenix.BuildConfig.BUILD_TYPE == "release") {
return true
}
return false
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/3e6266f…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/3e6266f…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.4.0esr-15.0-1] fixup! BB 43564: Modify ./mach bootstrap for Base Browser
by brizental (ï¼ brizental) 14 Oct '25
by brizental (ï¼ brizental) 14 Oct '25
14 Oct '25
brizental pushed to branch mullvad-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
28473216 by Beatriz Rizental at 2025-10-14T16:26:51+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
3 changed files:
- build/moz.configure/bootstrap.configure
- python/mozbuild/mozbuild/tbbutils.py
- python/mozbuild/mozbuild/test/test_tbbutils.py
Changes:
=====================================
build/moz.configure/bootstrap.configure
=====================================
@@ -221,11 +221,7 @@ def bootstrap_path(path, **kwargs):
log.info("no path found in tbb/out for %s", artifact)
return False
- # We will use the name of the artifact as the index.
- #
- # It's usually unique to the artifact version, but each artifact follows
- # a different naming convention, so we can't really get more specific here.
- artifact_index = artifact_path.rsplit("/", 1)[-1]
+ artifact_index = mozbuild.tbbutils.get_artifact_index(artifact_path)
index_file = os.path.join(toolchains_base_dir, "indices", artifact)
try:
with open(index_file) as fh:
=====================================
python/mozbuild/mozbuild/tbbutils.py
=====================================
@@ -41,6 +41,17 @@ ARTIFACT_NAME_MAP = {
}
+def get_artifact_index(artifact_path):
+ """
+ Return a unique identifier for the given artifact based on its path.
+
+ In most cases, artifacts built by tor-browser-build include part of their
+ SHA sum or version in the filename, so the file name itself serves as a unique
+ identifier.
+ """
+ return artifact_path.rsplit("/", 1)[-1]
+
+
def get_artifact_name(original_artifact_name, host):
# These are not build artifacts, they are pre-built artifacts to be added to the final build,
# therefore this check can come before the host check.
=====================================
python/mozbuild/mozbuild/test/test_tbbutils.py
=====================================
@@ -4,7 +4,7 @@ from unittest.mock import MagicMock, patch
import mozunit
-from mozbuild.tbbutils import get_artifact_path, list_files_http
+from mozbuild.tbbutils import get_artifact_index, get_artifact_path, list_files_http
class TestGetArtifactName(unittest.TestCase):
@@ -34,6 +34,13 @@ class TestGetArtifactName(unittest.TestCase):
self.assertEqual(result, self.artifact[::-1])
+class TestGetArtifactIndex(unittest.TestCase):
+ def test_regular_artifact(self):
+ path = "https://tb-build-06.torproject.org/~tb-builder/tor-browser-build/out/tor/to…"
+ expected = "tor-b1f9824464dc-linux-x86_64-b0ffe2.tar.gz"
+ self.assertEqual(get_artifact_index(path), expected)
+
+
class TestGetArtifactPath(unittest.TestCase):
def setUp(self):
self.url = "http://example.com"
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/284…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/284…
You're receiving this email because of your account on gitlab.torproject.org.
1
0
[Git][tpo/applications/tor-browser][base-browser-140.4.0esr-15.0-1] fixup! BB 43564: Modify ./mach bootstrap for Base Browser
by brizental (ï¼ brizental) 14 Oct '25
by brizental (ï¼ brizental) 14 Oct '25
14 Oct '25
brizental pushed to branch base-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
a7eeac64 by Beatriz Rizental at 2025-10-14T16:25:12+02:00
fixup! BB 43564: Modify ./mach bootstrap for Base Browser
- - - - -
3 changed files:
- build/moz.configure/bootstrap.configure
- python/mozbuild/mozbuild/tbbutils.py
- python/mozbuild/mozbuild/test/test_tbbutils.py
Changes:
=====================================
build/moz.configure/bootstrap.configure
=====================================
@@ -221,11 +221,7 @@ def bootstrap_path(path, **kwargs):
log.info("no path found in tbb/out for %s", artifact)
return False
- # We will use the name of the artifact as the index.
- #
- # It's usually unique to the artifact version, but each artifact follows
- # a different naming convention, so we can't really get more specific here.
- artifact_index = artifact_path.rsplit("/", 1)[-1]
+ artifact_index = mozbuild.tbbutils.get_artifact_index(artifact_path)
index_file = os.path.join(toolchains_base_dir, "indices", artifact)
try:
with open(index_file) as fh:
=====================================
python/mozbuild/mozbuild/tbbutils.py
=====================================
@@ -41,6 +41,17 @@ ARTIFACT_NAME_MAP = {
}
+def get_artifact_index(artifact_path):
+ """
+ Return a unique identifier for the given artifact based on its path.
+
+ In most cases, artifacts built by tor-browser-build include part of their
+ SHA sum or version in the filename, so the file name itself serves as a unique
+ identifier.
+ """
+ return artifact_path.rsplit("/", 1)[-1]
+
+
def get_artifact_name(original_artifact_name, host):
# These are not build artifacts, they are pre-built artifacts to be added to the final build,
# therefore this check can come before the host check.
=====================================
python/mozbuild/mozbuild/test/test_tbbutils.py
=====================================
@@ -4,7 +4,7 @@ from unittest.mock import MagicMock, patch
import mozunit
-from mozbuild.tbbutils import get_artifact_path, list_files_http
+from mozbuild.tbbutils import get_artifact_index, get_artifact_path, list_files_http
class TestGetArtifactName(unittest.TestCase):
@@ -34,6 +34,13 @@ class TestGetArtifactName(unittest.TestCase):
self.assertEqual(result, self.artifact[::-1])
+class TestGetArtifactIndex(unittest.TestCase):
+ def test_regular_artifact(self):
+ path = "https://tb-build-06.torproject.org/~tb-builder/tor-browser-build/out/tor/to…"
+ expected = "tor-b1f9824464dc-linux-x86_64-b0ffe2.tar.gz"
+ self.assertEqual(get_artifact_index(path), expected)
+
+
class TestGetArtifactPath(unittest.TestCase):
def setUp(self):
self.url = "http://example.com"
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/a7eeac6…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/a7eeac6…
You're receiving this email because of your account on gitlab.torproject.org.
1
0