tr8n 3.2.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/Gemfile.lock +3 -1
  2. data/app/assets/javascripts/tr8n/tr8n-compiled.js +336 -0
  3. data/app/assets/stylesheets/tr8n/admin.css.scss +23 -0
  4. data/app/assets/stylesheets/tr8n/components.css.scss +23 -0
  5. data/app/assets/stylesheets/tr8n/keyboard_1_49.css +271 -0
  6. data/app/assets/stylesheets/tr8n/layout.css.scss +23 -0
  7. data/app/assets/stylesheets/tr8n/tr8n.css.scss +1 -1
  8. data/app/controllers/tr8n/api/v1/base_controller.rb +6 -0
  9. data/app/controllers/tr8n/api/v1/language_controller.rb +7 -10
  10. data/app/controllers/tr8n/api/v1/translation_controller.rb +0 -1
  11. data/app/javascript/compile.rb +37 -0
  12. data/app/javascript/compile.sh +1 -0
  13. data/app/javascript/compressors/google/COPYING +202 -0
  14. data/app/javascript/compressors/google/README +292 -0
  15. data/app/javascript/compressors/google/compiler.jar +0 -0
  16. data/app/javascript/config.yml +66 -0
  17. data/app/javascript/src/base.js +35 -0
  18. data/app/javascript/src/effects.js +67 -0
  19. data/app/javascript/src/ext/inflector.js +309 -0
  20. data/app/{assets/javascripts/tr8n → javascript/src/ext}/jsDraw2D.js +0 -0
  21. data/app/{assets/javascripts/tr8n → javascript/src/ext}/keyboard_1_36.js +0 -0
  22. data/app/{assets/javascripts/tr8n → javascript/src/ext}/keyboard_1_44.js +0 -0
  23. data/app/javascript/src/ext/keyboard_1_49.js +1796 -0
  24. data/app/javascript/src/ext/md5.js +209 -0
  25. data/app/{assets/javascripts/tr8n → javascript/src/ext}/shortcut.js +0 -0
  26. data/app/javascript/src/init.js +47 -0
  27. data/app/javascript/src/language.js +38 -0
  28. data/app/javascript/src/logger.js +203 -0
  29. data/app/{assets/javascripts/tr8n/tr8n_prototype_effects.js → javascript/src/prototype/effects.js} +5 -5
  30. data/app/javascript/src/proxy.js +254 -0
  31. data/app/javascript/src/rules/date_rule.js +37 -0
  32. data/app/javascript/src/rules/gender_list_rule.js +37 -0
  33. data/app/javascript/src/rules/gender_rule.js +87 -0
  34. data/app/javascript/src/rules/language_rule.js +55 -0
  35. data/app/javascript/src/rules/list_rule.js +37 -0
  36. data/app/javascript/src/rules/numeric_rule.js +95 -0
  37. data/app/javascript/src/tml/label.js +60 -0
  38. data/app/javascript/src/tml/token.js +107 -0
  39. data/app/javascript/src/tokens/data_token.js +45 -0
  40. data/app/javascript/src/tokens/decoration_token.js +82 -0
  41. data/app/javascript/src/tokens/token.js +121 -0
  42. data/app/javascript/src/tokens/transform_token.js +106 -0
  43. data/app/javascript/src/translation_key.js +183 -0
  44. data/app/javascript/src/ui/language_case_manager.js +155 -0
  45. data/app/javascript/src/ui/language_selector.js +126 -0
  46. data/app/javascript/src/ui/lightbox.js +72 -0
  47. data/app/javascript/src/ui/translator.js +257 -0
  48. data/app/javascript/src/utils.js +286 -0
  49. data/app/models/tr8n/language_case.rb +27 -16
  50. data/app/models/tr8n/language_case_rule.rb +24 -7
  51. data/app/models/tr8n/translation_key.rb +23 -21
  52. data/app/views/tr8n/common/_scripts.html.erb +8 -10
  53. data/app/views/tr8n/language_cases/_manager_header.html.erb +3 -3
  54. data/app/views/tr8n/language_cases/manager.html.erb +2 -2
  55. data/app/views/tr8n/translations/_original_phrase.html.erb +1 -1
  56. data/lib/tr8n/extensions/action_view_extension.rb +8 -1
  57. data/lib/tr8n/keyboard_mapping.rb +101 -0
  58. data/lib/tr8n/token.rb +1 -2
  59. data/lib/tr8n/version.rb +1 -1
  60. data/spec/models/tr8n/gender_rule_spec.rb +6 -6
  61. data/spec/models/tr8n/language_case_rule_spec.rb +219 -1
  62. data/spec/models/tr8n/language_case_spec.rb +51 -1
  63. data/spec/models/tr8n/translation_key_spec.rb +256 -0
  64. data/tr8n.gemspec +2 -1
  65. metadata +129 -47
  66. data/app/assets/javascripts/tr8n/tr8n.js +0 -905
  67. data/app/assets/javascripts/tr8n/tr8n_client_sdk.js +0 -1472
