| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Message/plural format library with locale support. This can have different | |
| 7 * implementations based on the mechanism for finding the localized versions | |
| 8 * of messages. This version expects them to be in a library named e.g. | |
| 9 * 'messages_en_US'. The prefix is set in the [initializeMessages] call, which | |
| 10 * must be made for a locale before any lookups can be done. | |
| 11 * | |
| 12 * | |
| 13 * _message example: | |
| 14 * '''I see ${Intl.plural(num_people, | |
| 15 * {'0': 'no one at all', | |
| 16 * '1': 'one other person', | |
| 17 * 'other': '$num_people other people'})} in $place.'''' | |
| 18 * | |
| 19 * Usage examples: | |
| 20 * today(date) => intl.message( | |
| 21 * "Today's date is $date", | |
| 22 * desc: 'Indicate the current date', | |
| 23 * examples: {'date' : 'June 8, 2012'}); | |
| 24 * print(today(new Date.now()); | |
| 25 * | |
| 26 * msg(num_people, place) => intl.message( | |
| 27 * '''I see ${Intl.plural(num_people, | |
| 28 * {'0': 'no one at all', | |
| 29 * '1': 'one other person', | |
| 30 * 'other': '$num_people other people'})} in $place.'''', | |
| 31 * desc: 'Description of how many people are seen as program start.', | |
| 32 * examples: {'num_people': 3, 'place': 'London'}); | |
| 33 * | |
| 34 * Calling `msg({'num_people': 2, 'place': 'Athens'});` would | |
| 35 * produce "I see 2 other people in Athens." as output. | |
| 36 * | |
| 37 * See tests/message_format_test.dart for more examples. | |
| 38 */ | |
| 39 //TODO(efortuna): documentation example involving the offset parameter? | |
| 40 | |
| 41 #library('message_lookup_local'); | |
| 42 | |
| 43 #import('intl.dart'); | |
| 44 #import('dart:mirrors'); | |
| 45 | |
| 46 /** | |
| 47 * Initialize the user messages for [localeName]. Note that this is an ASYNC | |
| 48 * operation. This must be called before attempting to use messages in | |
| 49 * [localeName]. | |
| 50 */ | |
| 51 Future initializeMessages(localeName, [String source = 'messages_']) { | |
| 52 initializeInternalMessageLookup( | |
| 53 () => new MessageLookupLocal(localeName, source)); | |
| 54 _initializeMessagesForLocale(localeName); | |
| 55 return new Future.immediate(null); | |
| 56 } | |
| 57 | |
| 58 void _initializeMessagesForLocale(String localeName) {} | |
| 59 | |
| 60 class MessageLookupLocal { | |
| 61 /** Prevent infinite recursion when looking up the message. */ | |
| 62 bool _lookupInProgress = false; | |
| 63 | |
| 64 /** The libraries we can look in for internationalization messages. */ | |
| 65 Map<String, LibraryMirror> _libraries; | |
| 66 | |
| 67 /** The prefix used to find libraries that contain localized messages. | |
| 68 * So, if this is 'messages_' we would look for messages for the locale | |
| 69 * 'pt_BR' in a library named 'messages_pt_BR'. | |
| 70 */ | |
| 71 String _sourcePrefix; | |
| 72 | |
| 73 /** | |
| 74 * Constructor. The [localeName] is of the form 'en' or 'en_US'. | |
| 75 *The [source] parameter defines the prefix that is used to find | |
| 76 * libraries that contain localized messages. So with the default value of | |
| 77 * 'messages_', we would look for messages for the locale 'pt_BR' in a library | |
| 78 * named 'messages_pt_BR'. | |
| 79 */ | |
| 80 MessageLookupLocal(String localeName, this._sourcePrefix) { | |
| 81 _libraries = currentMirrorSystem().libraries; | |
| 82 } | |
| 83 | |
| 84 /** | |
| 85 * Return the localized version of a message. We are passed the original | |
| 86 * version of the message, which consists of a | |
| 87 * [message_str] that will be translated, and which may be interpolated | |
| 88 * based on one or more variables, a [desc] providing a description of usage | |
| 89 * for the [message_str], and a map of [examples] for each data element to be | |
| 90 * substituted into the message. | |
| 91 * | |
| 92 * For example, if message="Hello, $name", then | |
| 93 * examples = {'name': 'Sparky'}. If not using the user's default locale, or | |
| 94 * if the locale is not easily detectable, explicitly pass [locale]. | |
| 95 * | |
| 96 * The values of [desc] and [examples] are not used at run-time but are only | |
| 97 * made available to the translators, so they MUST be simple Strings available | |
| 98 * at compile time: no String interpolation or concatenation. | |
| 99 * The expected usage of this is inside a function that takes as parameters | |
| 100 * the variables used in the interpolated string. | |
| 101 * | |
| 102 * Ultimately, the information about the enclosing function and its arguments | |
| 103 * will be extracted automatically but for the time being it must be passed | |
| 104 * explicitly in the [name] and [args] arguments. | |
| 105 */ | |
| 106 String lookupMessage(String message_str, [final String desc='', | |
| 107 final Map examples=const {}, String locale, | |
| 108 String name, List<String> args]) { | |
| 109 if (name == null) return message_str; | |
| 110 // The translations also make use of Intl.message, so we need to not | |
| 111 // recurse and just stop when we find the first substitution. | |
| 112 if (_lookupInProgress) return message_str; | |
| 113 _lookupInProgress = true; | |
| 114 var result; | |
| 115 try { | |
| 116 // TODO(alanknight): Look up alternate forms, e.g. en for en_US | |
| 117 var actualLocale = (locale == null) ? Intl.getCurrentLocale() : locale; | |
| 118 LibraryMirror messagesForThisLocale = | |
| 119 _libraries['$_sourcePrefix$actualLocale']; | |
| 120 if (messagesForThisLocale == null) return message_str; | |
| 121 MethodMirror localized = messagesForThisLocale.functions[name]; | |
| 122 if (localized == null) return message_str; | |
| 123 result = messagesForThisLocale.invoke(localized.simpleName, args); | |
| 124 } | |
| 125 finally { | |
| 126 _lookupInProgress = false; | |
| 127 } | |
| 128 return result.value.reflectee; | |
| 129 } | |
| 130 } | |
| OLD | NEW |