i18n-js 3.8.2 → 3.9.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.
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