i18n-js 3.8.2 → 3.9.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
  SHA256:
3
- metadata.gz: 4eebc45e9890bdf47c3c7183b008b7383fcfb6415756ca7152bc7b20e5362989
4
- data.tar.gz: f4228b2bd329a17f99abc3e2cb455ed846126fdecb31cb2cf89ab361ae383a36
3
+ metadata.gz: af88256d90ed5aa70fdaf88ce224e2b3bdb378b65d3e4a826dd9073484d6d691
4
+ data.tar.gz: 3a6409f3e78871438978ebaeb10853e6c49b38eddb3be679a4bf5f550ebc1b17
5
5
  SHA512:
6
- metadata.gz: 0af9e0e46cbbbeccc196296198d67457c103185713a3df784cc5a8ccf1670a9852a9a0ba1a8ce1aa46f885569bedbc12d1f956270860e67990a05f8e514c5c7a
7
- data.tar.gz: 6c974b2d308f08edaaf0e387000c3736fb87ece6f012563dd7d731cfd8919d3d850d0c123e5f646e59b911ab613c3e9b7e4fe8bff90d9266227f1871b5cba914
6
+ metadata.gz: 93da6d4965b27b83a8064a0665b3689e8a55bf750881b4cfd00d220e3e73379c56840ff452a3fe586c66c69ff7b1f5132193160913ced2d956e2145ff4567894
7
+ data.tar.gz: 9ce7b91903ac75ee8e7c320058d45893330033eb5628b2ef1a3d8e29466053d21b931a6f1c87c15f7bb1f83bbce0c5c33a8b785c8be79c5acbdbb48eafb459ba
data/.editorconfig CHANGED
@@ -1,4 +1,4 @@
1
- # EditorConfig is awesome: http://EditorConfig.org
1
+ # EditorConfig is awesome: https://EditorConfig.org
2
2
 
3
3
  # top-most EditorConfig file
4
4
  root = true
@@ -4,11 +4,13 @@ on:
4
4
  pull_request:
5
5
  branches:
6
6
  - main
7
+ - v3
7
8
  paths-ignore:
8
9
  - 'README.md'
9
10
  push:
10
11
  branches:
11
12
  - main
13
+ - v3
12
14
  paths-ignore:
13
15
  - 'README.md'
14
16
 
@@ -26,6 +28,8 @@ jobs:
26
28
  - 2.5
27
29
  - 2.6
28
30
  - 2.7
31
+ - '3.0'
32
+ - 3.1
29
33
  gemfile:
30
34
  - gemfiles/i18n_0_6.gemfile
31
35
  - gemfiles/i18n_0_7.gemfile
@@ -40,6 +44,7 @@ jobs:
40
44
  - gemfiles/i18n_1_6.gemfile
41
45
  - gemfiles/i18n_1_7.gemfile
42
46
  - gemfiles/i18n_1_8.gemfile
47
+ - gemfiles/i18n_1_9.gemfile
43
48
  allow_failures:
44
49
  - false
45
50
  include:
data/Appraisals CHANGED
@@ -42,3 +42,7 @@ end
42
42
  appraise "i18n_1_8" do
43
43
  gem "i18n", "~> 1.8.0"
44
44
  end
