i18n-js 2.1.2 → 3.8.3

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 (127) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +24 -0
  3. data/.github/FUNDING.yml +3 -0
  4. data/.github/workflows/tests.yaml +100 -0
  5. data/.gitignore +6 -4
  6. data/.npmignore +27 -0
  7. data/Appraisals +44 -0
  8. data/CHANGELOG.md +539 -0
  9. data/Gemfile +1 -1
  10. data/README.md +1086 -0
  11. data/Rakefile +19 -7
  12. data/app/assets/javascripts/i18n.js +1095 -0
  13. data/app/assets/javascripts/i18n/filtered.js.erb +23 -0
  14. data/app/assets/javascripts/i18n/shims.js +240 -0
  15. data/app/assets/javascripts/i18n/translations.js +3 -0
  16. data/gemfiles/i18n_0_6.gemfile +7 -0
  17. data/gemfiles/i18n_0_7.gemfile +7 -0
  18. data/gemfiles/i18n_0_8.gemfile +7 -0
  19. data/gemfiles/i18n_0_9.gemfile +7 -0
  20. data/gemfiles/i18n_1_0.gemfile +7 -0
  21. data/gemfiles/i18n_1_1.gemfile +7 -0
  22. data/gemfiles/i18n_1_2.gemfile +7 -0
  23. data/gemfiles/i18n_1_3.gemfile +7 -0
  24. data/gemfiles/i18n_1_4.gemfile +7 -0
  25. data/gemfiles/i18n_1_5.gemfile +7 -0
  26. data/gemfiles/i18n_1_6.gemfile +7 -0
  27. data/gemfiles/i18n_1_7.gemfile +7 -0
  28. data/gemfiles/i18n_1_8.gemfile +7 -0
  29. data/i18n-js.gemspec +12 -9
  30. data/i18njs.png +0 -0
  31. data/lib/i18n-js.rb +1 -177
  32. data/lib/i18n/js.rb +264 -0
  33. data/lib/i18n/js/dependencies.rb +63 -0
  34. data/lib/i18n/js/engine.rb +87 -0
  35. data/lib/i18n/js/fallback_locales.rb +70 -0
  36. data/lib/i18n/js/formatters/base.rb +25 -0
  37. data/lib/i18n/js/formatters/js.rb +39 -0
  38. data/lib/i18n/js/formatters/json.rb +13 -0
  39. data/lib/{i18n-js → i18n/js}/middleware.rb +32 -9
  40. data/lib/i18n/js/private/config_store.rb +31 -0
  41. data/lib/i18n/js/private/hash_with_symbol_keys.rb +36 -0
  42. data/lib/i18n/js/segment.rb +80 -0
  43. data/lib/i18n/js/utils.rb +78 -0
  44. data/lib/i18n/js/version.rb +7 -0
  45. data/lib/rails/generators/i18n/js/config/config_generator.rb +19 -0
  46. data/{config → lib/rails/generators/i18n/js/config/templates}/i18n-js.yml +11 -6
  47. data/lib/tasks/export.rake +8 -0
  48. data/package.json +25 -0
  49. data/spec/fixtures/custom_path.yml +5 -0
  50. data/spec/fixtures/default.yml +5 -0
  51. data/spec/fixtures/erb.yml +5 -0
  52. data/spec/fixtures/except_condition.yml +7 -0
  53. data/spec/fixtures/js_export_dir_custom.yml +7 -0
  54. data/spec/fixtures/js_export_dir_none.yml +6 -0
  55. data/spec/fixtures/js_extend_parent.yml +6 -0
  56. data/spec/fixtures/js_extend_segment.yml +6 -0
  57. data/spec/fixtures/js_file_per_locale.yml +7 -0
  58. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml +4 -0
  59. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml +6 -0
  60. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml +4 -0
  61. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml +4 -0
  62. data/spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml +4 -0
  63. data/spec/fixtures/js_file_per_locale_without_fallbacks.yml +4 -0
  64. data/spec/fixtures/js_file_with_namespace_prefix_and_pretty_print.yml +9 -0
  65. data/spec/fixtures/js_sort_translation_keys_false.yml +6 -0
  66. data/spec/fixtures/js_sort_translation_keys_true.yml +6 -0
  67. data/spec/fixtures/json_only.yml +18 -0
  68. data/spec/{resources → fixtures}/locales.yml +58 -1
  69. data/spec/fixtures/merge_plurals.yml +6 -0
  70. data/spec/fixtures/merge_plurals_with_no_overrides.yml +4 -0
  71. data/spec/fixtures/merge_plurals_with_partial_overrides.yml +4 -0
  72. data/spec/fixtures/millions.yml +4 -0
  73. data/spec/fixtures/multiple_conditions.yml +7 -0
  74. data/spec/fixtures/multiple_conditions_per_locale.yml +7 -0
  75. data/spec/fixtures/multiple_files.yml +7 -0
  76. data/spec/{resources → fixtures}/no_config.yml +0 -0
  77. data/spec/fixtures/no_scope.yml +4 -0
  78. data/spec/fixtures/simple_scope.yml +5 -0
  79. data/spec/js/currency.spec.js +62 -0
  80. data/spec/js/current_locale.spec.js +19 -0
  81. data/spec/js/dates.spec.js +276 -0
  82. data/spec/js/defaults.spec.js +31 -0
  83. data/spec/js/extend.spec.js +110 -0
  84. data/spec/js/interpolation.spec.js +124 -0
  85. data/spec/js/jasmine/MIT.LICENSE +20 -0
  86. data/spec/js/jasmine/jasmine-html.js +190 -0
  87. data/spec/js/jasmine/jasmine.css +166 -0
  88. data/spec/js/jasmine/jasmine.js +2476 -0
  89. data/spec/js/jasmine/jasmine_favicon.png +0 -0
  90. data/spec/js/json_parsable.spec.js +14 -0
  91. data/spec/js/locales.spec.js +31 -0
  92. data/spec/js/localization.spec.js +78 -0
  93. data/spec/js/numbers.spec.js +174 -0
  94. data/spec/js/placeholder.spec.js +24 -0
  95. data/spec/js/pluralization.spec.js +219 -0
  96. data/spec/js/prepare_options.spec.js +41 -0
  97. data/spec/js/require.js +2083 -0
  98. data/spec/js/specs.html +49 -0
  99. data/spec/js/specs_requirejs.html +72 -0
  100. data/spec/js/translate.spec.js +304 -0
  101. data/spec/js/translations.js +188 -0
  102. data/spec/js/utility_functions.spec.js +20 -0
  103. data/spec/ruby/i18n/js/fallback_locales_spec.rb +84 -0
  104. data/spec/ruby/i18n/js/segment_spec.rb +261 -0
  105. data/spec/ruby/i18n/js/utils_spec.rb +106 -0
  106. data/spec/ruby/i18n/js_spec.rb +748 -0
  107. data/spec/spec_helper.rb +75 -14
  108. data/yarn.lock +131 -0
  109. metadata +223 -98
  110. data/.rspec +0 -1
  111. data/Gemfile.lock +0 -51
  112. data/README.rdoc +0 -305
  113. data/lib/i18n-js/engine.rb +0 -62
  114. data/lib/i18n-js/railtie.rb +0 -13
  115. data/lib/i18n-js/rake.rb +0 -16
  116. data/lib/i18n-js/version.rb +0 -10
  117. data/spec/i18n_spec.js +0 -768
  118. data/spec/i18n_spec.rb +0 -205
  119. data/spec/resources/custom_path.yml +0 -4
  120. data/spec/resources/default.yml +0 -4
  121. data/spec/resources/js_file_per_locale.yml +0 -3
  122. data/spec/resources/multiple_conditions.yml +0 -6
  123. data/spec/resources/multiple_files.yml +0 -6
  124. data/spec/resources/no_scope.yml +0 -3
  125. data/spec/resources/simple_scope.yml +0 -4
  126. data/vendor/assets/javascripts/i18n.js +0 -450
  127. data/vendor/assets/javascripts/i18n/translations.js.erb +0 -7
