| Index: pkg/intl/message_lookup_local.dart
|
| ===================================================================
|
| --- pkg/intl/message_lookup_local.dart (revision 12066)
|
| +++ pkg/intl/message_lookup_local.dart (working copy)
|
| @@ -3,7 +3,11 @@
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| /**
|
| - * Message/plural format library with locale support.
|
| + * Message/plural format library with locale support. This can have different
|
| + * implementations based on the mechanism for finding the localized versions
|
| + * of messages. This version expects them to be in a library named e.g.
|
| + * 'messages_en_US'. The prefix is set in the [initializeMessages] call, which
|
| + * must be made for a locale before any lookups can be done.
|
| *
|
| *
|
| * _message example:
|
| @@ -34,43 +38,93 @@
|
| */
|
| //TODO(efortuna): documentation example involving the offset parameter?
|
|
|
| -class IntlMessage {
|
| +#library('message_lookup_local');
|
|
|
| - /** String describing the use case for this message. */
|
| - String _messageDescription;
|
| +#import('intl.dart');
|
| +#import('dart:mirrors');
|
|
|
| - /**
|
| - * String that contains the message to be displayed. It may contain
|
| - * placeholders in the form of string interpolated items (ie 'hello$foo') that
|
| - * will be substituted in to complete the message.
|
| - * See tests/message_format_test.dart for more examples.
|
| +/**
|
| + * Initialize the user messages for [localeName]. Note that this is an ASYNC
|
| + * operation. This must be called before attempting to use messages in
|
| + * [localeName].
|
| + */
|
| +Future initializeMessages(localeName, [String source = 'messages_']) {
|
| + initializeInternalMessageLookup(
|
| + () => new MessageLookupLocal(localeName, source));
|
| + _initializeMessagesForLocale(localeName);
|
| + return new Future.immediate(null);
|
| +}
|
| +
|
| +void _initializeMessagesForLocale(String localeName) {}
|
| +
|
| +class MessageLookupLocal {
|
| + /** Prevent infinite recursion when looking up the message. */
|
| + bool _lookupInProgress = false;
|
| +
|
| + /** The libraries we can look in for internationalization messages. */
|
| + Map<String, LibraryMirror> _libraries;
|
| +
|
| + /** The prefix used to find libraries that contain localized messages.
|
| + * So, if this is 'messages_' we would look for messages for the locale
|
| + * 'pt_BR' in a library named 'messages_pt_BR'.
|
| */
|
| - String _message;
|
| + String _sourcePrefix;
|
|
|
| /**
|
| - * String indicating the locale code with which the message is to be
|
| - * formatted (such as en-CA).
|
| + * Constructor. The [localeName] is of the form 'en' or 'en_US'.
|
| + *The [source] parameter defines the prefix that is used to find
|
| + * libraries that contain localized messages. So with the default value of
|
| + * 'messages_', we would look for messages for the locale 'pt_BR' in a library
|
| + * named 'messages_pt_BR'.
|
| */
|
| - String _languageCode;
|
| + MessageLookupLocal(String localeName, this._sourcePrefix) {
|
| + _libraries = currentMirrorSystem().libraries;
|
| + }
|
|
|
| - /** Examples of the placeholders used in the message string. */
|
| - Map _messageExamples;
|
| -
|
| /**
|
| - * Accepts a String [_message] that contains the message (that
|
| - * will be internationalized). A String [_messageDescription] describes the
|
| - * use case for this string in the program, and [examples] provides a map of
|
| - * examples for the items (if any) to be subsituted into [_message].
|
| - * It also optionally accepts a [_languageCode] to specify the particular
|
| - * language to return content in (necessary if the Dart code is not running in
|
| - * a browser). The values of [desc] and [examples] *must* be
|
| - * simple Strings available at compile time: no String interpolation or
|
| - * concatenation.
|
| + * Return the localized version of a message. We are passed the original
|
| + * version of the message, which consists of a
|
| + * [message_str] that will be translated, and which may be interpolated
|
| + * based on one or more variables, a [desc] providing a description of usage
|
| + * for the [message_str], and a map of [examples] for each data element to be
|
| + * substituted into the message.
|
| + *
|
| + * For example, if message="Hello, $name", then
|
| + * examples = {'name': 'Sparky'}. If not using the user's default locale, or
|
| + * if the locale is not easily detectable, explicitly pass [locale].
|
| + *
|
| + * The values of [desc] and [examples] are not used at run-time but are only
|
| + * made available to the translators, so they MUST be simple Strings available
|
| + * at compile time: no String interpolation or concatenation.
|
| + * The expected usage of this is inside a function that takes as parameters
|
| + * the variables used in the interpolated string.
|
| + *
|
| + * Ultimately, the information about the enclosing function and its arguments
|
| + * will be extracted automatically but for the time being it must be passed
|
| + * explicitly in the [name] and [args] arguments.
|
| */
|
| - IntlMessage(this._message, [final String desc='', final Map examples=const {},
|
| - final String locale='']) {
|
| - this._messageDescription = desc;
|
| - this._messageExamples = examples;
|
| - this._languageCode = locale;
|
| + String lookupMessage(String message_str, [final String desc='',
|
| + final Map examples=const {}, String locale,
|
| + String name, List<String> args]) {
|
| + if (name == null) return message_str;
|
| + // The translations also make use of Intl.message, so we need to not
|
| + // recurse and just stop when we find the first substitution.
|
| + if (_lookupInProgress) return message_str;
|
| + _lookupInProgress = true;
|
| + var result;
|
| + try {
|
| + // TODO(alanknight): Look up alternate forms, e.g. en for en_US
|
| + var actualLocale = (locale == null) ? Intl.getCurrentLocale() : locale;
|
| + LibraryMirror messagesForThisLocale =
|
| + _libraries['$_sourcePrefix$actualLocale'];
|
| + if (messagesForThisLocale == null) return message_str;
|
| + MethodMirror localized = messagesForThisLocale.functions[name];
|
| + if (localized == null) return message_str;
|
| + result = messagesForThisLocale.invoke(localized.simpleName, args);
|
| + }
|
| + finally {
|
| + _lookupInProgress = false;
|
| + }
|
| + return result.value.reflectee;
|
| }
|
| -}
|
| +}
|
|
|