45
+
46
+ appraise "i18n_1_9" do
47
+ gem "i18n", "~> 1.9.0"
48
+ end
data/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
- This project adheres to [Semantic Versioning](http://semver.org/).
3
+ This project adheres to [Semantic Versioning](https://semver.org/).
4
4
 
5
5
 
6
6
  ## [Unreleased]
@@ -18,6 +18,40 @@ This project adheres to [Semantic Versioning](http://semver.org/).
18
18
  - Nothing
19
19
 
20
20
 
21
+ ## [3.9.1] - 2022-02-08
22
+
23
+ ### Changed
24
+
25
+ - [Ruby] Allow rails 7
26
+ (PR: https://github.com/fnando/i18n-js/pull/638)
27
+
28
+
29
+ ## [3.9.0]
30
+
31
+ ### Added
32
+
33
+ - [Ruby] Allow to set custom locales instead of using only `I18n.available_locales`.
34
+ (PR: https://github.com/fnando/i18n-js/pull/617)
35
+
36
+
37
+ ## [3.8.4]
38
+
39
+ ### Fixed
40
+
41
+ - [Ruby] Fix proc exported to JS/JSON file(s) causing issues like git merge conflicts
42
+ (PR: https://github.com/fnando/i18n-js/pull/591)
43
+
44
+
45
+ ## [3.8.3]
46
+
47
+ ### Changed
48
+
49
+ - [Ruby] Generate translations in JS as `JSON.parse` instead of object literal for performance
50
+ (PR: https://github.com/fnando/i18n-js/pull/605)
51
+ (PR: https://github.com/fnando/i18n-js/pull/606)
52
+ (PR: https://github.com/fnando/i18n-js/pull/607)
53
+
54
+
21
55
  ## [3.8.2] - 2021-03-18
22
56
 
23
57
  ### Fixed
@@ -491,7 +525,11 @@ And today is not April Fools' Day
491
525
 
492
526
 
493
527
 
494
- [Unreleased]: https://github.com/fnando/i18n-js/compare/v3.8.2...HEAD
528
+ [Unreleased]: https://github.com/fnando/i18n-js/compare/v3.9.1...HEAD
529
+ [3.9.1]: https://github.com/fnando/i18n-js/compare/v3.9.0...v3.9.1
530
+ [3.9.0]: https://github.com/fnando/i18n-js/compare/v3.8.4...v3.9.0
531
+ [3.8.4]: https://github.com/fnando/i18n-js/compare/v3.8.3...v3.8.4
532
+ [3.8.3]: https://github.com/fnando/i18n-js/compare/v3.8.2...v3.8.3
495
533
  [3.8.2]: https://github.com/fnando/i18n-js/compare/v3.8.1...v3.8.2
496
534
  [3.8.1]: https://github.com/fnando/i18n-js/compare/v3.8.0...v3.8.1
497
535
  [3.8.0]: https://github.com/fnando/i18n-js/compare/v3.7.1...v3.8.0
data/README.md CHANGED
@@ -8,11 +8,10 @@
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://github.com/fnando/i18n-js/actions?query=workflow%3ATests"><img src="https://github.com/fnando/i18n-js/workflows/Tests/badge.svg" alt="Tests"></a>
11
- <a href="http://badge.fury.io/rb/i18n-js"><img src="http://img.shields.io/gem/v/i18n-js.svg" alt="Gem Version"></a>
11
+ <a href="https://badge.fury.io/rb/i18n-js"><img src="https://img.shields.io/gem/v/i18n-js.svg" alt="Gem Version"></a>
12
12
  <a href="https://www.npmjs.com/package/i18n-js"><img src="https://img.shields.io/npm/v/i18n-js.svg" alt="npm"></a>
13
13
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
14
- <a href="https://travis-ci.org/fnando/i18n-js"><img src="http://img.shields.io/travis/fnando/i18n-js.svg" alt="Build Status"></a>
15
- <a href="https://coveralls.io/r/fnando/i18n-js"><img src="http://img.shields.io/coveralls/fnando/i18n-js.svg" alt="Coverage Status"></a>
14
+ <a href="https://coveralls.io/r/fnando/i18n-js"><img src="https://img.shields.io/coveralls/fnando/i18n-js.svg" alt="Coverage Status"></a>
16
15
  <a href="https://gitter.im/fnando/i18n-js"><img src="https://img.shields.io/badge/gitter-join%20chat-1dce73.svg" alt="Gitter"></a>
17
16
  </p>
18
17
 
@@ -59,10 +58,10 @@ For more details, see:
59
58
  - [this gist](https://gist.github.com/bazzel/ecdff4718962e57c2d5569cf01d332fe)
60
59
  - https://github.com/fnando/i18n-js/issues/597
61
60
 
62
- #### Rails app with [Asset Pipeline](http://guides.rubyonrails.org/asset_pipeline.html)
61
+ #### Rails app with [Asset Pipeline](https://guides.rubyonrails.org/asset_pipeline.html)
63
62
 
64
63
  If you're using the
65
- [asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html), then you
64
+ [asset pipeline](https://guides.rubyonrails.org/asset_pipeline.html), then you
66
65
  must add the following line to your `app/assets/javascripts/application.js`.
67
66
 
68
67
  ```javascript
@@ -77,7 +76,7 @@ must add the following line to your `app/assets/javascripts/application.js`.
77
76
  //= require i18n/translations
78
77
  ```
79
78
 
80
- #### Rails app without [Asset Pipeline](http://guides.rubyonrails.org/asset_pipeline.html)
79
+ #### Rails app without [Asset Pipeline](https://guides.rubyonrails.org/asset_pipeline.html)
81
80
 
82
81
  First, put this in your `application.html` (layout file). Then get the JS files
83
82
  following the instructions below.
@@ -271,6 +270,17 @@ You must disable this feature by setting the option to `false`.
271
270
  To find more examples on how to use the configuration file please refer to the
272
271
  tests.
273
272
 
273
+ #### Available locales
274
+
275
+ By specifying option `js_available_locales` with a list of locales, this list
276
+ would be used instead of default `I18n.available_locales` to generate translations.
277
+
278
+ Example:
279
+
280
+ ```yaml
281
+ js_available_locales: ["de", "en"]
282
+ ```
283
+
274
284
  #### Namespace
275
285
 
276
286
  Setting the `namespace` option will change the namespace of the output
@@ -480,6 +490,8 @@ I18n.locales.no = function (locale) {
480
490
  };
481
491
  ```
482
492
 
493
+ ### Translation Missing Behaviour Control
494
+
483
495
  By default a missing translation will be displayed as
484
496
 
485
497
  [missing "name of scope" translation]
@@ -498,8 +510,10 @@ Camel case becomes lower cased text and underscores are replaced with space
498
510
 
499
511
  becomes "what is your favorite Christmas present"
500
512
 
513
+ #### Option `missingTranslationPrefix`
514
+
501
515
  In order to still detect untranslated strings, you can set
502
- `i18n.missingTranslationPrefix` to something like:
516
+ `I18n.missingTranslationPrefix` to something like:
503
517
 
504
518
  ```javascript
505
519
  I18n.missingTranslationPrefix = "EE: ";
@@ -514,14 +528,27 @@ And result will be:
514
528
 
515
529
  This will help you doing automated tests against your localisation assets.
516
530
 
517
- Some people prefer returning `null` for missing translation:
531
+ #### Customize return when translation entry missing
532
+
533
+ Some people prefer returning `null`/`undefined` for missing translation:
518
534
 
519
535
  ```javascript
520
- I18n.missingTranslation = function () {
536
+ I18n.missingTranslation = function (scope, options) {
521
537
  return undefined;
522
538
  };
523
539
  ```
524
540
 
541
+ ### Option `defaultSeparator` (global) / `separator` (local)
542
+
543
+ Default separator of translation key is `.` (dot)
544
+ Meaning `I18n.t("scope.entry")` would search for translation entry `I18n.translations[locale].scope.entry`
545
+ Using a different separator can be done either globally or locally.
546
+
547
+ Globally: `I18n.defaultSeparator = newSeparator`
548
+ Locally: `I18n.t("full_sentences|Server Busy. Please retry later", {separator: '|'})`
549
+
550
+ ### Pluralization
551
+
525
552
  Pluralization is possible as well and by default provides English rules:
526
553
 
527
554
  ```javascript
@@ -959,23 +986,26 @@ more details and discussion of this issue.
959
986
  ### JS `I18n.toCurrency` & `I18n.toNumber` cannot handle large integers
960
987
 
961
988
  The above methods use `toFixed` and it only supports 53 bit integers. Ref:
962
- http://2ality.com/2012/07/large-integers.html
989
+ https://2ality.com/2012/07/large-integers.html
963
990
 
964
991
  Feel free to find & discuss possible solution(s) at issue
965
992
  [#511](https://github.com/fnando/i18n-js/issues/511)
966
993
 
967
- ### Only works with `Simple` backend
994
+ ### May not work with all backend implementations
968
995
 
969
- If you set `I18n.backend` to something other than the default `Simple` backend,
970
- you will likely get an exception like this:
996
+ I18n backend implementations have to conform to a specific interface to work
997
+ with i18n-js. For backends that do not conform to the interface, you will likely
998
+ get an exception like this:
971
999
 
972
1000
  ```
973
1001
  Undefined method 'initialized?' for <your backend class>
974
1002
  ```
975
1003
 
976
- For now, i18n-js is only compatible with the `Simple` backend. If you need a
977
- more sophisticated backend for your rails application, like
978
- `I18n::Backend::ActiveRecord`, you can setup i18n-js to get translations from a
1004
+ For now, i18n-js is compatible with the `Simple` backend and with
1005
+ `I18n::Backend::ActiveRecord` (>= 0.4.0).
1006
+
1007
+ If you need a more sophisticated backend for your rails application that doesn't
1008
+ implement the required methods, you can setup i18n-js to get translations from a
979
1009
  separate `Simple` backend, by adding the following in an initializer:
980
1010
 
981
1011
  ```ruby
@@ -1014,18 +1044,18 @@ and discussion of this issue.
1014
1044
 
1015
1045
  ## Maintainer
1016
1046
 
1017
- - Nando Vieira - <http://nandovieira.com>
1047
+ - Nando Vieira - <https://nandovieira.com>
1018
1048
 
1019
1049
  ## Contributing
1020
1050
 
1021
1051
  Once you've made your great commits:
1022
1052
 
1023
- 1. [Fork](http://help.github.com/forking/) I18n.js
1053
+ 1. [Fork](https://help.github.com/forking/) I18n.js
1024
1054
  2. Create a branch with a clear name
1025
1055
  3. Make your changes (Please also add/change spec, README and CHANGELOG if
1026
1056
  applicable)
1027
1057
  4. Push changes to the created branch
1028
- 5. [Create an Pull Request](http://github.com/fnando/i18n-js/pulls)
1058
+ 5. [Create an Pull Request](https://github.com/fnando/i18n-js/pulls)
1029
1059
  6. That's it!
1030
1060
 
1031
1061
  Please respect the indentation rules and code style. And use 2 spaces, not tabs.
@@ -33,7 +33,7 @@ if (!Array.prototype.indexOf) {
33
33
  }
34
34
 
35
35
  // Production steps of ECMA-262, Edition 5, 15.4.4.18
36
- // Reference: http://es5.github.com/#x15.4.4.18
36
+ // Reference: https://es5.github.com/#x15.4.4.18
37
37
  // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
38
38
  if ( !Array.prototype.forEach ) {
39
39
 
@@ -53,7 +53,7 @@ if ( !Array.prototype.forEach ) {
53
53
  var len = O.length >>> 0; // Hack to convert O.length to a UInt32
54
54
 
55
55
  // 4. If IsCallable(callback) is false, throw a TypeError exception.
56
- // See: http://es5.github.com/#x9.11
56
+ // See: https://es5.github.com/#x9.11
57
57
  if ( {}.toString.call(callback) !== "[object Function]" ) {
58
58
  throw new TypeError( callback + " is not a function" );
59
59
  }
@@ -139,7 +139,7 @@ if (!Array.prototype.map) {
139
139
  var len = O.length >>> 0;
140
140
 
141
141
  // 4. If IsCallable(callback) is false, throw a TypeError exception.
142
- // See: http://es5.github.com/#x9.11
142
+ // See: https://es5.github.com/#x9.11
143
143
  if (typeof callback !== 'function') {
144
144
  throw new TypeError(callback + ' is not a function');
145
145
  }
@@ -269,23 +269,23 @@
269
269
  }
270
270
 
271
271
  // Locale code format 1:
272
- // According to RFC4646 (http://www.ietf.org/rfc/rfc4646.txt)
272
+ // According to RFC4646 (https://www.ietf.org/rfc/rfc4646.txt)
273
273
  // language codes for Traditional Chinese should be `zh-Hant`
274
274
  //
275
275
  // But due to backward compatibility
276
276
  // We use older version of IETF language tag
277
- // @see http://www.w3.org/TR/html401/struct/dirlang.html
278
- // @see http://en.wikipedia.org/wiki/IETF_language_tag
277
+ // @see https://www.w3.org/TR/html401/struct/dirlang.html
278
+ // @see https://en.wikipedia.org/wiki/IETF_language_tag
279
279
  //
280
280
  // Format: `language-code = primary-code ( "-" subcode )*`
281
281
  //
282
282
  // primary-code uses ISO639-1
283
- // @see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
284
- // @see http://www.iso.org/iso/home/standards/language_codes.htm
283
+ // @see https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
284
+ // @see https://www.iso.org/iso/home/standards/language_codes.htm
285
285
  //
286
286
  // subcode uses ISO 3166-1 alpha-2
287
- // @see http://en.wikipedia.org/wiki/ISO_3166
288
- // @see http://www.iso.org/iso/country_codes.htm
287
+ // @see https://en.wikipedia.org/wiki/ISO_3166
288
+ // @see https://www.iso.org/iso/country_codes.htm
289
289
  //
290
290
  // @note
291
291
  // subcode can be in upper case or lower case
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.9.0"
6
+
7
+ gemspec path: "../"
data/i18n-js.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Nando Vieira"]
10
10
  s.email = ["fnando.vieira@gmail.com"]
11
- s.homepage = "http://rubygems.org/gems/i18n-js"
11
+ s.homepage = "https://rubygems.org/gems/i18n-js"
12
12
  s.summary = "It's a small library to provide the Rails I18n translations on the Javascript."
13
13
  s.description = s.summary
14
14
  s.license = "MIT"
@@ -18,7 +18,7 @@ module I18n
18
18
  # Call this in an initializer
19
19
  def using_asset_pipeline?
20
20
  assets_pipeline_available =
21
- (rails3? || rails4? || rails5? || rails6?) &&
21
+ (rails3? || rails4? || rails5? || rails6? || rails7?) &&
22
22
  Rails.respond_to?(:application) &&
23
23
  Rails.application.config.respond_to?(:assets)
24
24
  rails3_assets_enabled =
@@ -26,7 +26,7 @@ module I18n
26
26
  assets_pipeline_available &&
27
27
  Rails.application.config.assets.enabled != false
28
28
 
29
- assets_pipeline_available && (rails4? || rails5? || rails6? || rails3_assets_enabled)
29
+ assets_pipeline_available && (rails4? || rails5? || rails6? || rails7? || rails3_assets_enabled)
30
30
  end
31
31
 
32
32
  private
@@ -46,6 +46,10 @@ module I18n
46
46
  def rails6?
47
47
  rails? && Rails.version.to_i == 6
48
48
  end
49
+
50
+ def rails7?
51
+ rails? && Rails.version.to_i == 7
52
+ end
49
53
 
50
54
  def safe_gem_check(*args)
51
55
  if Gem::Specification.respond_to?(:find_by_name)
@@ -21,7 +21,7 @@ module I18n
21
21
  # https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb
22
22
  #
23
23
  # Finisher hook is the place which should be used as border.
24
- # http://guides.rubyonrails.org/configuring.html#initializers
24
+ # https://guides.rubyonrails.org/configuring.html#initializers
25
25
  #
26
26
  # For detail see Pull Request:
27
27
  # https://github.com/fnando/i18n-js/pull/371
@@ -4,6 +4,12 @@ module I18n
4
4
  module JS
5
5
  module Formatters
6
6
  class JS < Base
7
+ JSON_ESCAPE_MAP = {
8
+ "'" => "\\'",
9
+ "\\" => "\\\\"
10
+ }.freeze
11
+ private_constant :JSON_ESCAPE_MAP
12
+
7
13
  def format(translations)
8
14
  contents = header
9
15
  translations.each do |locale, translations_for_locale|
@@ -20,10 +26,11 @@ module I18n
20
26
  end
21
27
 
22
28
  def line(locale, translations)
29
+ json_literal = @pretty_print ? translations : %(JSON.parse('#{translations.gsub(/#{Regexp.union(JSON_ESCAPE_MAP.keys)}/){|match| JSON_ESCAPE_MAP.fetch(match) }}'))
23
30
  if @js_extend
24
- %(#{@namespace}.translations["#{locale}"] = I18n.extend((#{@namespace}.translations["#{locale}"] || {}), #{translations});\n)
31
+ %(#{@namespace}.translations["#{locale}"] = I18n.extend((#{@namespace}.translations["#{locale}"] || {}), #{json_literal});\n)
25
32
  else
26
- %(#{@namespace}.translations["#{locale}"] = #{translations};\n)
33
+ %(#{@namespace}.translations["#{locale}"] = #{json_literal};\n)
27
34
  end
28
35
  end
29
36
  end
@@ -33,7 +33,7 @@ module I18n
33
33
  # Saves JSON file containing translations
34
34
  def save!
35
35
  if @file =~ LOCALE_INTERPOLATOR
36
- I18n.available_locales.each do |locale|
36
+ I18n::JS.js_available_locales.each do |locale|
37
37
  write_file(file_for_locale(locale), @translations.slice(locale))
38
38
  end
39
39
  else
@@ -50,6 +50,7 @@ module I18n
50
50
  def write_file(_file = @file, _translations = @translations)
51
51
  FileUtils.mkdir_p File.dirname(_file)
52
52
  _translations = Utils.deep_key_sort(_translations) if @sort_translation_keys
53
+ _translations = Utils.deep_remove_procs(_translations)
53
54
  contents = formatter.format(_translations)
54
55
 
55
56
  return if File.exist?(_file) && File.read(_file) == contents
data/lib/i18n/js/utils.rb CHANGED
@@ -3,7 +3,7 @@ module I18n
3
3
  module Utils
4
4
  PLURAL_KEYS = %i[zero one two few many other].freeze
5
5
 
6
- # Based on deep_merge by Stefan Rusterholz, see <http://www.ruby-forum.com/topic/142809>.
6
+ # Based on deep_merge by Stefan Rusterholz, see <https://www.ruby-forum.com/topic/142809>.
7
7
  # This method is used to handle I18n fallbacks. Given two equivalent path nodes in two locale trees:
8
8
  # 1. If the node in the current locale appears to be an I18n pluralization (:one, :other, etc.),
9
9
  # use the node, but merge in any missing/non-nil keys from the fallback (default) locale.
@@ -73,6 +73,19 @@ module I18n
73
73
  seed[key] = value.is_a?(Hash) ? deep_key_sort(value) : value
74
74
  end
75
75
  end
76
+
77
+ def self.deep_remove_procs(hash)
78
+ # procs exist in `i18n.plural.rule` as pluralizer
79
+ # But having it in translation causes the exported JS/JSON changes every time
80
+ # https://github.com/ruby-i18n/i18n/blob/v1.8.7/lib/i18n/backend/pluralization.rb#L51
81
+ hash.keys.
82
+ each_with_object({}) do |key, seed|
83
+ value = hash[key]
84
+ next if value.is_a?(Proc)
85
+
86
+ seed[key] = value.is_a?(Hash) ? deep_remove_procs(value) : value
87
+ end
88
+ end
76
89
  end
77
90
  end
78
91
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module JS
5
- VERSION = "3.8.2"
5
+ VERSION = "3.9.1"
6
6
  end
7
7
  end
data/lib/i18n/js.rb CHANGED
@@ -81,7 +81,7 @@ module I18n
81
81
 
82
82
  # deep_merge! given result with result for fallback locale
83
83
  def self.merge_with_fallbacks!(result)
84
- I18n.available_locales.each do |locale|
84
+ js_available_locales.each do |locale|
85
85
  fallback_locales = FallbackLocales.new(fallbacks, locale)
86
86
  fallback_locales.each do |fallback_locale|
87
87
  # `result[fallback_locale]` could be missing
@@ -183,7 +183,7 @@ module I18n
183
183
  #
184
184
  # So the input is wrapped by our class for better `#slice`
185
185
  Private::HashWithSymbolKeys.new(translations).
186
- slice(*::I18n.available_locales).
186
+ slice(*::I18n::JS.js_available_locales).
187
187
  to_h
188
188
  end
189
189
  end
@@ -213,6 +213,16 @@ module I18n
213
213
  end
214
214
  end
215
215
 
216
+ # Get all available locales.
217
+ #
218
+ # @return [Array<Symbol>] the locales.
219
+ def self.js_available_locales
220
+ config.fetch(:js_available_locales) do
221
+ # default value
222
+ I18n.available_locales
223
+ end.map(&:to_sym)
224
+ end
225
+
216
226
  def self.sort_translation_keys?
217
227
  @sort_translation_keys ||= (config[:sort_translation_keys]) if config.key?(:sort_translation_keys)
218
228
  @sort_translation_keys = true if @sort_translation_keys.nil?
data/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "i18n"
9
9
  ],
10
10
  "devDependencies": {
11
- "jasmine-node": "^1.14.5"
11
+ "jasmine-node": "^3.0.0"
12
12
  },
13
13
  "main": "app/assets/javascripts/i18n.js",
14
14
  "scripts": {
@@ -0,0 +1 @@
1
+ js_available_locales: ["en", "foo"]
@@ -0,0 +1,14 @@
1
+ describe("JSON.parse", function () {
2
+ it('should parse', function () {
3
+ expect(JSON.parse('{"a":"Test\'s"}')).toEqual({
4
+ a: "Test's"
5
+ })
6
+
7
+ expect(JSON.parse('{"a":"say \\"hello\\""}')).toEqual({
8
+ a: 'say "hello"'
9
+ });
10
+ expect(JSON.parse('{"double-backslash-in-double-quote":"\\"\\\\\\\\\\""}')).toEqual({
11
+ 'double-backslash-in-double-quote': '"\\\\"'
12
+ });
13
+ })
14
+ })
data/spec/js/require.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /** vim: et:ts=4:sw=4:sts=4
2
2
  * @license RequireJS 2.1.16 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
3
3
  * Available via the MIT or new BSD license.
4
- * see: http://github.com/jrburke/requirejs for details
4
+ * see: https://github.com/jrburke/requirejs for details
5
5
  */
6
6
  //Not using strict: uneven strict support in browsers, #392, and causes
7
7
  //problems with requirejs.exec()/transpiler plugins that may not be strict.
@@ -163,7 +163,7 @@ var requirejs, require, define;
163
163
  * @returns {Error}
164
164
  */
165
165
  function makeError(id, msg, err, requireModules) {
166
- var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
166
+ var e = new Error(msg + '\nhttps://requirejs.org/docs/errors.html#' + id);
167
167
  e.requireType = id;
168
168
  e.requireModules = requireModules;
169
169
  if (err) {
@@ -1810,7 +1810,7 @@ var requirejs, require, define;
1810
1810
  head = s.head = document.getElementsByTagName('head')[0];
1811
1811
  //If BASE tag is in play, using appendChild is a problem for IE6.
1812
1812
  //When that browser dies, this can be removed. Details in this jQuery bug:
1813
- //http://dev.jquery.com/ticket/2709
1813
+ //https://dev.jquery.com/ticket/2709
1814
1814
  baseElement = document.getElementsByTagName('base')[0];
1815
1815
  if (baseElement) {
1816
1816
  head = s.head = baseElement.parentNode;
@@ -1829,7 +1829,7 @@ var requirejs, require, define;
1829
1829
  */
1830
1830
  req.createNode = function (config, moduleName, url) {
1831
1831
  var node = config.xhtml ?
1832
- document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
1832
+ document.createElementNS('https://www.w3.org/1999/xhtml', 'html:script') :
1833
1833
  document.createElement('script');
1834
1834
  node.type = config.scriptType || 'text/javascript';
1835
1835
  node.charset = 'utf-8';
@@ -131,8 +131,8 @@ EOS
131
131
 
132
132
  expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
133
133
  MyNamespace.translations || (MyNamespace.translations = {});
134
- MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"test":"Test"});
135
- MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), {"test":"Test2"});
134
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"test":"Test"}'));
135
+ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), JSON.parse('{"test":"Test2"}'));
136
136
  EOF
137
137
  end
138
138
  end
@@ -146,12 +146,54 @@ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] ||
146
146
 
147
147
  expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
148
148
  MyNamespace.translations || (MyNamespace.translations = {});
149
- MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"test":"Test"});
149
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"test":"Test"}'));
150
150
  EOF
151
151
 
152
152
  expect(File.open(File.join(temp_path, "fr.js")){|f| f.read}).to eql <<-EOF
153
153
  MyNamespace.translations || (MyNamespace.translations = {});
154
- MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), {"test":"Test2"});
154
+ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), JSON.parse('{"test":"Test2"}'));
155
+ EOF
156
+ end
157
+ end
158
+
159
+ context "when file includes single quote" do
160
+ let(:file){ "tmp/i18n-js/%{locale}.js" }
161
+ let(:translations){ { en: { "a" => "Test's" } } }
162
+
163
+ it "should write files" do
164
+ file_should_exist "en.js"
165
+
166
+ expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
167
+ MyNamespace.translations || (MyNamespace.translations = {});
168
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"Test\\'s"}'));
169
+ EOF
170
+ end
171
+ end
172
+
173
+ context "when file includes escaped double quote" do
174
+ let(:file){ "tmp/i18n-js/%{locale}.js" }
175
+ let(:translations){ { en: { "a" => 'say "hello"' } } }
176
+
177
+ it "should escape double quote" do
178
+ file_should_exist "en.js"
179
+
180
+ expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
181
+ MyNamespace.translations || (MyNamespace.translations = {});
182
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"say \\\\"hello\\\\""}'));
183
+ EOF
184
+ end
185
+ end
186
+
187
+ context "when file includes backslash in double quote" do
188
+ let(:file){ "tmp/i18n-js/%{locale}.js" }
189
+ let(:translations){ { en: { "double-backslash-in-double-quote" => '"\\\\"' } } }
190
+
191
+ it "should escape backslash" do
192
+ file_should_exist "en.js"
193
+
194
+ expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
195
+ MyNamespace.translations || (MyNamespace.translations = {});
196
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"double-backslash-in-double-quote":"\\\\"\\\\\\\\\\\\\\\\\\\\""}'));
155
197
  EOF
156
198
  end
157
199
  end
@@ -166,7 +208,7 @@ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] ||
166
208
 
167
209
  expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
168
210
  MyNamespace.translations || (MyNamespace.translations = {});
169
- MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"a":"Test","b":"Test"});
211
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"Test","b":"Test"}'));
170
212
  EOF
171
213
  end
172
214
  end
@@ -181,7 +223,7 @@ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] ||
181
223
 
182
224
  expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
183
225
  MyNamespace.translations || (MyNamespace.translations = {});
184
- MyNamespace.translations["en"] = {"a":"Test","b":"Test"};
226
+ MyNamespace.translations["en"] = JSON.parse('{"a":"Test","b":"Test"}');
185
227
  EOF
186
228
  end
187
229
  end
@@ -196,7 +238,7 @@ MyNamespace.translations["en"] = {"a":"Test","b":"Test"};
196
238
 
197
239
  expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
198
240
  MyNamespace.translations || (MyNamespace.translations = {});
199
- MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"a":"Test","b":"Test"});
241
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"Test","b":"Test"}'));
200
242
  EOF