@@ -0,0 +1,23 @@
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
+ }));
@@ -0,0 +1,240 @@
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
+ })();
@@ -0,0 +1,3 @@
1
+ //= require i18n/shims
2
+ //= require i18n
3
+ //= require i18n/filtered
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 0.6.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 0.7.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 0.8.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 0.9.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.0.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.1.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.2.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.3.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.4.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.5.1"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.6.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.7.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
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/i18n-js.gemspec CHANGED
@@ -1,27 +1,30 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
- require "i18n-js/version"
3
+ require "i18n/js/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "i18n-js"
7
- s.version = SimplesIdeias::I18n::Version::STRING
7
+ s.version = I18n::JS::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Nando Vieira"]
10
10
  s.email = ["fnando.vieira@gmail.com"]
11
11
  s.homepage = "http://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
+ s.license = "MIT"
14
15
 
15
16
  s.files = `git ls-files`.split("\n")
16
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
19
  s.require_paths = ["lib"]
19
20
 
20
- s.add_dependency "i18n"
21
- s.add_development_dependency "fakeweb"
22
- s.add_development_dependency "activesupport", ">= 3.0.0"
23
- s.add_development_dependency "rspec", "~> 2.6"
24
- s.add_development_dependency "spec-js", "~> 0.1.0.beta.0"
25
- s.add_development_dependency "rake"
26
- s.add_development_dependency "pry"
21
+ s.add_dependency "i18n", ">= 0.6.6"
22
+
23
+ s.add_development_dependency "appraisal", "~> 2.3"
24
+ s.add_development_dependency "rspec", "~> 3.0"
25
+ s.add_development_dependency "rake", "~> 12.0"
26
+ s.add_development_dependency "gem-release", ">= 0.7"
27
+ s.add_development_dependency "coveralls", ">= 0.7"
28
+
29
+ s.required_ruby_version = ">= 2.1.0"
27
30
  end
