Firefox の JS コンテキストのロケール指定方法
背景・目的
WebDriver 経由で geckodriver + Firefox を操作して JS の自動テストを行いたい。 その時、JS にロケール依存の処理が含まれていれば、テスト実行時にも Firefox の JS コンテキストのロケール指定を行いたい。
3 行まとめ
詳しい話
ECMAScript と国際化
ECMAScript における国際化のための仕様として ECMA-402 (ECMAScript Internationalization API Specification) というものがある。
この仕様により、例えば Date.prototype.toLocaleString
メソッドなどが定義される。 このメソッドの呼び出し時にロケールを明示的に指定しなかった場合、使用されるロケールは DefaultLocale
抽象操作によって決まる。 DefaultLocale
は実装依存である。
Firefox での DefaultLocale
(JS コンテキストのデフォルトロケール)
Firefox における ECMA-402 の DefaultLocale
の実装は、Firefox のロケールを返すようになっている模様。 ちゃんとしたドキュメントは見当たらなかったが、Bugzilla で教えてもらった。
JS context locale is tied to Firefox locale, not requested locale.
1475876 - intl.locale.requested doesn't affect to JS locale unless Language Pack is installed
Firefox のロケールの決まり方
で、Firefox のロケールの決まり方であるが、RFC 5656 をベースに、available locales と requested locales から決まるらしい。
Due to the imperfections in data matching, all operations on locales should always use a language negotiation algorithm to resolve the best available set of locales, based on the list of all available locales and an ordered list of requested locales.
Such algorithms may vary in sophistication and number of strategies. Mozilla’s solution is based on modified logic from RFC 5656.
Locale management — Mozilla Source Tree Docs 63.0a1 documentation
Available locales は、Firefox のパッケージに含まれているロケール (packaged locales) と、拡張機能としてインストールされた言語パックのロケール。
In Gecko, available locales come from the Packaged Locales and the installed language packs. Language packs are a variant of web extensions providing just localized resources for one or more languages.
Locale management — Mozilla Source Tree Docs 63.0a1 documentation
デスクトップ版の Firefox では、Packaged locales は普通は 1 つのみ。 Android 版の方は 100 ぐらいのロケールを含むらしい。
When the Gecko application is being packaged it bundles a selection of locale resources to be available within it. At the moment, for example, most Firefox for Android builds come with almost 100 locales packaged into it, while Desktop Firefox comes with usually just one packaged locale.
Locale management — Mozilla Source Tree Docs 63.0a1 documentation
Requested locales は次のとおりで、intl.locale.requested
pref に保持される。
After the sanitization, the value will be stored in a pref
intl.locale.requested
. The pref usually will store a comma separated list of valid BCP47 locale codes, but it can also have two special meanings:
- If the pref is not set at all, Gecko will use the default locale as the requested one.
- If the pref is set to an empty string, Gecko will look into OS app locales as the requested.
The former is the current default setting for Firefox Desktop, and the latter is the default setting for Firefox for Android.
Locale management — Mozilla Source Tree Docs 63.0a1 documentation
なので、基本的には使いたいロケールが Firefox のパッケージに含まれるロケールか言語パックとしてインストールされたロケールであれば、intl.locale.requested
にそのロケールを指定してやれば JS コンテキストのロケールがそのロケールになる。
en-US ロケールは特殊なロケール
日本語ロケールのデスクトップ版 Firefox で intl.locale.requested=en-US
とした場合、英語の言語パックをインストールしていないと en-US ロケールにはならなさそう (available locales に含まれてないはずなので) なのだけど、実際には JS コンテキストのロケールは en-US になっているような挙動になった。
なんでだろー、と思ったのだけど、どうやら last fallback locale という特殊な扱いで en-US が使われてるらしい。
Gecko also support a notion of last fallback locale, which is currently hardcoded to “en-US”, and is the very final locale to try in case nothing else (including the default locale) works.
Locale management — Mozilla Source Tree Docs 63.0a1 documentation
悩み
というわけで、複数のロケールを切り替えて JS のテストをしたい場合は、言語パックをインストールすることになるっぽい。 もしくはロケールごとに Firefox のバイナリを用意するか。
言語パックのインストールがコマンドライン上で簡単にできればいいのだけど、ちょっと調べた感じでは大変そうで、どうしたものかなーと思っている。 簡単にできる方法があれば教えてください!
参考
- Locale management — Mozilla Source Tree Docs 63.0a1 documentation : 詳しいことは全部ここに書かれている。
- 言語パックで Firefox のインターフェイスを他の言語にする | Firefox ヘルプ
- Firefoxの言語設定 - Hideki Saito Wiki Japanese : Firefox 59 から UI のロケールの指定方法が変わったとのこと。
Acknowledgement
この記事の内容は、株式会社 OND の仕事の一環として調べたものです。