201
243
  end
202
244
  end
@@ -211,7 +253,32 @@ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] ||
211
253
 
212
254
  expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
213
255
  MyNamespace.translations || (MyNamespace.translations = {});
214
- MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"b":"Test","a":"Test"});
256
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"b":"Test","a":"Test"}'));
257
+ EOF
258
+ end
259
+ end
260
+
261
+ context "when translation entries contain procs" do
262
+ let(:translations) do
263
+ {
264
+ en: {
265
+ "test" => "Test",
266
+ "i18n" => {"plural" => {"rule" => proc {} }},
267
+ },
268
+ fr: {
269
+ "test" => "Test2",
270
+ "i18n" => {"plural" => {"rule" => proc {} }},
271
+ },
272
+ }
273
+ end
274
+
275
+ it "should write files without procs or their string representations" do
276
+ file_should_exist "segment.js"
277
+
278
+ expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
279
+ MyNamespace.translations || (MyNamespace.translations = {});
280
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"i18n":{"plural":{}},"test":"Test"}'));
281
+ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), JSON.parse('{"i18n":{"plural":{}},"test":"Test2"}'));
215
282
  EOF
216
283
  end
217
284
  end
@@ -103,4 +103,36 @@ describe I18n::JS::Utils do
103
103
  expect(described_class.scopes_match?([:a, :b, :c], [:a, '*', '*'])).to eql true
