Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 this.EXPORTED_SYMBOLS = ["StringBundle"];
7 const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
9 /**
10 * A string bundle.
11 *
12 * This object presents two APIs: a deprecated one that is equivalent to the API
13 * for the stringbundle XBL binding, to make it easy to switch from that binding
14 * to this module, and a new one that is simpler and easier to use.
15 *
16 * The benefit of this module over the XBL binding is that it can also be used
17 * in JavaScript modules and components, not only in chrome JS.
18 *
19 * To use this module, import it, create a new instance of StringBundle,
20 * and then use the instance's |get| and |getAll| methods to retrieve strings
21 * (you can get both plain and formatted strings with |get|):
22 *
23 * let strings =
24 * new StringBundle("chrome://example/locale/strings.properties");
25 * let foo = strings.get("foo");
26 * let barFormatted = strings.get("bar", [arg1, arg2]);
27 * for each (let string in strings.getAll())
28 * dump (string.key + " = " + string.value + "\n");
29 *
30 * @param url {String}
31 * the URL of the string bundle
32 */
33 this.StringBundle = function StringBundle(url) {
34 this.url = url;
35 }
37 StringBundle.prototype = {
38 /**
39 * the locale associated with the application
40 * @type nsILocale
41 * @private
42 */
43 get _appLocale() {
44 try {
45 return Cc["@mozilla.org/intl/nslocaleservice;1"].
46 getService(Ci.nsILocaleService).
47 getApplicationLocale();
48 }
49 catch(ex) {
50 return null;
51 }
52 },
54 /**
55 * the wrapped nsIStringBundle
56 * @type nsIStringBundle
57 * @private
58 */
59 get _stringBundle() {
60 let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"].
61 getService(Ci.nsIStringBundleService).
62 createBundle(this.url, this._appLocale);
63 this.__defineGetter__("_stringBundle", function() stringBundle);
64 return this._stringBundle;
65 },
68 // the new API
70 /**
71 * the URL of the string bundle
72 * @type String
73 */
74 _url: null,
75 get url() {
76 return this._url;
77 },
78 set url(newVal) {
79 this._url = newVal;
80 delete this._stringBundle;
81 },
83 /**
84 * Get a string from the bundle.
85 *
86 * @param key {String}
87 * the identifier of the string to get
88 * @param args {array} [optional]
89 * an array of arguments that replace occurrences of %S in the string
90 *
91 * @returns {String} the value of the string
92 */
93 get: function(key, args) {
94 if (args)
95 return this.stringBundle.formatStringFromName(key, args, args.length);
96 else
97 return this.stringBundle.GetStringFromName(key);
98 },
100 /**
101 * Get all the strings in the bundle.
102 *
103 * @returns {Array}
104 * an array of objects with key and value properties
105 */
106 getAll: function() {
107 let strings = [];
109 // FIXME: for performance, return an enumerable array that wraps the string
110 // bundle's nsISimpleEnumerator (does JavaScript already support this?).
112 let enumerator = this.stringBundle.getSimpleEnumeration();
114 while (enumerator.hasMoreElements()) {
115 // We could simply return the nsIPropertyElement objects, but I think
116 // it's better to return standard JS objects that behave as consumers
117 // expect JS objects to behave (f.e. you can modify them dynamically).
118 let string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
119 strings.push({ key: string.key, value: string.value });
120 }
122 return strings;
123 },
126 // the deprecated XBL binding-compatible API
128 /**
129 * the URL of the string bundle
130 * @deprecated because its name doesn't make sense outside of an XBL binding
131 * @type String
132 */
133 get src() {
134 return this.url;
135 },
136 set src(newVal) {
137 this.url = newVal;
138 },
140 /**
141 * the locale associated with the application
142 * @deprecated because it has never been used outside the XBL binding itself,
143 * and consumers should obtain it directly from the locale service anyway.
144 * @type nsILocale
145 */
146 get appLocale() {
147 return this._appLocale;
148 },
150 /**
151 * the wrapped nsIStringBundle
152 * @deprecated because this module should provide all necessary functionality
153 * @type nsIStringBundle
154 *
155 * If you do ever need to use this, let the authors of this module know why
156 * so they can surface functionality for your use case in the module itself
157 * and you don't have to access this underlying XPCOM component.
158 */
159 get stringBundle() {
160 return this._stringBundle;
161 },
163 /**
164 * Get a string from the bundle.
165 * @deprecated use |get| instead
166 *
167 * @param key {String}
168 * the identifier of the string to get
169 *
170 * @returns {String}
171 * the value of the string
172 */
173 getString: function(key) {
174 return this.get(key);
175 },
177 /**
178 * Get a formatted string from the bundle.
179 * @deprecated use |get| instead
180 *
181 * @param key {string}
182 * the identifier of the string to get
183 * @param args {array}
184 * an array of arguments that replace occurrences of %S in the string
185 *
186 * @returns {String}
187 * the formatted value of the string
188 */
189 getFormattedString: function(key, args) {
190 return this.get(key, args);
191 },
193 /**
194 * Get an enumeration of the strings in the bundle.
195 * @deprecated use |getAll| instead
196 *
197 * @returns {nsISimpleEnumerator}
198 * a enumeration of the strings in the bundle
199 */
200 get strings() {
201 return this.stringBundle.getSimpleEnumeration();
202 }
203 }