i18n-js 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 353417f345acd62bc99d23f7a5fec4009cc0ee3e
4
- data.tar.gz: f06f7d88940146630ad37d71dc64d0ed7e746a75
3
+ metadata.gz: a6045fc4e7caf2df9308248a08c9a5f7f74d08a5
4
+ data.tar.gz: 3ac4f6ee77a6afa9948a73758bfcb70ecf92a156
5
5
  SHA512:
6
- metadata.gz: 40cb6d125502a38e0a9e87bb57fb57f3a4913ad6647a0431bd9c81cfa40b60b37b77562bec24c93c0a3b40687be33163107c63e9af7abc7a2d35a323dfc8fcee
7
- data.tar.gz: a6503dbaecb63aa9638f348e28625df2854399dd5c4cacacc776a13f2fdfd88aef8ca21f0aed3d6b6e1cb56571c83d8ca270ba6f949c4b14c452cdf177472fcd
6
+ metadata.gz: 0b56080a8ec45da012f3a846d8d811ed80245f76f2c3905079cf7930b08b3775b2381757b20b2384ab91e17fcfd76586daf459c594b31f03aa04e31fc65a8fe0
7
+ data.tar.gz: 9d093f0a6c62daee153bc8d9b7702f2aab193d660a752e17e1c0fe4595637f19748819dc7c45d4e46816adaf97342d56f3db1285a687f565fd87e74ac308cf58
@@ -0,0 +1,24 @@
1
+ # EditorConfig is awesome: http://EditorConfig.org
2
+
3
+ # top-most EditorConfig file
4
+ root = true
5
+
6
+ # default configuration
7
+ [*]
8
+ indent_style = space
9
+ indent_size = 2
10
+ insert_final_newline = true
11
+ trim_trailing_whitespace = true
12
+
13
+ # Unix-style newlines with a newline ending every file
14
+ end_of_line = lf
15
+
16
+ # Set default charset
17
+ charset = utf-8
18
+
19
+ # Tab indentation (no size specified)
20
+ [Makefile]
21
+ indent_style = tab
22
+
23
+ [*.{md,markdown}]
24
+ trim_trailing_whitespace = false
@@ -0,0 +1,26 @@
1
+ # https://docs.npmjs.com/misc/developers#keeping-files-out-of-your-package
2
+
3
+ # tests
4
+ spec
5
+ coverage
6
+
7
+ # build tools
8
+ .travis.yml
9
+
10
+ # linters
11
+ .jscsrc
12
+ .jshintrc
13
+ .eslintrc*
14
+
15
+ # editor settings
16
+ .idea
17
+ .editorconfig
18
+
19
+ # Ruby code
20
+ gemfiles
21
+ lib
22
+ Gemfile*
23
+ *.gemspec
24
+ Rakefile
25
+ Appraisals
26
+
@@ -18,6 +18,17 @@ This project adheres to [Semantic Versioning](http://semver.org/).
18
18
  - Nothing
19
19
 
20
20
 
21
+ ## [3.0.1] - 2017-08-02
22
+
23
+ ### Changed
24
+
25
+ - [Ruby] Relax Rails detection code to work with alternative installation methods
26
+ (PR: https://github.com/fnando/i18n-js/pull/467)
27
+ - [JS] Fix fallback when "3-part" locale like `zh-Hant-TW` is used
28
+ It fallbacks to `zh` only before, now it fallbacks to `zh-Hant`
29
+ (PR: https://github.com/fnando/i18n-js/pull/465)
30
+
31
+
21
32
  ## [3.0.0] - 2017-04-01
22
33
 
23
34
  This is a fake official release, the *real* one will be `3.0.0.rc17`
@@ -240,7 +251,8 @@ And today is not April Fools' Day
240
251
 
241
252
 
242
253
 
243
- [Unreleased]: https://github.com/fnando/i18n-js/compare/v3.0.0...HEAD
254
+ [Unreleased]: https://github.com/fnando/i18n-js/compare/v3.0.1...HEAD
255
+ [3.0.1]: https://github.com/fnando/i18n-js/compare/v3.0.0...v3.0.1
244
256
  [3.0.0]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc16...v3.0.0
245
257
  [3.0.0.rc16]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc15...v3.0.0.rc16
246
258
  [3.0.0.rc15]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc14...v3.0.0.rc15
data/README.md CHANGED
@@ -257,7 +257,7 @@ translations:
257
257
  ```
258
258
 
259
259
 
260
- #### Javscript Deep Merge (:js_extend option)
260
+ #### Javascript Deep Merge (:js_extend option)
261
261
 
262
262
  By default, the output file Javascript will call the `I18n.extend` method to ensure that newly loaded locale
263
263
  files are deep-merged with any locale data already in memory. To disable this either globally or per-file,
@@ -453,7 +453,7 @@ I18n.pluralization["ru"] = function (count) {
453
453
  };
454
454
  ```
455
455
 
456
- You can find all rules on <http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html>.
456
+ You can find all rules on <http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html>.
457
457
 
458
458
  If you're using the same scope over and over again, you may use the `scope` option.
459
459
 
@@ -52,7 +52,17 @@
52
52
  // Borrowed from Underscore.js
53
53
  var isObject = function(obj) {
54
54
  var type = typeof obj;
55
- return type === 'function' || type === 'object' && !!obj;
55
+ return type === 'function' || type === 'object'
56
+ };
57
+
58
+ var isFunction = function(func) {
59
+ var type = typeof func;
60
+ return type === 'function'
61
+ };
62
+
63
+ // Check if value is different than undefined and null;
64
+ var isSet = function(value) {
65
+ return typeof(value) !== 'undefined' && value !== null;
56
66
  };
57
67
 
58
68
  // Is a given value an array?
@@ -95,6 +105,14 @@
95
105
  return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
96
106
  }
97
107
 
108
+ var lazyEvaluate = function(message, scope) {
109
+ if (isFunction(message)) {
110
+ return message(scope);
111
+ } else {
112
+ return message;
113
+ }
114
+ }
115
+
98
116
  var merge = function (dest, obj) {
99
117
  var key, value;
100
118
  for (key in obj) if (obj.hasOwnProperty(key)) {
@@ -173,60 +191,21 @@
173
191
  , missingTranslationPrefix: ''
174
192
  };
175
193
 
194
+ // Set default locale. This locale will be used when fallback is enabled and
195
+ // the translation doesn't exist in a particular locale.
176
196
  I18n.reset = function() {
177
- // Set default locale. This locale will be used when fallback is enabled and
178
- // the translation doesn't exist in a particular locale.
179
- this.defaultLocale = DEFAULT_OPTIONS.defaultLocale;
180
-
181
- // Set the current locale to `en`.
182
- this.locale = DEFAULT_OPTIONS.locale;
183
-
184
- // Set the translation key separator.
185
- this.defaultSeparator = DEFAULT_OPTIONS.defaultSeparator;
186
-
187
- // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.
188
- this.placeholder = DEFAULT_OPTIONS.placeholder;
189
-
190
- // Set if engine should fallback to the default locale when a translation
191
- // is missing.
192
- this.fallbacks = DEFAULT_OPTIONS.fallbacks;
193
-
194
- // Set the default translation object.
195
- this.translations = DEFAULT_OPTIONS.translations;
196
-
197
- // Set the default missing behaviour
198
- this.missingBehaviour = DEFAULT_OPTIONS.missingBehaviour;
199
-
200
- // Set the default missing string prefix for guess behaviour
201
- this.missingTranslationPrefix = DEFAULT_OPTIONS.missingTranslationPrefix;
202
-
197
+ var key;
198
+ for (key in DEFAULT_OPTIONS) {
199
+ this[key] = DEFAULT_OPTIONS[key];
200
+ }
203
201
  };
204
202
 
205
203
  // Much like `reset`, but only assign options if not already assigned
206
204
  I18n.initializeOptions = function() {
207
- if (typeof(this.defaultLocale) === "undefined" && this.defaultLocale !== null)
208
- this.defaultLocale = DEFAULT_OPTIONS.defaultLocale;
209
-
210
- if (typeof(this.locale) === "undefined" && this.locale !== null)
211
- this.locale = DEFAULT_OPTIONS.locale;
212
-
213
- if (typeof(this.defaultSeparator) === "undefined" && this.defaultSeparator !== null)
214
- this.defaultSeparator = DEFAULT_OPTIONS.defaultSeparator;
215
-
216
- if (typeof(this.placeholder) === "undefined" && this.placeholder !== null)
217
- this.placeholder = DEFAULT_OPTIONS.placeholder;
218
-
219
- if (typeof(this.fallbacks) === "undefined" && this.fallbacks !== null)
220
- this.fallbacks = DEFAULT_OPTIONS.fallbacks;
221
-
222
- if (typeof(this.translations) === "undefined" && this.translations !== null)
223
- this.translations = DEFAULT_OPTIONS.translations;
224
-
225
- if (typeof(this.missingBehaviour) === "undefined" && this.missingBehaviour !== null)
226
- this.missingBehaviour = DEFAULT_OPTIONS.missingBehaviour;
227
-
228
- if (typeof(this.missingTranslationPrefix) === "undefined" && this.missingTranslationPrefix !== null)
229
- this.missingTranslationPrefix = DEFAULT_OPTIONS.missingTranslationPrefix;
205
+ var key;
206
+ for (key in DEFAULT_OPTIONS) if (!isSet(this[key])) {
207
+ this[key] = DEFAULT_OPTIONS[key];
208
+ }
230
209
  };
231
210
  I18n.initializeOptions();
232
211
 
@@ -252,7 +231,7 @@
252
231
  I18n.locales.get = function(locale) {
253
232
  var result = this[locale] || this[I18n.locale] || this["default"];
254
233
 
255
- if (typeof(result) === "function") {
234
+ if (isFunction(result)) {
256
235
  result = result(locale);
257
236
  }
258
237
 
@@ -267,8 +246,6 @@
267
246
  I18n.locales["default"] = function(locale) {
268
247
  var locales = []
269
248
  , list = []
270
- , countryCode
271
- , count
272
249
  ;
273
250
 
274
251
  // Handle the inline locale option that can be provided to
@@ -287,19 +264,85 @@
287
264
  locales.push(I18n.defaultLocale);
288
265
  }
289
266
 
267
+ // Locale code format 1:
268
+ // According to RFC4646 (http://www.ietf.org/rfc/rfc4646.txt)
269
+ // language codes for Traditional Chinese should be `zh-Hant`
270
+ //
271
+ // But due to backward compatibility
272
+ // We use older version of IETF language tag
273
+ // @see http://www.w3.org/TR/html401/struct/dirlang.html
274
+ // @see http://en.wikipedia.org/wiki/IETF_language_tag
275
+ //
276
+ // Format: `language-code = primary-code ( "-" subcode )*`
277
+ //
278
+ // primary-code uses ISO639-1
279
+ // @see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
280
+ // @see http://www.iso.org/iso/home/standards/language_codes.htm
281
+ //
282
+ // subcode uses ISO 3166-1 alpha-2
283
+ // @see http://en.wikipedia.org/wiki/ISO_3166
284
+ // @see http://www.iso.org/iso/country_codes.htm
285
+ //
286
+ // @note
287
+ // subcode can be in upper case or lower case
288
+ // defining it in upper case is a convention only
289
+
290
+
291
+ // Locale code format 2:
292
+ // Format: `code = primary-code ( "-" region-code )*`
293
+ // primary-code uses ISO 639-1
294
+ // script-code uses ISO 15924
295
+ // region-code uses ISO 3166-1 alpha-2
296
+ // Example: zh-Hant-TW, en-HK, zh-Hant-CN
297
+ //
298
+ // It is similar to RFC4646 (or actually the same),
299
+ // but seems to be limited to language, script, region
300
+
290
301
  // Compute each locale with its country code.
291
- // So this will return an array containing both
292
- // `de-DE` and `de` locales.
293
- locales.forEach(function(locale){
294
- countryCode = locale.split("-")[0];
302
+ // So this will return an array containing
303
+ // `de-DE` and `de`
304
+ // or
305
+ // `zh-hans-tw`, `zh-hans`, `zh`
306
+ // locales.
307
+ locales.forEach(function(locale) {
308
+ var localeParts = locale.split("-");
309
+ var firstFallback = null;
310
+ var secondFallback = null;
311
+ if (localeParts.length === 3) {
312
+ firstFallback = localeParts[0];
313
+ secondFallback = [
314
+ localeParts[0],
315
+ localeParts[1]
316
+ ].join("-");
317
+ }
318
+ else if (localeParts.length === 2) {
319
+ firstFallback = localeParts[0];
320
+ }
295
321
 
296
- if (!~list.indexOf(locale)) {
322
+ if (list.indexOf(locale) === -1) {
297
323
  list.push(locale);
298
324
  }
299
325
 
300
- if (I18n.fallbacks && countryCode && countryCode !== locale && !~list.indexOf(countryCode)) {
301
- list.push(countryCode);
326
+ if (! I18n.fallbacks) {
327
+ return;
302
328
  }
329
+
330
+ [
331
+ firstFallback,
332
+ secondFallback
333
+ ].forEach(function(nullableFallbackLocale) {
334
+ // We don't want null values
335
+ if (typeof nullableFallbackLocale === "undefined") { return; }
336
+ if (nullableFallbackLocale === null) { return; }
337
+ // We don't want duplicate values
338
+ //
339
+ // Comparing with `locale` first is faster than
340
+ // checking whether value's presence in the list
341
+ if (nullableFallbackLocale === locale) { return; }
342
+ if (list.indexOf(nullableFallbackLocale) !== -1) { return; }
343
+
344
+ list.push(nullableFallbackLocale);
345
+ });
303
346
  });
304
347
 
305
348
  // No locales set? English it is.
@@ -336,28 +379,27 @@
336
379
  };
337
380
 
338
381
  // Check if value is different than undefined and null;
339
- I18n.isSet = function(value) {
340
- return value !== undefined && value !== null;
341
- };
382
+ I18n.isSet = isSet;
342
383
 
343
384
  // Find and process the translation using the provided scope and options.
344
385
  // This is used internally by some functions and should not be used as an
345
386
  // public API.
346
387
  I18n.lookup = function(scope, options) {
347
- options = this.prepareOptions(options);
388
+ options = options || {}
348
389
 
349
390
  var locales = this.locales.get(options.locale).slice()
350
391
  , requestedLocale = locales[0]
351
392
  , locale
352
393
  , scopes
394
+ , fullScope
353
395
  , translations
354
396
  ;
355
397
 
356
- scope = this.getFullScope(scope, options);
398
+ fullScope = this.getFullScope(scope, options);
357
399
 
358
400
  while (locales.length) {
359
401
  locale = locales.shift();
360
- scopes = scope.split(this.defaultSeparator);
402
+ scopes = fullScope.split(this.defaultSeparator);
361
403
  translations = this.translations[locale];
362
404
 
363
405
  if (!translations) {
@@ -376,8 +418,8 @@
376
418
  }
377
419
  }
378
420
 
379
- if (this.isSet(options.defaultValue)) {
380
- return options.defaultValue;
421
+ if (isSet(options.defaultValue)) {
422
+ return lazyEvaluate(options.defaultValue, scope);
381
423
  }
382
424
  };
383
425
 
@@ -391,7 +433,7 @@
391
433
  if (isObject(translations)) {
392
434
  while (pluralizerKeys.length) {
393
435
  pluralizerKey = pluralizerKeys.shift();
394
- if (this.isSet(translations[pluralizerKey])) {
436
+ if (isSet(translations[pluralizerKey])) {
395
437
  message = translations[pluralizerKey];
396
438
  break;
397
439
  }
@@ -403,7 +445,7 @@
403
445
 
404
446
  // Lookup dedicated to pluralization
405
447
  I18n.pluralizationLookup = function(count, scope, options) {
406
- options = this.prepareOptions(options);
448
+ options = options || {}
407
449
  var locales = this.locales.get(options.locale).slice()
408
450
  , requestedLocale = locales[0]
409
451
  , locale
@@ -437,7 +479,7 @@
437
479
  }
438
480
 
439
481
  if (message == null || message == undefined) {
440
- if (this.isSet(options.defaultValue)) {
482
+ if (isSet(options.defaultValue)) {
441
483
  if (isObject(options.defaultValue)) {
442
484
  message = this.pluralizationLookupWithoutFallback(count, options.locale, options.defaultValue);
443
485
  } else {
@@ -492,7 +534,7 @@
492
534
  continue;
493
535
  }
494
536
 
495
- if (this.isSet(options[attr])) {
537
+ if (isSet(options[attr])) {
496
538
  continue;
497
539
  }
498
540
 
@@ -511,15 +553,14 @@
511
553
 
512
554
  // Defaults should be an array of hashes containing either
513
555
  // fallback scopes or messages
514
- if (this.isSet(options.defaults)) {
556
+ if (isSet(options.defaults)) {
515
557
  translationOptions = translationOptions.concat(options.defaults);
516
558
  }
517
559
 
518
560
  // Maintain support for defaultValue. Since it is always a message
519
561
  // insert it in to the translation options as such.
520
- if (this.isSet(options.defaultValue)) {
562
+ if (isSet(options.defaultValue)) {
521
563
  translationOptions.push({ message: options.defaultValue });
522
- delete options.defaultValue;
523
564
  }
524
565
 
525
566
  return translationOptions;
@@ -527,20 +568,23 @@
527
568
 
528
569
  // Translate the given scope with the provided options.
529
570
  I18n.translate = function(scope, options) {
530
- options = this.prepareOptions(options);
571
+ options = options || {}
531
572
 
532
- var copiedOptions = this.prepareOptions(options);
533
573
  var translationOptions = this.createTranslationOptions(scope, options);
534
574
 
535
575
  var translation;
576
+
577
+ var optionsWithoutDefault = this.prepareOptions(options)
578
+ delete optionsWithoutDefault.defaultValue
579
+
536
580
  // Iterate through the translation options until a translation
537
581
  // or message is found.
538
582
  var translationFound =
539
583
  translationOptions.some(function(translationOption) {
540
- if (this.isSet(translationOption.scope)) {
541
- translation = this.lookup(translationOption.scope, options);
542
- } else if (this.isSet(translationOption.message)) {
543
- translation = translationOption.message;
584
+ if (isSet(translationOption.scope)) {
585
+ translation = this.lookup(translationOption.scope, optionsWithoutDefault);
586
+ } else if (isSet(translationOption.message)) {
587
+ translation = lazyEvaluate(translationOption.message, scope);
544
588
  }
545
589
 
546
590
  if (translation !== undefined && translation !== null) {
@@ -554,8 +598,8 @@
554
598
 
555
599
  if (typeof(translation) === "string") {
556
600
  translation = this.interpolate(translation, options);
557
- } else if (isObject(translation) && this.isSet(options.count)) {
558
- translation = this.pluralize(options.count, scope, copiedOptions);
601
+ } else if (isObject(translation) && isSet(options.count)) {
602
+ translation = this.pluralize(options.count, scope, options);
559
603
  }
560
604
 
561
605
  return translation;
@@ -563,7 +607,7 @@
563
607
 
564
608
  // This function interpolates the all variables in the given message.
565
609
  I18n.interpolate = function(message, options) {
566
- options = this.prepareOptions(options);
610
+ options = options || {}
567
611
  var matches = message.match(this.placeholder)
568
612
  , placeholder
569
613
  , value
@@ -581,7 +625,7 @@
581
625
  placeholder = matches.shift();
582
626
  name = placeholder.replace(this.placeholder, "$1");
583
627
 
584
- if (this.isSet(options[name])) {
628
+ if (isSet(options[name])) {
585
629
  value = options[name].toString().replace(/\$/gm, "_#$#_");
586
630
  } else if (name in options) {
587
631
  value = this.nullPlaceholder(placeholder, message, options);
@@ -600,7 +644,7 @@
600
644
  // The pluralized translation may have other placeholders,
601
645
  // which will be retrieved from `options`.
602
646
  I18n.pluralize = function(count, scope, options) {
603
- options = this.prepareOptions(options);
647
+ options = this.prepareOptions({count: String(count)}, options)
604
648
  var pluralizer, message, result;
605
649
 
606
650
  result = this.pluralizationLookup(count, scope, options);
@@ -608,8 +652,6 @@
608
652
  return this.missingTranslation(scope, options);
609
653
  }
610
654
 
611
- options.count = String(count);
612
-
613
655
  if (result.message != undefined && result.message != null) {
614
656
  return this.interpolate(result.message, options);
615
657
  }
@@ -982,10 +1024,10 @@
982
1024
  };
983
1025
 
984
1026
  I18n.getFullScope = function(scope, options) {
985
- options = this.prepareOptions(options);
1027
+ options = options || {}
986
1028
 
987
1029
  // Deal with the scope as an array.
988
- if (scope.constructor === Array) {
1030
+ if (isArray(scope)) {
989
1031
  scope = scope.join(this.defaultSeparator);
990
1032
  }
991
1033
 
@@ -4,28 +4,12 @@ module I18n
4
4
  # we need to specify pre-release version suffix in version constraint
5
5
  module Dependencies
6
6
  class << self
7
- def rails3?
8
- safe_gem_check("rails", "~> 3.0") && running_rails3?
9
- end
10
-
11
- def rails4?
12
- safe_gem_check("rails", "~> 4.0", ">= 4.0.0.beta1") && running_rails4?
13
- end
14
-
15
- def rails5?
16
- safe_gem_check("rails", "~> 5.0", ">= 5.0.0.beta1") && running_rails5?
17
- end
18
-
19
- def sprockets_supports_register_preprocessor?
20
- defined?(Sprockets) && Sprockets.respond_to?(:register_preprocessor)
21
- end
22
-
23
7
  def rails?
24
- rails_available? && running_rails?
8
+ defined?(Rails) && Rails.respond_to?(:version)
25
9
  end
26
10
 
27
- def rails_available?
28
- safe_gem_check("rails", '>= 3.0.0.beta')
11
+ def sprockets_rails_v2_plus?
12
+ safe_gem_check("sprockets-rails", ">= 2")
29
13
  end
30
14
 
31
15
  # This cannot be called at class definition time
@@ -47,20 +31,16 @@ module I18n
47
31
 
48
32
  private
49
33
 
50
- def running_rails3?
51
- running_rails? && Rails.version.to_i == 3
52
- end
53
-
54
- def running_rails4?
55
- running_rails? && Rails.version.to_i == 4
34
+ def rails3?
35
+ rails? && Rails.version.to_i == 3
56
36
  end
57
37
 
58
- def running_rails5?
59
- running_rails? && Rails.version.to_i == 5
38
+ def rails4?
39
+ rails? && Rails.version.to_i == 4
60
40
  end
61
41
 
62
- def running_rails?
63
- defined?(Rails) && Rails.respond_to?(:version)
42
+ def rails5?
43
+ rails? && Rails.version.to_i == 5
64
44
  end
65
45
 
66
46
  def safe_gem_check(*args)
@@ -9,56 +9,39 @@ module I18n
9
9
  end
10
10
 
11
11
  class Engine < ::Rails::Engine
12
- if JS::Dependencies.sprockets_supports_register_preprocessor?
13
- # constant `Sprockets` should be available here after
14
- # `.sprockets_supports_register_preprocessor?` called
15
- sprockets_version = Gem::Version.new(Sprockets::VERSION).release
16
- v2_only = Gem::Dependency.new("", " ~> 2")
17
- v3_plus = Gem::Dependency.new("", " >= 3")
12
+ # See https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
13
+ # for reference of supporting multiple versions
18
14
 
19
- # See https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
20
- # for reference of supporting multiple versions
15
+ # `sprockets.environment` was used for 1.x of `sprockets-rails`
16
+ # https://github.com/rails/sprockets-rails/issues/227
17
+ #
18
+ # References for current values:
19
+ #
20
+ # Here is where sprockets are attached with Rails. There is no 'sprockets.environment' mentioned.
21
+ # https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb
22
+ #
23
+ # Finisher hook is the place which should be used as border.
24
+ # http://guides.rubyonrails.org/configuring.html#initializers
25
+ #
26
+ # For detail see Pull Request:
27
+ # https://github.com/fnando/i18n-js/pull/371
28
+ initializer "i18n-js.register_preprocessor", after: :engines_blank_point, before: :finisher_hook do
29
+ # This must be called inside initializer block
30
+ # For details see comments for `using_asset_pipeline?`
31
+ next unless JS::Dependencies.using_asset_pipeline?
21
32
 
22
- # `sprockets.environment` was used for 1.x of `sprockets-rails`
23
- # https://github.com/rails/sprockets-rails/issues/227
33
+ # From README of 2.x & 3.x of `sprockets-rails`
34
+ # It seems the `configure` block is preferred way to call `register_preprocessor`
35
+ # Not sure if this will break older versions of rails
24
36
  #
25
- # References for current values:
26
- #
27
- # Here is where sprockets are attached with Rails. There is no 'sprockets.environment' mentioned.
28
- # https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb
29
- #
30
- # Finisher hook is the place which should be used as border.
31
- # http://guides.rubyonrails.org/configuring.html#initializers
32
- #
33
- # For detail see Pull Request:
34
- # https://github.com/fnando/i18n-js/pull/371
35
- #
36
- # Not using -> for JRuby compatibility
37
- # See https://github.com/fnando/i18n-js/issues/419
38
- initializer_args = case sprockets_version
39
- when lambda {|v| v2_only.match?("", v) || v3_plus.match?("", v) }
40
- { after: :engines_blank_point, before: :finisher_hook }
41
- else
42
- raise StandardError, "Sprockets version #{sprockets_version} is not supported"
43
- end
44
-
45
- initializer "i18n-js.register_preprocessor", initializer_args do
46
- # This must be called inside initializer block
47
- # For details see comments for `using_asset_pipeline?`
48
- next unless JS::Dependencies.using_asset_pipeline?
49
-
50
- # From README of 2.x & 3.x of `sprockets-rails`
51
- # It seems the `configure` block is preferred way to call `register_preprocessor`
52
- # Not sure if this will break older versions of rails
53
- #
54
- # https://github.com/rails/sprockets-rails/blob/v2.3.3/README.md
55
- # https://github.com/rails/sprockets-rails/blob/v3.0.0/README.md
37
+ # https://github.com/rails/sprockets-rails/blob/v2.3.3/README.md
38
+ # https://github.com/rails/sprockets-rails/blob/v3.0.0/README.md
39
+ if JS::Dependencies.sprockets_rails_v2_plus?
56
40
  Rails.application.config.assets.configure do |config|
57
- config.register_preprocessor(
58
- "application/javascript",
59
- ::I18n::JS::SprocketsExtension,
60
- )
41
+ config.register_preprocessor("application/javascript", ::I18n::JS::SprocketsExtension)
61
42
  end
43
+ elsif Rails.application.assets.respond_to?(:register_preprocessor)
44
+ Rails.application.assets.register_preprocessor("application/javascript", ::I18n::JS::SprocketsExtension)
62
45
  end
63
46
  end
64
47
  end
@@ -1,5 +1,5 @@
1
1
  module I18n
2
2
  module JS
3
- VERSION = "3.0.0"
3
+ VERSION = "3.0.1"
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18n-js",
3
- "version": "0.0.0",
3
+ "version": "3.0.1",
4
4
  "devDependencies": {
5
5
  "jasmine-node": "^1.14.5"
6
6
  },
@@ -65,7 +65,7 @@ describe("Translate", function(){
65
65
  expect(I18n.t("hello", {locale: "pt-BR"})).toEqual("Olá Mundo!");
66
66
  });
67
67
 
68
- it("fallbacks to the default locale when I18n.fallbackss is enabled", function(){
68
+ it("fallbacks to the default locale when I18n.fallbacks is enabled", function(){
69
69
  I18n.locale = "pt-BR";
70
70
  I18n.fallbacks = true;
71
71
  expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
@@ -83,6 +83,21 @@ describe("Translate", function(){
83
83
  expect(I18n.t("hello")).toEqual("Hallo Welt!");
84
84
  });
85
85
 
86
+ describe("when a 3-part locale is used", function(){
87
+ beforeEach(function(){
88
+ I18n.locale = "zh-Hant-TW";
89
+ I18n.fallbacks = true;
90
+ });
91
+
92
+ it("fallbacks to 2-part locale when absent", function(){
93
+ expect(I18n.t("cat")).toEqual("貓");
94
+ });
95
+
96
+ it("fallbacks to 1-part locale when 2-part missing requested translation", function(){
97
+ expect(I18n.t("dog")).toEqual("狗");
98
+ });
99
+ });
100
+
86
101
  it("fallbacks using custom rules (function)", function(){
87
102
  I18n.locale = "no";
88
103
  I18n.fallbacks = true;
@@ -145,6 +160,26 @@ describe("Translate", function(){
145
160
  actual = I18n.t("foo", options);
146
161
  expect(actual).toEqual("Hello all!");
147
162
  });
163
+
164
+ it("uses default scope over default value if default scope is found", function() {
165
+ var options = {
166
+ defaults: [{scope: "hello"}]
167
+ , defaultValue: "Hello all!"
168
+ };
169
+ actual = I18n.t("foo", options);
170
+ expect(actual).toEqual("Hello World!");
171
+ })
172
+
173
+ it("uses default value with lazy evaluation", function () {
174
+ var options = {
175
+ defaults: [{scope: "bar"}]
176
+ , defaultValue: function(scope) {
177
+ return scope.toUpperCase();
178
+ }
179
+ };
180
+ actual = I18n.t("foo", options);
181
+ expect(actual).toEqual("FOO");
182
+ })
148
183
  });
149
184
 
150
185
  it("uses default value for simple translation", function(){
@@ -130,6 +130,14 @@ var DEBUG = false;
130
130
  hello: "Hei Verden!"
131
131
  };
132
132
 
133
+ Translations["zh-Hant"] = {
134
+ cat: "貓"
135
+ };
136
+
137
+ Translations["zh"] = {
138
+ dog: "狗"
139
+ };
140
+
133
141
  return Translations;
134
142
  };
135
143
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-js
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-01 00:00:00.000000000 Z
11
+ date: 2017-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -93,7 +93,9 @@ executables: []
93
93
  extensions: []
94
94
  extra_rdoc_files: []
95
95
  files:
96
+ - ".editorconfig"
96
97
  - ".gitignore"
98
+ - ".npmignore"
97
99
  - ".travis.yml"
98
100
  - Appraisals
99
101
  - CHANGELOG.md
@@ -170,7 +172,6 @@ files:
170
172
  - spec/js/translate.spec.js
171
173
  - spec/js/translations.js
172
174
  - spec/js/utility_functions.spec.js
173
- - spec/ruby/i18n/js/dependencies_spec.rb
174
175
  - spec/ruby/i18n/js/fallback_locales_spec.rb
175
176
  - spec/ruby/i18n/js/segment_spec.rb
176
177
  - spec/ruby/i18n/js/utils_spec.rb
@@ -196,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
197
  version: '0'
197
198
  requirements: []
198
199
  rubyforge_project:
199
- rubygems_version: 2.6.11
200
+ rubygems_version: 2.6.12
200
201
  signing_key:
201
202
  specification_version: 4
202
203
  summary: It's a small library to provide the Rails I18n translations on the Javascript.
@@ -249,7 +250,6 @@ test_files:
249
250
  - spec/js/translate.spec.js
250
251
  - spec/js/translations.js
251
252
  - spec/js/utility_functions.spec.js
252
- - spec/ruby/i18n/js/dependencies_spec.rb
253
253
  - spec/ruby/i18n/js/fallback_locales_spec.rb
254
254
  - spec/ruby/i18n/js/segment_spec.rb
255
255
  - spec/ruby/i18n/js/utils_spec.rb
@@ -1,43 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe I18n::JS::Dependencies, ".sprockets_supports_register_preprocessor?" do
4
-
5
- subject { described_class.sprockets_supports_register_preprocessor? }
6
-
7
- context 'when Sprockets is available to register preprocessors' do
8
- let!(:sprockets_double) do
9
- class_double('Sprockets').as_stubbed_const(register_processor: true).tap do |double|
10
- allow(double).to receive(:respond_to?).with(:register_preprocessor).and_return(true)
11
- end
12
- end
13
-
14
- it { is_expected.to be_truthy }
15
- it 'calls respond_to? with register_preprocessor on Sprockets' do
16
- expect(sprockets_double).to receive(:respond_to?).with(:register_preprocessor).and_return(true)
17
- subject
18
- end
19
- end
20
-
21
- context 'when Sprockets is NOT available to register preprocessors' do
22
- let!(:sprockets_double) do
23
- class_double('Sprockets').as_stubbed_const(register_processor: true).tap do |double|
24
- allow(double).to receive(:respond_to?).with(:register_preprocessor).and_return(false)
25
- end
26
- end
27
-
28
- it { is_expected.to be_falsy }
29
- it 'calls respond_to? with register_preprocessor on Sprockets' do
30
- expect(sprockets_double).to receive(:respond_to?).with(:register_preprocessor).and_return(false)
31
- subject
32
- end
33
- end
34
-
35
- context 'when Sprockets is missing' do
36
- before do
37
- hide_const('Sprockets')
38
- expect { Sprockets }.to raise_error(NameError)
39
- end
40
-
41
- it { is_expected.to be_falsy }
42
- end
43
- end