104
104
  end
105
105
  end
106
+
107
+ describe ".deep_remove_procs" do
108
+ let(:proc_obj) { proc {} }
109
+ let(:hash_with_proc) do
110
+ {
111
+ :a => :b,
112
+ :c => proc_obj,
113
+ :d => {
114
+ :e => proc_obj,
115
+ :f => :g,
116
+ }
117
+ }
118
+ end
119
+ subject { described_class.deep_remove_procs(hash_with_proc) }
120
+
121
+ it "performs a deep keys sort without changing the original hash" do
122
+ should eql({
123
+ :a => :b,
124
+ :d => {
125
+ :f => :g,
126
+ }
127
+ })
128
+ expect(hash_with_proc).to eql({
129
+ :a => :b,
130
+ :c => proc_obj,
131
+ :d => {
132
+ :e => proc_obj,
133
+ :f => :g,
134
+ }
135
+ })
136
+ end
137
+ end
106
138
  end
@@ -67,13 +67,13 @@ describe I18n::JS do
67
67
  en_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "en.js"))
68
68
  expect(en_output).to eq(<<EOS
69
69
  I18n.translations || (I18n.translations = {});
70
- I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), {"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]}});
70
+ I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), JSON.parse('{"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]}}'));
71
71
  EOS
72
72
  )
