mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 10:23:02 +00:00
On wasm, detect_system_lang() always returned English, so Auto showed English whatever the browser's language. It now reads navigator.languages in order, then navigator.language, and takes the first tag with a catalog, as the desktop builds do with the system languages and as VectorCraft and FilmCraft do in their browser builds. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -71,7 +71,7 @@ rfd = { workspace = true, features = ["file-handle-inner"] }
|
||||
wasm-bindgen-futures = "0.4"
|
||||
wasm-bindgen = "0.2"
|
||||
js-sys = "0.3"
|
||||
web-sys = { version = "0.3", features = ["Window", "Document", "Element", "HtmlElement", "HtmlAnchorElement", "Blob", "BlobPropertyBag", "Url", "HtmlIFrameElement", "HtmlImageElement", "HtmlCollection", "Node", "EventTarget"] }
|
||||
web-sys = { version = "0.3", features = ["Window", "Document", "Element", "HtmlElement", "HtmlAnchorElement", "Blob", "BlobPropertyBag", "Url", "HtmlIFrameElement", "HtmlImageElement", "HtmlCollection", "Node", "EventTarget", "Navigator"] }
|
||||
|
||||
[dev-dependencies]
|
||||
pdfcraft-xfa = { workspace = true }
|
||||
|
||||
@@ -390,9 +390,23 @@ fn first_supported(list: &str) -> Option<Lang> {
|
||||
list.split(['(', ')', ',', '"', '\n']).map(str::trim).filter(|s| !s.is_empty()).find_map(lang_from_tag)
|
||||
}
|
||||
|
||||
/// The first supported language among BCP 47 tags in preference order, as the browser lists them
|
||||
/// in `navigator.languages` (#2954). Only the first few tags are looked at: the list is short in
|
||||
/// practice, and a page can't make Auto walk an unbounded one.
|
||||
#[cfg_attr(not(target_arch = "wasm32"), allow(dead_code))]
|
||||
fn first_supported_tag<S: AsRef<str>>(tags: impl IntoIterator<Item = S>) -> Option<Lang> {
|
||||
tags.into_iter().take(32).find_map(|tag| lang_from_tag(tag.as_ref().trim()))
|
||||
}
|
||||
|
||||
/// The browser's preferred languages, as the desktop builds use the system's: `navigator.languages`
|
||||
/// in order, then `navigator.language` (kept within the 32 tags `first_supported_tag` reads).
|
||||
/// English when the browser offers none we have a catalog for.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn detect_system_lang() -> Lang {
|
||||
Lang::EN
|
||||
let Some(navigator) = web_sys::window().map(|w| w.navigator()) else { return Lang::EN };
|
||||
let mut tags: Vec<String> = navigator.languages().iter().take(31).filter_map(|v| v.as_string()).collect();
|
||||
tags.extend(navigator.language());
|
||||
first_supported_tag(&tags).unwrap_or(Lang::EN)
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
@@ -650,6 +664,21 @@ mod tests {
|
||||
assert_eq!(first_supported("("), None);
|
||||
}
|
||||
|
||||
/// #2954: the web build's Auto language follows the browser's preferred languages in order,
|
||||
/// skipping ones without a catalog, and is English only when none is supported.
|
||||
#[test]
|
||||
fn browser_language_list_is_followed_in_order() {
|
||||
assert_eq!(first_supported_tag(["it-IT", "en-US"]), Lang::from_code("it"));
|
||||
assert_eq!(first_supported_tag(["xx-YY", "ja", "fr-FR"]), Some(JA()));
|
||||
assert_eq!(first_supported_tag(["zh-TW"]), Lang::from_code("zh-hant"));
|
||||
assert_eq!(first_supported_tag(["en-GB", "fr-FR"]), Some(Lang::EN));
|
||||
assert_eq!(first_supported_tag([" pt-PT "]), Lang::from_code("pt-br"));
|
||||
assert_eq!(first_supported_tag(["", "xx"]), None);
|
||||
assert_eq!(first_supported_tag(Vec::<String>::new()), None);
|
||||
let long = std::iter::repeat_n("xx", 10_000).chain(["fr"]);
|
||||
assert_eq!(first_supported_tag(long), None, "only the first tags are read");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windows_display_language_resolves_chinese_scripts() {
|
||||
for tag in ["zh-CN", "zh-SG", "zh-Hans", "zh-Hans-CN"] {
|
||||
|
||||
Reference in New Issue
Block a user