238 lines, 55 LOC, 38 covered (69%)
38 | 1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
|
3 | * |
|
4 | * The contents of this file are subject to the Mozilla Public License Version |
|
5 | * 1.1 (the "License"); you may not use this file except in compliance with |
|
6 | * the License. You may obtain a copy of the License at |
|
7 | * http://www.mozilla.org/MPL/ |
|
8 | * |
|
9 | * Software distributed under the License is distributed on an "AS IS" basis, |
|
10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
|
11 | * for the specific language governing rights and limitations under the |
|
12 | * License. |
|
13 | * |
|
14 | * The Original Code is String Bundle. |
|
15 | * |
|
16 | * The Initial Developer of the Original Code is Mozilla. |
|
17 | * Portions created by the Initial Developer are Copyright (C) 2008 |
|
18 | * the Initial Developer. All Rights Reserved. |
|
19 | * |
|
20 | * Contributor(s): |
|
21 | * Myk Melez <myk@mozilla.org> |
|
22 | * |
|
23 | * Alternatively, the contents of this file may be used under the terms of |
|
24 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
|
25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|
26 | * in which case the provisions of the GPL or the LGPL are applicable instead |
|
27 | * of those above. If you wish to allow use of your version of this file only |
|
28 | * under the terms of either the GPL or the LGPL, and not to allow others to |
|
29 | * use your version of this file under the terms of the MPL, indicate your |
|
30 | * decision by deleting the provisions above and replace them with the notice |
|
31 | * and other provisions required by the GPL or the LGPL. If you do not delete |
|
32 | * the provisions above, a recipient may use your version of this file under |
|
33 | * the terms of any one of the MPL, the GPL or the LGPL. |
|
34 | * |
|
35 | * ***** END LICENSE BLOCK ***** */ |
|
36 | ||
266 | 37 | let EXPORTED_SYMBOLS = ["StringBundle"]; |
38 | ||
152 | 39 | const Cc = Components.classes; |
152 | 40 | const Ci = Components.interfaces; |
152 | 41 | const Cr = Components.results; |
152 | 42 | const Cu = Components.utils; |
43 | ||
44 | /** |
|
45 | * A string bundle. |
|
46 | * |
|
47 | * This object presents two APIs: a deprecated one that is equivalent to the API |
|
48 | * for the stringbundle XBL binding, to make it easy to switch from that binding |
|
49 | * to this module, and a new one that is simpler and easier to use. |
|
50 | * |
|
51 | * The benefit of this module over the XBL binding is that it can also be used |
|
52 | * in JavaScript modules and components, not only in chrome JS. |
|
53 | * |
|
54 | * To use this module, import it, create a new instance of StringBundle, |
|
55 | * and then use the instance's |get| and |getAll| methods to retrieve strings |
|
56 | * (you can get both plain and formatted strings with |get|): |
|
57 | * |
|
58 | * let strings = |
|
59 | * new StringBundle("chrome://example/locale/strings.properties"); |
|
60 | * let foo = strings.get("foo"); |
|
61 | * let barFormatted = strings.get("bar", [arg1, arg2]); |
|
62 | * for each (let string in strings.getAll()) |
|
63 | * dump (string.key + " = " + string.value + "\n"); |
|
64 | * |
|
65 | * @param url {String} |
|
66 | * the URL of the string bundle |
|
67 | */ |
|
77 | 68 | function StringBundle(url) { |
4 | 69 | this.url = url; |
70 | } |
|
71 | ||
76 | 72 | StringBundle.prototype = { |
73 | /** |
|
74 | * the locale associated with the application |
|
75 | * @type nsILocale |
|
76 | * @private |
|
77 | */ |
|
77 | 78 | get _appLocale() { |
1 | 79 | try { |
3 | 80 | return Cc["@mozilla.org/intl/nslocaleservice;1"]. |
6 | 81 | getService(Ci.nsILocaleService). |
82 | getApplicationLocale(); |
|
83 | } |
|
84 | catch(ex) { |
|
85 | return null; |
|
86 | } |
|
87 | }, |
|
88 | ||
89 | /** |
|
90 | * the wrapped nsIStringBundle |
|
91 | * @type nsIStringBundle |
|
92 | * @private |
|
93 | */ |
|
77 | 94 | get _stringBundle() { |
3 | 95 | let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"]. |
4 | 96 | getService(Ci.nsIStringBundleService). |
4 | 97 | createBundle(this.url, this._appLocale); |
12 | 98 | this.__defineGetter__("_stringBundle", function() stringBundle); |
2 | 99 | return this._stringBundle; |
100 | }, |
|
101 | ||
102 | ||
103 | // the new API |
|
104 | ||
105 | /** |
|
106 | * the URL of the string bundle |
|
107 | * @type String |
|
108 | */ |
|
76 | 109 | _url: null, |
77 | 110 | get url() { |
2 | 111 | return this._url; |
112 | }, |
|
77 | 113 | set url(newVal) { |
3 | 114 | this._url = newVal; |
4 | 115 | delete this._stringBundle; |
116 | }, |
|
117 | ||
118 | /** |
|
119 | * Get a string from the bundle. |
|
120 | * |
|
121 | * @param key {String} |
|
122 | * the identifier of the string to get |
|
123 | * @param args {array} [optional] |
|
124 | * an array of arguments that replace occurrences of %S in the string |
|
125 | * |
|
126 | * @returns {String} the value of the string |
|
127 | */ |
|
78 | 128 | get: function(key, args) { |
4 | 129 | if (args) |
130 | return this.stringBundle.formatStringFromName(key, args, args.length); |
|
131 | else |
|
10 | 132 | return this.stringBundle.GetStringFromName(key); |
133 | }, |
|
134 | ||
135 | /** |
|
136 | * Get all the strings in the bundle. |
|
137 | * |
|
138 | * @returns {Array} |
|
139 | * an array of objects with key and value properties |
|
140 | */ |
|
76 | 141 | getAll: function() { |
142 | let strings = []; |
|
143 | ||
144 | // FIXME: for performance, return an enumerable array that wraps the string |
|
145 | // bundle's nsISimpleEnumerator (does JavaScript already support this?). |
|
146 | ||
147 | let enumerator = this.stringBundle.getSimpleEnumeration(); |
|
148 | ||
149 | while (enumerator.hasMoreElements()) { |
|
150 | // We could simply return the nsIPropertyElement objects, but I think |
|
151 | // it's better to return standard JS objects that behave as consumers |
|
152 | // expect JS objects to behave (f.e. you can modify them dynamically). |
|
153 | let string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement); |
|
154 | strings.push({ key: string.key, value: string.value }); |
|
155 | } |
|
156 | ||
157 | return strings; |
|
158 | }, |
|
159 | ||
160 | ||
161 | // the deprecated XBL binding-compatible API |
|
162 | ||
163 | /** |
|
164 | * the URL of the string bundle |
|
165 | * @deprecated because its name doesn't make sense outside of an XBL binding |
|
166 | * @type String |
|
167 | */ |
|
76 | 168 | get src() { |
169 | return this.url; |
|
170 | }, |
|
76 | 171 | set src(newVal) { |
172 | this.url = newVal; |
|
173 | }, |
|
174 | ||
175 | /** |
|
176 | * the locale associated with the application |
|
177 | * @deprecated because it has never been used outside the XBL binding itself, |
|
178 | * and consumers should obtain it directly from the locale service anyway. |
|
179 | * @type nsILocale |
|
180 | */ |
|
76 | 181 | get appLocale() { |
182 | return this._appLocale; |
|
183 | }, |
|
184 | ||
185 | /** |
|
186 | * the wrapped nsIStringBundle |
|
187 | * @deprecated because this module should provide all necessary functionality |
|
188 | * @type nsIStringBundle |
|
189 | * |
|
190 | * If you do ever need to use this, let the authors of this module know why |
|
191 | * so they can surface functionality for your use case in the module itself |
|
192 | * and you don't have to access this underlying XPCOM component. |
|
193 | */ |
|
78 | 194 | get stringBundle() { |
4 | 195 | return this._stringBundle; |
196 | }, |
|
197 | ||
198 | /** |
|
199 | * Get a string from the bundle. |
|
200 | * @deprecated use |get| instead |
|
201 | * |
|
202 | * @param key {String} |
|
203 | * the identifier of the string to get |
|
204 | * |
|
205 | * @returns {String} |
|
206 | * the value of the string |
|
207 | */ |
|
76 | 208 | getString: function(key) { |
209 | return this.get(key); |
|
210 | }, |
|
211 | ||
212 | /** |
|
213 | * Get a formatted string from the bundle. |
|
214 | * @deprecated use |get| instead |
|
215 | * |
|
216 | * @param key {string} |
|
217 | * the identifier of the string to get |
|
218 | * @param args {array} |
|
219 | * an array of arguments that replace occurrences of %S in the string |
|
220 | * |
|
221 | * @returns {String} |
|
222 | * the formatted value of the string |
|
223 | */ |
|
76 | 224 | getFormattedString: function(key, args) { |
225 | return this.get(key, args); |
|
226 | }, |
|
227 | ||
228 | /** |
|
229 | * Get an enumeration of the strings in the bundle. |
|
230 | * @deprecated use |getAll| instead |
|
231 | * |
|
232 | * @returns {nsISimpleEnumerator} |
|
233 | * a enumeration of the strings in the bundle |
|
234 | */ |
|
190 | 235 | get strings() { |
236 | return this.stringBundle.getSimpleEnumeration(); |
|
237 | } |
|
38 | 238 | } |