@@ -0,0 +1,66 @@
1
+ all:
2
+ src/ext/inflector.js
3
+ src/ext/md5.js
4
+ src/ext/shortcut.js
5
+ src/ext/keyboard_1_49.js
6
+ src/base.js
7
+ src/utils.js
8
+ src/effects.js
9
+ src/ui/language_case_manager.js
10
+ src/ui/language_selector.js
11
+ src/ui/lightbox.js
12
+ src/ui/translator.js
13
+ src/proxy.js
14
+ src/logger.js
15
+ src/language.js
16
+ src/translation_key.js
17
+ src/tokens/token.js
18
+ src/tokens/data_token.js
19
+ src/tokens/transform_token.js
20
+ src/tokens/decoration_token.js
21
+ src/rules/language_rule.js
22
+ src/rules/date_rule.js
23
+ src/rules/gender_rule.js
24
+ src/rules/numeric_rule.js
25
+ src/rules/list_rule.js
26
+ src/rules/gender_list_rule.js
27
+ src/tml/label.js
28
+ src/tml/token.js
29
+ src/init.js
30
+
31
+ ui:
32
+ src/ext/shortcut.js
33
+ src/ext/keyboard_1_49.js
34
+ src/base.js
35
+ src/utils.js
36
+ src/effects.js
37
+ src/ui/language_case_manager.js
38
+ src/ui/language_selector.js
39
+ src/ui/lightbox.js
40
+ src/ui/translator.js
41
+ src/init.js
42
+
43
+ proxy:
44
+ src/ext/inflector.js
45
+ src/ext/md5.js
46
+ src/base.js
47
+ src/utils.js
48
+ src/effects.js
49
+ src/proxy.js
50
+ src/logger.js
51
+ src/language.js
52
+ src/translation_key.js
53
+ src/tokens/token.js
54
+ src/tokens/data_token.js
55
+ src/tokens/transform_token.js
56
+ src/tokens/decoration_token.js
57
+ src/rules/language_rule.js
58
+ src/rules/date_rule.js
59
+ src/rules/gender_rule.js
60
+ src/rules/numeric_rule.js
61
+ src/rules/list_rule.js
62
+ src/rules/gender_list_rule.js
63
+ src/tml/label.js
64
+ src/tml/token.js
65
+
66
+
@@ -0,0 +1,35 @@
1
+ /****************************************************************************
2
+ Copyright (c) 2010-2012 Michael Berkovich, Ian McDaniel, tr8n.net
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ ****************************************************************************/
23
+
24
+ document.createElement('tr8n');
25
+ document.createElement('tml');
26
+
27
+ var Tr8n = Tr8n || {
28
+ element:function(element_id) {
29
+ if (typeof element_id == 'string') return document.getElementById(element_id);
30
+ return element_id;
31
+ },
32
+ value:function(element_id) {
33
+ return Tr8n.element(element_id).value;
34
+ }
35
+ };
@@ -0,0 +1,67 @@
1
+ /****************************************************************************
2
+ Copyright (c) 2010-2012 Michael Berkovich, Ian McDaniel, tr8n.net
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ ****************************************************************************/
23
+
24
+ Tr8n.Effects = {
25
+ toggle: function(element_id) {
26
+ if (Tr8n.element(element_id).style.display == "none")
27
+ Tr8n.element(element_id).show();
28
+ else
29
+ Tr8n.element(element_id).hide();
30
+ },
31
+ hide: function(element_id) {
32
+ Tr8n.element(element_id).style.display = "none";
33
+ },
34
+ show: function(element_id) {
35
+ var style = (Tr8n.element(element_id).tagName == "SPAN") ? "inline" : "block";
36
+ Tr8n.element(element_id).style.display = style;
37
+ },
38
+ blindUp: function(element_id) {
39
+ Tr8n.Effects.hide(element_id);
40
+ },
41
+ blindDown: function(element_id) {
42
+ Tr8n.Effects.show(element_id);
43
+ },
44
+ appear: function(element_id) {
45
+ Tr8n.Effects.show(element_id);
46
+ },
47
+ fade: function(element_id) {
48
+ Tr8n.Effects.hide(element_id);
49
+ },
50
+ submit: function(element_id) {
51
+ Tr8n.element(element_id).submit();
52
+ },
53
+ focus: function(element_id) {
54
+ Tr8n.element(element_id).focus();
55
+ },
56
+ scrollTo: function(element_id) {
57
+ var theElement = Tr8n.element(element_id);
58
+ var selectedPosX = 0;
59
+ var selectedPosY = 0;
60
+ while(theElement != null){
61
+ selectedPosX += theElement.offsetLeft;
62
+ selectedPosY += theElement.offsetTop;
63
+ theElement = theElement.offsetParent;
64
+ }
65
+ window.scrollTo(selectedPosX,selectedPosY);
66
+ }
67
+ }
@@ -0,0 +1,309 @@
1
+ /*
2
+ Copyright (c) 2010 Ryan Schuft (ryan.schuft@gmail.com)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ */
22
+
23
+ /*
24
+ This code is based in part on the work done in Ruby to support
25
+ infection as part of Ruby on Rails in the ActiveSupport's Inflector
26
+ and Inflections classes. It was initally ported to Javascript by
27
+ Ryan Schuft (ryan.schuft@gmail.com) in 2007.
28
+
29
+ The code is available at http://code.google.com/p/inflection-js/
30
+
31
+ The basic usage is:
32
+ 1. Include this script on your web page.
33
+ 2. Call functions on any String object in Javascript
34
+
35
+ Currently implemented functions:
36
+
37
+ String.pluralize(plural) == String
38
+ renders a singular English language noun into its plural form
39
+ normal results can be overridden by passing in an alternative
40
+
41
+ String.singularize(singular) == String
42
+ renders a plural English language noun into its singular form
43
+ normal results can be overridden by passing in an alterative
44
+ */
45
+
46
+ /*
47
+ This sets up a container for some constants in its own namespace
48
+ We use the window (if available) to enable dynamic loading of this script
49
+ Window won't necessarily exist for non-browsers.
50
+ */
51
+ if (window && !window.InflectionJS)
52
+ {
53
+ window.InflectionJS = null;
54
+ }
55
+
56
+ /*
57
+ This sets up some constants for later use
58
+ This should use the window namespace variable if available
59
+ */
60
+ InflectionJS =
61
+ {
62
+ /*
63
+ This is a list of nouns that use the same form for both singular and plural.
64
+ This list should remain entirely in lower case to correctly match Strings.
65
+ */
66
+ uncountable_words: [
67
+ 'equipment', 'information', 'rice', 'money', 'species', 'series',
68
+ 'fish', 'sheep', 'moose', 'deer', 'news'
69
+ ],
70
+
71
+ /*
72
+ These rules translate from the singular form of a noun to its plural form.
73
+ */
74
+ plural_rules: [
75
+ [new RegExp('(m)an$', 'gi'), '$1en'],
76
+ [new RegExp('(pe)rson$', 'gi'), '$1ople'],
77
+ [new RegExp('(child)$', 'gi'), '$1ren'],
78
+ [new RegExp('^(ox)$', 'gi'), '$1en'],
79
+ [new RegExp('(ax|test)is$', 'gi'), '$1es'],
80
+ [new RegExp('(octop|vir)us$', 'gi'), '$1i'],
81
+ [new RegExp('(alias|status)$', 'gi'), '$1es'],
82
+ [new RegExp('(bu)s$', 'gi'), '$1ses'],
83
+ [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'],
84
+ [new RegExp('([ti])um$', 'gi'), '$1a'],
85
+ [new RegExp('sis$', 'gi'), 'ses'],
86
+ [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'],
87
+ [new RegExp('(hive)$', 'gi'), '$1s'],
88
+ [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'],
89
+ [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'],
90
+ [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'],
91
+ [new RegExp('([m|l])ouse$', 'gi'), '$1ice'],
92
+ [new RegExp('(quiz)$', 'gi'), '$1zes'],
93
+ [new RegExp('s$', 'gi'), 's'],
94
+ [new RegExp('$', 'gi'), 's']
95
+ ],
96
+
97
+ /*
98
+ These rules translate from the plural form of a noun to its singular form.
99
+ */
100
+ singular_rules: [
101
+ [new RegExp('(m)en$', 'gi'), '$1an'],
102
+ [new RegExp('(pe)ople$', 'gi'), '$1rson'],
103
+ [new RegExp('(child)ren$', 'gi'), '$1'],
104
+ [new RegExp('([ti])a$', 'gi'), '$1um'],
105
+ [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'],
106
+ [new RegExp('(hive)s$', 'gi'), '$1'],
107
+ [new RegExp('(tive)s$', 'gi'), '$1'],
108
+ [new RegExp('(curve)s$', 'gi'), '$1'],
109
+ [new RegExp('([lr])ves$', 'gi'), '$1f'],
110
+ [new RegExp('([^fo])ves$', 'gi'), '$1fe'],
111
+ [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'],
112
+ [new RegExp('(s)eries$', 'gi'), '$1eries'],
113
+ [new RegExp('(m)ovies$', 'gi'), '$1ovie'],
114
+ [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'],
115
+ [new RegExp('([m|l])ice$', 'gi'), '$1ouse'],
116
+ [new RegExp('(bus)es$', 'gi'), '$1'],
117
+ [new RegExp('(o)es$', 'gi'), '$1'],
118
+ [new RegExp('(shoe)s$', 'gi'), '$1'],
119
+ [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'],
120
+ [new RegExp('(octop|vir)i$', 'gi'), '$1us'],
121
+ [new RegExp('(alias|status)es$', 'gi'), '$1'],
122
+ [new RegExp('^(ox)en', 'gi'), '$1'],
123
+ [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'],
124
+ [new RegExp('(matr)ices$', 'gi'), '$1ix'],
125
+ [new RegExp('(quiz)zes$', 'gi'), '$1'],
126
+ [new RegExp('s$', 'gi'), '']
127
+ ],
128
+
129
+ /*
130
+ This is a list of words that should not be capitalized for title case
131
+ */
132
+ non_titlecased_words: [
133
+ 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at',
134
+ 'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over',
135
+ 'with', 'for'
136
+ ],
137
+
138
+ /*
139
+ These are regular expressions used for converting between String formats
140
+ */
141
+ id_suffix: new RegExp('(_ids|_id)$', 'g'),
142
+ underbar: new RegExp('_', 'g'),
143
+ space_or_underbar: new RegExp('[\ _]', 'g'),
144
+ uppercase: new RegExp('([A-Z])', 'g'),
145
+ underbar_prefix: new RegExp('^_'),
146
+
147
+ /*
148
+ This is a helper method that applies rules based replacement to a String
149
+ Signature:
150
+ InflectionJS.apply_rules(str, rules, skip, override) == String
151
+ Arguments:
152
+ str - String - String to modify and return based on the passed rules
153
+ rules - Array: [RegExp, String] - Regexp to match paired with String to use for replacement
154
+ skip - Array: [String] - Strings to skip if they match
155
+ override - String (optional) - String to return as though this method succeeded (used to conform to APIs)
156
+ Returns:
157
+ String - passed String modified by passed rules
158
+ Examples:
159
+ InflectionJS.apply_rules("cows", InflectionJs.singular_rules) === 'cow'
160
+ */
161
+ apply_rules: function(str, rules, skip, override)
162
+ {
163
+ if (override)
164
+ {
165
+ str = override;
166
+ }
167
+ else
168
+ {
169
+ var ignore = (skip.indexOf(str.toLowerCase()) > -1);
170
+ if (!ignore)
171
+ {
172
+ for (var x = 0; x < rules.length; x++)
173
+ {
174
+ if (str.match(rules[x][0]))
175
+ {
176
+ str = str.replace(rules[x][0], rules[x][1]);
177
+ break;
178
+ }
179
+ }
180
+ }
181
+ }
182
+ return str;
183
+ }
184
+ };
185
+
186
+ /*
187
+ This lets us detect if an Array contains a given element
188
+ Signature:
189
+ Array.indexOf(item, fromIndex, compareFunc) == Integer
190
+ Arguments:
191
+ item - Object - object to locate in the Array
192
+ fromIndex - Integer (optional) - starts checking from this position in the Array
193
+ compareFunc - Function (optional) - function used to compare Array item vs passed item
194
+ Returns:
195
+ Integer - index position in the Array of the passed item
196
+ Examples:
197
+ ['hi','there'].indexOf("guys") === -1
198
+ ['hi','there'].indexOf("hi") === 0
199
+ */
200
+ if (!Array.prototype.indexOf)
201
+ {
202
+ Array.prototype.indexOf = function(item, fromIndex, compareFunc)
203
+ {
204
+ if (!fromIndex)
205
+ {
206
+ fromIndex = -1;
207
+ }
208
+ var index = -1;
209
+ for (var i = fromIndex; i < this.length; i++)
210
+ {
211
+ if (this[i] === item || compareFunc && compareFunc(this[i], item))
212
+ {
213
+ index = i;
214
+ break;
215
+ }
216
+ }
217
+ return index;
218
+ };
219
+ }
220
+
221
+ /*
222
+ You can override this list for all Strings or just one depending on if you
223
+ set the new values on prototype or on a given String instance.
224
+ */
225
+ if (!String.prototype._uncountable_words)
226
+ {
227
+ String.prototype._uncountable_words = InflectionJS.uncountable_words;
228
+ }
229
+
230
+ /*
231
+ You can override this list for all Strings or just one depending on if you
232
+ set the new values on prototype or on a given String instance.
233
+ */
234
+ if (!String.prototype._plural_rules)
235
+ {
236
+ String.prototype._plural_rules = InflectionJS.plural_rules;
237
+ }
238
+
239
+ /*
240
+ You can override this list for all Strings or just one depending on if you
241
+ set the new values on prototype or on a given String instance.
242
+ */
243
+ if (!String.prototype._singular_rules)
244
+ {
245
+ String.prototype._singular_rules = InflectionJS.singular_rules;
246
+ }
247
+
248
+ /*
249
+ You can override this list for all Strings or just one depending on if you
250
+ set the new values on prototype or on a given String instance.
251
+ */
252
+ if (!String.prototype._non_titlecased_words)
253
+ {
254
+ String.prototype._non_titlecased_words = InflectionJS.non_titlecased_words;
255
+ }
256
+
257
+ /*
258
+ This function adds plurilization support to every String object
259
+ Signature:
260
+ String.pluralize(plural) == String
261
+ Arguments:
262
+ plural - String (optional) - overrides normal output with said String
263
+ Returns:
264
+ String - singular English language nouns are returned in plural form
265
+ Examples:
266
+ "person".pluralize() == "people"
267
+ "octopus".pluralize() == "octopi"
268
+ "Hat".pluralize() == "Hats"
269
+ "person".pluralize("guys") == "guys"
270
+ */
271
+ if (!String.prototype.pluralize)
272
+ {
273
+ String.prototype.pluralize = function(plural)
274
+ {
275
+ return InflectionJS.apply_rules(
276
+ this,
277
+ this._plural_rules,
278
+ this._uncountable_words,
279
+ plural
280
+ );
281
+ };
282
+ }
283
+
284
+ /*
285
+ This function adds singularization support to every String object
286
+ Signature:
287
+ String.singularize(singular) == String
288
+ Arguments:
289
+ singular - String (optional) - overrides normal output with said String
290
+ Returns:
291
+ String - plural English language nouns are returned in singular form
292
+ Examples:
293
+ "people".singularize() == "person"
294
+ "octopi".singularize() == "octopus"
295
+ "Hats".singularize() == "Hat"
296
+ "guys".singularize("person") == "person"
297
+ */
298
+ if (!String.prototype.singularize)
299
+ {
300
+ String.prototype.singularize = function(singular)
301
+ {
302
+ return InflectionJS.apply_rules(
303
+ this,
304
+ this._singular_rules,
305
+ this._uncountable_words,
306
+ singular
307
+ );
308
+ };
309
+ }