73
73
  fr_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "fr.js"))
74
74
  expect(fr_output).to eq(<<EOS
75
75
  I18n.translations || (I18n.translations = {});
76
- I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), {"admin":{"edit":{"title":"Editer"},"show":{"note":"plus de détails","title":"Visualiser"}},"date":{"abbr_day_names":["dim","lun","mar","mer","jeu","ven","sam"],"abbr_month_names":[null,"jan.","fév.","mar.","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],"day_names":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"},"month_names":[null,"janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"]}});
76
+ I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), JSON.parse('{"admin":{"edit":{"title":"Editer"},"show":{"note":"plus de détails","title":"Visualiser"}},"date":{"abbr_day_names":["dim","lun","mar","mer","jeu","ven","sam"],"abbr_month_names":[null,"jan.","fév.","mar.","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],"day_names":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"},"month_names":[null,"janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"]}}'));
77
77
  EOS
78
78
  )
79
79
  end
@@ -98,13 +98,13 @@ EOS
98
98
  en_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "bits.en.js"))
99
99
  expect(en_output).to eq(<<EOS
100
100
  I18n.translations || (I18n.translations = {});
101
- I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), {"date":{"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"}},"number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}}}});
101
+ I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), JSON.parse('{"date":{"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"}},"number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}}}}'));
102
102
  EOS
