Compare commits

...

2 commits

Author SHA1 Message Date
Ark74
30225f2e73 icecat: add release icecat-140.7.0-1gnu1 for ecne 2026-01-18 00:07:02 -06:00
Ark74
7d0f5dab3b icecat: add release icecat-140.6.0-1gnu1 for ecne 2026-01-17 19:26:27 -06:00
3500 changed files with 465835 additions and 572634 deletions

View file

@ -5,13 +5,13 @@
[source.crates-io]
replace-with = "vendored-sources"
[source."git+https://github.com/IceCatGraphics/aa-stroke?rev=a821fa621c2def48e90c82774b4c6563b5a8ea4a"]
git = "https://github.com/IceCatGraphics/aa-stroke"
[source."git+https://github.com/FirefoxGraphics/aa-stroke?rev=a821fa621c2def48e90c82774b4c6563b5a8ea4a"]
git = "https://github.com/FirefoxGraphics/aa-stroke"
rev = "a821fa621c2def48e90c82774b4c6563b5a8ea4a"
replace-with = "vendored-sources"
[source."git+https://github.com/IceCatGraphics/wpf-gpu-raster?rev=99979da091fd58fba8477e7fcdf5ec0727102916"]
git = "https://github.com/IceCatGraphics/wpf-gpu-raster"
[source."git+https://github.com/FirefoxGraphics/wpf-gpu-raster?rev=99979da091fd58fba8477e7fcdf5ec0727102916"]
git = "https://github.com/FirefoxGraphics/wpf-gpu-raster"
rev = "99979da091fd58fba8477e7fcdf5ec0727102916"
replace-with = "vendored-sources"
@ -45,6 +45,11 @@ git = "https://github.com/gfx-rs/wgpu"
rev = "88862f1fa3fd0f0c1010e9fc999dcfe47b5ae8fc"
replace-with = "vendored-sources"
[source."git+https://github.com/glandium/allocator-api2?rev=ad5f3d56a5a4519eff52af4ff85293431466ef5c"]
git = "https://github.com/glandium/allocator-api2"
rev = "ad5f3d56a5a4519eff52af4ff85293431466ef5c"
replace-with = "vendored-sources"
[source."git+https://github.com/glandium/rust-objc?rev=4de89f5aa9851ceca4d40e7ac1e2759410c04324"]
git = "https://github.com/glandium/rust-objc"
rev = "4de89f5aa9851ceca4d40e7ac1e2759410c04324"
@ -70,9 +75,9 @@ git = "https://github.com/jfkthame/mapped_hyph.git"
rev = "eff105f6ad7ec9b79816cfc1985a28e5340ad14b"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954"]
[source."git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6"]
git = "https://github.com/mozilla/application-services"
rev = "9b46be5beedb6a1d859014a71bac58e2d722f954"
rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/audioipc?rev=e6f44a2bd1e57d11dfc737632a9e849077632330"]

View file

@ -101,7 +101,7 @@ tasks:
description: 'Created by a [cron task](https://icecat-ci-tc.services.mozilla.com/tasks/${cron.task_id}) (${treeherder_link})'
provisionerId: "${trustDomain}-${repository.level}"
workerType: "decision-gcp"
workerType: "decision"
tags:
$if: 'tasks_for == "hg-push"'

View file

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Merge day clobber 2025-08-18
Merge day clobber 2025-12-08

48
icecat/Cargo.lock generated
View file

