joosy 1.2.0.alpha.73 → 1.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/Gruntfile.coffee +56 -18
  3. data/bower.json +1 -1
  4. data/build/joosy/form.js +1 -0
  5. data/build/joosy/resources.js +1 -0
  6. data/build/joosy.js +2 -2774
  7. data/package.json +5 -4
  8. data/source/joosy/application.coffee +9 -7
  9. data/source/joosy/{extensions/resources-form/form.coffee → form.coffee} +58 -51
  10. data/source/joosy/helpers/form.coffee +241 -0
  11. data/source/joosy/helpers/index.coffee +3 -0
  12. data/source/joosy/helpers/routes.coffee +3 -1
  13. data/source/joosy/helpers/view.coffee +9 -9
  14. data/source/joosy/joosy.coffee +3 -5
  15. data/source/joosy/module.coffee +9 -4
  16. data/source/joosy/modules/dom.coffee +33 -31
  17. data/source/joosy/modules/events.coffee +24 -20
  18. data/source/joosy/modules/filters.coffee +38 -35
  19. data/source/joosy/modules/page/title.coffee +3 -3
  20. data/source/joosy/modules/renderer.coffee +23 -18
  21. data/source/joosy/modules/resources/identity_map.coffee +45 -0
  22. data/source/joosy/modules/resources/model.coffee +146 -0
  23. data/source/joosy/modules/widgets_manager.coffee +8 -8
  24. data/source/joosy/resources/array.coffee +0 -5
  25. data/source/joosy/resources/hash.coffee +8 -13
  26. data/source/joosy/resources/index.coffee +2 -0
  27. data/source/joosy/{extensions/resources → resources}/rest.coffee +48 -19
  28. data/source/joosy/resources/scalar.coffee +8 -10
  29. data/source/joosy/router.coffee +13 -12
  30. data/source/joosy/templaters/jst.coffee +3 -2
  31. data/source/joosy/widget.coffee +17 -15
  32. data/source/joosy.coffee +2 -0
  33. data/source/vendor/es5-shim.js +1316 -0
  34. data/source/vendor/inflections.js +598 -0
  35. data/source/vendor/metamorph.js +457 -0
  36. data/spec/helpers/matchers.coffee +4 -4
  37. data/spec/joosy/core/application_spec.coffee +1 -1
  38. data/spec/joosy/core/helpers/view_spec.coffee +2 -2
  39. data/spec/joosy/core/joosy_spec.coffee +8 -4
  40. data/spec/joosy/core/modules/dom_spec.coffee +7 -7
  41. data/spec/joosy/core/modules/events_spec.coffee +2 -2
  42. data/spec/joosy/core/modules/filters_spec.coffee +7 -8
  43. data/spec/joosy/core/modules/module_spec.coffee +5 -5
  44. data/spec/joosy/core/router_spec.coffee +3 -3
  45. data/spec/joosy/core/widget_spec.coffee +6 -6
  46. data/spec/joosy/environments/amd_spec.coffee +4 -2
  47. data/spec/joosy/environments/global_spec.coffee +1 -1
  48. data/spec/joosy/{extensions/form → form}/form_spec.coffee +9 -16
  49. data/spec/joosy/{extensions/form → form}/helpers/forms_spec.coffee +5 -5
  50. data/spec/joosy/{core/resources → resources}/array_spec.coffee +2 -2
  51. data/spec/joosy/{core/resources → resources}/hash_spec.coffee +0 -8
  52. data/spec/joosy/{core/modules/resources → resources/modules}/cacher_spec.coffee +0 -0
  53. data/spec/joosy/resources/modules/identity_map_spec.coffee +47 -0
  54. data/spec/joosy/{extensions/resources/base_spec.coffee → resources/modules/model_spec.coffee} +28 -48
  55. data/spec/joosy/{extensions/resources → resources}/rest_spec.coffee +29 -22
  56. data/spec/joosy/{core/resources → resources}/scalar_spec.coffee +8 -8
  57. data/templates/application/application.coffee.tt +0 -2
  58. data/templates/environment/app/haml/index.haml +2 -2
  59. data/templates/environment/package.json +1 -1
  60. metadata +23 -19
  61. data/build/joosy/extensions/resources-form.js +0 -590
  62. data/build/joosy/extensions/resources.js +0 -561
  63. data/source/joosy/extensions/resources/base.coffee +0 -282
  64. data/source/joosy/extensions/resources/index.coffee +0 -1
  65. data/source/joosy/extensions/resources-form/helpers/form.coffee +0 -104
  66. data/source/joosy/extensions/resources-form/index.coffee +0 -1
  67. data/source/metamorph.coffee +0 -410