103
103
  )
104
104
  fr_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "bits.fr.js"))
105
105
  expect(fr_output).to eq(<<EOS
106
106
  I18n.translations || (I18n.translations = {});
107
- I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), {"date":{"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"}},"number":{"currency":{"format":{"format":"%n %u","precision":2,"unit":"€"}}}});
107
+ I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), JSON.parse('{"date":{"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"}},"number":{"currency":{"format":{"format":"%n %u","precision":2,"unit":"€"}}}}'));
108
108
  EOS
109
109
  )
110
110
  end
@@ -307,21 +307,30 @@ EOS
307
307
  expect(subject[:de][:null_test]).to eql(nil)
308
308
  end
309
309
 
310
- context "when given locale is in `I18n.available_locales` but its translation is missing" do
310
+ context 'when given locale is in `I18n.available_locales` but its translation is missing' do
311
311
  subject { translations[:fr][:fallback_test] }
312
312
 
313
- let(:new_locale) { :pirate }
314
- let!(:old_available_locales) { I18n.config.available_locales }
315
- let!(:new_available_locales) { I18n.config.available_locales + [new_locale] }
313
+ let(:available_locales) { %i[fr pirate] }
314
+
316
315
  before do
317
- I18n.config.available_locales = new_available_locales
318
- set_config "js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml"
316
+ allow(::I18n).to receive(:available_locales).and_return(available_locales)
317
+ set_config 'js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml'
319
318
  end
320
- after do
321
- I18n.config.available_locales = old_available_locales
319
+
320
+ it { should eql(nil) }
321
+ end
322
+
323
+ context 'when given locale is in `.js_available_locales` but its translation is missing' do
324
+ subject { translations[:fr][:fallback_test] }
325
+
326
+ let(:available_locales) { %i[fr pirate] }
327
+
328
+ before do
329
+ allow(described_class).to receive(:js_available_locales).and_return(available_locales)
330
+ set_config 'js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml'
322
331
  end
323
332
 
324
- it {should eql(nil)}
333
+ it { should eql(nil) }
325
334
  end
326
335
 
327
336
  context "with I18n::Fallbacks enabled" do
@@ -385,27 +394,67 @@ EOS
385
394
  end
386
395
  end
387
396
 
388
- context "I18n.available_locales" do
397
+ describe '.js_available_locales' do
398
+ subject { described_class.js_available_locales }
399
+
400
+ let(:results) { described_class.scoped_translations('*.admin.*.title') }
401
+ let(:result) { ->(locale) { results[locale][:admin][:show][:title] } }
389
402
 
390
- context "when I18n.available_locales is not set" do
391
- it "should allow all locales" do
392
- result = I18n::JS.scoped_translations("*.admin.*.title")
403
+ context 'when I18n.available_locales is not set' do
404
+ it { expect(subject).to eq ::I18n.available_locales }
393
405
 
394
- expect(result[:en][:admin][:show][:title]).to eql("Show")
395
- expect(result[:fr][:admin][:show][:title]).to eql("Visualiser")
396
- expect(result[:ja][:admin][:show][:title]).to eql("Ignore me")
406
+ it 'should allow all locales' do
407
+ expect(result.call(:en)).to eql('Show')
408
+ expect(result.call(:fr)).to eql('Visualiser')
409
+ expect(result.call(:ja)).to eql('Ignore me')
397
410
  end
398
411
  end
399
412
 
400
- context "when I18n.available_locales is set" do
401
- before { allow(::I18n).to receive(:available_locales){ [:en, :fr] } }
413
+ context 'when I18n.available_locales is set' do
414
+ let(:available_locales) { %i[en fr] }
415
+
416
+ before { allow(::I18n).to receive(:available_locales).and_return(available_locales) }
417
+
418
+ it { expect(subject).to eq available_locales }
419
+
420
+ it 'should ignore non-valid locales' do
421
+ expect(result.call(:en)).to eql('Show')
422
+ expect(result.call(:fr)).to eql('Visualiser')
423
+ expect(results).not_to include(:ja)
424
+ end
425
+
426
+ context 'when :js_available_locales set in config' do
427
+ before { set_config 'js_available_locales_custom.yml' }
402
428
 
403
- it "should ignore non-valid locales" do
404
- result = I18n::JS.scoped_translations("*.admin.*.title")
429
+ it { expect(subject).to eq %i[en foo] }
430
+
431
+ it 'should ignore non-valid locales' do
432
+ expect(result.call(:en)).to eql('Show')
433
+ expect(results).not_to include(:fr, :ja)
434
+ end
435
+ end
436
+ end
437
+ end
438
+
439
+ context 'I18n.available_locales' do
440
+ let(:results) { described_class.scoped_translations('*.admin.*.title') }
441
+ let(:result) { ->(locale) { results[locale][:admin][:show][:title] } }
442
+
443
+ context 'when I18n.available_locales is not set' do
444
+ it 'should allow all locales' do
445
+ expect(result.call(:en)).to eql('Show')
446
+ expect(result.call(:fr)).to eql('Visualiser')
447
+ expect(result.call(:ja)).to eql('Ignore me')
448
+ end
449
+ end
450
+
451
+ context 'when I18n.available_locales is set' do
452
+ before { allow(::I18n).to receive(:available_locales){ [:en, :fr] } }
405
453
 
406
- expect(result[:en][:admin][:show][:title]).to eql("Show")
407
- expect(result[:fr][:admin][:show][:title]).to eql("Visualiser")
408
- expect(result.keys.include?(:ja)).to eql(false)
454
+ it 'should ignore non-valid locales' do
455
+ expect(result.call(:en)).to eql('Show')
456
+ expect(result.call(:fr)).to eql('Visualiser')
457
+ expect(results).not_to include(:ja)
409
458
  end
410
459
  end
411
460
  end
@@ -599,7 +648,7 @@ EOS
599
648
  it "exports with the keys sorted" do