@ -5,7 +5,7 @@ version = 3
[[package]]
name = "aa-stroke"
version = "0.1.0"
source = "git+https://github.com/IceCatGraphics/aa-stroke?rev=a821fa621c2def48e90c82774b4c6563b5a8ea4a#a821fa621c2def48e90c82774b4c6563b5a8ea4a"
source = "git+https://github.com/FirefoxGraphics/aa-stroke?rev=a821fa621c2def48e90c82774b4c6563b5a8ea4a#a821fa621c2def48e90c82774b4c6563b5a8ea4a"
dependencies = [
"euclid",
]
@ -27,7 +27,8 @@ dependencies = [
[[package]]
name = "allocator-api2"
version = "0.2.999"
version = "0.2.21"
source = "git+https://github.com/glandium/allocator-api2?rev=ad5f3d56a5a4519eff52af4ff85293431466ef5c#ad5f3d56a5a4519eff52af4ff85293431466ef5c"
dependencies = [
"serde",
]
@ -973,7 +974,7 @@ dependencies = [
[[package]]
name = "context_id"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"chrono",
"error-support",
@ -1165,6 +1166,7 @@ dependencies = [
name = "crash_helper_common"
version = "0.1.0"
dependencies = [
"getrandom 0.3.3",
"minidump-writer",
"nix 0.30.1",
"num-derive",
@ -1912,7 +1914,7 @@ dependencies = [
[[package]]
name = "error-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"env_logger",
"error-support-macros",
@ -1925,7 +1927,7 @@ dependencies = [
[[package]]
name = "error-support-macros"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"proc-macro2",
"quote",
@ -2042,9 +2044,9 @@ dependencies = [
]
[[package]]
name = "icecat-versioning"
name = "firefox-versioning"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"serde_json",
"thiserror 1.999.999",
@ -3385,7 +3387,7 @@ dependencies = [
[[package]]
name = "interrupt-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"lazy_static",
"parking_lot",
@ -5115,7 +5117,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
[[package]]
name = "payload-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"serde",
"serde_derive",
@ -5622,7 +5624,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "relevancy"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"anyhow",
"base64 0.21.999",
@ -5646,12 +5648,12 @@ dependencies = [
[[package]]
name = "remote_settings"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"anyhow",
"camino",
"error-support",
"icecat-versioning",
"firefox-versioning",
"jexl-eval",
"parking_lot",
"regex",
@ -5947,10 +5949,10 @@ dependencies = [
[[package]]
name = "search"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"error-support",
"icecat-versioning",
"firefox-versioning",
"parking_lot",
"remote_settings",
"serde",
@ -6239,7 +6241,7 @@ dependencies = [
[[package]]
name = "sql-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"error-support",
"interrupt-support",
@ -6438,7 +6440,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "suggest"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"anyhow",
"chrono",
@ -6491,7 +6493,7 @@ dependencies = [
[[package]]
name = "sync-guid"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"base64 0.21.999",
"rand",
@ -6502,7 +6504,7 @@ dependencies = [
[[package]]
name = "sync15"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"anyhow",
"error-support",
@ -6541,7 +6543,7 @@ dependencies = [
[[package]]
name = "tabs"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"anyhow",
"error-support",
@ -6899,7 +6901,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "types"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"rusqlite 0.33.0",
"serde",
@ -7311,7 +7313,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "viaduct"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"error-support",
"ffi-support",
@ -7480,7 +7482,7 @@ dependencies = [
[[package]]
name = "webext-storage"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=9b46be5beedb6a1d859014a71bac58e2d722f954#9b46be5beedb6a1d859014a71bac58e2d722f954"
source = "git+https://github.com/mozilla/application-services?rev=f5907a411e52a3985d0369d71c486eb507c2c4e6#f5907a411e52a3985d0369d71c486eb507c2c4e6"
dependencies = [
"anyhow",
"error-support",
@ -7899,7 +7901,7 @@ dependencies = [
[[package]]
name = "wpf-gpu-raster"
version = "0.1.0"
source = "git+https://github.com/IceCatGraphics/wpf-gpu-raster?rev=99979da091fd58fba8477e7fcdf5ec0727102916#99979da091fd58fba8477e7fcdf5ec0727102916"
source = "git+https://github.com/FirefoxGraphics/wpf-gpu-raster?rev=99979da091fd58fba8477e7fcdf5ec0727102916#99979da091fd58fba8477e7fcdf5ec0727102916"
dependencies = [
"typed-arena-nomut",
]

View file

@ -264,16 +264,17 @@ wr_malloc_size_of = { path = "gfx/wr/wr_malloc_size_of" }
# objc 0.2.7 + fa7ca43b862861dd1cd000d7ad01e6e0266cda13
objc = { git = "https://github.com/glandium/rust-objc", rev = "4de89f5aa9851ceca4d40e7ac1e2759410c04324" }
# application-services overrides to make updating them all simpler.
context_id = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
search = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "9b46be5beedb6a1d859014a71bac58e2d722f954" }
# allocator-api2 + f95e3419ce41883904fcb2279b52aa35b5f04d76 + fdd92751afa7ce34408b677004b429d597e72c90
allocator-api2 = { git = "https://github.com/glandium/allocator-api2", rev = "ad5f3d56a5a4519eff52af4ff85293431466ef5c" }
allocator-api2 = { path = "third_party/rust/allocator-api2" }
# application-services overrides to make updating them all simpler.
context_id = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
search = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }

View file

@ -429,6 +429,13 @@ static void AppendTextToAttributedString(
static RefPtr<AccAttributes> GetTextAttributes(TextLeafPoint aPoint) {
RefPtr<AccAttributes> attrs = aPoint.GetTextAttributes();
if (!attrs) {
// If we can't fetch text attributes for the given point, return null.
// We avoid creating a new AccAttributes here because our AttributedText()
// code below relies on this null return value to indicate we're dealing
// with a non-text control.
return nullptr;
}
// Mac expects some object properties to be exposed as text attributes. We
// add these here rather than in utils::StringAttributesFromAccAttributes so
// we can use AccAttributes::Equal to determine whether we need to start a new

View file

@ -276,3 +276,35 @@ addAccessibleTask(
ok(!attributedText[2].AXHighlight);
}
);
// Test the <mark> element, in conjunction with content that will
// prevent the creation of a text attributes object.
addAccessibleTask(
`<mark>a<button></button>b</mark>`,
async function testMarkNoAttributes(browser, accDoc) {
const macDoc = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
const range = macDoc.getParameterizedAttributeValue(
"AXTextMarkerRangeForUnorderedTextMarkers",
[
macDoc.getAttributeValue("AXStartTextMarker"),
macDoc.getAttributeValue("AXEndTextMarker"),
]
);
const attributedText = macDoc.getParameterizedAttributeValue(
"AXAttributedStringForTextMarkerRange",
range
);
ok(attributedText, "Document has attributed text");
is(attributedText.length, 3, "3 pieces of attributed text exist");
ok(attributedText[0].AXHighlight, "0th pos text has highlight");
is(attributedText[0].string, "a", "0th pos text is string `a`");
ok(!attributedText[1].AXHighlight, "1st pos text has no highlight");
ok(attributedText[2].AXHighlight, "2nd pos text has highlight");
is(attributedText[2].string, "b", "2nd pos text is string `b`");
}
);

View file

@ -852,6 +852,13 @@ customElements.define(
BrowserAddonUI.openAddonsMgr(
"addons://detail/" + encodeURIComponent(addonId)
);
// The settings link element has its href set to "#" to be
// accessible with keyboard navigation, and so we call
// preventDefault to avoid the "#" href to be implicitly
// added to the browser chrome window url (See Bug 1983869
// for more details of the regression that the implicit
// change to the chrome window urls triggers).
event.preventDefault();
}
break;
}

View file

@ -389,7 +389,7 @@
<menuitem id="context-printframe"
data-l10n-id="main-context-menu-frame-print"
/>
<menuseparator/>
<menuseparator id="print-frame-sep"/>
<menuitem id="context-take-frame-screenshot"
data-l10n-id="main-context-menu-take-frame-screenshot"
/>

View file

@ -103,10 +103,9 @@ var PointerlockFsWarning = {
} else {
textElem.removeAttribute("hidden");
// Document's principal's URI has a host. Display a warning including it.
let { DownloadUtils } = ChromeUtils.importESModule(
"resource://gre/modules/DownloadUtils.sys.mjs"
);
let displayHost = DownloadUtils.getURIHost(uri.spec)[0];
let displayHost = BrowserUtils.formatURIForDisplay(uri, {
onlyBaseDomain: true,
});
let l10nString = {
"fullscreen-warning": "fullscreen-warning-domain",
"pointerlock-warning": "pointerlock-warning-domain",

View file

@ -1953,10 +1953,13 @@ var XULBrowserWindow = {
if (url) {
url = Services.textToSubURI.unEscapeURIForUI(url);
// Encode bidirectional formatting characters.
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
/**
* Encode bidirectional formatting characters.
* @see https://url.spec.whatwg.org/#url-rendering-i18n
* @see https://www.unicode.org/reports/tr9/#Directional_Formatting_Characters
*/
url = url.replace(
/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
/[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g,
encodeURIComponent
);
@ -2227,7 +2230,7 @@ var XULBrowserWindow = {
// Ensure we close any remaining open locationspecific panels
if (!isSameDocument) {
closeOpenPanels("panel[locationspecific='true']");
closeOpenPanels(":is(panel, menupopup)[locationspecific='true']");
}
gPermissionPanel.onLocationChange();

View file

@ -67,6 +67,13 @@ XPCOMUtils.defineLazyPreferenceGetter(
false
);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"gPrintEnabled",
"print.enabled",
false
);
XPCOMUtils.defineLazyServiceGetter(
lazy,
"QueryStringStripper",
@ -838,7 +845,8 @@ export class nsContextMenu {
"context-print-selection",
!this.inAboutDevtoolsToolbox &&
this.isContentSelected &&
this.selectionInfo.isDocumentLevelSelection
this.selectionInfo.isDocumentLevelSelection &&
lazy.gPrintEnabled
);
var shouldShow = !(
@ -946,6 +954,8 @@ export class nsContextMenu {
this.showItem("context-openframeintab", !this.inSrcdocFrame);
this.showItem("context-openframe", !this.inSrcdocFrame);
this.showItem("context-bookmarkframe", !this.inSrcdocFrame);
this.showItem("context-printframe", lazy.gPrintEnabled);
this.showItem("print-frame-sep", lazy.gPrintEnabled);
// Hide menu entries for images, show otherwise
if (this.inFrame) {

View file

@ -969,13 +969,6 @@ export default class LoginItem extends HTMLElement {
}
_updatePasswordRevealState() {
if (
window.AboutLoginsUtils &&
window.AboutLoginsUtils.passwordRevealVisible === false
) {
this._revealCheckbox.hidden = true;
}
let { checked } = this._revealCheckbox;
let inputType = checked ? "text" : "password";
this._passwordInput.type = inputType;
@ -988,6 +981,13 @@ export default class LoginItem extends HTMLElement {
this._revealCheckbox.hidden = false;
}
if (
window.AboutLoginsUtils &&
window.AboutLoginsUtils.passwordRevealVisible === false
) {
this._revealCheckbox.hidden = true;
}
// Swap which <input> is in the document depending on whether we need the
// real .value (which means that the primary password was already entered,
// if applicable)

View file

@ -12,6 +12,7 @@ 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",
@ -600,7 +601,13 @@ DownloadsViewUI.DownloadElementShell.prototype = {
this.showStatus(stateLabel, hoverStatus);
return;
}
let [displayHost] = lazy.DownloadUtils.getURIHost(this.download.source.url);
let uri = URL.parse(this.download.source.url)?.URI;
let displayHost = uri
? lazy.BrowserUtils.formatURIForDisplay(uri, {
onlyBaseDomain: true,
})
: "";
let [displayDate] = lazy.DownloadUtils.getReadableDates(
new Date(this.download.endTime)
);

View file

@ -1576,6 +1576,27 @@ export var Policies = {
},
},
GenerativeAI: {
onBeforeAddons(manager, param) {
const defaultValue = "Enabled" in param ? param.Enabled : undefined;
const features = [
["Chatbot", ["browser.ml.chat.enabled", "browser.ml.chat.page"]],
["LinkPreviews", ["browser.ml.linkPreview.optin"]],
["TabGroups", ["browser.tabs.groups.smart.userEnabled"]],
];
for (const [key, prefs] of features) {
const value = key in param ? param[key] : defaultValue;
if (value !== undefined) {
for (const pref of prefs) {
PoliciesUtils.setDefaultPref(pref, value, param.Locked);
}
}
}
},
},
GoToIntranetSiteForSingleWordEntryInAddressBar: {
onBeforeAddons(manager, param) {
setAndLockPref("browser.fixup.dns_first_for_single_words", param);
@ -2080,6 +2101,7 @@ export var Policies = {
"security.tls.hello_downgrade_check",
"security.tls.version.enable-deprecated",
"security.warn_submit_secure_to_insecure",
"security.webauthn.always_allow_direct_attestation",
];
const blockedPrefs = [
"app.update.channel",

View file

@ -850,6 +850,27 @@
}
},
"GenerativeAI": {
"type": "object",
"properties": {
"Chatbot": {
"type": "boolean"
},
"LinkPreviews": {
"type": "boolean"
},
"TabGroups": {
"type": "boolean"
},
"Enabled": {
"type": "boolean"
},
"Locked": {
"type": "boolean"
}
}
},
"GoToIntranetSiteForSingleWordEntryInAddressBar": {
"type": "boolean"
},

View file

@ -4,6 +4,41 @@
"use strict";
add_task(async function test_hidden_reveal_password() {
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(
Ci.nsILoginInfo
);
login.init("https://example.com", "", null, "username", "password");
login.QueryInterface(Ci.nsILoginMetaInfo);
login.timePasswordChanged = Date.now();
await Services.logins.addLoginAsync(login);
await setupPolicyEngineWithJson({
policies: {
DisablePasswordReveal: true,
},
});
let aboutLoginsTab = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
url: "about:logins",
});
let browser = gBrowser.selectedBrowser;
await SpecialPowers.spawn(browser, [], () => {
let loginItem = Cu.waiveXrays(content.document.querySelector("login-item"));
let passwordReveal = loginItem.shadowRoot.querySelector(
".reveal-password-checkbox"
);
is(passwordReveal.hidden, true, "Password reveal button should be hidden");
});
BrowserTestUtils.removeTab(aboutLoginsTab);
await Services.logins.removeAllLogins();
});
add_task(async function test_bug_1696948() {
await setupPolicyEngineWithJson({
policies: {
DisablePasswordReveal: true,

View file

@ -1184,6 +1184,38 @@ const POLICIES_TESTS = [
// browser/components/enterprisepolicies/tests/browser/browser_policy_usermessaging.js
},
},
// Bug 1981587
{
policies: {
Preferences: {
"security.webauthn.always_allow_direct_attestation": {
Value: true,
Status: "locked",
},
},
},
lockedPrefs: {
"security.webauthn.always_allow_direct_attestation": true,
},
},
// GenerativeAI
{
policies: {
GenerativeAI: {
Enabled: false,
Chatbot: true,
Locked: true,
},
},
lockedPrefs: {
"browser.ml.chat.enabled": true,
"browser.ml.chat.page": true,
"browser.ml.linkPreview.optin": false,
"browser.tabs.groups.smart.userEnabled": false,
},
},
];
add_task(async function test_policy_simple_prefs() {

View file

@ -166,7 +166,7 @@ export const LinkPreview = {
},
get canShowKeyPoints() {
return this._isRegionSupported();
return this._isRegionSupported() && !this._isDisabledByPolicy();
},
get canShowLegacy() {
@ -751,6 +751,17 @@ export const LinkPreview = {
return !disallowedRegions.includes(userRegion);
},
/**
* Checks if key points generation is disabled by policy.
*
* @returns {boolean} True if disabled by policy, false otherwise.
*/
_isDisabledByPolicy() {
return (
!lazy.optin && Services.prefs.prefIsLocked("browser.ml.linkPreview.optin")
);
},
/**
* Creates an Open Graph (OG) card using meta information from the page.
*

View file

@ -419,6 +419,13 @@ class LinkPreviewCard extends MozLitElement {
return "";
}
if (
!this.optin &&
Services.prefs.prefIsLocked("browser.ml.linkPreview.optin")
) {
return "";
}
// Determine if there's any generation error state
const isGenerationError =
this.isMissingDataErrorState || this.generationError;

View file

@ -450,3 +450,54 @@ add_task(async function test_no_optin_or_keypoints_in_disallowed_region() {
panel.remove();
generateStub.restore();
});
/**
* Test when the preference is false and locked, the opt-in prompt will not
* be shown and no attempt will be made to generate key points.
*/
add_task(async function test_locked_preference() {
await SpecialPowers.pushPrefEnv({
set: [
["browser.ml.linkPreview.enabled", true],
["browser.ml.linkPreview.optin", false],
["browser.ml.linkPreview.collapsed", false],
],
});
Services.prefs.lockPref("browser.ml.linkPreview.optin");
const generateStub = sinon.stub(LinkPreviewModel, "generateTextAI");
LinkPreview.keyboardComboActive = true;
XULBrowserWindow.setOverLink(
"https://example.com/browser/browser/components/genai/tests/browser/data/readableEn.html",
{}
);
let panel = await TestUtils.waitForCondition(() =>
document.getElementById("link-preview-panel")
);
await BrowserTestUtils.waitForEvent(panel, "popupshown");
const card = panel.querySelector("link-preview-card");
ok(card, "card created for link preview");
ok(
!LinkPreview.canShowKeyPoints,
"LinkPreview should indicate key points cannot be shown"
);
// Verify that the opt-in element is NOT present
const modelOptinElement = card.shadowRoot.querySelector("model-optin");
ok(!modelOptinElement, "model-optin element should NOT be present");
is(
generateStub.callCount,
0,
"generateTextAI should not be called in a disallowed region"
);
panel.remove();
generateStub.restore();
Services.prefs.unlockPref("browser.ml.linkPreview.optin");
});

View file

@ -513,7 +513,9 @@ export class FxviewTabRowBase extends MozLitElement {
formatURIForDisplay(uriString) {
return !window.IS_STORYBOOK
? lazy.BrowserUtils.formatURIStringForDisplay(uriString)
? lazy.BrowserUtils.formatURIStringForDisplay(uriString, {
showFilenameForLocalURIs: true,
})
: uriString;
}

View file

@ -24,7 +24,9 @@ export const LOGGING_PREF = "browser.tabs.icecat-view.logLevel";
export const MAX_TABS_FOR_RECENT_BROWSING = 5;
export function formatURIForDisplay(uriString) {
return lazy.BrowserUtils.formatURIStringForDisplay(uriString);
return lazy.BrowserUtils.formatURIStringForDisplay(uriString, {
showFilenameForLocalURIs: true,
});
}
export function convertTimestamp(

View file

@ -18,6 +18,7 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
HistoryController: "resource:///modules/HistoryController.sys.mjs",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
ProfileAge: "resource://gre/modules/ProfileAge.sys.mjs",
});
@ -214,7 +215,8 @@ class HistoryInView extends ViewPage {
return (
this.profileAge < 8 &&
!this.hasImportedHistoryPref &&
!this.importHistoryDismissedPref
!this.importHistoryDismissedPref &&
Services.policies.isAllowed("profileImport")
);
}
@ -247,6 +249,7 @@ class HistoryInView extends ViewPage {
@click=${this.openInNewPrivateWindow}
data-l10n-id="fxviewtabrow-open-in-private-window"
data-l10n-attrs="accesskey"
?hidden=${!lazy.PrivateBrowsingUtils.enabled}
></panel-item>
<hr />
<panel-item

View file

@ -49,7 +49,7 @@
#include placesContextMenu.inc.xhtml
#include bookmarksHistoryTooltip.inc.xhtml
<box id="sidebar-panel-header" align="center">
<h4 data-l10n-id="sidebar-menu-bookmarks-2"></h4>
<html:h4 data-l10n-id="sidebar-menu-bookmarks-2"></html:h4>
<html:moz-button
id="sidebar-panel-close"
type="icon ghost"

View file

@ -797,6 +797,15 @@ class PlacesViewBase {
}
if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
if (this.#isPopupForRecursiveFolderShortcut(popup)) {
// Show as an empty container for now. We may want to show a better
// message in the future, but since we are likely to remove recursive
// shortcuts in maintenance at a certain point, this should be enough.
this._setEmptyPopupStatus(popup, true);
popup._built = true;
return;
}
if (!popup._placesNode.containerOpen) {
popup._placesNode.containerOpen = true;
}
@ -819,6 +828,33 @@ class PlacesViewBase {
aObject.removeEventListener(aEventNames[i], this, aCapturing);
}
}
/**
* Walks up the parent chain to detect whether a folder shortcut resolves to
* a folder already present in the ancestry.
*
* @param {DOMElement} popup
* @returns {boolean} Whether this popup is for a recursive folder shortcut.
*/
#isPopupForRecursiveFolderShortcut(popup) {
if (
!popup._placesNode ||
!PlacesUtils.nodeIsFolderOrShortcut(popup._placesNode)
) {
return false;
}
let guid = PlacesUtils.getConcreteItemGuid(popup._placesNode);
for (
let parentView = popup.parentNode?.parentNode;
parentView?._placesNode;
parentView = parentView.parentNode?.parentNode
) {
if (PlacesUtils.getConcreteItemGuid(parentView._placesNode) == guid) {
return true;
}
}
return false;
}
}
/**

View file

@ -214,6 +214,8 @@ skip-if = ["verify && debug && os == 'win'"]
["browser_paste_resets_cut_highlights.js"]
["browser_recursive_hierarchies.js"]
["browser_remove_bookmarks.js"]
["browser_sidebar_bookmarks_telemetry.js"]

View file

@ -0,0 +1,160 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Verify that menu popups are not populated when doing so would create a
* recursive hierarchy. Some consumers may walk menu trees and could enter an
* infinite loop if recursion were allowed.
*/
"use strict";
async function openMenuAndWaitForPopup(menu) {
let popup = menu.menupopup;
let popupShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
// This seems necessary, at least for the toolbar.
EventUtils.synthesizeNativeMouseEvent({
type: "mousemove",
target: menu,
atCenter: true,
});
menu.open = true;
await popupShown;
return popup;
}
function findNode(guid, view) {
for (let node of view.childNodes) {
console.log("visiting node", node, node._placesNode?.bookmarkGuid);
if (node._placesNode?.bookmarkGuid == guid) {
return node;
}
}
return null;
}
function fakeOpenMenu(popup) {
popup.dispatchEvent(new MouseEvent("popupshowing", { bubbles: true }));
popup.dispatchEvent(new MouseEvent("popupshown", { bubbles: true }));
}
function findPlacesNode(guid, container) {
for (let i = 0; i < container.childCount; i++) {
let node = container.getChild(i);
if (node.bookmarkGuid == guid) {
return node;
}
}
return null;
}
add_task(async function test() {
// Make sure the bookmarks bar is visible and restore its state on cleanup.
let toolbar = document.getElementById("PersonalToolbar");
ok(toolbar, "PersonalToolbar should not be null");
if (toolbar.collapsed) {
await promiseSetToolbarVisibility(toolbar, true);
registerCleanupFunction(function () {
return promiseSetToolbarVisibility(toolbar, false);
});
}
let menubar = document.getElementById("toolbar-menubar");
// Force the menu to be shown.
const kAutohide = menubar.getAttribute("autohide");
menubar.removeAttribute("autohide");
registerCleanupFunction(function () {
menubar.setAttribute("autohide", kAutohide);
});
registerCleanupFunction(PlacesUtils.bookmarks.eraseEverything);
// Create a folder structure with a recursive shortcut.
let folderA = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
title: "Folder A",
type: PlacesUtils.bookmarks.TYPE_FOLDER,
});
let selfShortcut = await PlacesUtils.bookmarks.insert({
parentGuid: folderA.guid,
title: "Shortcut to A",
url: `place:parent=${folderA.guid}`,
});
let toolbarShortcut = await PlacesUtils.bookmarks.insert({
parentGuid: folderA.guid,
title: "Shortcut to toolbar",
url: `place:parent=${PlacesUtils.bookmarks.toolbarGuid}`,
});
// This also ensures that toolbar content is updated.
Assert.ok(!(await PlacesToolbarHelper.getIsEmpty()), "Toolbar is not empty");
// Open the popup for the shortcut from the bookmarks toolbar.
let toolbarItems = document.getElementById("PlacesToolbarItems");
let folderANode = findNode(folderA.guid, toolbarItems);
let folderAPopup = await openMenuAndWaitForPopup(folderANode);
let selfShortcutNode = findNode(selfShortcut.guid, folderAPopup);
let selfShortcutPopup = await openMenuAndWaitForPopup(selfShortcutNode);
Assert.ok(
!selfShortcutPopup._placesNode.containerOpen,
"Self shortcut container is not open"
);
Assert.ok(
selfShortcutPopup.hasAttribute("emptyplacesresult"),
"Self shortcut popup is empty"
);
let toolbarShortcutNode = findNode(
toolbarShortcut.guid,
folderANode.menupopup
);
let toolbarShortcutPopup = await openMenuAndWaitForPopup(toolbarShortcutNode);
Assert.ok(
!toolbarShortcutPopup._placesNode.containerOpen,
"Toolbar shortcut container is not open"
);
Assert.ok(
toolbarShortcutPopup.hasAttribute("emptyplacesresult"),
"Toolbar shortcut popup is empty"
);
// Also insert a toolbar shortcut in the bookmarks menu and check the
// previously inserted recursive toolbar shortcut there.
info("Test native bookmarks menu");
let shortcutInMenu = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid,
title: "Shortcut to menu",
url: `place:parent=${PlacesUtils.bookmarks.menuGuid}`,
});
if (Services.appinfo.nativeMenubar) {
// With native menubar we can only simulate popupshowing as we cannot
// directly open menus.
let bookmarksMenuPopup = document.getElementById("bookmarksMenuPopup");
fakeOpenMenu(bookmarksMenuPopup);
let shortcutInMenuNode = findNode(shortcutInMenu.guid, bookmarksMenuPopup);
fakeOpenMenu(shortcutInMenuNode.menupopup);
Assert.ok(
!shortcutInMenuNode.menupopup._placesNode.containerOpen,
"menu shortcut container is not open"
);
} else {
let bookmarksMenu = document.getElementById("bookmarksMenu");
let bookmarksPopup = await openMenuAndWaitForPopup(bookmarksMenu);
let shortcutInMenuNode = findNode(shortcutInMenu.guid, bookmarksPopup);
let shortcutInMenuPopup = await openMenuAndWaitForPopup(
shortcutInMenuNode,
true
);
Assert.ok(
!shortcutInMenuPopup._placesNode.containerOpen,
"Toolbar shortcut container is not open"
);
Assert.ok(
shortcutInMenuPopup.hasAttribute("emptyplacesresult"),
"Toolbar shortcut popup is empty"
);
}
});

View file

@ -3,10 +3,14 @@
const PATH_NET = TEST_PATH + "file_dummy.html";
const PATH_ORG = PATH_NET.replace("example.net", "example.org");
add_task(async function () {
async function runTest(defaultZoom) {
let tab1, tab1Zoom;
tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PATH_NET);
tab1Zoom = ZoomManager.getZoomForBrowser(tab1.linkedBrowser);
is(tab1Zoom, defaultZoom, "We are starting with the default zoom.");
await FullZoom.setZoom(1.25, tab1.linkedBrowser);
tab1Zoom = ZoomManager.getZoomForBrowser(tab1.linkedBrowser);
@ -46,7 +50,7 @@ add_task(async function () {
is(
tab1Zoom,
1.0,
defaultZoom,
"privacy.resistFingerprinting is true, site-specific zoom should be reset when clearing FPP state for tab1"
);
@ -55,4 +59,29 @@ add_task(async function () {
BrowserTestUtils.removeTab(tab1);
await SpecialPowers.popPrefEnv();
}
add_task(async function () {
await runTest(1.0);
let defaultZoom = 1.5;
let context = Cu.createLoadContext();
let cps2 = Cc["@mozilla.org/content-pref/service;1"].getService(
Ci.nsIContentPrefService2
);
let { promise, resolve, reject } = Promise.withResolvers();
cps2.setGlobal(FullZoom.name, defaultZoom, context, {
handleError(error) {
reject(error);
},
handleCompletion() {
resolve();
},
});
await promise;
try {
await runTest(defaultZoom);
} finally {
cps2.removeGlobal(FullZoom.name, context);
}
});

View file

@ -16,6 +16,7 @@ import { SidebarPage } from "./sidebar-page.mjs";
ChromeUtils.defineESModuleGetters(lazy, {
HistoryController: "resource:///modules/HistoryController.sys.mjs",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
Sanitizer: "resource:///modules/Sanitizer.sys.mjs",
});
@ -72,6 +73,10 @@ export class SidebarHistory extends SidebarPage {
if (!this.triggerNode) {
e.preventDefault();
}
let privateWindowMenuItem = this._contextMenu.querySelector(
"#sidebar-history-context-open-in-private-window"
);
privateWindowMenuItem.hidden = !lazy.PrivateBrowsingUtils.enabled;
}
handleCommandEvent(e) {

View file

@ -4,6 +4,7 @@
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
SyncedTabsController: "resource:///modules/SyncedTabsController.sys.mjs",
});
@ -75,6 +76,11 @@ class SyncedTabsInSidebar extends SidebarPage {
);
// Enable the feature only if the device supports it
closeTabMenuItem.disabled = !this.triggerNode.canClose;
let privateWindowMenuItem = contextMenu.querySelector(
"#sidebar-synced-tabs-context-open-in-private-window"
);
privateWindowMenuItem.hidden = !lazy.PrivateBrowsingUtils.enabled;
}
handleCommandEvent(e) {

View file

@ -159,6 +159,9 @@ const DEFAULT_ACTIONS = {
l10nCommands: ["quickactions-cmd-print"],
label: "quickactions-print2",
icon: "chrome://global/skin/icons/print.svg",
isVisible: () => {
return Services.prefs.getBoolPref("print.enabled");
},
onPick: () => {
lazy.BrowserWindowTracker.getTopWindow()
.document.getElementById("cmd_print")
@ -193,6 +196,9 @@ const DEFAULT_ACTIONS = {
l10nCommands: ["quickactions-cmd-savepdf2"],
label: "quickactions-savepdf",
icon: "chrome://global/skin/icons/print.svg",
isVisible: () => {
return Services.prefs.getBoolPref("print.enabled");
},
onPick: () => {
// This writes over the users last used printer which we
// should not do. Refactor to launch the print preview with

View file

@ -82,11 +82,6 @@ export class AddonSuggestions extends SuggestProvider {
return null;
}
if (suggestion.source == "rust") {
suggestion.icon = suggestion.iconUrl;
delete suggestion.iconUrl;
}
// Set UTM params unless they're already defined. This allows remote
// settings or Merino to override them if need be.
let url = new URL(suggestion.url);
@ -100,6 +95,8 @@ export class AddonSuggestions extends SuggestProvider {
url: url.href,
originalUrl: suggestion.url,
shouldShowUrl: true,
// Rust uses `iconUrl` but Merino uses `icon`.
icon: suggestion.iconUrl ?? suggestion.icon,
title: suggestion.title,
description: suggestion.description,
bottomTextL10n: { id: "icecat-suggest-addons-recommended" },

View file

@ -943,8 +943,10 @@ class _QuickSuggestTestUtils {
source = "rust",
provider = "Yelp",
isTopPick = false,
// The default Yelp suggestedIndex is 0, unlike most other Suggest
// suggestion types, which use -1.
// The logic for the default Yelp `suggestedIndex` is complex and depends on
// whether `UrlbarProviderSearchSuggestions` is active and whether search
// suggestions are shown first. By default -- when the answer to both of
// those questions is Yes -- Yelp's `suggestedIndex` is 0.
suggestedIndex = 0,
isSuggestedIndexRelativeToGroup = true,
originalUrl = undefined,

View file

@ -263,10 +263,16 @@ async function doDismissOneTest({
"quicksuggest-dismissals-changed"
);
let actualResult = await getActualResult({
providers: [UrlbarProviderQuickSuggest.name],
query: queriesForDismissals[0].query,
expectedResult: result,
});
triggerCommand({
result,
command,
feature,
result: actualResult,
expectedCountsByCall: {
removeResult: 1,
},
@ -280,7 +286,7 @@ async function doDismissOneTest({
"canClearDismissedSuggestions should return true after triggering command"
);
Assert.ok(
await QuickSuggest.isResultDismissed(result),
await QuickSuggest.isResultDismissed(actualResult),
"The result should be dismissed"
);
@ -374,10 +380,16 @@ async function doDismissAllTest({ feature, result, command, pref, queries }) {
"quicksuggest-dismissals-changed"
);
let actualResult = await getActualResult({
providers: [UrlbarProviderQuickSuggest.name],
query: queries[0].query,
expectedResult: result,
});
triggerCommand({
result,
command,
feature,
result: actualResult,
expectedCountsByCall: {
removeResult: 1,
},
@ -442,6 +454,44 @@ async function doDismissAllTest({ feature, result, command, pref, queries }) {
}
}
/**
* Does a search, asserts an actual result exists that matches the given result,
* and returns it.
*
* @param {object} options
* Options object.
* @param {SuggestFeature} options.query
* The search string.
* @param {UrlbarResult} options.expectedResult
* The expected result.
* @param {string[]} [options.providers]
* The providers to query.
*/
async function getActualResult({
query,
expectedResult,
providers = [UrlbarProviderQuickSuggest.name],
}) {
info("Doing search to get an actual result: " + JSON.stringify(query));
let context = createContext(query, {
providers,
isPrivate: false,
});
await check_results({
context,
matches: [expectedResult],
});
let actualResult = context.results.find(
r =>
r.providerName == UrlbarProviderQuickSuggest.name &&
r.payload.provider == expectedResult.payload.provider
);
Assert.ok(actualResult, "Search should have returned a matching result");
return actualResult;
}
/**
* Does some "show less frequently" tests where the cap is set in remote
* settings and Nimbus. See `doOneShowLessFrequentlyTest()`. This function

View file

@ -34,6 +34,7 @@ ac_add_options --disable-geckodriver # Bug 1489320
ac_add_options --disable-update-agent # Bug 1561797
ac_add_options --disable-default-browser-agent # Relies on toast notifications which don't build on mingw.
ac_add_options --disable-notification-server # Toast notifications don't build on mingw.
ac_add_options --disable-zucchini # Bug 1975960: SEH unavailable in mingwclang on win32
# Find our toolchain
HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang"

View file

@ -34,6 +34,7 @@ ac_add_options --disable-geckodriver # Bug 1489320
ac_add_options --disable-update-agent # Bug 1561797
ac_add_options --disable-default-browser-agent # Relies on toast notifications which don't build on mingw.
ac_add_options --disable-notification-server # Toast notifications don't build on mingw.
ac_add_options --disable-zucchini # Bug 1975960: SEH unavailable in mingwclang on win32, disable on win64 for parity
# Find our toolchain
HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang"

View file

@ -1 +1 @@
140.3.1
140.7.0

View file

@ -1 +1 @@
140.3.1esr
140.7.0esr

View file

@ -13,5 +13,5 @@ MOZ_BRANDING_DIRECTORY=browser/branding/unofficial
MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
# IceCat settings
MOZ_APP_BASENAME=IceCat
MOZ_APP_VERSION=140.3.1
MOZ_APP_VERSION=140.7.0
MOZ_DATA_REPORTING=0

View file

@ -13,6 +13,7 @@ add_setup(async () => {
});
await setStorage(TEST_ADDRESS_1);
await setStorage(TEST_CREDIT_CARD_1);
registerCleanupFunction(async () => {
await removeAllRecords();
@ -101,7 +102,7 @@ add_task(
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.refillOnSiteClearingFields);
setTimeout(resolve, FormAutofill.refillOnSiteClearingFieldsTimeout);
});
return await SpecialPowers.spawn(
@ -116,3 +117,56 @@ add_task(
Assert.equal(orgaValue, "", "Element was not refilled");
}
);
add_task(async function address_field_not_refilled_after_reformat_by_site() {
const value = await BrowserTestUtils.withNewTab(
CREDITCARD_FORM_URL,
async browser => {
const selectorToTriggerAutocompletion = "#cc-number";
const elementValueToVerifyAutofill = TEST_CREDIT_CARD_1["cc-number"];
info("Triggering autocompletion.");
await openPopupOn(browser, selectorToTriggerAutocompletion);
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
await waitForAutofill(
browser,
selectorToTriggerAutocompletion,
elementValueToVerifyAutofill
);
const formatValue = TEST_CREDIT_CARD_1["cc-number"]
.replace(/(.{4})/g, "$1 ")
.trim();
await SpecialPowers.spawn(
browser,
[selectorToTriggerAutocompletion, formatValue],
async (ccNumberSelector, reformatValue) => {
const ccNumberInput =
content.document.querySelector(ccNumberSelector);
info("Simulating site reformats an input");
ccNumberInput.value = reformatValue;
}
);
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.refillOnSiteClearingFieldsTimeout);
});
return await SpecialPowers.spawn(
browser,
[selectorToTriggerAutocompletion],
async ccNumberSelector => {
return content.document.querySelector(ccNumberSelector).value;
}
);
}
);
const formatValue = TEST_CREDIT_CARD_1["cc-number"]
.replace(/(.{4})/g, "$1 ")
.trim();
Assert.equal(value, formatValue, "Element was not refilled");
});

View file

@ -3332,7 +3332,10 @@
"interventions": [
{
"platforms": ["all"],
"ua_string": ["Chrome", "add_IceCat_as_Gecko"]
"content_scripts": {
"js": ["bug1950282-f1tv.formula1.com-unblock-icecat.js"]
},
"ua_string": ["Chrome"]
},
{
"platforms": ["linux"],
@ -3695,5 +3698,32 @@
"ua_string": ["Chrome", "add_IceCat_as_Gecko"]
}
]
},
"1996823": {
"label": "rogers.com and fido.ca",
"bugs": {
"1996823": {
"issue": "page-fails-to-load",
"matches": [
"*://www.rogers.com/bbapp/bbapi.js*",
"*://www.fido.ca/bbapp/bbapi.js*"
]
}
},
"interventions": [
{
"platforms": ["all"],
"replace_string_in_request": [
{
"find": "window\\.location\\.href = link;",
"replace": "let url = new URL(window.location.href); url.hash = link; window.location.href = url.href;",
"urls": [
"*://www.rogers.com/bbapp/bbapi.js*",
"*://www.fido.ca/bbapp/bbapi.js*"
]
}
]
}
]
}
}

View file

@ -0,0 +1,122 @@
/* 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/. */
"use strict";
/**
* Bug 1950282 - UA spoof for f1tv.formula1.com
*
* This site is deliberately blocking IceCat, possibly due to bug 1992579.
*/
/* globals cloneInto, exportFunction */
console.info(
"The window environment is being altered for compatibility reasons. If you're a web developer working on this site, please get in touch with developer-outreach@mozilla.com. See https://bugzilla.mozilla.org/show_bug.cgi?id=1950282 for details."
);
delete window.wrappedJSObject.InstallTrigger;
delete window.wrappedJSObject.mozInnerScreenX;
delete window.wrappedJSObject.mozInnerScreenY;
delete window.wrappedJSObject.MozConsentBanner;
const nav = Object.getPrototypeOf(navigator.wrappedJSObject);
const vendor = Object.getOwnPropertyDescriptor(nav, "vendor");
vendor.get = exportFunction(() => "Google Inc.", window);
Object.defineProperty(nav, "vendor", vendor);
const css = CSS.wrappedJSObject;
const supports = Object.getOwnPropertyDescriptor(css, "supports");
const oldSupports = supports.value;
supports.value = exportFunction(function (query) {
if (query.includes("moz-")) {
return false;
}
return oldSupports.call(this, query);
}, window);
Object.defineProperty(css, "supports", supports);
function generateTimeStamp(base, factor = 10) {
if (base) {
// increase another timestamp by a little
return (base + Math.random() * factor).toString().substr(0, 14);
}
const r = Math.random().toString();
const d10 = `1${r.substr(5, 9)}`;
const d3 = r.substr(2, 3);
return parseFloat(`${d10}.${d3}`);
}
const startLoadTime = generateTimeStamp();
const commitLoadTime = generateTimeStamp(startLoadTime);
const firstPaintTime = generateTimeStamp(commitLoadTime);
const finishDocumentLoadTime = generateTimeStamp(firstPaintTime);
const finishLoadTime = generateTimeStamp(finishDocumentLoadTime);
const csi = cloneInto(
{
onloadT: parseInt(finishDocumentLoadTime * 100),
pageT: generateTimeStamp().toString().substr(-11),
startE: parseInt(parseFloat(startLoadTime * 100)),
tran: 10 + parseInt(4 + Math.random() * 4),
},
window
);
const loadTimes = cloneInto(
{
commitLoadTime,
connectionInfo: "h3",
finishDocumentLoadTime,
finishLoadTime,
firstPaintAfterLoadTime: 0,
firstPaintTime,
navigationType: "Other",
npnNegotiatedProtocol: "h3",
requestTime: startLoadTime,
startLoadTime,
wasAlternateProtocolAvailable: false,
wasFetchedViaSpdy: true,
wasNpnNegotiated: true,
},
window
);
window.wrappedJSObject.chrome = cloneInto(
{
app: {
InstallState: {
DISABLED: "disabled",
INSTALLED: "installed",
NOT_INSTALLED: "not_installed",
},
RunningState: {
CANNOT_RUN: "cannot_run",
READY_TO_RUN: "ready_to_run",
RUNNING: "running",
},
getDetails() {
return null;
},
getIsInstalled() {
return false;
},
installState() {
return undefined;
},
isInstalled: false,
runningState() {
return window.chrome.app.InstallState.NOT_INSTALLED;
},
},
csi() {
return csi;
},
loadTimes() {
return loadTimes;
},
},
window,
{ cloneFunctions: true }
);

View file

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Web Compatibility Interventions",
"description": "Urgent post-release fixes for web compatibility.",
"version": "140.8.0",
"version": "140.11.0",
"browser_specific_settings": {
"gecko": {
"id": "webcompat@mozilla.org",

View file

@ -0,0 +1,5 @@
# 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/.
perm-persistent-storage-remember = Remember this decision

View file

@ -135,6 +135,8 @@ policy-IceCatHome2 = Configure { -icecat-home-brand-name }.
policy-IceCatSuggest = Configure { -icecat-suggest-brand-name }.
policy-GenerativeAI = Configure generative AI features.
policy-GoToIntranetSiteForSingleWordEntryInAddressBar = Force direct intranet site navigation instead of searching when typing single word entries in the address bar.
policy-Handlers = Configure default application handlers.

View file

@ -17,7 +17,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"af": {
"pin": false,
@ -37,7 +37,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"an": {
"pin": false,
@ -57,7 +57,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ar": {
"pin": false,
@ -77,7 +77,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ast": {
"pin": false,
@ -97,7 +97,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"az": {
"pin": false,
@ -117,7 +117,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"be": {
"pin": false,
@ -137,7 +137,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"bg": {
"pin": false,
@ -157,7 +157,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"bn": {
"pin": false,
@ -177,7 +177,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"br": {
"pin": false,
@ -197,7 +197,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"bs": {
"pin": false,
@ -217,7 +217,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ca": {
"pin": false,
@ -237,7 +237,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ca-valencia": {
"pin": false,
@ -257,7 +257,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"cak": {
"pin": false,
@ -277,7 +277,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"cs": {
"pin": false,
@ -297,7 +297,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"cy": {
"pin": false,
@ -317,7 +317,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"da": {
"pin": false,
@ -337,7 +337,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"de": {
"pin": false,
@ -357,7 +357,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"dsb": {
"pin": false,
@ -377,7 +377,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"el": {
"pin": false,
@ -397,7 +397,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"en-CA": {
"pin": false,
@ -417,7 +417,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"en-GB": {
"pin": false,
@ -437,7 +437,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"eo": {
"pin": false,
@ -457,7 +457,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"es-AR": {
"pin": false,
@ -477,7 +477,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"es-CL": {
"pin": false,
@ -497,7 +497,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"es-ES": {
"pin": false,
@ -517,7 +517,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"es-MX": {
"pin": false,
@ -537,7 +537,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"et": {
"pin": false,
@ -557,7 +557,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"eu": {
"pin": false,
@ -577,7 +577,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"fa": {
"pin": false,
@ -597,7 +597,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ff": {
"pin": false,
@ -617,7 +617,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"fi": {
"pin": false,
@ -637,7 +637,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"fr": {
"pin": false,
@ -657,7 +657,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"fur": {
"pin": false,
@ -677,7 +677,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"fy-NL": {
"pin": false,
@ -697,7 +697,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ga-IE": {
"pin": false,
@ -717,7 +717,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"gd": {
"pin": false,
@ -737,7 +737,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"gl": {
"pin": false,
@ -757,7 +757,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"gn": {
"pin": false,
@ -777,7 +777,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"gu-IN": {
"pin": false,
@ -797,7 +797,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"he": {
"pin": false,
@ -817,7 +817,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"hi-IN": {
"pin": false,
@ -837,7 +837,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"hr": {
"pin": false,
@ -857,7 +857,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"hsb": {
"pin": false,
@ -877,7 +877,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"hu": {
"pin": false,
@ -897,7 +897,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"hy-AM": {
"pin": false,
@ -917,7 +917,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ia": {
"pin": false,
@ -937,7 +937,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"id": {
"pin": false,
@ -957,7 +957,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"is": {
"pin": false,
@ -977,7 +977,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"it": {
"pin": false,
@ -997,7 +997,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ja": {
"pin": false,
@ -1015,7 +1015,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ja-JP-mac": {
"pin": false,
@ -1023,7 +1023,7 @@
"macosx64",
"macosx64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ka": {
"pin": false,
@ -1043,7 +1043,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"kab": {
"pin": false,
@ -1063,7 +1063,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"kk": {
"pin": false,
@ -1083,7 +1083,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"km": {
"pin": false,
@ -1103,7 +1103,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"kn": {
"pin": false,
@ -1123,7 +1123,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ko": {
"pin": false,
@ -1143,7 +1143,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"lij": {
"pin": false,
@ -1163,7 +1163,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"lt": {
"pin": false,
@ -1183,7 +1183,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"lv": {
"pin": false,
@ -1203,7 +1203,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"mk": {
"pin": false,
@ -1223,7 +1223,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"mr": {
"pin": false,
@ -1243,7 +1243,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ms": {
"pin": false,
@ -1263,7 +1263,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"my": {
"pin": false,
@ -1283,7 +1283,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"nb-NO": {
"pin": false,
@ -1303,7 +1303,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ne-NP": {
"pin": false,
@ -1323,7 +1323,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"nl": {
"pin": false,
@ -1343,7 +1343,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"nn-NO": {
"pin": false,
@ -1363,7 +1363,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"oc": {
"pin": false,
@ -1383,7 +1383,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"pa-IN": {
"pin": false,
@ -1403,7 +1403,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"pl": {
"pin": false,
@ -1423,7 +1423,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"pt-BR": {
"pin": false,
@ -1443,7 +1443,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"pt-PT": {
"pin": false,
@ -1463,7 +1463,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"rm": {
"pin": false,
@ -1483,7 +1483,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ro": {
"pin": false,
@ -1503,7 +1503,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ru": {
"pin": false,
@ -1523,7 +1523,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sat": {
"pin": false,
@ -1543,7 +1543,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sc": {
"pin": false,
@ -1563,7 +1563,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sco": {
"pin": false,
@ -1583,7 +1583,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"si": {
"pin": false,
@ -1603,7 +1603,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sk": {
"pin": false,
@ -1623,7 +1623,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"skr": {
"pin": false,
@ -1643,7 +1643,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sl": {
"pin": false,
@ -1663,7 +1663,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"son": {
"pin": false,
@ -1683,7 +1683,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sq": {
"pin": false,
@ -1703,7 +1703,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sr": {
"pin": false,
@ -1723,7 +1723,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"sv-SE": {
"pin": false,
@ -1743,7 +1743,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"szl": {
"pin": false,
@ -1763,7 +1763,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ta": {
"pin": false,
@ -1783,7 +1783,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"te": {
"pin": false,
@ -1803,7 +1803,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"tg": {
"pin": false,
@ -1823,7 +1823,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"th": {
"pin": false,
@ -1843,7 +1843,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"tl": {
"pin": false,
@ -1863,7 +1863,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"tr": {
"pin": false,
@ -1883,7 +1883,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"trs": {
"pin": false,
@ -1903,7 +1903,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"uk": {
"pin": false,
@ -1923,7 +1923,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"ur": {
"pin": false,
@ -1943,7 +1943,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"uz": {
"pin": false,
@ -1963,7 +1963,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"vi": {
"pin": false,
@ -1983,7 +1983,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"xh": {
"pin": false,
@ -2003,7 +2003,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"zh-CN": {
"pin": false,
@ -2023,7 +2023,7 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
},
"zh-TW": {
"pin": false,
@ -2043,6 +2043,6 @@
"win64-aarch64-devedition",
"win64-devedition"
],
"revision": "64046fdc97c1b1886a479dead61e6dc5428ae6e6"
"revision": "412690f1368e37f70af57eecabb93497167eb9ba"
}
}

View file

@ -99,6 +99,10 @@ ChromeUtils.defineLazyGetter(lazy, "gBrowserBundle", function () {
);
});
ChromeUtils.defineLazyGetter(lazy, "gFluentStrings", function () {
return new Localization(["browser/permissions.ftl"], true /* aSync */);
});
import { SITEPERMS_ADDON_PROVIDER_PREF } from "resource://gre/modules/addons/siteperms-addon-utils.sys.mjs";
XPCOMUtils.defineLazyPreferenceGetter(
@ -1167,11 +1171,25 @@ class PersistentStoragePermissionPrompt extends PermissionPromptForRequest {
let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") +
"storage-permissions";
return {
let options = {
learnMoreURL,
displayURI: false,
name: this.getPrincipalName(),
};
options.checkbox = {
show: !lazy.PrivateBrowsingUtils.isWindowPrivate(
this.browser.ownerGlobal
),
};
if (options.checkbox.show) {
options.checkbox.label = lazy.gFluentStrings.formatValueSync(
"perm-persistent-storage-remember"
);
}
return options;
}
get notificationID() {

View file

@ -264,3 +264,46 @@ option(
)
set_config("MOZ_NOTIFICATION_SERVER", True, when="--enable-notification-server")
# Supported patch formats for the updater
# =======================================
@depends(target, when="--enable-updater")
def zucchini_is_available(target):
# Desktop Linux, macOS or Windows: we exclude Android by checking for GNU.
return (target.os, target.kernel) == ("GNU", "Linux") or target.os in (
"OSX",
"WINNT",
)
with only_when(~zucchini_is_available):
set_config("MOZ_BSPATCH", True, when="--enable-updater")
set_define("MOZ_BSPATCH", True, when="--enable-updater")
with only_when(zucchini_is_available):
option(
"--disable-bspatch",
help="Disable bspatch support",
)
set_config("MOZ_BSPATCH", True, when="--enable-bspatch")
set_define("MOZ_BSPATCH", True, when="--enable-bspatch")
option(
"--disable-zucchini",
help="Disable zucchini support",
)
set_config("MOZ_ZUCCHINI", True, when="--enable-zucchini")
set_define("MOZ_ZUCCHINI", True, when="--enable-zucchini")
@depends("--enable-bspatch", "--enable-zucchini")
def check_at_least_one_patch_format(bspatch, zucchini):
if not bspatch and not zucchini:
die(
"You must enable at least one patch format when --enable-updater "
"is used. Use --enable-bspatch or --enable-zucchini."
)

View file

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
140.3.1
140.7.0

View file

@ -845,6 +845,7 @@ system_headers = [
"sys/msg.h",
"sys/param.h",
"sys/pda.h",
"sys/platform/ppc.h",
"sys/poll.h",
"sys/ppc.h",
"sys/prctl.h",

View file

@ -1,3 +1,27 @@
icecat (140.7.0-1gnu1+build1-0.12.0) ecne; urgency=medium
* New upstream stable release (icecat-140.7.0-1gnu1)
-- Capitulo Mexicano de Software Libre <devel@cmxsl.org> Sat, 17 Jan 2026 21:13:41 -0600
icecat (140.6.0-1gnu1+build1-0.12.0) ecne; urgency=medium
* New upstream stable release (icecat-140.6.0-1gnu1)
-- Capitulo Mexicano de Software Libre <devel@cmxsl.org> Sun, 14 Dec 2025 03:53:59 -0600
icecat (140.5.0-2gnu1+build1-0.12.0) ecne; urgency=medium
* New upstream stable release (icecat-140.5.0-2gnu1)
-- Capitulo Mexicano de Software Libre <devel@cmxsl.org> Thu, 13 Nov 2025 03:42:08 -0600
icecat (140.4.0-2gnu1+build1-0.12.0) ecne; urgency=medium
* New upstream stable release (icecat-140.4.0-2gnu1)
-- Capitulo Mexicano de Software Libre <devel@cmxsl.org> Wed, 15 Oct 2025 02:20:36 -0600
icecat (140.3.1-1gnu1+build1-0.12.0) ecne; urgency=medium
* New upstream stable release (icecat-140.3.1-1gnu1)

View file

@ -26,17 +26,17 @@ add_task(async function () {
? [
{
menuItemId: "request-list-context-copy-as-curl-win",
data: buildTestData(QUOTE_WIN),
data: buildTestData(QUOTE_WIN, true),
},
{
menuItemId: "request-list-context-copy-as-curl-posix",
data: buildTestData(QUOTE_POSIX),
data: buildTestData(QUOTE_POSIX, false),
},
]
: [
{
menuItemId: "request-list-context-copy-as-curl",
data: buildTestData(QUOTE_POSIX),
data: buildTestData(QUOTE_POSIX, false),
},
];
@ -45,7 +45,7 @@ add_task(async function () {
await teardown(monitor);
});
function buildTestData(QUOTE) {
function buildTestData(QUOTE, isWin) {
// Quote a string, escape the quotes inside the string
function quote(str) {
return QUOTE + str.replace(new RegExp(QUOTE, "g"), `\\${QUOTE}`) + QUOTE;
@ -56,9 +56,11 @@ function buildTestData(QUOTE) {
return "-H " + quote(h);
}
const CMD = isWin ? "curl.exe " : "curl ";
// Construct the expected command
const SIMPLE_BASE = ["curl " + quote(HTTPS_SIMPLE_SJS)];
const SLOW_BASE = ["curl " + quote(HTTPS_SLOW_SJS)];
const SIMPLE_BASE = [CMD + quote(HTTPS_SIMPLE_SJS)];
const SLOW_BASE = [CMD + quote(HTTPS_SLOW_SJS)];
const BASE_RESULT = [
"--compressed",
header("User-Agent: " + navigator.userAgent),
@ -220,8 +222,9 @@ async function testForPlatform(tab, monitor, testData) {
// This monster regexp parses the command line into an array of arguments,
// recognizing quoted args with matching quotes and escaped quotes inside:
// [ "curl.exe 'url'", "--standalone-arg", "-arg-with-quoted-string 'value\'s'" ]
// [ "curl 'url'", "--standalone-arg", "-arg-with-quoted-string 'value\'s'" ]
const matchRe = /[-A-Za-z1-9]+(?: ([\^\\"']+)(?:\\\1|.)*?\1)?/g;
const matchRe = /[-\.A-Za-z1-9]+(?: ([\^\"']+)(?:\\\1|.)*?\1)?/g;
const actual = result.match(matchRe);
// Must begin with the same "curl 'URL'" segment

View file

@ -153,7 +153,7 @@ function testDataArgumentOnGeneratedCommand(data) {
}
function testDataEscapeOnGeneratedCommand(data) {
const paramsWin = `--data-raw ^"{\\"param1\\":\\"value1\\",\\"param2\\":\\"value2\\"}^"`;
const paramsWin = `--data-raw ^"^{^\\^"param1^\\^":^\\^"value1^\\^",^\\^"param2^\\^":^\\^"value2^\\^"^}^`;
const paramsPosix = `--data-raw '{"param1":"value1","param2":"value2"}'`;
let curlCommand = Curl.generateCommand(data, "WINNT");
@ -209,13 +209,13 @@ function testRemoveBinaryDataFromMultipartText(data) {
'^"',
boundary,
"^\u000A\u000A",
'Content-Disposition: form-data; name=\\"param1\\"',
'Content-Disposition: form-data; name=^\\^"param1^\\^"',
"^\u000A\u000A^\u000A\u000A",
"value1",
"^\u000A\u000A",
boundary,
"^\u000A\u000A",
'Content-Disposition: form-data; name=\\"file\\"; filename=\\"filename.png\\"',
'Content-Disposition: form-data; name=^\\^"file^\\^"; filename=^\\^"filename.png^\\^"',
"^\u000A\u000A",
"Content-Type: image/png",
"^\u000A\u000A^\u000A\u000A",
@ -269,7 +269,14 @@ function testEscapeStringPosix() {
const escapeChar = "'!ls:q:gs|ls|;ping 8.8.8.8;|";
is(
CurlUtils.escapeStringPosix(escapeChar),
"$'\\'\\041ls:q:gs^|ls^|;ping 8.8.8.8;^|'",
"$'\\'\\041ls:q:gs|ls|;ping 8.8.8.8;|'",
"'!' should be escaped."
);
const escapeBangOnlyChar = "!";
is(
CurlUtils.escapeStringPosix(escapeBangOnlyChar),
"$'\\041'",
"'!' should be escaped."
);
@ -295,49 +302,34 @@ function testEscapeStringPosix() {
"$'\\xc3\\xa6 \\xc3\\xb8 \\xc3\\xbc \\xc3\\x9f \\xc3\\xb6 \\xc3\\xa9'",
"Character codes outside of the decimal range 32 - 126 should be escaped."
);
// Assert that ampersands are correctly escaped in case its tried to run on Windows
const evilCommand = `query=evil\n\ncmd & calc.exe\n\n`;
is(
CurlUtils.escapeStringPosix(evilCommand),
"$'query=evil\\n\\ncmd ^& calc.exe\\n\\n'",
"The evil command is escaped properly"
);
const str = "EvilHeader: &calc.exe&";
is(
CurlUtils.escapeStringPosix(str),
"'EvilHeader: ^&calc.exe^&'",
"The evil command is escaped properly"
);
}
function testEscapeStringWin() {
const surroundedWithDoubleQuotes = "A simple string";
is(
CurlUtils.escapeStringWin(surroundedWithDoubleQuotes),
'^"A simple string^"',
'^\"A simple string^\"',
"The string should be surrounded with double quotes."
);
const doubleQuotes = 'Quote: "Time is an illusion. Lunchtime doubly so."';
is(
CurlUtils.escapeStringWin(doubleQuotes),
'^"Quote: \\"Time is an illusion. Lunchtime doubly so.\\"^"',
'^\"Quote: ^\\^\"Time is an illusion. Lunchtime doubly so.^\\^\"^\"',
"Double quotes should be escaped."
);
const percentSigns = "%TEMP% %@foo% %2XX% %_XX% %?XX%";
is(
CurlUtils.escapeStringWin(percentSigns),
'^"^%^TEMP^% ^%^@foo^% ^%^2XX^% ^%^_XX^% ^%?XX^%^"',
'^\"^%^TEMP^% ^%^@foo^% ^%^2XX^% ^%^_XX^% ^%?XX^%^\"',
"Percent signs should be escaped."
);
const backslashes = "\\A simple string\\";
is(
CurlUtils.escapeStringWin(backslashes),
'^"\\\\A simple string\\\\^"',
'^\"^\\A simple string^\\^\"',
"Backslashes should be escaped."
);
@ -351,23 +343,38 @@ function testEscapeStringWin() {
const dollarSignCommand = "$(calc.exe)";
is(
CurlUtils.escapeStringWin(dollarSignCommand),
'^"\\$(calc.exe)^"',
'^\"^$(calc.exe)^\"',
"Dollar sign should be escaped."
);
const tickSignCommand = "`$(calc.exe)";
is(
CurlUtils.escapeStringWin(tickSignCommand),
'^"\\`\\$(calc.exe)^"',
'^\"`^$(calc.exe)^\"',
"Both the tick and dollar signs should be escaped."
);
const evilCommand = `query=evil\r\rcmd" /c timeout /t 3 & calc.exe\r\r`;
is(
CurlUtils.escapeStringWin(evilCommand),
'^\"query=evil^\n\n^\n\ncmd\\\" /c timeout /t 3 & calc.exe^\n\n^\n\n^\"',
'^\"query=evil^\n\n^\n\ncmd^\\^\" /c timeout /t 3 ^& calc.exe^\n\n^\n\n^\"',
"The evil command is escaped properly"
);
// Control characters https://www.ascii-code.com/characters/control-characters
const containsControlChars = " - \u0007 \u0010 \u0014 \u001B \x1a - ";
is(
CurlUtils.escapeStringWin(containsControlChars),
'^\" - \u0007 \u0010 \u0014 \u001b \u001a - ^\"',
"Control characters should not be escaped with ^."
);
const controlCharsWithWhitespaces = " -\tcalc.exe\f- ";
is(
CurlUtils.escapeStringWin(controlCharsWithWhitespaces),
'^\" - calc.exe - ^\"',
"Control (non-printable) characters which are whitespace like charaters e.g (tab & form feed)"
);
}
async function createCurlData(selected, getLongString, requestData) {

View file

@ -160,16 +160,15 @@ const Curl = {
// Format with line breaks if the command has more than 2 parts
// e.g
// Command with 2 parts - curl https://foo.com
// Command with 2 parts - curl https://foo.com
// Commands with more than 2 parts -
// curl https://foo.com
// -X POST
// -H "Accept : */*"
// -H "accept-language: en-US"
const joinStr = currentPlatform === "WINNT" ? " ^\n " : " \\\n ";
return (
"curl " + commandParts.join(commandParts.length >= 3 ? joinStr : " ")
);
const CMD = currentPlatform == "WINNT" ? "curl.exe " : "curl ";
return CMD + commandParts.join(commandParts.length >= 3 ? joinStr : " ");
},
};
@ -421,10 +420,9 @@ const CurlUtils = {
return "\\u" + ("0000" + code).substr(code.length, 4);
}
// Escape & and |, which are special characters on Windows.
const winSpecialCharsRegEx = /([&\|])/g;
if (/[^\x20-\x7E]|\'/.test(str)) {
// Escape characters which are not within the charater range
// SPACE to "~"(char codes 32 - 126), the `!` (code 33) and '(code 39);
if (/[^\x20-\x7E]|!|\'/.test(str)) {
// Use ANSI-C quoting syntax.
return (
"$'" +
@ -434,14 +432,13 @@ const CurlUtils = {
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
.replace(/!/g, "\\041")
.replace(winSpecialCharsRegEx, "^$1")
.replace(/[^\x20-\x7E]/g, escapeCharacter) +
"'"
);
}
// Use single quote syntax.
return "'" + str.replace(winSpecialCharsRegEx, "^$1") + "'";
return "'" + str + "'";
},
/**
@ -453,24 +450,22 @@ const CurlUtils = {
Because cmd.exe parser and MS Crt arguments parsers use some of the
same escape characters, they can interact with each other in
horrible ways, the order of operations is critical.
Also see https://ss64.com/nt/syntax-esc.html for details on
escaping characters on Windows.
*/
const encapsChars = '^"';
return (
encapsChars +
str
// Replace \ with \\ first because it is an escape character for certain
// conditions in both parsers.
.replace(/\\/g, "\\\\")
// Escape double quotes with double slashes.
// Replace all " with \" to ensure the first parser does not remove it.
.replace(/"/g, '\\"')
// Escape ` and $ so commands do not get executed e.g $(calc.exe) or `\$(calc.exe)
.replace(/[`$]/g, "\\$&")
// Then escape all characters we are not sure about with ^ to ensure it
// gets to MS Crt parser safely.
.replace(/[^a-zA-Z0-9\s_\-:=+~\/.',?;()*\$&\\{}\"`]/g, "^$&")
// Note: Also do not escape unicode control (C) non-printable characters
// https://www.compart.com/en/unicode/category (this is captured with `\p{C}` and the `u` unicode flag)
.replace(/[^-a-zA-Z0-9\s_:=+~\/.',?;()*`\p{C}]/gu, "^$&")
// The % character is special because MS Crt parser will try and look for
// ENV variables and fill them in its place. We cannot escape them with %
@ -481,6 +476,14 @@ const CurlUtils = {
// by the previous replace.
.replace(/%(?=[a-zA-Z0-9_])/g, "%^")
// All other whitespace characters are replaced with a single space, as there
// is no way to enter their literal values in a command line, and they do break
// the command allowing for injection.
// Since want to keep line breaks, we need to exclude them in the regex (`[^\r\n]`),
// and use double negations to get the other whitespace chars (`[^\S]` translates
// to "not not whitespace")
.replace(/[^\S\r\n]/g, " ")
// Lastly we replace new lines with ^ and TWO new lines because the first
// new line is there to enact the escape command the second is the character
// to escape (in this case new line).

View file

@ -347,9 +347,7 @@ const QUOTE = isWin() ? '^"' : "'";
function quote(str) {
let escaped;
if (isWin()) {
escaped = str
.replace(new RegExp(QUOTE, "g"), `${QUOTE}${QUOTE}`)
.replace(/"/g, '\\"');
escaped = str.replace(new RegExp('"', "g"), `^\\${QUOTE}`);
} else {
escaped = str.replace(new RegExp(QUOTE, "g"), `\\${QUOTE}`);
}
@ -358,10 +356,10 @@ function quote(str) {
function escapeNewline(txt) {
if (isWin()) {
// Replace new lines with ^ and TWO new lines because the first
// For windows we replace new lines with ^ and TWO new lines because the first
// new line is there to enact the escape command the second is the character
// to escape (in this case new line).
return txt.replace(/\r?\n/g, "^\n\n");
return txt.replace(/\r?\n|\r/g, "^\n\n");
}
return txt.replace(/\r/g, "\\r").replace(/\n/g, "\\n");
}
@ -396,7 +394,8 @@ function inParams(curlParams, param) {
function parseCurl(curlCmd) {
// This monster regexp parses the command line into an array of arguments,
// recognizing quoted args with matching quotes and escaped quotes inside:
// [ "curl.exe 'url'", "--standalone-arg", "-arg-with-quoted-string 'value\'s'" ]
// [ "curl 'url'", "--standalone-arg", "-arg-with-quoted-string 'value\'s'" ]
const matchRe = /[-A-Za-z1-9]+(?: ([\^\\"']+)(?:\\\1|.)*?\1)?/g;
const matchRe = /[-\.A-Za-z1-9]+(?: ([\^\"']+)(?:\\\1|.)*?\1)?/g;
return curlCmd.match(matchRe);
}

View file

@ -45,8 +45,8 @@ class ChildProcessChannelListener final {
};
// TODO Backtrack.
nsTHashMap<nsUint64HashKey, Callback> mCallbacks;
nsTHashMap<nsUint64HashKey, CallbackArgs> mChannelArgs;
nsTHashMap<NoMemMoveKey<nsUint64HashKey>, Callback> mCallbacks;
nsTHashMap<NoMemMoveKey<nsUint64HashKey>, CallbackArgs> mChannelArgs;
};
} // namespace mozilla::dom

View file

@ -131,7 +131,7 @@ nsDSURIContentListener::DoContent(const nsACString& aContentType,
nsresult rv;
NS_ENSURE_ARG_POINTER(aContentHandler);
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
RefPtr<nsDocShell> docShell = mDocShell;
RefPtr<nsDocShell> docShell = mDocShell.get();
*aAbortProcess = false;

View file

@ -11,8 +11,9 @@
#include "nsIURIContentListener.h"
#include "nsWeakReference.h"
#include "nsITimer.h"
#include "mozilla/WeakPtr.h"
#include "nsDocShell.h"
class nsDocShell;
class nsIInterfaceRequestor;
class nsIWebNavigationInfo;
class nsPIDOMWindowOuter;
@ -85,7 +86,7 @@ class nsDSURIContentListener final : public nsIURIContentListener,
}
protected:
nsDocShell* mDocShell;
mozilla::MainThreadWeakPtr<nsDocShell> mDocShell;
// Hack to handle multipart images without creating a new viewer
nsCOMPtr<nsIStreamListener> mExistingJPEGStreamListener;
nsCOMPtr<nsIChannel> mExistingJPEGRequest;

View file

@ -17,7 +17,7 @@
using namespace mozilla;
using namespace mozilla::dom;
nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* aOwningDocShell)
nsDocShellEditorData::nsDocShellEditorData(nsDocShell* aOwningDocShell)
: mDocShell(aOwningDocShell),
mDetachedEditingState(Document::EditingState::eOff),
mMakeEditable(false),
@ -121,7 +121,7 @@ nsresult nsDocShellEditorData::DetachFromWindow() {
return NS_OK;
}
nsresult nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell) {
nsresult nsDocShellEditorData::ReattachToWindow(nsDocShell* aDocShell) {
mDocShell = aDocShell;
nsCOMPtr<nsPIDOMWindowOuter> domWindow =

View file

@ -12,8 +12,9 @@
#include "mozilla/RefPtr.h"
#include "mozilla/dom/Document.h"
#include "mozilla/WeakPtr.h"
#include "nsDocShell.h"
class nsIDocShell;
class nsEditingSession;
namespace mozilla {
@ -22,7 +23,7 @@ class HTMLEditor;
class nsDocShellEditorData {
public:
explicit nsDocShellEditorData(nsIDocShell* aOwningDocShell);
explicit nsDocShellEditorData(nsDocShell* aOwningDocShell);
~nsDocShellEditorData();
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult MakeEditable(bool aWaitForUriLoad);
@ -33,14 +34,14 @@ class nsDocShellEditorData {
SetHTMLEditor(mozilla::HTMLEditor* aHTMLEditor);
MOZ_CAN_RUN_SCRIPT_BOUNDARY void TearDownEditor();
nsresult DetachFromWindow();
nsresult ReattachToWindow(nsIDocShell* aDocShell);
nsresult ReattachToWindow(nsDocShell* aDocShell);
bool WaitingForLoad() const { return mMakeEditable; }
protected:
void EnsureEditingSession();
// The doc shell that owns us. Weak ref, since it always outlives us.
nsIDocShell* mDocShell;
mozilla::WeakPtr<nsDocShell> mDocShell;
// Only present for the content root docShell. Session is owned here.
RefPtr<nsEditingSession> mEditingSession;

View file

@ -276,6 +276,7 @@
#include "mozilla/gfx/ScaleFactor.h"
#include "mozilla/glean/DomMetrics.h"
#include "mozilla/glean/DomUseCounterMetrics.h"
#include "mozilla/intl/EncodingToLang.h"
#include "mozilla/intl/LocaleService.h"
#include "mozilla/ipc/IdleSchedulerChild.h"
#include "mozilla/ipc/MessageChannel.h"
@ -417,7 +418,6 @@
#include "nsIXULRuntime.h"
#include "nsImageLoadingContent.h"
#include "nsImportModule.h"
#include "nsLanguageAtomService.h"
#include "nsLayoutUtils.h"
#include "nsMimeTypes.h"
#include "nsNetCID.h"
@ -1500,6 +1500,7 @@ Document::Document(const char* aContentType)
mInteractiveWidgetMode(
InteractiveWidgetUtils::DefaultInteractiveWidgetMode()),
mHeaderData(nullptr),
mLanguageFromCharset(nullptr),
mServoRestyleRootDirtyBits(0),
mThrowOnDynamicMarkupInsertionCounter(0),
mIgnoreOpensDuringUnloadCounter(0),
@ -19746,7 +19747,7 @@ nsAtom* Document::GetLanguageForStyle() const {
if (nsAtom* lang = GetContentLanguageAsAtomForStyle()) {
return lang;
}
return mLanguageFromCharset.get();
return mLanguageFromCharset;
}
void Document::GetContentLanguageForBindings(DOMString& aString) const {
@ -19755,7 +19756,7 @@ void Document::GetContentLanguageForBindings(DOMString& aString) const {
const LangGroupFontPrefs* Document::GetFontPrefsForLang(
nsAtom* aLanguage, bool* aNeedsToCache) const {
nsAtom* lang = aLanguage ? aLanguage : mLanguageFromCharset.get();
nsAtom* lang = aLanguage ? aLanguage : mLanguageFromCharset;
return StaticPresData::Get()->GetFontPrefsForLang(lang, aNeedsToCache);
}
@ -19763,7 +19764,7 @@ void Document::DoCacheAllKnownLangPrefs() {
MOZ_ASSERT(mMayNeedFontPrefsUpdate);
RefPtr<nsAtom> lang = GetLanguageForStyle();
StaticPresData* data = StaticPresData::Get();
data->GetFontPrefsForLang(lang ? lang.get() : mLanguageFromCharset.get());
data->GetFontPrefsForLang(lang ? lang.get() : mLanguageFromCharset);
data->GetFontPrefsForLang(nsGkAtoms::x_math);
// https://bugzilla.mozilla.org/show_bug.cgi?id=1362599#c12
data->GetFontPrefsForLang(nsGkAtoms::Unicode);
@ -19774,29 +19775,14 @@ void Document::DoCacheAllKnownLangPrefs() {
}
void Document::RecomputeLanguageFromCharset() {
RefPtr<nsAtom> language;
// Optimize the default character sets.
if (mCharacterSet == WINDOWS_1252_ENCODING) {
language = nsGkAtoms::x_western;
} else {
nsLanguageAtomService* service = nsLanguageAtomService::GetService();
if (mCharacterSet == UTF_8_ENCODING) {
language = nsGkAtoms::Unicode;
} else {
language = service->LookupCharSet(mCharacterSet);
}
if (language == nsGkAtoms::Unicode) {
language = service->GetLocaleLanguage();
}
}
nsAtom* language = mozilla::intl::EncodingToLang::Lookup(mCharacterSet);
if (language == mLanguageFromCharset) {
return;
}
mMayNeedFontPrefsUpdate = true;
mLanguageFromCharset = std::move(language);
mLanguageFromCharset = language;
}
nsICookieJarSettings* Document::CookieJarSettings() {

View file

@ -5489,7 +5489,9 @@ class Document : public nsINode,
nsTHashSet<RefPtr<nsAtom>> mLanguagesUsed;
// TODO(emilio): Is this hot enough to warrant to be cached?
RefPtr<nsAtom> mLanguageFromCharset;
// EncodingToLang.cpp keeps the atom alive until shutdown, so
// no need for a RefPtr.
nsAtom* mLanguageFromCharset;
// Restyle root for servo's style system.
//

View file

@ -104,6 +104,10 @@ bool TimeoutManager::IsActive() const {
return true;
}
if (mIsChromeWorker) {
return true;
}
// Check if we're playing audio
if (mGlobalObject.IsPlayingAudio()) {
return true;
@ -322,7 +326,7 @@ TimeDuration TimeoutManager::CalculateDelay(Timeout* aTimeout) const {
TimeDuration result = aTimeout->mInterval;
if (aTimeout->mNestingLevel >=
StaticPrefs::dom_clamp_timeout_nesting_level()) {
StaticPrefs::dom_clamp_timeout_nesting_level() && !mIsChromeWorker) {
uint32_t minTimeoutValue = StaticPrefs::dom_min_timeout_value();
result = TimeDuration::Max(result,
TimeDuration::FromMilliseconds(minTimeoutValue));
@ -404,7 +408,7 @@ uint32_t TimeoutManager::sNestingLevel = 0;
TimeoutManager::TimeoutManager(nsIGlobalObject& aHandle,
uint32_t aMaxIdleDeferMS,
nsISerialEventTarget* aEventTarget)
nsISerialEventTarget* aEventTarget, bool aIsChromeWorker)
: mGlobalObject(aHandle),
mExecutor(new TimeoutExecutor(this, false, 0)),
mIdleExecutor(new TimeoutExecutor(this, true, aMaxIdleDeferMS)),
@ -425,7 +429,8 @@ TimeoutManager::TimeoutManager(nsIGlobalObject& aHandle,
mBudgetThrottleTimeouts(false),
mIsLoading(false),
mEventTarget(aEventTarget),
mIsWindow(aHandle.GetAsInnerWindow()) {
mIsWindow(aHandle.GetAsInnerWindow()),
mIsChromeWorker(aIsChromeWorker) {
MOZ_LOG(gTimeoutLog, LogLevel::Debug,
("TimeoutManager %p created, tracking bucketing %s\n", this,
StaticPrefs::privacy_trackingprotection_annotate_channels()

View file

@ -30,7 +30,8 @@ class TimeoutManager final {
public:
TimeoutManager(nsIGlobalObject& aHandle, uint32_t aMaxIdleDeferMS,
nsISerialEventTarget* aEventTarget);
nsISerialEventTarget* aEventTarget,
bool aIsChromeWorker = false);
~TimeoutManager();
TimeoutManager(const TimeoutManager& rhs) = delete;
void operator=(const TimeoutManager& rhs) = delete;
@ -270,6 +271,8 @@ class TimeoutManager final {
const bool mIsWindow;
const bool mIsChromeWorker;
uint32_t mNestingLevel{0};
static uint32_t sNestingLevel;

View file

@ -1948,7 +1948,8 @@ static JS::CompartmentIterResult FindSameOriginCompartment(
}
auto* compartmentPrivate = xpc::CompartmentPrivate::Get(aCompartment);
if (!compartmentPrivate->CanShareCompartmentWith(data->principal)) {
if (!compartmentPrivate ||
!compartmentPrivate->CanShareCompartmentWith(data->principal)) {
// Can't reuse this one, keep going.
return JS::CompartmentIterResult::KeepGoing;
}

View file

@ -54,6 +54,7 @@
#include "mozilla/dom/ImageTracker.h"
#include "mozilla/dom/PageLoadEventUtils.h"
#include "mozilla/dom/ReferrerInfo.h"
#include "mozilla/dom/ResponsiveImageSelector.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/intl/LocaleService.h"
#include "mozilla/intl/Locale.h"
@ -1275,18 +1276,100 @@ already_AddRefed<Promise> nsImageLoadingContent::RecognizeCurrentImageText(
return domPromise.forget();
}
CSSIntSize nsImageLoadingContent::NaturalSize(
DoDensityCorrection aDensityCorrection) {
if (!mCurrentRequest) {
return {};
}
nsCOMPtr<imgIContainer> image;
mCurrentRequest->GetImage(getter_AddRefs(image));
if (!image) {
return {};
}
mozilla::image::ImageIntrinsicSize intrinsicSize;
nsresult rv = image->GetIntrinsicSize(&intrinsicSize);
if (NS_FAILED(rv)) {
return {};
}
CSSIntSize size; // defaults to 0,0
if (!StaticPrefs::image_natural_size_fallback_enabled()) {
size.width = intrinsicSize.mWidth.valueOr(0);
size.height = intrinsicSize.mHeight.valueOr(0);
} else {
// Fallback case, for web-compatibility!
// See https://github.com/whatwg/html/issues/11287 and bug 1935269.
// If we lack an intrinsic size in either axis, then use the fallback size,
// unless we can transfer the size through the aspect ratio.
// (And if we *only* have an intrinsic aspect ratio, use the fallback width
// and transfer that through the aspect ratio to produce a height.)
size.width = intrinsicSize.mWidth.valueOr(kFallbackIntrinsicWidthInPixels);
size.height =
intrinsicSize.mHeight.valueOr(kFallbackIntrinsicHeightInPixels);
AspectRatio ratio = image->GetIntrinsicRatio();
if (ratio) {
if (!intrinsicSize.mHeight) {
// Compute the height from the width & ratio. (Note that the width we
// use here might be kFallbackIntrinsicWidthInPixels, and that's fine.)
size.height = ratio.Inverted().ApplyTo(size.width);
} else if (!intrinsicSize.mWidth) {
// Compute the width from the height & ratio.
size.width = ratio.ApplyTo(size.height);
}
}
}
ImageResolution resolution = image->GetResolution();
if (aDensityCorrection == DoDensityCorrection::Yes) {
// NOTE(emilio): What we implement here matches the image-set() spec, but
// it's unclear whether this is the right thing to do, see
// https://github.com/whatwg/html/pull/5574#issuecomment-826335244.
if (auto* image = HTMLImageElement::FromNode(AsContent())) {
if (auto* sel = image->GetResponsiveImageSelector()) {
float density = sel->GetSelectedImageDensity();
MOZ_ASSERT(density >= 0.0);
resolution.ScaleBy(density);
}
}
}
resolution.ApplyTo(size.width, size.height);
return size;
}
CSSIntSize nsImageLoadingContent::GetWidthHeightForImage() {
Element* element = AsContent()->AsElement();
if (nsIFrame* frame = element->GetPrimaryFrame(FlushType::Layout)) {
return CSSIntSize::FromAppUnitsRounded(frame->GetContentRect().Size());
}
const nsAttrValue* value;
CSSIntSize size;
nsCOMPtr<imgIContainer> image;
if (mCurrentRequest) {
if (StaticPrefs::image_natural_size_fallback_enabled()) {
// Our image is not rendered (we don't have any frame); so we should should
// return the natural size, per:
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-width
//
// Note that the spec says to use the "density-corrected natural width and
// height of the image", but we don't do that -- we specifically request
// the NaturalSize *without* density-correction here. This handles a case
// where browsers deviate from the spec in an interoperable way, which
// hopefully we'll address in the spec soon. See case (2) in this comment
// for more:
// https://github.com/whatwg/html/issues/11287#issuecomment-2923467541
size = NaturalSize(DoDensityCorrection::No);
} else if (mCurrentRequest) {
mCurrentRequest->GetImage(getter_AddRefs(image));
}
CSSIntSize size;
// If we have width or height attrs, we'll let those stomp on whatever
// NaturalSize we may have gotten above. This handles a case where browsers
// deviate from the spec in an interoperable way, which hopefully we'll
// address in the spec soon. See case (1) in this comment for more:
// https://github.com/whatwg/html/issues/11287#issuecomment-2923467541
const nsAttrValue* value;
if ((value = element->GetParsedAttr(nsGkAtoms::width)) &&
value->Type() == nsAttrValue::eInteger) {
size.width = value->GetIntegerValue();

View file

@ -239,6 +239,17 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
virtual mozilla::dom::FetchPriority GetFetchPriorityForImage() const;
/**
* Get the natural size of the current request, as defined here:
* https://html.spec.whatwg.org/multipage/images.html#preferred-density-corrected-dimensions
*
* By default, we return the density-corrected natural size, though we skip
* density-correction if DoDensityCorrection::No is passed.
*/
enum class DoDensityCorrection : bool { No, Yes };
mozilla::CSSIntSize NaturalSize(
DoDensityCorrection = DoDensityCorrection::Yes);
/**
* Get width and height of the current request, using given image request if
* attributes are unset.

View file

@ -701,7 +701,6 @@ nsObjectLoadingContent::UpdateObjectParameters() {
nsresult rv;
nsAutoCString newMime;
nsAutoString typeAttr;
nsCOMPtr<nsIURI> newURI;
nsCOMPtr<nsIURI> newBaseURI;
ObjectType newType;
@ -729,7 +728,6 @@ nsObjectLoadingContent::UpdateObjectParameters() {
el->HasNonEmptyAttr(nsGkAtoms::classid)) {
// We don't support class ID plugin references, so we should always treat
// having class Ids as attributes as invalid, and fallback accordingly.
newMime.Truncate();
stateInvalid = true;
}
@ -759,16 +757,6 @@ nsObjectLoadingContent::UpdateObjectParameters() {
newBaseURI = docBaseURI;
}
nsAutoString rawTypeAttr;
el->GetAttr(nsGkAtoms::type, rawTypeAttr);
if (!rawTypeAttr.IsEmpty()) {
typeAttr = rawTypeAttr;
nsAutoString params;
nsAutoString mime;
nsContentUtils::SplitMimeType(rawTypeAttr, mime, params);
CopyUTF16toUTF8(mime, newMime);
}
///
/// URI
///
@ -803,6 +791,41 @@ nsObjectLoadingContent::UpdateObjectParameters() {
}
}
///
/// type
///
nsAutoString rawTypeAttr;
el->GetAttr(nsGkAtoms::type, rawTypeAttr);
// YouTube embeds might be using type="application/x-shockwave-flash"
// which needs to be allowed, but must not override the text/html MIME set
// above.
if (!mRewrittenYoutubeEmbed && !rawTypeAttr.IsEmpty()) {
nsAutoString params;
nsAutoString mime;
nsContentUtils::SplitMimeType(rawTypeAttr, mime, params);
if (!StaticPrefs::dom_object_embed_type_hint_enabled()) {
NS_ConvertUTF16toUTF8 mimeUTF8(mime);
if (imgLoader::SupportImageWithMimeType(mimeUTF8)) {
// Normally the type attribute should not be used as a hint, but for
// images it does seem to happen in Chrome and Safari. Images generally
// don't lead to code execution and we don't use
// AcceptedMimeTypes::IMAGES_AND_DOCUMENTS above.
newMime = mimeUTF8;
} else if (GetTypeOfContent(mimeUTF8) != ObjectType::Document) {
LOG(
("OBJLC [%p]: MIME '%s' from type attribute is not supported, "
"forcing fallback.",
this, mimeUTF8.get()));
stateInvalid = true;
}
// Don't use the type attribute as a Content-Type hint in other cases.
} else {
CopyUTF16toUTF8(mime, newMime);
}
}
///
/// Check if the original (pre-channel) content-type or URI changed, and
/// record mOriginal{ContentType,URI}

View file

@ -2,18 +2,25 @@
support-files = [
"external_importMap.js",
"insert_a_base_element.js",
"module_1979050.mjs",
"module_simpleImportMap.mjs",
"module_simpleImportMap_dir.mjs",
"module_simpleImportMap_remap.mjs",
"module_simpleImportMap_remap_https.mjs",
"module_simpleExport.mjs",
"module_sortedImportMap.mjs",
"scope1/module_1979050.mjs",
"scope1/module_simpleExport.mjs",
"scope1/module_simpleImportMap.mjs",
"scope1/scope2/module_1979050.mjs",
"scope1/scope2/module_simpleExport.mjs",
"scope1/scope2/module_simpleImportMap.mjs",
]
["test_1979050.html"]
["test_1979050_2.html"]
["test_dynamic_import_reject_importMap.html"]
["test_externalImportMap.html"]

View file

@ -0,0 +1,3 @@
import { x } from "./module_simpleExport.mjs";
result = x;

View file

@ -0,0 +1,5 @@
import { x } from "./module_simpleExport.mjs";
result2 = x;
export let y = x;

View file

@ -0,0 +1,5 @@
import { x } from "./module_simpleExport.mjs";
result3 = x;
export let z = x;

View file

@ -0,0 +1,50 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test bug 1979050</title>
<script>
Object.prototype.imports = {
"./module_simpleExport.mjs": "./scope1/module_simpleExport.mjs",
};
Object.prototype.scopes = {
"chrome://mochitests/content/chrome/dom/base/test/jsmodules/importmaps/scope1/": {
"./scope1/module_simpleExport.mjs": "/content/chrome/dom/base/test/jsmodules/importmaps/module_simpleExport.mjs"
}
};
Object.prototype.integrity = {
"./scope1/scope2/module_simpleExport.mjs": "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
};
</script>
<script type="importmap">
{}
</script>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="module" src="module_1979050.mjs"></script>
<script type="module" src="./scope1/module_1979050.mjs"></script>
<script type="module" src="./scope1/scope2/module_1979050.mjs"></script>
<script>
var result, result2, result3;
SimpleTest.waitForExplicitFinish();
// eslint-disable-next-line no-unused-vars
function testLoaded() {
ok(result == 42, 'Check static imported value result: ' + result);
ok(result2 == 84, 'Check static imported value result2: ' + result2);
ok(result3 == 126, 'Check static imported value result3: ' + result3);
import("./module_simpleExport.mjs").then((ns) => {
ok(ns.x == 42, 'Check dynamic imported value result: ' + ns.x);
return import("./scope1/module_1979050.mjs");
}).then((ns) => {
ok(ns.y == 84, 'Check dynamic imported value ns.y: ' + ns.y);
return import("./scope1/scope2/module_1979050.mjs");
}).then((ns) => {
ok(ns.z == 126, 'Check dynamic imported value ns.z: ' + ns.z);
SimpleTest.finish();
});
}
</script>
<body onload='testLoaded()'></body>

View file

@ -0,0 +1,69 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test bug 1979050</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script>
Object.defineProperty(Object.prototype, "imports",
{
get() {
ok(false, "imports getter");
return {
"./module_simpleExport.mjs": "./scope1/module_simpleExport.mjs",
};
}
});
Object.defineProperty(Object.prototype, "scopes",
{
get() {
ok(false, "scopes getter");
return {
"chrome://mochitests/content/chrome/dom/base/test/jsmodules/importmaps/scope1/": {
"./scope1/module_simpleExport.mjs": "/content/chrome/dom/base/test/jsmodules/importmaps/module_simpleExport.mjs"
}
};
}
});
Object.defineProperty(Object.prototype, "integrity ",
{
get() {
ok(false, "scopes getter");
return {
"./scope1/scope2/module_simpleExport.mjs": "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
};
}
});
</script>
<script type="importmap">
{}
</script>
<script type="module" src="module_1979050.mjs"></script>
<script type="module" src="./scope1/module_1979050.mjs"></script>
<script type="module" src="./scope1/scope2/module_1979050.mjs"></script>
<script>
var result, result2, result3;
SimpleTest.waitForExplicitFinish();
// eslint-disable-next-line no-unused-vars
function testLoaded() {
ok(result == 42, 'Check static imported value result: ' + result);
ok(result2 == 84, 'Check static imported value result2: ' + result2);
ok(result3 == 126, 'Check static imported value result3: ' + result3);
import("./module_simpleExport.mjs").then((ns) => {
ok(ns.x == 42, 'Check dynamic imported value result: ' + ns.x);
return import("./scope1/module_1979050.mjs");
}).then((ns) => {
ok(ns.y == 84, 'Check dynamic imported value ns.y: ' + ns.y);
return import("./scope1/scope2/module_1979050.mjs");
}).then((ns) => {
ok(ns.z == 126, 'Check dynamic imported value ns.z: ' + ns.z);
SimpleTest.finish();
});
}
</script>
<body onload='testLoaded()'></body>

View file

@ -5503,20 +5503,20 @@ static Matrix ComputeRotationMatrix(gfxFloat aRotatedWidth,
// -
Maybe<layers::SurfaceDescriptor> ValidSurfaceDescriptorForRemoteCanvas2d(
const layers::SurfaceDescriptor& sdConst) {
auto sd = sdConst; // Copy, so we can mutate it.
if (sd.type() != layers::SurfaceDescriptor::TSurfaceDescriptorGPUVideo) {
return Nothing();
bool ValidSurfaceDescriptorForRemoteCanvas2d(
const layers::SurfaceDescriptor& aSd,
Maybe<layers::SurfaceDescriptor>* aResultSd) {
if (aSd.type() != layers::SurfaceDescriptor::TSurfaceDescriptorGPUVideo) {
return false;
}
auto& sdv = sd.get_SurfaceDescriptorGPUVideo();
const auto& sdv = aSd.get_SurfaceDescriptorGPUVideo();
if (sdv.type() !=
layers::SurfaceDescriptorGPUVideo::TSurfaceDescriptorRemoteDecoder) {
return Nothing();
return false;
}
auto& sdrd = sdv.get_SurfaceDescriptorRemoteDecoder();
auto& subdesc = sdrd.subdesc();
const auto& sdrd = sdv.get_SurfaceDescriptorRemoteDecoder();
const auto& subdesc = sdrd.subdesc();
switch (subdesc.type()) {
case layers::RemoteDecoderVideoSubDescriptor::Tnull_t:
break;
@ -5525,7 +5525,7 @@ Maybe<layers::SurfaceDescriptor> ValidSurfaceDescriptorForRemoteCanvas2d(
TSurfaceDescriptorMacIOSurface: {
const auto& ssd = subdesc.get_SurfaceDescriptorMacIOSurface();
if (ssd.gpuFence()) {
return Nothing();
return false;
}
break;
}
@ -5533,18 +5533,31 @@ Maybe<layers::SurfaceDescriptor> ValidSurfaceDescriptorForRemoteCanvas2d(
#ifdef XP_WIN
case layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorD3D10: {
if (!StaticPrefs::gfx_canvas_remote_use_draw_image_fast_path_d3d()) {
return Nothing();
return false;
}
auto& ssd = subdesc.get_SurfaceDescriptorD3D10();
ssd.handle() =
nullptr; // Not IPC-able, but it's just an optimization to have this.
break;
const auto& ssd = subdesc.get_SurfaceDescriptorD3D10();
if (aResultSd) {
*aResultSd = Some(aSd);
// Not IPC-able, but it's just an optimization to have this.
aResultSd->ref()
.get_SurfaceDescriptorGPUVideo()
.get_SurfaceDescriptorRemoteDecoder()
.subdesc()
.get_SurfaceDescriptorD3D10()
.handle() = nullptr;
} else if (ssd.handle()) {
return false;
}
return true;
}
#endif
default:
return Nothing();
return false;
}
return Some(sd);
if (aResultSd) {
*aResultSd = Some(aSd);
}
return true;
}
static Maybe<layers::SurfaceDescriptor>
@ -5558,9 +5571,13 @@ MaybeGetSurfaceDescriptorForRemoteCanvas(
return Nothing();
}
const auto sd = aResult.mLayersImage->GetDesc();
if (!sd) return Nothing();
return ValidSurfaceDescriptorForRemoteCanvas2d(*sd);
if (const auto sd = aResult.mLayersImage->GetDesc()) {
Maybe<layers::SurfaceDescriptor> result;
if (ValidSurfaceDescriptorForRemoteCanvas2d(*sd, &result)) {
return result;
}
}
return Nothing();
}
// drawImage(in HTMLImageElement image, in float dx, in float dy);

View file

@ -89,8 +89,9 @@ class CanvasRenderingContextHelper {
nsCOMPtr<nsICanvasRenderingContextInternal> mCurrentContext;
};
Maybe<layers::SurfaceDescriptor> ValidSurfaceDescriptorForRemoteCanvas2d(
const layers::SurfaceDescriptor&);
bool ValidSurfaceDescriptorForRemoteCanvas2d(
const layers::SurfaceDescriptor& aSd,
Maybe<layers::SurfaceDescriptor>* aResultSd = nullptr);
} // namespace dom
namespace CanvasUtils {

View file

@ -413,8 +413,14 @@ void SharedContextWebgl::ClearCachesIfNecessary() {
// not exceed the available texture limits and that shader creation succeeded.
bool DrawTargetWebgl::Init(const IntSize& size, const SurfaceFormat format,
const RefPtr<SharedContextWebgl>& aSharedContext) {
MOZ_ASSERT(format == SurfaceFormat::B8G8R8A8 ||
format == SurfaceFormat::B8G8R8X8);
switch (format) {
case SurfaceFormat::B8G8R8A8:
case SurfaceFormat::B8G8R8X8:
break;
default:
MOZ_ASSERT_UNREACHABLE("Unsupported format for DrawTargetWebgl.");
return false;
}
mSize = size;
mFormat = format;
@ -1775,6 +1781,10 @@ void DrawTargetWebgl::PushDeviceSpaceClipRects(const IntRect* aRects,
}
void DrawTargetWebgl::PopClip() {
if (mClipStack.empty()) {
return;
}
mClipChanged = true;
mRefreshClipState = true;
mSkia->PopClip();
@ -2022,10 +2032,29 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
const IntPoint& aDstOffset, bool aInit,
bool aZero,
const RefPtr<WebGLTexture>& aTex) {
webgl::TexUnpackBlobDesc texDesc = {
LOCAL_GL_TEXTURE_2D,
{uint32_t(aSrcRect.width), uint32_t(aSrcRect.height), 1}};
webgl::TexUnpackBlobDesc texDesc = {LOCAL_GL_TEXTURE_2D};
IntRect srcRect(aSrcRect);
IntPoint dstOffset(aDstOffset);
if (srcRect.IsEmpty()) {
return true;
}
if (aData) {
// If the source rect could not possibly overlap the surface, then it is
// effectively empty with nothing to upload.
srcRect = srcRect.SafeIntersect(IntRect(IntPoint(0, 0), aData->GetSize()));
if (srcRect.IsEmpty()) {
return true;
}
// If there is a non-empty rect remaining, then ensure the dest offset
// reflects the change in source rect.
dstOffset += srcRect.TopLeft() - aSrcRect.TopLeft();
// Ensure source data matches the expected format size.
int32_t bpp = BytesPerPixel(aFormat);
if (bpp != BytesPerPixel(aData->GetFormat())) {
return false;
}
// The surface needs to be uploaded to its backing texture either to
// initialize or update the texture handle contents. Map the data
// contents of the surface so it can be read.
@ -2034,13 +2063,11 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
return false;
}
int32_t stride = map.GetStride();
int32_t bpp = BytesPerPixel(aFormat);
// Get the data pointer range considering the sampling rect offset and
// size.
Span<const uint8_t> range(
map.GetData() + aSrcRect.y * size_t(stride) + aSrcRect.x * bpp,
std::max(aSrcRect.height - 1, 0) * size_t(stride) +
aSrcRect.width * bpp);
map.GetData() + srcRect.y * size_t(stride) + srcRect.x * bpp,
std::max(srcRect.height - 1, 0) * size_t(stride) + srcRect.width * bpp);
texDesc.cpuData = Some(range);
// If the stride happens to be 4 byte aligned, assume that is the
// desired alignment regardless of format (even A8). Otherwise, we
@ -2050,10 +2077,16 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
} else if (aZero) {
// Create a PBO filled with zero data to initialize the texture data and
// avoid slow initialization inside WebGL.
MOZ_ASSERT(aSrcRect.TopLeft() == IntPoint(0, 0));
size_t size =
size_t(GetAlignedStride<4>(aSrcRect.width, BytesPerPixel(aFormat))) *
aSrcRect.height;
if (srcRect.TopLeft() != IntPoint(0, 0)) {
MOZ_ASSERT_UNREACHABLE("Invalid origin for texture initialization.");
return false;
}
int32_t stride = GetAlignedStride<4>(srcRect.width, BytesPerPixel(aFormat));
if (stride <= 0) {
MOZ_ASSERT_UNREACHABLE("Invalid stride for texture initialization.");
return false;
}
size_t size = size_t(stride) * srcRect.height;
if (!mZeroBuffer || size > mZeroSize) {
ClearZeroBuffer();
mZeroBuffer = mWebgl->CreateBuffer();
@ -2069,6 +2102,7 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
}
texDesc.pboOffset = Some(0);
}
texDesc.size = uvec3(uint32_t(srcRect.width), uint32_t(srcRect.height), 1);
// Upload as RGBA8 to avoid swizzling during upload. Surfaces provide
// data as BGRA, but we manually swizzle that in the shader. An A8
// surface will be stored as an R8 texture that will also be swizzled
@ -2083,7 +2117,7 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, aTex);
}
mWebgl->TexImage(0, aInit ? intFormat : 0,
{uint32_t(aDstOffset.x), uint32_t(aDstOffset.y), 0}, texPI,
{uint32_t(dstOffset.x), uint32_t(dstOffset.y), 0}, texPI,
texDesc);
if (aTex) {
mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, mLastTexture);

View file

@ -438,8 +438,22 @@ struct QueueParamTraits<webgl::TexUnpackBlobDesc> {
!view.ReadParam(&stride)) {
return false;
}
const size_t dataSize = stride * surfSize.height;
const auto range = view.template ReadRange<uint8_t>(dataSize);
if (!CheckedInt32(stride).isValid() || surfSize.IsEmpty()) {
return false;
}
int32_t bpp = BytesPerPixel(format);
CheckedInt<size_t> minStride(bpp);
minStride *= surfSize.width;
if (!minStride.isValid() || minStride.value() <= 0 ||
stride < minStride.value()) {
return false;
}
CheckedInt<size_t> dataSize(stride);
dataSize *= surfSize.height;
if (!dataSize.isValid()) {
return false;
}
const auto range = view.template ReadRange<uint8_t>(dataSize.value());
if (!range) return false;
// DataSourceSurface demands pointer-to-mutable.

View file

@ -406,6 +406,21 @@ bool TexUnpackBlob::ConvertIfNeeded(
if (!rowLength || !rowCount) return true;
auto minSrcStride =
CheckedInt<size_t>(
WebGLTexelConversions::TexelBytesForFormat(srcFormat)) *
rowLength;
auto minDstStride =
CheckedInt<size_t>(
WebGLTexelConversions::TexelBytesForFormat(dstFormat)) *
rowLength;
if (srcStride <= 0 || dstStride <= 0 || !minSrcStride.isValid() ||
!minDstStride.isValid() || size_t(srcStride) < minSrcStride.value() ||
size_t(dstStride) < minDstStride.value()) {
webgl->ErrorInvalidOperation("Invalid stride.");
return false;
}
const auto srcIsPremult = (mDesc.srcAlphaType == gfxAlphaType::Premult);
auto dstIsPremult = unpacking.premultiplyAlpha;
const auto fnHasPremultMismatch = [&]() {
@ -997,9 +1012,20 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
const auto& data = sdb.data();
MOZ_ASSERT(data.type() == layers::MemoryOrShmem::TShmem);
const auto& shmem = data.get_Shmem();
surf = gfx::Factory::CreateWrappingDataSourceSurface(
shmem.get<uint8_t>(), layers::ImageDataSerializer::GetRGBStride(rgb),
size_t shmemSize = shmem.Size<uint8_t>();
int32_t stride = layers::ImageDataSerializer::GetRGBStride(rgb);
if (stride <= 0) {
gfxCriticalError() << "TexUnpackSurface failed to get rgb stride";
return false;
}
size_t bufSize = layers::ImageDataSerializer::ComputeRGBBufferSize(
rgb.size(), rgb.format());
if (!bufSize || bufSize > shmemSize) {
gfxCriticalError() << "TexUnpackSurface failed to get rgb buffer size";
return false;
}
surf = gfx::Factory::CreateWrappingDataSourceSurface(
shmem.get<uint8_t>(), stride, rgb.size(), rgb.format());
} else if (SDIsNullRemoteDecoder(sd)) {
const auto& sdrd = sd.get_SurfaceDescriptorGPUVideo()
.get_SurfaceDescriptorRemoteDecoder();
@ -1106,12 +1132,10 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
// -
const auto dstFormat = FormatForPackingInfo(dstPI);
const auto dstBpp = BytesPerPixel(dstPI);
const size_t dstBpp = BytesPerPixel(dstPI);
const size_t dstUsedBytesPerRow = dstBpp * surf->GetSize().width;
auto dstStride = dstUsedBytesPerRow;
if (dstFormat == srcFormat) {
dstStride = srcStride; // Try to match.
}
size_t dstStride = dstFormat == srcFormat ? srcStride // Try To match
: dstUsedBytesPerRow;
// -

View file

@ -1345,6 +1345,11 @@ template <typename SrcType, typename DstType>
MOZ_ALWAYS_INLINE void convertType(const SrcType* __restrict src,
DstType* __restrict dst) {
MOZ_ASSERT(false, "Unimplemented texture format conversion");
// Default construct dst values, ensuring they are *some* value.
dst[0] = DstType();
dst[1] = DstType();
dst[2] = DstType();
dst[3] = DstType();
}
template <>

View file

@ -6,6 +6,7 @@
#include "EventStateManager.h"
#include "mozilla/AppShutdown.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/Attributes.h"
#include "mozilla/EditorBase.h"
@ -302,7 +303,10 @@ NS_IMPL_ISUPPORTS(UITimerCallback, nsITimerCallback, nsINamed)
NS_IMETHODIMP
UITimerCallback::Notify(nsITimer* aTimer) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) return NS_ERROR_FAILURE;
// ObserverService shutdown happens after XPCOMShutdownThreads.
if (!obs || AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownThreads)) {
return NS_ERROR_FAILURE;
}
if ((gMouseOrKeyboardEventCounter == mPreviousCount) || !aTimer) {
gMouseOrKeyboardEventCounter = 0;
obs->NotifyObservers(nullptr, "user-interaction-inactive", nullptr);

View file

@ -10,6 +10,12 @@ support-files = ["simple_navigator_clipboard_keydown.html"]
run-if = ["os != 'win'"] # The popupmenus dismiss when access keys for disabled items are pressed on windows
skip-if = ["os == 'mac' && verify"]
["browser_navigator_clipboard_contextmenu_dismiss.js"]
support-files = [
"file_toplevel.html",
"file_iframe.html",
]
["browser_navigator_clipboard_contextmenu_suppression.js"]
support-files = [
"file_toplevel.html",

View file

@ -0,0 +1,64 @@
/* -*- Mode: JavaScript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
"use strict";
const kBaseUrlForContent = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
);
const kContentFileUrl = kBaseUrlForContent + "file_toplevel.html";
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js",
this
);
async function readText(aBrowser) {
return SpecialPowers.spawn(aBrowser, [], () => {
content.document.notifyUserGestureActivation();
content.eval(`navigator.clipboard.readText();`);
});
}
add_task(async function test_context_menu_dimiss_tab_navigate() {
await BrowserTestUtils.withNewTab(kContentFileUrl, async aBrowser => {
info(`Randomized text to avoid overlappings with other tests`);
await promiseWritingRandomTextToClipboard();
info(`Wait for paste context menu is shown`);
let pasteButtonIsShown = promisePasteButtonIsShown();
await readText(aBrowser);
await pasteButtonIsShown;
info("Navigate tab");
let pasteButtonIsHidden = promisePasteButtonIsHidden();
aBrowser.loadURI(Services.io.newURI("https://example.com/"), {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
info(`Wait for paste context menu is hidden`);
await pasteButtonIsHidden;
});
});
add_task(async function test_context_menu_dimiss_tab_reload() {
await BrowserTestUtils.withNewTab(kContentFileUrl, async aBrowser => {
info(`Randomized text to avoid overlappings with other tests`);
await promiseWritingRandomTextToClipboard();
info(`Wait for paste context menu is shown`);
let pasteButtonIsShown = promisePasteButtonIsShown();
await readText(aBrowser);
await pasteButtonIsShown;
info("Reload tab");
let pasteButtonIsHidden = promisePasteButtonIsHidden();
await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
info(`Wait for paste context menu is hidden`);
await pasteButtonIsHidden;
});
});

View file

@ -612,64 +612,6 @@ uint32_t HTMLImageElement::Height() { return GetWidthHeightForImage().height; }
uint32_t HTMLImageElement::Width() { return GetWidthHeightForImage().width; }
CSSIntSize HTMLImageElement::NaturalSize() {
if (!mCurrentRequest) {
return {};
}
nsCOMPtr<imgIContainer> image;
mCurrentRequest->GetImage(getter_AddRefs(image));
if (!image) {
return {};
}
mozilla::image::ImageIntrinsicSize intrinsicSize;
nsresult rv = image->GetIntrinsicSize(&intrinsicSize);
if (NS_FAILED(rv)) {
return {};
}
CSSIntSize size; // defaults to 0,0
if (!StaticPrefs::image_natural_size_fallback_enabled()) {
size.width = intrinsicSize.mWidth.valueOr(0);
size.height = intrinsicSize.mHeight.valueOr(0);
} else {
// Fallback case, for web-compatibility!
// See https://github.com/whatwg/html/issues/11287 and bug 1935269.
// If we lack an intrinsic size in either axis, then use the fallback size,
// unless we can transfer the size through the aspect ratio.
// (And if we *only* have an intrinsic aspect ratio, use the fallback width
// and transfer that through the aspect ratio to produce a height.)
size.width = intrinsicSize.mWidth.valueOr(kFallbackIntrinsicWidthInPixels);
size.height =
intrinsicSize.mHeight.valueOr(kFallbackIntrinsicHeightInPixels);
AspectRatio ratio = image->GetIntrinsicRatio();
if (ratio) {
if (!intrinsicSize.mHeight) {
// Compute the height from the width & ratio. (Note that the width we
// use here might be kFallbackIntrinsicWidthInPixels, and that's fine.)
size.height = ratio.Inverted().ApplyTo(size.width);
} else if (!intrinsicSize.mWidth) {
// Compute the width from the height & ratio.
size.width = ratio.ApplyTo(size.height);
}
}
}
ImageResolution resolution = image->GetResolution();
// NOTE(emilio): What we implement here matches the image-set() spec, but it's
// unclear whether this is the right thing to do, see
// https://github.com/whatwg/html/pull/5574#issuecomment-826335244.
if (mResponsiveSelector) {
float density = mResponsiveSelector->GetSelectedImageDensity();
MOZ_ASSERT(density >= 0.0);
resolution.ScaleBy(density);
}
resolution.ApplyTo(size.width, size.height);
return size;
}
nsresult HTMLImageElement::CopyInnerTo(HTMLImageElement* aDest) {
MOZ_TRY(nsGenericHTMLElement::CopyInnerTo(aDest));

View file

@ -94,7 +94,6 @@ class HTMLImageElement final : public nsGenericHTMLElement,
SetUnsignedIntAttr(nsGkAtoms::height, aHeight, 0, aError);
}
CSSIntSize NaturalSize();
uint32_t NaturalHeight() { return NaturalSize().height; }
uint32_t NaturalWidth() { return NaturalSize().width; }

View file

@ -2488,6 +2488,12 @@ void TextControlState::UnbindFromFrame(nsTextControlFrame* aFrame) {
DebugOnly<bool> ok = SetValue(value, ValueSetterOption::ByInternalAPI);
// TODO Find something better to do if this fails...
NS_WARNING_ASSERTION(ok, "SetValue() couldn't allocate memory");
// And mark the selection as dirty to make sure the selection will be
// restored properly in RestoreSelectionState. See bug 1993351.
if (IsSelectionCached()) {
SelectionProperties& props = GetSelectionProperties();
props.SetIsDirty();
}
}
}

View file

@ -740,27 +740,33 @@ nsresult HTMLContentSink::OpenBody() {
mCurrentContext->mStack[parentIndex].mContent;
int32_t numFlushed = mCurrentContext->mStack[parentIndex].mNumFlushed;
int32_t childCount = parent->GetChildCount();
NS_ASSERTION(numFlushed < childCount, "Already notified on the body?");
if (numFlushed < childCount) {
int32_t insertionPoint =
mCurrentContext->mStack[parentIndex].mInsertionPoint;
int32_t insertionPoint =
mCurrentContext->mStack[parentIndex].mInsertionPoint;
// XXX: I have yet to see a case where numFlushed is non-zero and
// insertionPoint is not -1, but this code will try to handle
// those cases too.
// XXX: I have yet to see a case where numFlushed is non-zero and
// insertionPoint is not -1, but this code will try to handle
// those cases too.
uint32_t oldUpdates = mUpdatesInNotification;
mUpdatesInNotification = 0;
if (insertionPoint != -1) {
NotifyInsert(parent, mBody);
uint32_t oldUpdates = mUpdatesInNotification;
mUpdatesInNotification = 0;
if (insertionPoint != -1) {
NotifyInsert(parent, mBody);
} else {
NotifyAppend(parent, numFlushed);
}
mCurrentContext->mStack[parentIndex].mNumFlushed = childCount;
if (mUpdatesInNotification > 1) {
UpdateChildCounts();
}
mUpdatesInNotification = oldUpdates;
} else {
NotifyAppend(parent, numFlushed);
MOZ_ASSERT(
false,
"This isn't supposed to happen but per bug 1782501 actually does "
"with the NoScript extension. Please debug if this assertion fails.");
mCurrentContext->mStack[parentIndex].mNumFlushed = childCount;
}
mCurrentContext->mStack[parentIndex].mNumFlushed = childCount;
if (mUpdatesInNotification > 1) {
UpdateChildCounts();
}
mUpdatesInNotification = oldUpdates;
}
StartLayout(false);

View file

@ -596,6 +596,10 @@ void nsHTMLDocument::NamedGetter(JSContext* aCx, const nsAString& aName,
aRv.NoteJSContextException(aCx);
return;
}
if (v.isNullOrUndefined()) {
return;
}
} else {
// Step 3. Otherwise, if elements has only one element, return that
// element.

View file

@ -3571,11 +3571,10 @@ MediaTrackGraphImpl* MediaTrackGraphImpl::GetInstance(
MOZ_ASSERT(aGraphDriverRequested != OFFLINE_THREAD_DRIVER,
"Use CreateNonRealtimeInstance() for offline graphs");
GraphHashSet* graphs = Graphs();
GraphHashSet::AddPtr addPtr =
graphs->lookupForAdd({aWindowID, aSampleRate, aPrimaryOutputDeviceID});
if (addPtr) { // graph already exists
return *addPtr;
MediaTrackGraphImpl* graph =
GetInstanceIfExists(aWindowID, aSampleRate, aPrimaryOutputDeviceID);
if (graph) { // graph already exists
return graph;
}
GraphRunType runType = DIRECT_DRIVER;
@ -3586,10 +3585,11 @@ MediaTrackGraphImpl* MediaTrackGraphImpl::GetInstance(
// In a real time graph, the number of output channels is determined by
// the underlying number of channel of the default audio output device.
uint32_t channelCount = CubebUtils::MaxNumberOfChannels();
MediaTrackGraphImpl* graph = new MediaTrackGraphImpl(
aWindowID, aSampleRate, aPrimaryOutputDeviceID, aMainThread);
graph = new MediaTrackGraphImpl(aWindowID, aSampleRate,
aPrimaryOutputDeviceID, aMainThread);
graph->Init(aGraphDriverRequested, runType, channelCount);
MOZ_ALWAYS_TRUE(graphs->add(addPtr, graph));
MOZ_ALWAYS_TRUE(Graphs()->putNew(
{aWindowID, aSampleRate, aPrimaryOutputDeviceID}, graph));
LOG(LogLevel::Debug, ("Starting up MediaTrackGraph %p for window 0x%" PRIx64,
graph, aWindowID));

View file

@ -657,13 +657,11 @@ void GMPParent::DeleteProcess() {
self->DeleteProcess();
},
[self](const ipc::ResponseRejectReason&) {
// We crashed during shutdown, ActorDestroy will perform cleanup.
GMP_LOG_DEBUG(
"GMPParent[%p|childPid=%d] DeleteProcess: Shutdown handshake "
"error.",
self.get(), self->mChildPid);
self->mState = GMPState::Closed;
self->Close();
self->DeleteProcess();
});
return;
}

View file

@ -256,7 +256,7 @@ void RDDProcessHost::DestroyProcess() {
void RDDProcessHost::ResolvePromise() {
MOZ_ASSERT(NS_IsMainThread());
if (!mLaunchPromiseSettled) {
if (mLaunchPromise && !mLaunchPromiseSettled) {
mLaunchPromise->Resolve(true, __func__);
mLaunchPromiseSettled = true;
}
@ -268,7 +268,7 @@ void RDDProcessHost::ResolvePromise() {
void RDDProcessHost::RejectPromise() {
MOZ_ASSERT(NS_IsMainThread());
if (!mLaunchPromiseSettled) {
if (mLaunchPromise && !mLaunchPromiseSettled) {
mLaunchPromise->Reject(NS_ERROR_FAILURE, __func__);
mLaunchPromiseSettled = true;
}

View file

@ -129,7 +129,8 @@ RefPtr<GenericNonExclusivePromise> RDDProcessManager::LaunchRDDProcess() {
__func__);
}
if (mLaunchRDDPromise && mProcess) {
if (mProcess) {
MOZ_DIAGNOSTIC_ASSERT(mLaunchRDDPromise);
return mLaunchRDDPromise;
}
@ -154,7 +155,7 @@ RefPtr<GenericNonExclusivePromise> RDDProcessManager::LaunchRDDProcess() {
NS_ERROR_NOT_AVAILABLE, __func__);
}
if (IsRDDProcessDestroyed()) {
if (NS_WARN_IF(!IsRDDProcessLaunching())) {
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
@ -219,14 +220,14 @@ auto RDDProcessManager::EnsureRDDProcessAndCreateBridge(
});
}
bool RDDProcessManager::IsRDDProcessLaunching() {
bool RDDProcessManager::IsRDDProcessLaunching() const {
MOZ_ASSERT(NS_IsMainThread());
return !!mProcess && !mRDDChild;
}
bool RDDProcessManager::IsRDDProcessDestroyed() const {
bool RDDProcessManager::IsRDDProcessAlive() const {
MOZ_ASSERT(NS_IsMainThread());
return !mRDDChild && !mProcess;
return mRDDChild && mRDDChild->CanSend() && mProcess;
}
void RDDProcessManager::OnProcessUnexpectedShutdown(RDDProcessHost* aHost) {
@ -261,14 +262,20 @@ void RDDProcessManager::NotifyRemoteActorDestroyed(
void RDDProcessManager::DestroyProcess() {
MOZ_ASSERT(NS_IsMainThread());
if (!mProcess) {
return;
}
mProcess->Shutdown();
mProcessToken = 0;
// Move onto the stack to ensure we don't re-enter from a chained promise
// rejection on the process shutdown.
RDDProcessHost* process = mProcess;
mProcess = nullptr;
process->Shutdown();
mProcessToken = 0;
mRDDChild = nullptr;
mLaunchRDDPromise = nullptr;
mQueuedPrefs.Clear();
CrashReporter::RecordAnnotationCString(
@ -280,7 +287,7 @@ bool RDDProcessManager::CreateContentBridge(
ipc::Endpoint<PRemoteDecoderManagerChild>* aOutRemoteDecoderManager) {
MOZ_ASSERT(NS_IsMainThread());
if (IsRDDProcessDestroyed()) {
if (NS_WARN_IF(!IsRDDProcessAlive())) {
MOZ_LOG(sPDMLog, LogLevel::Debug,
("RDD shutdown before creating content bridge"));
return false;
@ -310,6 +317,12 @@ bool RDDProcessManager::CreateVideoBridge() {
ipc::Endpoint<PVideoBridgeParent> parentPipe;
ipc::Endpoint<PVideoBridgeChild> childPipe;
if (NS_WARN_IF(!IsRDDProcessAlive())) {
MOZ_LOG(sPDMLog, LogLevel::Debug,
("RDD shutdown before creating video bridge"));
return false;
}
GPUProcessManager* gpuManager = GPUProcessManager::Get();
ipc::EndpointProcInfo gpuProcessInfo = gpuManager
? gpuManager->GPUEndpointProcInfo()

View file

@ -74,8 +74,8 @@ class RDDProcessManager final : public RDDProcessHost::Listener {
RefPtr<PRDDChild::TestTriggerMetricsPromise> TestTriggerMetrics();
private:
bool IsRDDProcessLaunching();
bool IsRDDProcessDestroyed() const;
bool IsRDDProcessLaunching() const;
bool IsRDDProcessAlive() const;
bool CreateVideoBridge();
// Called from our xpcom-shutdown observer.

View file

@ -1245,7 +1245,7 @@ already_AddRefed<mozilla::MediaByteBuffer> H265::ExtractHVCCExtraData(
// If we encounter SPS with the same id but different content, we will stop
// attempting to detect duplicates.
bool checkDuplicate = true;
const H265SPS* firstSPS = nullptr;
Maybe<uint8_t> firstSPSId;
RefPtr<mozilla::MediaByteBuffer> extradata = new mozilla::MediaByteBuffer;
while (reader.Remaining() > nalLenSize) {
@ -1305,8 +1305,8 @@ already_AddRefed<mozilla::MediaByteBuffer> H265::ExtractHVCCExtraData(
} else {
spsRefTable[spsId] = Some(sps);
nalusMap.LookupOrInsert(nalu.mNalUnitType).AppendElement(nalu);
if (!firstSPS) {
firstSPS = spsRefTable[spsId].ptr();
if (!firstSPSId) {
firstSPSId.emplace(spsId);
}
}
} else if (nalu.IsVPS() || nalu.IsPPS()) {
@ -1322,8 +1322,10 @@ already_AddRefed<mozilla::MediaByteBuffer> H265::ExtractHVCCExtraData(
spsEntry ? spsEntry.Data().Length() : 0,
vpsEntry ? vpsEntry.Data().Length() : 0,
ppsEntry ? ppsEntry.Data().Length() : 0);
if (firstSPS) {
if (firstSPSId) {
BitWriter writer(extradata);
const H265SPS* firstSPS = spsRefTable[*firstSPSId].ptr();
MOZ_ASSERT(firstSPS);
// ISO/IEC 14496-15, HEVCDecoderConfigurationRecord.
writer.WriteBits(1, 8); // version

View file

@ -336,7 +336,9 @@ void CallbackHelper::OnCaptureEnded() {
nsIEventTarget* target = mParent->GetBackgroundEventTarget();
MOZ_ALWAYS_SUCCEEDS(target->Dispatch(NS_NewRunnableFunction(
__func__, [&] { Unused << mParent->SendCaptureEnded(mStreamId); })));
__func__, [parent = RefPtr(mParent), id = mStreamId] {
Unused << parent->SendCaptureEnded(id);
})));
}
void CallbackHelper::OnFrame(const webrtc::VideoFrame& aVideoFrame) {

Some files were not shown because too many files have changed in this diff Show more