Update On Sun Apr 20 20:22:02 CEST 2025

This commit is contained in:
github-action[bot] 2025-04-20 20:22:02 +02:00
parent a4d062ffa7
commit 858786b3a9
514 changed files with 47320 additions and 25959 deletions

150
Cargo.lock generated
View file

@ -54,6 +54,12 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_log-sys"
version = "0.2.0"
@ -782,16 +788,17 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.19"
version = "0.4.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
dependencies = [
"libc",
"num-integer",
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"time 0.1.45",
"winapi",
"wasm-bindgen",
"windows-link",
]
[[package]]
@ -1082,6 +1089,60 @@ dependencies = [
"mach2",
]
[[package]]
name = "crash_helper_client"
version = "0.1.0"
dependencies = [
"anyhow",
"crash_helper_common",
"minidump-writer",
"nix 0.29.0",
"num-derive",
"num-traits",
"rust_minidump_writer_linux",
"windows-sys",
]
[[package]]
name = "crash_helper_common"
version = "0.1.0"
dependencies = [
"minidump-writer",
"nix 0.29.0",
"num-derive",
"num-traits",
"thiserror 2.0.9",
"windows-sys",
]
[[package]]
name = "crash_helper_server"
version = "0.1.0"
dependencies = [
"android_logger",
"anyhow",
"cc",
"cfg-if",
"crash_helper_common",
"dirs",
"env_logger",
"linked-hash-map",
"log",
"minidump-writer",
"mozannotation_server",
"mozbuild",
"mozilla-central-workspace-hack",
"nix 0.29.0",
"num-derive",
"num-traits",
"once_cell",
"rust_minidump_writer_linux",
"thiserror 2.0.9",
"uuid",
"windows-sys",
"yaml-rust",
]
[[package]]
name = "crashreporter"
version = "1.0.0"
@ -1752,6 +1813,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
dependencies = [
"log",
"regex",
"termcolor",
]
@ -1792,7 +1854,7 @@ dependencies = [
[[package]]
name = "error-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"error-support-macros",
"lazy_static",
@ -1804,7 +1866,7 @@ dependencies = [
[[package]]
name = "error-support-macros"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"proc-macro2",
"quote",
@ -1921,7 +1983,7 @@ dependencies = [
[[package]]
name = "firefox-versioning"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"serde_json",
"thiserror 1.999.999",
@ -2437,6 +2499,7 @@ dependencies = [
"cert_storage",
"chardetng_c",
"cose-c",
"crash_helper_client",
"crypto_hash",
"cubeb-coreaudio",
"cubeb-pulse",
@ -2973,6 +3036,30 @@ dependencies = [
"want",
]
[[package]]
name = "iana-time-zone"
version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "icu_calendar"
version = "1.5.2"
@ -3233,7 +3320,7 @@ dependencies = [
[[package]]
name = "interrupt-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"lazy_static",
"parking_lot",
@ -4261,19 +4348,15 @@ dependencies = [
[[package]]
name = "mozannotation_client"
version = "0.1.0"
dependencies = [
"nsstring",
]
[[package]]
name = "mozannotation_server"
version = "0.1.0"
dependencies = [
"memoffset 0.8.999",
"memoffset 0.9.0",
"mozannotation_client",
"process_reader",
"thin-vec",
"thiserror 1.999.999",
"thiserror 2.0.9",
]
[[package]]
@ -4435,9 +4518,9 @@ dependencies = [
name = "mozwer_s"
version = "0.1.0"
dependencies = [
"crash_helper_client",
"libc",
"mozilla-central-workspace-hack",
"process_reader",
"rust-ini",
"serde",
"serde_json",
@ -4685,6 +4768,7 @@ dependencies = [
"cfg-if",
"cfg_aliases",
"libc",
"memoffset 0.9.0",
]
[[package]]
@ -4944,7 +5028,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
[[package]]
name = "payload-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"serde",
"serde_derive",
@ -5186,7 +5270,7 @@ dependencies = [
"memoffset 0.9.0",
"mozilla-central-workspace-hack",
"scroll",
"thiserror 1.999.999",
"thiserror 2.0.9",
"windows-sys",
]
@ -5447,7 +5531,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "relevancy"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"anyhow",
"base64 0.21.999",
@ -5472,7 +5556,7 @@ dependencies = [
[[package]]
name = "remote_settings"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"anyhow",
"camino",
@ -5820,7 +5904,7 @@ dependencies = [
[[package]]
name = "search"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"error-support",
"firefox-versioning",
@ -6111,7 +6195,7 @@ dependencies = [
[[package]]
name = "sql-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"interrupt-support",
"lazy_static",
@ -6317,7 +6401,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "suggest"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"anyhow",
"chrono",
@ -6369,7 +6453,7 @@ dependencies = [
[[package]]
name = "sync-guid"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"base64 0.21.999",
"rand",
@ -6380,7 +6464,7 @@ dependencies = [
[[package]]
name = "sync15"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"anyhow",
"error-support",
@ -6420,7 +6504,7 @@ dependencies = [
[[package]]
name = "tabs"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"anyhow",
"error-support",
@ -6764,7 +6848,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "types"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"rusqlite 0.33.0",
"serde",
@ -7146,7 +7230,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "viaduct"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"ffi-support",
"log",
@ -7316,7 +7400,7 @@ dependencies = [
[[package]]
name = "webext-storage"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=6a007c98292fa72965d36389ce32d7609e399217#6a007c98292fa72965d36389ce32d7609e399217"
source = "git+https://github.com/mozilla/application-services?rev=e1b42aa3292a71e788bc0f95fb5ab5fbe533996f#e1b42aa3292a71e788bc0f95fb5ab5fbe533996f"
dependencies = [
"anyhow",
"error-support",
@ -7655,6 +7739,12 @@ dependencies = [
"syn",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-result"
version = "0.2.0"

View file

@ -18,9 +18,10 @@ members = [
"testing/geckodriver",
"toolkit/components/uniffi-bindgen-gecko-js",
"toolkit/crashreporter/client/app",
"toolkit/crashreporter/crash_helper_server",
"toolkit/crashreporter/crash_helper_client",
"toolkit/crashreporter/minidump-analyzer/android/export",
"toolkit/crashreporter/mozwer-rust",
"toolkit/crashreporter/rust_minidump_writer_linux",
"toolkit/library/gtest/rust",
"toolkit/library/rust/",
]
@ -259,14 +260,14 @@ malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
objc = { git = "https://github.com/glandium/rust-objc", rev = "4de89f5aa9851ceca4d40e7ac1e2759410c04324" }
# application-services overrides to make updating them all simpler.
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
search = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "6a007c98292fa72965d36389ce32d7609e399217" }
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
search = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "e1b42aa3292a71e788bc0f95fb5ab5fbe533996f" }
allocator-api2 = { path = "third_party/rust/allocator-api2" }

14
aclocal.m4 vendored
View file

@ -1,14 +0,0 @@
dnl
dnl Local autoconf macros used with mozilla
dnl The contents of this file are under the Public Domain.
dnl
builtin(include, build/autoconf/hooks.m4)dnl
builtin(include, build/autoconf/config.status.m4)dnl
builtin(include, build/autoconf/altoptions.m4)dnl
# Read the user's .mozconfig script. We can't do this in
# configure.in: autoconf puts the argument parsing code above anything
# expanded from configure.in, and we need to get the configure options
# from .mozconfig in place before that argument parsing code.
MOZ_READ_MOZCONFIG(.)

View file

@ -13,6 +13,9 @@
#if defined(MOZ_ASAN) || defined(MOZ_TSAN) || defined(FUZZING)
/llvm-symbolizer
#endif
#if defined(MOZ_CRASHREPORTER)
/crashhelper
#endif
/nmhproxy
/pingsender
/pk12util

View file

@ -0,0 +1,9 @@
/* 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/. */
#clearDataForSiteDialog::part(dialog-button) {
min-height: 24px;
align-items: center;
justify-content: center;
}

View file

@ -0,0 +1,35 @@
/* 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";
let lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
ForgetAboutSite: "resource://gre/modules/ForgetAboutSite.sys.mjs",
});
window.addEventListener("load", () => {
let retVals = window.arguments[0];
document.addEventListener("dialogaccept", e => {
e.preventDefault();
lazy.ForgetAboutSite.removeDataFromBaseDomain(retVals.host).catch(
console.error
);
window.close();
});
document.addEventListener("dialogcancel", e => {
e.preventDefault();
window.close();
});
document.l10n.setAttributes(
document.getElementById("clear-data-for-site-list"),
"clear-data-for-site-list",
{
site: retVals.hostOrBaseDomain,
}
);
});

View file

@ -0,0 +1,56 @@
<?xml version="1.0"?>
<!-- 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/. -->
<?csp default-src chrome: ?>
<window
id="clearDataForSiteDialogWindow"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
aria-describedby="infoTitle"
>
<dialog
id="clearDataForSiteDialog"
buttons="accept,cancel"
defaultButton="accept"
buttonidaccept="clear-data-for-site-dialog-accept-button"
buttonidcancel="clear-data-for-site-dialog-cancel-button"
>
<linkset>
<html:link rel="stylesheet" href="chrome://global/skin/global.css" />
<html:link
rel="stylesheet"
href="chrome://global/skin/commonDialog.css"
/>
<html:link
rel="stylesheet"
href="chrome://browser/content/places/clearDataForSite.css"
/>
<html:link rel="localization" href="browser/clearDataForSite.ftl" />
</linkset>
<div xmlns="http://www.w3.org/1999/xhtml" id="dialogGrid">
<h4 data-l10n-id="clear-data-for-site-title" id="infoTitle"></h4>
<!-- Use placeholder l10n arg "this site" so dialog height is calculated correctly
at dialog opening before l10n args are updated with actual site name in clearDataForSite.js -->
<p
data-l10n-id="clear-data-for-site-list"
data-l10n-args='{"site": "URL"}'
id="clear-data-for-site-list"
></p>
<ul>
<li data-l10n-id="clear-data-for-site-browsing-history"></li>
<li data-l10n-id="clear-data-for-site-cookies"></li>
<li data-l10n-id="clear-data-for-site-cache"></li>
<li data-l10n-id="cclear-data-for-site-permissions"></li>
</ul>
<p data-l10n-id="clear-data-for-site-exceptions"></p>
</div>
<script src="chrome://browser/content/places/clearDataForSite.js" />
</dialog>
</window>

View file

@ -1408,37 +1408,20 @@ PlacesController.prototype = {
} catch (e) {
// If there is no baseDomain we fall back to host
}
const [title, body, forget] = await document.l10n.formatValues([
{ id: "places-forget-about-this-site-confirmation-title" },
{
id: "places-forget-about-this-site-confirmation-msg",
args: { hostOrBaseDomain: baseDomain ?? host },
},
{ id: "places-forget-about-this-site-forget" },
]);
const flags =
Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
Services.prompt.BUTTON_POS_1_DEFAULT;
let bag = await Services.prompt.asyncConfirmEx(
window.browsingContext,
Services.prompt.MODAL_TYPE_INTERNAL_WINDOW,
title,
body,
flags,
forget,
null,
null,
null,
false
);
if (bag.getProperty("buttonNumClicked") !== 0) {
return;
let params = { host, hostOrBaseDomain: baseDomain ?? host };
if (window.gDialogBox) {
await window.gDialogBox.open(
"chrome://browser/content/places/clearDataForSite.xhtml",
params
);
} else {
await window.openDialog(
"chrome://browser/content/places/clearDataForSite.xhtml",
null,
"modal,centerscreen",
params
);
}
await this.ForgetAboutSite.removeDataFromBaseDomain(host);
},
showInFolder(aBookmarkGuid) {

View file

@ -20,6 +20,9 @@ browser.jar:
content/browser/places/historySidebar.js (content/historySidebar.js)
* content/browser/places/bookmarksSidebar.xhtml (content/bookmarksSidebar.xhtml)
content/browser/places/bookmarksSidebar.js (content/bookmarksSidebar.js)
content/browser/places/clearDataForSite.xhtml (content/clearDataForSite.xhtml)
content/browser/places/clearDataForSite.js (content/clearDataForSite.js)
content/browser/places/clearDataForSite.css (content/clearDataForSite.css)
content/browser/places/editBookmark.js (content/editBookmark.js)
content/browser/places/placesContextMenu.js (content/placesContextMenu.js)
content/browser/places/interactionsViewer.css (metadataViewer/interactionsViewer.css)

View file

@ -115,35 +115,28 @@ async function testForgetAboutThisSite(
return;
}
// Resolves once the confirmation prompt has been closed.
let promptPromise;
// Resolves once the confirmation dialog has been closed.
let dialogPromise;
// Cancel prompt via esc key. We have to get the prompt closed promise
// Cancel dialog via esc key. We have to get the dialog closed promise
// ourselves.
if (cancelConfirmWithEsc) {
promptPromise = PromptTestUtils.waitForPrompt(organizer, {
modalType: Services.prompt.MODAL_TYPE_WINDOW,
promptType: "confirmEx",
}).then(dialog => {
let dialogWindow = dialog.ui.prompt;
let dialogClosedPromise = BrowserTestUtils.waitForEvent(
dialogWindow.opener,
"DOMModalDialogClosed"
);
EventUtils.synthesizeKey("KEY_Escape", undefined, dialogWindow);
dialogPromise = BrowserTestUtils.promiseAlertDialogOpen(
null,
"chrome://browser/content/places/clearDataForSite.xhtml"
).then(dialog => {
let dialogClosedPromise = BrowserTestUtils.waitForEvent(dialog, "unload");
EventUtils.synthesizeKey("KEY_Escape", undefined, dialog);
return dialogClosedPromise;
});
} else {
// Close prompt via buttons. PromptTestUtils supplies the closed promise.
promptPromise = PromptTestUtils.handleNextPrompt(
organizer,
{ modalType: Services.prompt.MODAL_TYPE_WINDOW, promptType: "confirmEx" },
{ buttonNumClick: shouldForget ? 0 : 1 }
dialogPromise = BrowserTestUtils.promiseAlertDialog(
shouldForget ? "accept" : "cancel",
"chrome://browser/content/places/clearDataForSite.xhtml"
);
}
// If we cancel the prompt, create stubs to check that none of the clear
// If we cancel the dialog, create stubs to check that none of the clear
// methods are called.
if (!shouldForget) {
sinon.stub(ForgetAboutSite, "removeDataFromBaseDomain").resolves();
@ -158,8 +151,8 @@ async function testForgetAboutThisSite(
// Execute the delete command.
contextmenu.activateItem(forgetThisSite);
// Wait for prompt to be handled.
await promptPromise;
// Wait for dialog to be handled.
await dialogPromise;
// If we expect to remove items, wait the page-removed event to fire. If we
// don't wait, we may test the list before any items have been removed.

View file

@ -378,25 +378,31 @@ export class SidebarState {
set launcherDragActive(active) {
this.#props.launcherDragActive = active;
if (active) {
this.#launcherEl.toggleAttribute("customWidth", true);
if (
this.launcherExpanded &&
this.#controller.sidebarRevampVisibility === "expand-on-hover"
) {
// Temporarily disable expand on hover functionality while dragging
if (this.#controller.sidebarRevampVisibility === "expand-on-hover") {
this.#controller.toggleExpandOnHover(false);
}
this.#launcherEl.toggleAttribute("customWidth", true);
} else if (this.launcherWidth < LAUNCHER_MINIMUM_WIDTH) {
// Re-enable expand on hover if necessary
if (this.#controller.sidebarRevampVisibility === "expand-on-hover") {
this.#controller.toggleExpandOnHover(true, true);
}
// Snap back to collapsed state when the new width is too narrow.
this.launcherExpanded = false;
if (this.revampVisibility === "hide-sidebar") {
this.launcherVisible = false;
}
} else {
// Store the user-preferred launcher width.
this.expandedLauncherWidth = this.launcherWidth;
// Re-enable expand on hover if necessary
if (this.#controller.sidebarRevampVisibility === "expand-on-hover") {
this.#controller.toggleExpandOnHover(true, true);
}
// Store the user-preferred launcher width.
this.expandedLauncherWidth = this.launcherWidth;
}
const rootEl = this.#controllerGlobal.document.documentElement;
rootEl.toggleAttribute("sidebar-launcher-drag-active", active);

View file

@ -7,9 +7,9 @@ Sidebar
The new sidebar builds on existing legacy sidebar code treating ``browser-sidebar.js`` as a `SidebarController`. As part of the new sidebar and vertical tabs project, we've added new components including top-level system module `SidebarManager.sys.mjs` and a per window state manager, `SidebarState.sys.ms`. We've added new UI components that use a combination of moz components and custom lit components. The sidebar team maintains the existing synced tabs and history panels.
Introducing a new panel
~~~~~~~~~~~~~~~~~~~~~~~
-----------------------
Every panel that is registered and enabled in ``browser-sidebar.js``` and the ```toolsNameMap``` map will show as an option in the Customize Sidebar menu (which is a sidebar panel that contains settings).
Every panel that is registered and enabled in ``browser-sidebar.js``` and the ``toolsNameMap`` map will show as an option in the Customize Sidebar menu (which is a sidebar panel that contains settings).
The launcher is a container for tools (ie, icons that when clicked open or close the associated panel). Registering a panel - which should be behind a pref until it is ready to be introduced - does not automatically add a new icon to the launcher.
@ -20,3 +20,91 @@ If you only want to add this item if the pref governing visibility is true, you
In both cases, the tool will be introduced to the launcher one time (appended to a user's customized list of tools) and any customization after that (ie, removing it) takes precedence. If it's not removed, it will persist after that session.
If you only want to introduce a tool to new users, you can do so by adding it to the ``DEFAULT_LAUNCHER_TOOLS`` list in ``SidebarManager`` and the ``toolsNameMap``. You can do this even if you have previously introduced a tool via a pref branch migration as there is logic that will prevent a tool from being added twice, however the expectation is that when adding it to ``defaultTools`` the pref governing panel visibility is also enabled in-tree.
State Management
----------------
The sidebar includes a variety of options that users can customize, such as:
- Sidebar visibility (e.g., expand on hover, hide tabs and sidebar)
- Sidebar position (left or right)
- Tab strip orientation (vertical or horizontal)
- Available tools (which can be enabled or disabled)
These options are stored internally as preference values, meaning they persist across
browser windows. For example, if you have two windows open and move the sidebar to the
right in one of them, the other window's sidebar will also move to the right.
In addition to these preferences, there are also *state* values that depend on user
interaction, such as:
- Whether the launcher is expanded, collapsed, or hidden
- Which panel is currently open
- The width of the launcher and panel
These state values are usually stored in ``SessionStore``. However, if the user has
disabled session restore (e.g., via permanent private browsing mode), they are serialized
and stored under the ``sidebar.backupState`` preference instead.
State values are per-window and do not carry over between windows. For example, if you
load a panel in one window, other windows will not display that same panel.
SidebarState: Per-Window State
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``SidebarState`` tracks and updates sidebar-related UI state within a specific browser
window. It acts as the single source of truth for the sidebar's current state in that
window. In practice, it functions as a "reactive controller," handling user interactions,
maintaining internal state values, and determining the appropriate DOM updates.
When state values are changed, ``SidebarState`` immediately applies corresponding
adjustments to the UI. For example:
- When ``launcherVisible`` is set to ``false``, the launcher is hidden, and the sidebar's
inline padding is adjusted accordingly.
- When ``launcherWidth`` or ``panelWidth`` are updated, inline CSS is modified to ensure
that the sidebar does not occupy more than 75% of the browser's width.
SidebarManager: Global State
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``SidebarManager`` handles listening to preference values, global events, and loading the
"backup state" if necessary. When such handlers are triggered, ``SidebarManager`` delegates
tasks to each instance of ``SidebarController`` (a per-window module).
Use cases for ``SidebarManager`` include:
- Updating visibility preferences when the tab orientation changes.
- Managing the default set of tools for new sidebar users.
- Detecting when the sidebar button is removed from ``CustomizableUI``, thereby signaling
all ``SidebarController`` instances to close the sidebar if it is open.
.. note::
``SidebarManager`` should also be responsible for updating the customize panel when
preferences are changed from another source, but that is currently not the case. This
should be addressed in `Bug 1945530 <https://bugzil.la/1945530>`_.
Example Workflows
~~~~~~~~~~~~~~~~~
Per-Window State Change
^^^^^^^^^^^^^^^^^^^^^^^
Suppose a user clicks the toolbar button to show the sidebar. This is how the interaction
is handled:
1. ``SidebarController.handleToolbarButtonClick()`` is called, which sets ``state.launcherVisible``.
2. ``SidebarState`` calls the setter for ``launcherVisible``, removing the ``hidden``
attribute from the launcher element.
Global State Change
^^^^^^^^^^^^^^^^^^^
Suppose a user removes the toolbar button. Since ``CustomizableUI`` changes are synced
across windows, this is treated as a global state change. The interaction is handled as
follows:
1. ``CustomizableUI`` notifies listeners (including ``SidebarManager``) about a widget
removal.
2. ``SidebarManager.onWidgetRemoved()`` is called to handle the event.
3. ``onWidgetRemoved`` calls the ``hide()`` function on every ``SidebarController`` instance.

View file

@ -16,7 +16,6 @@ const { LightweightThemeConsumer } = ChromeUtils.importESModule(
);
ChromeUtils.defineESModuleGetters(lazy, {
BrowserUtils: "resource://gre/modules/BrowserUtils.sys.mjs",
ForgetAboutSite: "resource://gre/modules/ForgetAboutSite.sys.mjs",
PlacesUIUtils: "resource:///modules/PlacesUIUtils.sys.mjs",
});
@ -173,7 +172,6 @@ export class SidebarPage extends MozLitElement {
}
}
// TO DO: find a central place for this to live that's not PlacesController or here Bug 1954843
async forgetAboutThisSite() {
let host;
if (PlacesUtils.nodeIsHost(this.triggerNode)) {
@ -187,37 +185,10 @@ export class SidebarPage extends MozLitElement {
} catch (e) {
// If there is no baseDomain we fall back to host
}
const [title, body, forget] = await document.l10n.formatValues([
{ id: "places-forget-about-this-site-confirmation-title" },
{
id: "places-forget-about-this-site-confirmation-msg",
args: { hostOrBaseDomain: baseDomain ?? host },
},
{ id: "places-forget-about-this-site-forget" },
]);
const flags =
Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
Services.prompt.BUTTON_POS_1_DEFAULT;
let bag = await Services.prompt.asyncConfirmEx(
window.browsingContext,
Services.prompt.MODAL_TYPE_INTERNAL_WINDOW,
title,
body,
flags,
forget,
null,
null,
null,
false
await this.topWindow.gDialogBox.open(
"chrome://browser/content/places/clearDataForSite.xhtml",
{ host, hostOrBaseDomain: baseDomain ?? host }
);
if (bag.getProperty("buttonNumClicked") !== 0) {
return;
}
await lazy.ForgetAboutSite.removeDataFromBaseDomain(host);
}
/**

View file

@ -585,18 +585,45 @@ add_task(async function test_history_context_menu() {
is(window.gBrowser.currentURI.spec, rows[0].mainEl.href, "New tab opened");
info("Clear all data from website");
const promptPromise = PromptTestUtils.handleNextPrompt(
window.SidebarController.browser,
{ modalType: Services.prompt.MODAL_TYPE_WINDOW, promptType: "confirmEx" },
{ buttonNumClick: 0 }
let dialogOpened = BrowserTestUtils.promiseAlertDialogOpen(
null,
"chrome://browser/content/places/clearDataForSite.xhtml",
{ isSubDialog: true }
);
site = rows[0].mainEl.href;
const promiseForgotten = PlacesTestUtils.waitForNotification("page-removed");
await openAndWaitForContextMenu(contextMenu, rows[0].mainEl, () =>
contextMenu.activateItem(getItem("forget-site"))
);
await promptPromise;
await promiseForgotten;
let dialog = await dialogOpened;
let forgetSiteText = dialog.document.getElementById(
"clear-data-for-site-list"
);
let siteToForget = rows[0].mainEl.href.substring(
rows[0].mainEl.href.includes("https") ? 8 : 7,
rows[0].mainEl.href.length - 1
);
let siteForgottenIsCorrect;
await BrowserTestUtils.waitForMutationCondition(
forgetSiteText,
{ attributes: true, attributeFilter: ["data-l10n-args"] },
() => {
let text = JSON.parse(forgetSiteText.getAttribute("data-l10n-args")).site;
siteForgottenIsCorrect =
text.includes(siteToForget) || siteToForget.includes(text);
return siteForgottenIsCorrect;
}
);
ok(
siteForgottenIsCorrect,
"The text for forgetting a specific site should be set"
);
let dialogClosed = BrowserTestUtils.waitForEvent(dialog, "unload");
let removeButton = dialog.document
.querySelector("dialog")
.getButton("accept");
removeButton.click();
await Promise.all([dialogClosed, promiseForgotten]);
await TestUtils.waitForCondition(
() => rows[0].mainEl.href !== site,
"The forgotten entry should no longer be visible."

View file

@ -10,7 +10,10 @@ support-files = ["distribution.ini"]
["test_browserGlue_migration_no_errors.js"]
["test_browserGlue_migration_osauth.js"]
skip-if = ["nightly_build"]
skip-if = [
"nightly_build",
"os == 'linux' && os_version == '18.04' && processor == 'x86_64'",
]
["test_browserGlue_migration_places_xulstore.js"]

View file

@ -12,7 +12,7 @@ const REMOTE_SETTINGS_RECORDS = [
subjects: ["ramen"],
preModifiers: ["best"],
postModifiers: ["delivery"],
locationSigns: ["in"],
locationSigns: [{ keyword: "in", needLocation: true }],
yelpModifiers: [],
icon: "1234",
score: 0.5,

View file

@ -15,7 +15,10 @@ const REMOTE_SETTINGS_RECORDS = [
subjects: ["ramen", "ab", "alongerkeyword", "1234"],
preModifiers: ["best"],
postModifiers: ["delivery"],
locationSigns: ["in", "nearby"],
locationSigns: [
{ keyword: "in", needLocation: true },
{ keyword: "nearby", needLocation: false },
],
yelpModifiers: [],
icon: "1234",
score: 0.5,
@ -86,8 +89,8 @@ add_task(async function basic() {
description: "No specific location with location-modifier",
query: "ramen nearby",
expected: {
url: "https://www.yelp.com/search?find_desc=ramen&find_loc=Yokohama%2C+Kanagawa",
title: "ramen nearby Yokohama, Kanagawa",
url: "https://www.yelp.com/search?find_desc=ramen+nearby&find_loc=Yokohama%2C+Kanagawa",
title: "ramen nearby in Yokohama, Kanagawa",
},
},
{

View file

@ -19,7 +19,10 @@ const REMOTE_SETTINGS_RECORDS = [
subjects: ["coffee"],
preModifiers: [],
postModifiers: [],
locationSigns: ["in", "nearby"],
locationSigns: [
{ keyword: "in", needLocation: true },
{ keyword: "nearby", needLocation: false },
],
yelpModifiers: [],
icon: "1234",
score: 0.5,

View file

@ -1,7 +1,7 @@
. "$topsrcdir/browser/config/mozconfigs/linux32/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/aurora

View file

@ -3,7 +3,7 @@
ac_add_options --enable-debug-symbols=-gline-tables-only
# Add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
# ASan specific options on Linux
ac_add_options --enable-valgrind

View file

@ -1,7 +1,7 @@
. $topsrcdir/browser/config/mozconfigs/linux64/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View file

@ -1,5 +1,5 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
MOZ_AUTOMATION_CHECK=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_CHECK=0
. "$topsrcdir/build/unix/mozconfig.unix"

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
. "$topsrcdir/build/mozconfig.common"

View file

@ -1,7 +1,7 @@
. "$topsrcdir/browser/config/mozconfigs/linux64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/aurora

View file

@ -1,7 +1,7 @@
ac_add_options --enable-debug-symbols=-gline-tables-only
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
# ASan specific options on Linux
ac_add_options --enable-valgrind

View file

@ -1,7 +1,7 @@
ac_add_options --disable-optimize
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
# ASan specific options on Linux
ac_add_options --enable-valgrind

View file

@ -4,7 +4,7 @@
ac_add_options --enable-debug-symbols=-gline-tables-only
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
# ASan specific options on Linux
ac_add_options --enable-valgrind

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
. $topsrcdir/browser/config/mozconfigs/linux64/nightly

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_CHECK=0
export MOZ_AUTOMATION_CHECK=0
. $topsrcdir/browser/config/mozconfigs/linux64/nightly

View file

@ -1,7 +1,7 @@
. $topsrcdir/browser/config/mozconfigs/macosx64-aarch64/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/macosx64/debug"

View file

@ -1,7 +1,7 @@
. "$topsrcdir/browser/config/mozconfigs/macosx64-aarch64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --enable-instruments

View file

@ -1,7 +1,7 @@
. $topsrcdir/browser/config/mozconfigs/macosx64/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/macosx64/debug"

View file

@ -1,5 +1,5 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
MOZ_AUTOMATION_CHECK=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_CHECK=0
. $topsrcdir/build/macosx/mozconfig.common

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
. $topsrcdir/build/macosx/mozconfig.common

View file

@ -1,7 +1,7 @@
. "$topsrcdir/browser/config/mozconfigs/macosx64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --enable-instruments

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
. $topsrcdir/browser/config/mozconfigs/macosx64/nightly

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
. $topsrcdir/build/macosx/mozconfig.common

View file

@ -1,7 +1,7 @@
. $topsrcdir/browser/config/mozconfigs/win32/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
. "$topsrcdir/build/mozconfig.win-common"
. "$topsrcdir/browser/config/mozconfigs/common"

View file

@ -3,7 +3,7 @@
. "$topsrcdir/browser/config/mozconfigs/win32/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/aurora

View file

@ -36,15 +36,15 @@ ac_add_options --disable-default-browser-agent # Relies on toast notifications w
ac_add_options --disable-notification-server # Toast notifications don't build on mingw.
# Find our toolchain
HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang"
HOST_CXX="$MOZ_FETCHES_DIR/clang/bin/clang++"
CC="$MOZ_FETCHES_DIR/clang/bin/i686-w64-mingw32-clang"
CXX="$MOZ_FETCHES_DIR/clang/bin/i686-w64-mingw32-clang++"
CXXFLAGS="-fms-extensions"
CFLAGS="$CFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
CXXFLAGS="$CXXFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
CFLAGS="$CFLAGS -include _mingw.h"
CXXFLAGS="$CXXFLAGS -include _mingw.h"
export HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang"
export HOST_CXX="$MOZ_FETCHES_DIR/clang/bin/clang++"
export CC="$MOZ_FETCHES_DIR/clang/bin/i686-w64-mingw32-clang"
export CXX="$MOZ_FETCHES_DIR/clang/bin/i686-w64-mingw32-clang++"
export CXXFLAGS="-fms-extensions"
export CFLAGS="$CFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
export CXXFLAGS="$CXXFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
export CFLAGS="$CFLAGS -include _mingw.h"
export CXXFLAGS="$CXXFLAGS -include _mingw.h"
# We want to make sure we use binutils and other binaries in the tooltool
# package.

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/win32/debug"

View file

@ -3,7 +3,7 @@
. "$topsrcdir/browser/config/mozconfigs/win64-aarch64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/aurora

View file

@ -1,7 +1,7 @@
. $topsrcdir/browser/config/mozconfigs/win64/nightly
#add-on signing is checked but not enforced
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/unofficial
ac_add_options --enable-update-channel=default

View file

@ -1,5 +1,5 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
MOZ_AUTOMATION_CHECK=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_CHECK=0
. "$topsrcdir/build/mozconfig.win-common"
. "$topsrcdir/browser/config/mozconfigs/common"

View file

@ -3,7 +3,7 @@
. "$topsrcdir/browser/config/mozconfigs/win64/common-opt"
# Add-on signing is not required for DevEdition
MOZ_REQUIRE_SIGNING=
unset MOZ_REQUIRE_SIGNING
ac_add_options --with-branding=browser/branding/aurora

View file

@ -36,15 +36,15 @@ ac_add_options --disable-default-browser-agent # Relies on toast notifications w
ac_add_options --disable-notification-server # Toast notifications don't build on mingw.
# Find our toolchain
HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang"
HOST_CXX="$MOZ_FETCHES_DIR/clang/bin/clang++"
CC="$MOZ_FETCHES_DIR/clang/bin/x86_64-w64-mingw32-clang"
CXX="$MOZ_FETCHES_DIR/clang/bin/x86_64-w64-mingw32-clang++"
CXXFLAGS="-fms-extensions"
CFLAGS="$CFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
CXXFLAGS="$CXXFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
CFLAGS="$CFLAGS -include _mingw.h"
CXXFLAGS="$CXXFLAGS -include _mingw.h"
export HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang"
export HOST_CXX="$MOZ_FETCHES_DIR/clang/bin/clang++"
export CC="$MOZ_FETCHES_DIR/clang/bin/x86_64-w64-mingw32-clang"
export CXX="$MOZ_FETCHES_DIR/clang/bin/x86_64-w64-mingw32-clang++"
export CXXFLAGS="-fms-extensions"
export CFLAGS="$CFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
export CXXFLAGS="$CXXFLAGS -fcrash-diagnostics-dir=${UPLOAD_PATH}"
export CFLAGS="$CFLAGS -include _mingw.h"
export CXXFLAGS="$CXXFLAGS -include _mingw.h"
# We want to make sure we use binutils and other binaries in the tooltool
# package.

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
. $topsrcdir/browser/config/mozconfigs/win64/nightly

View file

@ -1,4 +1,4 @@
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
# Developers often build with these options for a better debugging experience.
. "$topsrcdir/browser/config/mozconfigs/win64/debug"

View file

@ -10,6 +10,7 @@ support-files = [
"../fixtures/dynamic_formless_fields_updated_due_to_node_mutations.html",
"../fixtures/dynamic_formless_fields_updated_due_to_visiblity_state_change.html",
"../fixtures/dynamic_form_changing_on_user_interaction.html",
"../fixtures/dynamic_form_replacing_all_fields.html",
"../fixtures/page_navigation.html",
"./empty.html",
"../fixtures/**",

View file

@ -196,6 +196,72 @@ add_task(
}
);
add_task(
async function address_fields_filled_in_form_after_all_fields_replaced() {
await BrowserTestUtils.withNewTab(
FORMS_REPLACING_ALL_FIELDS_ON_INPUT,
async browser => {
const selectorToTriggerAutocompletion = "#email-node-addition";
const elementValueToVerifyAutofill = TEST_ADDRESS_1.email;
info("Triggering autocompletion.");
await openPopupOn(browser, selectorToTriggerAutocompletion);
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
const filledOnFormChangePromise = TestUtils.topicObserved(
"formautofill-fill-after-form-change-complete"
);
await waitForAutofill(
browser,
selectorToTriggerAutocompletion,
elementValueToVerifyAutofill
);
info(
`Waiting for "formautofill-fill-after-form-change-complete" notification`
);
await filledOnFormChangePromise;
info("Verify new fields that replaced the old fields are autofilled");
const expectedAdditionalFieldsNotFilled = {
fields: [
{ fieldName: "name", autofill: "John R. Smith" },
{ fieldName: "email", autofill: TEST_ADDRESS_1.email },
{ fieldName: "tel", autofill: TEST_ADDRESS_1.tel },
{ fieldName: "country", autofill: TEST_ADDRESS_1.country },
{
fieldName: "street-address",
autofill: TEST_ADDRESS_1["street-address"].replace("\n", " "),
},
{
fieldName: "address-level1",
autofill: TEST_ADDRESS_1["address-level1"],
},
{
fieldName: "address-level2",
autofill: TEST_ADDRESS_1["address-level2"],
},
{
fieldName: "postal-code",
autofill: TEST_ADDRESS_1["postal-code"],
},
],
};
const actor =
browser.browsingContext.currentWindowGlobal.getActor("FormAutofill");
const section = Array.from(actor.sectionsByRootId.values()).flat()[0];
await verifyAutofillResult(
browser,
section,
expectedAdditionalFieldsNotFilled
);
}
);
}
);
/**
* Tests that additional fields are not filled when the form change was initiated
* by a user interaction that triggered a "click" event on the form.

View file

@ -154,14 +154,20 @@ async function checkFormChangeHappened(formId) {
0
);
const fieldDetectedAfterFieldMutations =
const fieldDetectedAfterRemovingField =
getFieldDetectionCompletedPromiseResolver();
// This is for checking the changes of element removed and added then.
removeInputField(browser, `#${formId} input[name=address-level2]`);
await fieldDetectedAfterRemovingField;
const fieldDetectedAfterAddingField =
getFieldDetectionCompletedPromiseResolver();
addInputField(browser, formId, "address-level2");
await fieldDetectedAfterFieldMutations;
await fieldDetectedAfterAddingField;
await openPopupOn(browser, `#${formId} input[name=address-level2]`);

View file

@ -1,5 +1,12 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { FormAutofill } = ChromeUtils.importESModule(
"resource://autofill/FormAutofill.sys.mjs"
);
const IFRAME_URL_PATH = BASE_URL + "autocomplete_iframe.html";
// Start by adding a few addresses to storage.
@ -38,8 +45,14 @@ add_task(async function test_iframe_autocomplete() {
// Highlight and select the second item in the list
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);
await expectWarningText(browser, "Also autofills organization, email");
EventUtils.synthesizeKey("VK_RETURN", {});
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.fillOnDynamicFormChangeTimeout);
});
let onLoaded = BrowserTestUtils.browserLoaded(browser, true);
await SpecialPowers.spawn(iframeBC, [], async function () {
await ContentTaskUtils.waitForCondition(() => {
@ -79,6 +92,11 @@ add_task(async function test_iframe_autocomplete() {
await waitForAutofill(iframeBC, "#tel", "+16172535702");
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.fillOnDynamicFormChangeTimeout);
});
// Open the dropdown and select the Clear Form item.
await openPopupOnSubframe(browser, iframeBC, "#street-address");
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);

View file

@ -1,5 +1,12 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { FormAutofill } = ChromeUtils.importESModule(
"resource://autofill/FormAutofill.sys.mjs"
);
add_task(async function test_save_doorhanger_shown_no_profile() {
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
@ -223,6 +230,11 @@ add_task(
TEST_CREDIT_CARD_1["cc-number"]
);
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.fillOnDynamicFormChangeTimeout);
});
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {
@ -284,6 +296,11 @@ add_task(
TEST_CREDIT_CARD_1["cc-number"]
);
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.fillOnDynamicFormChangeTimeout);
});
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {

View file

@ -49,6 +49,12 @@ add_task(async function test_submit_creditCard_update() {
}
await waitForAutofill(browser, "#cc-name", "John Doe");
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.fillOnDynamicFormChangeTimeout);
});
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {

View file

@ -2,6 +2,10 @@ const { TelemetryTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/TelemetryTestUtils.sys.mjs"
);
const { FormAutofill } = ChromeUtils.importESModule(
"resource://autofill/FormAutofill.sys.mjs"
);
const CC_NUM_USES_HISTOGRAM = "CREDITCARD_NUM_USES";
function ccFormArgsv2(method, extra) {
@ -189,6 +193,12 @@ async function openTabAndUseCreditCard(
await osKeyStoreLoginShown;
}
await waitForAutofill(browser, "#cc-number", creditCard["cc-number"]);
/* eslint-disable mozilla/no-arbitrary-setTimeout */
await new Promise(resolve => {
setTimeout(resolve, FormAutofill.fillOnDynamicFormChangeTimeout);
});
await focusUpdateSubmitForm(
browser,
{

View file

@ -86,6 +86,8 @@ const FORM_IFRAME_SANDBOXED_URL =
"https://example.org" + HTTP_TEST_PATH + "autocomplete_iframe_sandboxed.html";
const FORMS_WITH_DYNAMIC_FORM_CHANGE =
"https://example.org" + HTTP_TEST_PATH + "dynamic_forms.html";
const FORMS_REPLACING_ALL_FIELDS_ON_INPUT =
"https://example.org" + HTTP_TEST_PATH + "dynamic_forms.html";
const FORM_WITH_USER_INITIATED_FORM_CHANGE =
"https://example.org" +
HTTP_TEST_PATH +

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- Address form adding and removing nodes dynamically on user input -->
<form id="address-form-node-addition">
<label for="name-node-addition">Name</label>
<input type="text" id="name-node-addition" autocomplete="name">
<label for="email-node-addition">Email</label>
<input type="email" id="email-node-addition" autocomplete="email">
<label for="phone-node-addition">Phone</label>
<input type="tel" id="phone-node-addition" autocomplete="tel">
<label for="country-node-addition">Country</label>
<input type="text" id="country-node-addition" autocomplete="country">
<label for="street-address-node-addition">Street Address</label>
<input id="street-address-node-addition" type="text" autocomplete="street-address">
<label for="address-level1-node-addition">Address Level 1</label>
<input id="address-level1-node-addition" type="text" autocomplete="address-level1">
<label for="address-level2-node-addition">Address Level 2</label>
<input id="address-level2-node-addition" type="text" autocomplete="address-level2">
<label for="postal-code-node-addition">Postal Code</label>
<input id="postal-code-node-addition" type="text" autocomplete="postal-code">
</form>
<script>
const countryInputNodeAddition = document.getElementById("country-node-addition");
countryInputNodeAddition.addEventListener('input', () => {
const form = document.getElementById("address-form-node-addition");
const children = Array.from(form.children);
form.replaceChildren();
children.forEach((child, _) => {
// Alter the children to simulate fields replacement
const newChild = child.cloneNode(true);
newChild.id = newChild.id + "-after-form-change";
newChild.value = ""
form.append(newChild);
});
});
</script>
</html>

View file

@ -147,6 +147,7 @@ for (const type of [
"SAVE_SESSION_PERF_DATA",
"SAVE_TO_POCKET",
"SCREENSHOT_UPDATED",
"SECTION_DATA_UPDATE",
"SECTION_DEREGISTER",
"SECTION_DISABLE",
"SECTION_ENABLE",

View file

@ -106,6 +106,7 @@ export const INITIAL_STATE = {
visible: false,
data: {},
},
sectionData: {},
},
// Messages received from ASRouter to render in newtab
Messages: {
@ -938,6 +939,8 @@ function DiscoveryStream(prevState = INITIAL_STATE.DiscoveryStream, action) {
visible: false,
},
};
case at.SECTION_DATA_UPDATE:
return { ...prevState, sectionData: action.data };
default:
return prevState;
}

View file

@ -583,7 +583,7 @@ export class BaseContent extends React.PureComponent {
}
}
// eslint-disable-next-line max-statements
// eslint-disable-next-line max-statements, complexity
render() {
const { props } = this;
const { App, DiscoveryStream } = props;
@ -765,7 +765,10 @@ export class BaseContent extends React.PureComponent {
>
{mobileDownloadPromoEnabled && mobileDownloadPromoVariantABorC && (
<ErrorBoundary>
<DownloadModalToggle onClick={this.toggleDownloadHighlight} />
<DownloadModalToggle
isActive={this.state.showDownloadHighlight}
onClick={this.toggleDownloadHighlight}
/>
{this.state.showDownloadHighlight && (
<MessageWrapper
hiddenOverride={this.state.showDownloadHighlight}
@ -773,7 +776,8 @@ export class BaseContent extends React.PureComponent {
dispatch={this.props.dispatch}
>
<DownloadMobilePromoHighlight
position="inset-block-end inset-inline-start"
// Var B layout has the weather right-aligned
position={`${layoutsVariantBEnabled ? "inset-inline-start" : "inset-inline-end"} inset-block-end`}
dispatch={this.props.dispatch}
/>
</MessageWrapper>

View file

@ -4,31 +4,13 @@
import React, { useState, useCallback, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { actionCreators as ac } from "common/Actions.mjs";
import { actionCreators as ac, actionTypes as at } from "common/Actions.mjs";
// eslint-disable-next-line no-shadow
import { CSSTransition } from "react-transition-group";
const PREF_FOLLOWED_SECTIONS = "discoverystream.sections.following";
const PREF_BLOCKED_SECTIONS = "discoverystream.sections.blocked";
/**
* Transforms a comma-separated string of topics in user preferences
* into a cleaned-up array.
*
* @param pref
* @returns string[]
*/
// TODO: DRY Issue: Import function from CardSections.jsx?
const getTopics = pref => {
return pref
.split(",")
.map(item => item.trim())
.filter(item => item);
};
function SectionsMgmtPanel({ exitEventFired }) {
const [showPanel, setShowPanel] = useState(false); // State management with useState
const prefs = useSelector(state => state.Prefs.values);
const { sectionData } = useSelector(state => state.DiscoveryStream);
const layoutComponents = useSelector(
state => state.DiscoveryStream.layout[0].components
);
@ -50,45 +32,43 @@ function SectionsMgmtPanel({ exitEventFired }) {
sectionsList = sections[sectionsFeedName].data.sections;
}
const followedSectionsPref = prefs[PREF_FOLLOWED_SECTIONS] || "";
const blockedSectionsPref = prefs[PREF_BLOCKED_SECTIONS] || "";
const followedSections = getTopics(followedSectionsPref);
const blockedSections = getTopics(blockedSectionsPref);
const [sectionsState, setSectionState] = useState(sectionData); // State management with useState
const [followedSectionsState, setFollowedSectionsState] =
useState(followedSectionsPref); // State management with useState
const [blockedSectionsState, setBlockedSectionsState] =
useState(blockedSectionsPref); // State management with useState
let followedSectionsData = sectionsList.filter(item =>
followedSectionsState.includes(item.sectionKey)
let followedSectionsData = sectionsList.filter(
item => sectionsState[item.sectionKey]?.isFollowed
);
let blockedSectionsData = sectionsList.filter(item =>
blockedSectionsState.includes(item.sectionKey)
let blockedSectionsData = sectionsList.filter(
item => sectionsState[item.sectionKey]?.isBlocked
);
function updateCachedData() {
// Reset cached followed/blocked list data while panel is open
setFollowedSectionsState(followedSectionsPref);
setBlockedSectionsState(blockedSectionsPref);
setSectionState(sectionData);
followedSectionsData = sectionsList.filter(item =>
followedSectionsState.includes(item.sectionKey)
followedSectionsData = sectionsList.filter(
item => sectionsState[item.sectionKey]?.isFollowed
);
blockedSectionsData = sectionsList.filter(item =>
blockedSectionsState.includes(item.sectionKey)
blockedSectionsData = sectionsList.filter(
item => sectionsState[item.sectionKey]?.isBlocked
);
}
const onFollowClick = useCallback(
(sectionKey, receivedRank) => {
dispatch(
ac.SetPref(
PREF_FOLLOWED_SECTIONS,
[...followedSections, sectionKey].join(", ")
)
ac.AlsoToMain({
type: at.SECTION_DATA_UPDATE,
data: {
...sectionData,
[sectionKey]: {
isFollowed: true,
isBlocked: false,
followedAt: new Date().toISOString(),
},
},
})
);
// Telemetry Event Dispatch
dispatch(
@ -102,16 +82,22 @@ function SectionsMgmtPanel({ exitEventFired }) {
})
);
},
[dispatch, followedSections]
[dispatch, sectionData]
);
const onBlockClick = useCallback(
(sectionKey, receivedRank) => {
dispatch(
ac.SetPref(
PREF_BLOCKED_SECTIONS,
[...blockedSections, sectionKey].join(", ")
)
ac.AlsoToMain({
type: at.SECTION_DATA_UPDATE,
data: {
...sectionData,
[sectionKey]: {
isFollowed: false,
isBlocked: true,
},
},
})
);
// Telemetry Event Dispatch
@ -126,16 +112,18 @@ function SectionsMgmtPanel({ exitEventFired }) {
})
);
},
[dispatch, blockedSections]
[dispatch, sectionData]
);
const onUnblockClick = useCallback(
(sectionKey, receivedRank) => {
const updatedSectionData = { ...sectionData };
delete updatedSectionData[sectionKey];
dispatch(
ac.SetPref(
PREF_BLOCKED_SECTIONS,
[...blockedSections.filter(item => item !== sectionKey)].join(", ")
)
ac.AlsoToMain({
type: at.SECTION_DATA_UPDATE,
data: updatedSectionData,
})
);
// Telemetry Event Dispatch
dispatch(
@ -149,16 +137,18 @@ function SectionsMgmtPanel({ exitEventFired }) {
})
);
},
[dispatch, blockedSections]
[dispatch, sectionData]
);
const onUnfollowClick = useCallback(
(sectionKey, receivedRank) => {
const updatedSectionData = { ...sectionData };
delete updatedSectionData[sectionKey];
dispatch(
ac.SetPref(
PREF_FOLLOWED_SECTIONS,
[...followedSections.filter(item => item !== sectionKey)].join(", ")
)
ac.AlsoToMain({
type: at.SECTION_DATA_UPDATE,
data: updatedSectionData,
})
);
// Telemetry Event Dispatch
dispatch(
@ -172,7 +162,7 @@ function SectionsMgmtPanel({ exitEventFired }) {
})
);
},
[dispatch, followedSections]
[dispatch, sectionData]
);
// Close followed/blocked topic subpanel when parent menu is closed
@ -193,7 +183,7 @@ function SectionsMgmtPanel({ exitEventFired }) {
const followedSectionsList = followedSectionsData.map(
({ sectionKey, title, receivedRank }) => {
const following = followedSections.includes(sectionKey);
const following = sectionData[sectionKey]?.isFollowed;
return (
<li key={sectionKey}>
@ -235,7 +225,7 @@ function SectionsMgmtPanel({ exitEventFired }) {
const blockedSectionsList = blockedSectionsData.map(
({ sectionKey, title, receivedRank }) => {
const blocked = blockedSections.includes(sectionKey);
const blocked = sectionData[sectionKey]?.isBlocked;
return (
<li key={sectionKey}>

View file

@ -39,6 +39,10 @@ export function AdBannerContextMenu({
const [contextMenuClassNames, setContextMenuClassNames] =
useState("ads-context-menu");
// The keyboard access parameter is passed down to LinkMenu component
// that uses it to focus on the first context menu option for accessibility.
const [isKeyboardAccess, setIsKeyboardAccess] = useState(false);
/**
* Toggles the style fix for context menu hover/active styles.
* This allows us to have unobtrusive, transparent button background by default,
@ -54,11 +58,28 @@ export function AdBannerContextMenu({
}
};
const onClick = e => {
e.preventDefault();
/**
* Toggles the context menu to open or close. Sets state depending on whether
* the context menu is accessed by mouse or keyboard.
*
* @param isKeyBoard
*/
const toggleContextMenu = isKeyBoard => {
toggleContextMenuStyleSwitch(!showContextMenu);
setShowContextMenu(!showContextMenu);
setIsKeyboardAccess(isKeyBoard);
};
const onClick = e => {
e.preventDefault();
toggleContextMenu(false);
};
const onKeyDown = e => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
toggleContextMenu(true);
}
};
const onUpdate = () => {
@ -74,11 +95,13 @@ export function AdBannerContextMenu({
size="default"
iconsrc="chrome://global/skin/icons/more.svg"
onClick={onClick}
onKeyDown={onKeyDown}
/>
{showContextMenu && (
<LinkMenu
onUpdate={onUpdate}
dispatch={dispatch}
keyboardAccess={isKeyboardAccess}
options={ADBANNER_CONTEXT_MENU_OPTIONS}
shouldSendImpressionStats={true}
userEvent={ac.DiscoveryStreamUserEvent}

View file

@ -21,8 +21,6 @@ const PREF_SECTIONS_PERSONALIZATION_ENABLED =
"discoverystream.sections.personalization.enabled";
const PREF_TOPICS_ENABLED = "discoverystream.topicLabels.enabled";
const PREF_TOPICS_SELECTED = "discoverystream.topicSelection.selectedTopics";
const PREF_FOLLOWED_SECTIONS = "discoverystream.sections.following";
const PREF_BLOCKED_SECTIONS = "discoverystream.sections.blocked";
const PREF_TOPICS_AVAILABLE = "discoverystream.topicSelection.topics";
const PREF_THUMBS_UP_DOWN_ENABLED = "discoverystream.thumbsUpDown.enabled";
const PREF_INTEREST_PICKER_ENABLED =
@ -114,6 +112,7 @@ function CardSection({
ctaButtonSponsors,
}) {
const prefs = useSelector(state => state.Prefs.values);
const { sectionData } = useSelector(state => state.DiscoveryStream);
const showTopics = prefs[PREF_TOPICS_ENABLED];
const mayHaveSectionsCards = prefs[PREF_SECTIONS_CARDS_ENABLED];
const mayHaveSectionsCardsThumbsUpDown =
@ -121,8 +120,6 @@ function CardSection({
const mayHaveThumbsUpDown = prefs[PREF_THUMBS_UP_DOWN_ENABLED];
const selectedTopics = prefs[PREF_TOPICS_SELECTED];
const availableTopics = prefs[PREF_TOPICS_AVAILABLE];
const followedSectionsPref = prefs[PREF_FOLLOWED_SECTIONS] || "";
const blockedSectionsPref = prefs[PREF_BLOCKED_SECTIONS] || "";
const { saveToPocketCard } = useSelector(state => state.DiscoveryStream);
const mayHaveSectionsPersonalization =
@ -131,9 +128,7 @@ function CardSection({
const { sectionKey, title, subtitle } = section;
const { responsiveLayouts } = section.layout;
const followedSections = prefToArray(followedSectionsPref);
const following = followedSections.includes(sectionKey);
const blockedSections = prefToArray(blockedSectionsPref);
const following = sectionData[sectionKey]?.isFollowed;
const handleIntersection = useCallback(() => {
dispatch(
@ -156,11 +151,19 @@ function CardSection({
mayHaveSectionsCardsThumbsUpDown && mayHaveThumbsUpDown;
const onFollowClick = useCallback(() => {
const updatedSectionData = {
...sectionData,
[sectionKey]: {
isFollowed: true,
isBlocked: false,
followedAt: new Date().toISOString(),
},
};
dispatch(
ac.SetPref(
PREF_FOLLOWED_SECTIONS,
[...followedSections, sectionKey].join(", ")
)
ac.AlsoToMain({
type: at.SECTION_DATA_UPDATE,
data: updatedSectionData,
})
);
// Telemetry Event Dispatch
dispatch(
@ -173,15 +176,18 @@ function CardSection({
},
})
);
}, [dispatch, followedSections, sectionKey, sectionPosition]);
}, [dispatch, sectionData, sectionKey, sectionPosition]);
const onUnfollowClick = useCallback(() => {
const updatedSectionData = { ...sectionData };
delete updatedSectionData[sectionKey];
dispatch(
ac.SetPref(
PREF_FOLLOWED_SECTIONS,
[...followedSections.filter(item => item !== sectionKey)].join(", ")
)
ac.AlsoToMain({
type: at.SECTION_DATA_UPDATE,
data: updatedSectionData,
})
);
// Telemetry Event Dispatch
dispatch(
ac.OnlyToMain({
@ -193,7 +199,7 @@ function CardSection({
},
})
);
}, [dispatch, followedSections, sectionKey, sectionPosition]);
}, [dispatch, sectionData, sectionKey, sectionPosition]);
const { maxTile } = getMaxTiles(responsiveLayouts);
const displaySections = section.data.slice(0, maxTile);
@ -233,8 +239,7 @@ function CardSection({
dispatch={dispatch}
index={sectionPosition}
following={following}
followedSections={followedSections}
blockedSections={blockedSections}
sectionData={sectionData}
sectionKey={sectionKey}
title={title}
type={type}
@ -349,7 +354,7 @@ function CardSections({
ctaButtonSponsors,
}) {
const prefs = useSelector(state => state.Prefs.values);
const { spocs } = useSelector(state => state.DiscoveryStream);
const { spocs, sectionData } = useSelector(state => state.DiscoveryStream);
const personalizationEnabled = prefs[PREF_SECTIONS_PERSONALIZATION_ENABLED];
const interestPickerEnabled = prefs[PREF_INTEREST_PICKER_ENABLED];
@ -359,11 +364,10 @@ function CardSections({
}
const visibleSections = prefToArray(prefs[PREF_VISIBLE_SECTIONS]);
const blockedSections = prefToArray(prefs[PREF_BLOCKED_SECTIONS] || "");
const { interestPicker } = data;
let filteredSections = data.sections.filter(
section => !blockedSections.includes(section.sectionKey)
section => !sectionData[section.sectionKey]?.isBlocked
);
if (interestPickerEnabled && visibleSections.length) {

View file

@ -46,22 +46,22 @@
&.inset-block-end {
margin-top: var(--space-xxlarge);
}
&.inset-inline-end {
inset-inline-start: calc(var(--arrow-size) * -2);
&::after {
// inset-block-start: -12px;
// transform: rotate(225deg);
inset-inline-start: calc(var(--space-xxlarge) - 14px);
}
}
&.inset-inline-start {
// inset-inline-end: 0;
inset-inline-end: calc(calc(calc(var(--arrow-size) / 2) * -1) - 6px);
// inset-inline-end: calc(calc(var(--arrow-size) / 2) * -1);
&::after {
inset-inline-end: calc(var(--space-xxlarge) - 12px);
}
}
// Message Arrow Pointer

View file

@ -6,7 +6,6 @@ import React, { useState, useRef, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { actionCreators as ac, actionTypes as at } from "common/Actions.mjs";
import { useIntersectionObserver } from "../../../lib/utils";
const PREF_FOLLOWED_SECTIONS = "discoverystream.sections.following";
const PREF_VISIBLE_SECTIONS =
"discoverystream.sections.interestPicker.visibleSections";
@ -23,13 +22,10 @@ function InterestPicker({ title, subtitle, interests, receivedFeedRank }) {
const focusRef = useRef(null);
const [focusedIndex, setFocusedIndex] = useState(0);
const prefs = useSelector(state => state.Prefs.values);
const { sectionData } = useSelector(state => state.DiscoveryStream);
const visibleSections = prefs[PREF_VISIBLE_SECTIONS]?.split(",")
.map(item => item.trim())
.filter(item => item);
const following =
prefs[PREF_FOLLOWED_SECTIONS]?.split(",")
.map(item => item.trim())
.filter(item => item) || [];
const handleIntersection = useCallback(() => {
dispatch(
@ -80,11 +76,13 @@ function InterestPicker({ title, subtitle, interests, receivedFeedRank }) {
// by selecting them from the list
function handleChange(e, index) {
const { name: topic, checked } = e.target;
let updatedTopics = following;
let updatedSections = { ...sectionData };
if (checked) {
updatedTopics = updatedTopics.length
? [...updatedTopics, topic]
: [topic];
updatedSections[topic] = {
isFollowed: true,
isBlocked: false,
followedAt: new Date().toISOString(),
};
if (!visibleSections.includes(topic)) {
// add section to visible sections and place after the inline picker
// subtract 1 from the rank so that it is normalized with array index
@ -92,7 +90,7 @@ function InterestPicker({ title, subtitle, interests, receivedFeedRank }) {
dispatch(ac.SetPref(PREF_VISIBLE_SECTIONS, visibleSections.join(", ")));
}
} else {
updatedTopics = updatedTopics.filter(t => t !== topic);
delete updatedSections[topic];
}
dispatch(
ac.OnlyToMain({
@ -105,7 +103,9 @@ function InterestPicker({ title, subtitle, interests, receivedFeedRank }) {
},
})
);
dispatch(ac.SetPref(PREF_FOLLOWED_SECTIONS, updatedTopics.join(", ")));
dispatch(
ac.AlsoToMain({ type: at.SECTION_DATA_UPDATE, data: updatedSections })
);
}
return (
<section
@ -127,7 +127,7 @@ function InterestPicker({ title, subtitle, interests, receivedFeedRank }) {
ref={focusRef}
>
{interests.map((interest, index) => {
const checked = following.includes(interest.sectionId);
const checked = sectionData[interest.sectionId]?.isFollowed;
return (
<li
key={interest.sectionId}

View file

@ -19,8 +19,7 @@ export function SectionContextMenu({
dispatch,
sectionKey,
following,
followedSections,
blockedSections,
sectionData,
sectionPosition,
}) {
// Initial context menu options: block this section only.
@ -58,8 +57,7 @@ export function SectionContextMenu({
options={SECTIONS_CONTEXT_MENU_OPTIONS}
shouldSendImpressionStats={true}
site={{
followedSections,
blockedSections,
sectionData,
sectionKey,
sectionPosition,
title,

View file

@ -4,9 +4,12 @@
import React from "react";
function DownloadModalToggle({ onClick }) {
function DownloadModalToggle({ onClick, isActive }) {
return (
<button className="mobile-download-promo" onClick={onClick}>
<button
className={`mobile-download-promo ${isActive ? " is-active" : ""}`}
onClick={onClick}
>
<div className="icon icon-device-phone"></div>
</button>
);

View file

@ -5,10 +5,12 @@
// This class is applied when the weather widget is active and has
// a display mode set to "detailed"
&.is-tall {
height: 74px;
@media (min-width: $break-point-widest) {
height: 74px;
}
}
@media (min-width: $break-point-widest) {
@media (min-width: $break-point-medium) {
display: flex;
align-items: center;
justify-content: center;
@ -20,18 +22,37 @@
z-index: 1;
}
// Variant B uses 40px spacing
.layout-variant-b & {
@media (min-width: $break-point-widest) {
@media (min-width: $break-point-medium) {
inset-block-start: 40px;
inset-inline-start: auto;
// On smallest break point visible, make additional room for weather widget
inset-inline-end: var(--space-medium);
}
@media (min-width: $break-point-layout-variant) {
// Reset horizontal spacing back to 40px
inset-inline-end: 40px;
}
}
// Variant B / No search bar: delay showing the mobile icon until the next breakpoint
.layout-variant-b.no-search & {
display: none;
@media (min-width: $break-point-large) {
display: flex;
inset-block-start: 40px;
inset-inline-start: auto;
inset-inline-end: 40px;
inset-block-start: 40px;
}
}
// Variant A uses 24px spacing
.layout-variant-a & {
@media (min-width: $break-point-widest) {
@media (min-width: $break-point-medium) {
inset-inline-start: 24px;
inset-block-start: 24px;
}
@ -55,6 +76,11 @@
}
}
// Active state for the toggle button while the modal is open
&.is-active {
background-color: var(--button-background-color-ghost-active);
}
// Bug 1908010 - This overwrites the design system color because of a
// known transparency issue with color-mix syntax when a wallpaper is set
.lightWallpaper &,

View file

@ -251,6 +251,21 @@ $glyph-forward: url('chrome://browser/skin/forward.svg');
}
}
// Bug 1960519 - Custom override for mobile icon next to weather
&.has-mobile-download-promo {
.search-inner-wrapper {
@media (min-width: $break-point-widest) {
// Set to smaller breakpoint to fit weather
width: 497px;
}
@media (min-width: $break-point-weather) {
// Reset back to default length
width: 720px;
}
}
}
.logo {
width: 52px;
height: 52px;

View file

@ -183,26 +183,33 @@
// Bug 1959189 - Show mobile QR code modal toggle next to weather widget
.has-mobile-download-promo {
// No Variant Layout
.weather {
$mobile-download-promo-width: 32px;
// No Variant Layout, Var A Layout
.weather, &.layout-variant-a .weather {
// Default spacing (--space-xlarge) + width of .mobile-download-promo (32px) + gap
@media (min-width: $break-point-widest) {
inset-inline-start: calc(var(--space-xlarge) + 32px + var(--space-large));
}
}
&.layout-variant-a .weather {
// Var A offset (24px) + width of .mobile-download-promo (32px) + gap
@media (min-width: $break-point-widest) {
inset-inline-start: calc(24px + 32px + var(--space-medium));
@media (min-width: $break-point-medium) {
inset-inline-start: calc($mobile-download-promo-width + var(--space-xxlarge));
}
}
&.layout-variant-b .weather {
// Var B offset (40px) + width of .mobile-download-promo (32px) + gap
@media (min-width: $break-point-widest) {
// Var B: width of .mobile-download-promo (32px) + gap
@media (min-width: $break-point-medium) {
inset-inline-start: auto;
inset-inline-end: calc(40px + 32px + var(--space-medium));
inset-inline-end: calc($mobile-download-promo-width + var(--space-medium));
}
// Var B offset (40px) + width of .mobile-download-promo (32px) + gap
@media (min-width: $break-point-layout-variant) {
inset-inline-end: calc(40px + $mobile-download-promo-width + var(--space-medium));
}
}
// Layout when search has been turned off. It will show one breakpoint later than `has-search`
&.layout-variant-b.no-search .weather {
// Var B offset (40px) + width of .mobile-download-promo (32px) + gap
@media (min-width: $break-point-large) {
inset-inline-end: calc(40px + $mobile-download-promo-width + var(--space-medium));
}
}
}

View file

@ -453,7 +453,7 @@ export const LinkMenuOptions = {
type: at.OPEN_ABOUT_FAKESPOT,
}),
}),
SectionBlock: ({ blockedSections, sectionKey, sectionPosition, title }) => ({
SectionBlock: ({ sectionData, sectionKey, sectionPosition, title }) => ({
id: "newtab-menu-section-block",
icon: "delete",
action: {
@ -464,10 +464,13 @@ export const LinkMenuOptions = {
// Once the user confirmed their intention to block this section,
// update their preferences.
ac.AlsoToMain({
type: at.SET_PREF,
type: at.SECTION_DATA_UPDATE,
data: {
name: "discoverystream.sections.blocked",
value: [...blockedSections, sectionKey].join(", "),
...sectionData,
[sectionKey]: {
isBlocked: true,
isFollowed: false,
},
},
}),
// Telemetry
@ -498,16 +501,13 @@ export const LinkMenuOptions = {
},
userEvent: "DIALOG_OPEN",
}),
SectionUnfollow: ({ followedSections, sectionKey, sectionPosition }) => ({
SectionUnfollow: ({ sectionData, sectionKey, sectionPosition }) => ({
id: "newtab-menu-section-unfollow",
action: ac.AlsoToMain({
type: at.SET_PREF,
data: {
name: "discoverystream.sections.following",
value: [...followedSections.filter(item => item !== sectionKey)].join(
", "
),
},
type: at.SECTION_DATA_UPDATE,
data: (({ sectionKey: _sectionKey, ...remaining }) => remaining)(
sectionData
),
}),
impression: ac.OnlyToMain({
type: at.UNFOLLOW_SECTION,

View file

@ -1810,6 +1810,16 @@ main section {
width: 720px;
}
}
@media (min-width: 1122px) {
.layout-variant-b.has-recommended-stories.has-mobile-download-promo .search-inner-wrapper {
width: 497px;
}
}
@media (min-width: 1506px) {
.layout-variant-b.has-recommended-stories.has-mobile-download-promo .search-inner-wrapper {
width: 720px;
}
}
.layout-variant-b.has-recommended-stories .logo {
width: 52px;
height: 52px;
@ -2973,19 +2983,24 @@ main section {
margin-inline-end: 5px;
}
@media (min-width: 1122px) {
.has-mobile-download-promo .weather {
inset-inline-start: calc(var(--space-xlarge) + 32px + var(--space-large));
@media (min-width: 610px) {
.has-mobile-download-promo .weather, .has-mobile-download-promo.layout-variant-a .weather {
inset-inline-start: calc(32px + var(--space-xxlarge));
}
}
@media (min-width: 1122px) {
.has-mobile-download-promo.layout-variant-a .weather {
inset-inline-start: calc(56px + var(--space-medium));
}
}
@media (min-width: 1122px) {
@media (min-width: 610px) {
.has-mobile-download-promo.layout-variant-b .weather {
inset-inline-start: auto;
inset-inline-end: calc(32px + var(--space-medium));
}
}
@media (min-width: 724px) {
.has-mobile-download-promo.layout-variant-b .weather {
inset-inline-end: calc(72px + var(--space-medium));
}
}
@media (min-width: 866px) {
.has-mobile-download-promo.layout-variant-b.no-search .weather {
inset-inline-end: calc(72px + var(--space-medium));
}
}
@ -3562,10 +3577,12 @@ main section {
display: none;
height: 55px;
}
.mobileDownloadPromoWrapper.is-tall {
height: 74px;
}
@media (min-width: 1122px) {
.mobileDownloadPromoWrapper.is-tall {
height: 74px;
}
}
@media (min-width: 610px) {
.mobileDownloadPromoWrapper {
display: flex;
align-items: center;
@ -3578,14 +3595,30 @@ main section {
z-index: 1;
}
}
@media (min-width: 1122px) {
@media (min-width: 610px) {
.layout-variant-b .mobileDownloadPromoWrapper {
inset-inline-start: auto;
inset-inline-end: 40px;
inset-block-start: 40px;
inset-inline-start: auto;
inset-inline-end: var(--space-medium);
}
}
@media (min-width: 1122px) {
@media (min-width: 724px) {
.layout-variant-b .mobileDownloadPromoWrapper {
inset-inline-end: 40px;
}
}
.layout-variant-b.no-search .mobileDownloadPromoWrapper {
display: none;
}
@media (min-width: 866px) {
.layout-variant-b.no-search .mobileDownloadPromoWrapper {
display: flex;
inset-block-start: 40px;
inset-inline-start: auto;
inset-inline-end: 40px;
}
}
@media (min-width: 610px) {
.layout-variant-a .mobileDownloadPromoWrapper {
inset-inline-start: 24px;
inset-block-start: 24px;
@ -3607,6 +3640,9 @@ main section {
.mobile-download-promo:hover:active {
background-color: var(--button-background-color-ghost-active);
}
.mobile-download-promo.is-active {
background-color: var(--button-background-color-ghost-active);
}
.lightWallpaper .mobile-download-promo, .darkWallpaper .mobile-download-promo {
background-color: var(--newtab-weather-background-color);
}
@ -7508,6 +7544,12 @@ main section {
.download-firefox-feature-highlight .feature-highlight .feature-highlight-modal.inset-block-end {
margin-top: var(--space-xxlarge);
}
.download-firefox-feature-highlight .feature-highlight .feature-highlight-modal.inset-inline-end {
inset-inline-start: calc(var(--arrow-size) * -2);
}
.download-firefox-feature-highlight .feature-highlight .feature-highlight-modal.inset-inline-end::after {
inset-inline-start: calc(var(--space-xxlarge) - 14px);
}
.download-firefox-feature-highlight .feature-highlight .feature-highlight-modal.inset-inline-start {
inset-inline-end: calc(var(--arrow-size) / 2 * -1 - 6px);
}

View file

@ -220,6 +220,7 @@ for (const type of [
"SAVE_SESSION_PERF_DATA",
"SAVE_TO_POCKET",
"SCREENSHOT_UPDATED",
"SECTION_DATA_UPDATE",
"SECTION_DEREGISTER",
"SECTION_DISABLE",
"SECTION_ENABLE",
@ -2141,7 +2142,7 @@ const LinkMenuOptions = {
type: actionTypes.OPEN_ABOUT_FAKESPOT,
}),
}),
SectionBlock: ({ blockedSections, sectionKey, sectionPosition, title }) => ({
SectionBlock: ({ sectionData, sectionKey, sectionPosition, title }) => ({
id: "newtab-menu-section-block",
icon: "delete",
action: {
@ -2152,10 +2153,13 @@ const LinkMenuOptions = {
// Once the user confirmed their intention to block this section,
// update their preferences.
actionCreators.AlsoToMain({
type: actionTypes.SET_PREF,
type: actionTypes.SECTION_DATA_UPDATE,
data: {
name: "discoverystream.sections.blocked",
value: [...blockedSections, sectionKey].join(", "),
...sectionData,
[sectionKey]: {
isBlocked: true,
isFollowed: false,
},
},
}),
// Telemetry
@ -2186,16 +2190,13 @@ const LinkMenuOptions = {
},
userEvent: "DIALOG_OPEN",
}),
SectionUnfollow: ({ followedSections, sectionKey, sectionPosition }) => ({
SectionUnfollow: ({ sectionData, sectionKey, sectionPosition }) => ({
id: "newtab-menu-section-unfollow",
action: actionCreators.AlsoToMain({
type: actionTypes.SET_PREF,
data: {
name: "discoverystream.sections.following",
value: [...followedSections.filter(item => item !== sectionKey)].join(
", "
),
},
type: actionTypes.SECTION_DATA_UPDATE,
data: (({ sectionKey: _sectionKey, ...remaining }) => remaining)(
sectionData
),
}),
impression: actionCreators.OnlyToMain({
type: actionTypes.UNFOLLOW_SECTION,
@ -4571,6 +4572,10 @@ function AdBannerContextMenu({
const [showContextMenu, setShowContextMenu] = (0,external_React_namespaceObject.useState)(false);
const [contextMenuClassNames, setContextMenuClassNames] = (0,external_React_namespaceObject.useState)("ads-context-menu");
// The keyboard access parameter is passed down to LinkMenu component
// that uses it to focus on the first context menu option for accessibility.
const [isKeyboardAccess, setIsKeyboardAccess] = (0,external_React_namespaceObject.useState)(false);
/**
* Toggles the style fix for context menu hover/active styles.
* This allows us to have unobtrusive, transparent button background by default,
@ -4585,10 +4590,27 @@ function AdBannerContextMenu({
setContextMenuClassNames("ads-context-menu");
}
};
const onClick = e => {
e.preventDefault();
/**
* Toggles the context menu to open or close. Sets state depending on whether
* the context menu is accessed by mouse or keyboard.
*
* @param isKeyBoard
*/
const toggleContextMenu = isKeyBoard => {
toggleContextMenuStyleSwitch(!showContextMenu);
setShowContextMenu(!showContextMenu);
setIsKeyboardAccess(isKeyBoard);
};
const onClick = e => {
e.preventDefault();
toggleContextMenu(false);
};
const onKeyDown = e => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
toggleContextMenu(true);
}
};
const onUpdate = () => {
toggleContextMenuStyleSwitch(!showContextMenu);
@ -4602,10 +4624,12 @@ function AdBannerContextMenu({
type: "icon",
size: "default",
iconsrc: "chrome://global/skin/icons/more.svg",
onClick: onClick
onClick: onClick,
onKeyDown: onKeyDown
}), showContextMenu && /*#__PURE__*/external_React_default().createElement(LinkMenu, {
onUpdate: onUpdate,
dispatch: dispatch,
keyboardAccess: isKeyboardAccess,
options: ADBANNER_CONTEXT_MENU_OPTIONS,
shouldSendImpressionStats: true,
userEvent: actionCreators.DiscoveryStreamUserEvent,
@ -7344,6 +7368,7 @@ const INITIAL_STATE = {
visible: false,
data: {},
},
sectionData: {},
},
// Messages received from ASRouter to render in newtab
Messages: {
@ -8176,6 +8201,8 @@ function DiscoveryStream(prevState = INITIAL_STATE.DiscoveryStream, action) {
visible: false,
},
};
case actionTypes.SECTION_DATA_UPDATE:
return { ...prevState, sectionData: action.data };
default:
return prevState;
}
@ -10684,8 +10711,7 @@ function SectionContextMenu({
dispatch,
sectionKey,
following,
followedSections,
blockedSections,
sectionData,
sectionPosition
}) {
// Initial context menu options: block this section only.
@ -10717,8 +10743,7 @@ function SectionContextMenu({
options: SECTIONS_CONTEXT_MENU_OPTIONS,
shouldSendImpressionStats: true,
site: {
followedSections,
blockedSections,
sectionData,
sectionKey,
sectionPosition,
title
@ -10734,7 +10759,6 @@ function SectionContextMenu({
const PREF_FOLLOWED_SECTIONS = "discoverystream.sections.following";
const PREF_VISIBLE_SECTIONS = "discoverystream.sections.interestPicker.visibleSections";
/**
@ -10755,8 +10779,10 @@ function InterestPicker({
const focusRef = (0,external_React_namespaceObject.useRef)(null);
const [focusedIndex, setFocusedIndex] = (0,external_React_namespaceObject.useState)(0);
const prefs = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.Prefs.values);
const {
sectionData
} = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.DiscoveryStream);
const visibleSections = prefs[PREF_VISIBLE_SECTIONS]?.split(",").map(item => item.trim()).filter(item => item);
const following = prefs[PREF_FOLLOWED_SECTIONS]?.split(",").map(item => item.trim()).filter(item => item) || [];
const handleIntersection = (0,external_React_namespaceObject.useCallback)(() => {
dispatch(actionCreators.AlsoToMain({
type: actionTypes.INLINE_SELECTION_IMPRESSION,
@ -10797,9 +10823,15 @@ function InterestPicker({
name: topic,
checked
} = e.target;
let updatedTopics = following;
let updatedSections = {
...sectionData
};
if (checked) {
updatedTopics = updatedTopics.length ? [...updatedTopics, topic] : [topic];
updatedSections[topic] = {
isFollowed: true,
isBlocked: false,
followedAt: new Date().toISOString()
};
if (!visibleSections.includes(topic)) {
// add section to visible sections and place after the inline picker
// subtract 1 from the rank so that it is normalized with array index
@ -10807,7 +10839,7 @@ function InterestPicker({
dispatch(actionCreators.SetPref(PREF_VISIBLE_SECTIONS, visibleSections.join(", ")));
}
} else {
updatedTopics = updatedTopics.filter(t => t !== topic);
delete updatedSections[topic];
}
dispatch(actionCreators.OnlyToMain({
type: actionTypes.INLINE_SELECTION_CLICK,
@ -10818,7 +10850,10 @@ function InterestPicker({
section_position: receivedFeedRank
}
}));
dispatch(actionCreators.SetPref(PREF_FOLLOWED_SECTIONS, updatedTopics.join(", ")));
dispatch(actionCreators.AlsoToMain({
type: actionTypes.SECTION_DATA_UPDATE,
data: updatedSections
}));
}
return /*#__PURE__*/external_React_default().createElement("section", {
className: "inline-selection-wrapper ds-section",
@ -10839,7 +10874,7 @@ function InterestPicker({
onBlur: onWrapperBlur,
ref: focusRef
}, interests.map((interest, index) => {
const checked = following.includes(interest.sectionId);
const checked = sectionData[interest.sectionId]?.isFollowed;
return /*#__PURE__*/external_React_default().createElement("li", {
key: interest.sectionId,
ref: index === focusedIndex ? focusedRef : null
@ -10920,8 +10955,6 @@ const PREF_SECTIONS_CARDS_THUMBS_UP_DOWN_ENABLED = "discoverystream.sections.car
const PREF_SECTIONS_PERSONALIZATION_ENABLED = "discoverystream.sections.personalization.enabled";
const CardSections_PREF_TOPICS_ENABLED = "discoverystream.topicLabels.enabled";
const CardSections_PREF_TOPICS_SELECTED = "discoverystream.topicSelection.selectedTopics";
const CardSections_PREF_FOLLOWED_SECTIONS = "discoverystream.sections.following";
const PREF_BLOCKED_SECTIONS = "discoverystream.sections.blocked";
const CardSections_PREF_TOPICS_AVAILABLE = "discoverystream.topicSelection.topics";
const CardSections_PREF_THUMBS_UP_DOWN_ENABLED = "discoverystream.thumbsUpDown.enabled";
const PREF_INTEREST_PICKER_ENABLED = "discoverystream.sections.interestPicker.enabled";
@ -10996,14 +11029,15 @@ function CardSection({
ctaButtonSponsors
}) {
const prefs = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.Prefs.values);
const {
sectionData
} = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.DiscoveryStream);
const showTopics = prefs[CardSections_PREF_TOPICS_ENABLED];
const mayHaveSectionsCards = prefs[CardSections_PREF_SECTIONS_CARDS_ENABLED];
const mayHaveSectionsCardsThumbsUpDown = prefs[PREF_SECTIONS_CARDS_THUMBS_UP_DOWN_ENABLED];
const mayHaveThumbsUpDown = prefs[CardSections_PREF_THUMBS_UP_DOWN_ENABLED];
const selectedTopics = prefs[CardSections_PREF_TOPICS_SELECTED];
const availableTopics = prefs[CardSections_PREF_TOPICS_AVAILABLE];
const followedSectionsPref = prefs[CardSections_PREF_FOLLOWED_SECTIONS] || "";
const blockedSectionsPref = prefs[PREF_BLOCKED_SECTIONS] || "";
const {
saveToPocketCard
} = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.DiscoveryStream);
@ -11016,9 +11050,7 @@ function CardSection({
const {
responsiveLayouts
} = section.layout;
const followedSections = prefToArray(followedSectionsPref);
const following = followedSections.includes(sectionKey);
const blockedSections = prefToArray(blockedSectionsPref);
const following = sectionData[sectionKey]?.isFollowed;
const handleIntersection = (0,external_React_namespaceObject.useCallback)(() => {
dispatch(actionCreators.AlsoToMain({
type: actionTypes.CARD_SECTION_IMPRESSION,
@ -11036,7 +11068,18 @@ function CardSection({
// Only show thumbs up/down buttons if both default thumbs and sections thumbs prefs are enabled
const mayHaveCombinedThumbsUpDown = mayHaveSectionsCardsThumbsUpDown && mayHaveThumbsUpDown;
const onFollowClick = (0,external_React_namespaceObject.useCallback)(() => {
dispatch(actionCreators.SetPref(CardSections_PREF_FOLLOWED_SECTIONS, [...followedSections, sectionKey].join(", ")));
const updatedSectionData = {
...sectionData,
[sectionKey]: {
isFollowed: true,
isBlocked: false,
followedAt: new Date().toISOString()
}
};
dispatch(actionCreators.AlsoToMain({
type: actionTypes.SECTION_DATA_UPDATE,
data: updatedSectionData
}));
// Telemetry Event Dispatch
dispatch(actionCreators.OnlyToMain({
type: "FOLLOW_SECTION",
@ -11046,9 +11089,17 @@ function CardSection({
event_source: "MOZ_BUTTON"
}
}));
}, [dispatch, followedSections, sectionKey, sectionPosition]);
}, [dispatch, sectionData, sectionKey, sectionPosition]);
const onUnfollowClick = (0,external_React_namespaceObject.useCallback)(() => {
dispatch(actionCreators.SetPref(CardSections_PREF_FOLLOWED_SECTIONS, [...followedSections.filter(item => item !== sectionKey)].join(", ")));
const updatedSectionData = {
...sectionData
};
delete updatedSectionData[sectionKey];
dispatch(actionCreators.AlsoToMain({
type: actionTypes.SECTION_DATA_UPDATE,
data: updatedSectionData
}));
// Telemetry Event Dispatch
dispatch(actionCreators.OnlyToMain({
type: "UNFOLLOW_SECTION",
@ -11058,7 +11109,7 @@ function CardSection({
event_source: "MOZ_BUTTON"
}
}));
}, [dispatch, followedSections, sectionKey, sectionPosition]);
}, [dispatch, sectionData, sectionKey, sectionPosition]);
const {
maxTile
} = getMaxTiles(responsiveLayouts);
@ -11090,8 +11141,7 @@ function CardSection({
dispatch: dispatch,
index: sectionPosition,
following: following,
followedSections: followedSections,
blockedSections: blockedSections,
sectionData: sectionData,
sectionKey: sectionKey,
title: title,
type: type,
@ -11195,7 +11245,8 @@ function CardSections({
}) {
const prefs = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.Prefs.values);
const {
spocs
spocs,
sectionData
} = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.DiscoveryStream);
const personalizationEnabled = prefs[PREF_SECTIONS_PERSONALIZATION_ENABLED];
const interestPickerEnabled = prefs[PREF_INTEREST_PICKER_ENABLED];
@ -11205,11 +11256,10 @@ function CardSections({
return null;
}
const visibleSections = prefToArray(prefs[CardSections_PREF_VISIBLE_SECTIONS]);
const blockedSections = prefToArray(prefs[PREF_BLOCKED_SECTIONS] || "");
const {
interestPicker
} = data;
let filteredSections = data.sections.filter(section => !blockedSections.includes(section.sectionKey));
let filteredSections = data.sections.filter(section => !sectionData[section.sectionKey]?.isBlocked);
if (interestPickerEnabled && visibleSections.length) {
filteredSections = visibleSections.reduce((acc, visibleSection) => {
const found = filteredSections.find(({
@ -11677,25 +11727,13 @@ const DiscoveryStreamBase = (0,external_ReactRedux_namespaceObject.connect)(stat
// eslint-disable-next-line no-shadow
const SectionsMgmtPanel_PREF_FOLLOWED_SECTIONS = "discoverystream.sections.following";
const SectionsMgmtPanel_PREF_BLOCKED_SECTIONS = "discoverystream.sections.blocked";
/**
* Transforms a comma-separated string of topics in user preferences
* into a cleaned-up array.
*
* @param pref
* @returns string[]
*/
// TODO: DRY Issue: Import function from CardSections.jsx?
const getTopics = pref => {
return pref.split(",").map(item => item.trim()).filter(item => item);
};
function SectionsMgmtPanel({
exitEventFired
}) {
const [showPanel, setShowPanel] = (0,external_React_namespaceObject.useState)(false); // State management with useState
const prefs = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.Prefs.values);
const {
sectionData
} = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.DiscoveryStream);
const layoutComponents = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.DiscoveryStream.layout[0].components);
const sections = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.DiscoveryStream.feeds.data);
const dispatch = (0,external_ReactRedux_namespaceObject.useDispatch)();
@ -11710,24 +11748,28 @@ function SectionsMgmtPanel({
if (sectionsFeedName) {
sectionsList = sections[sectionsFeedName].data.sections;
}
const followedSectionsPref = prefs[SectionsMgmtPanel_PREF_FOLLOWED_SECTIONS] || "";
const blockedSectionsPref = prefs[SectionsMgmtPanel_PREF_BLOCKED_SECTIONS] || "";
const followedSections = getTopics(followedSectionsPref);
const blockedSections = getTopics(blockedSectionsPref);
const [followedSectionsState, setFollowedSectionsState] = (0,external_React_namespaceObject.useState)(followedSectionsPref); // State management with useState
const [blockedSectionsState, setBlockedSectionsState] = (0,external_React_namespaceObject.useState)(blockedSectionsPref); // State management with useState
const [sectionsState, setSectionState] = (0,external_React_namespaceObject.useState)(sectionData); // State management with useState
let followedSectionsData = sectionsList.filter(item => followedSectionsState.includes(item.sectionKey));
let blockedSectionsData = sectionsList.filter(item => blockedSectionsState.includes(item.sectionKey));
let followedSectionsData = sectionsList.filter(item => sectionsState[item.sectionKey]?.isFollowed);
let blockedSectionsData = sectionsList.filter(item => sectionsState[item.sectionKey]?.isBlocked);
function updateCachedData() {
// Reset cached followed/blocked list data while panel is open
setFollowedSectionsState(followedSectionsPref);
setBlockedSectionsState(blockedSectionsPref);
followedSectionsData = sectionsList.filter(item => followedSectionsState.includes(item.sectionKey));
blockedSectionsData = sectionsList.filter(item => blockedSectionsState.includes(item.sectionKey));
setSectionState(sectionData);
followedSectionsData = sectionsList.filter(item => sectionsState[item.sectionKey]?.isFollowed);
blockedSectionsData = sectionsList.filter(item => sectionsState[item.sectionKey]?.isBlocked);
}
const onFollowClick = (0,external_React_namespaceObject.useCallback)((sectionKey, receivedRank) => {
dispatch(actionCreators.SetPref(SectionsMgmtPanel_PREF_FOLLOWED_SECTIONS, [...followedSections, sectionKey].join(", ")));
dispatch(actionCreators.AlsoToMain({
type: actionTypes.SECTION_DATA_UPDATE,
data: {
...sectionData,
[sectionKey]: {
isFollowed: true,
isBlocked: false,
followedAt: new Date().toISOString()
}
}
}));
// Telemetry Event Dispatch
dispatch(actionCreators.OnlyToMain({
type: "FOLLOW_SECTION",
@ -11737,9 +11779,18 @@ function SectionsMgmtPanel({
event_source: "CUSTOMIZE_PANEL"
}
}));
}, [dispatch, followedSections]);
}, [dispatch, sectionData]);
const onBlockClick = (0,external_React_namespaceObject.useCallback)((sectionKey, receivedRank) => {
dispatch(actionCreators.SetPref(SectionsMgmtPanel_PREF_BLOCKED_SECTIONS, [...blockedSections, sectionKey].join(", ")));
dispatch(actionCreators.AlsoToMain({
type: actionTypes.SECTION_DATA_UPDATE,
data: {
...sectionData,
[sectionKey]: {
isFollowed: false,
isBlocked: true
}
}
}));
// Telemetry Event Dispatch
dispatch(actionCreators.OnlyToMain({
@ -11750,9 +11801,16 @@ function SectionsMgmtPanel({
event_source: "CUSTOMIZE_PANEL"
}
}));
}, [dispatch, blockedSections]);
}, [dispatch, sectionData]);
const onUnblockClick = (0,external_React_namespaceObject.useCallback)((sectionKey, receivedRank) => {
dispatch(actionCreators.SetPref(SectionsMgmtPanel_PREF_BLOCKED_SECTIONS, [...blockedSections.filter(item => item !== sectionKey)].join(", ")));
const updatedSectionData = {
...sectionData
};
delete updatedSectionData[sectionKey];
dispatch(actionCreators.AlsoToMain({
type: actionTypes.SECTION_DATA_UPDATE,
data: updatedSectionData
}));
// Telemetry Event Dispatch
dispatch(actionCreators.OnlyToMain({
type: "UNBLOCK_SECTION",
@ -11762,9 +11820,16 @@ function SectionsMgmtPanel({
event_source: "CUSTOMIZE_PANEL"
}
}));
}, [dispatch, blockedSections]);
}, [dispatch, sectionData]);
const onUnfollowClick = (0,external_React_namespaceObject.useCallback)((sectionKey, receivedRank) => {
dispatch(actionCreators.SetPref(SectionsMgmtPanel_PREF_FOLLOWED_SECTIONS, [...followedSections.filter(item => item !== sectionKey)].join(", ")));
const updatedSectionData = {
...sectionData
};
delete updatedSectionData[sectionKey];
dispatch(actionCreators.AlsoToMain({
type: actionTypes.SECTION_DATA_UPDATE,
data: updatedSectionData
}));
// Telemetry Event Dispatch
dispatch(actionCreators.OnlyToMain({
type: "UNFOLLOW_SECTION",
@ -11774,7 +11839,7 @@ function SectionsMgmtPanel({
event_source: "CUSTOMIZE_PANEL"
}
}));
}, [dispatch, followedSections]);
}, [dispatch, sectionData]);
// Close followed/blocked topic subpanel when parent menu is closed
(0,external_React_namespaceObject.useEffect)(() => {
@ -11795,7 +11860,7 @@ function SectionsMgmtPanel({
title,
receivedRank
}) => {
const following = followedSections.includes(sectionKey);
const following = sectionData[sectionKey]?.isFollowed;
return /*#__PURE__*/external_React_default().createElement("li", {
key: sectionKey
}, /*#__PURE__*/external_React_default().createElement("label", {
@ -11824,7 +11889,7 @@ function SectionsMgmtPanel({
title,
receivedRank
}) => {
const blocked = blockedSections.includes(sectionKey);
const blocked = sectionData[sectionKey]?.isBlocked;
return /*#__PURE__*/external_React_default().createElement("li", {
key: sectionKey
}, /*#__PURE__*/external_React_default().createElement("label", {
@ -13473,10 +13538,11 @@ const Weather_Weather = (0,external_ReactRedux_namespaceObject.connect)(state =>
function DownloadModalToggle({
onClick
onClick,
isActive
}) {
return /*#__PURE__*/external_React_default().createElement("button", {
className: "mobile-download-promo",
className: `mobile-download-promo ${isActive ? " is-active" : ""}`,
onClick: onClick
}, /*#__PURE__*/external_React_default().createElement("div", {
className: "icon icon-device-phone"
@ -14615,7 +14681,7 @@ class BaseContent extends (external_React_default()).PureComponent {
}
}
// eslint-disable-next-line max-statements
// eslint-disable-next-line max-statements, complexity
render() {
const {
props
@ -14736,13 +14802,16 @@ class BaseContent extends (external_React_default()).PureComponent {
}, weatherEnabled && /*#__PURE__*/external_React_default().createElement(ErrorBoundary, null, /*#__PURE__*/external_React_default().createElement(Weather_Weather, null))), /*#__PURE__*/external_React_default().createElement("div", {
className: `mobileDownloadPromoWrapper ${mobileDownloadPromoWrapperHeightModifier}`
}, mobileDownloadPromoEnabled && mobileDownloadPromoVariantABorC && /*#__PURE__*/external_React_default().createElement(ErrorBoundary, null, /*#__PURE__*/external_React_default().createElement(DownloadModalToggle, {
isActive: this.state.showDownloadHighlight,
onClick: this.toggleDownloadHighlight
}), this.state.showDownloadHighlight && /*#__PURE__*/external_React_default().createElement(MessageWrapper, {
hiddenOverride: this.state.showDownloadHighlight,
onDismiss: this.handleDismissDownloadHighlight,
dispatch: this.props.dispatch
}, /*#__PURE__*/external_React_default().createElement(DownloadMobilePromoHighlight, {
position: "inset-block-end inset-inline-start",
}, /*#__PURE__*/external_React_default().createElement(DownloadMobilePromoHighlight
// Var B layout has the weather right-aligned
, {
position: `${layoutsVariantBEnabled ? "inset-inline-start" : "inset-inline-end"} inset-block-end`,
dispatch: this.props.dispatch
})))), /*#__PURE__*/external_React_default().createElement("div", {
className: outerClassName,

View file

@ -230,10 +230,10 @@ module.exports = function (config) {
},
"content-src/components/DiscoveryStreamComponents/CardSections/CardSections.jsx":
{
statements: 86.36,
lines: 85.94,
statements: 86.05,
lines: 85.48,
functions: 79.31,
branches: 57.97,
branches: 54.41,
},
"content-src/components/DiscoveryStreamComponents/SectionContextMenu/SectionContextMenu.jsx":
{
@ -248,10 +248,9 @@ module.exports = function (config) {
},
"content-src/components/DiscoveryStreamComponents/AdBannerContextMenu/AdBannerContextMenu.jsx":
{
statements: 80,
lines: 80,
functions: 75,
branches: 75,
statements: 86,
lines: 86,
functions: 83,
},
"content-src/components/DiscoveryStreamComponents/**/*.jsx": {
statements: 90.48,

View file

@ -397,6 +397,42 @@ export class DiscoveryStreamFeed {
);
}
async configureFollowedSections() {
const prefs = this.store.getState().Prefs.values;
const cachedData = (await this.cache.get()) || {};
let { sectionData } = cachedData;
// if sectionData is empty, populate it with data from the followed and blocked prefs
// eventually we could remove this (maybe once more of sections is added to release)
if (sectionData && Object.keys(sectionData).length === 0) {
// Raw string of followed/blocked topics, ex: "entertainment, news"
const followedSectionsString = prefs[PREF_SECTIONS_FOLLOWING];
const blockedSectionsString = prefs[PREF_SECTIONS_BLOCKED];
// Format followed sections
const followedSections = followedSectionsString
? followedSectionsString.split(",").map(s => s.trim())
: [];
// Format blocked sections
const blockedSections = blockedSectionsString
? blockedSectionsString.split(",").map(s => s.trim())
: [];
const sectionTopics = new Set([...followedSections, ...blockedSections]);
sectionData = Array.from(sectionTopics).reduce((acc, section) => {
acc[section] = {
isFollowed: followedSections.includes(section),
isBlocked: blockedSections.includes(section),
};
return acc;
}, {});
await this.cache.set("sectionData", sectionData);
}
this.store.dispatch(
ac.AlsoToMain({ type: at.SECTION_DATA_UPDATE, data: sectionData })
);
}
async setupPocketState(target) {
let dispatch = action =>
this.store.dispatch(ac.OnlyToOneContent(action, target));
@ -1630,7 +1666,7 @@ export class DiscoveryStreamFeed {
let feed = feeds ? feeds[feedUrl] : null;
if (this.isExpired({ cachedData, key: "feed", url: feedUrl, isStartup })) {
const options = this.formatComponentFeedRequest();
const options = this.formatComponentFeedRequest(cachedData.sectionData);
const feedResponse = await this.fetchFromEndpoint(feedUrl, options);
@ -1859,7 +1895,7 @@ export class DiscoveryStreamFeed {
}
}
formatComponentFeedRequest() {
formatComponentFeedRequest(sectionData = {}) {
const prefs = this.store.getState().Prefs.values;
const headers = new Headers();
if (this.isMerino) {
@ -1877,32 +1913,12 @@ export class DiscoveryStreamFeed {
PREF_MERINO_FEED_EXPERIMENT
);
// Raw string of followed/blocked topics, ex: "entertainment, news"
const followedSectionsString = prefs[PREF_SECTIONS_FOLLOWING];
const blockedSectionsString = prefs[PREF_SECTIONS_BLOCKED];
// Format followed sections
const followedSections = followedSectionsString
? followedSectionsString.split(",").map(s => s.trim())
: [];
// Format blocked sections
const blockedSections = blockedSectionsString
? blockedSectionsString.split(",").map(s => s.trim())
: [];
// Combine followed and blocked sections and format into desired JSON shape for merino.
// Example:
// {
// "sectionId": "business",
// "isFollowed": true,
// "isBlocked": false
// }
const sectionTopics = new Set([...followedSections, ...blockedSections]);
const sections = Array.from(sectionTopics).map(section => ({
sectionId: section,
isFollowed: followedSections.includes(section),
isBlocked: blockedSections.includes(section),
// convert section to array to match what merino is expecting
const sections = Object.entries(sectionData).map(([sectionId, data]) => ({
sectionId,
isFollowed: data.isFollowed,
isBlocked: data.isBlocked,
...(data.followedAt && { followedAt: data.followedAt }),
}));
// To display the inline interest picker pass `enableInterestPicker` into the request
@ -2540,6 +2556,7 @@ export class DiscoveryStreamFeed {
if (this.config.enabled) {
await this.enable({ updateOpenTabs: true, isStartup: true });
}
await this.configureFollowedSections();
Services.prefs.addObserver(PREF_POCKET_BUTTON, this);
// This function is async but just for devtools,
// so we don't need to wait for it.
@ -2805,6 +2822,8 @@ export class DiscoveryStreamFeed {
case at.TOPIC_SELECTION_IMPRESSION:
this.topicSelectionImpressionEvent();
break;
case at.SECTION_DATA_UPDATE:
await this.cache.set("sectionData", action.data);
}
}
}

View file

@ -51,6 +51,22 @@ describe("<AdBannerContextMenu>", () => {
assert.equal(wrapper.find(LinkMenu).length, 1);
});
it("should render LinkMenu when context menu is accessed with the 'Enter' key", () => {
let button = wrapper.find("moz-button");
button.simulate("keydown", { key: "Enter", preventDefault: () => {} });
assert.equal(wrapper.find(LinkMenu).length, 1);
});
it("should render LinkMenu when context menu is accessed with the 'Space' key", () => {
let button = wrapper.find("moz-button");
button.simulate("keydown", { key: " ", preventDefault: () => {} });
assert.equal(wrapper.find(LinkMenu).length, 1);
});
it("should pass props to LinkMenu", () => {
wrapper.find("moz-button").simulate("click", {
preventDefault: () => {},
@ -59,6 +75,7 @@ describe("<AdBannerContextMenu>", () => {
[
"onUpdate",
"dispatch",
"keyboardAccess",
"options",
"shouldSendImpressionStats",
"userEvent",

View file

@ -5,7 +5,6 @@ import { INITIAL_STATE, reducers } from "common/Reducers.sys.mjs";
import { CardSections } from "content-src/components/DiscoveryStreamComponents/CardSections/CardSections";
import { combineReducers, createStore } from "redux";
import { DSCard } from "../../../../../content-src/components/DiscoveryStreamComponents/DSCard/DSCard";
const PREF_FOLLOWED_SECTIONS = "discoverystream.sections.following";
const PREF_SECTIONS_PERSONALIZATION_ENABLED =
"discoverystream.sections.personalization.enabled";
@ -206,7 +205,9 @@ describe("<CardSections />", () => {
});
});
it("should dispatch PREF_FOLLOWED_SECTIONS updates with follow and unfollow", () => {
it("should dispatch SECTION_DATA_UPDATE updates with follow and unfollow", () => {
const fakeDate = "2020-01-01T00:00:00.000Z";
sandbox.useFakeTimers(new Date(fakeDate));
const layout = {
title: "layout_name",
responsiveLayouts: [
@ -244,11 +245,19 @@ describe("<CardSections />", () => {
// mock the pref for followed section
const state = {
...INITIAL_STATE,
DiscoveryStream: {
...INITIAL_STATE.DiscoveryStream,
sectionData: {
section_key_2: {
isFollowed: true,
isBlocked: false,
},
},
},
Prefs: {
...INITIAL_STATE.Prefs,
values: {
...INITIAL_STATE.Prefs.values,
[PREF_FOLLOWED_SECTIONS]: "section_key_2",
[PREF_SECTIONS_PERSONALIZATION_ENABLED]: true,
},
},
@ -297,11 +306,18 @@ describe("<CardSections />", () => {
let button = wrapper.find(".section-follow moz-button").first();
button.simulate("click", {});
assert.calledWith(dispatch.getCall(0), {
type: "SET_PREF",
assert.deepEqual(dispatch.getCall(0).firstArg, {
type: "SECTION_DATA_UPDATE",
data: {
name: "discoverystream.sections.following",
value: "section_key_2, section_key_1",
section_key_2: {
isFollowed: true,
isBlocked: false,
},
section_key_1: {
isFollowed: true,
isBlocked: false,
followedAt: fakeDate,
},
},
meta: {
from: "ActivityStream:Content",
@ -327,11 +343,8 @@ describe("<CardSections />", () => {
button.simulate("click", {});
assert.calledWith(dispatch.getCall(2), {
type: "SET_PREF",
data: {
name: "discoverystream.sections.following",
value: "",
},
type: "SECTION_DATA_UPDATE",
data: {},
meta: {
from: "ActivityStream:Content",
to: "ActivityStream:Main",

View file

@ -392,6 +392,12 @@ bin/libfreebl_64int_3.so
#endif
#endif
; [ crashhelper ]
;
#ifdef MOZ_CRASHREPORTER
@BINPATH@/crashhelper@BIN_SUFFIX@
#endif
; [ Ping Sender ]
;
@BINPATH@/pingsender@BIN_SUFFIX@

View file

@ -1585,6 +1585,7 @@ ${RemoveDefaultBrowserAgentShortcut}
Push "nssdbm3.dll"
Push "mozsqlite3.dll"
Push "xpcom.dll"
Push "crashhelper.exe"
Push "crashreporter.exe"
Push "default-browser-agent.exe"
Push "nmhproxy.exe"

View file

@ -0,0 +1,15 @@
# 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/.
clear-data-for-site-title = Clear all data for this website?
# Variables:
# $site (string) - Website name
clear-data-for-site-list = This will clear all data for { $site } including:
clear-data-for-site-browsing-history = Browsing and download history
clear-data-for-site-cookies = Cookies and site data, which may sign you out of the site
clear-data-for-site-cache = Cached files and pages
cclear-data-for-site-permissions = Permissions and preferences
clear-data-for-site-exceptions = Bookmarks and saved passwords wont be deleted
clear-data-for-site-dialog-accept-button = Clear data
clear-data-for-site-dialog-cancel-button = Cancel

View file

@ -144,16 +144,6 @@ places-manage-bookmarks =
.label = Manage Bookmarks
.accesskey = M
places-forget-about-this-site-confirmation-title =
Forgetting about this site
# Variables:
# $hostOrBaseDomain (string) - The base domain (or host in case there is no base domain) for which data is being removed
places-forget-about-this-site-confirmation-msg =
This action will remove data related to { $hostOrBaseDomain } including history, cookies, cache and content preferences. Related bookmarks and passwords will not be removed. Are you sure you want to proceed?
places-forget-about-this-site-forget = Forget
places-library3 =
.title = Library

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,80 +0,0 @@
dnl Map old names of Autoconf macros to new regularized names.
dnl This file is part of Autoconf.
dnl Copyright (C) 1994 Free Software Foundation, Inc.
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2, or (at your option)
dnl any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl General macros.
dnl
define(AC_WARN, [indir([AC_MSG_WARN], $@)])dnl
define(AC_ERROR, [indir([AC_MSG_ERROR], $@)])dnl
AC_DEFUN(AC_PROGRAM_CHECK, [indir([AC_CHECK_PROG], $@)])dnl
AC_DEFUN(AC_PROGRAM_PATH, [indir([AC_PATH_PROG], $@)])dnl
AC_DEFUN(AC_PROGRAMS_CHECK, [indir([AC_CHECK_PROGS], $@)])dnl
AC_DEFUN(AC_PROGRAMS_PATH, [indir([AC_PATH_PROGS], $@)])dnl
AC_DEFUN(AC_PREFIX, [indir([AC_PREFIX_PROGRAM], $@)])dnl
AC_DEFUN(AC_HEADER_EGREP, [indir([AC_EGREP_HEADER], $@)])dnl
AC_DEFUN(AC_PROGRAM_EGREP, [indir([AC_EGREP_CPP], $@)])dnl
AC_DEFUN(AC_TEST_PROGRAM, [indir([AC_TRY_RUN], $@)])dnl
AC_DEFUN(AC_TEST_CPP, [indir([AC_TRY_CPP], $@)])dnl
AC_DEFUN(AC_HEADER_CHECK, [indir([AC_CHECK_HEADER], $@)])dnl
AC_DEFUN(AC_FUNC_CHECK, [indir([AC_CHECK_FUNC], $@)])dnl
AC_DEFUN(AC_HAVE_FUNCS, [indir([AC_CHECK_FUNCS], $@)])dnl
AC_DEFUN(AC_HAVE_HEADERS, [indir([AC_CHECK_HEADERS], $@)])dnl
AC_DEFUN(AC_SIZEOF_TYPE, [indir([AC_CHECK_SIZEOF], $@)])dnl
dnl
dnl Specific macros.
dnl
AC_DEFUN(AC_GCC_TRADITIONAL, [indir([AC_PROG_GCC_TRADITIONAL])])dnl
AC_DEFUN(AC_MINUS_C_MINUS_O, [indir([AC_PROG_CC_C_O])])dnl
AC_DEFUN(AC_SET_MAKE, [indir([AC_PROG_MAKE_SET])])dnl
AC_DEFUN(AC_YYTEXT_POINTER, [indir([AC_DECL_YYTEXT])])dnl
AC_DEFUN(AC_LN_S, [indir([AC_PROG_LN_S])])dnl
AC_DEFUN(AC_STDC_HEADERS, [indir([AC_HEADER_STDC])])dnl
AC_DEFUN(AC_MAJOR_HEADER, [indir([AC_HEADER_MAJOR])])dnl
AC_DEFUN(AC_STAT_MACROS_BROKEN, [indir([AC_HEADER_STAT])])dnl
AC_DEFUN(AC_SYS_SIGLIST_DECLARED, [indir([AC_DECL_SYS_SIGLIST])])dnl
AC_DEFUN(AC_GETGROUPS_T, [indir([AC_TYPE_GETGROUPS])])dnl
AC_DEFUN(AC_UID_T, [indir([AC_TYPE_UID_T])])dnl
AC_DEFUN(AC_SIZE_T, [indir([AC_TYPE_SIZE_T])])dnl
AC_DEFUN(AC_PID_T, [indir([AC_TYPE_PID_T])])dnl
AC_DEFUN(AC_OFF_T, [indir([AC_TYPE_OFF_T])])dnl
AC_DEFUN(AC_MODE_T, [indir([AC_TYPE_MODE_T])])dnl
AC_DEFUN(AC_RETSIGTYPE, [indir([AC_TYPE_SIGNAL])])dnl
AC_DEFUN(AC_MMAP, [indir([AC_FUNC_MMAP])])dnl
AC_DEFUN(AC_VPRINTF, [indir([AC_FUNC_VPRINTF])])dnl
AC_DEFUN(AC_VFORK, [indir([AC_FUNC_VFORK])])dnl
AC_DEFUN(AC_WAIT3, [indir([AC_FUNC_WAIT3])])dnl
AC_DEFUN(AC_ALLOCA, [indir([AC_FUNC_ALLOCA])])dnl
AC_DEFUN(AC_GETLOADAVG, [indir([AC_FUNC_GETLOADAVG])])dnl
AC_DEFUN(AC_UTIME_NULL, [indir([AC_FUNC_UTIME_NULL])])dnl
AC_DEFUN(AC_STRCOLL, [indir([AC_FUNC_STRCOLL])])dnl
AC_DEFUN(AC_SETVBUF_REVERSED, [indir([AC_FUNC_SETVBUF_REVERSED])])dnl
AC_DEFUN(AC_TIME_WITH_SYS_TIME, [indir([AC_HEADER_TIME])])dnl
AC_DEFUN(AC_TIMEZONE, [indir([AC_STRUCT_TIMEZONE])])dnl
AC_DEFUN(AC_ST_BLOCKS, [indir([AC_STRUCT_ST_BLOCKS])])dnl
AC_DEFUN(AC_ST_BLKSIZE, [indir([AC_STRUCT_ST_BLKSIZE])])dnl
AC_DEFUN(AC_ST_RDEV, [indir([AC_STRUCT_ST_RDEV])])dnl
AC_DEFUN(AC_CROSS_CHECK, [indir([AC_C_CROSS])])dnl
AC_DEFUN(AC_CHAR_UNSIGNED, [indir([AC_C_CHAR_UNSIGNED])])dnl
AC_DEFUN(AC_LONG_DOUBLE, [indir([AC_C_LONG_DOUBLE])])dnl
AC_DEFUN(AC_WORDS_BIGENDIAN, [indir([AC_C_BIGENDIAN])])dnl
AC_DEFUN(AC_INLINE, [indir([AC_C_INLINE])])dnl
AC_DEFUN(AC_CONST, [indir([AC_C_CONST])])dnl
AC_DEFUN(AC_LONG_FILE_NAMES, [indir([AC_SYS_LONG_FILE_NAMES])])dnl
AC_DEFUN(AC_RESTARTABLE_SYSCALLS, [indir([AC_SYS_RESTARTABLE_SYSCALLS])])dnl
AC_DEFUN(AC_FIND_X, [indir([AC_PATH_X])])dnl
AC_DEFUN(AC_FIND_XTRA, [indir([AC_PATH_XTRA])])dnl

File diff suppressed because it is too large Load diff

View file

@ -1,72 +0,0 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
dnl altoptions.m4 - An alternative way of specifying command-line options.
dnl These macros are needed to support a menu-based configurator.
dnl This file also includes the macro, AM_READ_MYCONFIG, for reading
dnl the 'myconfig.m4' file.
dnl Send comments, improvements, bugs to Steve Lamm (slamm@netscape.com).
dnl MOZ_ARG_ENABLE_BOOL( NAME, HELP, IF-YES [, IF-NO [, ELSE]])
dnl MOZ_ARG_DISABLE_BOOL( NAME, HELP, IF-NO [, IF-YES [, ELSE]])
dnl MOZ_ARG_ENABLE_STRING( NAME, HELP, IF-SET [, ELSE])
dnl MOZ_ARG_WITH_BOOL( NAME, HELP, IF-YES [, IF-NO [, ELSE])
dnl MOZ_ARG_WITH_STRING( NAME, HELP, IF-SET [, ELSE])
dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file
define([MOZ_DIVERSION_ARGS], 12)
AC_DEFUN([MOZ_ARG],[dnl
AC_DIVERT_PUSH(MOZ_DIVERSION_ARGS)dnl
'$1',
AC_DIVERT_POP()dnl
])
AC_DEFUN([MOZ_AC_ARG_ENABLE],[MOZ_ARG([--enable-]translit([$1],[_],[-]))AC_ARG_ENABLE([$1], [$2], [$3], [$4])])
AC_DEFUN([MOZ_AC_ARG_WITH],[MOZ_ARG([--with-]translit([$1],[_],[-]))AC_ARG_WITH([$1], [$2], [$3], [$4])])
dnl MOZ_TWO_STRING_TEST(NAME, VAL, STR1, IF-STR1, STR2, IF-STR2 [, ELSE])
AC_DEFUN([MOZ_TWO_STRING_TEST],
[if test "[$2]" = "[$3]"; then
ifelse([$4], , :, [$4])
elif test "[$2]" = "[$5]"; then
ifelse([$6], , :, [$6])
else
ifelse([$7], ,
[AC_MSG_ERROR([Option, [$1], does not take an argument ([$2]).])],
[$7])
fi])
dnl MOZ_ARG_ENABLE_BOOL(NAME, HELP, IF-YES [, IF-NO [, ELSE]])
AC_DEFUN([MOZ_ARG_ENABLE_BOOL],
[MOZ_AC_ARG_ENABLE([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$enableval], yes, [$3], no, [$4])],
[$5])])
dnl MOZ_ARG_DISABLE_BOOL(NAME, HELP, IF-NO [, IF-YES [, ELSE]])
AC_DEFUN([MOZ_ARG_DISABLE_BOOL],
[MOZ_AC_ARG_ENABLE([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$enableval], no, [$3], yes, [$4])],
[$5])])
dnl MOZ_ARG_ENABLE_STRING(NAME, HELP, IF-SET [, ELSE])
AC_DEFUN([MOZ_ARG_ENABLE_STRING],
[MOZ_AC_ARG_ENABLE([$1], [$2], [$3], [$4])])
dnl MOZ_ARG_WITH_BOOL(NAME, HELP, IF-YES [, IF-NO [, ELSE])
AC_DEFUN([MOZ_ARG_WITH_BOOL],
[MOZ_AC_ARG_WITH([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$withval], yes, [$3], no, [$4])],
[$5])])
dnl MOZ_ARG_WITH_STRING(NAME, HELP, IF-SET [, ELSE])
AC_DEFUN([MOZ_ARG_WITH_STRING],
[MOZ_AC_ARG_WITH([$1], [$2], [$3], [$4])])
dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file
AC_DEFUN([MOZ_READ_MOZCONFIG],
[AC_REQUIRE([AC_INIT_BINSH])dnl
. $OLD_CONFIGURE_VARS
])

View file

@ -1,28 +0,0 @@
dnl Driver that loads the Autoconf macro files.
dnl Requires GNU m4.
dnl This file is part of Autoconf.
dnl Copyright (C) 1994 Free Software Foundation, Inc.
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2, or (at your option)
dnl any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl Written by David MacKenzie.
dnl
include(acgeneral.m4)dnl
builtin(include, acspecific.m4)dnl
builtin(include, acoldnames.m4)dnl
dnl Do not sinclude acsite.m4 here, because it may not be installed
dnl yet when Autoconf is frozen.
dnl Do not sinclude ./aclocal.m4 here, to prevent it from being frozen.

View file

@ -1,158 +0,0 @@
#! @SHELL@
# autoconf -- create `configure' using m4 macros
# Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# If given no args, create `configure' from template file `configure.in'.
# With one arg, create a configure script on standard output from
# the given template file.
usage="\
Usage: autoconf [-h] [--help] [-m dir] [--macrodir=dir]
[-l dir] [--localdir=dir] [--version] [template-file]"
# NLS nuisances.
# Only set these to C if already set. These must not be set unconditionally
# because not all systems understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
: ${AC_MACRODIR=@datadir@}
: ${M4=@M4@}
: ${AWK=@AWK@}
case "${M4}" in
/*) # Handle the case that m4 has moved since we were configured.
# It may have been found originally in a build directory.
test -f "${M4}" || M4=m4 ;;
esac
: ${TMPDIR=/tmp}
tmpout=${TMPDIR}/acout.$$
localdir=
show_version=no
while test $# -gt 0 ; do
case "${1}" in
-h | --help | --h* )
echo "${usage}" 1>&2; exit 0 ;;
--localdir=* | --l*=* )
localdir="`echo \"${1}\" | sed -e 's/^[^=]*=//'`"
shift ;;
-l | --localdir | --l*)
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
localdir="${1}"
shift ;;
--macrodir=* | --m*=* )
AC_MACRODIR="`echo \"${1}\" | sed -e 's/^[^=]*=//'`"
shift ;;
-m | --macrodir | --m* )
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
AC_MACRODIR="${1}"
shift ;;
--version | --v* )
show_version=yes; shift ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "${usage}" 1>&2; exit 1 ;;
* )
break ;;
esac
done
if test $show_version = yes; then
version=`sed -n 's/define.AC_ACVERSION.[ ]*\([0-9.]*\).*/\1/p' \
$AC_MACRODIR/acgeneral.m4`
echo "Autoconf version $version"
exit 0
fi
case $# in
0) infile=configure.in ;;
1) infile="$1" ;;
*) echo "$usage" >&2; exit 1 ;;
esac
trap 'rm -f $tmpin $tmpout; exit 1' 1 2 15
tmpin=${TMPDIR}/acin.$$ # Always set this, to avoid bogus errors from some rm's.
if test z$infile = z-; then
infile=$tmpin
cat > $infile
elif test ! -r "$infile"; then
echo "autoconf: ${infile}: No such file or directory" >&2
exit 1
fi
if test -n "$localdir"; then
use_localdir="-I$localdir -DAC_LOCALDIR=$localdir"
else
use_localdir=
fi
# Use the frozen version of Autoconf if available.
r= f=
# Some non-GNU m4's don't reject the --help option, so give them /dev/null.
case `$M4 --help < /dev/null 2>&1` in
*reload-state*) test -r $AC_MACRODIR/autoconf.m4f && { r=--reload f=f; } ;;
*traditional*) ;;
*) echo Autoconf requires GNU m4 1.1 or later >&2; rm -f $tmpin; exit 1 ;;
esac
$M4 -I$AC_MACRODIR $use_localdir $r autoconf.m4$f $infile > $tmpout ||
{ rm -f $tmpin $tmpout; exit 2; }
# You could add your own prefixes to pattern if you wanted to check for
# them too, e.g. pattern='\(AC_\|ILT_\)', except that UNIX sed doesn't do
# alternation.
pattern="AC_"
status=0
if grep "^[^#]*${pattern}" $tmpout > /dev/null 2>&1; then
echo "autoconf: Undefined macros:" >&2
sed -n "s/^[^#]*\\(${pattern}[_A-Za-z0-9]*\\).*/\\1/p" $tmpout |
while read macro; do
grep -n "^[^#]*$macro" $infile /dev/null
test $? -eq 1 && echo >&2 "***BUG in Autoconf--please report*** $macro"
done | sort -u >&2
status=1
fi
if test $# -eq 0; then
echo "This case should not be reached."
exit 1
fi
# Put the real line numbers into the output to make config.log more helpful.
$AWK '
/__oline__/ { printf "%d:", NR + 1 }
{ print }
' $tmpout | sed '
/__oline__/s/^\([0-9][0-9]*\):\(.*\)__oline__/\2\1/
'
rm -f $tmpout
exit $status

View file

@ -1,162 +0,0 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
dnl For use in AC_SUBST replacement
define([MOZ_DIVERSION_SUBST], 11)
dnl Replace AC_SUBST to store values in a format suitable for python.
dnl The necessary comma after the tuple can't be put here because it
dnl can mess around with things like:
dnl AC_SOMETHING(foo,AC_SUBST(),bar)
define([AC_SUBST],
[ifdef([AC_SUBST_SET_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_SET on the same variable ($1)])],
[ifdef([AC_SUBST_LIST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_LIST on the same variable ($1)])],
[ifdef([AC_SUBST_$1], ,
[define([AC_SUBST_$1], )dnl
AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
(''' $1 ''', r''' [$]$1 ''')
AC_DIVERT_POP()dnl
])])])])])
dnl Like AC_SUBST, but makes the value available as a set in python,
dnl with values got from the value of the environment variable, split on
dnl whitespaces.
define([AC_SUBST_SET],
[ifdef([AC_SUBST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_SET on the same variable ($1)])],
[ifdef([AC_SUBST_LIST_$1], [m4_fatal([Cannot use AC_SUBST_LIST and AC_SUBST_SET on the same variable ($1)])],
[ifdef([AC_SUBST_SET_$1], ,
[define([AC_SUBST_SET_$1], )dnl
AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
(''' $1 ''', unique_list(split(r''' [$]$1 ''')))
AC_DIVERT_POP()dnl
])])])])])
dnl Like AC_SUBST, but makes the value available as a list in python,
dnl with values got from the value of the environment variable, split on
dnl whitespaces.
define([AC_SUBST_LIST],
[ifdef([AC_SUBST_$1], [m4_fatal([Cannot use AC_SUBST and AC_SUBST_LIST on the same variable ($1)])],
[ifdef([AC_SUBST_SET_$1], [m4_fatal([Cannot use AC_SUBST_SET and AC_SUBST_LIST on the same variable ($1)])],
[ifdef([AC_SUBST_LIST_$1], ,
[define([AC_SUBST_LIST_$1], )dnl
AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
(''' $1 ''', list(split(r''' [$]$1 ''')))
AC_DIVERT_POP()dnl
])])])])])
dnl Ignore AC_SUBSTs for variables we don't have use for but that autoconf
dnl itself exports.
define([AC_SUBST_CFLAGS], )
define([AC_SUBST_CPPFLAGS], )
define([AC_SUBST_CXXFLAGS], )
define([AC_SUBST_FFLAGS], )
define([AC_SUBST_DEFS], )
define([AC_SUBST_LDFLAGS], )
define([AC_SUBST_LIBS], )
define([AC_SUBST_exec_prefix], )
define([AC_SUBST_prefix], )
define([AC_SUBST_datadir], )
define([AC_SUBST_libdir], )
define([AC_SUBST_includedir], )
dnl Wrap AC_DEFINE to store values in a format suitable for python.
dnl autoconf's AC_DEFINE still needs to be used to fill confdefs.h,
dnl which is #included during some compile checks.
dnl The necessary comma after the tuple can't be put here because it
dnl can mess around with things like:
dnl AC_SOMETHING(foo,AC_DEFINE(),bar)
define([_MOZ_AC_DEFINE], defn([AC_DEFINE]))
define([AC_DEFINE],
[cat >> confdefs.pytmp <<\EOF
(''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
EOF
ifelse($#, 2, _MOZ_AC_DEFINE([$1], [$2]), $#, 3, _MOZ_AC_DEFINE([$1], [$2], [$3]),_MOZ_AC_DEFINE([$1]))dnl
])
dnl Wrap AC_DEFINE_UNQUOTED to store values in a format suitable for
dnl python.
define([_MOZ_AC_DEFINE_UNQUOTED], defn([AC_DEFINE_UNQUOTED]))
define([AC_DEFINE_UNQUOTED],
[cat >> confdefs.pytmp <<EOF
(''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
EOF
ifelse($#, 2, _MOZ_AC_DEFINE_UNQUOTED($1, $2), $#, 3, _MOZ_AC_DEFINE_UNQUOTED($1, $2, $3),_MOZ_AC_DEFINE_UNQUOTED($1))dnl
])
dnl Replace AC_OUTPUT to create and call a python config.status
define([MOZ_CREATE_CONFIG_STATUS],
[dnl Used in all Makefile.in files
top_srcdir=$srcdir
AC_SUBST(top_srcdir)
dnl Picked from autoconf 2.13
trap '' 1 2 15
AC_CACHE_SAVE
trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
: ${CONFIG_STATUS=./config.data}
dnl We're going to need [ ] for python syntax.
changequote(<<<, >>>)dnl
echo creating $CONFIG_STATUS
cat > $CONFIG_STATUS <<EOF
dnl All defines and substs are stored with an additional space at the beginning
dnl and at the end of the string, to avoid any problem with values starting or
dnl ending with quotes.
defines = [
EOF
dnl confdefs.pytmp contains AC_DEFINEs, in the expected format, but
dnl lacks the final comma (see above).
if test -e confdefs.pytmp; then
sed 's/$/,/' confdefs.pytmp >> $CONFIG_STATUS
rm confdefs.pytmp
fi
rm -f confdefs.h
cat >> $CONFIG_STATUS <<\EOF
]
substs = [
EOF
dnl The MOZ_DIVERSION_SUBST output diversion contains AC_SUBSTs, in the
dnl expected format, but lacks the final comma (see above).
sed 's/$/,/' >> $CONFIG_STATUS <<EOF
undivert(MOZ_DIVERSION_SUBST)dnl
EOF
dnl Add in the output from the subconfigure script
for ac_subst_arg in $_subconfigure_ac_subst_args; do
variable='$'$ac_subst_arg
echo " (''' $ac_subst_arg ''', r''' `eval echo $variable` ''')," >> $CONFIG_STATUS
done
cat >> $CONFIG_STATUS <<\EOF
]
flags = [
undivert(MOZ_DIVERSION_ARGS)dnl
]
EOF
changequote([, ])
])
define([m4_fatal],[
errprint([$1
])
m4exit(1)
])
define([AC_OUTPUT], [ifelse($#_$1, 1_, [MOZ_CREATE_CONFIG_STATUS()
MOZ_RUN_CONFIG_STATUS()],
[m4_fatal([Use CONFIGURE_SUBST_FILES in moz.build files to create substituted files.])]
)])
define([AC_CONFIG_HEADER],
[m4_fatal([Use CONFIGURE_DEFINE_FILES in moz.build files to produce header files.])
])

View file

@ -1,31 +0,0 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
dnl Wrap AC_INIT_PREPARE to add the above trap.
define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
define([AC_INIT_PREPARE],
[_MOZ_AC_INIT_PREPARE($1)
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
])
dnl Print error messages in config.log as well as stderr
define([AC_MSG_ERROR],
[{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
dnl Divert AC_TRY_COMPILER to make ac_cv_prog_*_works actually cached.
dnl This will allow to just skip the test when python configure has set
dnl the value for us. But since ac_cv_prog_*_cross is calculated at the same
dnl time, and has a different meaning as in python configure, we only want to
dnl use its value to display whether a cross-compile is happening. We forbid
dnl configure tests that would rely on ac_cv_prog_*_cross autoconf meaning
dnl (being able to execute the product of compilation), which are already bad
dnl for cross compiles anyways, so it's a win to get rid of them.
define([_MOZ_AC_TRY_COMPILER], defn([AC_TRY_COMPILER]))
define([AC_TRY_COMPILER], [AC_CACHE_VAL($2, _MOZ_AC_TRY_COMPILER($1, $2, $3))])
define([AC_TRY_RUN], [m4_fatal([AC_TRY_RUN is forbidden])])
define([AC_CHECK_FILE], [m4_fatal([AC_CHECK_FILE is forbidden])])

View file

@ -70,6 +70,23 @@ Store`` automatic connection will not happen and this can result in a broken
state. Inspecting ``snap connections firefox`` using a store-installed snap
should get your an accurate list that you can replicate.
Cross-compilation
=================
There is now support for cross-compilation for both ``armhf`` and ``arm64``.
To produce cross-compiled version locally:
- follow the steps above for building, except you need to pass
``--build-for=ARCH`` to ``snapcraft``
- this needs ``snapcraft`` of at least v8.x
- make sure you uncomment the ``##CROSS-COMPILATION##`` lines due to Launchpad
limitations
Builds on Treeherder as well as Try pushes are also available using
cross-compilation. Tests on Treeherder will also be supported when ARM-based
workers will be available, confere `Bug 1855463
<https://bugzilla.mozilla.org/show_bug.cgi?id=1855463>`_.
What CI coverage
================

View file

@ -65,11 +65,12 @@ set_config("DIST", build_environment.dist)
option(env="MOZ_AUTOMATION", help="Enable options for automated builds")
set_config("MOZ_AUTOMATION", depends_if("MOZ_AUTOMATION")(lambda x: True))
option(env="OLD_CONFIGURE", nargs=1, help="Path to the old configure script")
option(env="MOZCONFIG", nargs=1, help="Mozconfig location")
option(env="MOZ_AUTOMATION_MOZCONFIG", help="Indicates mozconfig from automated builds")
set_config(
"MOZ_AUTOMATION_MOZCONFIG", depends_if("MOZ_AUTOMATION_MOZCONFIG")(lambda x: True)
)
# Read user mozconfig
# ==============================================================
@ -78,34 +79,11 @@ option(env="MOZCONFIG", nargs=1, help="Mozconfig location")
# be called when --help is passed, and the mozconfig wouldn't be read.
@depends("MOZCONFIG", "OLD_CONFIGURE", build_environment, "--help")
@depends("MOZCONFIG", build_environment, "--help")
@imports(_from="mozbuild.mozconfig", _import="MozconfigLoader")
@imports(_from="mozboot.mozconfig", _import="find_mozconfig")
@imports("os")
def mozconfig(mozconfig, old_configure, build_env, help):
# Don't read the mozconfig for the js configure (yay backwards
# compatibility)
# While the long term goal is that js and top-level use the same configure
# and the same overall setup, including the possibility to use mozconfigs,
# figuring out what we want to do wrt mozconfig vs. command line and
# environment variable is not a clear-cut case, and it's more important to
# fix the immediate problem mozconfig causes to js developers by
# "temporarily" returning to the previous behavior of not loading the
# mozconfig for the js configure.
# Separately to the immediate problem for js developers, there is also the
# need to not load a mozconfig when running js configure as a subconfigure.
# Unfortunately, there is no direct way to tell whether the running
# configure is the js configure. The indirect way is to look at the
# OLD_CONFIGURE path, which points to js/src/old-configure.
# I expect we'll have figured things out for mozconfigs well before
# old-configure dies.
if (
old_configure
and os.path.dirname(os.path.abspath(old_configure[0])).endswith("/js/src")
or (mozconfig and mozconfig[0] == os.devnull)
):
return {"path": None}
def mozconfig(mozconfig, build_env, help):
topsrcdir = build_env.topsrcdir
loader = MozconfigLoader(topsrcdir)
mozconfig = mozconfig[0] if mozconfig else None
@ -155,6 +133,7 @@ def help_shell(help, shell):
shell = help_shell | shell
set_config("SHELL", shell)
# Python 3
@ -235,10 +214,6 @@ def mozconfig_options(mozconfig, early_options, automation, help):
for key, (_, value) in mozconfig["env"]["modified"].items():
add(key, value)
os.environ[key] = value
for key, value in mozconfig["vars"]["added"].items():
add(key, value)
for key, (_, value) in mozconfig["vars"]["modified"].items():
add(key, value)
@depends(build_environment, "--help")
@ -1326,6 +1301,17 @@ set_config("prefix", depends("--prefix")(lambda prefix: prefix[0]))
# Unlike autoconf, we don't offer these as a customisation point.
set_config("exec_prefix", depends("--prefix")(lambda prefix: prefix[0]))
set_config("datadir", depends("--prefix")(lambda prefix: f"{prefix[0]}/share"))
set_config("bindir", depends("--prefix")(lambda prefix: f"{prefix[0]}/bin"))
set_config("sbindir", depends("--prefix")(lambda prefix: f"{prefix[0]}/sbin"))
set_config("infodir", depends("--prefix")(lambda prefix: f"{prefix[0]}/info"))
set_config("libexec", depends("--prefix")(lambda prefix: f"{prefix[0]}/libexec"))
set_config("localstatedir", depends("--prefix")(lambda prefix: f"{prefix[0]}/var"))
set_config("sharedstatedir", depends("--prefix")(lambda prefix: f"{prefix[0]}/com"))
set_config("sysconfdir", depends("--prefix")(lambda prefix: f"{prefix[0]}/etc"))
set_config("mandir", depends("--prefix")(lambda prefix: f"{prefix[0]}/man"))
set_config("oldincludedir", depends("--prefix")(lambda prefix: f"{prefix[0]}/include"))
set_config("top_srcdir", build_environment.topsrcdir)
set_config("program_transform_name", "s,x,x,")
option(
"--includedir",

View file

@ -1,395 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
m4 = check_prog(
"M4",
(
"gm4",
"m4",
),
paths=prefer_mozillabuild_path,
)
@depends(mozconfig)
def prepare_mozconfig(mozconfig):
if mozconfig["path"]:
items = {}
for key, value in mozconfig["vars"]["added"].items():
items[key] = (value, "added")
for key, (old, value) in mozconfig["vars"]["modified"].items():
items[key] = (value, "modified")
for t in ("env", "vars"):
for key in mozconfig[t]["removed"].keys():
items[key] = (None, "removed " + t)
return items
@depends("OLD_CONFIGURE", build_project)
def old_configure(old_configure, build_project):
if not old_configure:
die("The OLD_CONFIGURE environment variable must be set")
# os.path.abspath in the sandbox will ensure forward slashes on Windows,
# which is actually necessary because this path actually ends up literally
# as $0, and backslashes there breaks autoconf's detection of the source
# directory.
old_configure = os.path.abspath(old_configure[0])
if build_project == "js":
old_configure_dir = os.path.dirname(old_configure)
if not old_configure_dir.endswith("/js/src"):
old_configure = os.path.join(
old_configure_dir, "js", "src", os.path.basename(old_configure)
)
return old_configure
@depends(prepare_mozconfig)
@imports(_from="__builtin__", _import="open")
@imports(_from="__builtin__", _import="print")
@imports(_from="mozbuild.shellutil", _import="quote")
def prepare_configure(mozconfig):
assignments = {}
with open("old-configure.vars", "w") as out:
log.debug("Injecting the following to old-configure:")
def inject(command):
print(command, file=out) # noqa Python 2vs3
log.debug("| %s", command)
if mozconfig:
inject("# start of mozconfig values")
for key, (value, action) in sorted(mozconfig.items()):
if action.startswith("removed "):
inject("unset %s # from %s" % (key, action[len("removed ") :]))
else:
inject("%s=%s # %s" % (key, quote(value), action))
assignments[key] = value
inject("# end of mozconfig values")
return namespace(assignments=assignments)
@template
def old_configure_options(*options):
for opt in options:
option(opt, nargs="*", help="Help missing for old configure options")
@dependable
def all_options():
return list(options)
return depends(all_options, *options)
@old_configure_options(
"--cache-file",
"--x-includes",
"--x-libraries",
)
def prepare_configure_options(all_options, *options):
# old-configure only supports the options listed in @old_configure_options
# so we don't need to pass it every single option we've been passed. Only
# the ones that are not supported by python configure need to.
options = [
value.format(name)
for name, value in zip(all_options, options)
if value.origin != "default"
]
return namespace(options=options, all_options=all_options)
@template
def old_configure_for(old_configure_path, extra_env=None):
if extra_env is None:
extra_env = dependable(None)
@depends(
prepare_configure,
prepare_configure_options,
"--prefix",
"--includedir",
"--libdir",
prefer_mozillabuild_path,
altered_path,
extra_env,
build_environment,
old_configure_path,
awk,
m4,
shell,
"--cache-file",
)
@imports(_from="__builtin__", _import="compile")
@imports(_from="__builtin__", _import="open")
@imports(_from="__builtin__", _import="OSError")
@imports("glob")
@imports("itertools")
@imports("logging")
@imports("os")
@imports("re")
@imports("subprocess")
@imports("sys")
@imports(_from="mozbuild.shellutil", _import="quote")
@imports(_from="mozbuild.shellutil", _import="split")
@imports(_from="tempfile", _import="NamedTemporaryFile")
@imports(_from="subprocess", _import="CalledProcessError")
@imports(_from="__builtin__", _import="exec")
def old_configure(
prepare_configure,
prepare_configure_options,
prefix,
includedir,
libdir,
prefer_mozillabuild_path,
altered_path,
extra_env,
build_env,
old_configure,
awk,
m4,
shell,
cache_file_option,
):
if altered_path:
path = altered_path
else:
path = os.pathsep.join(prefer_mozillabuild_path)
cxx = prepare_configure.assignments.get("CXX")
cc = prepare_configure.assignments.get("CC")
if cc and cxx:
if cache_file_option:
config_cache = cache_file_option[0]
else:
config_cache = "config.cache"
if os.path.exists(config_cache):
remove = False
with open(config_cache, "r") as cfg_cache:
cxx_pattern = re.compile(
r"^ac_cv_prog_CXX=\${ac_cv_prog_CXX='(.*)'}$"
)
cc_pattern = re.compile(r"^ac_cv_prog_CC=\${ac_cv_prog_CC='(.*)'}$")
for line in cfg_cache:
m = cc_pattern.match(line)
if m and m.group(1) != cc:
remove = True
break
m = cxx_pattern.match(line)
if m and m.group(1) != cxx:
remove = True
break
if remove:
log.info("invalidating config.cache")
os.remove(config_cache)
refresh = True
if os.path.exists(old_configure):
mtime = os.path.getmtime(old_configure)
aclocal = os.path.join(build_env.topsrcdir, "build", "autoconf", "*.m4")
for input in itertools.chain(
(
old_configure + ".in",
os.path.join(os.path.dirname(old_configure), "aclocal.m4"),
),
glob.iglob(aclocal),
):
if os.path.getmtime(input) > mtime:
break
else:
refresh = False
if refresh:
autoconf = os.path.join(
build_env.topsrcdir, "build", "autoconf", "autoconf.sh"
)
log.info("Refreshing %s with %s", old_configure, autoconf)
env = dict(os.environ)
env["M4"] = m4
env["AWK"] = awk
env["AC_MACRODIR"] = os.path.join(build_env.topsrcdir, "build", "autoconf")
env["PATH"] = path
try:
script = subprocess.check_output(
[
shell,
autoconf,
"--localdir=%s" % os.path.dirname(old_configure),
old_configure + ".in",
],
# Fix the working directory, so that when m4 is called, that
# includes of relative paths are deterministically resolved
# relative to the directory containing old-configure.
cwd=os.path.dirname(old_configure),
env=env,
)
except CalledProcessError as exc:
die("autoconf exited with return code {}".format(exc.returncode))
if not script:
die(
"Generated old-configure is empty! Check that your autoconf 2.13 program works!"
)
# Make old-configure append to config.log, where we put our own log.
# This could be done with a m4 macro, but it's way easier this way
script = script.replace(b">./config.log", b">>${CONFIG_LOG=./config.log}")
with NamedTemporaryFile(
mode="wb",
prefix=os.path.basename(old_configure),
dir=os.path.dirname(old_configure),
delete=False,
) as fh:
fh.write(script)
try:
os.rename(fh.name, old_configure)
except OSError:
try:
# Likely the file already existed (on Windows). Retry after removing it.
os.remove(old_configure)
os.rename(fh.name, old_configure)
except OSError as e:
die("Failed re-creating old-configure: %s" % e.message)
old_configure_options = {
"prefix": prefix[0],
"includedir": includedir[0],
"libdir": libdir[0],
}
cmd = (
[shell, old_configure]
+ prepare_configure_options.options
+ [f"--{k}={v}" for k, v in old_configure_options.items()]
)
env = dict(os.environ)
# For debugging purpose, in case it's not what we'd expect.
log.debug("Running %s", quote(*cmd))
# Our logging goes to config.log, the same file old.configure uses.
# We can't share the handle on the file, so close it.
logger = logging.getLogger("moz.configure")
config_log = None
for handler in logger.handlers:
if isinstance(handler, logging.FileHandler):
config_log = handler
config_log.close()
logger.removeHandler(config_log)
env["CONFIG_LOG"] = config_log.baseFilename
log_size = os.path.getsize(config_log.baseFilename)
break
env["PATH"] = path
if extra_env:
env.update(extra_env)
env["OLD_CONFIGURE_VARS"] = os.path.join(
build_env.topobjdir, "old-configure.vars"
)
proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env
)
while True:
line = proc.stdout.readline()
if not line:
break
log.info(line.rstrip())
ret = proc.wait()
if ret:
with log.queue_debug():
if config_log:
with open(config_log.baseFilename, "r") as fh:
fh.seek(log_size)
for line in fh:
log.debug(line.rstrip())
log.error("old-configure failed")
sys.exit(ret)
if config_log:
# Create a new handler in append mode
handler = logging.FileHandler(config_log.baseFilename, mode="a", delay=True)
handler.setFormatter(config_log.formatter)
logger.addHandler(handler)
raw_config = {
"split": split,
"unique_list": unique_list,
}
with open("config.data", "r") as fh:
code = compile(fh.read(), "config.data", "exec")
exec(code, raw_config)
# Ensure all the flags known to old-configure appear in the
# @old_configure_options above.
all_options = set(prepare_configure_options.all_options)
for flag in raw_config["flags"]:
if flag not in all_options:
die(
"Missing option in `@old_configure_options` in %s: %s",
__file__,
flag,
)
# If the code execution above fails, we want to keep the file around for
# debugging.
os.remove("config.data")
return namespace(
**{
c: [
(k[1:-1], v[1:-1] if isinstance(v, str) else v)
for k, v in raw_config[c]
# Eventually we'll want to filter out all lowercase keys. (bug 1869127)
# For now, we only filter out the most problematic one that
# we know is unused.
if k != " target_cpu "
]
for c in ("substs", "defines")
}
)
return old_configure
old_configure = old_configure_for(old_configure)
set_config("OLD_CONFIGURE_SUBSTS", old_configure.substs)
set_config("OLD_CONFIGURE_DEFINES", old_configure.defines)
# Assuming no other option is declared after this function, handle the
# env options that were injected by mozconfig_options by creating dummy
# Option instances and having the sandbox's CommandLineHelper handle
# them. We only do so for options that haven't been declared so far,
# which should be a proxy for the options that old-configure handles
# and that we don't know anything about.
@depends("--help")
@imports("__sandbox__")
@imports(_from="mozbuild.configure.options", _import="Option")
def remaining_mozconfig_options(_):
helper = __sandbox__._helper
for arg in list(helper):
if helper._origins[arg] != "mozconfig":
continue
name = arg.split("=", 1)[0]
if name.isupper() and name not in __sandbox__._options:
option = Option(env=name, nargs="*", help=name)
helper.handle(option)
# Please do not add anything after remaining_mozconfig_options()

View file

@ -1,6 +1,6 @@
# Common options for artifact builds to set automation steps.
# This gets included before mozconfig.automation.
MOZ_AUTOMATION_BUILD_SYMBOLS=0
export MOZ_AUTOMATION_BUILD_SYMBOLS=0
MOZ_AUTOMATION_PACKAGE_GENERATED_SOURCES=0
MOZ_AUTOMATION_ARTIFACT_BUILDS=1

View file

@ -107,7 +107,9 @@ def generate(output):
# Write out some useful strings from the buildconfig.
output.write(generate_string("MOZ_MACBUNDLE_ID"))
output.write(generate_string("MOZ_APP_BASENAME"))
output.write(generate_string("MOZ_APP_NAME"))
output.write(generate_string("MOZ_APP_VENDOR"))
# Write out some useful booleans from the buildconfig.
output.write(generate_bool("MOZ_FOLD_LIBS"))

View file

@ -73,9 +73,6 @@ def main(argv):
config = {}
if "OLD_CONFIGURE" not in os.environ:
os.environ["OLD_CONFIGURE"] = os.path.join(base_dir, "old-configure")
sandbox = ConfigureSandbox(config, os.environ, argv)
if not sandbox._help:
@ -144,28 +141,21 @@ def main(argv):
buildstatus("START_configure config.status")
logging.getLogger("moz.configure").info("Creating config.status")
old_js_configure_substs = config.pop("OLD_JS_CONFIGURE_SUBSTS", None)
old_js_configure_defines = config.pop("OLD_JS_CONFIGURE_DEFINES", None)
try:
if old_js_configure_substs or old_js_configure_defines:
js_config = config.copy()
pwd = os.getcwd()
try:
os.makedirs("js/src", exist_ok=True)
os.chdir("js/src")
js_config["OLD_CONFIGURE_SUBSTS"] = old_js_configure_substs
js_config["OLD_CONFIGURE_DEFINES"] = old_js_configure_defines
# The build system frontend expects $objdir/js/src/config.status
# to have $objdir/js/src as topobjdir.
# We want forward slashes on all platforms.
js_config["TOPOBJDIR"] += "/js/src"
ret = config_status(js_config, execute=False)
if ret:
return ret
finally:
os.chdir(pwd)
js_config = config.copy()
pwd = os.getcwd()
try:
os.makedirs("js/src", exist_ok=True)
os.chdir("js/src")
# The build system frontend expects $objdir/js/src/config.status
# to have $objdir/js/src as topobjdir.
# We want forward slashes on all platforms.
js_config["TOPOBJDIR"] += "/js/src"
ret = config_status(js_config, execute=False)
if ret:
return ret
finally:
os.chdir(pwd)
return config_status(config)
finally:
buildstatus("END_configure config.status")
@ -217,17 +207,11 @@ def config_status(config, execute=True):
"TOPSRCDIR",
"TOPOBJDIR",
"CONFIG_STATUS_DEPS",
"OLD_CONFIGURE_SUBSTS",
"OLD_CONFIGURE_DEFINES",
)
}
for k, v in config["OLD_CONFIGURE_SUBSTS"]:
sanitized_config["substs"][k] = sanitize_config(v)
sanitized_config["defines"] = {
k: sanitize_config(v) for k, v in config["DEFINES"].items()
}
for k, v in config["OLD_CONFIGURE_DEFINES"]:
sanitized_config["defines"][k] = sanitize_config(v)
sanitized_config["topsrcdir"] = config["TOPSRCDIR"]
sanitized_config["topobjdir"] = config["TOPOBJDIR"]
sanitized_config["mozconfig"] = config.get("MOZCONFIG")

View file

@ -54,6 +54,8 @@ export class QuickOpenModal extends Component {
// Put it on the class so it can be retrieved in tests
static UPDATE_RESULTS_THROTTLE = 100;
#willUnmountCalled = false;
constructor(props) {
super(props);
this.state = { results: null, selectedIndex: 0 };
@ -113,6 +115,10 @@ export class QuickOpenModal extends Component {
}
}
componentWillUnmount() {
this.#willUnmountCalled = true;
}
closeModal = () => {
this.props.closeQuickOpen();
};
@ -209,27 +215,37 @@ export class QuickOpenModal extends Component {
);
};
updateResults = throttle(query => {
if (this.isGotoQuery()) {
return;
}
updateResults = throttle(async query => {
try {
if (this.isGotoQuery()) {
return;
}
if (query == "" && !this.isShortcutQuery()) {
this.showTopSources();
return;
}
if (query == "" && !this.isShortcutQuery()) {
this.showTopSources();
return;
}
if (this.isSymbolSearch()) {
this.searchSymbols(query);
return;
}
if (this.isSymbolSearch()) {
await this.searchSymbols(query);
return;
}
if (this.isShortcutQuery()) {
this.searchShortcuts(query);
return;
}
if (this.isShortcutQuery()) {
this.searchShortcuts(query);
return;
}
this.searchSources(query);
this.searchSources(query);
} catch (e) {
// Due to throttling this might get scheduled after the component and the
// toolbox are destroyed.
if (this.#willUnmountCalled) {
console.warn("Throttled QuickOpen.updateResults failed", e);
} else {
throw e;
}
}
}, QuickOpenModal.UPDATE_RESULTS_THROTTLE);
setModifier = item => {

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