commit 0c8136611b84cecbb6f470d14709788c4abbcb8f
parent 206592bdcb3d02b5369ab17eb3ca46419d28a23f
Author: Sandor Molnar <smolnar@mozilla.com>
Date: Sat, 1 Nov 2025 02:30:02 +0200
Revert "Bug 1970743 - move strings for browser-utils to the right file, r=fluent-reviewers,bolsson" for causing bc failures @ browser_unknownContentType_blob.js
This reverts commit 53772e4cc4022d2cbeb4ba5427c8117010227805.
Revert "Bug 1970743 - consolidate DownloadUtils.getURIHost into BrowserUtils.formatURIForDisplay, r=mak"
This reverts commit 72fc2f83fe2979b1a7b0f1552555d77b63bbf891.
Diffstat:
11 files changed, 138 insertions(+), 164 deletions(-)
diff --git a/browser/base/content/browser-fullScreenAndPointerLock.js b/browser/base/content/browser-fullScreenAndPointerLock.js
@@ -100,9 +100,10 @@ var PointerlockFsWarning = {
} else {
textElem.removeAttribute("hidden");
// Document's principal's URI has a host. Display a warning including it.
- let displayHost = BrowserUtils.formatURIForDisplay(uri, {
- onlyBaseDomain: true,
- });
+ let { DownloadUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/DownloadUtils.sys.mjs"
+ );
+ let displayHost = DownloadUtils.getURIHost(uri.spec)[0];
let l10nString = {
"fullscreen-warning": "fullscreen-warning-domain",
"pointerlock-warning": "pointerlock-warning-domain",
diff --git a/browser/components/downloads/DownloadsViewUI.sys.mjs b/browser/components/downloads/DownloadsViewUI.sys.mjs
@@ -12,7 +12,6 @@ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
- BrowserUtils: "resource://gre/modules/BrowserUtils.sys.mjs",
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
DownloadUtils: "resource://gre/modules/DownloadUtils.sys.mjs",
Downloads: "resource://gre/modules/Downloads.sys.mjs",
@@ -604,13 +603,7 @@ DownloadsViewUI.DownloadElementShell.prototype = {
this.showStatus(stateLabel, hoverStatus);
return;
}
- let uri = URL.parse(this.download.source.url)?.URI;
- let displayHost = uri
- ? lazy.BrowserUtils.formatURIForDisplay(uri, {
- onlyBaseDomain: true,
- })
- : "";
-
+ let [displayHost] = lazy.DownloadUtils.getURIHost(this.download.source.url);
let [displayDate] = lazy.DownloadUtils.getReadableDates(
new Date(this.download.endTime)
);
diff --git a/browser/components/firefoxview/fxview-tab-list.mjs b/browser/components/firefoxview/fxview-tab-list.mjs
@@ -517,9 +517,7 @@ export class FxviewTabRowBase extends MozLitElement {
formatURIForDisplay(uriString) {
return !window.IS_STORYBOOK
- ? lazy.BrowserUtils.formatURIStringForDisplay(uriString, {
- showFilenameForLocalURIs: true,
- })
+ ? lazy.BrowserUtils.formatURIStringForDisplay(uriString)
: uriString;
}
diff --git a/browser/components/firefoxview/helpers.mjs b/browser/components/firefoxview/helpers.mjs
@@ -24,9 +24,7 @@ export const LOGGING_PREF = "browser.tabs.firefox-view.logLevel";
export const MAX_TABS_FOR_RECENT_BROWSING = 5;
export function formatURIForDisplay(uriString) {
- return lazy.BrowserUtils.formatURIStringForDisplay(uriString, {
- showFilenameForLocalURIs: true,
- });
+ return lazy.BrowserUtils.formatURIStringForDisplay(uriString);
}
export function convertTimestamp(
diff --git a/python/l10n/fluent_migrations/bug_1970743_browser_utils.py b/python/l10n/fluent_migrations/bug_1970743_browser_utils.py
@@ -1,26 +0,0 @@
-# Any copyright is dedicated to the Public Domain.
-# http://creativecommons.org/publicdomain/zero/1.0/
-
-import fluent.syntax.ast as FTL
-from fluent.migrate import COPY_PATTERN
-from fluent.migrate.helpers import transforms_from
-from fluent.migrate.transforms import COPY
-
-
-def migrate(ctx):
- """Bug 1970743 - move some download strings to browser-utils.ftl, part {index}."""
- source = "toolkit/toolkit/downloads/downloadUtils.ftl"
- target = "toolkit/toolkit/global/browser-utils.ftl"
-
- ctx.add_transforms(
- target,
- target,
- transforms_from(
- """
-browser-utils-file-scheme = {COPY_PATTERN(from_path, "download-utils-done-file-scheme")}
-
-browser-utils-url-scheme = {COPY_PATTERN(from_path, "download-utils-done-scheme")}
-""",
- from_path=source,
- ),
- )
diff --git a/toolkit/locales/en-US/toolkit/downloads/downloadUtils.ftl b/toolkit/locales/en-US/toolkit/downloads/downloadUtils.ftl
@@ -95,5 +95,12 @@ download-utils-time-left-double = { $time1 } { $time2 } left
download-utils-time-few-seconds = A few seconds left
download-utils-time-unknown = Unknown time left
+# Variables:
+# $scheme (string) - URI scheme like data: jar: about:
+download-utils-done-scheme = { $scheme } resource
+# Special case of done-scheme for file:
+# This is used as an eTLD replacement for local files, so make it lower case
+download-utils-done-file-scheme = local file
+
# Displayed time for files finished yesterday
download-utils-yesterday = Yesterday
diff --git a/toolkit/locales/en-US/toolkit/global/browser-utils.ftl b/toolkit/locales/en-US/toolkit/global/browser-utils.ftl
@@ -5,14 +5,6 @@
# Used for data: URLs where we don't have any useful origin information
browser-utils-url-data = (data)
-# Variables:
-# $scheme (string) - URI scheme like jar: about:
-browser-utils-url-scheme = { $scheme } resource
-# Special case of done-scheme for file:
-# This is used as an eTLD replacement for local files, so make it lower case
-browser-utils-file-scheme = local file
-
-
# Used for extension URLs
# Variables:
# $extension (string) - Name of the extension that generated the URL
diff --git a/toolkit/modules/BrowserUtils.sys.mjs b/toolkit/modules/BrowserUtils.sys.mjs
@@ -246,36 +246,8 @@ export var BrowserUtils = {
}
},
- /**
- * Show a URI in the UI in a user-friendly (but security-sensitive) way.
- *
- * @param {nsIURI} uri
- * @param {object} [options={}]
- * @param {boolean} [options.showInsecureHTTP=false]
- * Whether to show "http://" for insecure HTTP URLs.
- * @param {boolean} [options.showWWW=false]
- * Whether to show "www." for URLs that have it.
- * @param {boolean} [options.onlyBaseDomain=false]
- * Whether to show only the base domain (eTLD+1) for HTTP(S) URLs.
- * @param {boolean} [options.showFilenameForLocalURIs=false]
- * If false (default), will show a protocol-specific label for local
- * URIs (file:, chrome:, resource:, moz-src:, jar:).
- * Otherwise, will show the filename for such URIs. Only use 'true' if
- * the context in which the URI is being represented is not security-
- * critical.
- */
formatURIForDisplay(uri, options = {}) {
- let {
- showInsecureHTTP = false,
- showWWW = false,
- onlyBaseDomain = false,
- showFilenameForLocalURIs = false,
- } = options;
- // For moz-icon and jar etc. which wrap nsIURLs, if we want to show the
- // actual filename, unwrap:
- if (uri && uri instanceof Ci.nsINestedURI && showFilenameForLocalURIs) {
- return this.formatURIForDisplay(uri.innermostURI, options);
- }
+ let { showInsecureHTTP = false } = options;
switch (uri.scheme) {
case "view-source": {
let innerURI = uri.spec.substring("view-source:".length);
@@ -285,14 +257,8 @@ export var BrowserUtils = {
// Fall through.
case "https": {
let host = uri.displayHostPort;
- let removeSubdomains =
- !showInsecureHTTP &&
- (onlyBaseDomain || (!showWWW && host.startsWith("www.")));
- if (removeSubdomains) {
+ if (!showInsecureHTTP && host.startsWith("www.")) {
host = Services.eTLD.getSchemelessSite(uri);
- if (uri.port != -1) {
- host += ":" + uri.port;
- }
}
if (showInsecureHTTP && uri.scheme == "http") {
return "http://" + host;
@@ -303,7 +269,7 @@ export var BrowserUtils = {
return "about:" + uri.filePath;
case "blob":
try {
- let url = URL.fromURI(uri);
+ let url = new URL(uri.specIgnoringRef);
// _If_ we find a non-null origin, report that.
if (url.origin && url.origin != "null") {
return this.formatURIStringForDisplay(url.origin, options);
@@ -325,22 +291,8 @@ export var BrowserUtils = {
}
case "chrome":
case "resource":
- case "moz-icon":
- case "moz-src":
case "jar":
case "file":
- if (!showFilenameForLocalURIs) {
- if (uri.scheme == "file") {
- return lazy.gLocalization.formatValueSync(
- "browser-utils-file-scheme"
- );
- }
- return lazy.gLocalization.formatValueSync(
- "browser-utils-url-scheme",
- { scheme: uri.scheme }
- );
- }
- // Otherwise, fall through to show filename...
default:
try {
let url = uri.QueryInterface(Ci.nsIURL);
@@ -366,7 +318,7 @@ export var BrowserUtils = {
console.error(ex);
}
}
- return uri.spec;
+ return uri.asciiHost || uri.spec;
},
// Given a URL returns a (possibly transformed) URL suitable for sharing, or null if
diff --git a/toolkit/modules/tests/xpcshell/test_BrowserUtils_urlFormatting.js b/toolkit/modules/tests/xpcshell/test_BrowserUtils_urlFormatting.js
@@ -19,10 +19,6 @@ const EXTENSION_URL_EXPECTED_STRING = gL10n.formatValueSync(
{ extension: EXTENSION_NAME }
);
-const FILE_URL_EXPECTED_STRING = gL10n.formatValueSync(
- "browser-utils-file-scheme"
-);
-
const { AddonTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/AddonTestUtils.sys.mjs"
);
@@ -92,7 +88,7 @@ const HTTP_TESTS = [
output: "www.co.uk",
},
- // Other subdomains should be kept:
+ // Other sudomains should be kept:
{
input: "https://webmail.example.co.uk",
output: "webmail.example.co.uk",
@@ -162,15 +158,6 @@ const TESTS = [
input: "data:text/html,42",
output: DATA_URL_EXPECTED_STRING,
},
-
- {
- input: `moz-icon:${Services.io.newFileURI(tempFile).spec}`,
- output: tempFile.leafName,
- },
- {
- input: "moz-icon://.extension?size=16",
- output: "moz-icon://.extension?size=16",
- },
];
add_setup(async () => {
@@ -233,9 +220,7 @@ const { BrowserUtils } = ChromeUtils.importESModule(
add_task(async function test_checkStringFormatting() {
for (let { input, output } of TESTS) {
Assert.equal(
- BrowserUtils.formatURIStringForDisplay(input, {
- showFilenameForLocalURIs: true,
- }),
+ BrowserUtils.formatURIStringForDisplay(input),
output,
`String ${input} formatted for output should match`
);
@@ -246,56 +231,13 @@ add_task(async function test_checkURIFormatting() {
for (let { input, output } of TESTS) {
let uri = Services.io.newURI(input);
Assert.equal(
- BrowserUtils.formatURIForDisplay(uri, {
- showFilenameForLocalURIs: true,
- }),
- output,
- `URI ${input} formatted for output should match`
- );
- }
-});
-
-add_task(async function test_checkOnlyBaseDomain() {
- for (let { input, output } of [
- { input: "https://subdomain.example.com/", output: "example.com" },
- {
- input: "http://www.city.mikasa.hokkaido.jp/",
- output: "city.mikasa.hokkaido.jp",
- },
- { input: "https://www.example.co.uk/", output: "example.co.uk" },
- {
- input: "mailto:example@subdomain.example.com",
- output: "mailto:example@subdomain.example.com",
- },
- ]) {
- let uri = Services.io.newURI(input);
- Assert.equal(
- BrowserUtils.formatURIForDisplay(uri, { onlyBaseDomain: true }),
+ BrowserUtils.formatURIForDisplay(uri),
output,
`URI ${input} formatted for output should match`
);
}
});
-add_task(async function test_checkLocalFileFormatting() {
- for (let { input } of TESTS) {
- let uri = Services.io.newURI(input);
- if (
- ["file", "chrome", "moz-icon", "resource", "jar"].includes(uri.scheme)
- ) {
- Assert.equal(
- BrowserUtils.formatURIForDisplay(uri, {
- showFilenameForLocalURIs: false,
- }),
- uri.scheme == "file"
- ? FILE_URL_EXPECTED_STRING
- : `${uri.scheme} resource`,
- `URI ${input} formatted for output should match`
- );
- }
- }
-});
-
add_task(async function test_checkViewSourceFormatting() {
for (let { input, output } of HTTP_TESTS) {
Assert.equal(
diff --git a/toolkit/mozapps/downloads/DownloadUtils.sys.mjs b/toolkit/mozapps/downloads/DownloadUtils.sys.mjs
@@ -3,6 +3,8 @@
* 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/. */
+import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+
/**
* This module provides the DownloadUtils object which contains useful methods
* for downloads such as displaying file sizes, transfer times, and download
@@ -53,6 +55,14 @@ const TIME_UNITS = [
// with TIME_UNITS without the last item
const TIME_SIZES = [60, 60, 24];
+const lazy = {};
+XPCOMUtils.defineLazyServiceGetter(
+ lazy,
+ "IDNService",
+ "@mozilla.org/network/idn-service;1",
+ Ci.nsIIDNService
+);
+
var localeNumberFormatCache = new Map();
function getLocaleNumberFormat(fractionDigits) {
if (!localeNumberFormatCache.has(fractionDigits)) {
@@ -377,6 +387,82 @@ export var DownloadUtils = {
},
/**
+ * Get the appropriate display host string for a URI string depending on if
+ * the URI has an eTLD + 1, is an IP address, a local file, or other protocol
+ *
+ * @param aURIString
+ * The URI string to try getting an eTLD + 1, etc.
+ * @return A pair: [display host for the URI string, full host name]
+ */
+ getURIHost: function DU_getURIHost(aURIString) {
+ // Get a URI that knows about its components
+ let uri = URL.parse(aURIString)?.URI;
+ if (!uri) {
+ return ["", ""];
+ }
+
+ // Get the inner-most uri for schemes like jar:
+ if (uri instanceof Ci.nsINestedURI) {
+ uri = uri.innermostURI;
+ }
+
+ if (uri.schemeIs("blob")) {
+ let origin = URL.fromURI(uri).origin;
+ // Origin can be "null" for blob URIs from a sandbox.
+ if (origin != "null") {
+ // `newURI` can throw (like for null) and throwing here breaks...
+ // a lot of stuff. So let's avoid doing that in case there are other
+ // edgecases we're missing here.
+ try {
+ uri = Services.io.newURI(origin);
+ } catch (ex) {
+ console.error(ex);
+ }
+ }
+ }
+
+ let fullHost;
+ try {
+ // Get the full host name; some special URIs fail (data: jar:)
+ fullHost = uri.host;
+ } catch (e) {
+ fullHost = "";
+ }
+
+ let displayHost;
+ try {
+ // This might fail if it's an IP address or doesn't have more than 1 part
+ let baseDomain = Services.eTLD.getBaseDomain(uri);
+
+ // Convert base domain for display
+ displayHost = lazy.IDNService.convertToDisplayIDN(baseDomain);
+ } catch (e) {
+ // Default to the host name
+ displayHost = fullHost;
+ }
+
+ // Check if we need to show something else for the host
+ if (uri.schemeIs("file")) {
+ // Display special text for file protocol
+ displayHost = l10n.formatValueSync("download-utils-done-file-scheme");
+ fullHost = displayHost;
+ } else if (!displayHost.length) {
+ // Got nothing; show the scheme (data: about: moz-icon:)
+ displayHost = l10n.formatValueSync("download-utils-done-scheme", {
+ scheme: uri.scheme,
+ });
+ fullHost = displayHost;
+ } else if (uri.port != -1) {
+ // Tack on the port if it's not the default port
+ let port = ":" + uri.port;
+ displayHost += port;
+ fullHost += port;
+ }
+
+ return [displayHost, fullHost];
+ },
+
+ /**
* Converts a number of bytes to the appropriate unit that results in an
* internationalized number that needs fewer than 4 digits.
*
diff --git a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
@@ -83,6 +83,16 @@ function testFormattedTimeStatus(aSec, aExpected) {
Assert.equal(status.l10n.id, aExpected);
}
+function testURI(aURI, aDisp, aHost) {
+ dump("URI Test: " + [aURI, aDisp, aHost] + "\n");
+
+ let [disp, host] = DownloadUtils.getURIHost(aURI);
+
+ // Make sure we have the right display host and full host
+ Assert.equal(disp, aDisp);
+ Assert.equal(host, aHost);
+}
+
function testGetReadableDates(aDate, aCompactValue) {
const now = new Date(2000, 11, 31, 11, 59, 59);
@@ -363,5 +373,26 @@ function run_test() {
testFormattedTimeStatus(0, "downloading-file-opens-in-seconds-2");
testFormattedTimeStatus(30, "downloading-file-opens-in-seconds-2");
+ testURI("http://www.mozilla.org/", "mozilla.org", "www.mozilla.org");
+ testURI(
+ "http://www.city.mikasa.hokkaido.jp/",
+ "city.mikasa.hokkaido.jp",
+ "www.city.mikasa.hokkaido.jp"
+ );
+ testURI("data:text/html,Hello World", "data resource", "data resource");
+ testURI(
+ "jar:http://www.mozilla.com/file!/magic",
+ "mozilla.com",
+ "www.mozilla.com"
+ );
+ testURI("file:///C:/Cool/Stuff/", "local file", "local file");
+ // Don't test for moz-icon if we don't have a protocol handler for it (e.g. b2g):
+ if ("@mozilla.org/network/protocol;1?name=moz-icon" in Cc) {
+ testURI("moz-icon:file:///test.extension", "local file", "local file");
+ testURI("moz-icon://.extension", "moz-icon resource", "moz-icon resource");
+ }
+ testURI("about:config", "about resource", "about resource");
+ testURI("invalid.uri", "", "");
+
testAllGetReadableDates();
}