~ubuntu-branches/ubuntu/trusty/python-babel/trusty

« back to all changes in this revision

Viewing changes to contrib/babel.js

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2013-10-28 10:11:31 UTC
  • mfrom: (4.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20131028101131-zwbmm8sc29iemmlr
Tags: 1.3-2ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - debian/rules: Run the testsuite during builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * Babel JavaScript Support
3
 
 *
4
 
 * Copyright (C) 2008 Edgewall Software
5
 
 * All rights reserved.
6
 
 *
7
 
 * This software is licensed as described in the file COPYING, which
8
 
 * you should have received as part of this distribution. The terms
9
 
 * are also available at http://babel.edgewall.org/wiki/License.
10
 
 *
11
 
 * This software consists of voluntary contributions made by many
12
 
 * individuals. For the exact contribution history, see the revision
13
 
 * history and logs, available at http://babel.edgewall.org/log/.
14
 
 */
15
 
 
16
 
/**
17
 
 * A simple module that provides a gettext like translation interface.
18
 
 * The catalog passed to load() must be a object conforming to this
19
 
 * interface::
20
 
 *
21
 
 *    {
22
 
 *      messages:     an object of {msgid: translations} items where
23
 
 *                    translations is an array of messages or a single
24
 
 *                    string if the message is not pluralizable.
25
 
 *      plural_expr:  the plural expression for the language.
26
 
 *      locale:       the identifier for this locale.
27
 
 *      domain:       the name of the domain.
28
 
 *    }
29
 
 *
30
 
 * Missing elements in the object are ignored.
31
 
 *
32
 
 * Typical usage::
33
 
 *
34
 
 *    var translations = babel.Translations.load(...).install();
35
 
 */
36
 
var babel = new function() {
37
 
 
38
 
  var defaultPluralExpr = function(n) { return n == 1 ? 0 : 1; };
39
 
  var formatRegex = /%?%(?:\(([^\)]+)\))?([disr])/g;
40
 
 
41
 
  /**
42
 
   * A translations object implementing the gettext interface
43
 
   */
44
 
  var Translations = this.Translations = function(locale, domain) {
45
 
    this.messages = {};
46
 
    this.locale = locale || 'unknown';
47
 
    this.domain = domain || 'messages';
48
 
    this.pluralexpr = defaultPluralExpr;
49
 
  };
50
 
 
51
 
  /**
52
 
   * Create a new translations object from the catalog and return it.
53
 
   * See the babel-module comment for more details.
54
 
   */
55
 
  Translations.load = function(catalog) {
56
 
    var rv = new Translations();
57
 
    rv.load(catalog);
58
 
    return rv;
59
 
  };
60
 
 
61
 
  Translations.prototype = {
62
 
    /**
63
 
     * translate a single string.
64
 
     */
65
 
    gettext: function(string) {
66
 
      var translated = this.messages[string];
67
 
      if (typeof translated == 'undefined')
68
 
        return string;
69
 
      return (typeof translated == 'string') ? translated : translated[0];
70
 
    },
71
 
 
72
 
    /**
73
 
     * translate a pluralizable string
74
 
     */
75
 
    ngettext: function(singular, plural, n) {
76
 
      var translated = this.messages[singular];
77
 
      if (typeof translated == 'undefined')
78
 
        return (n == 1) ? singular : plural;
79
 
      return translated[this.pluralexpr(n)];
80
 
    },
81
 
 
82
 
    /**
83
 
     * Install this translation document wide.  After this call, there are
84
 
     * three new methods on the window object: _, gettext and ngettext
85
 
     */
86
 
    install: function() {
87
 
      var self = this;
88
 
      window._ = window.gettext = function(string) {
89
 
        return self.gettext(string);
90
 
      };
91
 
      window.ngettext = function(singular, plural, n) {
92
 
        return self.ngettext(singular, plural, n);
93
 
      };
94
 
      return this;
95
 
    },
96
 
 
97
 
    /**
98
 
     * Works like Translations.load but updates the instance rather
99
 
     * then creating a new one.
100
 
     */
101
 
    load: function(catalog) {
102
 
      if (catalog.messages)
103
 
        this.update(catalog.messages)
104
 
      if (catalog.plural_expr)
105
 
        this.setPluralExpr(catalog.plural_expr);
106
 
      if (catalog.locale)
107
 
        this.locale = catalog.locale;
108
 
      if (catalog.domain)
109
 
        this.domain = catalog.domain;
110
 
      return this;
111
 
    },
112
 
 
113
 
    /**
114
 
     * Updates the translations with the object of messages.
115
 
     */
116
 
    update: function(mapping) {
117
 
      for (var key in mapping)
118
 
        if (mapping.hasOwnProperty(key))
119
 
          this.messages[key] = mapping[key];
120
 
      return this;
121
 
    },
122
 
 
123
 
    /**
124
 
     * Sets the plural expression
125
 
     */
126
 
    setPluralExpr: function(expr) {
127
 
      this.pluralexpr = new Function('n', 'return +(' + expr + ')');
128
 
      return this;
129
 
    }
130
 
  };
131
 
 
132
 
  /**
133
 
   * A python inspired string formatting function.  Supports named and
134
 
   * positional placeholders and "s", "d" and "i" as type characters
135
 
   * without any formatting specifications.
136
 
   *
137
 
   * Examples::
138
 
   *
139
 
   *    babel.format(_('Hello %s'), name)
140
 
   *    babel.format(_('Progress: %(percent)s%%'), {percent: 100})
141
 
   */ 
142
 
  this.format = function() {
143
 
    var arg, string = arguments[0], idx = 0;
144
 
    if (arguments.length == 1)
145
 
      return string;
146
 
    else if (arguments.length == 2 && typeof arguments[1] == 'object')
147
 
      arg = arguments[1];
148
 
    else {
149
 
      arg = [];
150
 
      for (var i = 1, n = arguments.length; i != n; ++i)
151
 
        arg[i - 1] = arguments[i];
152
 
    }
153
 
    return string.replace(formatRegex, function(all, name, type) {
154
 
      if (all[0] == all[1]) return all.substring(1);
155
 
      var value = arg[name || idx++];
156
 
      return (type == 'i' || type == 'd') ? +value : value; 
157
 
    });
158
 
  }
159
 
 
160
 
};