Update On Wed Apr 9 15:26:42 CEST 2025
This commit is contained in:
parent
9798769c58
commit
35b863fd86
1555 changed files with 67352 additions and 39669 deletions
269
Cargo.lock
generated
269
Cargo.lock
generated
|
@ -16,18 +16,6 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.0"
|
||||
|
@ -189,38 +177,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47cbc3cf73fa8d9833727bbee4835ba5c421a0d65b72daf9a7b5d0e0f9cfb57e"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"askama_escape",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c22fbe0413545c098358e56966ff22cdd039e10215ae213cfbd65032b119fc94"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"nom",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_escape"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||
|
||||
[[package]]
|
||||
name = "async-task"
|
||||
version = "4.3.0"
|
||||
|
@ -467,7 +423,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.999.999",
|
||||
"shlex",
|
||||
"syn",
|
||||
]
|
||||
|
@ -1836,7 +1792,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "error-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"error-support-macros",
|
||||
"lazy_static",
|
||||
|
@ -1848,7 +1804,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "error-support-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1965,7 +1921,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "firefox-versioning"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"thiserror 1.999.999",
|
||||
|
@ -2017,7 +1973,7 @@ dependencies = [
|
|||
"fluent-syntax",
|
||||
"intl-memoizer",
|
||||
"intl_pluralrules",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.999.999",
|
||||
"self_cell",
|
||||
"smallvec",
|
||||
"unic-langid",
|
||||
|
@ -2034,7 +1990,7 @@ dependencies = [
|
|||
"fluent-bundle",
|
||||
"futures",
|
||||
"once_cell",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.999.999",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
|
@ -2128,6 +2084,12 @@ dependencies = [
|
|||
"xpcom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.5.0"
|
||||
|
@ -2618,9 +2580,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glean"
|
||||
version = "63.1.0"
|
||||
version = "64.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2afa6754943cac5243099efd0d26e89cc8e06f1585776ba14ab0c6ee99e1f71"
|
||||
checksum = "251b9cb685554b96dcf785dba69ce90447006dd6d9229db783336c981c3777e1"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"glean-core",
|
||||
|
@ -2632,9 +2594,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glean-core"
|
||||
version = "63.1.0"
|
||||
version = "64.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53cd53bb7a3b89b17d3989e95dd808b137ff47c504d1d19f14cb0d820cc2f42e"
|
||||
checksum = "a49d1d62648ddeed8cb996373046ea45de93f1d1ff956aba054b9304bc305753"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"bincode",
|
||||
|
@ -2770,7 +2732,7 @@ checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557"
|
|||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"gpu-descriptor-types",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.14.999",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2843,17 +2805,25 @@ dependencies = [
|
|||
name = "hashbrown"
|
||||
version = "0.13.999"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
version = "0.14.999"
|
||||
dependencies = [
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
@ -2863,7 +2833,7 @@ version = "0.9.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.14.999",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3241,12 +3211,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.5.0"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
||||
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.15.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
@ -3264,7 +3234,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "interrupt-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
|
@ -3346,9 +3316,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.5"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "jexl-eval"
|
||||
|
@ -3484,7 +3454,7 @@ dependencies = [
|
|||
"futures",
|
||||
"pin-project-lite",
|
||||
"replace_with",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.999.999",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
|
@ -4536,12 +4506,12 @@ dependencies = [
|
|||
"cfg_aliases",
|
||||
"codespan-reporting",
|
||||
"half 2.5.0",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.14.999",
|
||||
"hexf-parse",
|
||||
"indexmap",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.999.999",
|
||||
"serde",
|
||||
"spirv",
|
||||
"strum",
|
||||
|
@ -4970,7 +4940,7 @@ checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
|
|||
[[package]]
|
||||
name = "payload-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
@ -5107,6 +5077,14 @@ dependencies = [
|
|||
"bindgen 0.69.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs11testmodule-static"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mozilla-central-workspace-hack",
|
||||
"pkcs11-bindings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.26"
|
||||
|
@ -5466,7 +5444,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
|||
[[package]]
|
||||
name = "relevancy"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.999",
|
||||
|
@ -5491,7 +5469,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "remote_settings"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
|
@ -5536,6 +5514,45 @@ dependencies = [
|
|||
"cache-padded",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dc4940d00595430b3d7d5a01f6222b5e5b51395d1120bdb28d854bb8abb17a5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"rinja_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_derive"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d9ed0146aef6e2825f1b1515f074510549efba38d71f4554eec32eb36ba18b"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"memchr",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rinja_parser",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rinja_parser"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f9a866e2e00a7a1fb27e46e9e324a6f7c0e7edc4543cae1d38f4e4a100c610"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"nom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rkv"
|
||||
version = "0.19.0"
|
||||
|
@ -5688,9 +5705,16 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
|||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
version = "1.999.999"
|
||||
dependencies = [
|
||||
"rustc-hash 2.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
|
@ -5776,7 +5800,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "search"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"error-support",
|
||||
"firefox-versioning",
|
||||
|
@ -6066,7 +6090,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "sql-support"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"interrupt-support",
|
||||
"lazy_static",
|
||||
|
@ -6265,7 +6289,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
|||
[[package]]
|
||||
name = "suggest"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
@ -6317,7 +6341,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "sync-guid"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"base64 0.21.999",
|
||||
"rand",
|
||||
|
@ -6328,7 +6352,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "sync15"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
|
@ -6368,7 +6392,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "tabs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
|
@ -6694,7 +6718,7 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46"
|
||||
dependencies = [
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.999.999",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -6712,7 +6736,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
|||
[[package]]
|
||||
name = "types"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"rusqlite",
|
||||
"serde",
|
||||
|
@ -6802,9 +6826,9 @@ checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
|||
|
||||
[[package]]
|
||||
name = "uniffi"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51ce6280c581045879e11b400bae14686a819df22b97171215d15549efa04ddb"
|
||||
checksum = "fe34585ac0275accf6c284d0080cc2840f3898c551cda869ec291b5a4218712c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_metadata",
|
||||
|
@ -6819,12 +6843,12 @@ name = "uniffi-bindgen-gecko-js"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"clap",
|
||||
"extend",
|
||||
"heck",
|
||||
"rinja",
|
||||
"serde",
|
||||
"textwrap",
|
||||
"toml",
|
||||
|
@ -6924,12 +6948,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e9f25730c9db2e878521d606f54e921edb719cdd94d735e7f97705d6796d024"
|
||||
checksum = "1a792af1424cc8b3c43b44c1a6cb7935ed1fbe5584a74f70e8bab9799740266d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"fs-err",
|
||||
|
@ -6938,6 +6961,7 @@ dependencies = [
|
|||
"heck",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"rinja",
|
||||
"serde",
|
||||
"textwrap",
|
||||
"toml",
|
||||
|
@ -6948,9 +6972,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_build"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88dba57ac699bd8ec53d6a352c8dd0e479b33f698c5659831bb1e4ce468c07bd"
|
||||
checksum = "00c4138211f2ae951018fcce6a978e1fcd1a47c3fd0bc0d5472a520520060db1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
|
@ -6958,36 +6982,33 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_checksum_derive"
|
||||
version = "0.28.2"
|
||||
name = "uniffi_core"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2c801f0f05b06df456a2da4c41b9c2c4fdccc6b9916643c6c67275c4c9e4d07"
|
||||
checksum = "c18baace68a52666d33d12d73ca335ecf27a302202cefb53b1f974512bb72417"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"once_cell",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_internal_macros"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9902d4ed16c65e6c0222241024dd0bfeed07ea3deb7c470eb175e5f5ef406cd"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_core"
|
||||
version = "0.28.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61049e4db6212d0ede80982adf0e1d6fa224e6118387324c5cfbe3083dfb2252"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"log",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b40fd2249e0c5dcbd2bfa3c263db1ec981f7273dca7f4132bf06a272359a586c"
|
||||
checksum = "9d82c82ef945c51082d8763635334b994e63e77650f09d0fae6d28dd08b1de83"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
|
@ -7001,21 +7022,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_meta"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9ad57039b4fafdbf77428d74fff40e0908e5a1731e023c19cfe538f6d4a8ed6"
|
||||
checksum = "8d6027b971c2aa86350dd180aee9819729c7b99bacd381534511ff29d2c09cea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"siphasher",
|
||||
"uniffi_checksum_derive",
|
||||
"uniffi_internal_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_testing"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21fa171d4d258dc51bbd01893cc9608c1b62273d2f9ea55fb64f639e77824567"
|
||||
checksum = "6301bcb50098dabcd304485318ba73f0f4db5e5d9d3c385c60b967810344ce90"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
|
@ -7026,14 +7046,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uniffi_udl"
|
||||
version = "0.28.2"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52299e247419e7e2934bef2f94d7cccb0e6566f3248b1d48b160d8f369a2668"
|
||||
checksum = "52300b7a4ab02dc159a038a13d5bfe27aefbad300d91b0b501b3dda094c1e0a2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"textwrap",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"weedle2",
|
||||
]
|
||||
|
||||
|
@ -7099,7 +7118,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||
[[package]]
|
||||
name = "viaduct"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"ffi-support",
|
||||
"log",
|
||||
|
@ -7269,7 +7288,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "webext-storage"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=d773da92641d92930b7308300e9fc2746a05ce6a#d773da92641d92930b7308300e9fc2746a05ce6a"
|
||||
source = "git+https://github.com/mozilla/application-services?rev=8e84c588a5cc2686973c5026ecd240d6275d7e94#8e84c588a5cc2686973c5026ecd240d6275d7e94"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"error-support",
|
||||
|
@ -7417,7 +7436,7 @@ dependencies = [
|
|||
"bytemuck",
|
||||
"cfg_aliases",
|
||||
"document-features",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.14.999",
|
||||
"indexmap",
|
||||
"log",
|
||||
"naga",
|
||||
|
@ -7425,7 +7444,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"profiling",
|
||||
"ron",
|
||||
"rustc-hash",
|
||||
"rustc-hash 1.999.999",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thiserror 2.0.9",
|
||||
|
@ -7468,7 +7487,7 @@ dependencies = [
|
|||
"gpu-alloc",
|
||||
"gpu-allocator",
|
||||
"gpu-descriptor",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown 0.14.999",
|
||||
"libc",
|
||||
"libloading",
|
||||
"log",
|
||||
|
|
37
Cargo.toml
37
Cargo.toml
|
@ -11,8 +11,9 @@ members = [
|
|||
"netwerk/test/http3server",
|
||||
"security/manager/ssl/ipcclientcerts",
|
||||
"security/manager/ssl/osclientcerts",
|
||||
"security/manager/ssl/trust_anchors",
|
||||
"security/manager/ssl/tests/unit/pkcs11testmodule",
|
||||
"security/manager/ssl/tests/unit/test_trust_anchors",
|
||||
"security/manager/ssl/trust_anchors",
|
||||
"security/mls/mls_gk",
|
||||
"testing/geckodriver",
|
||||
"toolkit/components/uniffi-bindgen-gecko-js",
|
||||
|
@ -61,12 +62,12 @@ rust-version = "1.82.0"
|
|||
|
||||
[workspace.dependencies]
|
||||
# Shared across multiple UniFFI consumers.
|
||||
uniffi = "0.28.2"
|
||||
uniffi_bindgen = "0.28.2"
|
||||
uniffi = "0.29.1"
|
||||
uniffi_bindgen = "0.29.1"
|
||||
# Shared across multiple application-services consumers.
|
||||
rusqlite = "0.31.0"
|
||||
# Shared across multiple glean consumers.
|
||||
glean = "=63.1.0"
|
||||
glean = "=64.0.1"
|
||||
|
||||
# Explicitly specify what our profiles use. The opt-level setting here is
|
||||
# a total fiction; see the setup of MOZ_RUST_DEFAULT_FLAGS for what the
|
||||
|
@ -176,11 +177,17 @@ goblin = { path = "build/rust/goblin" }
|
|||
# Implement getrandom 0.2 in terms of 0.3
|
||||
getrandom = { path = "build/rust/getrandom" }
|
||||
|
||||
# Patch rustc-hash 1.1.0 to 2.1.1
|
||||
rustc-hash = { path = "build/rust/rustc-hash" }
|
||||
|
||||
# Patch memoffset from 0.8.0 to 0.9.0 since it's compatible and it avoids duplication
|
||||
memoffset = { path = "build/rust/memoffset" }
|
||||
|
||||
# Patch `hashbrown` 0.12.* to depend on 0.14.*
|
||||
hashbrown = { path = "build/rust/hashbrown" }
|
||||
# Patch `hashbrown` 0.13.* to depend on 0.15.*
|
||||
hashbrown_0_13 = { package = "hashbrown", path = "build/rust/hashbrown-0.13" }
|
||||
|
||||
# Patch `hashbrown` 0.14.* to depend on 0.15.*
|
||||
hashbrown_0_14 = { package = "hashbrown", path = "build/rust/hashbrown" }
|
||||
|
||||
# Patch `socket2` 0.4 to 0.5
|
||||
socket2 = { path = "build/rust/socket2" }
|
||||
|
@ -244,14 +251,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 = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
relevancy = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
search = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "d773da92641d92930b7308300e9fc2746a05ce6a" }
|
||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
relevancy = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
search = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "8e84c588a5cc2686973c5026ecd240d6275d7e94" }
|
||||
|
||||
allocator-api2 = { path = "third_party/rust/allocator-api2" }
|
||||
|
|
|
@ -1264,9 +1264,10 @@ already_AddRefed<AccAttributes> LocalAccessible::NativeAttributes() {
|
|||
auto GetMargin = [&](mozilla::Side aSide) -> CSSCoord {
|
||||
// This is here only to guarantee that we do the same as getComputedStyle
|
||||
// does, so that we don't hit precision errors in tests.
|
||||
const auto& margin = f->StyleMargin()->GetMargin(aSide);
|
||||
if (margin.ConvertsToLength()) {
|
||||
return margin.AsLengthPercentage().ToLengthInCSSPixels();
|
||||
const auto margin =
|
||||
f->StyleMargin()->GetMargin(aSide, f->StyleDisplay()->mPosition);
|
||||
if (margin->ConvertsToLength()) {
|
||||
return margin->AsLengthPercentage().ToLengthInCSSPixels();
|
||||
}
|
||||
|
||||
nscoord coordVal = f->GetUsedMargin().Side(aSide);
|
||||
|
|
|
@ -43,16 +43,15 @@ support-files = [
|
|||
["test_focus_autocomplete.xhtml"]
|
||||
# Disabled on Linux and Windows due to frequent failures - bug 695019, bug 890795
|
||||
skip-if = [
|
||||
"os == 'win'",
|
||||
"os == 'linux'",
|
||||
"os == 'linux' && os_version == '18.04' && processor == 'x86_64'",
|
||||
"os == 'linux' && os_version == '22.04' && processor == 'x86_64'",
|
||||
"os == 'win' && os_version == '11.26100' && processor == 'x86_64'",
|
||||
"os == 'win' && os_version == '11.26100' && processor == 'x86'",
|
||||
]
|
||||
|
||||
["test_focus_canvas.html"]
|
||||
|
||||
["test_focus_contextmenu.xhtml"]
|
||||
skip-if = [
|
||||
"os == 'win' && os_version == '11.26100' && opt", # Bug 1865763
|
||||
]
|
||||
|
||||
["test_focus_controls.html"]
|
||||
|
||||
|
@ -73,7 +72,6 @@ skip-if = [
|
|||
["test_focus_selects.html"]
|
||||
|
||||
["test_focus_tabbox.xhtml"]
|
||||
skip-if = ["true"]
|
||||
|
||||
["test_focus_tree.xhtml"]
|
||||
|
||||
|
@ -97,13 +95,10 @@ skip-if = ["true"]
|
|||
|
||||
["test_selection.html"]
|
||||
skip-if = [
|
||||
"os == 'mac'",
|
||||
"os == 'mac' && os_version == '14.70' && processor == 'x86_64'",
|
||||
]
|
||||
|
||||
["test_selection.xhtml"]
|
||||
skip-if = [
|
||||
"os == 'mac'",
|
||||
]
|
||||
|
||||
["test_selection_aria.html"]
|
||||
|
||||
|
@ -123,5 +118,5 @@ skip-if = [
|
|||
|
||||
["test_valuechange.html"]
|
||||
skip-if = [
|
||||
"os == 'mac'",
|
||||
"os == 'mac' && os_version == '14.70' && processor == 'x86_64'",
|
||||
]
|
||||
|
|
|
@ -12,10 +12,11 @@ support-files = [
|
|||
["test_docload_iframe.html"]
|
||||
|
||||
["test_docload_root.html"]
|
||||
skip-if = ["os == 'mac'"] # bug 1456997
|
||||
skip-if = [
|
||||
"os == 'mac' && os_version == '14.70' && processor == 'x86_64'", # Bug 1456997
|
||||
]
|
||||
|
||||
["test_docload_shutdown.html"]
|
||||
skip-if = [
|
||||
"os == 'mac'", # bug 1456997
|
||||
"display == 'wayland'", # bug 1850412
|
||||
"os == 'mac' && os_version == '14.70' && processor == 'x86_64'", # Bug 1456997
|
||||
]
|
||||
|
|
|
@ -20,9 +20,6 @@ support-files = [
|
|||
["test_list.html"]
|
||||
|
||||
["test_markup.html"]
|
||||
skip-if = [
|
||||
"win11_2009 && debug", # Bug 1296784
|
||||
]
|
||||
|
||||
["test_svg.html"]
|
||||
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
support-files = "!/accessible/tests/mochitest/*.js"
|
||||
|
||||
["test_embeds.xhtml"]
|
||||
skip-if = [
|
||||
"os == 'linux' && !debug", # bug 1411145
|
||||
]
|
||||
|
||||
["test_general.html"]
|
||||
|
||||
|
|
|
@ -55,6 +55,3 @@ support-files = [
|
|||
["test_visibility.html"]
|
||||
|
||||
["test_visibility.xhtml"]
|
||||
skip-if = [
|
||||
"asan", # Bug 1199631
|
||||
]
|
||||
|
|
|
@ -10,7 +10,13 @@ support-files = [
|
|||
"!/dom/media/test/bug461281.ogg"]
|
||||
|
||||
["test_applicationacc.xhtml"]
|
||||
skip-if = ["true"] # Bug 561508
|
||||
skip-if = [
|
||||
"os == 'linux' && os_version == '18.04' && processor == 'x86_64'", # Bug 561508
|
||||
"os == 'linux' && os_version == '22.04' && processor == 'x86_64'", # Bug 561508
|
||||
"os == 'mac' && os_version == '14.70' && processor == 'x86_64'", # Bug 561508
|
||||
"os == 'win' && os_version == '11.26100' && processor == 'x86_64'", # Bug 561508
|
||||
"os == 'win' && os_version == '11.26100' && processor == 'x86'", # Bug 561508
|
||||
]
|
||||
|
||||
["test_aria_display_contents.html"]
|
||||
|
||||
|
@ -85,10 +91,6 @@ skip-if = ["true"] # Bug 561508
|
|||
["test_tabbox.xhtml"]
|
||||
|
||||
["test_tabbrowser.xhtml"]
|
||||
skip-if = [
|
||||
"os == 'linux' && debug", # Bug 1389365
|
||||
"os == 'win' && ccov", # Bug 1423218
|
||||
]
|
||||
|
||||
["test_table.html"]
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindowMac.xhtml");
|
||||
#ifdef XP_MACOSX
|
||||
pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindowMac.xhtml");
|
||||
#endif
|
||||
|
||||
// Set add-ons abuse report related prefs specific to Firefox Desktop.
|
||||
pref("extensions.abuseReport.enabled", true);
|
||||
|
@ -383,8 +385,6 @@ pref("browser.theme.colorway-closet", true);
|
|||
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
pref("browser.theme.native-theme", true);
|
||||
#elif defined(XP_MACOSX) && defined(NIGHTLY_BUILD)
|
||||
pref("browser.theme.native-theme", true);
|
||||
#else
|
||||
pref("browser.theme.native-theme", false);
|
||||
#endif
|
||||
|
@ -1059,7 +1059,13 @@ pref("browser.tabs.groups.enabled", true);
|
|||
#else
|
||||
pref("browser.tabs.groups.enabled", false);
|
||||
#endif
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("browser.tabs.groups.smart.enabled", true);
|
||||
#else
|
||||
pref("browser.tabs.groups.smart.enabled", false);
|
||||
#endif
|
||||
|
||||
pref("browser.tabs.groups.smart.optin", false);
|
||||
|
||||
pref("browser.tabs.dragDrop.createGroup.delayMS", 240);
|
||||
|
|
|
@ -375,6 +375,7 @@ var gBrowserInit = {
|
|||
Services.obs.addObserver(gXPInstallObserver, "addon-install-failed");
|
||||
Services.obs.addObserver(gXPInstallObserver, "addon-install-confirmation");
|
||||
Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup");
|
||||
Services.obs.addObserver(gLocaleChangeObserver, "intl:app-locales-changed");
|
||||
|
||||
BrowserOffline.init();
|
||||
CanvasPermissionPromptHelper.init();
|
||||
|
@ -1103,6 +1104,10 @@ var gBrowserInit = {
|
|||
"addon-install-confirmation"
|
||||
);
|
||||
Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
|
||||
Services.obs.removeObserver(
|
||||
gLocaleChangeObserver,
|
||||
"intl:app-locales-changed"
|
||||
);
|
||||
|
||||
MenuTouchModeObserver.uninit();
|
||||
BrowserOffline.uninit();
|
||||
|
|
|
@ -219,12 +219,6 @@ var gIdentityHandler = {
|
|||
"identity-popup-remove-cert-exception": () => {
|
||||
this.removeCertException();
|
||||
},
|
||||
"identity-popup-disable-mixed-content-blocking": () => {
|
||||
this.disableMixedContentProtection();
|
||||
},
|
||||
"identity-popup-enable-mixed-content-blocking": () => {
|
||||
this.enableMixedContentProtection();
|
||||
},
|
||||
"identity-popup-more-info": event => {
|
||||
this.handleMoreInfoClick(event);
|
||||
},
|
||||
|
@ -490,49 +484,6 @@ var gIdentityHandler = {
|
|||
Services.focus.clearFocus(window);
|
||||
},
|
||||
|
||||
disableMixedContentProtection() {
|
||||
// Use telemetry to measure how often unblocking happens
|
||||
const kMIXED_CONTENT_UNBLOCK_EVENT = 2;
|
||||
Glean.mixedContent.unblockCounter.accumulateSingleSample(
|
||||
kMIXED_CONTENT_UNBLOCK_EVENT
|
||||
);
|
||||
|
||||
SitePermissions.setForPrincipal(
|
||||
gBrowser.contentPrincipal,
|
||||
"mixed-content",
|
||||
SitePermissions.ALLOW,
|
||||
SitePermissions.SCOPE_SESSION
|
||||
);
|
||||
|
||||
// Reload the page with the content unblocked
|
||||
BrowserCommands.reloadWithFlags(
|
||||
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE
|
||||
);
|
||||
if (this._popupInitialized) {
|
||||
PanelMultiView.hidePopup(this._identityPopup);
|
||||
}
|
||||
},
|
||||
|
||||
// This is needed for some tests which need the permission reset, but which
|
||||
// then reuse the browser and would race between the reload and the next
|
||||
// load.
|
||||
enableMixedContentProtectionNoReload() {
|
||||
this.enableMixedContentProtection(false);
|
||||
},
|
||||
|
||||
enableMixedContentProtection(reload = true) {
|
||||
SitePermissions.removeFromPrincipal(
|
||||
gBrowser.contentPrincipal,
|
||||
"mixed-content"
|
||||
);
|
||||
if (reload) {
|
||||
BrowserCommands.reload();
|
||||
}
|
||||
if (this._popupInitialized) {
|
||||
PanelMultiView.hidePopup(this._identityPopup);
|
||||
}
|
||||
},
|
||||
|
||||
removeCertException() {
|
||||
if (!this._uriHasHost) {
|
||||
console.error(
|
||||
|
|
|
@ -341,6 +341,10 @@ if (AppConstants.ENABLE_WEBDRIVER) {
|
|||
ChromeUtils.defineLazyGetter(this, "RTL_UI", () => {
|
||||
return Services.locale.isAppLocaleRTL;
|
||||
});
|
||||
function gLocaleChangeObserver() {
|
||||
delete window.RTL_UI;
|
||||
window.RTL_UI = Services.locale.isAppLocaleRTL;
|
||||
}
|
||||
|
||||
ChromeUtils.defineLazyGetter(this, "gBrandBundle", () => {
|
||||
return Services.strings.createBundle(
|
||||
|
@ -1248,11 +1252,15 @@ var gKeywordURIFixup = {
|
|||
},
|
||||
};
|
||||
|
||||
Services.uriFixup.checkHost(
|
||||
fixedURI,
|
||||
onLookupCompleteListener,
|
||||
contentPrincipal.originAttributes
|
||||
);
|
||||
try {
|
||||
Services.uriFixup.checkHost(
|
||||
fixedURI,
|
||||
onLookupCompleteListener,
|
||||
contentPrincipal.originAttributes
|
||||
);
|
||||
} catch (ex) {
|
||||
// Ignore errors.
|
||||
}
|
||||
},
|
||||
|
||||
observe(fixupInfo) {
|
||||
|
|
|
@ -228,6 +228,7 @@
|
|||
"Marionette",
|
||||
"RemoteAgent",
|
||||
"RTL_UI",
|
||||
"gLocaleChangeObserver",
|
||||
"gBrandBundle",
|
||||
"gBrowserBundle",
|
||||
"gCustomizeMode",
|
||||
|
|
|
@ -32,8 +32,8 @@ add_task(async function test_user_namespaces() {
|
|||
const expectedBackgroundColor = content.window.matchMedia(
|
||||
"(prefers-color-scheme: dark)"
|
||||
).matches
|
||||
? "rgb(105, 15, 34)"
|
||||
: "rgb(255, 232, 232)";
|
||||
? "oklch(0.34 0.14 15)"
|
||||
: "oklch(0.97 0.05 15)";
|
||||
|
||||
return !![...tr]
|
||||
.filter(
|
||||
|
|
|
@ -498,24 +498,20 @@ add_task(async function testArrowsInPanelMultiView() {
|
|||
// Test that right/left arrows move in the expected direction for RTL locales.
|
||||
add_task(async function testArrowsRtl() {
|
||||
AddOldMenuSideButtons();
|
||||
await SpecialPowers.pushPrefEnv({ set: [["intl.l10n.pseudo", "bidi"]] });
|
||||
// window.RTL_UI doesn't update in existing windows when this pref is changed,
|
||||
// so we need to test in a new window.
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
startFromUrlBar(win);
|
||||
await expectFocusAfterKey("Tab", afterUrlBarButton, false, win);
|
||||
EventUtils.synthesizeKey("KEY_ArrowRight", {}, win);
|
||||
await BrowserTestUtils.enableRtlLocale();
|
||||
startFromUrlBar(window);
|
||||
await expectFocusAfterKey("Tab", afterUrlBarButton);
|
||||
EventUtils.synthesizeKey("KEY_ArrowRight", {});
|
||||
is(
|
||||
win.document.activeElement.id,
|
||||
document.activeElement.id,
|
||||
afterUrlBarButton,
|
||||
"ArrowRight at end of button group does nothing"
|
||||
);
|
||||
await expectFocusAfterKey("ArrowLeft", "library-button", false, win);
|
||||
await expectFocusAfterKey("ArrowLeft", "library-button");
|
||||
if (!sidebarRevampEnabled) {
|
||||
await expectFocusAfterKey("ArrowLeft", "sidebar-button", false, win);
|
||||
await expectFocusAfterKey("ArrowLeft", "sidebar-button");
|
||||
}
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await BrowserTestUtils.disableRtlLocale();
|
||||
RemoveOldMenuSideButtons();
|
||||
});
|
||||
|
||||
|
|
|
@ -55,6 +55,12 @@ const knownUnshownImages = [
|
|||
// This file is not loaded on Windows 7/8.
|
||||
intermittentNotLoaded: ["win"],
|
||||
},
|
||||
|
||||
{
|
||||
file: "chrome://global/skin/icons/highlights.svg",
|
||||
platforms: ["win", "linux", "macosx"],
|
||||
intermittentShown: ["win", "linux"],
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function () {
|
||||
|
|
|
@ -9,47 +9,6 @@ support-files = [
|
|||
https_first_disabled = true
|
||||
support-files = ["open-self-from-frame.html"]
|
||||
|
||||
["browser_bug822367.js"]
|
||||
tags = "mcb"
|
||||
support-files = [
|
||||
"file_bug822367_1.html",
|
||||
"file_bug822367_1.js",
|
||||
"file_bug822367_2.html",
|
||||
"file_bug822367_3.html",
|
||||
"file_bug822367_4.html",
|
||||
"file_bug822367_4.js",
|
||||
"file_bug822367_4B.html",
|
||||
"file_bug822367_5.html",
|
||||
"file_bug822367_6.html",
|
||||
]
|
||||
|
||||
["browser_bug902156.js"]
|
||||
tags = "mcb"
|
||||
support-files = [
|
||||
"file_bug902156.js",
|
||||
"file_bug902156_1.html",
|
||||
"file_bug902156_2.html",
|
||||
"file_bug902156_3.html",
|
||||
]
|
||||
|
||||
["browser_bug906190.js"]
|
||||
tags = "mcb"
|
||||
support-files = [
|
||||
"file_bug906190_1.html",
|
||||
"file_bug906190_2.html",
|
||||
"file_bug906190_3_4.html",
|
||||
"file_bug906190_redirected.html",
|
||||
"file_bug906190.js",
|
||||
"file_bug906190.sjs",
|
||||
]
|
||||
|
||||
["browser_bug1045809.js"]
|
||||
tags = "mcb"
|
||||
support-files = [
|
||||
"file_bug1045809_1.html",
|
||||
"file_bug1045809_2.html",
|
||||
]
|
||||
|
||||
["browser_check_identity_state.js"]
|
||||
skip-if = ["os == 'win' && !debug && msix"] # Bug 1895285
|
||||
https_first_disabled = true
|
||||
|
@ -157,7 +116,7 @@ support-files = ["test-mixedcontent-securityerrors.html"]
|
|||
tags = "mcb"
|
||||
support-files = [
|
||||
"file_mixedPassiveContent.html",
|
||||
"file_bug1045809_1.html",
|
||||
"file_mixedActiveContent_1.html",
|
||||
]
|
||||
|
||||
["browser_mixed_passive_content_indicator.js"]
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
// Test that the Mixed Content Doorhanger Action to re-enable protection works
|
||||
|
||||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
const PREF_INSECURE = "security.insecure_connection_icon.enabled";
|
||||
const TEST_URL =
|
||||
getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://example.com"
|
||||
) + "file_bug1045809_1.html";
|
||||
|
||||
var origBlockActive;
|
||||
|
||||
add_task(async function () {
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.setBoolPref(PREF_ACTIVE, origBlockActive);
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
// Store original preferences so we can restore settings after testing
|
||||
origBlockActive = Services.prefs.getBoolPref(PREF_ACTIVE);
|
||||
|
||||
// Make sure mixed content blocking is on
|
||||
Services.prefs.setBoolPref(PREF_ACTIVE, true);
|
||||
|
||||
let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser));
|
||||
|
||||
// Check with insecure lock disabled
|
||||
await SpecialPowers.pushPrefEnv({ set: [[PREF_INSECURE, false]] });
|
||||
await runTests(tab);
|
||||
|
||||
// Check with insecure lock disabled
|
||||
await SpecialPowers.pushPrefEnv({ set: [[PREF_INSECURE, true]] });
|
||||
await runTests(tab);
|
||||
});
|
||||
|
||||
async function runTests(tab) {
|
||||
// Test 1: mixed content must be blocked
|
||||
await promiseTabLoadEvent(tab, TEST_URL);
|
||||
await test1(gBrowser.getBrowserForTab(tab));
|
||||
|
||||
await promiseTabLoadEvent(tab);
|
||||
// Test 2: mixed content must NOT be blocked
|
||||
await test2(gBrowser.getBrowserForTab(tab));
|
||||
|
||||
// Test 3: mixed content must be blocked again
|
||||
await promiseTabLoadEvent(tab);
|
||||
await test3(gBrowser.getBrowserForTab(tab));
|
||||
}
|
||||
|
||||
async function test1(gTestBrowser) {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gTestBrowser, [], function () {
|
||||
let iframe = content.document.getElementsByTagName("iframe")[0];
|
||||
|
||||
SpecialPowers.spawn(iframe, [], () => {
|
||||
let container = content.document.getElementById("mixedContentContainer");
|
||||
is(container, null, "Mixed Content is NOT to be found in Test1");
|
||||
});
|
||||
});
|
||||
|
||||
// Disable Mixed Content Protection for the page (and reload)
|
||||
gIdentityHandler.disableMixedContentProtection();
|
||||
}
|
||||
|
||||
async function test2(gTestBrowser) {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gTestBrowser, [], function () {
|
||||
let iframe = content.document.getElementsByTagName("iframe")[0];
|
||||
|
||||
SpecialPowers.spawn(iframe, [], () => {
|
||||
let container = content.document.getElementById("mixedContentContainer");
|
||||
isnot(container, null, "Mixed Content is to be found in Test2");
|
||||
});
|
||||
});
|
||||
|
||||
// Re-enable Mixed Content Protection for the page (and reload)
|
||||
gIdentityHandler.enableMixedContentProtection();
|
||||
}
|
||||
|
||||
async function test3(gTestBrowser) {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gTestBrowser, [], function () {
|
||||
let iframe = content.document.getElementsByTagName("iframe")[0];
|
||||
|
||||
SpecialPowers.spawn(iframe, [], () => {
|
||||
let container = content.document.getElementById("mixedContentContainer");
|
||||
is(container, null, "Mixed Content is NOT to be found in Test3");
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
/*
|
||||
* User Override Mixed Content Block - Tests for Bug 822367
|
||||
*/
|
||||
|
||||
const PREF_DISPLAY = "security.mixed_content.block_display_content";
|
||||
const PREF_DISPLAY_UPGRADE = "security.mixed_content.upgrade_display_content";
|
||||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
|
||||
// We alternate for even and odd test cases to simulate different hosts
|
||||
const HTTPS_TEST_ROOT = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://example.com"
|
||||
);
|
||||
const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://test1.example.com"
|
||||
);
|
||||
|
||||
var gTestBrowser = null;
|
||||
|
||||
add_task(async function test() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[PREF_DISPLAY, true],
|
||||
[PREF_DISPLAY_UPGRADE, false],
|
||||
[PREF_ACTIVE, true],
|
||||
],
|
||||
});
|
||||
|
||||
var newTab = BrowserTestUtils.addTab(gBrowser);
|
||||
gBrowser.selectedTab = newTab;
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
newTab.linkedBrowser.stop();
|
||||
|
||||
// Mixed Script Test
|
||||
var url = HTTPS_TEST_ROOT + "file_bug822367_1.html";
|
||||
BrowserTestUtils.startLoadingURIString(gTestBrowser, url);
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser, false, url);
|
||||
});
|
||||
|
||||
// Mixed Script Test
|
||||
add_task(async function MixedTest1A() {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.disableMixedContentProtection();
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest1B() {
|
||||
await SpecialPowers.spawn(gTestBrowser, [], async function () {
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.getElementById("p1").innerHTML == "hello",
|
||||
"Waited too long for mixed script to run in Test 1"
|
||||
);
|
||||
});
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.enableMixedContentProtectionNoReload();
|
||||
});
|
||||
|
||||
// Mixed Display Test - Doorhanger should not appear
|
||||
add_task(async function MixedTest2() {
|
||||
var url = HTTPS_TEST_ROOT_2 + "file_bug822367_2.html";
|
||||
BrowserTestUtils.startLoadingURIString(gTestBrowser, url);
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser, false, url);
|
||||
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
});
|
||||
|
||||
// Mixed Script and Display Test - User Override should cause both the script and the image to load.
|
||||
add_task(async function MixedTest3() {
|
||||
var url = HTTPS_TEST_ROOT + "file_bug822367_3.html";
|
||||
BrowserTestUtils.startLoadingURIString(gTestBrowser, url);
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser, false, url);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest3A() {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.disableMixedContentProtection();
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest3B() {
|
||||
await SpecialPowers.spawn(gTestBrowser, [], async function () {
|
||||
let p1 = ContentTaskUtils.waitForCondition(
|
||||
() => content.document.getElementById("p1").innerHTML == "hello",
|
||||
"Waited too long for mixed script to run in Test 3"
|
||||
);
|
||||
let p2 = ContentTaskUtils.waitForCondition(
|
||||
() => content.document.getElementById("p2").innerHTML == "bye",
|
||||
"Waited too long for mixed image to load in Test 3"
|
||||
);
|
||||
await Promise.all([p1, p2]);
|
||||
});
|
||||
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: true,
|
||||
});
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.enableMixedContentProtectionNoReload();
|
||||
});
|
||||
|
||||
// Location change - User override on one page doesn't propagate to another page after location change.
|
||||
add_task(async function MixedTest4() {
|
||||
var url = HTTPS_TEST_ROOT_2 + "file_bug822367_4.html";
|
||||
BrowserTestUtils.startLoadingURIString(gTestBrowser, url);
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser, false, url);
|
||||
});
|
||||
|
||||
let preLocationChangePrincipal = null;
|
||||
add_task(async function MixedTest4A() {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
preLocationChangePrincipal = gTestBrowser.contentPrincipal;
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.disableMixedContentProtection();
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest4B() {
|
||||
let url = HTTPS_TEST_ROOT + "file_bug822367_4B.html";
|
||||
await SpecialPowers.spawn(gTestBrowser, [url], async function (wantedUrl) {
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.location == wantedUrl,
|
||||
"Waited too long for mixed script to run in Test 4"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function MixedTest4C() {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gTestBrowser, [], async function () {
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.getElementById("p1").innerHTML == "",
|
||||
"Mixed script loaded in test 4 after location change!"
|
||||
);
|
||||
});
|
||||
SitePermissions.removeFromPrincipal(
|
||||
preLocationChangePrincipal,
|
||||
"mixed-content"
|
||||
);
|
||||
});
|
||||
|
||||
// Mixed script attempts to load in a document.open()
|
||||
add_task(async function MixedTest5() {
|
||||
var url = HTTPS_TEST_ROOT + "file_bug822367_5.html";
|
||||
BrowserTestUtils.startLoadingURIString(gTestBrowser, url);
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser, false, url);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest5A() {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.disableMixedContentProtection();
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest5B() {
|
||||
await SpecialPowers.spawn(gTestBrowser, [], async function () {
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.getElementById("p1").innerHTML == "hello",
|
||||
"Waited too long for mixed script to run in Test 5"
|
||||
);
|
||||
});
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.enableMixedContentProtectionNoReload();
|
||||
});
|
||||
|
||||
// Mixed script attempts to load in a document.open() that is within an iframe.
|
||||
add_task(async function MixedTest6() {
|
||||
var url = HTTPS_TEST_ROOT_2 + "file_bug822367_6.html";
|
||||
BrowserTestUtils.startLoadingURIString(gTestBrowser, url);
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser, false, url);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest6A() {
|
||||
gTestBrowser.removeEventListener("load", MixedTest6A, true);
|
||||
let { gIdentityHandler } = gTestBrowser.ownerGlobal;
|
||||
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
|
||||
"Waited too long for control center to get mixed active blocked state"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest6B() {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.disableMixedContentProtection();
|
||||
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
});
|
||||
|
||||
add_task(async function MixedTest6C() {
|
||||
await SpecialPowers.spawn(gTestBrowser, [], async function () {
|
||||
function test() {
|
||||
try {
|
||||
return (
|
||||
content.document
|
||||
.getElementById("f1")
|
||||
.contentDocument.getElementById("p1").innerHTML == "hello"
|
||||
);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
test,
|
||||
"Waited too long for mixed script to run in Test 6"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function MixedTest6D() {
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
gTestBrowser.ownerGlobal.gIdentityHandler.enableMixedContentProtectionNoReload();
|
||||
});
|
||||
|
||||
add_task(async function cleanup() {
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
* Description of the Tests for
|
||||
* - Bug 902156: Persist "disable protection" option for Mixed Content Blocker
|
||||
*
|
||||
* 1. Navigate to the same domain via document.location
|
||||
* - Load a html page which has mixed content
|
||||
* - Control Center button to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin using document.location
|
||||
* - Control Center button should not appear anymore!
|
||||
*
|
||||
* 2. Navigate to the same domain via simulateclick for a link on the page
|
||||
* - Load a html page which has mixed content
|
||||
* - Control Center button to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin simulating a click
|
||||
* - Control Center button should not appear anymore!
|
||||
*
|
||||
* 3. Navigate to a differnet domain and show the content is still blocked
|
||||
* - Load a different html page which has mixed content
|
||||
* - Control Center button to disable protection should appear again because
|
||||
* we navigated away from html page where we disabled the protection.
|
||||
*
|
||||
* Note, for all tests we set gHttpTestRoot to use 'https'.
|
||||
*/
|
||||
|
||||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
|
||||
// We alternate for even and odd test cases to simulate different hosts.
|
||||
const HTTPS_TEST_ROOT_1 = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://test1.example.com"
|
||||
);
|
||||
const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://test2.example.com"
|
||||
);
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({ set: [[PREF_ACTIVE, true]] });
|
||||
});
|
||||
|
||||
add_task(async function test1() {
|
||||
let url = HTTPS_TEST_ROOT_1 + "file_bug902156_1.html";
|
||||
await BrowserTestUtils.withNewTab(url, async function (browser) {
|
||||
await assertMixedContentBlockingState(browser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
// Disable Mixed Content Protection for the page (and reload)
|
||||
let browserLoaded = BrowserTestUtils.browserLoaded(browser, false, url);
|
||||
let { gIdentityHandler } = browser.ownerGlobal;
|
||||
gIdentityHandler.disableMixedContentProtection();
|
||||
await browserLoaded;
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let expected = "Mixed Content Blocker disabled";
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() =>
|
||||
content.document.getElementById("mctestdiv").innerHTML == expected,
|
||||
"Error: Waited too long for mixed script to run in Test 1"
|
||||
);
|
||||
|
||||
let actual = content.document.getElementById("mctestdiv").innerHTML;
|
||||
is(
|
||||
actual,
|
||||
"Mixed Content Blocker disabled",
|
||||
"OK: Executed mixed script in Test 1"
|
||||
);
|
||||
});
|
||||
|
||||
// The Script loaded after we disabled the page, now we are going to reload the
|
||||
// page and see if our decision is persistent
|
||||
url = HTTPS_TEST_ROOT_1 + "file_bug902156_2.html";
|
||||
browserLoaded = BrowserTestUtils.browserLoaded(browser, false, url);
|
||||
BrowserTestUtils.startLoadingURIString(browser, url);
|
||||
await browserLoaded;
|
||||
|
||||
// The Control Center button should appear but isMixedContentBlocked should be NOT true,
|
||||
// because our decision of disabling the mixed content blocker is persistent.
|
||||
await assertMixedContentBlockingState(browser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
await SpecialPowers.spawn(browser, [], function () {
|
||||
let actual = content.document.getElementById("mctestdiv").innerHTML;
|
||||
is(
|
||||
actual,
|
||||
"Mixed Content Blocker disabled",
|
||||
"OK: Executed mixed script in Test 1"
|
||||
);
|
||||
});
|
||||
gIdentityHandler.enableMixedContentProtection();
|
||||
});
|
||||
});
|
||||
|
||||
// ------------------------ Test 2 ------------------------------
|
||||
|
||||
add_task(async function test2() {
|
||||
let url = HTTPS_TEST_ROOT_2 + "file_bug902156_2.html";
|
||||
await BrowserTestUtils.withNewTab(url, async function (browser) {
|
||||
await assertMixedContentBlockingState(browser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
// Disable Mixed Content Protection for the page (and reload)
|
||||
let browserLoaded = BrowserTestUtils.browserLoaded(browser, false, url);
|
||||
let { gIdentityHandler } = browser.ownerGlobal;
|
||||
gIdentityHandler.disableMixedContentProtection();
|
||||
await browserLoaded;
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let expected = "Mixed Content Blocker disabled";
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() =>
|
||||
content.document.getElementById("mctestdiv").innerHTML == expected,
|
||||
"Error: Waited too long for mixed script to run in Test 2"
|
||||
);
|
||||
|
||||
let actual = content.document.getElementById("mctestdiv").innerHTML;
|
||||
is(
|
||||
actual,
|
||||
"Mixed Content Blocker disabled",
|
||||
"OK: Executed mixed script in Test 2"
|
||||
);
|
||||
});
|
||||
|
||||
// The Script loaded after we disabled the page, now we are going to reload the
|
||||
// page and see if our decision is persistent
|
||||
url = HTTPS_TEST_ROOT_2 + "file_bug902156_1.html";
|
||||
browserLoaded = BrowserTestUtils.browserLoaded(browser, false, url);
|
||||
// reload the page using the provided link in the html file
|
||||
await SpecialPowers.spawn(browser, [], function () {
|
||||
let mctestlink = content.document.getElementById("mctestlink");
|
||||
mctestlink.click();
|
||||
});
|
||||
await browserLoaded;
|
||||
|
||||
// The Control Center button should appear but isMixedContentBlocked should be NOT true,
|
||||
// because our decision of disabling the mixed content blocker is persistent.
|
||||
await assertMixedContentBlockingState(browser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(browser, [], function () {
|
||||
let actual = content.document.getElementById("mctestdiv").innerHTML;
|
||||
is(
|
||||
actual,
|
||||
"Mixed Content Blocker disabled",
|
||||
"OK: Executed mixed script in Test 2"
|
||||
);
|
||||
});
|
||||
gIdentityHandler.enableMixedContentProtection();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test3() {
|
||||
let url = HTTPS_TEST_ROOT_1 + "file_bug902156_3.html";
|
||||
await BrowserTestUtils.withNewTab(url, async function (browser) {
|
||||
await assertMixedContentBlockingState(browser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,339 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Tests the persistence of the "disable protection" option for Mixed Content
|
||||
* Blocker in child tabs (bug 906190).
|
||||
*/
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
// We use the different urls for testing same origin checks before allowing
|
||||
// mixed content on child tabs.
|
||||
const HTTPS_TEST_ROOT_1 = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://test1.example.com"
|
||||
);
|
||||
const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://test2.example.com"
|
||||
);
|
||||
|
||||
/**
|
||||
* For all tests, we load the pages over HTTPS and test both:
|
||||
* - |CTRL+CLICK|
|
||||
* - |RIGHT CLICK -> OPEN LINK IN TAB|
|
||||
*/
|
||||
async function doTest(
|
||||
parentTabSpec,
|
||||
childTabSpec,
|
||||
testTaskFn,
|
||||
waitForMetaRefresh
|
||||
) {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url: parentTabSpec,
|
||||
},
|
||||
async function (browser) {
|
||||
// As a sanity check, test that active content has been blocked as expected.
|
||||
await assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
// Disable the Mixed Content Blocker for the page, which reloads it.
|
||||
let promiseReloaded = BrowserTestUtils.browserLoaded(browser);
|
||||
let principal = gBrowser.contentPrincipal;
|
||||
gIdentityHandler.disableMixedContentProtection();
|
||||
await promiseReloaded;
|
||||
|
||||
// Wait for the script in the page to update the contents of the test div.
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[childTabSpec],
|
||||
async childTabSpecContent => {
|
||||
let testDiv = content.document.getElementById("mctestdiv");
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => testDiv.innerHTML == "Mixed Content Blocker disabled"
|
||||
);
|
||||
|
||||
// Add the link for the child tab to the page.
|
||||
let mainDiv = content.document.createElement("div");
|
||||
|
||||
mainDiv.innerHTML =
|
||||
'<p><a id="linkToOpenInNewTab" href="' +
|
||||
childTabSpecContent +
|
||||
'">Link</a></p>';
|
||||
content.document.body.appendChild(mainDiv);
|
||||
}
|
||||
);
|
||||
|
||||
// Execute the test in the child tabs with the two methods to open it.
|
||||
for (let openFn of [simulateCtrlClick, simulateContextMenuOpenInTab]) {
|
||||
let promiseTabLoaded = waitForSomeTabToLoad();
|
||||
openFn(browser);
|
||||
await promiseTabLoaded;
|
||||
gBrowser.selectTabAtIndex(2);
|
||||
|
||||
if (waitForMetaRefresh) {
|
||||
await waitForSomeTabToLoad();
|
||||
}
|
||||
|
||||
await testTaskFn();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
|
||||
SitePermissions.removeFromPrincipal(principal, "mixed-content");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function simulateCtrlClick(browser) {
|
||||
BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
"#linkToOpenInNewTab",
|
||||
{ ctrlKey: true, metaKey: true },
|
||||
browser
|
||||
);
|
||||
}
|
||||
|
||||
function simulateContextMenuOpenInTab(browser) {
|
||||
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
|
||||
// These are operations that must be executed synchronously with the event.
|
||||
document.getElementById("context-openlinkintab").doCommand();
|
||||
event.target.hidePopup();
|
||||
return true;
|
||||
});
|
||||
BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
"#linkToOpenInNewTab",
|
||||
{ type: "contextmenu", button: 2 },
|
||||
browser
|
||||
);
|
||||
}
|
||||
|
||||
// Waits for a load event somewhere in the browser but ignore events coming
|
||||
// from <xul:browser>s without a tab assigned. That are most likely browsers
|
||||
// that preload the new tab page.
|
||||
function waitForSomeTabToLoad() {
|
||||
return BrowserTestUtils.firstBrowserLoaded(window, true, browser => {
|
||||
let tab = gBrowser.getTabForBrowser(browser);
|
||||
return !!tab;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the Mixed Content Blocker is enabled.
|
||||
*/
|
||||
add_task(async function test_initialize() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["security.mixed_content.block_active_content", true],
|
||||
// We need to disable the dFPI heuristic. So, we won't have unnecessary
|
||||
// 3rd party cookie permission that could affect following tests because
|
||||
// it will create a permission icon on the URL bar.
|
||||
["privacy.restrict3rdpartystorage.heuristic.recently_visited", false],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 1. - Load a html page which has mixed content
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a subpage from the same origin in a new tab simulating a click
|
||||
* - Doorhanger should >> NOT << appear anymore!
|
||||
*/
|
||||
add_task(async function test_same_origin() {
|
||||
await doTest(
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_2.html",
|
||||
async function () {
|
||||
// The doorhanger should appear but activeBlocked should be >> NOT << true,
|
||||
// because our decision of disabling the mixed content blocker is persistent
|
||||
// across tabs.
|
||||
await assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
|
||||
Assert.equal(
|
||||
content.document.getElementById("mctestdiv").innerHTML,
|
||||
"Mixed Content Blocker disabled",
|
||||
"OK: Executed mixed script"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 2. - Load a html page which has mixed content
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a new page from a different origin in a new tab simulating a click
|
||||
* - Doorhanger >> SHOULD << appear again!
|
||||
*/
|
||||
add_task(async function test_different_origin() {
|
||||
await doTest(
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_2.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190_2.html",
|
||||
async function () {
|
||||
// The doorhanger should appear and activeBlocked should be >> TRUE <<,
|
||||
// because our decision of disabling the mixed content blocker should only
|
||||
// persist if pages are from the same domain.
|
||||
await assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
|
||||
Assert.equal(
|
||||
content.document.getElementById("mctestdiv").innerHTML,
|
||||
"Mixed Content Blocker enabled",
|
||||
"OK: Blocked mixed script"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 3. - Load a html page which has mixed content
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin in a new tab simulating a click
|
||||
* - Redirect to another page from the same origin using meta-refresh
|
||||
* - Doorhanger should >> NOT << appear again!
|
||||
*/
|
||||
add_task(async function test_same_origin_metarefresh_same_origin() {
|
||||
// file_bug906190_3_4.html redirects to page test1.example.com/* using meta-refresh
|
||||
await doTest(
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_3_4.html",
|
||||
async function () {
|
||||
// The doorhanger should appear but activeBlocked should be >> NOT << true!
|
||||
await assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
|
||||
Assert.equal(
|
||||
content.document.getElementById("mctestdiv").innerHTML,
|
||||
"Mixed Content Blocker disabled",
|
||||
"OK: Executed mixed script"
|
||||
);
|
||||
});
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 4. - Load a html page which has mixed content
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin in a new tab simulating a click
|
||||
* - Redirect to another page from a different origin using meta-refresh
|
||||
* - Doorhanger >> SHOULD << appear again!
|
||||
*/
|
||||
add_task(async function test_same_origin_metarefresh_different_origin() {
|
||||
await doTest(
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190_3_4.html",
|
||||
async function () {
|
||||
// The doorhanger should appear and activeBlocked should be >> TRUE <<.
|
||||
await assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
|
||||
Assert.equal(
|
||||
content.document.getElementById("mctestdiv").innerHTML,
|
||||
"Mixed Content Blocker enabled",
|
||||
"OK: Blocked mixed script"
|
||||
);
|
||||
});
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 5. - Load a html page which has mixed content
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin in a new tab simulating a click
|
||||
* - Redirect to another page from the same origin using 302 redirect
|
||||
*/
|
||||
add_task(async function test_same_origin_302redirect_same_origin() {
|
||||
// the sjs files returns a 302 redirect- note, same origins
|
||||
await doTest(
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190.sjs",
|
||||
async function () {
|
||||
// The doorhanger should appear but activeBlocked should be >> NOT << true.
|
||||
// Currently it is >> TRUE << - see follow up bug 914860
|
||||
ok(
|
||||
!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
|
||||
"OK: Mixed Content is NOT being blocked"
|
||||
);
|
||||
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
|
||||
Assert.equal(
|
||||
content.document.getElementById("mctestdiv").innerHTML,
|
||||
"Mixed Content Blocker disabled",
|
||||
"OK: Executed mixed script"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 6. - Load a html page which has mixed content
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin in a new tab simulating a click
|
||||
* - Redirect to another page from a different origin using 302 redirect
|
||||
*/
|
||||
add_task(async function test_same_origin_302redirect_different_origin() {
|
||||
// the sjs files returns a 302 redirect - note, different origins
|
||||
await doTest(
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190.sjs",
|
||||
async function () {
|
||||
// The doorhanger should appear and activeBlocked should be >> TRUE <<.
|
||||
await assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: false,
|
||||
activeBlocked: true,
|
||||
passiveLoaded: false,
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
|
||||
Assert.equal(
|
||||
content.document.getElementById("mctestdiv").innerHTML,
|
||||
"Mixed Content Blocker enabled",
|
||||
"OK: Blocked mixed script"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 7. - Test memory leak issue on redirection error. See Bug 1269426.
|
||||
*/
|
||||
add_task(async function test_bad_redirection() {
|
||||
// the sjs files returns a 302 redirect - note, different origins
|
||||
await doTest(
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190.sjs?bad-redirection=1",
|
||||
function () {
|
||||
// Nothing to do. Just see if memory leak is reported in the end.
|
||||
ok(true, "Nothing to do");
|
||||
}
|
||||
);
|
||||
});
|
|
@ -45,12 +45,6 @@ add_task(async function () {
|
|||
await loadBadCertPage(MIXED_CONTENT_URL);
|
||||
checkIdentityPopup("security-warning.svg");
|
||||
|
||||
// check that the crossed out icon is shown when disabling mixed content protection
|
||||
gIdentityHandler.disableMixedContentProtection();
|
||||
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
|
||||
checkIdentityPopup("security-broken.svg");
|
||||
|
||||
// check that a warning is shown even without mixed content
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
gBrowser.selectedBrowser,
|
||||
|
|
|
@ -22,7 +22,7 @@ const kTestcases = [
|
|||
expectedIdentityMode: "mixedDisplayContent",
|
||||
},
|
||||
{
|
||||
uri: kBaseURI + "file_bug1045809_1.html",
|
||||
uri: kBaseURI + "file_mixedActiveContent_1.html",
|
||||
expectErrorPage: false,
|
||||
expectedIdentityMode: "mixedActiveBlocked",
|
||||
},
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
// loaded) we load the page and check the flags.
|
||||
// * We change the about:config prefs (mixed active blocked, mixed display
|
||||
// blocked), reload the page, and check the flags again.
|
||||
// * We override protection so all mixed content can load and check the
|
||||
// flags again.
|
||||
|
||||
const TEST_URI =
|
||||
getRootDirectory(gTestPath).replace(
|
||||
|
@ -56,16 +54,3 @@ add_task(async function blockMixedActiveContentTest() {
|
|||
passiveLoaded: false,
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function overrideMCB() {
|
||||
// Disable mixed content blocking (reloads page) and retest
|
||||
let { gIdentityHandler } = gTestBrowser.ownerGlobal;
|
||||
gIdentityHandler.disableMixedContentProtection();
|
||||
await BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
|
||||
await assertMixedContentBlockingState(gTestBrowser, {
|
||||
activeLoaded: true,
|
||||
activeBlocked: false,
|
||||
passiveLoaded: true,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 1 for Mixed Content Blocker User Override - Mixed Script
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 1 for Bug 822367</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1 +0,0 @@
|
|||
document.getElementById("p1").innerHTML = "hello";
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 2 for Mixed Content Blocker User Override - Mixed Display
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 2 for Bug 822367 - Mixed Display</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<img src="http://example.com/tests/image/test/mochitest/blue.png">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,27 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 3 for Mixed Content Blocker User Override - Mixed Script and Display
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 3 for Bug 822367</title>
|
||||
<script>
|
||||
function foo() {
|
||||
var x = document.createElement("p");
|
||||
x.setAttribute("id", "p2");
|
||||
x.innerHTML = "bye";
|
||||
document.getElementById("testContent").appendChild(x);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
<img src="http://example.com/tests/image/test/mochitest/blue.png" onload="foo()">
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 4 for Mixed Content Blocker User Override - Mixed Script and Display
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 4 for Bug 822367</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_4.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,2 +0,0 @@
|
|||
document.location =
|
||||
"https://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_4B.html";
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 4B for Mixed Content Blocker User Override - Location Changed
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 4B Location Change for Bug 822367</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 5 for Mixed Content Blocker User Override - Mixed Script in document.open()
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 5 for Bug 822367</title>
|
||||
<script>
|
||||
function createDoc() {
|
||||
var doc = document.open("text/html", "replace");
|
||||
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
|
||||
doc.close();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<img src="https://example.com/tests/image/test/mochitest/blue.png" onload="createDoc()">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 6 for Mixed Content Blocker User Override - Mixed Script in document.open() within an iframe
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 6 for Bug 822367</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<iframe name="f1" id="f1" src="https://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_5.html"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||
/*
|
||||
* Once the mixed content blocker is disabled for the page, this scripts loads
|
||||
* and updates the text inside the div container.
|
||||
*/
|
||||
document.getElementById("mctestdiv").innerHTML =
|
||||
"Mixed Content Blocker disabled";
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 1 for Bug 902156 - See file browser_bug902156.js for description.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=902156
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 1 for Bug 902156</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 2 for Bug 902156 - See file browser_bug902156.js for description.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=902156
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 2 for Bug 902156</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<a href="https://test2.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156_1.html"
|
||||
id="mctestlink" target="_top">Go to http site</a>
|
||||
<script src="http://test2.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 3 for Bug 902156 - See file browser_bug902156.js for description.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=902156
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 3 for Bug 902156</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||
/*
|
||||
* Once the mixed content blocker is disabled for the page, this scripts loads
|
||||
* and updates the text inside the div container.
|
||||
*/
|
||||
document.getElementById("mctestdiv").innerHTML =
|
||||
"Mixed Content Blocker disabled";
|
|
@ -1,18 +0,0 @@
|
|||
function handleRequest(request, response) {
|
||||
var page = "<!DOCTYPE html><html><body>bug 906190</body></html>";
|
||||
var path =
|
||||
"https://test1.example.com/browser/browser/base/content/test/siteIdentity/";
|
||||
var url;
|
||||
|
||||
if (request.queryString.includes("bad-redirection=1")) {
|
||||
url = path + "this_page_does_not_exist.html";
|
||||
} else {
|
||||
url = path + "file_bug906190_redirected.html";
|
||||
}
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.setStatusLine(request.httpVersion, "302", "Found");
|
||||
response.setHeader("Location", url, false);
|
||||
response.write(page);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 1 for Bug 906190 - See file browser_bug902156.js for description.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=906190
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 1 for Bug 906190</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 2 for Bug 906190 - See file browser_bug902156.js for description.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=906190
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 2 for Bug 906190</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test2.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,14 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test 3 and 4 for Bug 906190 - See file browser_bug902156.js for description.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=906190
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="0; url=https://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190_redirected.html">
|
||||
<title>Test 3 and 4 for Bug 906190</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Redirected Page of Test 3 to 6 for Bug 906190 - See file browser_bug902156.js for description.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=906190
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Redirected Page for Bug 906190</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -177,6 +177,10 @@ let propNameAllowlist = [
|
|||
|
||||
// Bug 1908535 to refactor form components to use this token
|
||||
{ propName: "--input-space-block", isFromDevTools: false },
|
||||
|
||||
// Ignore token properties that follow the pattern --color-[name]-[number]
|
||||
// This enables us to provide our full color palette for developers.
|
||||
{ propName: /--color-[a-z]+-\d+/, isFromDevTools: false },
|
||||
];
|
||||
|
||||
// Add suffix to stylesheets' URI so that we always load them here and
|
||||
|
@ -442,6 +446,13 @@ function shouldIgnorePropSource(item, prop) {
|
|||
.some(f => item.sourceName.test(f));
|
||||
}
|
||||
|
||||
function shouldIgnorePropPattern(item, prop) {
|
||||
if (!item.propName || !(item.propName instanceof RegExp)) {
|
||||
return false;
|
||||
}
|
||||
return item.propName.test(prop);
|
||||
}
|
||||
|
||||
add_task(async function checkAllTheCSS() {
|
||||
// Since we later in this test use Services.console.getMessageArray(),
|
||||
// better to not have some messages from previous tests in the array.
|
||||
|
@ -567,7 +578,9 @@ add_task(async function checkAllTheCSS() {
|
|||
for (let item of propNameAllowlist) {
|
||||
if (
|
||||
isDevtools == item.isFromDevTools &&
|
||||
(item.propName == prop || shouldIgnorePropSource(item, prop))
|
||||
(item.propName == prop ||
|
||||
shouldIgnorePropPattern(item, prop) ||
|
||||
shouldIgnorePropSource(item, prop))
|
||||
) {
|
||||
item.used = true;
|
||||
if (
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<?csp default-src chrome: ?>
|
||||
|
||||
<window id="webextpanels-window"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
@ -30,15 +32,10 @@
|
|||
<html:link rel="localization" href="browser/translations.ftl"/>
|
||||
</linkset>
|
||||
|
||||
<!-- nsContextMenu.initNavigationItems expects these elements -->
|
||||
<commandset id="mainCommandset">
|
||||
<command id="Browser:Back"
|
||||
oncommand="getPanelBrowser().webNavigation.goBack();"
|
||||
disabled="true"/>
|
||||
<command id="Browser:Forward"
|
||||
oncommand="getPanelBrowser().webNavigation.goForward();"
|
||||
disabled="true"/>
|
||||
<command id="Browser:Stop" oncommand="PanelBrowserStop();"/>
|
||||
<command id="Browser:Reload" oncommand="PanelBrowserReload();"/>
|
||||
<command id="Browser:Stop" disabled="true" />
|
||||
<command id="Browser:Reload" disabled="true" />
|
||||
</commandset>
|
||||
|
||||
<popupset id="mainPopupSet">
|
||||
|
|
|
@ -3698,7 +3698,7 @@ BrowserGlue.prototype = {
|
|||
_migrateUI() {
|
||||
// Use an increasing number to keep track of the current migration state.
|
||||
// Completely unrelated to the current Firefox release number.
|
||||
const UI_VERSION = 153;
|
||||
const UI_VERSION = 154;
|
||||
const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
|
||||
|
||||
if (!Services.prefs.prefHasUserValue("browser.migration.version")) {
|
||||
|
@ -4514,6 +4514,21 @@ BrowserGlue.prototype = {
|
|||
);
|
||||
}
|
||||
|
||||
if (currentUIVersion < 154) {
|
||||
// Remove mibbit handler.
|
||||
// The handler service will do this. We need to wait with migrating
|
||||
// until the handler service has started up, so just set a pref here.
|
||||
const kPref = "browser.handlers.migrations";
|
||||
// We might have set up another migration further up. Create an array,
|
||||
// and drop empty strings resulting from the `split`:
|
||||
let migrations = Services.prefs
|
||||
.getCharPref(kPref, "")
|
||||
.split(",")
|
||||
.filter(x => !!x);
|
||||
migrations.push("mibbit");
|
||||
Services.prefs.setCharPref(kPref, migrations.join(","));
|
||||
}
|
||||
|
||||
// Update the migration version.
|
||||
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
|
||||
},
|
||||
|
|
|
@ -28,7 +28,6 @@ module.exports = {
|
|||
"content-src/components/MultiStageScreen.jsx",
|
||||
"content-src/components/MultiStageProtonScreen.jsx",
|
||||
"content-src/components/MultiSelect.jsx",
|
||||
"content-src/components/ReturnToAMO.jsx",
|
||||
],
|
||||
rules: {
|
||||
"jsx-a11y/anchor-has-content": "off",
|
||||
|
|
|
@ -196,14 +196,6 @@ export class AboutWelcomeChild extends JSWindowActorChild {
|
|||
async getAWContent() {
|
||||
let attributionData = await this.sendQuery("AWPage:GET_ATTRIBUTION_DATA");
|
||||
|
||||
// Return to AMO gets returned early.
|
||||
if (attributionData?.template) {
|
||||
lazy.log.debug("Loading about:welcome with RTAMO attribution data");
|
||||
return Cu.cloneInto(attributionData, this.contentWindow);
|
||||
} else if (attributionData?.ua) {
|
||||
lazy.log.debug("Loading about:welcome with UA attribution");
|
||||
}
|
||||
|
||||
let experimentMetadata =
|
||||
lazy.ExperimentAPI.getExperimentMetaData({
|
||||
featureId: "aboutwelcome",
|
||||
|
|
|
@ -181,6 +181,10 @@ export class AboutWelcomeParent extends JSWindowActorParent {
|
|||
lazy.AddonManager.removeInstallListener(listener);
|
||||
resolve("install cancelled");
|
||||
},
|
||||
onDownloadCancelled() {
|
||||
lazy.AddonManager.removeInstallListener(listener);
|
||||
resolve("install cancelled");
|
||||
},
|
||||
onInstallFailed() {
|
||||
lazy.AddonManager.removeInstallListener(listener);
|
||||
resolve("install failed");
|
||||
|
@ -197,6 +201,7 @@ export class AboutWelcomeParent extends JSWindowActorParent {
|
|||
await lazy.AboutWelcomeDefaults.getAddonFromRepository(data);
|
||||
|
||||
return {
|
||||
addonId: addonDetails.id,
|
||||
label: addonDetails.name,
|
||||
icon: addonDetails.iconURL,
|
||||
type: addonDetails.type,
|
||||
|
|
|
@ -6,7 +6,6 @@ import React from "react";
|
|||
import ReactDOM from "react-dom";
|
||||
import { AboutWelcomeUtils } from "./lib/aboutwelcome-utils.mjs";
|
||||
import { MultiStageAboutWelcome } from "./components/MultiStageAboutWelcome";
|
||||
import { ReturnToAMO } from "./components/ReturnToAMO";
|
||||
|
||||
class AboutWelcome extends React.PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -57,21 +56,14 @@ class AboutWelcome extends React.PureComponent {
|
|||
|
||||
render() {
|
||||
const { props } = this;
|
||||
if (props.template === "return_to_amo") {
|
||||
return (
|
||||
<ReturnToAMO
|
||||
message_id={props.messageId}
|
||||
type={props.type}
|
||||
name={props.name}
|
||||
url={props.url}
|
||||
iconURL={props.iconURL}
|
||||
themeScreenshots={props.screenshots}
|
||||
metricsFlowUri={this.state.metricsFlowUri}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<MultiStageAboutWelcome
|
||||
addonId={props.addonId}
|
||||
addonType={props.type}
|
||||
addonName={props.name || ""}
|
||||
addonURL={props.url}
|
||||
addonIconURL={props.iconURL}
|
||||
themeScreenshots={props.screenshots}
|
||||
message_id={props.messageId}
|
||||
defaultScreens={props.screens}
|
||||
updateHistory={!props.disableHistoryUpdates}
|
||||
|
|
|
@ -754,6 +754,33 @@ html {
|
|||
|
||||
@include arrow-icon-styles;
|
||||
}
|
||||
|
||||
.loader {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border: 3px solid var(--in-content-primary-button-text-color);
|
||||
border-bottom-color: transparent;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
animation: rotation 1s linear infinite;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loaderContainer {
|
||||
display: flex;
|
||||
padding: 1.5px 37.5px;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
|
|
|
@ -2,72 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { AboutWelcomeUtils } from "../lib/aboutwelcome-utils.mjs";
|
||||
import { Localized } from "./MSLocalized";
|
||||
|
||||
export const Loader = () => {
|
||||
return (
|
||||
<button className="primary">
|
||||
<div className="loaderContainer">
|
||||
<span className="loader" />
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export const InstallButton = props => {
|
||||
// determine if the addon is already installed so the state is
|
||||
// consistent on refresh or navigation
|
||||
const [installing, setInstalling] = useState(false);
|
||||
const [installComplete, setInstallComplete] = useState(false);
|
||||
|
||||
const defaultInstallLabel = { string_id: "amo-picker-install-button-label" };
|
||||
const defaultInstallCompleteLabel = {
|
||||
string_id: "amo-picker-install-complete-label",
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setInstallComplete(props.installedAddons?.includes(props.addonId));
|
||||
}, [props.addonId, props.installedAddons]);
|
||||
|
||||
let buttonLabel = installComplete
|
||||
? props.install_complete_label || defaultInstallCompleteLabel
|
||||
: props.install_label || defaultInstallLabel;
|
||||
|
||||
function onClick(event) {
|
||||
props.handleAction(event);
|
||||
// Replace the label with the spinner
|
||||
setInstalling(true);
|
||||
|
||||
window.AWEnsureAddonInstalled(props.addonId).then(value => {
|
||||
if (value === "complete") {
|
||||
// Set the label to "Installed"
|
||||
setInstallComplete(true);
|
||||
}
|
||||
// Whether the addon installs or not, we want to remove the spinner
|
||||
setInstalling(false);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="install-button-wrapper">
|
||||
{installing ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<Localized text={buttonLabel}>
|
||||
<button
|
||||
id={`install-button-${props.addonId}`}
|
||||
value={props.index}
|
||||
onClick={onClick}
|
||||
disabled={installComplete}
|
||||
className="primary"
|
||||
/>
|
||||
</Localized>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
import { InstallButton } from "./InstallButton";
|
||||
|
||||
export const AddonsPicker = props => {
|
||||
const { content, installedAddons, layout } = props;
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/* 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/. */
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Localized } from "./MSLocalized";
|
||||
|
||||
export const Loader = () => {
|
||||
return (
|
||||
<button className="primary">
|
||||
<div className="loaderContainer">
|
||||
<span className="loader" />
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export const InstallButton = props => {
|
||||
// determine if the addon is already installed so the state is
|
||||
// consistent on refresh or navigation
|
||||
const [installing, setInstalling] = useState(false);
|
||||
const [installComplete, setInstallComplete] = useState(false);
|
||||
|
||||
const defaultInstallLabel = {
|
||||
string_id: "amo-picker-install-button-label",
|
||||
};
|
||||
|
||||
function getDefaultInstallCompleteLabel(addonType = "") {
|
||||
let defaultInstallCompleteLabel;
|
||||
if (addonType && addonType === "theme") {
|
||||
defaultInstallCompleteLabel = {
|
||||
string_id: "return-to-amo-theme-install-complete-label",
|
||||
};
|
||||
} else if (addonType && addonType === "extension") {
|
||||
defaultInstallCompleteLabel = {
|
||||
string_id: "return-to-amo-extension-install-complete-label",
|
||||
};
|
||||
} else {
|
||||
defaultInstallCompleteLabel = {
|
||||
string_id: "amo-picker-install-complete-label",
|
||||
};
|
||||
}
|
||||
return defaultInstallCompleteLabel;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setInstallComplete(props.installedAddons?.includes(props.addonId));
|
||||
}, [props.addonId, props.installedAddons]);
|
||||
|
||||
let buttonLabel = installComplete
|
||||
? props.install_complete_label ||
|
||||
getDefaultInstallCompleteLabel(props.addonType)
|
||||
: props.install_label || defaultInstallLabel;
|
||||
|
||||
function onClick(event) {
|
||||
props.handleAction(event);
|
||||
// Replace the label with the spinner
|
||||
setInstalling(true);
|
||||
|
||||
window.AWEnsureAddonInstalled(props.addonId).then(value => {
|
||||
if (value === "complete") {
|
||||
// Set the label to "Installed"
|
||||
setInstallComplete(true);
|
||||
}
|
||||
// Whether the addon installs or not, we want to remove the spinner
|
||||
setInstalling(false);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="install-button-wrapper">
|
||||
{installing ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<Localized text={buttonLabel}>
|
||||
<button
|
||||
id={`install-button-${props.addonId}`}
|
||||
value={props.index}
|
||||
onClick={onClick}
|
||||
disabled={installComplete}
|
||||
className="primary"
|
||||
data-l10n-args={JSON.stringify({
|
||||
"addon-name": props.addonName ?? "",
|
||||
})}
|
||||
/>
|
||||
</Localized>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -327,6 +327,13 @@ export const MultiStageAboutWelcome = props => {
|
|||
}
|
||||
installedAddons={installedAddons}
|
||||
setInstalledAddons={setInstalledAddons}
|
||||
addonId={props.addonId}
|
||||
addonType={props.addonType}
|
||||
addonName={props.addonName}
|
||||
addonURL={props.addonURL}
|
||||
addonIconURL={props.addonIconURL}
|
||||
themeScreenshots={props.themeScreenshots}
|
||||
isRtamo={currentScreen.content.isRtamo}
|
||||
/>
|
||||
) : null;
|
||||
})}
|
||||
|
@ -523,6 +530,17 @@ export class WelcomeScreen extends React.PureComponent {
|
|||
"FXA_SIGNIN_FLOW"
|
||||
);
|
||||
}
|
||||
|
||||
if (action.type === "INSTALL_ADDON_FROM_URL") {
|
||||
const url = props.addonURL;
|
||||
if (!action.data) {
|
||||
return;
|
||||
}
|
||||
// Set add-on url in action.data.url property from JSON
|
||||
action.data = { ...action.data, url };
|
||||
|
||||
AboutWelcomeUtils.handleUserAction(action);
|
||||
}
|
||||
// Wait until migration closes to complete the action
|
||||
const hasMigrate = a =>
|
||||
a.type === "SHOW_MIGRATION_WIZARD" ||
|
||||
|
@ -698,6 +716,13 @@ export class WelcomeScreen extends React.PureComponent {
|
|||
forceHideStepsIndicator={this.props.forceHideStepsIndicator}
|
||||
ariaRole={this.props.ariaRole}
|
||||
aboveButtonStepsIndicator={this.props.aboveButtonStepsIndicator}
|
||||
addonId={this.props.addonId}
|
||||
addonType={this.props.addonType}
|
||||
addonName={this.props.addonName}
|
||||
addonURL={this.props.addonURL}
|
||||
addonIconURL={this.props.addonIconURL}
|
||||
themeScreenshots={this.props.themeScreenshots}
|
||||
isRtamo={this.props.content.isRtamo}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import { OnboardingVideo } from "./OnboardingVideo";
|
|||
import { AdditionalCTA } from "./AdditionalCTA";
|
||||
import { LinkParagraph } from "./LinkParagraph";
|
||||
import { ContentTiles } from "./ContentTiles";
|
||||
import { InstallButton } from "./InstallButton";
|
||||
|
||||
export const MultiStageProtonScreen = props => {
|
||||
const { autoAdvance, handleAction, order } = props;
|
||||
|
@ -70,9 +71,12 @@ export const MultiStageProtonScreen = props => {
|
|||
previousOrder={props.previousOrder}
|
||||
autoAdvance={props.autoAdvance}
|
||||
isRtamo={props.isRtamo}
|
||||
addonId={props.addonId}
|
||||
addonType={props.addonType}
|
||||
addonName={props.addonName}
|
||||
isTheme={props.isTheme}
|
||||
iconURL={props.iconURL}
|
||||
addonURL={props.addonURL}
|
||||
addonIconURL={props.addonIconURL}
|
||||
themeScreenshots={props.themeScreenshots}
|
||||
messageId={props.messageId}
|
||||
negotiatedLanguage={props.negotiatedLanguage}
|
||||
langPackInstallPhase={props.langPackInstallPhase}
|
||||
|
@ -84,7 +88,15 @@ export const MultiStageProtonScreen = props => {
|
|||
};
|
||||
|
||||
export const ProtonScreenActionButtons = props => {
|
||||
const { content, addonName, activeMultiSelect } = props;
|
||||
const {
|
||||
content,
|
||||
isRtamo,
|
||||
addonId,
|
||||
addonType,
|
||||
addonName,
|
||||
activeMultiSelect,
|
||||
installedAddons,
|
||||
} = props;
|
||||
const defaultValue = content.checkbox?.defaultValue;
|
||||
|
||||
const [isChecked, setIsChecked] = useState(defaultValue || false);
|
||||
|
@ -106,6 +118,12 @@ export const ProtonScreenActionButtons = props => {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (isRtamo) {
|
||||
content.primary_button.label.string_id = addonType?.includes("theme")
|
||||
? "return-to-amo-add-theme-label"
|
||||
: "mr1-return-to-amo-add-extension-label";
|
||||
}
|
||||
|
||||
// If we have a multi-select screen, we want to disable the primary button
|
||||
// until the user has selected at least one item.
|
||||
const isPrimaryDisabled = primaryDisabledValue => {
|
||||
|
@ -133,28 +151,42 @@ export const ProtonScreenActionButtons = props => {
|
|||
flow={content.additional_button?.flow}
|
||||
alignment={content.additional_button?.alignment}
|
||||
>
|
||||
<Localized text={content.primary_button?.label}>
|
||||
<button
|
||||
ref={buttonRef}
|
||||
className={`${content.primary_button?.style ?? "primary"}${
|
||||
content.primary_button?.has_arrow_icon ? " arrow-icon" : ""
|
||||
}`}
|
||||
// Whether or not the checkbox is checked determines which action
|
||||
// should be handled. By setting value here, we indicate to
|
||||
// this.handleAction() where in the content tree it should take
|
||||
// the action to execute from.
|
||||
value={isChecked ? "checkbox" : "primary_button"}
|
||||
disabled={isPrimaryDisabled(content.primary_button?.disabled)}
|
||||
onClick={props.handleAction}
|
||||
data-l10n-args={
|
||||
addonName
|
||||
? JSON.stringify({
|
||||
"addon-name": addonName,
|
||||
})
|
||||
: ""
|
||||
}
|
||||
{isRtamo ? (
|
||||
<InstallButton
|
||||
key={addonId}
|
||||
addonId={addonId}
|
||||
addonType={addonType}
|
||||
addonName={addonName}
|
||||
index={"primary_button"}
|
||||
handleAction={props.handleAction}
|
||||
installedAddons={installedAddons}
|
||||
install_label={content.primary_button.label}
|
||||
install_complete_label={content.primary_button.install_complete_label}
|
||||
/>
|
||||
</Localized>
|
||||
) : (
|
||||
<Localized text={content.primary_button?.label}>
|
||||
<button
|
||||
ref={buttonRef}
|
||||
className={`${content.primary_button?.style ?? "primary"}${
|
||||
content.primary_button?.has_arrow_icon ? " arrow-icon" : ""
|
||||
}`}
|
||||
// Whether or not the checkbox is checked determines which action
|
||||
// should be handled. By setting value here, we indicate to
|
||||
// this.handleAction() where in the content tree it should take
|
||||
// the action to execute from.
|
||||
value={isChecked ? "checkbox" : "primary_button"}
|
||||
disabled={isPrimaryDisabled(content.primary_button?.disabled)}
|
||||
onClick={props.handleAction}
|
||||
data-l10n-args={
|
||||
addonName
|
||||
? JSON.stringify({
|
||||
"addon-name": addonName,
|
||||
})
|
||||
: ""
|
||||
}
|
||||
/>
|
||||
</Localized>
|
||||
)}
|
||||
{content.additional_button ? (
|
||||
<AdditionalCTA content={content} handleAction={props.handleAction} />
|
||||
) : null}
|
||||
|
@ -443,12 +475,30 @@ export class ProtonScreen extends React.PureComponent {
|
|||
return <>{elements}</>;
|
||||
}
|
||||
|
||||
renderRTAMOIcon(addonType, themeScreenshots, addonIconURL) {
|
||||
return (
|
||||
<div className="rtamo-icon">
|
||||
<img
|
||||
className={`${addonType?.includes("theme") ? "rtamo-theme-icon" : "brand-logo"}`}
|
||||
src={
|
||||
addonType?.includes("theme")
|
||||
? themeScreenshots[0].url
|
||||
: addonIconURL
|
||||
}
|
||||
loading={AboutWelcomeUtils.getLoadingStrategyFor(addonIconURL)}
|
||||
alt=""
|
||||
role="presentation"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
autoAdvance,
|
||||
content,
|
||||
isRtamo,
|
||||
isTheme,
|
||||
addonType,
|
||||
isFirstScreen,
|
||||
isLastScreen,
|
||||
isSingleScreen,
|
||||
|
@ -558,19 +608,13 @@ export class ProtonScreen extends React.PureComponent {
|
|||
? this.renderPicture(content.logo)
|
||||
: null}
|
||||
|
||||
{isRtamo ? (
|
||||
<div className="rtamo-icon">
|
||||
<img
|
||||
className={`${isTheme ? "rtamo-theme-icon" : "brand-logo"}`}
|
||||
src={this.props.iconURL}
|
||||
loading={AboutWelcomeUtils.getLoadingStrategyFor(
|
||||
this.props.iconURL
|
||||
)}
|
||||
alt=""
|
||||
role="presentation"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{isRtamo && !content.fullscreen
|
||||
? this.renderRTAMOIcon(
|
||||
addonType,
|
||||
this.props.themeScreenshots,
|
||||
this.props.addonIconURL
|
||||
)
|
||||
: null}
|
||||
|
||||
<div
|
||||
className="main-content-inner"
|
||||
|
@ -581,6 +625,13 @@ export class ProtonScreen extends React.PureComponent {
|
|||
{content.logo && content.fullscreen
|
||||
? this.renderPicture(content.logo)
|
||||
: null}
|
||||
{isRtamo && content.fullscreen
|
||||
? this.renderRTAMOIcon(
|
||||
addonType,
|
||||
this.props.themeScreenshots,
|
||||
this.props.addonIconURL
|
||||
)
|
||||
: null}
|
||||
{content.title || content.subtitle ? (
|
||||
<div
|
||||
id="multi-stage-message-welcome-text"
|
||||
|
@ -607,7 +658,11 @@ export class ProtonScreen extends React.PureComponent {
|
|||
{content.action_buttons_above_content && (
|
||||
<ProtonScreenActionButtons
|
||||
content={content}
|
||||
isRtamo={this.props.isRtamo}
|
||||
installedAddons={this.props.installedAddons}
|
||||
addonId={this.props.addonId}
|
||||
addonName={this.props.addonName}
|
||||
addonType={this.props.addonType}
|
||||
handleAction={this.props.handleAction}
|
||||
activeMultiSelect={this.props.activeMultiSelect}
|
||||
/>
|
||||
|
@ -637,7 +692,11 @@ export class ProtonScreen extends React.PureComponent {
|
|||
{!content.action_buttons_above_content && (
|
||||
<ProtonScreenActionButtons
|
||||
content={content}
|
||||
isRtamo={this.props.isRtamo}
|
||||
installedAddons={this.props.installedAddons}
|
||||
addonId={this.props.addonId}
|
||||
addonName={this.props.addonName}
|
||||
addonType={this.props.addonType}
|
||||
handleAction={this.props.handleAction}
|
||||
activeMultiSelect={this.props.activeMultiSelect}
|
||||
/>
|
||||
|
|
|
@ -1,105 +0,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/. */
|
||||
|
||||
import React from "react";
|
||||
import {
|
||||
AboutWelcomeUtils,
|
||||
DEFAULT_RTAMO_CONTENT,
|
||||
} from "../lib/aboutwelcome-utils.mjs";
|
||||
import { MultiStageProtonScreen } from "./MultiStageProtonScreen";
|
||||
import { BASE_PARAMS } from "../lib/addUtmParams.mjs";
|
||||
|
||||
export class ReturnToAMO extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.fetchFlowParams = this.fetchFlowParams.bind(this);
|
||||
this.handleAction = this.handleAction.bind(this);
|
||||
}
|
||||
|
||||
async fetchFlowParams() {
|
||||
if (this.props.metricsFlowUri) {
|
||||
this.setState({
|
||||
flowParams: await AboutWelcomeUtils.fetchFlowParams(
|
||||
this.props.metricsFlowUri
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.fetchFlowParams();
|
||||
}
|
||||
|
||||
handleAction(event) {
|
||||
const { content, message_id, url, utm_term } = this.props;
|
||||
let { action, source_id } = content[event.currentTarget.value];
|
||||
let { type, data } = action;
|
||||
|
||||
if (type === "INSTALL_ADDON_FROM_URL") {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
// Set add-on url in action.data.url property from JSON
|
||||
data = { ...data, url };
|
||||
} else if (type === "SHOW_FIREFOX_ACCOUNTS") {
|
||||
let params = {
|
||||
...BASE_PARAMS,
|
||||
utm_term: `aboutwelcome-${utm_term}-screen`,
|
||||
};
|
||||
if (action.addFlowParams && this.state.flowParams) {
|
||||
params = {
|
||||
...params,
|
||||
...this.state.flowParams,
|
||||
};
|
||||
}
|
||||
data = { ...data, extraParams: params };
|
||||
}
|
||||
|
||||
AboutWelcomeUtils.handleUserAction({ type, data });
|
||||
AboutWelcomeUtils.sendActionTelemetry(message_id, source_id);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { content, type } = this.props;
|
||||
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (content?.primary_button.label) {
|
||||
content.primary_button.label.string_id = type.includes("theme")
|
||||
? "return-to-amo-add-theme-label"
|
||||
: "mr1-return-to-amo-add-extension-label";
|
||||
}
|
||||
|
||||
// For experiments, when needed below rendered UI allows settings hard coded strings
|
||||
// directly inside JSON except for ReturnToAMOText which picks add-on name and icon from fluent string
|
||||
return (
|
||||
<div
|
||||
className={"outer-wrapper onboardingContainer proton"}
|
||||
style={content.backdrop ? { background: content.backdrop } : {}}
|
||||
>
|
||||
<MultiStageProtonScreen
|
||||
content={content}
|
||||
isRtamo={true}
|
||||
isTheme={type.includes("theme")}
|
||||
id={this.props.message_id}
|
||||
order={this.props.order || 0}
|
||||
totalNumberOfScreens={1}
|
||||
isSingleScreen={true}
|
||||
autoAdvance={this.props.auto_advance}
|
||||
iconURL={
|
||||
type.includes("theme")
|
||||
? this.props.themeScreenshots[0]?.url
|
||||
: this.props.iconURL
|
||||
}
|
||||
addonName={this.props.name}
|
||||
handleAction={this.handleAction}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnToAMO.defaultProps = DEFAULT_RTAMO_CONTENT;
|
|
@ -91,52 +91,3 @@ export const AboutWelcomeUtils = {
|
|||
}, {});
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_RTAMO_CONTENT = {
|
||||
template: "return_to_amo",
|
||||
utm_term: "rtamo",
|
||||
content: {
|
||||
position: "split",
|
||||
title: { string_id: "mr1-return-to-amo-subtitle" },
|
||||
has_noodles: false,
|
||||
subtitle: {
|
||||
string_id: "mr1-return-to-amo-addon-title",
|
||||
},
|
||||
backdrop:
|
||||
"var(--mr-welcome-background-color) var(--mr-welcome-background-gradient)",
|
||||
background:
|
||||
"url('chrome://activity-stream/content/data/content/assets/mr-rtamo-background-image.svg') no-repeat center",
|
||||
progress_bar: true,
|
||||
primary_button: {
|
||||
label: { string_id: "mr1-return-to-amo-add-extension-label" },
|
||||
source_id: "ADD_EXTENSION_BUTTON",
|
||||
action: {
|
||||
type: "INSTALL_ADDON_FROM_URL",
|
||||
data: { url: null, telemetrySource: "rtamo" },
|
||||
},
|
||||
},
|
||||
secondary_button: {
|
||||
label: {
|
||||
string_id: "onboarding-not-now-button-label",
|
||||
},
|
||||
source_id: "RTAMO_START_BROWSING_BUTTON",
|
||||
action: {
|
||||
type: "OPEN_AWESOME_BAR",
|
||||
},
|
||||
},
|
||||
secondary_button_top: {
|
||||
label: {
|
||||
string_id: "mr1-onboarding-sign-in-button-label",
|
||||
},
|
||||
source_id: "RTAMO_FXA_SIGNIN_BUTTON",
|
||||
action: {
|
||||
data: {
|
||||
entrypoint: "activity-stream-firstrun",
|
||||
where: "tab",
|
||||
},
|
||||
type: "SHOW_FIREFOX_ACCOUNTS",
|
||||
addFlowParams: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -25,8 +25,7 @@ module.exports = ReactDOM;
|
|||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ AboutWelcomeUtils: () => (/* binding */ AboutWelcomeUtils),
|
||||
/* harmony export */ DEFAULT_RTAMO_CONTENT: () => (/* binding */ DEFAULT_RTAMO_CONTENT)
|
||||
/* harmony export */ AboutWelcomeUtils: () => (/* binding */ AboutWelcomeUtils)
|
||||
/* harmony export */ });
|
||||
/* 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,
|
||||
|
@ -122,55 +121,6 @@ const AboutWelcomeUtils = {
|
|||
},
|
||||
};
|
||||
|
||||
const DEFAULT_RTAMO_CONTENT = {
|
||||
template: "return_to_amo",
|
||||
utm_term: "rtamo",
|
||||
content: {
|
||||
position: "split",
|
||||
title: { string_id: "mr1-return-to-amo-subtitle" },
|
||||
has_noodles: false,
|
||||
subtitle: {
|
||||
string_id: "mr1-return-to-amo-addon-title",
|
||||
},
|
||||
backdrop:
|
||||
"var(--mr-welcome-background-color) var(--mr-welcome-background-gradient)",
|
||||
background:
|
||||
"url('chrome://activity-stream/content/data/content/assets/mr-rtamo-background-image.svg') no-repeat center",
|
||||
progress_bar: true,
|
||||
primary_button: {
|
||||
label: { string_id: "mr1-return-to-amo-add-extension-label" },
|
||||
source_id: "ADD_EXTENSION_BUTTON",
|
||||
action: {
|
||||
type: "INSTALL_ADDON_FROM_URL",
|
||||
data: { url: null, telemetrySource: "rtamo" },
|
||||
},
|
||||
},
|
||||
secondary_button: {
|
||||
label: {
|
||||
string_id: "onboarding-not-now-button-label",
|
||||
},
|
||||
source_id: "RTAMO_START_BROWSING_BUTTON",
|
||||
action: {
|
||||
type: "OPEN_AWESOME_BAR",
|
||||
},
|
||||
},
|
||||
secondary_button_top: {
|
||||
label: {
|
||||
string_id: "mr1-onboarding-sign-in-button-label",
|
||||
},
|
||||
source_id: "RTAMO_FXA_SIGNIN_BUTTON",
|
||||
action: {
|
||||
data: {
|
||||
entrypoint: "activity-stream-firstrun",
|
||||
where: "tab",
|
||||
},
|
||||
type: "SHOW_FIREFOX_ACCOUNTS",
|
||||
addFlowParams: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 4 */
|
||||
|
@ -191,7 +141,7 @@ __webpack_require__.r(__webpack_exports__);
|
|||
/* harmony import */ var _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6);
|
||||
/* harmony import */ var _LanguageSwitcher__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7);
|
||||
/* harmony import */ var _SubmenuButton__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(12);
|
||||
/* harmony import */ var _lib_addUtmParams_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(22);
|
||||
/* harmony import */ var _lib_addUtmParams_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(23);
|
||||
/* 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/. */
|
||||
|
@ -467,7 +417,14 @@ const MultiStageAboutWelcome = props => {
|
|||
ariaRole: props.ariaRole,
|
||||
aboveButtonStepsIndicator: currentScreen.above_button_steps_indicator,
|
||||
installedAddons: installedAddons,
|
||||
setInstalledAddons: setInstalledAddons
|
||||
setInstalledAddons: setInstalledAddons,
|
||||
addonId: props.addonId,
|
||||
addonType: props.addonType,
|
||||
addonName: props.addonName,
|
||||
addonURL: props.addonURL,
|
||||
addonIconURL: props.addonIconURL,
|
||||
themeScreenshots: props.themeScreenshots,
|
||||
isRtamo: currentScreen.content.isRtamo
|
||||
}) : null;
|
||||
})));
|
||||
};
|
||||
|
@ -636,6 +593,18 @@ class WelcomeScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
|
|||
if (action.type === "FXA_SIGNIN_FLOW") {
|
||||
_lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.sendActionTelemetry(props.messageId, actionResult ? "sign_in" : "sign_in_cancel", "FXA_SIGNIN_FLOW");
|
||||
}
|
||||
if (action.type === "INSTALL_ADDON_FROM_URL") {
|
||||
const url = props.addonURL;
|
||||
if (!action.data) {
|
||||
return;
|
||||
}
|
||||
// Set add-on url in action.data.url property from JSON
|
||||
action.data = {
|
||||
...action.data,
|
||||
url
|
||||
};
|
||||
_lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.handleUserAction(action);
|
||||
}
|
||||
// Wait until migration closes to complete the action
|
||||
const hasMigrate = a => a.type === "SHOW_MIGRATION_WIZARD" || a.type === "MULTI_ACTION" && a.data?.actions?.some(hasMigrate);
|
||||
if (hasMigrate(action)) {
|
||||
|
@ -785,7 +754,14 @@ class WelcomeScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
|
|||
autoAdvance: this.props.autoAdvance,
|
||||
forceHideStepsIndicator: this.props.forceHideStepsIndicator,
|
||||
ariaRole: this.props.ariaRole,
|
||||
aboveButtonStepsIndicator: this.props.aboveButtonStepsIndicator
|
||||
aboveButtonStepsIndicator: this.props.aboveButtonStepsIndicator,
|
||||
addonId: this.props.addonId,
|
||||
addonType: this.props.addonType,
|
||||
addonName: this.props.addonName,
|
||||
addonURL: this.props.addonURL,
|
||||
addonIconURL: this.props.addonIconURL,
|
||||
themeScreenshots: this.props.themeScreenshots,
|
||||
isRtamo: this.props.content.isRtamo
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -924,6 +900,7 @@ __webpack_require__.r(__webpack_exports__);
|
|||
/* harmony import */ var _AdditionalCTA__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(11);
|
||||
/* harmony import */ var _LinkParagraph__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(13);
|
||||
/* harmony import */ var _ContentTiles__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(14);
|
||||
/* harmony import */ var _InstallButton__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(16);
|
||||
/* 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/. */
|
||||
|
@ -939,6 +916,7 @@ __webpack_require__.r(__webpack_exports__);
|
|||
|
||||
|
||||
|
||||
|
||||
const MultiStageProtonScreen = props => {
|
||||
const {
|
||||
autoAdvance,
|
||||
|
@ -989,9 +967,12 @@ const MultiStageProtonScreen = props => {
|
|||
previousOrder: props.previousOrder,
|
||||
autoAdvance: props.autoAdvance,
|
||||
isRtamo: props.isRtamo,
|
||||
addonId: props.addonId,
|
||||
addonType: props.addonType,
|
||||
addonName: props.addonName,
|
||||
isTheme: props.isTheme,
|
||||
iconURL: props.iconURL,
|
||||
addonURL: props.addonURL,
|
||||
addonIconURL: props.addonIconURL,
|
||||
themeScreenshots: props.themeScreenshots,
|
||||
messageId: props.messageId,
|
||||
negotiatedLanguage: props.negotiatedLanguage,
|
||||
langPackInstallPhase: props.langPackInstallPhase,
|
||||
|
@ -1003,8 +984,12 @@ const MultiStageProtonScreen = props => {
|
|||
const ProtonScreenActionButtons = props => {
|
||||
const {
|
||||
content,
|
||||
isRtamo,
|
||||
addonId,
|
||||
addonType,
|
||||
addonName,
|
||||
activeMultiSelect
|
||||
activeMultiSelect,
|
||||
installedAddons
|
||||
} = props;
|
||||
const defaultValue = content.checkbox?.defaultValue;
|
||||
const [isChecked, setIsChecked] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(defaultValue || false);
|
||||
|
@ -1018,6 +1003,9 @@ const ProtonScreenActionButtons = props => {
|
|||
if (!content.primary_button && !content.secondary_button && !content.additional_button) {
|
||||
return null;
|
||||
}
|
||||
if (isRtamo) {
|
||||
content.primary_button.label.string_id = addonType?.includes("theme") ? "return-to-amo-add-theme-label" : "mr1-return-to-amo-add-extension-label";
|
||||
}
|
||||
|
||||
// If we have a multi-select screen, we want to disable the primary button
|
||||
// until the user has selected at least one item.
|
||||
|
@ -1041,7 +1029,17 @@ const ProtonScreenActionButtons = props => {
|
|||
className: `action-buttons ${content.additional_button ? "additional-cta-container" : ""}`,
|
||||
flow: content.additional_button?.flow,
|
||||
alignment: content.additional_button?.alignment
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, {
|
||||
}, isRtamo ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_InstallButton__WEBPACK_IMPORTED_MODULE_11__.InstallButton, {
|
||||
key: addonId,
|
||||
addonId: addonId,
|
||||
addonType: addonType,
|
||||
addonName: addonName,
|
||||
index: "primary_button",
|
||||
handleAction: props.handleAction,
|
||||
installedAddons: installedAddons,
|
||||
install_label: content.primary_button.label,
|
||||
install_complete_label: content.primary_button.install_complete_label
|
||||
}) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, {
|
||||
text: content.primary_button?.label
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
|
||||
ref: buttonRef,
|
||||
|
@ -1293,12 +1291,23 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
|
|||
}
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, elements);
|
||||
}
|
||||
renderRTAMOIcon(addonType, themeScreenshots, addonIconURL) {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "rtamo-icon"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("img", {
|
||||
className: `${addonType?.includes("theme") ? "rtamo-theme-icon" : "brand-logo"}`,
|
||||
src: addonType?.includes("theme") ? themeScreenshots[0].url : addonIconURL,
|
||||
loading: _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.getLoadingStrategyFor(addonIconURL),
|
||||
alt: "",
|
||||
role: "presentation"
|
||||
}));
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
autoAdvance,
|
||||
content,
|
||||
isRtamo,
|
||||
isTheme,
|
||||
addonType,
|
||||
isFirstScreen,
|
||||
isLastScreen,
|
||||
isSingleScreen,
|
||||
|
@ -1348,20 +1357,12 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
|
|||
paddingBlock: content.split_content_padding_block ? content.split_content_padding_block : null,
|
||||
paddingInline: content.split_content_padding_inline ? content.split_content_padding_inline : null
|
||||
}
|
||||
}, content.logo && !content.fullscreen ? this.renderPicture(content.logo) : null, isRtamo ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "rtamo-icon"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("img", {
|
||||
className: `${isTheme ? "rtamo-theme-icon" : "brand-logo"}`,
|
||||
src: this.props.iconURL,
|
||||
loading: _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_2__.AboutWelcomeUtils.getLoadingStrategyFor(this.props.iconURL),
|
||||
alt: "",
|
||||
role: "presentation"
|
||||
})) : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
}, content.logo && !content.fullscreen ? this.renderPicture(content.logo) : null, isRtamo && !content.fullscreen ? this.renderRTAMOIcon(addonType, this.props.themeScreenshots, this.props.addonIconURL) : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "main-content-inner",
|
||||
style: {
|
||||
justifyContent: content.split_content_justify_content
|
||||
}
|
||||
}, content.logo && content.fullscreen ? this.renderPicture(content.logo) : null, content.title || content.subtitle ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
}, content.logo && content.fullscreen ? this.renderPicture(content.logo) : null, isRtamo && content.fullscreen ? this.renderRTAMOIcon(addonType, this.props.themeScreenshots, this.props.addonIconURL) : null, content.title || content.subtitle ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
id: "multi-stage-message-welcome-text",
|
||||
className: `welcome-text ${content.title_style || ""}`
|
||||
}, content.title ? this.renderTitle(content) : null, content.subtitle ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, {
|
||||
|
@ -1375,7 +1376,11 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
|
|||
id: "mainContentSubheader"
|
||||
})) : null, content.action_buttons_above_content && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ProtonScreenActionButtons, {
|
||||
content: content,
|
||||
isRtamo: this.props.isRtamo,
|
||||
installedAddons: this.props.installedAddons,
|
||||
addonId: this.props.addonId,
|
||||
addonName: this.props.addonName,
|
||||
addonType: this.props.addonType,
|
||||
handleAction: this.props.handleAction,
|
||||
activeMultiSelect: this.props.activeMultiSelect
|
||||
}), content.cta_paragraph ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_CTAParagraph__WEBPACK_IMPORTED_MODULE_5__.CTAParagraph, {
|
||||
|
@ -1386,7 +1391,11 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
|
|||
handleAction: this.props.handleAction
|
||||
}) : null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_ContentTiles__WEBPACK_IMPORTED_MODULE_10__.ContentTiles, this.props), this.renderLanguageSwitcher(), content.above_button_content ? this.renderOrderedContent(content.above_button_content) : null, !hideStepsIndicator && aboveButtonStepsIndicator ? this.renderStepsIndicator() : null, !content.action_buttons_above_content && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ProtonScreenActionButtons, {
|
||||
content: content,
|
||||
isRtamo: this.props.isRtamo,
|
||||
installedAddons: this.props.installedAddons,
|
||||
addonId: this.props.addonId,
|
||||
addonName: this.props.addonName,
|
||||
addonType: this.props.addonType,
|
||||
handleAction: this.props.handleAction,
|
||||
activeMultiSelect: this.props.activeMultiSelect
|
||||
}),
|
||||
|
@ -2057,12 +2066,12 @@ __webpack_require__.r(__webpack_exports__);
|
|||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
|
||||
/* harmony import */ var _AddonsPicker__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(15);
|
||||
/* harmony import */ var _SingleSelect__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16);
|
||||
/* harmony import */ var _MobileDownloads__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17);
|
||||
/* harmony import */ var _MultiSelect__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(18);
|
||||
/* harmony import */ var _EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(19);
|
||||
/* harmony import */ var _ActionChecklist__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(20);
|
||||
/* harmony import */ var _EmbeddedBrowser__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(21);
|
||||
/* harmony import */ var _SingleSelect__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(17);
|
||||
/* harmony import */ var _MobileDownloads__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(18);
|
||||
/* harmony import */ var _MultiSelect__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(19);
|
||||
/* harmony import */ var _EmbeddedMigrationWizard__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(20);
|
||||
/* harmony import */ var _ActionChecklist__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(21);
|
||||
/* harmony import */ var _EmbeddedBrowser__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(22);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(3);
|
||||
/* 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,
|
||||
|
@ -2252,14 +2261,13 @@ const ContentTiles = props => {
|
|||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ AddonsPicker: () => (/* binding */ AddonsPicker),
|
||||
/* harmony export */ InstallButton: () => (/* binding */ InstallButton),
|
||||
/* harmony export */ Loader: () => (/* binding */ Loader)
|
||||
/* harmony export */ AddonsPicker: () => (/* binding */ AddonsPicker)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
|
||||
/* harmony import */ var _InstallButton__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16);
|
||||
/* 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/. */
|
||||
|
@ -2267,55 +2275,7 @@ __webpack_require__.r(__webpack_exports__);
|
|||
|
||||
|
||||
|
||||
const Loader = () => {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
|
||||
className: "primary"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "loaderContainer"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
|
||||
className: "loader"
|
||||
})));
|
||||
};
|
||||
const InstallButton = props => {
|
||||
// determine if the addon is already installed so the state is
|
||||
// consistent on refresh or navigation
|
||||
const [installing, setInstalling] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
||||
const [installComplete, setInstallComplete] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
||||
const defaultInstallLabel = {
|
||||
string_id: "amo-picker-install-button-label"
|
||||
};
|
||||
const defaultInstallCompleteLabel = {
|
||||
string_id: "amo-picker-install-complete-label"
|
||||
};
|
||||
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
||||
setInstallComplete(props.installedAddons?.includes(props.addonId));
|
||||
}, [props.addonId, props.installedAddons]);
|
||||
let buttonLabel = installComplete ? props.install_complete_label || defaultInstallCompleteLabel : props.install_label || defaultInstallLabel;
|
||||
function onClick(event) {
|
||||
props.handleAction(event);
|
||||
// Replace the label with the spinner
|
||||
setInstalling(true);
|
||||
window.AWEnsureAddonInstalled(props.addonId).then(value => {
|
||||
if (value === "complete") {
|
||||
// Set the label to "Installed"
|
||||
setInstallComplete(true);
|
||||
}
|
||||
// Whether the addon installs or not, we want to remove the spinner
|
||||
setInstalling(false);
|
||||
});
|
||||
}
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "install-button-wrapper"
|
||||
}, installing ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Loader, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_2__.Localized, {
|
||||
text: buttonLabel
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
|
||||
id: `install-button-${props.addonId}`,
|
||||
value: props.index,
|
||||
onClick: onClick,
|
||||
disabled: installComplete,
|
||||
className: "primary"
|
||||
})));
|
||||
};
|
||||
|
||||
const AddonsPicker = props => {
|
||||
const {
|
||||
content,
|
||||
|
@ -2401,7 +2361,7 @@ const AddonsPicker = props => {
|
|||
handleAuthorClick(e, author.id);
|
||||
},
|
||||
className: "author-link"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, author.name)))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(InstallButton, {
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, author.name)))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_InstallButton__WEBPACK_IMPORTED_MODULE_3__.InstallButton, {
|
||||
key: id,
|
||||
addonId: id,
|
||||
handleAction: handleAction,
|
||||
|
@ -2425,7 +2385,7 @@ const AddonsPicker = props => {
|
|||
text: description
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "addon-description"
|
||||
}))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(InstallButton, {
|
||||
}))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_InstallButton__WEBPACK_IMPORTED_MODULE_3__.InstallButton, {
|
||||
key: id,
|
||||
addonId: id,
|
||||
handleAction: handleAction,
|
||||
|
@ -2440,6 +2400,91 @@ const AddonsPicker = props => {
|
|||
/* 16 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ InstallButton: () => (/* binding */ InstallButton),
|
||||
/* harmony export */ Loader: () => (/* binding */ Loader)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _MSLocalized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
|
||||
const Loader = () => {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
|
||||
className: "primary"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "loaderContainer"
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
|
||||
className: "loader"
|
||||
})));
|
||||
};
|
||||
const InstallButton = props => {
|
||||
// determine if the addon is already installed so the state is
|
||||
// consistent on refresh or navigation
|
||||
const [installing, setInstalling] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
||||
const [installComplete, setInstallComplete] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
|
||||
const defaultInstallLabel = {
|
||||
string_id: "amo-picker-install-button-label"
|
||||
};
|
||||
function getDefaultInstallCompleteLabel(addonType = "") {
|
||||
let defaultInstallCompleteLabel;
|
||||
if (addonType && addonType === "theme") {
|
||||
defaultInstallCompleteLabel = {
|
||||
string_id: "return-to-amo-theme-install-complete-label"
|
||||
};
|
||||
} else if (addonType && addonType === "extension") {
|
||||
defaultInstallCompleteLabel = {
|
||||
string_id: "return-to-amo-extension-install-complete-label"
|
||||
};
|
||||
} else {
|
||||
defaultInstallCompleteLabel = {
|
||||
string_id: "amo-picker-install-complete-label"
|
||||
};
|
||||
}
|
||||
return defaultInstallCompleteLabel;
|
||||
}
|
||||
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
|
||||
setInstallComplete(props.installedAddons?.includes(props.addonId));
|
||||
}, [props.addonId, props.installedAddons]);
|
||||
let buttonLabel = installComplete ? props.install_complete_label || getDefaultInstallCompleteLabel(props.addonType) : props.install_label || defaultInstallLabel;
|
||||
function onClick(event) {
|
||||
props.handleAction(event);
|
||||
// Replace the label with the spinner
|
||||
setInstalling(true);
|
||||
window.AWEnsureAddonInstalled(props.addonId).then(value => {
|
||||
if (value === "complete") {
|
||||
// Set the label to "Installed"
|
||||
setInstallComplete(true);
|
||||
}
|
||||
// Whether the addon installs or not, we want to remove the spinner
|
||||
setInstalling(false);
|
||||
});
|
||||
}
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "install-button-wrapper"
|
||||
}, installing ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(Loader, null) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MSLocalized__WEBPACK_IMPORTED_MODULE_1__.Localized, {
|
||||
text: buttonLabel
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
|
||||
id: `install-button-${props.addonId}`,
|
||||
value: props.index,
|
||||
onClick: onClick,
|
||||
disabled: installComplete,
|
||||
className: "primary",
|
||||
"data-l10n-args": JSON.stringify({
|
||||
"addon-name": props.addonName ?? ""
|
||||
})
|
||||
})));
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 17 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ SingleSelect: () => (/* binding */ SingleSelect)
|
||||
|
@ -2579,7 +2624,7 @@ const SingleSelect = ({
|
|||
};
|
||||
|
||||
/***/ }),
|
||||
/* 17 */
|
||||
/* 18 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
|
@ -2641,7 +2686,7 @@ const MobileDownloads = props => {
|
|||
};
|
||||
|
||||
/***/ }),
|
||||
/* 18 */
|
||||
/* 19 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
|
@ -2828,7 +2873,7 @@ const MultiSelect = ({
|
|||
};
|
||||
|
||||
/***/ }),
|
||||
/* 19 */
|
||||
/* 20 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
|
@ -2899,7 +2944,7 @@ const EmbeddedMigrationWizard = ({
|
|||
};
|
||||
|
||||
/***/ }),
|
||||
/* 20 */
|
||||
/* 21 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
|
@ -3057,7 +3102,7 @@ const ActionChecklist = ({
|
|||
};
|
||||
|
||||
/***/ }),
|
||||
/* 21 */
|
||||
/* 22 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
|
@ -3125,7 +3170,7 @@ const EmbeddedBrowserInner = ({
|
|||
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (EmbeddedBrowser);
|
||||
|
||||
/***/ }),
|
||||
/* 22 */
|
||||
/* 23 */
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
|
@ -3167,125 +3212,6 @@ function addUtmParams(url, utmTerm) {
|
|||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 23 */
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ ReturnToAMO: () => (/* binding */ ReturnToAMO)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
||||
/* harmony import */ var _MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
|
||||
/* harmony import */ var _lib_addUtmParams_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(22);
|
||||
/* 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/. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ReturnToAMO extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.fetchFlowParams = this.fetchFlowParams.bind(this);
|
||||
this.handleAction = this.handleAction.bind(this);
|
||||
}
|
||||
async fetchFlowParams() {
|
||||
if (this.props.metricsFlowUri) {
|
||||
this.setState({
|
||||
flowParams: await _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.fetchFlowParams(this.props.metricsFlowUri)
|
||||
});
|
||||
}
|
||||
}
|
||||
componentDidUpdate() {
|
||||
this.fetchFlowParams();
|
||||
}
|
||||
handleAction(event) {
|
||||
const {
|
||||
content,
|
||||
message_id,
|
||||
url,
|
||||
utm_term
|
||||
} = this.props;
|
||||
let {
|
||||
action,
|
||||
source_id
|
||||
} = content[event.currentTarget.value];
|
||||
let {
|
||||
type,
|
||||
data
|
||||
} = action;
|
||||
if (type === "INSTALL_ADDON_FROM_URL") {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
// Set add-on url in action.data.url property from JSON
|
||||
data = {
|
||||
...data,
|
||||
url
|
||||
};
|
||||
} else if (type === "SHOW_FIREFOX_ACCOUNTS") {
|
||||
let params = {
|
||||
..._lib_addUtmParams_mjs__WEBPACK_IMPORTED_MODULE_3__.BASE_PARAMS,
|
||||
utm_term: `aboutwelcome-${utm_term}-screen`
|
||||
};
|
||||
if (action.addFlowParams && this.state.flowParams) {
|
||||
params = {
|
||||
...params,
|
||||
...this.state.flowParams
|
||||
};
|
||||
}
|
||||
data = {
|
||||
...data,
|
||||
extraParams: params
|
||||
};
|
||||
}
|
||||
_lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.handleUserAction({
|
||||
type,
|
||||
data
|
||||
});
|
||||
_lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_1__.AboutWelcomeUtils.sendActionTelemetry(message_id, source_id);
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
content,
|
||||
type
|
||||
} = this.props;
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
if (content?.primary_button.label) {
|
||||
content.primary_button.label.string_id = type.includes("theme") ? "return-to-amo-add-theme-label" : "mr1-return-to-amo-add-extension-label";
|
||||
}
|
||||
|
||||
// For experiments, when needed below rendered UI allows settings hard coded strings
|
||||
// directly inside JSON except for ReturnToAMOText which picks add-on name and icon from fluent string
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "outer-wrapper onboardingContainer proton",
|
||||
style: content.backdrop ? {
|
||||
background: content.backdrop
|
||||
} : {}
|
||||
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MultiStageProtonScreen__WEBPACK_IMPORTED_MODULE_2__.MultiStageProtonScreen, {
|
||||
content: content,
|
||||
isRtamo: true,
|
||||
isTheme: type.includes("theme"),
|
||||
id: this.props.message_id,
|
||||
order: this.props.order || 0,
|
||||
totalNumberOfScreens: 1,
|
||||
isSingleScreen: true,
|
||||
autoAdvance: this.props.auto_advance,
|
||||
iconURL: type.includes("theme") ? this.props.themeScreenshots[0]?.url : this.props.iconURL,
|
||||
addonName: this.props.name,
|
||||
handleAction: this.handleAction
|
||||
}));
|
||||
}
|
||||
}
|
||||
ReturnToAMO.defaultProps = _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_RTAMO_CONTENT;
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
/************************************************************************/
|
||||
|
@ -3365,7 +3291,6 @@ __webpack_require__.r(__webpack_exports__);
|
|||
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var _lib_aboutwelcome_utils_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
||||
/* harmony import */ var _components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
|
||||
/* harmony import */ var _components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(23);
|
||||
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
/* 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,
|
||||
|
@ -3375,7 +3300,6 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
|
|||
|
||||
|
||||
|
||||
|
||||
class AboutWelcome extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -3428,18 +3352,13 @@ class AboutWelcome extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
|
|||
const {
|
||||
props
|
||||
} = this;
|
||||
if (props.template === "return_to_amo") {
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_ReturnToAMO__WEBPACK_IMPORTED_MODULE_4__.ReturnToAMO, {
|
||||
message_id: props.messageId,
|
||||
type: props.type,
|
||||
name: props.name,
|
||||
url: props.url,
|
||||
iconURL: props.iconURL,
|
||||
themeScreenshots: props.screenshots,
|
||||
metricsFlowUri: this.state.metricsFlowUri
|
||||
});
|
||||
}
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_3__.MultiStageAboutWelcome, {
|
||||
addonId: props.addonId,
|
||||
addonType: props.type,
|
||||
addonName: props.name || "",
|
||||
addonURL: props.url,
|
||||
addonIconURL: props.iconURL,
|
||||
themeScreenshots: props.screenshots,
|
||||
message_id: props.messageId,
|
||||
defaultScreens: props.screens,
|
||||
updateHistory: !props.disableHistoryUpdates,
|
||||
|
|
|
@ -1858,6 +1858,29 @@ html {
|
|||
.onboardingContainer .screen[pos=split] .section-main .main-content .action-buttons .secondary-cta .arrow-icon:dir(rtl)::after {
|
||||
background-image: url("chrome://browser/skin/back.svg");
|
||||
}
|
||||
.onboardingContainer .screen[pos=split] .section-main .main-content .action-buttons .loader {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border: 3px solid var(--in-content-primary-button-text-color);
|
||||
border-bottom-color: transparent;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
animation: rotation 1s linear infinite;
|
||||
justify-self: center;
|
||||
}
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.onboardingContainer .screen[pos=split] .section-main .main-content .action-buttons .loaderContainer {
|
||||
display: flex;
|
||||
padding: 1.5px 37.5px;
|
||||
margin: auto;
|
||||
}
|
||||
.onboardingContainer .screen[pos=split] .section-main .main-content .logo-container {
|
||||
text-align: start;
|
||||
}
|
||||
|
|
|
@ -169,6 +169,14 @@ module.exports = function (config) {
|
|||
"content-src/components/MultiStageProtonScreen.jsx": {
|
||||
branches: 79.07,
|
||||
},
|
||||
// The install actions and dynamic label of the InstallButton are covered
|
||||
// in the browser test browser_aboutwelcome_multistage_addonspicker.js.
|
||||
"content-src/components/InstallButton.jsx": {
|
||||
statements: 60,
|
||||
lines: 60,
|
||||
functions: 60,
|
||||
branches: 30,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -38,6 +38,53 @@ const MR_ABOUT_WELCOME_DEFAULT = {
|
|||
backdrop:
|
||||
"var(--mr-welcome-background-color) var(--mr-welcome-background-gradient)",
|
||||
screens: [
|
||||
{
|
||||
id: "RETURN_TO_AMO",
|
||||
targeting: "isRTAMO",
|
||||
content: {
|
||||
fullscreen: true,
|
||||
position: "split",
|
||||
title: { string_id: "mr1-return-to-amo-subtitle" },
|
||||
isRtamo: true,
|
||||
subtitle: {
|
||||
string_id: "mr1-return-to-amo-addon-title",
|
||||
},
|
||||
backdrop:
|
||||
"var(--mr-welcome-background-color) var(--mr-welcome-background-gradient)",
|
||||
background:
|
||||
"url('chrome://activity-stream/content/data/content/assets/mr-rtamo-background-image.svg') center center / cover no-repeat",
|
||||
progress_bar: true,
|
||||
primary_button: {
|
||||
label: { string_id: "mr1-return-to-amo-add-extension-label" },
|
||||
action: {
|
||||
type: "INSTALL_ADDON_FROM_URL",
|
||||
data: { url: null, telemetrySource: "rtamo" },
|
||||
},
|
||||
},
|
||||
secondary_button: {
|
||||
label: {
|
||||
string_id: "mr2022-onboarding-secondary-skip-button-label",
|
||||
},
|
||||
action: {
|
||||
navigate: true,
|
||||
},
|
||||
has_arrow_icon: true,
|
||||
},
|
||||
secondary_button_top: {
|
||||
label: {
|
||||
string_id: "mr1-onboarding-sign-in-button-label",
|
||||
},
|
||||
action: {
|
||||
data: {
|
||||
entrypoint: "activity-stream-firstrun",
|
||||
where: "tab",
|
||||
},
|
||||
type: "SHOW_FIREFOX_ACCOUNTS",
|
||||
addFlowParams: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "AW_WELCOME_BACK",
|
||||
targeting: "isDeviceMigration",
|
||||
|
@ -756,6 +803,7 @@ async function getAddonFromRepository(data) {
|
|||
}
|
||||
|
||||
return {
|
||||
addonId: addonInfo.id,
|
||||
name: addonInfo.name,
|
||||
url: addonInfo.sourceURI.spec,
|
||||
iconURL: addonInfo.icons["64"] || addonInfo.icons["32"],
|
||||
|
@ -802,6 +850,7 @@ async function getAttributionContent() {
|
|||
if (addonInfo) {
|
||||
return {
|
||||
...addonInfo,
|
||||
ua: decodeURIComponent(attribution.ua),
|
||||
template: "return_to_amo",
|
||||
};
|
||||
}
|
||||
|
|
|
@ -535,7 +535,7 @@ add_task(async function test_aboutwelcome_with_progress_bar() {
|
|||
for (let [key, val] of Object.entries({
|
||||
// The filled "completed" element should have
|
||||
// `background-color: var(--in-content-primary-button-background);`
|
||||
"background-color": "rgb(0, 97, 224)",
|
||||
"background-color": "oklch(0.55 0.24 260)",
|
||||
// Base progress bar step styles.
|
||||
height: "6px",
|
||||
"margin-inline": "-1px",
|
||||
|
|
|
@ -55,6 +55,7 @@ async function openAboutWelcome() {
|
|||
info(`evaluateScreenTargeting called with args: ${args}`);
|
||||
// Renders easy setup import screen as first screen to prevent pin/default dialog boxes breaking tests
|
||||
const falseTargeting = [
|
||||
"isRTAMO",
|
||||
"doesAppNeedPin && (unhandledCampaignAction != 'SET_DEFAULT_BROWSER') && 'browser.shell.checkDefaultBrowser'|preferenceValue && !isDefaultBrowser",
|
||||
"!doesAppNeedPin && (unhandledCampaignAction != 'SET_DEFAULT_BROWSER') && 'browser.shell.checkDefaultBrowser'|preferenceValue && !isDefaultBrowser",
|
||||
"doesAppNeedPin && (!'browser.shell.checkDefaultBrowser'|preferenceValue || isDefaultBrowser || (unhandledCampaignAction == 'SET_DEFAULT_BROWSER'))",
|
||||
|
|
|
@ -103,21 +103,6 @@ async function test_screen_content(
|
|||
);
|
||||
}
|
||||
|
||||
async function onButtonClick(browser, elementId) {
|
||||
await ContentTask.spawn(
|
||||
browser,
|
||||
{ elementId },
|
||||
async ({ elementId: buttonId }) => {
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => content.document.querySelector(buttonId),
|
||||
buttonId
|
||||
);
|
||||
let button = content.document.querySelector(buttonId);
|
||||
button.click();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the RTAMO welcome UI
|
||||
*/
|
||||
|
@ -137,7 +122,7 @@ add_task(async function test_rtamo_aboutwelcome() {
|
|||
`h2[data-l10n-args='{"addon-name":"${TEST_ADDON_INFO[0].name}"}'`,
|
||||
"div.rtamo-icon",
|
||||
"button.primary[data-l10n-id='mr1-return-to-amo-add-extension-label']",
|
||||
"button[data-l10n-id='onboarding-not-now-button-label']",
|
||||
"button[data-l10n-id='mr2022-onboarding-secondary-skip-button-label']",
|
||||
],
|
||||
// Unexpected selectors:
|
||||
[
|
||||
|
@ -148,12 +133,6 @@ add_task(async function test_rtamo_aboutwelcome() {
|
|||
]
|
||||
);
|
||||
|
||||
await onButtonClick(
|
||||
browser,
|
||||
"button[data-l10n-id='onboarding-not-now-button-label']"
|
||||
);
|
||||
Assert.ok(gURLBar.focused, "Focus should be on awesome bar");
|
||||
|
||||
let windowGlobalParent = browser.browsingContext.currentWindowGlobal;
|
||||
let aboutWelcomeActor = windowGlobalParent.getActor("AboutWelcome");
|
||||
const messageSandbox = sinon.createSandbox();
|
||||
|
@ -165,13 +144,32 @@ add_task(async function test_rtamo_aboutwelcome() {
|
|||
|
||||
await onButtonClick(browser, "button.primary");
|
||||
const { callCount } = aboutWelcomeActor.onContentMessage;
|
||||
|
||||
Assert.strictEqual(
|
||||
callCount,
|
||||
2,
|
||||
`${callCount} Stub called twice to install extension and send telemetry`
|
||||
4,
|
||||
`${callCount} Stub called four times to send telemetry, set url, install extension and verify install`
|
||||
);
|
||||
|
||||
const installExtensionCall = aboutWelcomeActor.onContentMessage.getCall(0);
|
||||
const sendTelemetryCall = aboutWelcomeActor.onContentMessage.getCall(0);
|
||||
const setUrlCall = aboutWelcomeActor.onContentMessage.getCall(1);
|
||||
const installExtensionCall = aboutWelcomeActor.onContentMessage.getCall(2);
|
||||
|
||||
Assert.equal(
|
||||
sendTelemetryCall.args[0],
|
||||
"AWPage:TELEMETRY_EVENT",
|
||||
"send event telemetry"
|
||||
);
|
||||
Assert.equal(
|
||||
sendTelemetryCall.args[1].event,
|
||||
"CLICK_BUTTON",
|
||||
"Telemetry event sent as INSTALL"
|
||||
);
|
||||
Assert.equal(
|
||||
setUrlCall.args[0],
|
||||
"AWPage:SPECIAL_ACTION",
|
||||
"send special action to set extension URL"
|
||||
);
|
||||
Assert.equal(
|
||||
installExtensionCall.args[0],
|
||||
"AWPage:SPECIAL_ACTION",
|
||||
|
@ -187,81 +185,6 @@ add_task(async function test_rtamo_aboutwelcome() {
|
|||
"https://test.xpi",
|
||||
"Install add on url"
|
||||
);
|
||||
Assert.equal(
|
||||
installExtensionCall.args[1].data.telemetrySource,
|
||||
"rtamo",
|
||||
"Install add on telemetry source"
|
||||
);
|
||||
const telemetryCall = aboutWelcomeActor.onContentMessage.getCall(1);
|
||||
Assert.equal(
|
||||
telemetryCall.args[0],
|
||||
"AWPage:TELEMETRY_EVENT",
|
||||
"send add extension telemetry"
|
||||
);
|
||||
Assert.equal(
|
||||
telemetryCall.args[1].event,
|
||||
"CLICK_BUTTON",
|
||||
"Telemetry event sent as INSTALL"
|
||||
);
|
||||
Assert.equal(
|
||||
telemetryCall.args[1].event_context.source,
|
||||
"ADD_EXTENSION_BUTTON",
|
||||
"Source of the event is Add Extension Button"
|
||||
);
|
||||
Assert.equal(
|
||||
telemetryCall.args[1].message_id,
|
||||
"RTAMO_DEFAULT_WELCOME_EXTENSION",
|
||||
"Message Id sent in telemetry for default RTAMO"
|
||||
);
|
||||
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
add_task(async function test_rtamo_over_experiments() {
|
||||
let sandbox = sinon.createSandbox();
|
||||
sandbox.stub(AddonRepository, "getAddonsByIDs").resolves(TEST_ADDON_INFO);
|
||||
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "aboutwelcome",
|
||||
value: { screens: [], enabled: true },
|
||||
});
|
||||
|
||||
let browser = await openRTAMOWelcomePage();
|
||||
|
||||
// If addon attribution exist, we should see RTAMO even if enrolled
|
||||
// in about:welcome experiment
|
||||
await test_screen_content(
|
||||
browser,
|
||||
"Experiment RTAMO UI",
|
||||
// Expected selectors:
|
||||
["h2[data-l10n-id='mr1-return-to-amo-addon-title']"],
|
||||
// Unexpected selectors:
|
||||
[]
|
||||
);
|
||||
|
||||
doExperimentCleanup();
|
||||
|
||||
browser = await openRTAMOWelcomePage();
|
||||
|
||||
await test_screen_content(
|
||||
browser,
|
||||
"No Experiment RTAMO UI",
|
||||
// Expected selectors:
|
||||
[
|
||||
"div.onboardingContainer",
|
||||
"h2[data-l10n-id='mr1-return-to-amo-addon-title']",
|
||||
"div.rtamo-icon",
|
||||
"button.primary",
|
||||
"button.secondary",
|
||||
],
|
||||
// Unexpected selectors:
|
||||
[
|
||||
"main.AW_STEP1",
|
||||
"main.AW_STEP2",
|
||||
"main.AW_STEP3",
|
||||
"div.tiles-container.info",
|
||||
]
|
||||
);
|
||||
|
||||
sandbox.restore();
|
||||
});
|
||||
|
@ -283,7 +206,7 @@ add_task(async function test_rtamo_primary_button_theme() {
|
|||
"h2[data-l10n-id='mr1-return-to-amo-addon-title']",
|
||||
"div.rtamo-icon",
|
||||
"button.primary[data-l10n-id='return-to-amo-add-theme-label']",
|
||||
"button[data-l10n-id='onboarding-not-now-button-label']",
|
||||
"button[data-l10n-id='mr2022-onboarding-secondary-skip-button-label']",
|
||||
"img.rtamo-theme-icon",
|
||||
],
|
||||
// Unexpected selectors:
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import { InstallButton } from "content-src/components/InstallButton";
|
||||
|
||||
const TEST_ADDON_INFO = [
|
||||
{
|
||||
name: "Test Add-on",
|
||||
id: "d634138d-c276-4fc8-924b-40a0ea21d284",
|
||||
url: "http://example.com",
|
||||
icons: { 32: "test.png", 64: "test.png" },
|
||||
type: "extension",
|
||||
},
|
||||
];
|
||||
|
||||
describe("InstallButton component", () => {
|
||||
let sandbox;
|
||||
let wrapper;
|
||||
let handleAction;
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox();
|
||||
handleAction = sandbox.stub();
|
||||
wrapper = shallow(
|
||||
<InstallButton
|
||||
key={TEST_ADDON_INFO.id}
|
||||
addonId={TEST_ADDON_INFO.id}
|
||||
addonType={TEST_ADDON_INFO.type}
|
||||
addonName={TEST_ADDON_INFO.name}
|
||||
index={"primary_button"}
|
||||
handleAction={handleAction}
|
||||
installedAddons={[]}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
it("should render InstallButton component", () => {
|
||||
assert.ok(wrapper.exists());
|
||||
});
|
||||
|
||||
it("should render the button with the correct value", () => {
|
||||
assert.lengthOf(wrapper.find("button[value='primary_button']"), 1);
|
||||
});
|
||||
|
||||
it("should call handleAction method when button is link is clicked", () => {
|
||||
const btnLink = wrapper.find("button.primary");
|
||||
btnLink.simulate("click");
|
||||
assert.calledOnce(handleAction);
|
||||
});
|
||||
});
|
|
@ -721,7 +721,7 @@ describe("MultiStageAboutWelcomeProton module", () => {
|
|||
);
|
||||
});
|
||||
it("should have a multi action primary button by default", async () => {
|
||||
const data = await prepConfig({}, ["AW_WELCOME_BACK"]);
|
||||
const data = await prepConfig({}, ["AW_WELCOME_BACK", "RETURN_TO_AMO"]);
|
||||
assert.propertyVal(
|
||||
data.screens[0].content.primary_button.action,
|
||||
"type",
|
||||
|
|
|
@ -561,6 +561,9 @@ const TEST_GLOBAL = {
|
|||
},
|
||||
Logger: FakeLogger,
|
||||
getFxAccountsSingleton() {},
|
||||
AWEnsureAddonInstalled() {
|
||||
return Promise.resolve({ value: "complete" });
|
||||
},
|
||||
AboutNewTab: {},
|
||||
Glean: {
|
||||
newtab: {
|
||||
|
|
|
@ -126,12 +126,9 @@
|
|||
|
||||
#vertical-pinned-tabs-container &,
|
||||
#tabbrowser-tabs[orient="vertical"] & {
|
||||
position: absolute;
|
||||
inset-inline-end: 0;
|
||||
height: calc(100% - 4px);
|
||||
margin: 0;
|
||||
margin-inline-end: 3px;
|
||||
height: auto;
|
||||
width: 2px;
|
||||
margin: 3px 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,17 +179,6 @@
|
|||
<html:a is="moz-support-link" when-mixedcontent="active-loaded"
|
||||
and-when-loginforms="secure" class="identity-popup-mcb-learn-more" support-page="mixed-content"/>
|
||||
</hbox>
|
||||
|
||||
|
||||
<!-- Buttons to enable/disable mixed content blocking. -->
|
||||
<button id="identity-popup-disable-mixed-content-blocking"
|
||||
when-mixedcontent="active-blocked"
|
||||
data-l10n-id="identity-disable-mixed-content-blocking"
|
||||
class="panel-button"/>
|
||||
<button id="identity-popup-enable-mixed-content-blocking"
|
||||
when-mixedcontent="active-loaded"
|
||||
data-l10n-id="identity-enable-mixed-content-blocking"
|
||||
class="panel-button"/>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
||||
|
|
|
@ -286,15 +286,16 @@ function generateDocumentation() {
|
|||
let string_mapping = {
|
||||
BackgroundAppUpdate: "BackgroundAppUpdate2",
|
||||
Certificates: "CertificatesDescription",
|
||||
DisableFirefoxAccounts: "DisableFirefoxAccounts1",
|
||||
DisableMasterPasswordCreation: "DisablePrimaryPasswordCreation",
|
||||
DisablePocket: "DisablePocket2",
|
||||
DisableSetDesktopBackground: "DisableSetAsDesktopBackground",
|
||||
FirefoxHome: "FirefoxHome2",
|
||||
Permissions: "Permissions2",
|
||||
SanitizeOnShutdown: "SanitizeOnShutdown2",
|
||||
WindowsSSO: "Windows10SSO",
|
||||
SecurityDevices: "SecurityDevices2",
|
||||
DisableFirefoxAccounts: "DisableFirefoxAccounts1",
|
||||
SkipTermsOfUse: "SkipTermsOfUse2",
|
||||
WindowsSSO: "Windows10SSO",
|
||||
};
|
||||
|
||||
for (let policyName in schema.properties) {
|
||||
|
|
|
@ -338,8 +338,6 @@ https_first_disabled = true
|
|||
|
||||
["browser_ext_originControls_internals.js"]
|
||||
|
||||
["browser_ext_overflow_underflow_events.js"]
|
||||
|
||||
["browser_ext_pageAction_activeTab.js"]
|
||||
|
||||
["browser_ext_pageAction_click_types.js"]
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_setup(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["layout.overflow-underflow.content.enabled", false],
|
||||
["layout.overflow-underflow.content.enabled_in_addons", true],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_overflow_underflow_events_in_sidebar() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
sidebar_action: {
|
||||
default_panel: "sidebar.html",
|
||||
},
|
||||
},
|
||||
files: {
|
||||
"sidebar.html": `<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div id="div" style="height: 10px; overflow-x: hidden">
|
||||
<div style="height: 10px"></div>
|
||||
</div>
|
||||
<script src="sidebar.js"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
"sidebar.js": async function () {
|
||||
/* global div */
|
||||
let overflow = new Promise(resolve =>
|
||||
div.addEventListener("overflow", resolve, { once: true })
|
||||
);
|
||||
let underflow = new Promise(resolve =>
|
||||
div.addEventListener("underflow", resolve, { once: true })
|
||||
);
|
||||
div.style.height = "5px";
|
||||
await overflow;
|
||||
div.style.height = "10px";
|
||||
await underflow;
|
||||
browser.test.notifyPass("overflow/underflow events in sidebar");
|
||||
},
|
||||
},
|
||||
});
|
||||
await extension.startup();
|
||||
await extension.awaitFinish();
|
||||
await extension.unload();
|
||||
});
|
|
@ -10,34 +10,30 @@
|
|||
*/
|
||||
add_task(async function () {
|
||||
info("Setting browser to RTL locale");
|
||||
await SpecialPowers.pushPrefEnv({ set: [["intl.l10n.pseudo", "bidi"]] });
|
||||
|
||||
// window.RTL_UI doesn't update in existing windows when this pref is changed,
|
||||
// so we need to test in a new window.
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await switchToWindow(win);
|
||||
await BrowserTestUtils.enableRtlLocale();
|
||||
|
||||
const TEST_ROOT = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://example.com"
|
||||
);
|
||||
let newTab = win.gBrowser.tabs[0];
|
||||
let newTab = gBrowser.tabs[0];
|
||||
|
||||
let waitForTestTabPromise = BrowserTestUtils.waitForNewTab(
|
||||
win.gBrowser,
|
||||
gBrowser,
|
||||
TEST_ROOT + "file_new_tab_page.html"
|
||||
);
|
||||
let testTab = await BrowserTestUtils.openNewForegroundTab(
|
||||
win.gBrowser,
|
||||
gBrowser,
|
||||
TEST_ROOT + "file_new_tab_page.html"
|
||||
);
|
||||
await waitForTestTabPromise;
|
||||
|
||||
let linkSrcEl = win.document.querySelector("a");
|
||||
// FIXME (bug 1958909): This uses the wrong document.
|
||||
let linkSrcEl = document.querySelector("a");
|
||||
ok(linkSrcEl, "Link exists");
|
||||
|
||||
let dropPromise = BrowserTestUtils.waitForEvent(
|
||||
win.gBrowser.tabContainer,
|
||||
gBrowser.tabContainer,
|
||||
"drop"
|
||||
);
|
||||
|
||||
|
@ -46,11 +42,11 @@ add_task(async function () {
|
|||
* 1. new tab (auto-generated)
|
||||
* 2. test tab
|
||||
*/
|
||||
is(win.gBrowser.visibleTabs.length, 2, "There should be 2 tabs");
|
||||
is(gBrowser.visibleTabs.length, 2, "There should be 2 tabs");
|
||||
|
||||
// Now open Firefox View tab
|
||||
info("Opening Firefox View tab");
|
||||
await openFirefoxViewTab(win);
|
||||
await openFirefoxViewTab(window);
|
||||
|
||||
/**
|
||||
* There should be 2 visible tabs:
|
||||
|
@ -59,16 +55,16 @@ add_task(async function () {
|
|||
* Firefox View tab is hidden.
|
||||
*/
|
||||
is(
|
||||
win.gBrowser.visibleTabs.length,
|
||||
gBrowser.visibleTabs.length,
|
||||
2,
|
||||
"There should still be 2 visible tabs after opening Firefox View tab"
|
||||
);
|
||||
|
||||
info("Switching to test tab");
|
||||
await BrowserTestUtils.switchTab(win.gBrowser, testTab);
|
||||
await BrowserTestUtils.switchTab(gBrowser, testTab);
|
||||
|
||||
let waitForDraggedTabPromise = BrowserTestUtils.waitForNewTab(
|
||||
win.gBrowser,
|
||||
gBrowser,
|
||||
"https://example.com/#test"
|
||||
);
|
||||
|
||||
|
@ -78,8 +74,8 @@ add_task(async function () {
|
|||
testTab,
|
||||
[[{ type: "text/plain", data: "https://example.com/#test" }]],
|
||||
"link",
|
||||
win,
|
||||
win,
|
||||
window,
|
||||
window,
|
||||
{
|
||||
clientX: testTab.getBoundingClientRect().right,
|
||||
}
|
||||
|
@ -99,23 +95,25 @@ add_task(async function () {
|
|||
* In RTL build, it should appear in the following order:
|
||||
* <test tab> <link dragged tab> <new tab> | <FxView tab>
|
||||
*/
|
||||
is(win.gBrowser.visibleTabs.length, 3, "There should be 3 tabs");
|
||||
is(gBrowser.visibleTabs.length, 3, "There should be 3 tabs");
|
||||
is(
|
||||
win.gBrowser.visibleTabs.indexOf(newTab),
|
||||
gBrowser.visibleTabs.indexOf(newTab),
|
||||
0,
|
||||
"New tab should still be rightmost visible tab"
|
||||
);
|
||||
is(
|
||||
win.gBrowser.visibleTabs.indexOf(draggedTab),
|
||||
gBrowser.visibleTabs.indexOf(draggedTab),
|
||||
1,
|
||||
"Dragged link should positioned at new index"
|
||||
);
|
||||
is(
|
||||
win.gBrowser.visibleTabs.indexOf(testTab),
|
||||
gBrowser.visibleTabs.indexOf(testTab),
|
||||
2,
|
||||
"Test tab should be to the left of dragged tab"
|
||||
);
|
||||
BrowserTestUtils.removeTab(draggedTab);
|
||||
BrowserTestUtils.removeTab(testTab);
|
||||
BrowserTestUtils.removeTab(FirefoxViewHandler.tab);
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await BrowserTestUtils.disableRtlLocale();
|
||||
});
|
||||
|
|
|
@ -20,5 +20,6 @@ prefs = [
|
|||
["browser_messagepreview_show_invalidmessage.js"]
|
||||
|
||||
["browser_messagepreview_show_privatebrowsing.js"]
|
||||
skip-if = ["true"] # Bug 1946629
|
||||
|
||||
["browser_messagepreview_show_spotlight.js"]
|
||||
|
|
|
@ -85,7 +85,6 @@ ChromeUtils.defineESModuleGetters(this, {
|
|||
"resource://gre/modules/ExtensionPreferencesManager.sys.mjs",
|
||||
ExtensionSettingsStore:
|
||||
"resource://gre/modules/ExtensionSettingsStore.sys.mjs",
|
||||
FeatureGate: "resource://featuregates/FeatureGate.sys.mjs",
|
||||
FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
|
||||
FirefoxRelay: "resource://gre/modules/FirefoxRelay.sys.mjs",
|
||||
HomePage: "resource:///modules/HomePage.sys.mjs",
|
||||
|
|
|
@ -13,16 +13,19 @@ const lazy = {};
|
|||
// This is used to keep the icon controllers alive for as long as their windows are alive.
|
||||
const TASKBAR_ICON_CONTROLLERS = new WeakMap();
|
||||
const PROFILES_PREF_NAME = "browser.profiles.enabled";
|
||||
const GROUPID_PREF_NAME = "toolkit.telemetry.cachedProfileGroupID";
|
||||
const DEFAULT_THEME_ID = "default-theme@mozilla.org";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
|
||||
ClientID: "resource://gre/modules/ClientID.sys.mjs",
|
||||
CryptoUtils: "resource://services-crypto/utils.sys.mjs",
|
||||
EveryWindow: "resource:///modules/EveryWindow.sys.mjs",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
||||
Sqlite: "resource://gre/modules/Sqlite.sys.mjs",
|
||||
AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
|
||||
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
||||
setTimeout: "resource://gre/modules/Timer.sys.mjs",
|
||||
Sqlite: "resource://gre/modules/Sqlite.sys.mjs",
|
||||
TelemetryUtils: "resource://gre/modules/TelemetryUtils.sys.mjs",
|
||||
});
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "profilesLocalization", () => {
|
||||
|
@ -122,7 +125,7 @@ class SelectableProfileServiceClass extends EventEmitter {
|
|||
"datareporting.policy.minimumPolicyVersion",
|
||||
"datareporting.policy.minimumPolicyVersion.channel-beta",
|
||||
"datareporting.usage.uploadEnabled",
|
||||
"toolkit.telemetry.cachedProfileGroupID",
|
||||
GROUPID_PREF_NAME,
|
||||
];
|
||||
|
||||
// Preferences that were previously shared but should now be ignored.
|
||||
|
@ -963,6 +966,18 @@ class SelectableProfileServiceClass extends EventEmitter {
|
|||
continue;
|
||||
}
|
||||
|
||||
// If the user has disabled then re-enabled data collection in another
|
||||
// profile in the group, an extra step is needed to ensure each profile
|
||||
// uses the same profile group ID.
|
||||
if (
|
||||
name === GROUPID_PREF_NAME &&
|
||||
value !== lazy.TelemetryUtils.knownProfileGroupID &&
|
||||
value !== Services.prefs.getCharPref(GROUPID_PREF_NAME)
|
||||
) {
|
||||
await lazy.ClientID.setProfileGroupID(value); // Sets the pref for us.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
Services.prefs.clearUserPref(name);
|
||||
} else {
|
||||
|
|
|
@ -20,6 +20,7 @@ const { SelectableProfileService } = ChromeUtils.importESModule(
|
|||
export class ProfileSelector extends MozLitElement {
|
||||
static properties = {
|
||||
profiles: { type: Array },
|
||||
showSelector: { type: Boolean },
|
||||
};
|
||||
|
||||
static queries = {
|
||||
|
@ -93,6 +94,8 @@ export class ProfileSelector extends MozLitElement {
|
|||
await this.selectableProfileService.init();
|
||||
await this.selectableProfileService.maybeSetupDataStore();
|
||||
this.profiles = await this.selectableProfileService.getAllProfiles();
|
||||
this.showSelector =
|
||||
this.selectableProfileService.groupToolkitProfile.showProfileSelector;
|
||||
|
||||
if (!this.profiles.length) {
|
||||
this.selectableProfileService.setShowProfileSelectorWindow(false);
|
||||
|
@ -110,10 +113,11 @@ export class ProfileSelector extends MozLitElement {
|
|||
}
|
||||
|
||||
handleCheckboxToggle() {
|
||||
let state = this.checkbox.checked ? "enabled" : "disabled";
|
||||
this.showSelector = this.checkbox.checked;
|
||||
let state = this.showSelector ? "enabled" : "disabled";
|
||||
Glean.profilesSelectorWindow.showAtStartup.record({ value: state });
|
||||
this.selectableProfileService.setShowProfileSelectorWindow(
|
||||
this.checkbox.checked
|
||||
this.showSelector
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -180,9 +184,15 @@ export class ProfileSelector extends MozLitElement {
|
|||
<moz-checkbox
|
||||
@click=${this.handleCheckboxToggle}
|
||||
data-l10n-id="profile-window-checkbox-label-2"
|
||||
?checked=${this.selectableProfileService.groupToolkitProfile
|
||||
.showProfileSelector}
|
||||
></moz-checkbox>`;
|
||||
?checked=${this.showSelector}
|
||||
>
|
||||
${!this.showSelector
|
||||
? html`<span
|
||||
slot="description"
|
||||
data-l10n-id="profile-window-checkbox-subcopy"
|
||||
></span>`
|
||||
: null}
|
||||
</moz-checkbox>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,13 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const lazy = {};
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
ClientID: "resource://gre/modules/ClientID.sys.mjs",
|
||||
setTimeout: "resource://gre/modules/Timer.sys.mjs",
|
||||
TelemetryUtils: "resource://gre/modules/TelemetryUtils.sys.mjs",
|
||||
});
|
||||
|
||||
// Note: copied from preferences head.js. We can remove this when we migrate
|
||||
// this test into that component.
|
||||
async function openPreferencesViaOpenPreferencesAPI(aPane, aOptions) {
|
||||
|
@ -178,3 +185,99 @@ add_task(async function testPrivacyInfoHiddenWhenDisabled() {
|
|||
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// If the user disables data collection, then re-enables data collection in
|
||||
// another profile in the profile group, verify that the new profile group ID
|
||||
// is correctly set to the value passed in from the database.
|
||||
add_task(async function testReactivateProfileGroupID() {
|
||||
if (!AppConstants.MOZ_TELEMETRY_REPORTING) {
|
||||
ok(true, "Skipping test because telemetry reporting is disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
await initGroupDatabase();
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["datareporting.healthreport.uploadEnabled", true]],
|
||||
});
|
||||
|
||||
await openPreferencesViaOpenPreferencesAPI("privacy", {
|
||||
leaveOpen: true,
|
||||
});
|
||||
let checkbox = gBrowser.contentDocument.getElementById(
|
||||
"submitHealthReportBox"
|
||||
);
|
||||
ok(
|
||||
checkbox.checked,
|
||||
"initially the data reporting checkbox should be checked"
|
||||
);
|
||||
|
||||
let checkboxUpdated = BrowserTestUtils.waitForMutationCondition(
|
||||
checkbox,
|
||||
{ attributeFilter: ["checked"] },
|
||||
() => !checkbox.checked
|
||||
);
|
||||
|
||||
checkbox.click();
|
||||
await checkboxUpdated;
|
||||
|
||||
Assert.ok(
|
||||
!checkbox.checked,
|
||||
"checkbox should not be checked after waiting for update"
|
||||
);
|
||||
Assert.equal(
|
||||
Services.prefs.getBoolPref("datareporting.healthreport.uploadEnabled"),
|
||||
false,
|
||||
"upload should be disabled after unchecking checkbox"
|
||||
);
|
||||
|
||||
// TODO: what could we explicitly await, rather than resorting to a timeout?
|
||||
await new Promise(resolve => lazy.setTimeout(resolve, 1000));
|
||||
|
||||
Assert.equal(
|
||||
Services.prefs.getStringPref("toolkit.telemetry.cachedProfileGroupID"),
|
||||
lazy.TelemetryUtils.knownProfileGroupID,
|
||||
"after disabling data collection, the profile group ID pref should have the canary value"
|
||||
);
|
||||
|
||||
let groupID = await lazy.ClientID.getProfileGroupID();
|
||||
Assert.equal(
|
||||
groupID,
|
||||
lazy.TelemetryUtils.knownProfileGroupID,
|
||||
"after disabling data collection, the ClientID profile group ID should have the canary value"
|
||||
);
|
||||
|
||||
// Simulate an update request from another instance that re-enables data
|
||||
// reporting and sends over a new profile group ID.
|
||||
let NEW_GROUP_ID = "12345678-b0ba-cafe-face-decafbad0123";
|
||||
SelectableProfileService._getAllDBPrefs =
|
||||
SelectableProfileService.getAllDBPrefs;
|
||||
SelectableProfileService.getAllDBPrefs = () => [
|
||||
{
|
||||
name: "datareporting.healthreport.uploadEnabled",
|
||||
value: true,
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
name: "toolkit.telemetry.cachedProfileGroupID",
|
||||
value: NEW_GROUP_ID,
|
||||
type: "string",
|
||||
},
|
||||
];
|
||||
await SelectableProfileService.loadSharedPrefsFromDatabase();
|
||||
|
||||
groupID = await lazy.ClientID.getProfileGroupID();
|
||||
Assert.equal(
|
||||
groupID,
|
||||
NEW_GROUP_ID,
|
||||
"after re-enabling data collection, the ClientID profile group ID should have the remote value"
|
||||
);
|
||||
Assert.equal(
|
||||
Services.prefs.getStringPref("toolkit.telemetry.cachedProfileGroupID"),
|
||||
NEW_GROUP_ID,
|
||||
"after re-enabling data collection, the profile group ID pref should have the remote value"
|
||||
);
|
||||
SelectableProfileService.getAllDBPrefs =
|
||||
SelectableProfileService._getAllDBPrefs;
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
|
|
@ -73,6 +73,11 @@ add_task(async function test_selector_window() {
|
|||
|
||||
Assert.ok(profileSelector.checkbox.checked, "Checkbox should be checked");
|
||||
|
||||
Assert.ok(
|
||||
!profileSelector.checkbox.querySelector('[slot="description"]'),
|
||||
"Description slot should not exist when checkbox is checked"
|
||||
);
|
||||
|
||||
let asyncFlushCalled = false;
|
||||
gProfileService.asyncFlush = () => (asyncFlushCalled = true);
|
||||
|
||||
|
@ -101,6 +106,11 @@ add_task(async function test_selector_window() {
|
|||
"Profile selector should be disabled"
|
||||
);
|
||||
|
||||
Assert.ok(
|
||||
profileSelector.checkbox.querySelector('[slot="description"]'),
|
||||
"Description slot should exist when checkbox is unchecked"
|
||||
);
|
||||
|
||||
await assertGlean(
|
||||
"profiles",
|
||||
"selector_window",
|
||||
|
@ -124,6 +134,11 @@ add_task(async function test_selector_window() {
|
|||
"Profile selector should be disabled"
|
||||
);
|
||||
|
||||
Assert.ok(
|
||||
!profileSelector.checkbox.querySelector('[slot="description"]'),
|
||||
"Description slot should not exist when checkbox is checked again"
|
||||
);
|
||||
|
||||
profileSelector.selectableProfileService.execProcess = mock;
|
||||
|
||||
const profiles = profileSelector.profileCards;
|
||||
|
|
|
@ -17,8 +17,6 @@ ChromeUtils.defineESModuleGetters(this, {
|
|||
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
|
||||
SEARCH_TELEMETRY_SHARED:
|
||||
"moz-src:///browser/components/search/SearchSERPTelemetry.sys.mjs",
|
||||
SearchSERPCategorization:
|
||||
"resource:///modules/SearchSERPCategorization.sys.mjs",
|
||||
SearchSERPDomainToCategoriesMap:
|
||||
"moz-src:///browser/components/search/SearchSERPTelemetry.sys.mjs",
|
||||
SearchUtils: "resource://gre/modules/SearchUtils.sys.mjs",
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"use strict";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
ReviewCheckerParent: "resource:///actors/ReviewCheckerParent.sys.mjs",
|
||||
ShoppingUtils: "resource:///modules/ShoppingUtils.sys.mjs",
|
||||
});
|
||||
|
||||
|
@ -111,7 +112,10 @@ async function assertEmptyStateType(browser, messageName) {
|
|||
!content.document.getElementById("multi-stage-message-root").hidden,
|
||||
"message is shown"
|
||||
);
|
||||
ok(content.document.querySelector(className), "Rendered correct message");
|
||||
ok(
|
||||
content.document.querySelector(className),
|
||||
`Rendered correct message ${className}`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -186,6 +190,9 @@ add_task(async function test_showOnboarding_notOptedIn() {
|
|||
Services.fog.testResetFOG();
|
||||
await Services.fog.testFlushAllChildren();
|
||||
|
||||
let sandbox = sinon.createSandbox();
|
||||
sandbox.stub(ReviewCheckerParent, "isIgnoredURL").returns(false);
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
url: "about:shoppingsidebar",
|
||||
|
@ -215,6 +222,7 @@ add_task(async function test_showOnboarding_notOptedIn() {
|
|||
info("Failed to get Glean value due to unknown bug. See bug 1862389.");
|
||||
}
|
||||
}
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -229,6 +237,9 @@ add_task(async function test_showOnboarding_notOptedIn_supported() {
|
|||
Services.fog.testResetFOG();
|
||||
await Services.fog.testFlushAllChildren();
|
||||
|
||||
let sandbox = sinon.createSandbox();
|
||||
sandbox.stub(ReviewCheckerParent, "isIgnoredURL").returns(false);
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
url: "about:shoppingsidebar",
|
||||
|
@ -259,6 +270,7 @@ add_task(async function test_showOnboarding_notOptedIn_supported() {
|
|||
}
|
||||
}
|
||||
await SpecialPowers.popPrefEnv();
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -275,6 +287,9 @@ add_task(
|
|||
Services.fog.testResetFOG();
|
||||
await Services.fog.testFlushAllChildren();
|
||||
|
||||
let sandbox = sinon.createSandbox();
|
||||
sandbox.stub(ReviewCheckerParent, "isIgnoredURL").returns(false);
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
url: "about:shoppingsidebar",
|
||||
|
@ -308,6 +323,7 @@ add_task(
|
|||
}
|
||||
}
|
||||
await SpecialPowers.popPrefEnv();
|
||||
sandbox.restore();
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -18,3 +18,6 @@ EXTRA_JS_MODULES += [
|
|||
XPCSHELL_TESTS_MANIFESTS += ["tests/unit/xpcshell.toml"]
|
||||
|
||||
SPHINX_TREES["docs"] = "docs"
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ("Firefox", "Sidebar")
|
||||
|
|
|
@ -558,9 +558,7 @@ add_task(async function test_sidebar_tabs_layout() {
|
|||
});
|
||||
|
||||
add_task(async function test_sidebar_position_rtl_ui() {
|
||||
const sandbox = sinon.createSandbox();
|
||||
sandbox.stub(window, "RTL_UI").value(true);
|
||||
await SpecialPowers.pushPrefEnv({ set: [["intl.l10n.pseudo", "bidi"]] });
|
||||
await BrowserTestUtils.enableRtlLocale();
|
||||
Services.fog.testResetFOG();
|
||||
|
||||
// When RTL is enabled, sidebar is shown on the right by default.
|
||||
|
@ -578,8 +576,7 @@ add_task(async function test_sidebar_position_rtl_ui() {
|
|||
"right"
|
||||
);
|
||||
|
||||
sandbox.restore();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await BrowserTestUtils.disableRtlLocale();
|
||||
await SidebarController.waitUntilStable();
|
||||
});
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
background:
|
||||
linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, 0.4) 0)
|
||||
no-repeat 100% 0 / 1em 1em,
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-red-05) 0);
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-red-0) 0);
|
||||
display: flex;
|
||||
font-size: 14px !important;
|
||||
height: 85px;
|
||||
|
@ -176,21 +176,21 @@
|
|||
background:
|
||||
linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, 0.4) 0)
|
||||
no-repeat 100% 0 / 1em 1em,
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-green-05) 0);
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-green-0) 0);
|
||||
}
|
||||
|
||||
&.blue {
|
||||
background:
|
||||
linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, 0.4) 0)
|
||||
no-repeat 100% 0 / 1em 1em,
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-blue-05) 0);
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-blue-0) 0);
|
||||
}
|
||||
|
||||
&.orange {
|
||||
background:
|
||||
linear-gradient(to left bottom, transparent 50%, rgba(0, 0, 0, 0.4) 0)
|
||||
no-repeat 100% 0 / 1em 1em,
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-yellow-05) 0);
|
||||
linear-gradient(-135deg, transparent 0.7em, var(--color-yellow-0) 0);
|
||||
}
|
||||
|
||||
&.big {
|
||||
|
|
|
@ -54,7 +54,7 @@ const EXPECTED_EMBEDDING_MODEL_OBJECTS = 4;
|
|||
|
||||
export const DIM_REDUCTION_METHODS = {};
|
||||
const MISSING_ANCHOR_IN_CLUSTER_PENALTY = 0.2;
|
||||
const NEAREST_NEIGHBOR_DEFAULT_THRESHOLD = 0.21;
|
||||
const NEAREST_NEIGHBOR_DEFAULT_THRESHOLD = 0.275;
|
||||
const MAX_NN_GROUPED_TABS = 4;
|
||||
const MAX_SUGGESTED_TABS = 10;
|
||||
|
||||
|
@ -250,7 +250,7 @@ export class SmartTabGroupingManager {
|
|||
groupLabel = "",
|
||||
threshold = NEAREST_NEIGHBOR_DEFAULT_THRESHOLD,
|
||||
precomputedEmbeddings = [],
|
||||
depth = 1,
|
||||
depth = 0,
|
||||
}) {
|
||||
// get embeddings for all the tabs
|
||||
const tabData = await this._prepareTabData(allTabs);
|
||||
|
@ -258,7 +258,7 @@ export class SmartTabGroupingManager {
|
|||
if (precomputedEmbeddings.length === 0) {
|
||||
embeddings = await this._generateEmbeddings(
|
||||
tabData.map((td, index) => {
|
||||
let text = td[EMBED_TEXT_KEY];
|
||||
let text = SmartTabGroupingManager.preprocessText(td[EMBED_TEXT_KEY]);
|
||||
// augment with group name if it's present
|
||||
if (groupLabel && groupedIndices.includes(index)) {
|
||||
text = `${groupLabel.slice(0, 100)}. ${td[EMBED_TEXT_KEY]}`;
|
||||
|
@ -772,6 +772,42 @@ export class SmartTabGroupingManager {
|
|||
return phrase; // return original phrase
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes trailing domain-related text such as '... - Mail' or '... | News'
|
||||
* If there's not enough information remaining after, we keep the text as is
|
||||
* @param {string} text tab title with potential domain information
|
||||
* @return {string}
|
||||
*/
|
||||
static preprocessText(text) {
|
||||
// Matches 'xyz - Domain' or 'xyz | Domain'
|
||||
// with a space before and after delimiter
|
||||
// or if there are multiple delimiters next to each other
|
||||
const delimiters = /(?<=\s)[|–-]+(?=\s)/;
|
||||
const splitText = text.split(delimiters);
|
||||
|
||||
// ensure there's enough info without the last element
|
||||
const hasEnoughInfo =
|
||||
!!splitText.length && splitText.slice(0, -1).join(" ").length > 5;
|
||||
|
||||
// domain related texts are usually shorter, this takes care of the most common cases
|
||||
const isPotentialDomainInfo =
|
||||
splitText.length > 1 && splitText[splitText.length - 1].length < 20;
|
||||
|
||||
// If both conditions are met, remove the last chunk, filter out empty strings,
|
||||
// join on space, trim, and lowercase
|
||||
if (hasEnoughInfo && isPotentialDomainInfo) {
|
||||
return splitText
|
||||
.slice(0, -1) // everything except the last element
|
||||
.map(t => t.trim())
|
||||
.filter(Boolean) // remove empty strings
|
||||
.join(" ") // join with spaces
|
||||
.trim(); // remove leading/trailing spaces
|
||||
}
|
||||
|
||||
// Otherwise, just return the text
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Postprocessing of raw output from Topic Model ML Engine
|
||||
* @param {string | undefined} topic Raw topic phrase from topic model or undefined in case of an error
|
||||
|
|
|
@ -3945,13 +3945,22 @@
|
|||
// 2) `itemAfter` is in a different tab group
|
||||
this.moveTabToGroup(tab, tabGroup);
|
||||
}
|
||||
} else if (
|
||||
this.isTab(itemAfter) &&
|
||||
itemAfter?.group?.tabs[0] == itemAfter
|
||||
) {
|
||||
// If there is ambiguity around whether or not a tab should be inserted
|
||||
// into a group (i.e. because the new tab is being inserted on the
|
||||
// edges of the group), prefer not to insert the tab into the group.
|
||||
//
|
||||
// We only need to handle the case where the tab is being inserted at
|
||||
// the starting boundary of a group because `insertBefore` called on
|
||||
// the tab just after a tab group will not add it to the group by
|
||||
// default.
|
||||
this.tabContainer.insertBefore(tab, itemAfter.group);
|
||||
} else {
|
||||
// Place ungrouped tab before `itemAfter` or its group
|
||||
// 1) Ungrouped tab between standalone tabs
|
||||
// 2) Ungrouped tab at the end of the tab strip
|
||||
// 3) Ungrouped tab right before the next tab group, if the
|
||||
// next tab is in a group
|
||||
this.tabContainer.insertBefore(tab, itemAfter?.group ?? itemAfter);
|
||||
// Place ungrouped tab before `itemAfter` by default
|
||||
this.tabContainer.insertBefore(tab, itemAfter);
|
||||
}
|
||||
|
||||
this._updateTabsAfterInsert();
|
||||
|
|
|
@ -191,6 +191,13 @@
|
|||
"always-show"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"_sidebarPositionStart",
|
||||
"sidebar.position_start",
|
||||
true
|
||||
);
|
||||
|
||||
if (gMultiProcessBrowser) {
|
||||
this.tabbox.tabpanels.setAttribute("async", "true");
|
||||
}
|
||||
|
@ -1028,29 +1035,8 @@
|
|||
}
|
||||
|
||||
#setMovingTabMode(movingTab) {
|
||||
if (movingTab == this.#isMovingTab()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.toggleAttribute("movingtab", movingTab);
|
||||
gNavToolbox.toggleAttribute("movingtab", movingTab);
|
||||
|
||||
if (movingTab) {
|
||||
// This is a bit of an escape hatch in case a tab drag & drop session
|
||||
// wasn't ended properly, leaving behind the movingtab attribute, which
|
||||
// may break the UI (bug 1954163). We don't get mousemove events while
|
||||
// dragging tabs, so at that point it should be safe to assume that we
|
||||
// should not be in drag and drop mode, and clean things up if needed.
|
||||
requestAnimationFrame(() => {
|
||||
this.addEventListener(
|
||||
"mousemove",
|
||||
() => {
|
||||
this.finishAnimateTabMove();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#isMovingTab() {
|
||||
|
@ -1395,7 +1381,10 @@
|
|||
let crossAxisPos = this.verticalMode ? event.screenX : event.screenY;
|
||||
let crossAxisStart, crossAxisEnd;
|
||||
if (this.verticalMode) {
|
||||
if (RTL_UI) {
|
||||
if (
|
||||
(RTL_UI && this._sidebarPositionStart) ||
|
||||
(!RTL_UI && !this._sidebarPositionStart)
|
||||
) {
|
||||
crossAxisStart = window.screenX + rect.right - 1.5 * rect.width;
|
||||
crossAxisEnd = window.screenX;
|
||||
} else {
|
||||
|
|
|
@ -179,3 +179,87 @@ add_task(async function test_tabs_to_suggest_should_exclude_firefox_view() {
|
|||
"about:firefoxview should be excluded"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(function test_text_processing_basic_cases() {
|
||||
// trailing domain-like text should be removed
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText("Some Title - Random Mail"),
|
||||
"Some Title",
|
||||
"Should remove '- Random Mail' suffix and lowercase result"
|
||||
);
|
||||
|
||||
// trailing domain-like text with '|'
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText(
|
||||
"Another Title | Some Video Website"
|
||||
),
|
||||
"Another Title",
|
||||
"Should remove '| Some Video Website' suffix and lowercase result"
|
||||
);
|
||||
|
||||
// no delimiter
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText("Simple Title"),
|
||||
"Simple Title",
|
||||
"Should only be lowercased since there's no recognized delimiter"
|
||||
);
|
||||
|
||||
// not enough info in first part
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText("AB - Mail"),
|
||||
"AB - Mail",
|
||||
"Should not remove '- Mail' because the first part is too short"
|
||||
);
|
||||
|
||||
// should not match for texts such as 'check-in'
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText("Check-in for flight"),
|
||||
"Check-in for flight",
|
||||
"Should not remove '-in'"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(function test_text_processing_edge_cases() {
|
||||
// empty string
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText(""),
|
||||
"",
|
||||
"Empty string returns empty string"
|
||||
);
|
||||
|
||||
// exactly 20 chars
|
||||
const domain20Chars = "12345678901234567890"; // 20 characters
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText(`My Title - ${domain20Chars}`),
|
||||
`My Title - ${domain20Chars}`,
|
||||
"Should not remove suffix because it’s exactly 20 chars long, not < 20"
|
||||
);
|
||||
|
||||
// multiple delimiters, remove last only
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText("Complex - Title - SomethingSmall"),
|
||||
"Complex Title",
|
||||
"Should remove only the last '- SomethingSmall', ignoring earlier delimiters"
|
||||
);
|
||||
|
||||
// repeated delimiters
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText("Title --- Domain"),
|
||||
"Title",
|
||||
"Should remove the last chunk and filter out empty strings"
|
||||
);
|
||||
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText("Title || Domain"),
|
||||
"Title",
|
||||
"Should remove the last chunk with double pipe delimiters too"
|
||||
);
|
||||
|
||||
// long trailing text
|
||||
const longDomain = "Useful information is present";
|
||||
Assert.equal(
|
||||
SmartTabGroupingManager.preprocessText(`Some Title - ${longDomain}`),
|
||||
`Some Title - ${longDomain}`,
|
||||
"Should not remove suffix if it's >= 20 characters"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -2169,3 +2169,63 @@ add_task(async function test_bug1936015() {
|
|||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
add_task(async function test_bug1957723_addTabsByIndex() {
|
||||
let initialTab = gBrowser.tabs[0];
|
||||
let triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
|
||||
const tabs = createManyTabs(5);
|
||||
const tabGroup = gBrowser.addTabGroup([tabs[1], tabs[2], tabs[3]], {
|
||||
insertBefore: tabs[1],
|
||||
});
|
||||
|
||||
let tab1 = gBrowser.addTab("https://example.com", {
|
||||
index: 2,
|
||||
triggeringPrincipal,
|
||||
});
|
||||
Assert.equal(
|
||||
tab1._tPos,
|
||||
2,
|
||||
"Tab added at starting index of tab group is in correct position"
|
||||
);
|
||||
Assert.equal(
|
||||
tab1.group,
|
||||
null,
|
||||
"Tab added at starting index of tab group is not in group"
|
||||
);
|
||||
gBrowser.removeTab(tab1);
|
||||
|
||||
let tab2 = gBrowser.addTab("https://example.com", {
|
||||
index: 4,
|
||||
triggeringPrincipal,
|
||||
});
|
||||
Assert.equal(
|
||||
tab2._tPos,
|
||||
4,
|
||||
"Tab added by index just before end of tab group is in correct position"
|
||||
);
|
||||
Assert.equal(
|
||||
tab2.group.id,
|
||||
tabGroup.id,
|
||||
"Tab added by index just before end of tab group is in group"
|
||||
);
|
||||
gBrowser.removeTab(tab2);
|
||||
|
||||
let tab3 = gBrowser.addTab("https://example.com", {
|
||||
index: 5,
|
||||
triggeringPrincipal,
|
||||
});
|
||||
Assert.equal(
|
||||
tab3._tPos,
|
||||
5,
|
||||
"Tab added at index just after end of tab group is in correct position"
|
||||
);
|
||||
Assert.equal(
|
||||
tab3.group,
|
||||
null,
|
||||
"Tab added at index just after end of tab group is not in group"
|
||||
);
|
||||
gBrowser.removeTab(tab3);
|
||||
|
||||
gBrowser.removeAllTabsBut(initialTab);
|
||||
});
|
||||
|
|
|
@ -34,6 +34,8 @@ support-files = [
|
|||
|
||||
["browser_translations_full_page_move_tab_to_new_window.js"]
|
||||
|
||||
["browser_translations_full_page_moz_extension.js"]
|
||||
|
||||
["browser_translations_full_page_multiple_windows.js"]
|
||||
|
||||
["browser_translations_full_page_panel_a11y_focus.js"]
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Tests a basic panel open, translation, and restoration to the original language.
|
||||
*/
|
||||
add_task(async function test_translations_moz_extension() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
web_accessible_resources: ["test_page.html"],
|
||||
},
|
||||
files: {
|
||||
"test_page.html": `<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<body>
|
||||
<div>
|
||||
<h1>Don Quijote de La Mancha</h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>`,
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
const { cleanup, resolveDownloads, runInPage } = await loadTestPage({
|
||||
page: `moz-extension://${extension.uuid}/test_page.html`,
|
||||
languagePairs: LANGUAGE_PAIRS,
|
||||
});
|
||||
|
||||
const { button } =
|
||||
await FullPageTranslationsTestUtils.assertTranslationsButton(
|
||||
{ button: true, circleArrows: false, locale: false, icon: true },
|
||||
"The button is available."
|
||||
);
|
||||
|
||||
is(button.getAttribute("data-l10n-id"), "urlbar-translations-button2");
|
||||
|
||||
await FullPageTranslationsTestUtils.assertPageIsUntranslated(runInPage);
|
||||
|
||||
await FullPageTranslationsTestUtils.openPanel({
|
||||
expectedFromLanguage: "es",
|
||||
expectedToLanguage: "en",
|
||||
onOpenPanel: FullPageTranslationsTestUtils.assertPanelViewDefault,
|
||||
});
|
||||
|
||||
await FullPageTranslationsTestUtils.clickTranslateButton({
|
||||
downloadHandler: resolveDownloads,
|
||||
});
|
||||
|
||||
await FullPageTranslationsTestUtils.assertPageIsTranslated({
|
||||
fromLanguage: "es",
|
||||
toLanguage: "en",
|
||||
runInPage,
|
||||
});
|
||||
|
||||
await cleanup();
|
||||
await extension.unload();
|
||||
});
|
|
@ -48,9 +48,6 @@ let globalActionsProviders = [
|
|||
* A provider that lets the user view all available global actions for a query.
|
||||
*/
|
||||
class ProviderGlobalActions extends UrlbarProvider {
|
||||
// A Map of the last queried actions.
|
||||
#actions = new Map();
|
||||
|
||||
get name() {
|
||||
return "UrlbarProviderGlobalActions";
|
||||
}
|
||||
|
@ -68,8 +65,7 @@ class ProviderGlobalActions extends UrlbarProvider {
|
|||
}
|
||||
|
||||
async startQuery(queryContext, addCallback) {
|
||||
this.#actions.clear();
|
||||
|
||||
let actionsResults = [];
|
||||
let searchModeEngine = "";
|
||||
|
||||
for (let provider of globalActionsProviders) {
|
||||
|
@ -81,12 +77,12 @@ class ProviderGlobalActions extends UrlbarProvider {
|
|||
// We only allow one action that provides an engine search mode.
|
||||
continue;
|
||||
}
|
||||
this.#actions.set(action.key, action);
|
||||
actionsResults.push(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.#actions.size) {
|
||||
if (!actionsResults.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -94,14 +90,12 @@ class ProviderGlobalActions extends UrlbarProvider {
|
|||
lazy.UrlbarPrefs.get(TIMES_TO_SHOW_PREF) >
|
||||
lazy.UrlbarPrefs.get(TIMES_SHOWN_PREF);
|
||||
|
||||
let results = [...this.#actions.keys()];
|
||||
|
||||
let query = results.includes("matched-contextual-search")
|
||||
let query = actionsResults.some(a => a.key == "matched-contextual-search")
|
||||
? ""
|
||||
: queryContext.searchString;
|
||||
|
||||
let payload = {
|
||||
results,
|
||||
actionsResults,
|
||||
dynamicType: DYNAMIC_TYPE_NAME,
|
||||
inputLength: queryContext.searchString.length,
|
||||
input: query,
|
||||
|
@ -125,12 +119,14 @@ class ProviderGlobalActions extends UrlbarProvider {
|
|||
|
||||
onSelection(result, element) {
|
||||
let key = element.dataset.action;
|
||||
this.#actions.get(key).onSelection?.(result, element);
|
||||
let action = result.payload.actionsResults.find(a => a.key == key);
|
||||
action.onSelection?.(result, element);
|
||||
}
|
||||
|
||||
onEngagement(queryContext, controller, details) {
|
||||
let key = details.element.dataset.action;
|
||||
let options = this.#actions.get(key).onPick(queryContext, controller);
|
||||
let action = details.result.payload.actionsResults.find(a => a.key == key);
|
||||
let options = action.onPick(queryContext, controller);
|
||||
if (options?.focusContent) {
|
||||
details.element.ownerGlobal.gBrowser.selectedBrowser.focus();
|
||||
}
|
||||
|
@ -153,15 +149,14 @@ class ProviderGlobalActions extends UrlbarProvider {
|
|||
}
|
||||
|
||||
getViewTemplate(result) {
|
||||
let children = result.payload.results.map((key, i) => {
|
||||
let action = this.#actions.get(key);
|
||||
let children = result.payload.actionsResults.map((action, i) => {
|
||||
let btn = {
|
||||
name: `button-${i}`,
|
||||
tag: "span",
|
||||
classList: ["urlbarView-action-btn"],
|
||||
attributes: {
|
||||
inputLength: result.payload.inputLength,
|
||||
"data-action": key,
|
||||
"data-action": action.key,
|
||||
role: "button",
|
||||
},
|
||||
children: [
|
||||
|
@ -211,8 +206,7 @@ class ProviderGlobalActions extends UrlbarProvider {
|
|||
l10n: { id: "press-tab-label", cacheable: true },
|
||||
};
|
||||
}
|
||||
result.payload.results.forEach((key, i) => {
|
||||
let action = this.#actions.get(key);
|
||||
result.payload.actionsResults.forEach((action, i) => {
|
||||
viewUpdate[`label-${i}`] = {
|
||||
l10n: { id: action.l10nId, args: action.l10nArgs, cacheable: true },
|
||||
};
|
||||
|
|
|
@ -1599,7 +1599,7 @@ export var UrlbarUtils = {
|
|||
if (result.providerName != "UrlbarProviderGlobalActions") {
|
||||
return result.payload.action?.key ?? "none";
|
||||
}
|
||||
return result.payload.results.map(({ key }) => key).join(",");
|
||||
return result.payload.actionsResults.map(({ key }) => key).join(",");
|
||||
},
|
||||
|
||||
_getQuickSuggestTelemetryType(result) {
|
||||
|
|
|
@ -431,7 +431,7 @@ export class UrlbarView {
|
|||
return;
|
||||
}
|
||||
|
||||
let l10n = { id: "firefox-suggest-feedback-acknowledgment" };
|
||||
let l10n = { id: "urlbar-feedback-acknowledgment" };
|
||||
await this.#l10nCache.ensure(l10n);
|
||||
if (row.result != result) {
|
||||
return;
|
||||
|
|
|
@ -53,9 +53,6 @@ urlbar-group-local =
|
|||
urlbar-group-sponsored =
|
||||
.label = Sponsored
|
||||
|
||||
# A message shown in a result when the user gives feedback on it.
|
||||
firefox-suggest-feedback-acknowledgment = Thanks for your feedback
|
||||
|
||||
# A message that replaces a result when the user dismisses a single suggestion.
|
||||
firefox-suggest-dismissal-acknowledgment-one = Thanks for your feedback. You won’t see this suggestion again.
|
||||
|
||||
|
@ -133,8 +130,6 @@ firefox-suggest-weather-sponsored = { $provider } · Sponsored
|
|||
|
||||
## These strings are used as labels of menu items in the result menu.
|
||||
|
||||
firefox-suggest-command-show-less-frequently =
|
||||
.label = Show less frequently
|
||||
firefox-suggest-command-dont-show-this =
|
||||
.label = Don’t show this
|
||||
firefox-suggest-command-dont-show-mdn =
|
||||
|
@ -143,8 +138,6 @@ firefox-suggest-command-not-relevant =
|
|||
.label = Not relevant
|
||||
firefox-suggest-command-not-interested =
|
||||
.label = Not interested
|
||||
firefox-suggest-weather-command-inaccurate-location =
|
||||
.label = Report inaccurate location
|
||||
firefox-suggest-command-manage-fakespot =
|
||||
.label = Manage { -fakespot-brand-name } suggestions
|
||||
firefox-suggest-command-dont-show-this-suggestion =
|
||||
|
|
|
@ -559,6 +559,7 @@ urlbar:
|
|||
type: boolean
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852058
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1958147
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852058#c2
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866204#c8
|
||||
|
@ -569,7 +570,7 @@ urlbar:
|
|||
- interaction
|
||||
notification_emails:
|
||||
- fx-search-telemetry@mozilla.com
|
||||
expires: 140
|
||||
expires: 147
|
||||
|
||||
pref_max_results:
|
||||
lifetime: application
|
||||
|
|
|
@ -128,7 +128,7 @@ export class AddonSuggestions extends SuggestProvider {
|
|||
commands.push({
|
||||
name: RESULT_MENU_COMMAND.SHOW_LESS_FREQUENTLY,
|
||||
l10n: {
|
||||
id: "firefox-suggest-command-show-less-frequently",
|
||||
id: "urlbar-result-menu-show-less-frequently",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue