blob: fe70ccfbdbf9b5b60dd04f33efa73399050a9470 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
* This provides facilities for Internationalization that are only available
* when running standalone. You should import only one of this or
* intl_browser.dart. Right now the only thing provided here is finding
* the operating system locale.
library intl_standalone;
import "dart:async";
import "dart:io";
import "intl.dart";
// TODO(alanknight): The need to do this by forcing the user to specially
// import a particular library is a horrible hack, only done because there
// seems to be no graceful way to do this at all. Either mirror access on
// dart2js or the ability to do spawnUri in the browser would be promising
// as ways to get rid of this requirement.
* Find the system locale, accessed via the appropriate system APIs, and
* set it as the default for internationalization operations in
* the [Intl.systemLocale] variable. To find it, we
* check the "LANG" environment variable on *nix, use the "systeminfo"
* command on Windows, and on the Mac check the environment variable "LANG",
* and if it's not found, use "defaults read -g AppleLocale". This
* is not an ideal way of getting a single system locale, even if that
* concept really made sense, but it's a reasonable first approximation that's
* not too difficult to get. If it can't find the locale information, it will
* not modify [Intl.systemLocale] and the Future will complete with null.
Future<String> findSystemLocale() {
// On *nix systems we expect this is an environment variable, which is the
// easiest thing to check. On a Mac the environment variable may be present
// so always check it first. We have no mechanism for this right now on
// Windows, so it will just fail.
String baseLocale = _checkEnvironmentVariable();
if (baseLocale != null) return _setLocale(baseLocale);
if (Platform.operatingSystem == 'macos') {
return _getAppleDefaults();
// We can't find anything, don't set the system locale and return null.
return new Future.value();
* Regular expression to match the expected output of reading the defaults
* database for AppleLanguages on Mac systems.
* e.g. {
* en,
* "pt-PT",
* ...
RegExp _appleDefaultsRegex = new RegExp(r'((\w\w)_\w+)');
* Check to see if we have a "LANG" environment variable we can use and return
* it if found. Otherwise return null;
String _checkEnvironmentVariable() {
try {
return Platform.environment['LANG'];
} catch (e) {};
return null;
* Run the "defaults read -g AppleLocale" command and return the output in
* a future.
Future _getAppleDefaults() {
var p ='defaults', ['read', '-g', 'AppleLocale']);
var myResult = p.then((result) => _checkResult(result, _appleDefaultsRegex));
return myResult;
* Given [result], find its text and extract the locale from it using
* [regex], and set it as the system locale. If the process didn't run correctly
* then don't set the variable and return a future that completes with null.
Future<String> _checkResult(ProcessResult result, RegExp regex) {
if (result.exitCode != 0) return new Future.value();
var match = regex.firstMatch(result.stdout);
if (match == null) return new Future.value();
var locale =;
return new Future.value(locale);
* Set [Intl.systemLocale] to be the canonicalizedLocale of [aLocale].
Future<String> _setLocale(aLocale) {
Intl.systemLocale = Intl.canonicalizedLocale(aLocale);
return new Future.value(Intl.systemLocale);