ext/StringBundle.js

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
}