lists.torproject.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

tbb-commits

Thread Start a new thread
Threads by month
  • ----- 2025 -----
  • 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
tbb-commits@lists.torproject.org

June 2025

  • 1 participants
  • 112 discussions
[Git][tpo/applications/tor-browser][tor-browser-140.0a1-15.0-1] fixup! TB 40562: Added Tor Browser preferences to 000-tor-browser.js
by morgan (@morgan) 16 Jun '25

16 Jun '25
morgan pushed to branch tor-browser-140.0a1-15.0-1 at The Tor Project / Applications / Tor Browser Commits: 4c65306a by Morgan at 2025-06-16T16:30:06+00:00 fixup! TB 40562: Added Tor Browser preferences to 000-tor-browser.js use netlify for moat's domain fronting - - - - - 1 changed file: - browser/app/profile/000-tor-browser.js Changes: ===================================== browser/app/profile/000-tor-browser.js ===================================== @@ -123,8 +123,8 @@ pref("extensions.torlauncher.torrc_path", ""); pref("extensions.torlauncher.tordatadir_path", ""); // BridgeDB-related preferences (used for Moat). -pref("extensions.torlauncher.bridgedb_front", "www.phpmyadmin.net"); -pref("extensions.torlauncher.bridgedb_reflector", "https://1723079976.rsc.cdn77.org"); +pref("extensions.torlauncher.bridgedb_front", "vuejs.org"); +pref("extensions.torlauncher.bridgedb_reflector", "https://bespoke-strudel-c243cc.netlify.app"); pref("extensions.torlauncher.moat_service", "https://bridges.torproject.org/moat"); // Log levels View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/4c65306… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/4c65306… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.0a1-15.0-1] fixup! BB 43615: Add Gitlab Issue and Merge Request templates
by morgan (@morgan) 16 Jun '25

16 Jun '25
morgan pushed to branch mullvad-browser-140.0a1-15.0-1 at The Tor Project / Applications / Mullvad Browser Commits: 0749a03c by Morgan at 2025-06-16T16:08:38+00:00 fixup! BB 43615: Add Gitlab Issue and Merge Request templates update target channels with esr140-15.0 and esr128-14.5 - - - - - 1 changed file: - .gitlab/merge_request_templates/Default.md Changes: ===================================== .gitlab/merge_request_templates/Default.md ===================================== @@ -27,8 +27,8 @@ #### Target Channels -- [ ] **Alpha**: esr128-14.5 -- [ ] **Stable**: esr128-14.0 +- [ ] **Alpha**: esr140-15.0 +- [ ] **Stable**: esr128-14.5 ### Backporting View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/074… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/074… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][base-browser-140.0a1-15.0-1] fixup! BB 43615: Add Gitlab Issue and Merge Request templates
by morgan (@morgan) 16 Jun '25

16 Jun '25
morgan pushed to branch base-browser-140.0a1-15.0-1 at The Tor Project / Applications / Tor Browser Commits: b496bae2 by Morgan at 2025-06-16T15:59:27+00:00 fixup! BB 43615: Add Gitlab Issue and Merge Request templates update target channels with esr140-15.0 and esr128-14.5 - - - - - 1 changed file: - .gitlab/merge_request_templates/Default.md Changes: ===================================== .gitlab/merge_request_templates/Default.md ===================================== @@ -27,8 +27,8 @@ #### Target Channels -- [ ] **Alpha**: esr128-14.5 -- [ ] **Stable**: esr128-14.0 +- [ ] **Alpha**: esr140-15.0 +- [ ] **Stable**: esr128-14.5 - [ ] **Legacy**: esr115-13.5 ### Backporting View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b496bae… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b496bae… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-140.0a1-15.0-1] fixup! BB 43615: Add Gitlab Issue and Merge Request templates
by morgan (@morgan) 16 Jun '25

16 Jun '25
morgan pushed to branch tor-browser-140.0a1-15.0-1 at The Tor Project / Applications / Tor Browser Commits: 33e257fa by Morgan at 2025-06-16T15:57:51+00:00 fixup! BB 43615: Add Gitlab Issue and Merge Request templates update target channels with esr140-15.0 and esr128-14.5 - - - - - 1 changed file: - .gitlab/merge_request_templates/Default.md Changes: ===================================== .gitlab/merge_request_templates/Default.md ===================================== @@ -27,8 +27,8 @@ #### Target Channels -- [ ] **Alpha**: esr128-14.5 -- [ ] **Stable**: esr128-14.0 +- [ ] **Alpha**: esr140-15.0 +- [ ] **Stable**: esr128-14.5 - [ ] **Legacy**: esr115-13.5 ### Backporting View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/33e257f… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/33e257f… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser-build][main] Bug 41491: Update firefox artifacts extension
by Pier Angelo Vendrame (@pierov) 16 Jun '25

16 Jun '25
Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build Commits: 9c261825 by Beatriz Rizental at 2025-06-16T16:12:19+02:00 Bug 41491: Update firefox artifacts extension - - - - - 1 changed file: - projects/firefox/build Changes: ===================================== projects/firefox/build ===================================== @@ -136,7 +136,7 @@ echo "Starting ./mach build $(date)" mkdir $artifactsdir # Copy the artifacts to the target directory # Naming convention is the same as Mozilla uses for their artifacts - cp -a obj-*/dist/*.tar.bz2 $artifactsdir/target.tar.bz2 + cp -a obj-*/dist/*.tar.xz $artifactsdir/target.tar.xz cp -a obj-*/dist/*.zip $artifactsdir/target.xpt_artifacts.zip ./mach python -m mozbuild.action.test_archive common $artifactsdir/target.common.tests.tar.gz [% END %] View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/9… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/9… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-140.0a1-15.0-1] fixup! BB 43615: Add Gitlab Issue and Merge Request templates
by morgan (@morgan) 16 Jun '25

16 Jun '25
morgan pushed to branch tor-browser-140.0a1-15.0-1 at The Tor Project / Applications / Tor Browser Commits: a8f4f126 by Morgan at 2025-06-12T19:09:19+00:00 fixup! BB 43615: Add Gitlab Issue and Merge Request templates add ~Emergency label and explicit optional Mullvad communication step - - - - - 1 changed file: - .gitlab/issue_templates/090 Emergency Security Issue.md Changes: ===================================== .gitlab/issue_templates/090 Emergency Security Issue.md ===================================== @@ -82,6 +82,8 @@ Sometimes fixes have side-effects: users lose their data, roadmaps need to be ad - if there are considerations or asks outside the Applications Team - [ ] **(Optional)** **gazebook** - if there are consequences to the organisation or partners beyond a browser update, then a communication plan may be needed + - [ ] **(Optional)** **ruihildt** + - if there are consequences to Mullvad and/or Mullvad Browser Godspeed! :pray: @@ -100,3 +102,4 @@ Godspeed! :pray: /label ~"Apps::Product::MullvadBrowser" /label ~"Apps::Type::Bug" /label ~"Apps::Priority::Blocker" +/label ~"Emergency" View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/a8f4f12… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/a8f4f12… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser-build][main] Bug 41488: Disable sys/random.h for Node.js.
by boklm (@boklm) 13 Jun '25

13 Jun '25
boklm pushed to branch main at The Tor Project / Applications / tor-browser-build Commits: a1e364d3 by Pier Angelo Vendrame at 2025-06-12T18:18:59+02:00 Bug 41488: Disable sys/random.h for Node.js. It is not available in the glibc version we use in our Linux containers. - - - - - 1 changed file: - projects/node/build Changes: ===================================== projects/node/build ===================================== @@ -11,6 +11,11 @@ distdir=/var/tmp/dist/[% project %] tar -xf [% c('input_files_by_name/node') %] cd node-v[% c('version') %] +[% IF c("var/linux") -%] + # Same workaround as Mozilla. See taskcluster/scripts/misc/build-nodejs.sh. + sed -i '/HAVE_SYS_RANDOM_H/d;/HAVE_GETRANDOM/d' deps/cares/config/linux/ares_config.h +[% END -%] + ./configure --prefix=$distdir make -j[% c("num_procs") %] make install View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/a… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/a… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-140.0a1-15.0-1] fixup! TB 40933: Add tor-launcher functionality
by henry (@henry) 12 Jun '25