data/i18njs.png ADDED
Binary file
data/lib/i18n-js.rb CHANGED
@@ -1,177 +1 @@
1
- require "FileUtils" unless defined?(FileUtils)
2
-
3
- module SimplesIdeias
4
- module I18n
5
- extend self
6
-
7
- require "i18n-js/railtie" if Rails.version >= "3.0"
8
- require "i18n-js/engine" if Rails.version >= "3.1"
9
- require "i18n-js/middleware"
10
-
11
- # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
12
- MERGER = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2 }
13
-
14
- # Under rails 3.1.1 and higher, perform a check to ensure that the
15
- # full environment will be available during asset compilation.
16
- # This is required to ensure I18n is loaded.
17
- def assert_usable_configuration!
18
- @usable_configuration ||= Rails.version >= "3.1.1" &&
19
- Rails.configuration.assets.initialize_on_precompile ||
20
- raise("Cannot precompile i18n-js translations unless environment is initialized. Please set config.assets.initialize_on_precompile to true.")
21
- end
22
-
23
- def has_asset_pipeline?
24
- Rails.configuration.respond_to?(:assets) && Rails.configuration.assets.enabled
25
- end
26
-
27
- def config_file
28
- Rails.root.join("config/i18n-js.yml")
29
- end
30
-
31
- def export_dir
32
- if has_asset_pipeline?
33
- "app/assets/javascripts/i18n"
34
- else
35
- "public/javascripts"
36
- end
37
- end
38
-
39
- def javascript_file
40
- Rails.root.join(export_dir, "i18n.js")
41
- end
42
-
43
- # Export translations to JavaScript, considering settings
44
- # from configuration file
45
- def export!
46
- translation_segments.each do |filename, translations|
47
- save(translations, filename)
48
- end
49
- end
50
-
51
- def segments_per_locale(pattern,scope)
52
- ::I18n.available_locales.each_with_object({}) do |locale,segments|
53
- result = scoped_translations("#{locale}.#{scope}")
54
- unless result.empty?
55
- segment_name = ::I18n.interpolate(pattern,{:locale => locale})
56
- segments[segment_name] = result
57
- end
58
- end
59
- end
60
-
61
- def segment_for_scope(scope)
62
- if scope == "*"
63
- translations
64
- else
65
- scoped_translations(scope)
66
- end
67
- end
68
-
69
- def configured_segments
70
- config[:translations].each_with_object({}) do |options,segments|
71
- options.reverse_merge!(:only => "*")
72
- if options[:file] =~ ::I18n::INTERPOLATION_PATTERN
73
- segments.merge!(segments_per_locale(options[:file],options[:only]))
74
- else
75
- result = segment_for_scope(options[:only])
76
- segments[options[:file]] = result unless result.empty?
77
- end
78
- end
79
- end
80
-
81
- def translation_segments
82
- if config? && config[:translations]
83
- configured_segments
84
- else
85
- {"#{export_dir}/translations.js" => translations}
86
- end
87
- end
88
-
89
- # Load configuration file for partial exporting and
90
- # custom output directory
91
- def config
92
- if config?
93
- (YAML.load_file(config_file) || {}).with_indifferent_access
94
- else
95
- {}
96
- end
97
- end
98
-
99
- # Check if configuration file exist
100
- def config?
101
- File.file? config_file
102
- end
103
-
104
- # Copy configuration and JavaScript library files to
105
- # <tt>config/i18n-js.yml</tt> and <tt>public/javascripts/i18n.js</tt>.
106
- def setup!
107
- FileUtils.cp(File.dirname(__FILE__) + "/../vendor/assets/javascripts/i18n.js", javascript_file) unless Rails.version >= "3.1"
108
- FileUtils.cp(File.dirname(__FILE__) + "/../config/i18n-js.yml", config_file) unless config?
109
- end
110
-
111
- # Retrieve an updated JavaScript library from Github.
112
- def update!
113
- require "open-uri"
114
- contents = open("https://raw.github.com/fnando/i18n-js/master/vendor/assets/javascripts/i18n.js").read
115
- File.open(javascript_file, "w+") {|f| f << contents}
116
- end
117
-
118
- # Convert translations to JSON string and save file.
119
- def save(translations, file)
120
- file = Rails.root.join(file)
121
- FileUtils.mkdir_p File.dirname(file)
122
-
123
- File.open(file, "w+") do |f|
124
- f << %(var I18n = I18n || {};\n)
125
- f << %(I18n.translations = );
126
- f << translations.to_json
127
- f << %(;)
128
- end
129
- end
130
-
131
- def scoped_translations(scopes) # :nodoc:
132
- result = {}
133
-
134
- [scopes].flatten.each do |scope|
135
- deep_merge! result, filter(translations, scope)
136
- end
137
-
138
- result
139
- end
140
-
141
- # Filter translations according to the specified scope.
142
- def filter(translations, scopes)
143
- scopes = scopes.split(".") if scopes.is_a?(String)
144
- scopes = scopes.clone
145
- scope = scopes.shift
146
-
147
- if scope == "*"
148
- results = {}
149
- translations.each do |scope, translations|
150
- tmp = scopes.empty? ? translations : filter(translations, scopes)
151
- results[scope.to_sym] = tmp unless tmp.nil?
152
- end
153
- return results
154
- elsif translations.has_key?(scope.to_sym)
155
- return {scope.to_sym => scopes.empty? ? translations[scope.to_sym] : filter(translations[scope.to_sym], scopes)}
156
- end
157
- nil
158
- end
159
-
160
- # Initialize and return translations
161
- def translations
162
- ::I18n.backend.instance_eval do
163
- init_translations unless initialized?
164
- translations
165
- end
166
- end
167
-
168
- def deep_merge(target, hash) # :nodoc:
169
- target.merge(hash, &MERGER)
170
- end
171
-
172
- def deep_merge!(target, hash) # :nodoc:
173
- target.merge!(hash, &MERGER)
174
- end
175
- end
176
- end
177
-
1
+ require "i18n/js"