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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 );