@@ -0,0 +1,598 @@
1
+ /*!
2
+ * inflection
3
+ * Copyright(c) 2011 Ben Lin <ben@dreamerslab.com>
4
+ * MIT Licensed
5
+ *
6
+ * @fileoverview
7
+ * A port of inflection-js to node.js module.
8
+ */
9
+
10
+ ( function ( root ){
11
+
12
+ /**
13
+ * @description This is a list of nouns that use the same form for both singular and plural.
14
+ * This list should remain entirely in lower case to correctly match Strings.
15
+ * @private
16
+ */
17
+ var uncountable_words = [
18
+ 'equipment', 'information', 'rice', 'money', 'species',
19
+ 'series', 'fish', 'sheep', 'moose', 'deer', 'news'
20
+ ];
21
+
22
+ /**
23
+ * @description These rules translate from the singular form of a noun to its plural form.
24
+ * @private
25
+ */
26
+ var plural_rules = [
27
+
28
+ // do not replace if its already a plural word
29
+ [ new RegExp( '(m)en$', 'gi' )],
30
+ [ new RegExp( '(pe)ople$', 'gi' )],
31
+ [ new RegExp( '(child)ren$', 'gi' )],
32
+ [ new RegExp( '([ti])a$', 'gi' )],
33
+ [ new RegExp( '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi' )],
34
+ [ new RegExp( '(hive)s$', 'gi' )],
35
+ [ new RegExp( '(tive)s$', 'gi' )],
36
+ [ new RegExp( '(curve)s$', 'gi' )],
37
+ [ new RegExp( '([lr])ves$', 'gi' )],
38
+ [ new RegExp( '([^fo])ves$', 'gi' )],
39
+ [ new RegExp( '([^aeiouy]|qu)ies$', 'gi' )],
40
+ [ new RegExp( '(s)eries$', 'gi' )],
41
+ [ new RegExp( '(m)ovies$', 'gi' )],
42
+ [ new RegExp( '(x|ch|ss|sh)es$', 'gi' )],
43
+ [ new RegExp( '([m|l])ice$', 'gi' )],
44
+ [ new RegExp( '(bus)es$', 'gi' )],
45
+ [ new RegExp( '(o)es$', 'gi' )],
46
+ [ new RegExp( '(shoe)s$', 'gi' )],
47
+ [ new RegExp( '(cris|ax|test)es$', 'gi' )],
48
+ [ new RegExp( '(octop|vir)i$', 'gi' )],
49
+ [ new RegExp( '(alias|status)es$', 'gi' )],
50
+ [ new RegExp( '^(ox)en', 'gi' )],
51
+ [ new RegExp( '(vert|ind)ices$', 'gi' )],
52
+ [ new RegExp( '(matr)ices$', 'gi' )],
53
+ [ new RegExp( '(quiz)zes$', 'gi' )],
54
+
55
+ // original rule
56
+ [ new RegExp( '(m)an$', 'gi' ), '$1en' ],
57
+ [ new RegExp( '(pe)rson$', 'gi' ), '$1ople' ],
58
+ [ new RegExp( '(child)$', 'gi' ), '$1ren' ],
59
+ [ new RegExp( '^(ox)$', 'gi' ), '$1en' ],
60
+ [ new RegExp( '(ax|test)is$', 'gi' ), '$1es' ],
61
+ [ new RegExp( '(octop|vir)us$', 'gi' ), '$1i' ],
62
+ [ new RegExp( '(alias|status)$', 'gi' ), '$1es' ],
63
+ [ new RegExp( '(bu)s$', 'gi' ), '$1ses' ],
64
+ [ new RegExp( '(buffal|tomat|potat)o$', 'gi' ), '$1oes' ],
65
+ [ new RegExp( '([ti])um$', 'gi' ), '$1a' ],
66
+ [ new RegExp( 'sis$', 'gi' ), 'ses' ],
67
+ [ new RegExp( '(?:([^f])fe|([lr])f)$', 'gi' ), '$1$2ves' ],
68
+ [ new RegExp( '(hive)$', 'gi' ), '$1s' ],
69
+ [ new RegExp( '([^aeiouy]|qu)y$', 'gi' ), '$1ies' ],
70
+ [ new RegExp( '(x|ch|ss|sh)$', 'gi' ), '$1es' ],
71
+ [ new RegExp( '(matr|vert|ind)ix|ex$', 'gi' ), '$1ices' ],
72
+ [ new RegExp( '([m|l])ouse$', 'gi' ), '$1ice' ],
73
+ [ new RegExp( '(quiz)$', 'gi' ), '$1zes' ],
74
+
75
+ [ new RegExp( 's$', 'gi' ), 's' ],
76
+ [ new RegExp( '$', 'gi' ), 's' ]
77
+ ];
78
+
79
+ /**
80
+ * @description These rules translate from the plural form of a noun to its singular form.
81
+ * @private
82
+ */
83
+ var singular_rules = [
84
+
85
+ // do not replace if its already a singular word
86
+ [ new RegExp( '(m)an$', 'gi' )],
87
+ [ new RegExp( '(pe)rson$', 'gi' )],
88
+ [ new RegExp( '(child)$', 'gi' )],
89
+ [ new RegExp( '^(ox)$', 'gi' )],
90
+ [ new RegExp( '(ax|test)is$', 'gi' )],
91
+ [ new RegExp( '(octop|vir)us$', 'gi' )],
92
+ [ new RegExp( '(alias|status)$', 'gi' )],
93
+ [ new RegExp( '(bu)s$', 'gi' )],
94
+ [ new RegExp( '(buffal|tomat|potat)o$', 'gi' )],
95
+ [ new RegExp( '([ti])um$', 'gi' )],
96
+ [ new RegExp( 'sis$', 'gi' )],
97
+ [ new RegExp( '(?:([^f])fe|([lr])f)$', 'gi' )],
98
+ [ new RegExp( '(hive)$', 'gi' )],
99
+ [ new RegExp( '([^aeiouy]|qu)y$', 'gi' )],
100
+ [ new RegExp( '(x|ch|ss|sh)$', 'gi' )],
101
+ [ new RegExp( '(matr|vert|ind)ix|ex$', 'gi' )],
102
+ [ new RegExp( '([m|l])ouse$', 'gi' )],
103
+ [ new RegExp( '(quiz)$', 'gi' )],
104
+
105
+ // original rule
106
+ [ new RegExp( '(m)en$', 'gi' ), '$1an' ],
107
+ [ new RegExp( '(pe)ople$', 'gi' ), '$1rson' ],
108
+ [ new RegExp( '(child)ren$', 'gi' ), '$1' ],
109
+ [ new RegExp( '([ti])a$', 'gi' ), '$1um' ],
110
+ [ new RegExp( '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi' ), '$1$2sis' ],
111
+ [ new RegExp( '(hive)s$', 'gi' ), '$1' ],
112
+ [ new RegExp( '(tive)s$', 'gi' ), '$1' ],
113
+ [ new RegExp( '(curve)s$', 'gi' ), '$1' ],
114
+ [ new RegExp( '([lr])ves$', 'gi' ), '$1f' ],
115
+ [ new RegExp( '([^fo])ves$', 'gi' ), '$1fe' ],
116
+ [ new RegExp( '([^aeiouy]|qu)ies$', 'gi' ), '$1y' ],
117
+ [ new RegExp( '(s)eries$', 'gi' ), '$1eries' ],
118
+ [ new RegExp( '(m)ovies$', 'gi' ), '$1ovie' ],
119
+ [ new RegExp( '(x|ch|ss|sh)es$', 'gi' ), '$1' ],
120
+ [ new RegExp( '([m|l])ice$', 'gi' ), '$1ouse' ],
121
+ [ new RegExp( '(bus)es$', 'gi' ), '$1' ],
122
+ [ new RegExp( '(o)es$', 'gi' ), '$1' ],
123
+ [ new RegExp( '(shoe)s$', 'gi' ), '$1' ],
124
+ [ new RegExp( '(cris|ax|test)es$', 'gi' ), '$1is' ],
125
+ [ new RegExp( '(octop|vir)i$', 'gi' ), '$1us' ],
126
+ [ new RegExp( '(alias|status)es$', 'gi' ), '$1' ],
127
+ [ new RegExp( '^(ox)en', 'gi' ), '$1' ],
128
+ [ new RegExp( '(vert|ind)ices$', 'gi' ), '$1ex' ],
129
+ [ new RegExp( '(matr)ices$', 'gi' ), '$1ix' ],
130
+ [ new RegExp( '(quiz)zes$', 'gi' ), '$1' ],
131
+ [ new RegExp( 'ss$', 'gi' ), 'ss' ],
132
+ [ new RegExp( 's$', 'gi' ), '' ]
133
+ ];
134
+
135
+ /**
136
+ * @description This is a list of words that should not be capitalized for title case.
137
+ * @private
138
+ */
139
+ var non_titlecased_words = [
140
+ 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at','by',
141
+ 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over', 'with', 'for'
142
+ ];
143
+
144
+ /**
145
+ * @description These are regular expressions used for converting between String formats.
146
+ * @private
147
+ */
148
+ var id_suffix = new RegExp( '(_ids|_id)$', 'g' );
149
+ var underbar = new RegExp( '_', 'g' );
150
+ var space_or_underbar = new RegExp( '[\ _]', 'g' );
151
+ var uppercase = new RegExp( '([A-Z])', 'g' );
152
+ var underbar_prefix = new RegExp( '^_' );
153
+
154
+ var inflector = {
155
+
156
+ /**
157
+ * A helper method that applies rules based replacement to a String.
158
+ * @private
159
+ * @function
160
+ * @param {String} str String to modify and return based on the passed rules.
161
+ * @param {Array: [RegExp, String]} rules Regexp to match paired with String to use for replacement
162
+ * @param {Array: [String]} skip Strings to skip if they match
163
+ * @param {String} override String to return as though this method succeeded (used to conform to APIs)
164
+ * @returns {String} Return passed String modified by passed rules.
165
+ * @example
166
+ *
167
+ * this._apply_rules( 'cows', singular_rules ); // === 'cow'
168
+ */
169
+ _apply_rules : function( str, rules, skip, override ){
170
+ if( override ){
171
+ str = override;
172
+ }else{
173
+ var ignore = ( inflector.indexOf( skip, str.toLowerCase()) > -1 );
174
+
175
+ if( !ignore ){
176
+ var i = 0;
177
+ var j = rules.length;
178
+
179
+ for( ; i < j; i++ ){
180
+ if( str.match( rules[ i ][ 0 ])){
181
+ if( rules[ i ][ 1 ] !== undefined ){
182
+ str = str.replace( rules[ i ][ 0 ], rules[ i ][ 1 ]);
183
+ }
184
+ break;
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ return str;
191
+ },
192
+
193
+
194
+
195
+ /**
196
+ * This lets us detect if an Array contains a given element.
197
+ * @public
198
+ * @function
199
+ * @param {Array} arr The subject array.
200
+ * @param {Object} item Object to locate in the Array.
201
+ * @param {Number} fromIndex Starts checking from this position in the Array.(optional)
202
+ * @param {Function} compareFunc Function used to compare Array item vs passed item.(optional)
203
+ * @returns {Number} Return index position in the Array of the passed item.
204
+ * @example
205
+ *
206
+ * var inflection = require( 'inflection' );
207
+ *
208
+ * inflection.indexOf([ 'hi','there' ], 'guys' ); // === -1
209
+ * inflection.indexOf([ 'hi','there' ], 'hi' ); // === 0
210
+ */
211
+ indexOf : function( arr, item, fromIndex, compareFunc ){
212
+ if( !fromIndex ){
213
+ fromIndex = -1;
214
+ }
215
+
216
+ var index = -1;
217
+ var i = fromIndex;
218
+ var j = arr.length;
219
+
220
+ for( ; i < j; i++ ){
221
+ if( arr[ i ] === item || compareFunc && compareFunc( arr[ i ], item )){
222
+ index = i;
223
+ break;
224
+ }
225
+ }
226
+
227
+ return index;
228
+ },
229
+
230
+
231
+
232
+ /**
233
+ * This function adds pluralization support to every String object.
234
+ * @public
235
+ * @function
236
+ * @param {String} str The subject string.
237
+ * @param {String} plural Overrides normal output with said String.(optional)
238
+ * @returns {String} Singular English language nouns are returned in plural form.
239
+ * @example
240
+ *
241
+ * var inflection = require( 'inflection' );
242
+ *
243
+ * inflection.pluralize( 'person' ); // === 'people'
244
+ * inflection.pluralize( 'octopus' ); // === "octopi"
245
+ * inflection.pluralize( 'Hat' ); // === 'Hats'
246
+ * inflection.pluralize( 'person', 'guys' ); // === 'guys'
247
+ */
248
+ pluralize : function ( str, plural ){
249
+ return inflector._apply_rules( str, plural_rules, uncountable_words, plural );
250
+ },
251
+
252
+
253
+
254
+ /**
255
+ * This function adds singularization support to every String object.
256
+ * @public
257
+ * @function
258
+ * @param {String} str The subject string.
259
+ * @param {String} singular Overrides normal output with said String.(optional)
260
+ * @returns {String} Plural English language nouns are returned in singular form.
261
+ * @example
262
+ *
263
+ * var inflection = require( 'inflection' );
264
+ *
265
+ * inflection.singularize( 'people' ); // === 'person'
266
+ * inflection.singularize( 'octopi' ); // === "octopus"
267
+ * inflection.singularize( 'Hats' ); // === 'Hat'
268
+ * inflection.singularize( 'guys', 'person' ); // === 'person'
269
+ */
270
+ singularize : function ( str, singular ){
271
+ return inflector._apply_rules( str, singular_rules, uncountable_words, singular );
272
+ },
273
+
274
+
275
+
276
+ /**
277
+ * This function adds camelization support to every String object.
278
+ * @public
279
+ * @function
280
+ * @param {String} str The subject string.
281
+ * @param {Boolean} lowFirstLetter Default is to capitalize the first letter of the results.(optional)
282
+ * Passing true will lowercase it.
283
+ * @returns {String} Lower case underscored words will be returned in camel case.
284
+ * additionally '/' is translated to '::'
285
+ * @example
286
+ *
287
+ * var inflection = require( 'inflection' );
288
+ *
289
+ * inflection.camelize( 'message_properties' ); // === 'MessageProperties'
290
+ * inflection.camelize( 'message_properties', true ); // === 'messageProperties'
291
+ */
292
+ camelize : function ( str, lowFirstLetter ){
293
+ var str_path = str.toLowerCase().split( '/' );
294
+ var i = 0;
295
+ var j = str_path.length;
296
+
297
+ for( ; i < j; i++ ){
298
+ var str_arr = str_path[ i ].split( '_' );
299
+ var initX = (( lowFirstLetter && i + 1 === j ) ? ( 1 ) : ( 0 ));
300
+ var k = initX;
301
+ var l = str_arr.length;
302
+
303
+ for( ; k < l; k++ ){
304
+ str_arr[ k ] = str_arr[ k ].charAt( 0 ).toUpperCase() + str_arr[ k ].substring( 1 );
305
+ }
306
+
307
+ str_path[ i ] = str_arr.join( '' );
308
+ }
309
+
310
+ return str_path.join( '::' );
311
+ },
312
+
313
+
314
+
315
+ /**
316
+ * This function adds underscore support to every String object.
317
+ * @public
318
+ * @function
319
+ * @param {String} str The subject string.
320
+ * @param {Boolean} allUpperCase Default is to lowercase and add underscore prefix.(optional)
321
+ * Passing true will return as entered.
322
+ * @returns {String} Camel cased words are returned as lower cased and underscored.
323
+ * additionally '::' is translated to '/'.
324
+ * @example
325
+ *
326
+ * var inflection = require( 'inflection' );
327
+ *
328
+ * inflection.underscore( 'MessageProperties' ); // === 'message_properties'
329
+ * inflection.underscore( 'messageProperties' ); // === 'message_properties'
330
+ * inflection.underscore( 'MP', true ); // === 'MP'
331
+ */
332
+ underscore : function ( str, allUpperCase ){
333
+ if( allUpperCase && str === str.toUpperCase()) return str;
334
+
335
+ var str_path = str.split( '::' );
336
+ var i = 0;
337
+ var j = str_path.length;
338
+
339
+ for( ; i < j; i++ ){
340
+ str_path[ i ] = str_path[ i ].replace( uppercase, '_$1' );
341
+ str_path[ i ] = str_path[ i ].replace( underbar_prefix, '' );
342
+ }
343
+
344
+ return str_path.join( '/' ).toLowerCase();
345
+ },
346
+
347
+
348
+
349
+ /**
350
+ * This function adds humanize support to every String object.
351
+ * @public
352
+ * @function
353
+ * @param {String} str The subject string.
354
+ * @param {Boolean} lowFirstLetter Default is to capitalize the first letter of the results.(optional)
355
+ * Passing true will lowercase it.
356
+ * @returns {String} Lower case underscored words will be returned in humanized form.
357
+ * @example
358
+ *
359
+ * var inflection = require( 'inflection' );
360
+ *
361
+ * inflection.humanize( 'message_properties' ); // === 'Message properties'
362
+ * inflection.humanize( 'message_properties', true ); // === 'message properties'
363
+ */
364
+ humanize : function( str, lowFirstLetter ){
365
+ str = str.toLowerCase();
366
+ str = str.replace( id_suffix, '' );
367
+ str = str.replace( underbar, ' ' );
368
+
369
+ if( !lowFirstLetter ){
370
+ str = inflector.capitalize( str );
371
+ }
372
+
373
+ return str;
374
+ },
375
+
376
+
377
+
378
+ /**
379
+ * This function adds capitalization support to every String object.
380
+ * @public
381
+ * @function
382
+ * @param {String} str The subject string.
383
+ * @returns {String} All characters will be lower case and the first will be upper.
384
+ * @example
385
+ *
386
+ * var inflection = require( 'inflection' );
387
+ *
388
+ * inflection.capitalize( 'message_properties' ); // === 'Message_properties'
389
+ * inflection.capitalize( 'message properties', true ); // === 'Message properties'
390
+ */
391
+ capitalize : function ( str ){
392
+ str = str.toLowerCase();
393
+
394
+ return str.substring( 0, 1 ).toUpperCase() + str.substring( 1 );
395
+ },
396
+
397
+
398
+
399
+ /**
400
+ * This function adds dasherization support to every String object.
401
+ * @public
402
+ * @function
403
+ * @param {String} str The subject string.
404
+ * @returns {String} Replaces all spaces or underbars with dashes.
405
+ * @example
406
+ *
407
+ * var inflection = require( 'inflection' );
408
+ *
409
+ * inflection.dasherize( 'message_properties' ); // === 'message-properties'
410
+ * inflection.dasherize( 'Message Properties' ); // === 'Message-Properties'
411
+ */
412
+ dasherize : function ( str ){
413
+ return str.replace( space_or_underbar, '-' );
414
+ },
415
+
416
+
417
+
418
+ /**
419
+ * This function adds titleize support to every String object.
420
+ * @public
421
+ * @function
422
+ * @param {String} str The subject string.
423
+ * @returns {String} Capitalizes words as you would for a book title.
424
+ * @example
425
+ *
426
+ * var inflection = require( 'inflection' );
427
+ *
428
+ * inflection.titleize( 'message_properties' ); // === 'Message Properties'
429
+ * inflection.titleize( 'message properties to keep' ); // === 'Message Properties to Keep'
430
+ */
431
+ titleize : function ( str ){
432
+ str = str.toLowerCase().replace( underbar, ' ');
433
+ var str_arr = str.split(' ');
434
+ var i = 0;
435
+ var j = str_arr.length;
436
+
437
+ for( ; i < j; i++ ){
438
+ var d = str_arr[ i ].split( '-' );
439
+ var k = 0;
440
+ var l = d.length;
441
+
442
+ for( ; k < l; k++){
443
+ if( inflector.indexOf( non_titlecased_words, d[ k ].toLowerCase()) < 0 ){
444
+ d[ k ] = inflector.capitalize( d[ k ]);
445
+ }
446
+ }
447
+
448
+ str_arr[ i ] = d.join( '-' );
449
+ }
450
+
451
+ str = str_arr.join( ' ' );
452
+ str = str.substring( 0, 1 ).toUpperCase() + str.substring( 1 );
453
+
454
+ return str;
455
+ },
456
+
457
+
458
+
459
+ /**
460
+ * This function adds demodulize support to every String object.
461
+ * @public
462
+ * @function
463
+ * @param {String} str The subject string.
464
+ * @returns {String} Removes module names leaving only class names.(Ruby style)
465
+ * @example
466
+ *
467
+ * var inflection = require( 'inflection' );
468
+ *
469
+ * inflection.demodulize( 'Message::Bus::Properties' ); // === 'Properties'
470
+ */
471
+ demodulize : function ( str ){
472
+ var str_arr = str.split( '::' );
473
+
474
+ return str_arr[ str_arr.length - 1 ];
475
+ },
476
+
477
+
478
+
479
+ /**
480
+ * This function adds tableize support to every String object.
481
+ * @public
482
+ * @function
483
+ * @param {String} str The subject string.
484
+ * @returns {String} Return camel cased words into their underscored plural form.
485
+ * @example
486
+ *
487
+ * var inflection = require( 'inflection' );
488
+ *
489
+ * inflection.tableize( 'MessageBusProperty' ); // === 'message_bus_properties'
490
+ */
491
+ tableize : function ( str ){
492
+ str = inflector.underscore( str );
493
+ str = inflector.pluralize( str );
494
+
495
+ return str;
496
+ },
497
+
498
+
499
+
500
+ /**
501
+ * This function adds classification support to every String object.
502
+ * @public
503
+ * @function
504
+ * @param {String} str The subject string.
505
+ * @returns {String} Underscored plural nouns become the camel cased singular form.
506
+ * @example
507
+ *
508
+ * var inflection = require( 'inflection' );
509
+ *
510
+ * inflection.classify( 'message_bus_properties' ); // === 'MessageBusProperty'
511
+ */
512
+ classify : function ( str ){
513
+ str = inflector.camelize( str );
514
+ str = inflector.singularize( str );
515
+
516
+ return str;
517
+ },
518
+
519
+
520
+
521
+ /**
522
+ * This function adds foreign key support to every String object.
523
+ * @public
524
+ * @function
525
+ * @param {String} str The subject string.
526
+ * @param {Boolean} dropIdUbar Default is to seperate id with an underbar at the end of the class name,
527
+ you can pass true to skip it.(optional)
528
+ * @returns {String} Underscored plural nouns become the camel cased singular form.
529
+ * @example
530
+ *
531
+ * var inflection = require( 'inflection' );
532
+ *
533
+ * inflection.foreign_key( 'MessageBusProperty' ); // === 'message_bus_property_id'
534
+ * inflection.foreign_key( 'MessageBusProperty', true ); // === 'message_bus_propertyid'
535
+ */
536
+ foreign_key : function( str, dropIdUbar ){
537
+ str = inflector.demodulize( str );
538
+ str = inflector.underscore( str ) + (( dropIdUbar ) ? ( '' ) : ( '_' )) + 'id';
539
+
540
+ return str;
541
+ },
542
+
543
+
544
+
545
+ /**
546
+ * This function adds ordinalize support to every String object.
547
+ * @public
548
+ * @function
549
+ * @param {String} str The subject string.
550
+ * @returns {String} Return all found numbers their sequence like "22nd".
551
+ * @example
552
+ *
553
+ * var inflection = require( 'inflection' );
554
+ *
555
+ * inflection.ordinalize( 'the 1 pitch' ); // === 'the 1st pitch'
556
+ */
557
+ ordinalize : function ( str ){
558
+ var str_arr = str.split(' ');
559
+ var i = 0;
560
+ var j = str_arr.length;
561
+
562
+ for( ; i < j; i++ ){
563
+ var k = parseInt( str_arr[ i ], 10 );
564
+
565
+ if( !isNaN( k )){
566
+ var ltd = str_arr[ i ].substring( str_arr[ i ].length - 2 );
567
+ var ld = str_arr[ i ].substring( str_arr[ i ].length - 1 );
568
+ var suf = 'th';
569
+
570
+ if( ltd != '11' && ltd != '12' && ltd != '13' ){
571
+ if( ld === '1' ){
572
+ suf = 'st';
573
+ }else if( ld === '2' ){
574
+ suf = 'nd';
575
+ }else if( ld === '3' ){
576
+ suf = 'rd';
577
+ }
578
+ }
579
+
580
+ str_arr[ i ] += suf;
581
+ }
582
+ }
583
+
584
+ return str_arr.join( ' ' );
585
+ }
586
+ };
587
+
588
+ if( typeof exports === 'undefined' ) return root.inflection = inflector;
589
+
590
+ /**
591
+ * @public
592
+ */
593
+ inflector.version = "1.2.5";
594
+ /**
595
+ * Exports module.
596
+ */
597
+ module.exports = inflector;
598
+ })( this );