[tbb-commits] [Git][tpo/applications/tor-browser][tor-browser-115.10.0esr-13.5-1] 4 commits: fixup! Bug 40458: Implement .tor.onion aliases
richard (@richard)
git at gitlab.torproject.org
Tue Apr 16 22:20:08 UTC 2024
richard pushed to branch tor-browser-115.10.0esr-13.5-1 at The Tor Project / Applications / Tor Browser
Commits:
5fd3baa6 by Henry Wilkes at 2024-04-16T21:57:16+00:00
fixup! Bug 40458: Implement .tor.onion aliases
Bug 42206: Migrate ruleset strings to Fluent.
- - - - -
7b790cf6 by Henry Wilkes at 2024-04-16T21:57:16+00:00
fixup! Tor Browser strings
Bug 42206: Migrate ruleset strings to Fluent.
- - - - -
caed3ae7 by Henry Wilkes at 2024-04-16T21:57:16+00:00
fixup! Add TorStrings module for localization
Bug 42206: Migrate ruleset strings to Fluent.
- - - - -
8c14330e by Henry Wilkes at 2024-04-16T21:57:16+00:00
fixup! Tor Browser localization migration scripts.
Bug 42206: Migrate ruleset strings to Fluent.
- - - - -
7 changed files:
- browser/components/rulesets/RulesetsParent.sys.mjs
- browser/components/rulesets/content/aboutRulesets.html
- browser/components/rulesets/content/aboutRulesets.js
- browser/locales/en-US/browser/tor-browser.ftl
- toolkit/modules/TorStrings.sys.mjs
- − toolkit/torbutton/chrome/locale/en-US/rulesets.properties
- + tools/torbrowser/l10n/migrations/bug-42206-rulesets.py
Changes:
=====================================
browser/components/rulesets/RulesetsParent.sys.mjs
=====================================
@@ -1,6 +1,5 @@
// Copyright (c) 2022, The Tor Project, Inc.
-import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
import {
OnionAliasStore,
OnionAliasStoreTopics,
@@ -8,8 +7,8 @@ import {
const kShowWarningPref = "torbrowser.rulesets.show_warning";
-// This class allows about:rulesets to get TorStrings and to load/save the
-// preference for skipping the warning
+// This class allows about:rulesets to load/save the preference for skipping the
+// warning
export class RulesetsParent extends JSWindowActorParent {
constructor(...args) {
super(...args);
@@ -53,7 +52,6 @@ export class RulesetsParent extends JSWindowActorParent {
return OnionAliasStore.getChannels();
case "rulesets:get-init-args":
return {
- TorStrings,
showWarning: Services.prefs.getBoolPref(kShowWarningPref, true),
};
case "rulesets:set-channel":
=====================================
browser/components/rulesets/content/aboutRulesets.html
=====================================
@@ -11,13 +11,19 @@
rel="stylesheet"
href="chrome://browser/content/rulesets/aboutRulesets.css"
/>
+
+ <link rel="localization" href="branding/brand.ftl" />
+ <link rel="localization" href="browser/tor-browser.ftl" />
</head>
<body>
<!-- Warning -->
<div id="warning-wrapper">
<div id="warning">
- <h1 id="warning-title"></h1>
- <p id="warning-description"></p>
+ <h1 id="warning-title" data-l10n-id="rulesets-warning-heading"></h1>
+ <p
+ id="warning-description"
+ data-l10n-id="rulesets-warning-description"
+ ></p>
<p>
<label>
<input
@@ -25,11 +31,18 @@
type="checkbox"
checked="checked"
/>
- <span id="warning-enable-label"></span>
+ <span
+ id="warning-enable-label"
+ data-l10n-id="rulesets-warning-checkbox"
+ ></span>
</label>
</p>
<div id="warning-buttonbar">
- <button id="warning-button" autofocus="autofocus"></button>
+ <button
+ id="warning-button"
+ autofocus="autofocus"
+ data-l10n-id="rulesets-warning-continue-button"
+ ></button>
</div>
</div>
</div>
@@ -37,11 +50,20 @@
<div id="main-content">
<!-- Ruleset list -->
<aside>
- <div id="ruleset-heading"></div>
+ <div
+ id="ruleset-heading"
+ data-l10n-id="rulesets-side-panel-heading"
+ ></div>
<div id="ruleset-list-container">
<div id="ruleset-list-empty">
- <p id="ruleset-list-empty-title"></p>
- <p id="ruleset-list-empty-description"></p>
+ <p
+ id="ruleset-list-empty-title"
+ data-l10n-id="rulesets-side-panel-no-rules"
+ ></p>
+ <p
+ id="ruleset-list-empty-description"
+ data-l10n-id="rulesets-side-panel-no-rules-description"
+ ></p>
</div>
<ul id="ruleset-list">
<li id="ruleset-template">
@@ -59,24 +81,40 @@
<section id="ruleset-details">
<div class="title">
<h1 id="ruleset-title"></h1>
- <button id="ruleset-edit" class="ghost-button"></button>
+ <button
+ id="ruleset-edit"
+ class="ghost-button"
+ data-l10n-id="rulesets-details-edit-button"
+ ></button>
</div>
<dl>
- <dt id="ruleset-jwk-label"></dt>
+ <dt id="ruleset-jwk-label" data-l10n-id="rulesets-details-jwk"></dt>
<dd id="ruleset-jwk-value"></dd>
- <dt id="ruleset-path-prefix-label"></dt>
+ <dt
+ id="ruleset-path-prefix-label"
+ data-l10n-id="rulesets-details-path"
+ ></dt>
<dd>
<a id="ruleset-path-prefix-value" target="_blank"></a>
</dd>
- <dt id="ruleset-scope-label"></dt>
+ <dt
+ id="ruleset-scope-label"
+ data-l10n-id="rulesets-details-scope"
+ ></dt>
<dd id="ruleset-scope-value"></dd>
</dl>
<label id="ruleset-enable">
<input type="checkbox" id="ruleset-enable-checkbox" />
- <span id="ruleset-enable-label"></span>
+ <span
+ id="ruleset-enable-label"
+ data-l10n-id="rulesets-details-enable-checkbox"
+ ></span>
</label>
<div id="ruleset-buttonbar">
- <button id="ruleset-update-button"></button>
+ <button
+ id="ruleset-update-button"
+ data-l10n-id="rulesets-details-update-button"
+ ></button>
</div>
<hr />
<p id="ruleset-updated"></p>
@@ -89,24 +127,52 @@
</div>
<form id="edit-ruleset-form">
<label>
- <div id="edit-jwk-label"></div>
- <textarea id="edit-jwk-textarea" rows="10"></textarea>
+ <div id="edit-jwk-label" data-l10n-id="rulesets-details-jwk"></div>
+ <textarea
+ id="edit-jwk-textarea"
+ rows="10"
+ data-l10n-id="rulesets-details-jwk-input"
+ ></textarea>
</label>
<label>
- <div id="edit-path-prefix-label"></div>
- <input id="edit-path-prefix-input" type="text" />
+ <div
+ id="edit-path-prefix-label"
+ data-l10n-id="rulesets-details-path"
+ ></div>
+ <input
+ id="edit-path-prefix-input"
+ type="text"
+ data-l10n-id="rulesets-details-path-input"
+ />
</label>
<label>
- <div id="edit-scope-label"></div>
- <input id="edit-scope-input" type="text" />
+ <div
+ id="edit-scope-label"
+ data-l10n-id="rulesets-details-scope"
+ ></div>
+ <input
+ id="edit-scope-input"
+ type="text"
+ data-l10n-id="rulesets-details-scope-input"
+ />
</label>
<label id="edit-enable">
<input type="checkbox" id="edit-enable-checkbox" />
- <span id="edit-enable-label"></span>
+ <span
+ id="edit-enable-label"
+ data-l10n-id="rulesets-details-enable-checkbox"
+ ></span>
</label>
<div id="edit-buttonbar">
- <button id="edit-save" class="primary"></button>
- <button id="edit-cancel"></button>
+ <button
+ id="edit-save"
+ class="primary"
+ data-l10n-id="rulesets-details-save-button"
+ ></button>
+ <button
+ id="edit-cancel"
+ data-l10n-id="rulesets-details-cancel-button"
+ ></button>
</div>
</form>
</section>
=====================================
browser/components/rulesets/content/aboutRulesets.js
=====================================
@@ -2,8 +2,6 @@
/* globals RPMAddMessageListener, RPMSendQuery, RPMSendAsyncMessage */
-let TorStrings;
-
const Orders = Object.freeze({
Name: "name",
NameDesc: "name-desc",
@@ -19,55 +17,35 @@ const States = Object.freeze({
function setUpdateDate(ruleset, element) {
if (!ruleset.enabled) {
- element.textContent = TorStrings.rulesets.disabled;
+ document.l10n.setAttributes(element, "rulesets-update-rule-disabled");
return;
}
if (!ruleset.currentTimestamp) {
- element.textContent = TorStrings.rulesets.neverUpdated;
+ document.l10n.setAttributes(element, "rulesets-update-never");
return;
}
- const formatter = new Intl.DateTimeFormat(navigator.languages, {
- year: "numeric",
- month: "long",
- day: "numeric",
+ document.l10n.setAttributes(element, "rulesets-update-last", {
+ date: ruleset.currentTimestamp * 1000,
});
- element.textContent = TorStrings.rulesets.lastUpdated.replace(
- "%S",
- formatter.format(new Date(ruleset.currentTimestamp * 1000))
- );
}
class WarningState {
- selectors = Object.freeze({
- wrapper: "#warning-wrapper",
- title: "#warning-title",
- description: "#warning-description",
- enableCheckbox: "#warning-enable-checkbox",
- enableLabel: "#warning-enable-label",
- button: "#warning-button",
- });
-
- elements = Object.freeze({
- wrapper: document.querySelector(this.selectors.wrapper),
- title: document.querySelector(this.selectors.title),
- description: document.querySelector(this.selectors.description),
- enableCheckbox: document.querySelector(this.selectors.enableCheckbox),
- enableLabel: document.querySelector(this.selectors.enableLabel),
- button: document.querySelector(this.selectors.button),
- });
+ elements = {
+ enableCheckbox: document.getElementById("warning-enable-checkbox"),
+ button: document.getElementById("warning-button"),
+ };
constructor() {
- const elements = this.elements;
- elements.title.textContent = TorStrings.rulesets.warningTitle;
- elements.description.textContent = TorStrings.rulesets.warningDescription;
- elements.enableLabel.textContent = TorStrings.rulesets.warningEnable;
- elements.button.textContent = TorStrings.rulesets.warningButton;
- elements.enableCheckbox.addEventListener(
+ this.elements.enableCheckbox.addEventListener(
"change",
this.onEnableChange.bind(this)
);
- elements.button.addEventListener("click", this.onButtonClick.bind(this));
+
+ this.elements.button.addEventListener(
+ "click",
+ this.onButtonClick.bind(this)
+ );
}
show() {
@@ -89,50 +67,28 @@ class WarningState {
}
class DetailsState {
- selectors = Object.freeze({
- title: "#ruleset-title",
- edit: "#ruleset-edit",
- jwkLabel: "#ruleset-jwk-label",
- jwkValue: "#ruleset-jwk-value",
- pathPrefixLabel: "#ruleset-path-prefix-label",
- pathPrefixValue: "#ruleset-path-prefix-value",
- scopeLabel: "#ruleset-scope-label",
- scopeValue: "#ruleset-scope-value",
- enableCheckbox: "#ruleset-enable-checkbox",
- enableLabel: "#ruleset-enable-label",
- updateButton: "#ruleset-update-button",
- updated: "#ruleset-updated",
- });
-
- elements = Object.freeze({
- title: document.querySelector(this.selectors.title),
- edit: document.querySelector(this.selectors.edit),
- jwkLabel: document.querySelector(this.selectors.jwkLabel),
- jwkValue: document.querySelector(this.selectors.jwkValue),
- pathPrefixLabel: document.querySelector(this.selectors.pathPrefixLabel),
- pathPrefixValue: document.querySelector(this.selectors.pathPrefixValue),
- scopeLabel: document.querySelector(this.selectors.scopeLabel),
- scopeValue: document.querySelector(this.selectors.scopeValue),
- enableCheckbox: document.querySelector(this.selectors.enableCheckbox),
- enableLabel: document.querySelector(this.selectors.enableLabel),
- updateButton: document.querySelector(this.selectors.updateButton),
- updated: document.querySelector(this.selectors.updated),
- });
+ elements = {
+ title: document.getElementById("ruleset-title"),
+ jwkValue: document.getElementById("ruleset-jwk-value"),
+ pathPrefixValue: document.getElementById("ruleset-path-prefix-value"),
+ scopeValue: document.getElementById("ruleset-scope-value"),
+ enableCheckbox: document.getElementById("ruleset-enable-checkbox"),
+ updateButton: document.getElementById("ruleset-update-button"),
+ updated: document.getElementById("ruleset-updated"),
+ };
constructor() {
- const elements = this.elements;
- elements.edit.textContent = TorStrings.rulesets.edit;
- elements.edit.addEventListener("click", this.onEdit.bind(this));
- elements.jwkLabel.textContent = TorStrings.rulesets.jwk;
- elements.pathPrefixLabel.textContent = TorStrings.rulesets.pathPrefix;
- elements.scopeLabel.textContent = TorStrings.rulesets.scope;
- elements.enableCheckbox.addEventListener(
+ document
+ .getElementById("ruleset-edit")
+ .addEventListener("click", this.onEdit.bind(this));
+ this.elements.enableCheckbox.addEventListener(
"change",
this.onEnable.bind(this)
);
- elements.enableLabel.textContent = TorStrings.rulesets.enable;
- elements.updateButton.textContent = TorStrings.rulesets.checkUpdates;
- elements.updateButton.addEventListener("click", this.onUpdate.bind(this));
+ this.elements.updateButton.addEventListener(
+ "click",
+ this.onUpdate.bind(this)
+ );
}
show(ruleset) {
@@ -179,61 +135,22 @@ class DetailsState {
}
class EditState {
- selectors = Object.freeze({
- form: "#edit-ruleset-form",
- title: "#edit-title",
- nameGroup: "#edit-name-group",
- nameLabel: "#edit-name-label",
- nameInput: "#edit-name-input",
- jwkLabel: "#edit-jwk-label",
- jwkTextarea: "#edit-jwk-textarea",
- pathPrefixLabel: "#edit-path-prefix-label",
- pathPrefixInput: "#edit-path-prefix-input",
- scopeLabel: "#edit-scope-label",
- scopeInput: "#edit-scope-input",
- enableCheckbox: "#edit-enable-checkbox",
- enableLabel: "#edit-enable-label",
- save: "#edit-save",
- cancel: "#edit-cancel",
- });
-
- elements = Object.freeze({
- form: document.querySelector(this.selectors.form),
- title: document.querySelector(this.selectors.title),
- jwkLabel: document.querySelector(this.selectors.jwkLabel),
- jwkTextarea: document.querySelector(this.selectors.jwkTextarea),
- pathPrefixLabel: document.querySelector(this.selectors.pathPrefixLabel),
- pathPrefixInput: document.querySelector(this.selectors.pathPrefixInput),
- scopeLabel: document.querySelector(this.selectors.scopeLabel),
- scopeInput: document.querySelector(this.selectors.scopeInput),
- enableCheckbox: document.querySelector(this.selectors.enableCheckbox),
- enableLabel: document.querySelector(this.selectors.enableLabel),
- save: document.querySelector(this.selectors.save),
- cancel: document.querySelector(this.selectors.cancel),
- });
+ elements = {
+ form: document.getElementById("edit-ruleset-form"),
+ title: document.getElementById("edit-title"),
+ jwkTextarea: document.getElementById("edit-jwk-textarea"),
+ pathPrefixInput: document.getElementById("edit-path-prefix-input"),
+ scopeInput: document.getElementById("edit-scope-input"),
+ enableCheckbox: document.getElementById("edit-enable-checkbox"),
+ };
constructor() {
- const elements = this.elements;
- elements.jwkLabel.textContent = TorStrings.rulesets.jwk;
- elements.jwkTextarea.setAttribute(
- "placeholder",
- TorStrings.rulesets.jwkPlaceholder
- );
- elements.pathPrefixLabel.textContent = TorStrings.rulesets.pathPrefix;
- elements.pathPrefixInput.setAttribute(
- "placeholder",
- TorStrings.rulesets.pathPrefixPlaceholder
- );
- elements.scopeLabel.textContent = TorStrings.rulesets.scope;
- elements.scopeInput.setAttribute(
- "placeholder",
- TorStrings.rulesets.scopePlaceholder
- );
- elements.enableLabel.textContent = TorStrings.rulesets.enable;
- elements.save.textContent = TorStrings.rulesets.save;
- elements.save.addEventListener("click", this.onSave.bind(this));
- elements.cancel.textContent = TorStrings.rulesets.cancel;
- elements.cancel.addEventListener("click", this.onCancel.bind(this));
+ document
+ .getElementById("edit-save")
+ .addEventListener("click", this.onSave.bind(this));
+ document
+ .getElementById("edit-cancel")
+ .addEventListener("click", this.onCancel.bind(this));
}
show(ruleset) {
@@ -276,7 +193,9 @@ class EditState {
elements.jwkTextarea.setCustomValidity("");
} catch (err) {
console.error("Invalid JSON or invalid JWK", err);
- elements.jwkTextarea.setCustomValidity(TorStrings.rulesets.jwkInvalid);
+ elements.jwkTextarea.setCustomValidity(
+ await document.l10n.formatValue("rulesets-details-jwk-input-invalid")
+ );
valid = false;
}
@@ -285,7 +204,7 @@ class EditState {
const url = new URL(pathPrefix);
if (url.protocol !== "http:" && url.protocol !== "https:") {
elements.pathPrefixInput.setCustomValidity(
- TorStrings.rulesets.pathPrefixInvalid
+ await document.l10n.formatValue("rulesets-details-path-input-invalid")
);
valid = false;
} else {
@@ -294,7 +213,7 @@ class EditState {
} catch (err) {
console.error("The path prefix is not a valid URL", err);
elements.pathPrefixInput.setCustomValidity(
- TorStrings.rulesets.pathPrefixInvalid
+ await document.l10n.formatValue("rulesets-details-path-input-invalid")
);
valid = false;
}
@@ -304,7 +223,9 @@ class EditState {
scope = new RegExp(elements.scopeInput.value.trim());
elements.scopeInput.setCustomValidity("");
} catch (err) {
- elements.scopeInput.setCustomValidity(TorStrings.rulesets.scopeInvalid);
+ elements.scopeInput.setCustomValidity(
+ await document.l10n.formatValue("rulesets-details-scope-input-invalid")
+ );
valid = false;
}
@@ -342,39 +263,17 @@ class NoRulesetsState {
}
class RulesetList {
- selectors = Object.freeze({
- heading: "#ruleset-heading",
- list: "#ruleset-list",
- emptyContainer: "#ruleset-list-empty",
- emptyTitle: "#ruleset-list-empty-title",
- emptyDescription: "#ruleset-list-empty-description",
- itemTemplate: "#ruleset-template",
- itemName: ".name",
- itemDescr: ".description",
- });
-
- elements = Object.freeze({
- heading: document.querySelector(this.selectors.heading),
- list: document.querySelector(this.selectors.list),
- emptyContainer: document.querySelector(this.selectors.emptyContainer),
- emptyTitle: document.querySelector(this.selectors.emptyTitle),
- emptyDescription: document.querySelector(this.selectors.emptyDescription),
- itemTemplate: document.querySelector(this.selectors.itemTemplate),
- });
+ elements = {
+ list: document.getElementById("ruleset-list"),
+ emptyContainer: document.getElementById("ruleset-list-empty"),
+ itemTemplate: document.getElementById("ruleset-template"),
+ };
nameAttribute = "data-name";
rulesets = [];
constructor() {
- const elements = this.elements;
-
- // Header
- elements.heading.textContent = TorStrings.rulesets.rulesets;
- // Empty
- elements.emptyTitle.textContent = TorStrings.rulesets.noRulesets;
- elements.emptyDescription.textContent = TorStrings.rulesets.noRulesetsDescr;
-
RPMAddMessageListener(
"rulesets:channels-change",
this.onRulesetsChanged.bind(this)
@@ -438,14 +337,10 @@ class RulesetList {
const item = this.elements.itemTemplate.cloneNode(true);
item.removeAttribute("id");
item.classList.add("item");
- item.querySelector(this.selectors.itemName).textContent = ruleset.name;
- const descr = item.querySelector(this.selectors.itemDescr);
- if (ruleset.enabled) {
- setUpdateDate(ruleset, descr);
- } else {
- descr.textContent = TorStrings.rulesets.disabled;
- item.classList.add("disabled");
- }
+ item.querySelector(".name").textContent = ruleset.name;
+ const descr = item.querySelector(".description");
+ setUpdateDate(ruleset, descr);
+ item.classList.toggle("disabled", !ruleset.enabled);
item.setAttribute(this.nameAttribute, ruleset.name);
item.addEventListener("click", () => {
this.onRulesetClick(ruleset);
@@ -478,7 +373,6 @@ class AboutRulesets {
async init() {
const args = await RPMSendQuery("rulesets:get-init-args");
- TorStrings = args.TorStrings;
const showWarning = args.showWarning;
this.list = new RulesetList();
=====================================
browser/locales/en-US/browser/tor-browser.ftl
=====================================
@@ -557,3 +557,53 @@ downloads-tor-warning-title = Be careful opening downloads
downloads-tor-warning-description = Some files may connect to the internet when opened without using Tor. To be safe, open the files while offline or use a portable operating system like <a data-l10n-name="tails-link">Tails</a>.
# Button to dismiss the warning forever.
downloads-tor-warning-dismiss-button = Got it
+
+## Initial warning page in about:rulesets. In Tor Browser, each ruleset is a set of rules for converting a ".tor.onion" address to a normal ".onion" address (used by SecureDrop). The feature is taken from the discontinued "HTTPS Everywhere".
+
+rulesets-warning-heading = Proceed with Caution
+rulesets-warning-description = Adding or modifying rulesets can cause attackers to hijack your browser. Proceed only if you know what you are doing.
+rulesets-warning-checkbox = Warn me when I attempt to access these preferences
+rulesets-warning-continue-button = Accept the Risk and Continue
+
+## Side panel in about:rulesets. In Tor Browser, each ruleset is a set of rules for converting a ".tor.onion" address to a normal ".onion" address (used by SecureDrop). The feature is taken from the discontinued "HTTPS Everywhere".
+
+rulesets-side-panel-heading = Rulesets
+rulesets-side-panel-no-rules = No rulesets found
+# -brand-short-name refers to 'Tor Browser', localized.
+rulesets-side-panel-no-rules-description = When you save a ruleset in { -brand-short-name }, it will show up here.
+
+## Ruleset update date in about:rulesets.
+
+# $date (Date) - The update date. The DATETIME function will format the $date according to the locale, using a "long" style. E.g. "January 1, 2000" for English (US), "١ يناير ٢٠٠٠" for Arabic, "2000년 1월 1일" in Korean, and "1 января 2000 г." in Russian.
+rulesets-update-last = Last updated { DATETIME($date, dateStyle: "long") }
+rulesets-update-never = Never updated, or last update failed
+# Shown when the ruleset is disabled.
+rulesets-update-rule-disabled = Disabled
+
+## Ruleset details in about:rulesets. In Tor Browser, each ruleset is a set of rules for converting a ".tor.onion" address to a normal ".onion" address (used by SecureDrop). The feature is taken from the discontinued "HTTPS Everywhere".
+
+rulesets-details-edit-button = Edit
+rulesets-details-enable-checkbox = Enable this ruleset
+rulesets-details-update-button = Check for Updates
+rulesets-details-save-button = Save
+rulesets-details-cancel-button = Cancel
+# "JWK" refers to "JSON Web Key" and likely should not be translated.
+rulesets-details-jwk = JWK
+# "JWK" refers to "JSON Web Key" and likely should not be translated.
+rulesets-details-jwk-input =
+ .placeholder = The key used to sign this ruleset in the JWK (JSON Web Key) format
+# "JWK" refers to "JSON Web Key" and likely should not be translated.
+rulesets-details-jwk-input-invalid = The JWK could not be parsed, or it is not a valid key
+# "Path" refers to the URL domain this rule applies to.
+rulesets-details-path = Path Prefix
+rulesets-details-path-input =
+ .placeholder = URL prefix that contains the files needed by the ruleset
+# "HTTP(S)" refers to "HTTP or HTTPS".
+rulesets-details-path-input-invalid = The path prefix is not a valid HTTP(S) URL
+# "Scope" refers to the breadth of URLs this rule applies to (as a regular expression).
+rulesets-details-scope = Scope
+# "Regular expression" refers to the computing term for a special pattern used for matching: https://en.wikipedia.org/wiki/Regular_expression.
+rulesets-details-scope-input =
+ .placeholder = Regular expression for the scope of the rules
+# "Regular expression" refers to the computing term for a special pattern used for matching: https://en.wikipedia.org/wiki/Regular_expression.
+rulesets-details-scope-input-invalid = The scope could not be parsed as a regular expression
=====================================
toolkit/modules/TorStrings.sys.mjs
=====================================
@@ -429,54 +429,6 @@ const Loader = {
learnMoreURLNotification: `https://tb-manual.torproject.org/${getLocale()}/onion-services/`,
};
} /* OnionLocation */,
-
- /*
- Rulesets
- */
- rulesets() {
- const strings = {
- // Initial warning
- warningTitle: "Proceed with Caution",
- warningDescription:
- "Adding or modifying rulesets can cause attackers to hijack your browser. Proceed only if you know what you are doing.",
- warningEnable: "Warn me when I attempt to access these preferences",
- warningButton: "Accept the Risk and Continue",
- // Ruleset list
- rulesets: "Rulesets",
- noRulesets: "No rulesets found",
- noRulesetsDescr:
- "When you save a ruleset in Tor Browser, it will show up here.",
- lastUpdated: "Last updated %S",
- neverUpdated: "Never updated, or last update failed",
- enabled: "Enabled",
- disabled: "Disabled",
- // Ruleset details
- edit: "Edit",
- name: "Name",
- jwk: "JWK",
- pathPrefix: "Path Prefix",
- scope: "Scope",
- enable: "Enable this ruleset",
- checkUpdates: "Check for Updates",
- // Add ruleset
- jwkPlaceholder:
- "The key used to sign this ruleset in the JWK (JSON Web Key) format",
- jwkInvalid: "The JWK could not be parsed, or it is not a valid key",
- pathPrefixPlaceholder:
- "URL prefix that contains the files needed by the ruleset",
- pathPrefixInvalid: "The path prefix is not a valid HTTP(S) URL",
- scopePlaceholder: "Regular expression for the scope of the rules",
- scopeInvalid: "The scope could not be parsed as a regular expression",
- save: "Save",
- cancel: "Cancel",
- };
-
- const tsb = new TorPropertyStringBundle(
- ["chrome://torbutton/locale/rulesets.properties"],
- "rulesets."
- );
- return tsb.getStrings(strings);
- } /* Rulesets */,
};
export const TorStrings = {
@@ -507,11 +459,4 @@ export const TorStrings = {
}
return this._onionLocation;
},
-
- get rulesets() {
- if (!this._rulesets) {
- this._rulesets = Loader.rulesets();
- }
- return this._rulesets;
- },
};
=====================================
toolkit/torbutton/chrome/locale/en-US/rulesets.properties deleted
=====================================
@@ -1,35 +0,0 @@
-# Copyright (c) 2022, The Tor Project, Inc.
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# about:rulesets strings.
-rulesets.warningTitle=Proceed with Caution
-rulesets.warningDescription=Adding or modifying rulesets can cause attackers to hijack your browser. Proceed only if you know what you are doing.
-rulesets.warningEnable=Warn me when I attempt to access these preferences
-rulesets.warningButton=Accept the Risk and Continue
-# Ruleset list
-rulesets.rulesets=Rulesets
-rulesets.noRulesets=No rulesets found
-rulesets.noRulesetsDescr=When you save a ruleset in Tor Browser, it will show up here.
-# LOCALIZATION NOTE: %S will be replaced by the update date (automatically formatted by Firefox's l10n component)
-rulesets.lastUpdated=Last updated %S
-rulesets.neverUpdated=Never updated, or last update failed
-rulesets.enabled=Enabled
-rulesets.disabled=Disabled
-# Ruleset details/edit ruleset
-rulesets.edit=Edit
-rulesets.name=Name
-rulesets.jwk=JWK
-rulesets.pathPrefix=Path Prefix
-rulesets.scope=Scope
-rulesets.enable=Enable this ruleset
-rulesets.checkUpdates=Check for Updates
-rulesets.jwkPlaceholder=The key used to sign this ruleset in the JWK (JSON Web Key) format
-rulesets.jwkInvalid=The JWK could not be parsed, or it is not a valid key
-rulesets.pathPrefixPlaceholder=URL prefix that contains the files needed by the ruleset
-rulesets.pathPrefixInvalid=The path prefix is not a valid HTTP(S) URL
-rulesets.scopePlaceholder=Regular expression for the scope of the rules
-rulesets.scopeInvalid=The scope could not be parsed as a regular expression
-rulesets.save=Save
-rulesets.cancel=Cancel
=====================================
tools/torbrowser/l10n/migrations/bug-42206-rulesets.py
=====================================
@@ -0,0 +1,70 @@
+import fluent.syntax.ast as FTL
+from fluent.migrate.helpers import transforms_from
+from fluent.migrate.transforms import REPLACE
+
+
+def migrate(ctx):
+ legacy_path = "rulesets.properties"
+
+ ctx.add_transforms(
+ "tor-browser.ftl",
+ "tor-browser.ftl",
+ transforms_from(
+ """
+rulesets-warning-heading = { COPY(path, "rulesets.warningTitle") }
+rulesets-warning-description = { COPY(path, "rulesets.warningDescription") }
+rulesets-warning-checkbox = { COPY(path, "rulesets.warningEnable") }
+rulesets-warning-continue-button = { COPY(path, "rulesets.warningButton") }
+
+rulesets-side-panel-heading = { COPY(path, "rulesets.rulesets") }
+rulesets-side-panel-no-rules = { COPY(path, "rulesets.noRulesets") }
+
+rulesets-update-never = { COPY(path, "rulesets.neverUpdated") }
+rulesets-update-rule-disabled = { COPY(path, "rulesets.disabled") }
+
+rulesets-details-edit-button = { COPY(path, "rulesets.edit") }
+rulesets-details-enable-checkbox = { COPY(path, "rulesets.enable") }
+rulesets-details-update-button = { COPY(path, "rulesets.checkUpdates") }
+rulesets-details-save-button = { COPY(path, "rulesets.save") }
+rulesets-details-cancel-button = { COPY(path, "rulesets.cancel") }
+rulesets-details-jwk-input =
+ .placeholder = { COPY(path, "rulesets.jwkPlaceholder") }
+rulesets-details-jwk-input-invalid = { COPY(path, "rulesets.jwkInvalid") }
+rulesets-details-path = { COPY(path, "rulesets.pathPrefix") }
+rulesets-details-path-input =
+ .placeholder = { COPY(path, "rulesets.pathPrefixPlaceholder") }
+rulesets-details-path-input-invalid = { COPY(path, "rulesets.pathPrefixInvalid") }
+rulesets-details-scope = { COPY(path, "rulesets.scope") }
+rulesets-details-scope-input =
+ .placeholder = { COPY(path, "rulesets.scopePlaceholder") }
+rulesets-details-scope-input-invalid = { COPY(path, "rulesets.scopeInvalid") }
+""",
+ path=legacy_path,
+ )
+ + [
+ # Replace "%1$S" with "{ DATETIME($date, dateStyle: "long") }"
+ FTL.Message(
+ FTL.Identifier("rulesets-update-last"),
+ value=REPLACE(
+ legacy_path,
+ "rulesets.lastUpdated",
+ {
+ "%1$S": FTL.FunctionReference(
+ FTL.Identifier("DATETIME"),
+ arguments=FTL.CallArguments(
+ positional=[
+ FTL.VariableReference(FTL.Identifier("date"))
+ ],
+ named=[
+ FTL.NamedArgument(
+ FTL.Identifier("dateStyle"),
+ value=FTL.StringLiteral("long"),
+ )
+ ],
+ ),
+ )
+ },
+ ),
+ ),
+ ],
+ )
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/08ed48facde83cda84f83b16bff3d69337ebfb75...8c14330efa6a56429f65f9a2726e868d552d2662
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/08ed48facde83cda84f83b16bff3d69337ebfb75...8c14330efa6a56429f65f9a2726e868d552d2662
You're receiving this email because of your account on gitlab.torproject.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20240416/a447dcd1/attachment-0001.htm>
More information about the tbb-commits
mailing list