i18n-js 3.8.3 → 4.0.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +4 -0
  3. data/.github/FUNDING.yml +1 -1
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  6. data/.github/PULL_REQUEST_TEMPLATE.md +38 -0
  7. data/.github/dependabot.yml +15 -0
  8. data/.github/workflows/ruby-tests.yml +61 -0
  9. data/.gitignore +11 -7
  10. data/.rubocop.yml +12 -0
  11. data/CHANGELOG.md +12 -535
  12. data/CODE_OF_CONDUCT.md +74 -0
  13. data/CONTRIBUTING.md +79 -0
  14. data/Gemfile +3 -0
  15. data/LICENSE.md +20 -0
  16. data/README.md +86 -1030
  17. data/Rakefile +10 -20
  18. data/exe/i18n +5 -0
  19. data/i18n-js.gemspec +47 -29
  20. data/lib/guard/i18n-js.rb +78 -0
  21. data/lib/guard/i18n-js/templates/Guardfile +10 -0
  22. data/lib/guard/i18n-js/version.rb +13 -0
  23. data/lib/i18n-js.rb +66 -1
  24. data/lib/i18n-js/cli.rb +47 -0
  25. data/lib/i18n-js/cli/command.rb +43 -0
  26. data/lib/i18n-js/cli/export_command.rb +108 -0
  27. data/lib/i18n-js/cli/init_command.rb +50 -0
  28. data/lib/i18n-js/cli/ui.rb +30 -0
  29. data/lib/i18n-js/cli/version_command.rb +18 -0
  30. data/lib/i18n-js/listen.rb +80 -0
  31. data/lib/i18n-js/schema.rb +92 -0
  32. data/lib/i18n-js/version.rb +5 -0
  33. metadata +122 -194
  34. data/.editorconfig +0 -24
  35. data/.github/workflows/tests.yaml +0 -100
  36. data/.npmignore +0 -27
  37. data/Appraisals +0 -44
  38. data/app/assets/javascripts/i18n.js +0 -1095
  39. data/app/assets/javascripts/i18n/filtered.js.erb +0 -23
  40. data/app/assets/javascripts/i18n/shims.js +0 -240
  41. data/app/assets/javascripts/i18n/translations.js +0 -3
  42. data/gemfiles/i18n_0_6.gemfile +0 -7
  43. data/gemfiles/i18n_0_7.gemfile +0 -7
  44. data/gemfiles/i18n_0_8.gemfile +0 -7
  45. data/gemfiles/i18n_0_9.gemfile +0 -7
  46. data/gemfiles/i18n_1_0.gemfile +0 -7
  47. data/gemfiles/i18n_1_1.gemfile +0 -7
  48. data/gemfiles/i18n_1_2.gemfile +0 -7
  49. data/gemfiles/i18n_1_3.gemfile +0 -7
  50. data/gemfiles/i18n_1_4.gemfile +0 -7
  51. data/gemfiles/i18n_1_5.gemfile +0 -7
  52. data/gemfiles/i18n_1_6.gemfile +0 -7
  53. data/gemfiles/i18n_1_7.gemfile +0 -7
  54. data/gemfiles/i18n_1_8.gemfile +0 -7
  55. data/i18njs.png +0 -0
  56. data/lib/i18n/js.rb +0 -264
  57. data/lib/i18n/js/dependencies.rb +0 -63
  58. data/lib/i18n/js/engine.rb +0 -87
  59. data/lib/i18n/js/fallback_locales.rb +0 -70
  60. data/lib/i18n/js/formatters/base.rb +0 -25
  61. data/lib/i18n/js/formatters/js.rb +0 -39
  62. data/lib/i18n/js/formatters/json.rb +0 -13
  63. data/lib/i18n/js/middleware.rb +0 -82
  64. data/lib/i18n/js/private/config_store.rb +0 -31
  65. data/lib/i18n/js/private/hash_with_symbol_keys.rb +0 -36
  66. data/lib/i18n/js/segment.rb +0 -80
  67. data/lib/i18n/js/utils.rb +0 -78
  68. data/lib/i18n/js/version.rb +0 -7
  69. data/lib/rails/generators/i18n/js/config/config_generator.rb +0 -19
  70. data/lib/rails/generators/i18n/js/config/templates/i18n-js.yml +0 -27
  71. data/lib/tasks/export.rake +0 -8
  72. data/package.json +0 -25
  73. data/spec/fixtures/custom_path.yml +0 -5
  74. data/spec/fixtures/default.yml +0 -5
  75. data/spec/fixtures/erb.yml +0 -5
  76. data/spec/fixtures/except_condition.yml +0 -7
  77. data/spec/fixtures/js_export_dir_custom.yml +0 -7
  78. data/spec/fixtures/js_export_dir_none.yml +0 -6
  79. data/spec/fixtures/js_extend_parent.yml +0 -6
  80. data/spec/fixtures/js_extend_segment.yml +0 -6
  81. data/spec/fixtures/js_file_per_locale.yml +0 -7
  82. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml +0 -4
  83. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml +0 -6
  84. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml +0 -4
  85. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml +0 -4
  86. data/spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml +0 -4
  87. data/spec/fixtures/js_file_per_locale_without_fallbacks.yml +0 -4
  88. data/spec/fixtures/js_file_with_namespace_prefix_and_pretty_print.yml +0 -9
  89. data/spec/fixtures/js_sort_translation_keys_false.yml +0 -6
  90. data/spec/fixtures/js_sort_translation_keys_true.yml +0 -6
  91. data/spec/fixtures/json_only.yml +0 -18
  92. data/spec/fixtures/locales.yml +0 -133
  93. data/spec/fixtures/merge_plurals.yml +0 -6
  94. data/spec/fixtures/merge_plurals_with_no_overrides.yml +0 -4
  95. data/spec/fixtures/merge_plurals_with_partial_overrides.yml +0 -4
  96. data/spec/fixtures/millions.yml +0 -4
  97. data/spec/fixtures/multiple_conditions.yml +0 -7
  98. data/spec/fixtures/multiple_conditions_per_locale.yml +0 -7
  99. data/spec/fixtures/multiple_files.yml +0 -7
  100. data/spec/fixtures/no_config.yml +0 -2
  101. data/spec/fixtures/no_scope.yml +0 -4
  102. data/spec/fixtures/simple_scope.yml +0 -5
  103. data/spec/js/currency.spec.js +0 -62
  104. data/spec/js/current_locale.spec.js +0 -19
  105. data/spec/js/dates.spec.js +0 -276
  106. data/spec/js/defaults.spec.js +0 -31
  107. data/spec/js/extend.spec.js +0 -110
  108. data/spec/js/interpolation.spec.js +0 -124
  109. data/spec/js/jasmine/MIT.LICENSE +0 -20
  110. data/spec/js/jasmine/jasmine-html.js +0 -190
  111. data/spec/js/jasmine/jasmine.css +0 -166
  112. data/spec/js/jasmine/jasmine.js +0 -2476
  113. data/spec/js/jasmine/jasmine_favicon.png +0 -0
  114. data/spec/js/json_parsable.spec.js +0 -14
  115. data/spec/js/locales.spec.js +0 -31
  116. data/spec/js/localization.spec.js +0 -78
  117. data/spec/js/numbers.spec.js +0 -174
  118. data/spec/js/placeholder.spec.js +0 -24
  119. data/spec/js/pluralization.spec.js +0 -219
  120. data/spec/js/prepare_options.spec.js +0 -41
  121. data/spec/js/require.js +0 -2083
  122. data/spec/js/specs.html +0 -49
  123. data/spec/js/specs_requirejs.html +0 -72
  124. data/spec/js/translate.spec.js +0 -304
  125. data/spec/js/translations.js +0 -188
  126. data/spec/js/utility_functions.spec.js +0 -20
  127. data/spec/ruby/i18n/js/fallback_locales_spec.rb +0 -84
  128. data/spec/ruby/i18n/js/segment_spec.rb +0 -261
  129. data/spec/ruby/i18n/js/utils_spec.rb +0 -106
  130. data/spec/ruby/i18n/js_spec.rb +0 -748
  131. data/spec/spec_helper.rb +0 -80
  132. data/yarn.lock +0 -131