12 Jun '25
henry pushed to branch tor-browser-140.0a1-15.0-1 at The Tor Project / Applications / Tor Browser Commits: 297b2e99 by Henry Wilkes at 2025-06-12T17:52:26+00:00 fixup! TB 40933: Add tor-launcher functionality TB 43577: Do not try and flush settings to torrc on android. - - - - - 1 changed file: - toolkit/components/tor-launcher/TorProvider.sys.mjs Changes: ===================================== toolkit/components/tor-launcher/TorProvider.sys.mjs ===================================== @@ -356,6 +356,10 @@ export class TorProvider { } async flushSettings() { + if (TorLauncherUtil.isAndroid) { + // Android does not have a torrc to flush to. See tor-browser#43577. + return; + } await this.#controller.flushSettings(); } View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/297b2e9… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/297b2e9… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-115.24.0esr-13.5-1] 5 commits: fixup! Bug 40925: Implemented the Security Level component
by ma1 (@ma1) 12 Jun '25

12 Jun '25
ma1 pushed to branch tor-browser-115.24.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: 88b35704 by Henry Wilkes at 2025-06-09T17:04:40+01:00 fixup! Bug 40925: Implemented the Security Level component TB 43783: Prompt user for a restart if their security level preferences are not aligned at startup or mid-session. Also handle failures to apply NoScript settings. - - - - - 6c89d75e by Henry Wilkes at 2025-06-09T17:05:13+01:00 fixup! Bug 40069: Add helpers for message passing with extensions TB 43783: Allow the browser to wait for the NoScript settings to be applied. - - - - - 9c10817a by Henry Wilkes at 2025-06-09T17:05:54+01:00 fixup! Base Browser strings TB 43783: Add security level prompt strings. - - - - - cdd62d0c by Henry Wilkes at 2025-06-09T17:05:59+01:00 fixup! Base Browser strings TB 43782: Add strings for new security level UX flow. - - - - - ebb66713 by Henry Wilkes at 2025-06-09T17:06:02+01:00 fixup! Bug 40925: Implemented the Security Level component TB 43782: Update security level UI for new UX flow. In addition, we drop the distinction between the security levels in the UI when the user has a custom security level. I.e. we always show shield as unfilled but with a yellow dot in the toolbar, and we just call it "Custom" rather than "Standard Custom", etc. - - - - - 17 changed files: - browser/components/BrowserGlue.sys.mjs - + browser/components/securitylevel/SecurityLevelUIUtils.sys.mjs - browser/components/securitylevel/content/securityLevel.js - browser/components/securitylevel/content/securityLevelButton.css - + browser/components/securitylevel/content/securityLevelDialog.js - + browser/components/securitylevel/content/securityLevelDialog.xhtml - browser/components/securitylevel/content/securityLevelPanel.css - browser/components/securitylevel/content/securityLevelPanel.inc.xhtml - browser/components/securitylevel/content/securityLevelPreferences.css - browser/components/securitylevel/content/securityLevelPreferences.inc.xhtml - browser/components/securitylevel/jar.mn - browser/components/securitylevel/moz.build - + browser/modules/SecurityLevelRestartNotification.sys.mjs - browser/modules/moz.build - toolkit/components/extensions/ExtensionParent.sys.mjs - toolkit/components/securitylevel/SecurityLevel.sys.mjs - toolkit/locales/en-US/toolkit/global/base-browser.ftl Changes: ===================================== browser/components/BrowserGlue.sys.mjs ===================================== @@ -59,6 +59,8 @@ ChromeUtils.defineESModuleGetters(lazy, { Sanitizer: "resource:///modules/Sanitizer.sys.mjs", ScreenshotsUtils: "resource:///modules/ScreenshotsUtils.sys.mjs", SearchSERPTelemetry: "resource:///modules/SearchSERPTelemetry.sys.mjs", + SecurityLevelRestartNotification: + "resource:///modules/SecurityLevelRestartNotification.sys.mjs", SessionStartup: "resource:///modules/sessionstore/SessionStartup.sys.mjs", SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs", ShellService: "resource:///modules/ShellService.sys.mjs", @@ -1907,6 +1909,8 @@ BrowserGlue.prototype = { lazy.DragDropFilter.init(); + lazy.SecurityLevelRestartNotification.ready(); + lazy.TorProviderBuilder.firstWindowLoaded(); ClipboardPrivacy.startup(); ===================================== browser/components/securitylevel/SecurityLevelUIUtils.sys.mjs ===================================== @@ -0,0 +1,73 @@ +/** + * Common methods for the desktop security level components. + */ +export const SecurityLevelUIUtils = { + /** + * Create an element that gives a description of the security level. To be + * used in the settings. + * + * @param {string} level - The security level to describe. + * @param {Document} doc - The document where the element will be inserted. + * + * @returns {Element} - The newly created element. + */ + createDescriptionElement(level, doc) { + const el = doc.createElement("div"); + el.classList.add("security-level-description"); + + let l10nIdSummary; + let bullets; + switch (level) { + case "standard": + l10nIdSummary = "security-level-summary-standard"; + break; + case "safer": + l10nIdSummary = "security-level-summary-safer"; + bullets = [ + "security-level-preferences-bullet-https-only-javascript", + "security-level-preferences-bullet-limit-font-and-symbols", + "security-level-preferences-bullet-limit-media", + ]; + break; + case "safest": + l10nIdSummary = "security-level-summary-safest"; + bullets = [ + "security-level-preferences-bullet-disabled-javascript", + "security-level-preferences-bullet-limit-font-and-symbols-and-images", + "security-level-preferences-bullet-limit-media", + ]; + break; + case "custom": + l10nIdSummary = "security-level-summary-custom"; + break; + default: + throw Error(`Unhandled level: ${level}`); + } + + const summaryEl = doc.createElement("div"); + summaryEl.classList.add("security-level-summary"); + doc.l10n.setAttributes(summaryEl, l10nIdSummary); + + el.append(summaryEl); + + if (!bullets) { + return el; + } + + const listEl = doc.createElement("ul"); + listEl.classList.add("security-level-description-extra"); + // Add a mozilla styling class as well: + listEl.classList.add("privacy-extra-information"); + for (const l10nId of bullets) { + const bulletEl = doc.createElement("li"); + bulletEl.classList.add("security-level-description-bullet"); + + doc.l10n.setAttributes(bulletEl, l10nId); + + listEl.append(bulletEl); + } + + el.append(listEl); + return el; + }, +}; ===================================== browser/components/securitylevel/content/securityLevel.js ===================================== @@ -1,9 +1,10 @@ "use strict"; -/* global AppConstants, Services, openPreferences, XPCOMUtils */ +/* global AppConstants, Services, openPreferences, XPCOMUtils, gSubDialog */ ChromeUtils.defineESModuleGetters(this, { SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", + SecurityLevelUIUtils: "resource:///modules/SecurityLevelUIUtils.sys.mjs", }); /* @@ -35,12 +36,8 @@ var SecurityLevelButton = { _anchorButton: null, _configUIFromPrefs() { - const level = SecurityLevelPrefs.securityLevel; - if (!level) { - return; - } - const custom = SecurityLevelPrefs.securityCustom; - this._button.setAttribute("level", custom ? `${level}_custom` : level); + const level = SecurityLevelPrefs.securityLevelSummary; + this._button.setAttribute("level", level); let l10nIdLevel; switch (level) { @@ -53,15 +50,12 @@ var SecurityLevelButton = { case "safest": l10nIdLevel = "security-level-toolbar-button-safest"; break; + case "custom": + l10nIdLevel = "security-level-toolbar-button-custom"; + break; default: throw Error(`Unhandled level: ${level}`); } - if (custom) { - // Don't distinguish between the different levels when in the custom - // state. We just want to emphasise that it is custom rather than any - // specific level. - l10nIdLevel = "security-level-toolbar-button-custom"; - } document.l10n.setAttributes(this._button, l10nIdLevel); }, @@ -164,12 +158,7 @@ var SecurityLevelPanel = { panel: document.getElementById("securityLevel-panel"), background: document.getElementById("securityLevel-background"), levelName: document.getElementById("securityLevel-level"), - customName: document.getElementById("securityLevel-custom"), summary: document.getElementById("securityLevel-summary"), - restoreDefaultsButton: document.getElementById( - "securityLevel-restoreDefaults" - ), - settingsButton: document.getElementById("securityLevel-settings"), }; const learnMoreEl = document.getElementById("securityLevel-learnMore"); @@ -177,12 +166,11 @@ var SecurityLevelPanel = { this.hide(); }); - this._elements.restoreDefaultsButton.addEventListener("command", () => { - this.restoreDefaults(); - }); - this._elements.settingsButton.addEventListener("command", () => { - this.openSecuritySettings(); - }); + document + .getElementById("securityLevel-settings") + .addEventListener("command", () => { + this.openSecuritySettings(); + }); this._elements.panel.addEventListener("popupshown", () => { // Bring focus into the panel by focusing the default button. @@ -200,19 +188,7 @@ var SecurityLevelPanel = { } // get security prefs - const level = SecurityLevelPrefs.securityLevel; - const custom = SecurityLevelPrefs.securityCustom; - - // only visible when user is using custom settings - this._elements.customName.hidden = !custom; - this._elements.restoreDefaultsButton.hidden = !custom; - if (custom) { - this._elements.settingsButton.removeAttribute("default"); - this._elements.restoreDefaultsButton.setAttribute("default", "true"); - } else { - this._elements.settingsButton.setAttribute("default", "true"); - this._elements.restoreDefaultsButton.removeAttribute("default"); - } + const level = SecurityLevelPrefs.securityLevelSummary; // Descriptions change based on security level this._elements.background.setAttribute("level", level); @@ -231,12 +207,13 @@ var SecurityLevelPanel = { l10nIdLevel = "security-level-panel-level-safest"; l10nIdSummary = "security-level-summary-safest"; break; + case "custom": + l10nIdLevel = "security-level-panel-level-custom"; + l10nIdSummary = "security-level-summary-custom"; + break; default: throw Error(`Unhandled level: ${level}`); } - if (custom) { - l10nIdSummary = "security-level-summary-custom"; - } document.l10n.setAttributes(this._elements.levelName, l10nIdLevel); document.l10n.setAttributes(this._elements.summary, l10nIdSummary); @@ -270,13 +247,6 @@ var SecurityLevelPanel = { this._elements.panel.hidePopup(); }, - restoreDefaults() { - SecurityLevelPrefs.securityCustom = false; - // Move focus to the settings button since restore defaults button will - // become hidden. - this._elements.settingsButton.focus(); - }, - openSecuritySettings() { openPreferences("privacy-securitylevel"); this.hide(); @@ -302,62 +272,64 @@ var SecurityLevelPanel = { var SecurityLevelPreferences = { _securityPrefsBranch: null, + /** - * The notification box shown when the user has a custom security setting. - * - * @type {Element} - */ - _customNotification: null, - /** - * The radiogroup for this preference. - * - * @type {Element} - */ - _radiogroup: null, - /** - * A list of radio options and their containers. + * The element that shows the current security level. * - * @type {Array<object>} + * @type {?Element} */ - _radioOptions: null, + _currentEl: null, _populateXUL() { - this._customNotification = document.getElementById( - "securityLevel-customNotification" + this._currentEl = document.getElementById("security-level-current"); + const changeButton = document.getElementById("security-level-change"); + const badgeEl = this._currentEl.querySelector( + ".security-level-current-badge" ); - document - .getElementById("securityLevel-restoreDefaults") - .addEventListener("command", () => { - SecurityLevelPrefs.securityCustom = false; - }); - this._radiogroup = document.getElementById("securityLevel-radiogroup"); + for (const { level, nameId } of [ + { level: "standard", nameId: "security-level-panel-level-standard" }, + { level: "safer", nameId: "security-level-panel-level-safer" }, + { level: "safest", nameId: "security-level-panel-level-safest" }, + { level: "custom", nameId: "security-level-panel-level-custom" }, + ]) { + // Classes that control visibility: + // security-level-current-standard + // security-level-current-safer + // security-level-current-safest + // security-level-current-custom + const visibilityClass = `security-level-current-${level}`; + const nameEl = document.createElement("div"); + nameEl.classList.add("security-level-name", visibilityClass); + document.l10n.setAttributes(nameEl, nameId); + + const descriptionEl = SecurityLevelUIUtils.createDescriptionElement( + level, + document + ); + descriptionEl.classList.add(visibilityClass); - this._radioOptions = Array.from( - this._radiogroup.querySelectorAll(".securityLevel-radio-option"), - container => { - return { container, radio: container.querySelector("radio") }; - } - ); + this._currentEl.insertBefore(nameEl, badgeEl); + this._currentEl.insertBefore(descriptionEl, changeButton); + } - this._radiogroup.addEventListener("select", () => { - SecurityLevelPrefs.securityLevel = this._radiogroup.value; + changeButton.addEventListener("click", () => { + this._openDialog(); }); }, + _openDialog() { + gSubDialog.open( + "chrome://browser/content/securitylevel/securityLevelDialog.xhtml", + { features: "resizable=yes" } + ); + }, + _configUIFromPrefs() { - this._radiogroup.value = SecurityLevelPrefs.securityLevel; - const isCustom = SecurityLevelPrefs.securityCustom; - this._radiogroup.disabled = isCustom; - this._customNotification.hidden = !isCustom; - // Have the container's selection CSS class match the selection state of the - // radio elements. - for (const { container, radio } of this._radioOptions) { - container.classList.toggle( - "securityLevel-radio-option-selected", - radio.selected - ); - } + // Set a data-current-level attribute for showing the current security + // level, and hiding the rest. + this._currentEl.dataset.currentLevel = + SecurityLevelPrefs.securityLevelSummary; }, init() { ===================================== browser/components/securitylevel/content/securityLevelButton.css ===================================== @@ -7,12 +7,6 @@ toolbarbutton#security-level-button[level="safer"] { toolbarbutton#security-level-button[level="safest"] { list-style-image: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#safest"); } -toolbarbutton#security-level-button[level="standard_custom"] { +toolbarbutton#security-level-button[level="custom"] { list-style-image: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#standard_custom"); } -toolbarbutton#security-level-button[level="safer_custom"] { - list-style-image: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#safer_custom"); -} -toolbarbutton#security-level-button[level="safest_custom"] { - list-style-image: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#safest_custom"); -} \ No newline at end of file ===================================== browser/components/securitylevel/content/securityLevelDialog.js ===================================== @@ -0,0 +1,188 @@ +"use strict"; + +const { SecurityLevelPrefs } = ChromeUtils.importESModule( + "resource://gre/modules/SecurityLevel.sys.mjs" +); +const { SecurityLevelUIUtils } = ChromeUtils.importESModule( + "resource:///modules/SecurityLevelUIUtils.sys.mjs" +); + +const gSecurityLevelDialog = { + /** + * The security level when this dialog was opened. + * + * @type {string} + */ + _prevLevel: SecurityLevelPrefs.securityLevelSummary, + /** + * The security level currently selected. + * + * @type {string} + */ + _selectedLevel: "", + /** + * The radiogroup for this preference. + * + * @type {?Element} + */ + _radiogroup: null, + /** + * A list of radio options and their containers. + * + * @type {?Array<{ container: Element, radio: Element }>} + */ + _radioOptions: null, + + /** + * Initialise the dialog. + */ + async init() { + const dialog = document.getElementById("security-level-dialog"); + dialog.addEventListener("dialogaccept", event => { + if (this._acceptButton.disabled) { + event.preventDefault(); + return; + } + this._commitChange(); + }); + + this._acceptButton = dialog.getButton("accept"); + + document.l10n.setAttributes( + this._acceptButton, + "security-level-dialog-save-restart" + ); + + this._radiogroup = document.getElementById("security-level-radiogroup"); + + this._radioOptions = Array.from( + this._radiogroup.querySelectorAll(".security-level-radio-container"), + container => { + return { + container, + radio: container.querySelector(".security-level-radio"), + }; + } + ); + + for (const { container, radio } of this._radioOptions) { + const level = radio.value; + radio.id = `security-level-radio-${level}`; + const currentEl = container.querySelector( + ".security-level-current-badge" + ); + currentEl.id = `security-level-current-badge-${level}`; + const descriptionEl = SecurityLevelUIUtils.createDescriptionElement( + level, + document + ); + descriptionEl.classList.add("indent"); + descriptionEl.id = `security-level-description-${level}`; + + // Wait for the full translation of the element before adding it to the + // DOM. In particular, we want to make sure the elements have text before + // we measure the maxHeight below. + await document.l10n.translateFragment(descriptionEl); + document.l10n.pauseObserving(); + container.append(descriptionEl); + document.l10n.resumeObserving(); + + if (level === this._prevLevel) { + currentEl.hidden = false; + // When the currentEl is visible, include it in the accessible name for + // the radio option. + // NOTE: The currentEl has an accessible name which includes punctuation + // to help separate it's content from the security level name. + // E.g. "Standard (Current level)". + radio.setAttribute("aria-labelledby", `${radio.id} ${currentEl.id}`); + } else { + currentEl.hidden = true; + } + // We point the accessible description to the wrapping + // .security-level-description element, rather than its children + // that define the actual text content. This means that when the + // privacy-extra-information is shown or hidden, its text content is + // included or excluded from the accessible description, respectively. + radio.setAttribute("aria-describedby", descriptionEl.id); + } + + // We want to reserve the maximum height of the radiogroup so that the + // dialog has enough height when the user switches options. So we cycle + // through the options and measure the height when they are selected to set + // a minimum height that fits all of them. + // NOTE: At the time of implementation, at this point the dialog may not + // yet have the "subdialog" attribute, which means it is missing the + // common.css stylesheet from its shadow root, which effects the size of the + // .radio-check element and the font. Therefore, we have duplicated the + // import of common.css in SecurityLevelDialog.xhtml to ensure it is applied + // at this earlier stage. + let maxHeight = 0; + for (const { container } of this._radioOptions) { + container.classList.add("selected"); + maxHeight = Math.max( + maxHeight, + this._radiogroup.getBoundingClientRect().height + ); + container.classList.remove("selected"); + } + this._radiogroup.style.minHeight = `${maxHeight}px`; + + if (this._prevLevel !== "custom") { + this._selectedLevel = this._prevLevel; + this._radiogroup.value = this._prevLevel; + } else { + this._radiogroup.selectedItem = null; + } + + this._radiogroup.addEventListener("select", () => { + this._selectedLevel = this._radiogroup.value; + this._updateSelected(); + }); + + this._updateSelected(); + }, + + /** + * Update the UI in response to a change in selection. + */ + _updateSelected() { + this._acceptButton.disabled = + !this._selectedLevel || this._selectedLevel === this._prevLevel; + // Have the container's `selected` CSS class match the selection state of + // the radio elements. + for (const { container, radio } of this._radioOptions) { + container.classList.toggle("selected", radio.selected); + } + }, + + /** + * Commit the change in security level and restart the browser. + */ + _commitChange() { + SecurityLevelPrefs.setSecurityLevelBeforeRestart(this._selectedLevel); + Services.startup.quit( + Services.startup.eAttemptQuit | Services.startup.eRestart + ); + }, +}; + +// Initial focus is not visible, even if opened with a keyboard. We avoid the +// default handler and manage the focus ourselves, which will paint the focus +// ring by default. +// NOTE: A side effect is that the focus ring will show even if the user opened +// with a mouse event. +// TODO: Remove this once bugzilla bug 1708261 is resolved. +document.subDialogSetDefaultFocus = () => { + document.getElementById("security-level-radiogroup").focus(); +}; + +// Delay showing and sizing the subdialog until it is fully initialised. +document.mozSubdialogReady = new Promise(resolve => { + window.addEventListener( + "DOMContentLoaded", + () => { + gSecurityLevelDialog.init().finally(resolve); + }, + { once: true } + ); +}); ===================================== browser/components/securitylevel/content/securityLevelDialog.xhtml ===================================== @@ -0,0 +1,86 @@ +<?xml version="1.0"?> + +<window + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + data-l10n-id="security-level-dialog-window" +> + <dialog id="security-level-dialog" buttons="accept,cancel"> + <linkset> + <html:link rel="stylesheet" href="chrome://global/skin/global.css" /> + <!-- NOTE: We include common.css explicitly, rather than relying on + - the dialog's shadowroot importing it, which is late loaded in + - response to the dialog's "subdialog" attribute, which is set + - in response to DOMFrameContentLoaded. + - In particular, we need the .radio-check rule and font rules from + - common-shared.css to be in place when gSecurityLevelDialog.init is + - called, which will help ensure that the radio element has the correct + - size when we measure its bounding box. --> + <html:link + rel="stylesheet" + href="chrome://global/skin/in-content/common.css" + /> + <html:link + rel="stylesheet" + href="chrome://browser/skin/preferences/preferences.css" + /> + <html:link + rel="stylesheet" + href="chrome://browser/skin/preferences/privacy.css" + /> + <html:link + rel="stylesheet" + href="chrome://browser/content/securitylevel/securityLevelPreferences.css" + /> + + <html:link rel="localization" href="branding/brand.ftl" /> + <html:link rel="localization" href="toolkit/global/base-browser.ftl" /> + </linkset> + + <script src="chrome://browser/content/securitylevel/securityLevelDialog.js" /> + + <description data-l10n-id="security-level-dialog-restart-description" /> + + <radiogroup id="security-level-radiogroup" class="highlighting-group"> + <html:div + class="security-level-radio-container security-level-grid privacy-detailedoption info-box-container" + > + <radio + class="security-level-radio security-level-name" + value="standard" + data-l10n-id="security-level-preferences-level-standard" + /> + <html:div + class="security-level-current-badge" + data-l10n-id="security-level-preferences-current-badge" + ></html:div> + </html:div> + <html:div + class="security-level-radio-container security-level-grid privacy-detailedoption info-box-container" + > + <radio + class="security-level-radio security-level-name" + value="safer" + data-l10n-id="security-level-preferences-level-safer" + /> + <html:div + class="security-level-current-badge" + data-l10n-id="security-level-preferences-current-badge" + ></html:div> + </html:div> + <html:div + class="security-level-radio-container security-level-grid privacy-detailedoption info-box-container" + > + <radio + class="security-level-radio security-level-name" + value="safest" + data-l10n-id="security-level-preferences-level-safest" + /> + <html:div + class="security-level-current-badge" + data-l10n-id="security-level-preferences-current-badge" + ></html:div> + </html:div> + </radiogroup> + </dialog> +</window> ===================================== browser/components/securitylevel/content/securityLevelPanel.css ===================================== @@ -23,7 +23,7 @@ background-position-x: right var(--background-inline-offset); } -#securityLevel-background[level="standard"] { +#securityLevel-background:is([level="standard"], [level="custom"]) { background-image: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#standard"); } @@ -49,14 +49,6 @@ font-weight: 600; } -#securityLevel-custom { - border-radius: 4px; - background-color: var(--warning-color); - color: black; - padding: 0.4em 0.5em; - margin-inline-start: 1em; -} - #securityLevel-summary { padding-inline-end: 5em; max-width: 20em; ===================================== browser/components/securitylevel/content/securityLevelPanel.inc.xhtml ===================================== @@ -16,10 +16,6 @@ <vbox id="securityLevel-background" class="panel-subview-body"> <html:p id="securityLevel-subheading"> <html:span id="securityLevel-level"></html:span> - <html:span - id="securityLevel-custom" - data-l10n-id="security-level-panel-custom-badge" - ></html:span> </html:p> <html:p id="securityLevel-summary"></html:p> <html:a @@ -32,11 +28,8 @@ <hbox class="panel-footer"> <button id="securityLevel-settings" + default="true" data-l10n-id="security-level-panel-open-settings-button" /> - <button - id="securityLevel-restoreDefaults" - data-l10n-id="security-level-restore-defaults-button" - /> </hbox> </panel> ===================================== browser/components/securitylevel/content/securityLevelPreferences.css ===================================== @@ -1,58 +1,185 @@ -#securityLevel-groupbox { - --section-highlight-background-color: color-mix(in srgb, var(--in-content-accent-color) 20%, transparent); +/* CSS variables copied from ESR 128 */ +:root { + --space-xsmall: 0.267rem; + --space-small: calc(2 * var(--space-xsmall)); + --space-medium: calc(3 * var(--space-xsmall)); + --space-large: calc(4 * var(--space-xsmall)); + --space-xlarge: calc(6 * var(--space-xsmall)); + --font-size-small: 0.867rem; + --background-color-information: #e2f7ff; /* acorn oklch --color-blue-0 */ + --button-text-color-primary: var(--in-content-primary-button-text-color); + --border-radius-small: 4px; } -#securityLevel-customNotification { - /* Spacing similar to #fpiIncompatibilityWarning. */ - margin-block: 16px; +@media (prefers-color-scheme: dark) { + :root { + --background-color-information: #00317e; /* acorn oklch --color-blue-90 */ + } } -.info-icon.securityLevel-custom-warning-icon { - list-style-image: url("chrome://global/skin/icons/warning.svg"); +.security-level-grid { + display: grid; + grid-template: + "icon name badge button" min-content + "icon summary summary button" auto + "icon extra extra ." auto + / max-content max-content 1fr max-content; } -#securityLevel-customHeading { - font-weight: bold; +.security-level-icon { + grid-area: icon; + align-self: start; + width: 24px; + height: 24px; + -moz-context-properties: fill; + fill: var(--in-content-icon-color); + margin-block-start: var(--space-xsmall); + margin-inline-end: var(--space-large); +} + +.security-level-current-badge { + grid-area: badge; + align-self: center; + justify-self: start; + white-space: nowrap; + background: var(--background-color-information); + color: inherit; + font-size: var(--font-size-small); + border-radius: var(--border-radius-circle); + margin-inline-start: var(--space-small); + padding-block: var(--space-xsmall); + padding-inline: var(--space-small); +} + +.security-level-current-badge span { + /* Still accessible to screen reader, but not visual. + * Keep inline, but with no layout width. */ + display: inline-block; + width: 1px; + margin-inline-end: -1px; + clip-path: inset(50%); } -/* Overwrite indent rule from preferences.css */ -#securityLevel-radiogroup description.indent { - color: var(--in-content-page-color); +@media (prefers-contrast) and (not (forced-colors)) { + .security-level-current-badge { + /* Match the checkbox/radio colors. */ + background: var(--color-accent-primary); + color: var(--button-text-color-primary); + } } -#securityLevel-radiogroup radio { +@media (forced-colors) { + .security-level-current-badge { + /* Match the checkbox/radio/selected colors. */ + background: SelectedItem; + color: SelectedItemText; + } +} + +.security-level-name { + grid-area: name; font-weight: bold; + align-self: center; + white-space: nowrap; +} + +.security-level-description { + display: grid; + grid-column: summary-start / extra-end; + grid-row: summary-start / extra-end; + grid-template-rows: subgrid; + grid-template-columns: subgrid; + margin-block-start: var(--space-small); +} + +.security-level-summary { + grid-area: summary; } -#securityLevel-radiogroup[disabled] { - opacity: 0.5; +.security-level-description-extra { + grid-area: extra; + margin-block: var(--space-medium) 0; + margin-inline: var(--space-large) 0; + padding: 0; } -/* Overwrite the rule in common-shared.css so we don't get 0.25 opacity overall - * on the radio text. */ -#securityLevel-radiogroup[disabled] radio[disabled] { - opacity: 1.0; +.security-level-description-bullet:not(:last-child) { + margin-block-end: var(--space-medium); } -.securityLevel-radio-option { +/* Tweak current security level display. */ + +#security-level-current { + margin-block-start: var(--space-large); + background: var(--in-content-box-background); border: 1px solid var(--in-content-box-border-color); - border-radius: 4px; - margin: 3px 0; - padding: 9px; + border-radius: var(--border-radius-small); + padding: var(--space-medium); } -.securityLevel-radio-option.securityLevel-radio-option-selected { - background-color: var(--section-highlight-background-color); - border: 1px solid var(--in-content-accent-color); +#security-level-change { + grid-area: button; + align-self: center; + margin: 0; + margin-inline-start: var(--space-large); +} + +/* Adjust which content is visible depending on the current security level. */ + +#security-level-current:not([data-current-level="standard"]) .security-level-current-standard { + display: none; +} +#security-level-current:not([data-current-level="safer"]) .security-level-current-safer { + display: none; } -.securityLevel-radio-option:not( - .securityLevel-radio-option-selected -) .securityLevel-descriptionList { +#security-level-current:not([data-current-level="safest"]) .security-level-current-safest { display: none; } -.securityLevel-descriptionList description { - display: list-item; +#security-level-current:not([data-current-level="custom"]) .security-level-current-custom { + display: none; +} + +#security-level-current[data-current-level="standard"] .security-level-icon { + content: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#standard"); +} + +#security-level-current[data-current-level="safer"] .security-level-icon { + content: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#safer"); +} + +#security-level-current[data-current-level="safest"] .security-level-icon { + content: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#safest"); +} + +#security-level-current[data-current-level="custom"] .security-level-icon { + content: url("chrome://browser/content/securitylevel/securityLevelIcon.svg#standard_custom"); +} + +/* Tweak security level dialog. */ + +#security-level-radiogroup { + margin-block: var(--space-large) var(--space-xlarge); +} + +.security-level-radio-container { + padding-block: var(--space-large); +} + +#security-level-radiogroup .security-level-radio { + margin: 0; +} + +#security-level-radiogroup .radio-label-box { + /* .security-level-current-badge already has a margin. */ + margin: 0; +} + +#security-level-radiogroup .privacy-detailedoption.security-level-radio-container:not(.selected) .security-level-description-extra { + /* .privacy-detailedoption uses visibility: hidden, which does not work with + * our grid display (the margin is still reserved) so we use display: none + * instead. */ + display: none; } ===================================== browser/components/securitylevel/content/securityLevelPreferences.inc.xhtml ===================================== @@ -18,108 +18,19 @@ data-l10n-id="security-level-preferences-learn-more-link" ></html:a> </description> - <hbox - id="securityLevel-customNotification" - class="info-box-container" - flex="1" - > - <hbox class="info-icon-container"> - <image class="info-icon securityLevel-custom-warning-icon"/> - </hbox> - <vbox flex="1"> - <label - id="securityLevel-customHeading" - data-l10n-id="security-level-preferences-custom-heading" - /> - <description - id="securityLevel-customDescription" - data-l10n-id="security-level-summary-custom" - flex="1" - /> - </vbox> - <hbox align="center"> - <button - id="securityLevel-restoreDefaults" - data-l10n-id="security-level-restore-defaults-button" - /> - </hbox> - </hbox> - <radiogroup id="securityLevel-radiogroup"> - <vbox class="securityLevel-radio-option"> - <radio - value="standard" - data-l10n-id="security-level-preferences-level-standard" - aria-describedby="securityLevelSummary-standard" - /> - <vbox id="securityLevelSummary-standard"> - <description - class="summary indent" - flex="1" - data-l10n-id="security-level-summary-standard" - /> - </vbox> - </vbox> - <vbox class="securityLevel-radio-option"> - <!-- NOTE: We point the accessible description to the wrapping vbox - - rather than its first description element. This means that when the - - securityLevel-descriptionList is shown or hidden, its text content - - is included or excluded from the accessible description, - - respectively. --> - <radio - value="safer" - data-l10n-id="security-level-preferences-level-safer" - aria-describedby="securityLevelSummary-safer" - /> - <vbox id="securityLevelSummary-safer"> - <description - class="summary indent" - flex="1" - data-l10n-id="security-level-summary-safer" - /> - <vbox class="securityLevel-descriptionList indent"> - <description - class="indent" - data-l10n-id="security-level-preferences-bullet-https-only-javascript" - /> - <description - class="indent" - data-l10n-id="security-level-preferences-bullet-limit-font-and-symbols" - /> - <description - class="indent" - data-l10n-id="security-level-preferences-bullet-limit-media" - /> - </vbox> - </vbox> - </vbox> - <vbox class="securityLevel-radio-option"> - <radio - value="safest" - data-l10n-id="security-level-preferences-level-safest" - aria-describedby="securityLevelSummary-safest" - /> - <vbox id="securityLevelSummary-safest"> - <description - class="summary indent" - flex="1" - data-l10n-id="security-level-summary-safest" - /> - <vbox class="securityLevel-descriptionList indent"> - <description - class="indent" - data-l10n-id="security-level-preferences-bullet-disabled-javascript" - /> - <description - class="indent" - data-l10n-id="security-level-preferences-bullet-limit-font-and-symbols-and-images" - /> - <description - class="indent" - data-l10n-id="security-level-preferences-bullet-limit-media" - /> - </vbox> - </vbox> - </vbox> - </radiogroup> + <html:div id="security-level-current" class="security-level-grid"> + <html:img + class="security-level-icon" + alt="" + /> + <html:div + class="security-level-current-badge" + data-l10n-id="security-level-preferences-current-badge" + ></html:div> + <html:button + id="security-level-change" + data-l10n-id="security-level-preferences-change-button" + ></html:button> + </html:div> </vbox> </groupbox> ===================================== browser/components/securitylevel/jar.mn ===================================== @@ -4,3 +4,5 @@ browser.jar: content/browser/securitylevel/securityLevelButton.css (content/securityLevelButton.css) content/browser/securitylevel/securityLevelPreferences.css (content/securityLevelPreferences.css) content/browser/securitylevel/securityLevelIcon.svg (content/securityLevelIcon.svg) + content/browser/securitylevel/securityLevelDialog.xhtml (content/securityLevelDialog.xhtml) + content/browser/securitylevel/securityLevelDialog.js (content/securityLevelDialog.js) ===================================== browser/components/securitylevel/moz.build ===================================== @@ -1 +1,5 @@ JAR_MANIFESTS += ["jar.mn"] + +EXTRA_JS_MODULES += [ + "SecurityLevelUIUtils.sys.mjs", +] ===================================== browser/modules/SecurityLevelRestartNotification.sys.mjs ===================================== @@ -0,0 +1,77 @@ +import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; + +const lazy = {}; + +XPCOMUtils.defineLazyModuleGetters(lazy, { + BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm", +}); + +ChromeUtils.defineESModuleGetters(lazy, { + SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", +}); + +ChromeUtils.defineLazyGetter(lazy, "NotificationStrings", function () { + return new Localization([ + "branding/brand.ftl", + "toolkit/global/base-browser.ftl", + ]); +}); + +/** + * Interface for showing the security level restart notification on desktop. + */ +export const SecurityLevelRestartNotification = { + /** + * Whether we have already been initialised. + * + * @type {boolean} + */ + _initialized: false, + + /** + * Called when the UI is ready to show a notification. + */ + ready() { + if (this._initialized) { + return; + } + this._initialized = true; + lazy.SecurityLevelPrefs.setRestartNotificationHandler(this); + }, + + /** + * Show the restart notification, and perform the restart if the user agrees. + */ + async tryRestartBrowser() { + const [titleText, bodyText, primaryButtonText, secondaryButtonText] = + await lazy.NotificationStrings.formatValues([ + { id: "security-level-restart-prompt-title" }, + { id: "security-level-restart-prompt-body" }, + { id: "security-level-restart-prompt-button-restart" }, + { id: "security-level-restart-prompt-button-ignore" }, + ]); + const buttonFlags = + Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 + + Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_1; + + const propBag = await Services.prompt.asyncConfirmEx( + lazy.BrowserWindowTracker.getTopWindow()?.browsingContext ?? null, + Services.prompt.MODAL_TYPE_INTERNAL_WINDOW, + titleText, + bodyText, + buttonFlags, + primaryButtonText, + secondaryButtonText, + null, + null, + null, + {} + ); + + if (propBag.get("buttonNumClicked") === 0) { + Services.startup.quit( + Services.startup.eAttemptQuit | Services.startup.eRestart + ); + } + }, +}; ===================================== browser/modules/moz.build ===================================== @@ -142,6 +142,7 @@ EXTRA_JS_MODULES += [ "PingCentre.jsm", "ProcessHangMonitor.jsm", "Sanitizer.sys.mjs", + "SecurityLevelRestartNotification.sys.mjs", "SelectionChangedMenulist.jsm", "SiteDataManager.jsm", "SitePermissions.sys.mjs", ===================================== toolkit/components/extensions/ExtensionParent.sys.mjs ===================================== @@ -2275,6 +2275,7 @@ async function torSendExtensionMessage(extensionId, message) { const result = await ProxyMessenger.conduit.castRuntimeMessage("messenger", { extensionId, holder: new StructuredCloneHolder("torSendExtensionMessage", null, message), + query: true, firstResponse: true, sender: { id: extensionId, ===================================== toolkit/components/securitylevel/SecurityLevel.sys.mjs ===================================== @@ -18,6 +18,7 @@ const BrowserTopics = Object.freeze({ // The Security Settings prefs in question. const kSliderPref = "browser.security_level.security_slider"; const kCustomPref = "browser.security_level.security_custom"; +const kNoScriptInitedPref = "browser.security_level.noscript_inited"; // __getPrefValue(prefName)__ // Returns the current value of a preference, regardless of its type. @@ -34,11 +35,11 @@ var getPrefValue = function (prefName) { } }; -// __bindPref(prefName, prefHandler, init)__ +// __bindPref(prefName, prefHandler)__ // Applies prefHandler whenever the value of the pref changes. // If init is true, applies prefHandler to the current value. -// Returns a zero-arg function that unbinds the pref. -var bindPref = function (prefName, prefHandler, init = false) { +// Returns the observer that was added. +var bindPref = function (prefName, prefHandler) { let update = () => { prefHandler(getPrefValue(prefName)); }, @@ -50,21 +51,9 @@ var bindPref = function (prefName, prefHandler, init = false) { }, }; Services.prefs.addObserver(prefName, observer); - if (init) { - update(); - } - return () => { - Services.prefs.removeObserver(prefName, observer); - }; + return observer; }; -// __bindPrefAndInit(prefName, prefHandler)__ -// Applies prefHandler to the current value of pref specified by prefName. -// Re-applies prefHandler whenever the value of the pref changes. -// Returns a zero-arg function that unbinds the pref. -var bindPrefAndInit = (prefName, prefHandler) => - bindPref(prefName, prefHandler, true); - async function waitForExtensionMessage(extensionId, checker = () => {}) { const { torWaitForExtensionMessage } = lazy.ExtensionParent; if (torWaitForExtensionMessage) { @@ -76,7 +65,7 @@ async function waitForExtensionMessage(extensionId, checker = () => {}) { async function sendExtensionMessage(extensionId, message) { const { torSendExtensionMessage } = lazy.ExtensionParent; if (torSendExtensionMessage) { - return torSendExtensionMessage(extensionId, message); + return await torSendExtensionMessage(extensionId, message); } return undefined; } @@ -189,14 +178,8 @@ var initializeNoScriptControl = () => { // `browser.runtime.onMessage.addListener(...)` in NoScript's bg/main.js. // TODO: Is there a better way? - let sendNoScriptSettings = settings => - sendExtensionMessage(noscriptID, settings); - - // __setNoScriptSafetyLevel(safetyLevel)__. - // Set NoScript settings according to a particular safety level - // (security slider level): 0 = Standard, 1 = Safer, 2 = Safest - let setNoScriptSafetyLevel = safetyLevel => - sendNoScriptSettings(noscriptSettings(safetyLevel)); + let sendNoScriptSettings = async settings => + await sendExtensionMessage(noscriptID, settings); // __securitySliderToSafetyLevel(sliderState)__. // Converts the "browser.security_level.security_slider" pref value @@ -206,36 +189,46 @@ var initializeNoScriptControl = () => { // Wait for the first message from NoScript to arrive, and then // bind the security_slider pref to the NoScript settings. - let messageListener = a => { + let messageListener = async a => { try { logger.debug("Message received from NoScript:", a); - let noscriptPersist = Services.prefs.getBoolPref( - "browser.security_level.noscript_persist", - false - ); + const persistPref = "browser.security_level.noscript_persist"; + let noscriptPersist = Services.prefs.getBoolPref(persistPref, false); let noscriptInited = Services.prefs.getBoolPref( - "browser.security_level.noscript_inited", + kNoScriptInitedPref, false ); - // Set the noscript safety level once if we have never run noscript - // before, or if we are not allowing noscript per-site settings to be - // persisted between browser sessions. Otherwise make sure that the - // security slider position, if changed, will rewrite the noscript - // settings. - bindPref( - kSliderPref, - sliderState => - setNoScriptSafetyLevel(securitySliderToSafetyLevel(sliderState)), - !noscriptPersist || !noscriptInited - ); - if (!noscriptInited) { - Services.prefs.setBoolPref( - "browser.security_level.noscript_inited", - true + // Set the noscript safety level once at startup. + // If a user has set noscriptPersist, then we only send this if the + // security level was changed in a previous session. + // NOTE: We do not re-send this when the security_slider preference + // changes mid-session because this should always require a restart. + if (noscriptPersist && noscriptInited) { + logger.warn( + `Not initialising NoScript since the user has set ${persistPref}` ); + return; } + // Read the security level, even if the user has the "custom" + // preference. + const securityIndex = Services.prefs.getIntPref(kSliderPref, 0); + const safetyLevel = securitySliderToSafetyLevel(securityIndex); + // May throw if NoScript fails to apply the settings: + const noscriptResult = await sendNoScriptSettings( + noscriptSettings(safetyLevel) + ); + // Mark the NoScript extension as initialised so we do not reset it + // at the next startup for noscript_persist users. + Services.prefs.setBoolPref(kNoScriptInitedPref, true); + logger.info("NoScript successfully initialised."); + // In the future NoScript may tell us more about how it applied our + // settings, e.g. if user is overriding per-site permissions. + // Up to NoScript 12.6 noscriptResult is undefined. + logger.debug("NoScript response:", noscriptResult); } catch (e) { - logger.exception(e); + logger.error("Could not apply NoScript settings", e); + // Treat as a custom security level for the rest of the session. + Services.prefs.setBoolPref(kCustomPref, true); } }; waitForExtensionMessage(noscriptID, a => a.__meta.name === "started").then( @@ -244,6 +237,8 @@ var initializeNoScriptControl = () => { logger.info("Listening for messages from NoScript."); } catch (e) { logger.exception(e); + // Treat as a custom security level for the rest of the session. + Services.prefs.setBoolPref(kCustomPref, true); } }; @@ -274,16 +269,60 @@ const kSecuritySettings = { // ### Prefs +/** + * Amend the security level index to a standard value. + * + * @param {integer} index - The input index value. + * @returns {integer} - A standard index value. + */ +function fixupIndex(index) { + if (!Number.isInteger(index) || index < 1 || index > 4) { + // Unexpected value out of range, go to the "safest" level as a fallback. + return 1; + } + if (index === 3) { + // Migrate from old medium-low (3) to new medium (2). + return 2; + } + return index; +} + +/** + * A list of preference observers that should be disabled whilst we write our + * preference values. + * + * @type {{ prefName: string, observer: object }[]} + */ +const prefObservers = []; + // __write_setting_to_prefs(settingIndex)__. // Take a given setting index and write the appropriate pref values // to the pref database. var write_setting_to_prefs = function (settingIndex) { - Object.keys(kSecuritySettings).forEach(prefName => - Services.prefs.setBoolPref( - prefName, - kSecuritySettings[prefName][settingIndex] - ) - ); + settingIndex = fixupIndex(settingIndex); + // Don't want to trigger our internal observers when setting ourselves. + for (const { prefName, observer } of prefObservers) { + Services.prefs.removeObserver(prefName, observer); + } + try { + // Make sure noscript is re-initialised at the next startup when the + // security level changes. + Services.prefs.setBoolPref(kNoScriptInitedPref, false); + Services.prefs.setIntPref(kSliderPref, settingIndex); + // NOTE: We do not clear kCustomPref. Instead, we rely on the preference + // being cleared on the next startup. + Object.keys(kSecuritySettings).forEach(prefName => + Services.prefs.setBoolPref( + prefName, + kSecuritySettings[prefName][settingIndex] + ) + ); + } finally { + // Re-add the observers. + for (const { prefName, observer } of prefObservers) { + Services.prefs.addObserver(prefName, observer); + } + } }; // __read_setting_from_prefs()__. @@ -312,24 +351,6 @@ var read_setting_from_prefs = function (prefNames) { return null; }; -// __watch_security_prefs(onSettingChanged)__. -// Whenever a pref bound to the security slider changes, onSettingChanged -// is called with the new security setting value (1,2,3,4 or null). -// Returns a zero-arg function that ends this binding. -var watch_security_prefs = function (onSettingChanged) { - let prefNames = Object.keys(kSecuritySettings); - let unbindFuncs = []; - for (let prefName of prefNames) { - unbindFuncs.push( - bindPrefAndInit(prefName, () => - onSettingChanged(read_setting_from_prefs()) - ) - ); - } - // Call all the unbind functions. - return () => unbindFuncs.forEach(unbind => unbind()); -}; - // __initialized__. // Have we called initialize() yet? var initializedSecPrefs = false; @@ -345,36 +366,82 @@ var initializeSecurityPrefs = function () { } logger.info("Initializing security-prefs.js"); initializedSecPrefs = true; - // When security_custom is set to false, apply security_slider setting - // to the security-sensitive prefs. - bindPrefAndInit(kCustomPref, function (custom) { - if (custom === false) { - write_setting_to_prefs(Services.prefs.getIntPref(kSliderPref)); - } - }); - // If security_slider is given a new value, then security_custom should - // be set to false. - bindPref(kSliderPref, function (prefIndex) { + + const wasCustom = Services.prefs.getBoolPref(kCustomPref, false); + // For new profiles with no user preference, the security level should be "4" + // and it should not be custom. + let desiredIndex = Services.prefs.getIntPref(kSliderPref, 4); + desiredIndex = fixupIndex(desiredIndex); + // Make sure the user has a set preference user value. + Services.prefs.setIntPref(kSliderPref, desiredIndex); + Services.prefs.setBoolPref(kCustomPref, wasCustom); + + // Make sure that the preference values at application startup match the + // expected values for the desired security level. See tor-browser#43783. + + // NOTE: We assume that the controlled preference values that are read prior + // to profile-after-change do not change in value before this method is + // called. I.e. we expect the current preference values to match the + // preference values that were used during the application initialisation. + const effectiveIndex = read_setting_from_prefs(); + + if (wasCustom && effectiveIndex !== null) { + logger.info(`Custom startup values match index ${effectiveIndex}`); + // Do not consider custom any more. + // NOTE: This level needs to be set before it is read elsewhere. In + // particular, for the NoScript addon. Services.prefs.setBoolPref(kCustomPref, false); - write_setting_to_prefs(prefIndex); + Services.prefs.setIntPref(kSliderPref, effectiveIndex); + } else if (!wasCustom && effectiveIndex !== desiredIndex) { + // NOTE: We assume all our controlled preferences require a restart. + // In practice, only a subset of these preferences may actually require a + // restart, so we could switch their values. But we treat them all the same + // for simplicity, consistency and stability in case mozilla changes the + // restart requirements. + logger.info(`Startup values do not match for index ${desiredIndex}`); + SecurityLevelPrefs.requireRestart(); + } + + // Start listening for external changes to the controlled preferences. + prefObservers.push({ + prefName: kCustomPref, + observer: bindPref(kCustomPref, custom => { + // Custom flag was removed mid-session. Requires a restart to apply the + // security level. + if (custom === false) { + logger.info("Custom flag was cleared externally"); + SecurityLevelPrefs.requireRestart(); + } + }), }); - // If a security-sensitive pref changes, then decide if the set of pref values - // constitutes a security_slider setting or a custom value. - watch_security_prefs(settingIndex => { - if (settingIndex === null) { - Services.prefs.setBoolPref(kCustomPref, true); - } else { - Services.prefs.setIntPref(kSliderPref, settingIndex); - Services.prefs.setBoolPref(kCustomPref, false); - } + prefObservers.push({ + prefName: kSliderPref, + observer: bindPref(kSliderPref, () => { + // Security level was changed mid-session. Requires a restart to apply. + logger.info("Security level was changed externally"); + SecurityLevelPrefs.requireRestart(); + }), }); - // Migrate from old medium-low (3) to new medium (2). - if ( - Services.prefs.getBoolPref(kCustomPref) === false && - Services.prefs.getIntPref(kSliderPref) === 3 - ) { - Services.prefs.setIntPref(kSliderPref, 2); - write_setting_to_prefs(2); + + for (const prefName of Object.keys(kSecuritySettings)) { + prefObservers.push({ + prefName, + observer: bindPref(prefName, () => { + logger.warn( + `The controlled preference ${prefName} was changed externally.` + + " Treating as a custom security level." + ); + // Something outside of this module changed the preference value for a + // preference we control. + // Always treat as a custom security level for the rest of this session, + // even if the new preference values match a pre-set security level. We + // do this because some controlled preferences require a restart to be + // properly applied. See tor-browser#43783. + // In the case where it does match a pre-set security level, the custom + // flag will be cleared at the next startup. + Services.prefs.setBoolPref(kCustomPref, true); + }), + }); } logger.info("security-prefs.js initialization complete"); @@ -426,8 +493,9 @@ export class SecurityLevel { init() { migratePreferences(); - initializeNoScriptControl(); + // Fixup our preferences before we pass on the security level to NoScript. initializeSecurityPrefs(); + initializeNoScriptControl(); } observe(aSubject, aTopic, aData) { @@ -437,10 +505,19 @@ export class SecurityLevel { } } +/** + * @typedef {object} SecurityLevelRestartNotificationHandler + * + * An object that can serve the user a restart notification. + * + * @property {Function} tryRestartBrowser - The method that should be called to + * ask the user to restart the browser. + */ + /* Security Level Prefs - Getters and Setters for relevant torbutton prefs + Getters and Setters for relevant security level prefs */ export const SecurityLevelPrefs = { SecurityLevels: Object.freeze({ @@ -451,6 +528,14 @@ export const SecurityLevelPrefs = { security_slider_pref: "browser.security_level.security_slider", security_custom_pref: "browser.security_level.security_custom", + /** + * The current security level preference. + * + * This ignores any custom settings the user may have changed, and just + * gives the underlying security level. + * + * @type {?string} + */ get securityLevel() { // Set the default return value to 0, which won't match anything in // SecurityLevels. @@ -460,18 +545,147 @@ export const SecurityLevelPrefs = { )?.[0]; }, - set securityLevel(level) { - const val = this.SecurityLevels[level]; - if (val !== undefined) { - Services.prefs.setIntPref(this.security_slider_pref, val); - } + /** + * Set the desired security level just before a restart. + * + * The caller must restart the browser after calling this method. + * + * @param {string} level - The name of the new security level to set. + */ + setSecurityLevelBeforeRestart(level) { + write_setting_to_prefs(this.SecurityLevels[level]); }, + /** + * Whether the user has any custom setting values that do not match a pre-set + * security level. + * + * @type {boolean} + */ get securityCustom() { return Services.prefs.getBoolPref(this.security_custom_pref); }, - set securityCustom(val) { - Services.prefs.setBoolPref(this.security_custom_pref, val); + /** + * A summary of the current security level. + * + * If the user has some custom settings, this returns "custom". Otherwise + * returns the name of the security level. + * + * @type {string} + */ + get securityLevelSummary() { + if (this.securityCustom) { + return "custom"; + } + return this.securityLevel ?? "custom"; + }, + + /** + * Whether the browser should be restarted to apply the security level. + * + * @type {boolean} + */ + _needRestart: false, + + /** + * The external handler that can show a notification to the user, if any. + * + * @type {?SecurityLevelRestartNotificationHandler} + */ + _restartNotificationHandler: null, + + /** + * Set the external handler for showing notifications to the user. + * + * This should only be called once per session once the handler is ready to + * show a notification, which may occur immediately during this call. + * + * @param {SecurityLevelRestartNotificationHandler} handler - The new handler + * to use. + */ + setRestartNotificationHandler(handler) { + logger.info("Restart notification handler is set"); + this._restartNotificationHandler = handler; + if (this._needRestart) { + // Show now using the new handler. + this._tryShowRestartNotification(); + } + }, + + /** + * A promise for any ongoing notification prompt task. + * + * @type {Promise} + */ + _restartNotificationPromise: null, + + /** + * Try show a notification to the user. + * + * If no notification handler has been attached yet, this will do nothing. + */ + async _tryShowRestartNotification() { + if (!this._restartNotificationHandler) { + logger.info("Missing a restart notification handler"); + // This may be added later in the session. + return; + } + + const prevPromise = this._restartNotificationPromise; + let resolve; + this._restartNotificationPromise = new Promise(r => { + resolve = r; + }); + await prevPromise; + + try { + await this._restartNotificationHandler?.tryRestartBrowser(); + } finally { + // Allow the notification to be shown again. + resolve(); + } + }, + + /** + * Mark the session as requiring a restart to apply a change in security + * level. + * + * The security level will immediately be switched to "custom", and the user + * may be shown a notification to restart the browser. + */ + requireRestart() { + logger.warn("The browser needs to be restarted to set the security level"); + // Treat as a custom security level for the rest of the session. + // At the next startup, the custom flag may be cleared if the settings are + // as expected. + Services.prefs.setBoolPref(kCustomPref, true); + this._needRestart = true; + + // NOTE: We need to change the controlled security level preferences in + // response to the desired change in security level. We could either: + // 1. Only change the controlled preferences after the user confirms a + // restart. Or + // 2. Change the controlled preferences and then try and ask the user to + // restart. + // + // We choose the latter: + // 1. To allow users to manually restart. + // 2. If the user ignores or misses the notification, they will at least be + // in the correct state when the browser starts again. Although they will + // be in a custom/undefined state in the mean time. + // 3. Currently Android relies on triggering the change in security level + // by setting the browser.security_level.security_slider preference + // value. So it currently uses this path. So we need to set the values + // now, before it preforms a restart. + // TODO: Have android use the `setSecurityLevelBeforeRestart` method + // instead of setting the security_slider preference value directly, so that + // it knows exactly when it can restart the browser. tor-browser#43820 + write_setting_to_prefs(Services.prefs.getIntPref(kSliderPref, 0)); + // NOTE: Even though we have written the preferences, the session should + // still be marked as "custom" because: + // 1. Some preferences require a browser restart to be applied. + // 2. NoScript has not been updated with the new settings. + this._tryShowRestartNotification(); }, }; /* Security Level Prefs */ ===================================== toolkit/locales/en-US/toolkit/global/base-browser.ftl ===================================== @@ -118,10 +118,6 @@ security-level-toolbar-button-custom = # Uses sentence case in English (US). security-level-panel-heading = Security level - -security-level-panel-level-standard = Standard -security-level-panel-level-safer = Safer -security-level-panel-level-safest = Safest security-level-panel-learn-more-link = Learn more # Button to open security level settings. security-level-panel-open-settings-button = Settings… @@ -131,6 +127,19 @@ security-level-panel-open-settings-button = Settings… security-level-preferences-heading = Security Level security-level-preferences-overview = Disable certain web features that can be used to attack your security and anonymity. security-level-preferences-learn-more-link = Learn more +# Text for a badge that labels the currently active security level. +# The text in between '<span>' and '</span>' should contain some kind of bracket, like '(' and ')', or other punctuation used in your language to separate out text from its surrounding context. This will not be visible, but will be use for screen readers to make it clear that the text is not part of the same sentence. For example, in US English this would be read as "(Current level)", and the full line of text would be read as "Safest (Current level)". +security-level-preferences-current-badge = <span>(</span>Current level<span>)</span> +security-level-preferences-change-button = Change… + +## Security level settings dialog. + +security-level-dialog-window = + .title = Change security level + +# '-brand-short-name' is the localized browser name, like "Tor Browser". +security-level-dialog-restart-description = You will need to restart { -brand-short-name } to apply any changes. This will close all windows and tabs. + security-level-preferences-level-standard = .label = Standard security-level-preferences-level-safer = @@ -138,6 +147,16 @@ security-level-preferences-level-safer = security-level-preferences-level-safest = .label = Safest +security-level-dialog-save-restart = + .label = Save and restart + +## Security level names shown in the security panel and settings. + +security-level-panel-level-standard = Standard +security-level-panel-level-safer = Safer +security-level-panel-level-safest = Safest +security-level-panel-level-custom = Custom + ## Security level summaries shown in security panel and settings. security-level-summary-standard = All browser and website features are enabled. @@ -156,16 +175,16 @@ security-level-preferences-bullet-limit-font-and-symbols-and-images = Some fonts ## Custom security level. ## Some custom preferences configuration has placed the user outside one of the standard three levels. -# Shown in the security level panel as an orange badge next to the expected level. -security-level-panel-custom-badge = Custom -# Shown in the security level settings in a warning box. -security-level-preferences-custom-heading = Custom security level configured # Description of custom state and recommended action. # Shown in the security level panel and settings. security-level-summary-custom = Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels. -# Button to undo custom changes to the security level and place the user in one of the standard security levels. -# Shown in the security level panel and settings. -security-level-restore-defaults-button = Restore defaults + +## Security level restart prompt. + +security-level-restart-prompt-title = Your security level settings require a restart +security-level-restart-prompt-body = You must restart { -brand-short-name } for your security level settings to be applied. This will close all your windows and tabs. +security-level-restart-prompt-button-restart = Restart +security-level-restart-prompt-button-ignore = Ignore ## Notification for dropped operating system support. View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/d3e4ff… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/d3e4ff… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-140.0a1-15.0-1] 3 commits: fixup! Tweaks to the build system
by brizental (@brizental) 12 Jun '25

12 Jun '25
brizental pushed to branch tor-browser-140.0a1-15.0-1 at The Tor Project / Applications / Tor Browser Commits: fadec010 by Beatriz Rizental at 2025-06-12T17:31:27+02:00 fixup! Tweaks to the build system Make it possible to provide MOZ_PKG_MAC_DSSTORE, MOZ_PKG_MAC_BACKGROUND, MOZ_PKG_MAC_ICON as environment variables. These files are not where the build system expects it. In our build system these files are in tor-browser-build/projects/browser/Bundle-Data/BaseBrowser.dmg while the build system expects it to be in browser/branding/tb-*. For ./mach package to work properly when building for macos we need these locations. Passing them as env vars is fine for building artifacts in tbb. - - - - - d1bcbcb1 by Beatriz Rizental at 2025-06-12T17:31:27+02:00 fixup! Tweaks to the build system Disable inclusion of browser/installer/windows into packaged development artifacts. That file is not included by our builds -- at least not by the ones done by tor-browser-build. Attempting to zip the unexisting folder will crash `./mach package` when building inside tor-browser-build. - - - - - 315fd439 by Beatriz Rizental at 2025-06-12T17:31:28+02:00 BB 43843: Do not bootstrap MacOS packaging tools if available Do not bootstrap MacOS packing tools if they are already available in the environment. This can be uplifted. - - - - - 3 changed files: - python/mozbuild/mozbuild/action/make_dmg.py - toolkit/mozapps/installer/packager.mk - toolkit/mozapps/installer/upload-files.mk Changes: ===================================== python/mozbuild/mozbuild/action/make_dmg.py ===================================== @@ -7,6 +7,7 @@ import platform import sys from pathlib import Path +import buildconfig from mozpack import dmg from mozbuild.bootstrap import bootstrap_toolchain @@ -46,9 +47,11 @@ def main(args): ) # Resolve required tools - dmg_tool = bootstrap_toolchain("dmg/dmg") - hfs_tool = bootstrap_toolchain("dmg/hfsplus") - mkfshfs_tool = bootstrap_toolchain("hfsplus/newfs_hfs") + dmg_tool = buildconfig.substs.get("DMG_TOOL") or bootstrap_toolchain("dmg/dmg") + hfs_tool = buildconfig.substs.get("HFS_TOOL") or bootstrap_toolchain("dmg/hfsplus") + mkfshfs_tool = buildconfig.substs.get("MKFSHFS") or bootstrap_toolchain( + "hfsplus/newfs_hfs" + ) dmg.create_dmg( source_directory=Path(options.inpath), ===================================== toolkit/mozapps/installer/packager.mk ===================================== @@ -135,7 +135,7 @@ make-package: FORCE $(MAKE) make-package-internal ifeq (WINNT,$(OS_ARCH)) ifeq ($(MOZ_PKG_FORMAT),ZIP) - $(MAKE) -C windows ZIP_IN='$(ABS_DIST)/$(PACKAGE)' installer +# $(MAKE) -C windows ZIP_IN='$(ABS_DIST)/$(PACKAGE)' installer endif endif ifdef MOZ_AUTOMATION ===================================== toolkit/mozapps/installer/upload-files.mk ===================================== @@ -205,9 +205,9 @@ ifeq ($(MOZ_PKG_FORMAT),DMG) _ABS_MOZSRCDIR = $(shell cd $(MOZILLA_DIR) && pwd) PKG_DMG_SOURCE = $(MOZ_PKG_DIR) - MOZ_PKG_MAC_DSSTORE=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/dsstore - MOZ_PKG_MAC_BACKGROUND=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/background.png - MOZ_PKG_MAC_ICON=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/disk.icns + MOZ_PKG_MAC_DSSTORE?=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/dsstore + MOZ_PKG_MAC_BACKGROUND?=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/background.png + MOZ_PKG_MAC_ICON?=$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/disk.icns INNER_MAKE_PACKAGE = \ $(call py_action,make_dmg, \ $(if $(MOZ_PKG_MAC_DSSTORE),--dsstore '$(MOZ_PKG_MAC_DSSTORE)') \ View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/759ac0… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/759ac0… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.