From 1a0c7edebacc76a70e57dfd494e24420fa77b56b Mon Sep 17 00:00:00 2001 From: Luca Matei Pintilie Date: Tue, 18 Oct 2022 15:33:35 +0200 Subject: [PATCH] feat: introduce navigator.language (#12322) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Link to the spec: https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-language-dev Co-authored-by: Bartek IwaƄczuk --- cli/dts/lib.deno.window.d.ts | 2 + cli/dts/lib.deno.worker.d.ts | 2 + cli/standalone.rs | 1 + cli/tests/integration/run_tests.rs | 53 +++++++++++++++++++++++ cli/tests/testdata/navigator_language.ts | 1 + cli/tests/testdata/navigator_languages.ts | 1 + cli/worker.rs | 2 + runtime/examples/hello_runtime.rs | 1 + runtime/js/99_main.js | 36 ++++++++++++++- runtime/worker.rs | 1 + runtime/worker_bootstrap.rs | 3 ++ 11 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 cli/tests/testdata/navigator_language.ts create mode 100644 cli/tests/testdata/navigator_languages.ts diff --git a/cli/dts/lib.deno.window.d.ts b/cli/dts/lib.deno.window.d.ts index 77204fcbd6..4ce288a4d1 100644 --- a/cli/dts/lib.deno.window.d.ts +++ b/cli/dts/lib.deno.window.d.ts @@ -97,6 +97,8 @@ declare class Navigator { readonly gpu: GPU; readonly hardwareConcurrency: number; readonly userAgent: string; + readonly language: string; + readonly languages: string[]; } /** @category Web APIs */ diff --git a/cli/dts/lib.deno.worker.d.ts b/cli/dts/lib.deno.worker.d.ts index 10a7718076..d274d4c05f 100644 --- a/cli/dts/lib.deno.worker.d.ts +++ b/cli/dts/lib.deno.worker.d.ts @@ -61,6 +61,8 @@ declare class WorkerNavigator { readonly gpu: GPU; readonly hardwareConcurrency: number; readonly userAgent: string; + readonly language: string; + readonly languages: string[]; } /** @category Web APIs */ diff --git a/cli/standalone.rs b/cli/standalone.rs index 0c454ce776..528c55f1c3 100644 --- a/cli/standalone.rs +++ b/cli/standalone.rs @@ -276,6 +276,7 @@ pub async fn run( .unwrap_or(1), debug_flag: metadata.log_level.map_or(false, |l| l == Level::Debug), enable_testing_features: false, + locale: deno_core::v8::icu::get_language_tag(), location: metadata.location, no_color: !colors::use_color(), is_tty: colors::is_tty(), diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index 004acb4696..156940185b 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -2377,6 +2377,59 @@ itest!(eval_context_throw_dom_exception { output: "run/eval_context_throw_dom_exception.js.out", }); +#[test] +#[cfg(unix)] +fn navigator_language_unix() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_language.ts", + None, + Some(vec![("LC_ALL".to_owned(), "pl_PL".to_owned())]), + false, + ); + assert_eq!(res, "pl-PL\n") +} + +#[test] +fn navigator_language() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_language.ts", + None, + None, + false, + ); + assert!(!res.is_empty()) +} + +#[test] +#[cfg(unix)] +fn navigator_languages_unix() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_languages.ts", + None, + Some(vec![ + ("LC_ALL".to_owned(), "pl_PL".to_owned()), + ("NO_COLOR".to_owned(), "1".to_owned()), + ]), + false, + ); + assert_eq!(res, "[ \"pl-PL\" ]\n") +} + +#[test] +fn navigator_languages() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_languages.ts", + None, + None, + false, + ); + assert!(!res.is_empty()) +} + /// Regression test for https://github.com/denoland/deno/issues/12740. #[test] fn issue12740() { diff --git a/cli/tests/testdata/navigator_language.ts b/cli/tests/testdata/navigator_language.ts new file mode 100644 index 0000000000..1cdbc2fe67 --- /dev/null +++ b/cli/tests/testdata/navigator_language.ts @@ -0,0 +1 @@ +console.log(navigator.language); diff --git a/cli/tests/testdata/navigator_languages.ts b/cli/tests/testdata/navigator_languages.ts new file mode 100644 index 0000000000..41dece9505 --- /dev/null +++ b/cli/tests/testdata/navigator_languages.ts @@ -0,0 +1 @@ +console.log(navigator.languages); diff --git a/cli/worker.rs b/cli/worker.rs index 581d4f90f0..10fe5b36f9 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -418,6 +418,7 @@ pub async fn create_main_worker( .log_level() .map_or(false, |l| l == log::Level::Debug), enable_testing_features: ps.options.enable_testing_features(), + locale: deno_core::v8::icu::get_language_tag(), location: ps.options.location_flag().map(ToOwned::to_owned), no_color: !colors::use_color(), is_tty: colors::is_tty(), @@ -534,6 +535,7 @@ fn create_web_worker_callback( .log_level() .map_or(false, |l| l == log::Level::Debug), enable_testing_features: ps.options.enable_testing_features(), + locale: deno_core::v8::icu::get_language_tag(), location: Some(args.main_module.clone()), no_color: !colors::use_color(), is_tty: colors::is_tty(), diff --git a/runtime/examples/hello_runtime.rs b/runtime/examples/hello_runtime.rs index b4a8d8201e..1f36107891 100644 --- a/runtime/examples/hello_runtime.rs +++ b/runtime/examples/hello_runtime.rs @@ -32,6 +32,7 @@ async fn main() -> Result<(), AnyError> { cpu_count: 1, debug_flag: false, enable_testing_features: false, + locale: deno_core::v8::icu::get_language_tag(), location: None, no_color: false, is_tty: false, diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 0a65cadee2..a123fc24f7 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -335,7 +335,7 @@ delete Intl.v8BreakIterator; const navigator = webidl.createBranded(Navigator); - let numCpus, userAgent; + let numCpus, userAgent, language; ObjectDefineProperties(Navigator.prototype, { gpu: { @@ -362,6 +362,22 @@ delete Intl.v8BreakIterator; return userAgent; }, }, + language: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, NavigatorPrototype); + return language; + }, + }, + languages: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, NavigatorPrototype); + return [language]; + }, + }, }); const NavigatorPrototype = Navigator.prototype; @@ -393,6 +409,22 @@ delete Intl.v8BreakIterator; webidl.assertBranded(this, WorkerNavigatorPrototype); return numCpus; }, + language: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, WorkerNavigatorPrototype); + return language; + }, + }, + languages: { + configurable: true, + enumerable: true, + get() { + webidl.assertBranded(this, WorkerNavigatorPrototype); + return [language]; + }, + }, }, }); const WorkerNavigatorPrototype = WorkerNavigator.prototype; @@ -705,6 +737,7 @@ delete Intl.v8BreakIterator; numCpus = runtimeOptions.cpuCount; userAgent = runtimeOptions.userAgent; + language = runtimeOptions.locale; const internalSymbol = Symbol("Deno.internal"); @@ -793,6 +826,7 @@ delete Intl.v8BreakIterator; location.setLocationHref(runtimeOptions.location); numCpus = runtimeOptions.cpuCount; + language = runtimeOptions.locale; globalThis.pollForMessages = pollForMessages; diff --git a/runtime/worker.rs b/runtime/worker.rs index 36833da329..61cdfb94e7 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -549,6 +549,7 @@ mod tests { cpu_count: 1, debug_flag: false, enable_testing_features: false, + locale: deno_core::v8::icu::get_language_tag(), location: None, no_color: true, is_tty: false, diff --git a/runtime/worker_bootstrap.rs b/runtime/worker_bootstrap.rs index 8af78c21a5..07b093e448 100644 --- a/runtime/worker_bootstrap.rs +++ b/runtime/worker_bootstrap.rs @@ -16,6 +16,7 @@ pub struct BootstrapOptions { pub cpu_count: usize, pub debug_flag: bool, pub enable_testing_features: bool, + pub locale: String, pub location: Option, /// Sets `Deno.noColor` in JS runtime. pub no_color: bool, @@ -47,6 +48,7 @@ impl Default for BootstrapOptions { enable_testing_features: Default::default(), debug_flag: Default::default(), ts_version: Default::default(), + locale: "en-EN".to_string(), location: Default::default(), unstable: Default::default(), inspect: Default::default(), @@ -63,6 +65,7 @@ impl BootstrapOptions { "cpuCount": self.cpu_count, "debugFlag": self.debug_flag, "denoVersion": self.runtime_version, + "locale": self.locale, "location": self.location, "noColor": self.no_color, "isTty": self.is_tty,