@@ -1,23 +0,0 @@
1
- <%# encoding: utf-8 %>
2
-
3
- // Using UMD pattern from
4
- // https://github.com/umdjs/umd#regular-module
5
- // `returnExports.js` version
6
- ;(function (root, factory) {
7
- if (typeof define === 'function' && define.amd) {
8
- // AMD. Register as an anonymous module.
9
- define(["i18n"], factory);
10
- } else if (typeof module === 'object' && module.exports) {
11
- // Node. Does not work with strict CommonJS, but
12
- // only CommonJS-like environments that support module.exports,
13
- // like Node.
14
- factory(require("i18n"));
15
- } else {
16
- // Browser globals (root is window)
17
- factory(root.I18n);
18
- }
19
- }(this, function(I18n) {
20
- "use strict";
21
-
22
- I18n.translations = <%= I18n::JS.filtered_translations.to_json %>;
23
- }));
@@ -1,240 +0,0 @@
1
- // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
2
- if (!Array.prototype.indexOf) {
3
- Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
4
- "use strict";
5
- if (this == null) {
6
- throw new TypeError();
7
- }
8
- var t = Object(this);
9
- var len = t.length >>> 0;
10
- if (len === 0) {
11
- return -1;
12
- }
13
- var n = 0;
14
- if (arguments.length > 1) {
15
- n = Number(arguments[1]);
16
- if (n != n) { // shortcut for verifying if it's NaN
17
- n = 0;
18
- } else if (n != 0 && n != Infinity && n != -Infinity) {
19
- n = (n > 0 || -1) * Math.floor(Math.abs(n));
20
- }
21
- }
22
- if (n >= len) {
23
- return -1;
24
- }
25
- var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
26
- for (; k < len; k++) {
27
- if (k in t && t[k] === searchElement) {
28
- return k;
29
- }
30
- }
31
- return -1;
32
- }
33
- }
34
-
35
- // Production steps of ECMA-262, Edition 5, 15.4.4.18
36
- // Reference: http://es5.github.com/#x15.4.4.18
37
- // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
38
- if ( !Array.prototype.forEach ) {
39
-
40
- Array.prototype.forEach = function forEach( callback, thisArg ) {
41
-
42
- var T, k;
43
-
44
- if ( this == null ) {
45
- throw new TypeError( "this is null or not defined" );
46
- }
47
-
48
- // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
49
- var O = Object(this);
50
-
51
- // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
52
- // 3. Let len be ToUint32(lenValue).
53
- var len = O.length >>> 0; // Hack to convert O.length to a UInt32
54
-
55
- // 4. If IsCallable(callback) is false, throw a TypeError exception.
56
- // See: http://es5.github.com/#x9.11
57
- if ( {}.toString.call(callback) !== "[object Function]" ) {
58
- throw new TypeError( callback + " is not a function" );
59
- }
60
-
61
- // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
62
- if ( thisArg ) {
63
- T = thisArg;
64
- }
65
-
66
- // 6. Let k be 0
67
- k = 0;
68
-
69
- // 7. Repeat, while k < len
70
- while( k < len ) {
71
-
72
- var kValue;
73
-
74
- // a. Let Pk be ToString(k).
75
- // This is implicit for LHS operands of the in operator
76
- // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
77
- // This step can be combined with c
78
- // c. If kPresent is true, then
79
- if ( Object.prototype.hasOwnProperty.call(O, k) ) {
80
-
81
- // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
82
- kValue = O[ k ];
83
-
84
- // ii. Call the Call internal method of callback with T as the this value and
85
- // argument list containing kValue, k, and O.
86
- callback.call( T, kValue, k, O );
87
- }
88
- // d. Increase k by 1.
89
- k++;
90
- }
91
- // 8. return undefined
92
- };
93
- }
94
-
95
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
96
- if (!Array.prototype.some)
97
- {
98
- Array.prototype.some = function(fun /*, thisArg */)
99
- {
100
- 'use strict';
101
-
102
- if (this === void 0 || this === null)
103
- throw new TypeError();
104
-
105
- var t = Object(this);
106
- var len = t.length >>> 0;
107
- if (typeof fun !== 'function')
108
- throw new TypeError();
109
-
110
- var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
111
- for (var i = 0; i < len; i++)
112
- {
113
- if (i in t && fun.call(thisArg, t[i], i, t))
114
- return true;
115
- }
116
-
117
- return false;
118
- };
119
- }
120
-
121
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
122
- if (!Array.prototype.map) {
123
-
124
- Array.prototype.map = function(callback/*, thisArg*/) {
125
-
126
- var T, A, k;
127
-
128
- if (this == null) {
129
- throw new TypeError('this is null or not defined');
130
- }
131
-
132
- // 1. Let O be the result of calling ToObject passing the |this|
133
- // value as the argument.
134
- var O = Object(this);
135
-
136
- // 2. Let lenValue be the result of calling the Get internal
137
- // method of O with the argument "length".
138
- // 3. Let len be ToUint32(lenValue).
139
- var len = O.length >>> 0;
140
-
141
- // 4. If IsCallable(callback) is false, throw a TypeError exception.
142
- // See: http://es5.github.com/#x9.11
143
- if (typeof callback !== 'function') {
144
- throw new TypeError(callback + ' is not a function');
145
- }
146
-
147
- // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
148
- if (arguments.length > 1) {
149
- T = arguments[1];
150
- }
151
-
152
- // 6. Let A be a new array created as if by the expression new Array(len)
153
- // where Array is the standard built-in constructor with that name and
154
- // len is the value of len.
155
- A = new Array(len);
156
-
157
- // 7. Let k be 0
158
- k = 0;
159
-
160
- // 8. Repeat, while k < len
161
- while (k < len) {
162
-
163
- var kValue, mappedValue;
164
-
165
- // a. Let Pk be ToString(k).
166
- // This is implicit for LHS operands of the in operator
167
- // b. Let kPresent be the result of calling the HasProperty internal
168
- // method of O with argument Pk.
169
- // This step can be combined with c
170
- // c. If kPresent is true, then
171
- if (k in O) {
172
-
173
- // i. Let kValue be the result of calling the Get internal
174
- // method of O with argument Pk.
175
- kValue = O[k];
176
-
177
- // ii. Let mappedValue be the result of calling the Call internal
178
- // method of callback with T as the this value and argument
179
- // list containing kValue, k, and O.
180
- mappedValue = callback.call(T, kValue, k, O);
181
-
182
- // iii. Call the DefineOwnProperty internal method of A with arguments
183
- // Pk, Property Descriptor
184
- // { Value: mappedValue,
185
- // Writable: true,
186
- // Enumerable: true,
187
- // Configurable: true },
188
- // and false.
189
-
190
- // In browsers that support Object.defineProperty, use the following:
191
- // Object.defineProperty(A, k, {
192
- // value: mappedValue,
193
- // writable: true,
194
- // enumerable: true,
195
- // configurable: true
196
- // });
197
-
198
- // For best browser support, use the following:
199
- A[k] = mappedValue;
200
- }
201
- // d. Increase k by 1.
202
- k++;
203
- }
204
-
205
- // 9. return A
206
- return A;
207
- };
208
- }
209
-
210
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
211
- if (!Function.prototype.bind) (function(){
212
- var ArrayPrototypeSlice = Array.prototype.slice;
213
- Function.prototype.bind = function(otherThis) {
214
- if (typeof this !== 'function') {
215
- // closest thing possible to the ECMAScript 5
216
- // internal IsCallable function
217
- throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
218
- }
219
-
220
- var baseArgs= ArrayPrototypeSlice .call(arguments, 1),
221
- baseArgsLength = baseArgs.length,
222
- fToBind = this,
223
- fNOP = function() {},
224
- fBound = function() {
225
- baseArgs.length = baseArgsLength; // reset to default base arguments
226
- baseArgs.push.apply(baseArgs, arguments);
227
- return fToBind.apply(
228
- fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
229
- );
230
- };
231
-
232
- if (this.prototype) {
233
- // Function.prototype doesn't have a prototype property
234
- fNOP.prototype = this.prototype;
235
- }
236
- fBound.prototype = new fNOP();
237
-
238
- return fBound;
239
- };
240
- })();
@@ -1,3 +0,0 @@
1
- //= require i18n/shims
2
- //= require i18n
3
- //= require i18n/filtered
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.6.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.7.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.8.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 0.9.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.0.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.1.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.2.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.3.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.4.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.5.1"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.6.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.7.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "i18n", "~> 1.8.0"
6
-
7
- gemspec path: "../"
data/i18njs.png DELETED
Binary file
data/lib/i18n/js.rb DELETED
@@ -1,264 +0,0 @@
1
- require "yaml"
2
- require "fileutils"
3
- require "i18n"
4
-
5
- require "i18n/js/utils"
6
- require "i18n/js/private/hash_with_symbol_keys"
7
- require "i18n/js/private/config_store"
8
-
9
- module I18n
10
- module JS
11
- require "i18n/js/dependencies"
12
- require "i18n/js/fallback_locales"
13
- require "i18n/js/segment"
14
- if JS::Dependencies.rails?
15
- require "i18n/js/middleware"
16
- require "i18n/js/engine"
17
- end
18
-
19
- DEFAULT_CONFIG_PATH = "config/i18n-js.yml"
20
- DEFAULT_EXPORT_DIR_PATH = "public/javascripts"
21
-
22
- # The configuration file. This defaults to the `config/i18n-js.yml` file.
23
- #
24
- def self.config_file_path
25
- @config_file_path ||= DEFAULT_CONFIG_PATH
26
- end
27
-
28
- def self.config_file_path=(new_path)
29
- @config_file_path = new_path
30
- # new config file path = need to re-read config from new file
31
- Private::ConfigStore.instance.flush_cache
32
- end
33
-
34
- # Allow using a different backend than the one globally configured
35
- def self.backend
36
- @backend ||= I18n.backend
37
- end
38
-
39
- def self.backend=(alternative_backend)
40
- @backend = alternative_backend
41
- end
42
-
43
- # Export translations to JavaScript, considering settings
44
- # from configuration file
45
- def self.export
46
- export_i18n_js
47
-
48
- translation_segments.each(&:save!)
49
- end
50
-
51
- def self.segment_for_scope(scope, exceptions)
52
- if scope == "*"
53
- exclude(translations, exceptions)
54
- else
55
- scoped_translations(scope, exceptions)
56
- end
57
- end
58
-
59
- def self.configured_segments
60
- config[:translations].inject([]) do |segments, options_hash|
61
- options_hash_with_symbol_keys = Private::HashWithSymbolKeys.new(options_hash)
62
- file = options_hash_with_symbol_keys[:file]
63
- only = options_hash_with_symbol_keys[:only] || '*'
64
- exceptions = [options_hash_with_symbol_keys[:except] || []].flatten
65
-
66
- result = segment_for_scope(only, exceptions)
67
-
68
- merge_with_fallbacks!(result) if fallbacks
69
-
70
- unless result.empty?
71
- segments << Segment.new(
72
- file,
73
- result,
74
- extract_segment_options(options_hash_with_symbol_keys),
75
- )
76
- end
77
-
78
- segments
79
- end
80
- end
81
-
82
- # deep_merge! given result with result for fallback locale
83
- def self.merge_with_fallbacks!(result)
84
- I18n.available_locales.each do |locale|
85
- fallback_locales = FallbackLocales.new(fallbacks, locale)
86
- fallback_locales.each do |fallback_locale|
87
- # `result[fallback_locale]` could be missing
88
- result[locale] = Utils.deep_merge(result[fallback_locale] || {}, result[locale] || {})
89
- end
90
- end
91
- end
92
-
93
- def self.filtered_translations
94
- translations = {}.tap do |result|
95
- translation_segments.each do |segment|
96
- Utils.deep_merge!(result, segment.translations)
97
- end
98
- end
99
- return Utils.deep_key_sort(translations) if I18n::JS.sort_translation_keys?
100
- translations
101
- end
102
-
103
- def self.translation_segments
104
- if config_file_exists? && config[:translations]
105
- configured_segments
106
- else
107
- [Segment.new("#{DEFAULT_EXPORT_DIR_PATH}/translations.js", translations)]
108
- end
109
- end
110
-
111
- # Load configuration file for partial exporting and
112
- # custom output directory
113
- def self.config
114
- Private::ConfigStore.instance.fetch do
115
- if config_file_exists?
116
- erb_result_from_yaml_file = ERB.new(File.read(config_file_path)).result
117
- Private::HashWithSymbolKeys.new(
118
- (::YAML.load(erb_result_from_yaml_file) || {})
119
- )
120
- else
121
- Private::HashWithSymbolKeys.new({})
122
- end.freeze
123
- end
124
- end
125
-
126
- # @api private
127
- # Check if configuration file exist
128
- def self.config_file_exists?
129
- File.file? config_file_path
130
- end
131
-
132
- def self.scoped_translations(scopes, exceptions = []) # :nodoc:
133
- result = {}
134
-
135
- [scopes].flatten.each do |scope|
136
- translations_without_exceptions = exclude(translations, exceptions)
137
- filtered_translations = filter(translations_without_exceptions, scope) || {}
138
-
139
- Utils.deep_merge!(result, filtered_translations)
140
- end
141
-
142
- result
143
- end
144
-
145
- # Exclude keys from translations listed in the `except:` section in the config file
146
- def self.exclude(translations, exceptions)
147
- return translations if exceptions.empty?
148
-
149
- exceptions.inject(translations) do |memo, exception|
150
- exception_scopes = exception.to_s.split(".")
151
- Utils.deep_reject(memo) do |key, value, scopes|
152
- Utils.scopes_match?(scopes, exception_scopes)
153
- end
154
- end
155
- end
156
-
157
- # Filter translations according to the specified scope.
158
- def self.filter(translations, scopes)
159
- scopes = scopes.split(".") if scopes.is_a?(String)
160
- scopes = scopes.clone
161
- scope = scopes.shift
162
-
163
- if scope == "*"
164
- results = {}
165
- translations.each do |scope, translations|
166
- tmp = scopes.empty? ? translations : filter(translations, scopes)
167
- results[scope.to_sym] = tmp unless tmp.nil?
168
- end
169
- return results
170
- elsif translations.respond_to?(:key?) && translations.key?(scope.to_sym)
171
- return {scope.to_sym => scopes.empty? ? translations[scope.to_sym] : filter(translations[scope.to_sym], scopes)}
172
- end
173
- nil
174
- end
175
-
176
- # Initialize and return translations
177
- def self.translations
178
- self.backend.instance_eval do
179
- init_translations unless initialized?
180
- # When activesupport is absent,
181
- # the core extension (`#slice`) from `i18n` gem will be used instead
182
- # And it's causing errors (at least in test)
183
- #
184
- # So the input is wrapped by our class for better `#slice`
185
- Private::HashWithSymbolKeys.new(translations).
186
- slice(*::I18n.available_locales).
187
- to_h
188
- end
189
- end
190
-
191
- def self.use_fallbacks?
192
- fallbacks != false
193
- end
194
-
195
- def self.json_only
196
- config.fetch(:json_only) do
197
- # default value
198
- false
199
- end
200
- end
201
-
202
- def self.fallbacks
203
- config.fetch(:fallbacks) do
204
- # default value
205
- true
206
- end
207
- end
208
-
209
- def self.js_extend
210
- config.fetch(:js_extend) do
211
- # default value
212
- true
213
- end
214
- end
215
-
216
- def self.sort_translation_keys?
217
- @sort_translation_keys ||= (config[:sort_translation_keys]) if config.key?(:sort_translation_keys)
218
- @sort_translation_keys = true if @sort_translation_keys.nil?
219
- @sort_translation_keys
220
- end
221
-
222
- def self.sort_translation_keys=(value)
223
- @sort_translation_keys = !!value
224
- end
225
-
226
- def self.extract_segment_options(options)
227
- segment_options = Private::HashWithSymbolKeys.new({
228
- js_extend: js_extend,
229
- sort_translation_keys: sort_translation_keys?,
230
- json_only: json_only
231
- }).freeze
232
- segment_options.merge(options.slice(*Segment::OPTIONS))
233
- end
234
-
235
- ### Export i18n.js
236
- begin
237
-
238
- # Copy i18n.js
239
- def self.export_i18n_js
240
- return unless export_i18n_js_dir_path.is_a? String
241
-
242
- FileUtils.mkdir_p(export_i18n_js_dir_path)
243
-
244
- i18n_js_path = File.expand_path('../../../app/assets/javascripts/i18n.js', __FILE__)
245
- destination_path = File.expand_path("i18n.js", export_i18n_js_dir_path)
246
- return if File.exist?(destination_path) && FileUtils.identical?(i18n_js_path, destination_path)
247
-
248
- FileUtils.cp(i18n_js_path, export_i18n_js_dir_path)
249
- end
250
-
251
- def self.export_i18n_js_dir_path
252
- @export_i18n_js_dir_path ||= (config[:export_i18n_js] || :none) if config.key?(:export_i18n_js)
253
- @export_i18n_js_dir_path ||= DEFAULT_EXPORT_DIR_PATH
254
- @export_i18n_js_dir_path
255
- end
256
-
257
- # Setting this to nil would disable i18n.js exporting
258
- def self.export_i18n_js_dir_path=(new_path)
259
- new_path = :none unless new_path.is_a? String
260
- @export_i18n_js_dir_path = new_path
261
- end
262
- end
263
- end
264
- end