600
649
  expect(subject).to eq <<EOS
601
650
  I18n.translations || (I18n.translations = {});
602
- I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), {"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]},"fallback_test":"Success","foo":"Foo","merge_plurals":{"one":"Apple","other":"Apples"},"merge_plurals_with_no_overrides":{"one":"Apple","other":"Apples","zero":"No Apple"},"merge_plurals_with_partial_overrides":{"one":"Cat","other":"Cats"},"null_test":"fallback for null","number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}},"format":{"delimiter":",","precision":3,"separator":"."},"human":{"decimal_units":{"units":{"million":"Million"}}}},"time":{"am":"am","formats":{"default":"%a, %d %b %Y %H:%M:%S %z","long":"%B %d, %Y %H:%M","short":"%d %b %H:%M"},"pm":"pm"}});
651
+ I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), JSON.parse('{"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]},"fallback_test":"Success","foo":"Foo","merge_plurals":{"one":"Apple","other":"Apples"},"merge_plurals_with_no_overrides":{"one":"Apple","other":"Apples","zero":"No Apple"},"merge_plurals_with_partial_overrides":{"one":"Cat","other":"Cats"},"null_test":"fallback for null","number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}},"format":{"delimiter":",","precision":3,"separator":"."},"human":{"decimal_units":{"units":{"million":"Million"}}}},"time":{"am":"am","formats":{"default":"%a, %d %b %Y %H:%M:%S %z","long":"%B %d, %Y %H:%M","short":"%d %b %H:%M"},"pm":"pm"}}'));
603
652
  EOS
604
653
  end
605
654
  end
@@ -628,13 +677,13 @@ EOS
628
677
 
629
678
  expect(subject).to eq <<EOS
630
679
  I18n.translations || (I18n.translations = {});
631
- I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
632
- I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
633
- I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
634
- I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":{\"one\":\"millón\",\"other\":\"millones\"}}}}}});
635
- I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
636
- I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
637
- I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
680
+ I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
681
+ I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
682
+ I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
683
+ I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":{\"one\":\"millón\",\"other\":\"millones\"}}}}}}'));
684
+ I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
685
+ I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
686
+ I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
638
687
  EOS
639
688
  end
640
689
  end
@@ -648,8 +697,8 @@ EOS
648
697
  output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "js_extend_parent.js"))
649
698
  expect(output).to eq(<<EOS
650
699
  I18n.translations || (I18n.translations = {});
651
- I18n.translations[\"en\"] = {\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}};
652
- I18n.translations[\"fr\"] = {\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}};
700
+ I18n.translations[\"en\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}}');
701
+ I18n.translations[\"fr\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}}');
653
702
  EOS
654
703
  )
655
704
  end
@@ -663,8 +712,8 @@ EOS
663
712
  output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "js_extend_segment.js"))
664
713
  expect(output).to eq(<<EOS
665
714
  I18n.translations || (I18n.translations = {});
666
- I18n.translations[\"en\"] = {\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}};
667
- I18n.translations[\"fr\"] = {\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}};
715
+ I18n.translations[\"en\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}}');
716
+ I18n.translations[\"fr\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}}');
668
717
  EOS
669
718
  )
670
719
  end
@@ -686,7 +735,7 @@ EOS
686
735
 
687
736
  expect(subject).to eq <<EOS
688
737
  I18n.translations || (I18n.translations = {});
689
- I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals\":{\"one\":\"Apple\",\"other\":\"Apples\"}});\nI18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals\":{\"one\":\"Pomme\",\"other\":\"Pommes\",\"zero\":\"Pomme\"}});
738
+ I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals\":{\"one\":\"Apple\",\"other\":\"Apples\"}}'));\nI18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals\":{\"one\":\"Pomme\",\"other\":\"Pommes\",\"zero\":\"Pomme\"}}'));
690
739
  EOS
691
740
  end
692
741
  end
@@ -707,13 +756,13 @@ EOS
707
756
 
708
757
  expect(subject).to eq <<EOS
709
758
  I18n.translations || (I18n.translations = {});
710
- I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
711
- I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
712
- I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
713
- I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
714
- I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
715
- I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
716
- I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"merge_plurals_with_no_overrides\":{\"few\":\"кошек\",\"many\":\"кошка\",\"one\":\"кот\",\"other\":\"кошек\"}});
759
+ I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
760
+ I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
761
+ I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
762
+ I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
763
+ I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
764
+ I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
765
+ I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"few\":\"кошек\",\"many\":\"кошка\",\"one\":\"кот\",\"other\":\"кошек\"}}'));
717
766
  EOS
718
767
  end
719
768
  end
@@ -735,13 +784,13 @@ EOS
735
784
 
736
785
  expect(subject).to eq <<EOS
737
786
  I18n.translations || (I18n.translations = {});
738
- I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
739
- I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
740
- I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"few\":null,\"many\":null,\"one\":\"Cat\",\"other\":\"Cats\"}});
741
- I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
742
- I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
743
- I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
744
- I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
787
+ I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
788
+ I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
789
+ I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"few\":null,\"many\":null,\"one\":\"Cat\",\"other\":\"Cats\"}}'));
790
+ I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
791
+ I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
792
+ I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
793
+ I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
745
794
  EOS
746
795
  end
747
796
  end
data/yarn.lock CHANGED
@@ -13,9 +13,10 @@ brace-expansion@^1.1.7:
13
13
  balanced-match "^1.0.0"
14
14
  concat-map "0.0.1"
15
15
 
16
- coffeescript@>=1.0.1:
17
- version "2.3.1"
18
- resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.3.1.tgz#a25f69c251d25805c9842e57fc94bfc453ef6aed"
16
+ coffeescript@~1.12.7:
17
+ version "1.12.7"
18
+ resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27"
19
+ integrity sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA==
19
20
 
20
21
  concat-map@0.0.1:
21
22
  version "0.0.1"
@@ -50,9 +51,10 @@ globule@^1.0.0:
50
51
  lodash "~4.17.10"
51
52
  minimatch "~3.0.2"
52
53
 
53
- growl@^1.10.2:
54
+ growl@^1.10.5:
54
55
  version "1.10.5"
55
56
  resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
57
+ integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
56
58
 
57
59
  inflight@^1.0.4:
58
60
  version "1.0.6"
@@ -65,24 +67,26 @@ inherits@2:
65
67
  version "2.0.3"
66
68
  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
67
69
 
68
- jasmine-growl-reporter@~1.0.1:
69
- version "1.0.1"
70
- resolved "https://registry.yarnpkg.com/jasmine-growl-reporter/-/jasmine-growl-reporter-1.0.1.tgz#375306cef1fbf6357ad7913ca0358aa2285d6d39"
70
+ jasmine-growl-reporter@~2.0.0:
71
+ version "2.0.0"
72
+ resolved "https://registry.yarnpkg.com/jasmine-growl-reporter/-/jasmine-growl-reporter-2.0.0.tgz#4943a2481193d66a8a68ee2f38b6c360fb037859"
73
+ integrity sha512-RYwVfPaGgxQQSHDOt6jQ99/KAkFQ/Fiwg/AzBS+uO9A4UhGhxb7hwXaUUSU/Zs0MxBoFNqmIRC+7P4/+5O3lXg==
71
74
  dependencies:
72
- growl "^1.10.2"
75
+ growl "^1.10.5"
73
76
 
74
- jasmine-node@^1.14.5:
75
- version "1.15.0"
76
- resolved "https://registry.yarnpkg.com/jasmine-node/-/jasmine-node-1.15.0.tgz#d5e9a92623c111f55e4b83ff2ab0407ddbc2a5b7"
77
+ jasmine-node@^3.0.0:
78
+ version "3.0.0"
79
+ resolved "https://registry.yarnpkg.com/jasmine-node/-/jasmine-node-3.0.0.tgz#f12b6fdd24633402ec23e8ea6fef6ffbcb464f90"
80
+ integrity sha512-vUa5Q7bQYwHHqi6FlJYndiKqZp+d+c3MKe0QUMwwrC4JRmoRV3zkg0buxB/uQ6qLh0NO34TNstpAnvaZ6xGlAA==
77
81
  dependencies:
78
- coffeescript ">=1.0.1"
82
+ coffeescript "~1.12.7"
79
83
  gaze "~1.1.2"
80
- jasmine-growl-reporter "~1.0.1"
84
+ jasmine-growl-reporter "~2.0.0"
81
85
  jasmine-reporters "~1.0.0"
82
86
  mkdirp "~0.3.5"
83
- requirejs ">=0.27.1"
84
- underscore ">= 1.3.1"
85
- walkdir ">= 0.0.1"
87
+ requirejs "~2.3.6"
88
+ underscore "~1.9.1"
89
+ walkdir "~0.0.12"
86
90
 
87
91
  jasmine-reporters@~1.0.0:
88
92
  version "1.0.2"
@@ -91,8 +95,8 @@ jasmine-reporters@~1.0.0:
91
95
  mkdirp "~0.3.5"
92
96
 
93
97
  lodash@~4.17.10:
94
- version "4.17.20"
95
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
98
+ version "4.17.21"
99
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
96
100
 
97
101
  minimatch@^3.0.4, minimatch@~3.0.2:
98
102
  version "3.0.4"
@@ -114,17 +118,20 @@ path-is-absolute@^1.0.0:
114
118
  version "1.0.1"
115
119
  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
116
120
 
117
- requirejs@>=0.27.1:
118
- version "2.3.5"
119
- resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.5.tgz#617b9acbbcb336540ef4914d790323a8d4b861b0"
121
+ requirejs@~2.3.6:
122
+ version "2.3.6"
123
+ resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9"
124
+ integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==
120
125
 
121
- "underscore@>= 1.3.1":
122
- version "1.9.1"
123
- resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
126
+ underscore@~1.9.1:
127
+ version "1.9.2"
128
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.2.tgz#0c8d6f536d6f378a5af264a72f7bec50feb7cf2f"
129
+ integrity sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==
124
130
 
125
- "walkdir@>= 0.0.1":
131
+ walkdir@~0.0.12:
126
132
  version "0.0.12"
127
133
  resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.12.tgz#2f24f1ade64aab1e458591d4442c8868356e9281"
134
+ integrity sha512-HFhaD4mMWPzFSqhpyDG48KDdrjfn409YQuVW7ckZYhW4sE87mYtWifdB/+73RA7+p4s4K18n5Jfx1kHthE1gBw==
128
135
 
129
136
  wrappy@1:
130
137
  version "1.0.2"
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.8.2
4
+ version: 3.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-18 00:00:00.000000000 Z
11
+ date: 2022-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -128,6 +128,7 @@ files:
128
128
  - gemfiles/i18n_1_6.gemfile
129
129
  - gemfiles/i18n_1_7.gemfile
130
130
  - gemfiles/i18n_1_8.gemfile
131
+ - gemfiles/i18n_1_9.gemfile
131
132
  - i18n-js.gemspec
132
133
  - i18njs.png
133
134
  - lib/i18n-js.rb
@@ -152,6 +153,7 @@ files:
152
153
  - spec/fixtures/default.yml
153
154
  - spec/fixtures/erb.yml
154
155
  - spec/fixtures/except_condition.yml
156
+ - spec/fixtures/js_available_locales_custom.yml
155
157
  - spec/fixtures/js_export_dir_custom.yml
156
158
  - spec/fixtures/js_export_dir_none.yml
157
159
  - spec/fixtures/js_extend_parent.yml
@@ -189,6 +191,7 @@ files:
189
191
  - spec/js/jasmine/jasmine.css
190
192
  - spec/js/jasmine/jasmine.js
191
193
  - spec/js/jasmine/jasmine_favicon.png
194
+ - spec/js/json_parsable.spec.js
192
195
  - spec/js/locales.spec.js
193
196
  - spec/js/localization.spec.js
194
197
  - spec/js/numbers.spec.js
@@ -207,11 +210,11 @@ files:
207
210
  - spec/ruby/i18n/js_spec.rb
208
211
  - spec/spec_helper.rb
209
212
  - yarn.lock
210
- homepage: http://rubygems.org/gems/i18n-js
213
+ homepage: https://rubygems.org/gems/i18n-js
211
214
  licenses:
212
215
  - MIT
213
216
  metadata: {}
214
- post_install_message:
217
+ post_install_message:
215
218
  rdoc_options: []
216
219
  require_paths:
217
220
  - lib
@@ -226,8 +229,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
229
  - !ruby/object:Gem::Version
227
230
  version: '0'
228
231
  requirements: []
229
- rubygems_version: 3.2.14
230
- signing_key:
232
+ rubygems_version: 3.3.6
233
+ signing_key:
231
234
  specification_version: 4
232
235
  summary: It's a small library to provide the Rails I18n translations on the Javascript.
233
236
  test_files:
@@ -235,6 +238,7 @@ test_files:
235
238
  - spec/fixtures/default.yml
236
239
  - spec/fixtures/erb.yml
237
240
  - spec/fixtures/except_condition.yml
241
+ - spec/fixtures/js_available_locales_custom.yml
238
242
  - spec/fixtures/js_export_dir_custom.yml
239
243
  - spec/fixtures/js_export_dir_none.yml
240
244
  - spec/fixtures/js_extend_parent.yml
@@ -272,6 +276,7 @@ test_files:
272
276
  - spec/js/jasmine/jasmine.css
273
277
  - spec/js/jasmine/jasmine.js
274
278
  - spec/js/jasmine/jasmine_favicon.png
279
+ - spec/js/json_parsable.spec.js
275
280
  - spec/js/locales.spec.js
276
281
  - spec/js/localization.spec.js
277
282
  - spec/js/numbers.spec.js