i18n-js 2.0.1 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +27 -27
- data/README.rdoc +28 -7
- data/i18n-js.gemspec +1 -2
- data/lib/i18n-js.rb +54 -19
- data/lib/i18n-js/engine.rb +53 -1
- data/lib/i18n-js/middleware.rb +18 -11
- data/lib/i18n-js/railtie.rb +1 -1
- data/lib/i18n-js/version.rb +1 -1
- data/spec/i18n_spec.js +16 -0
- data/spec/i18n_spec.rb +24 -14
- data/spec/resources/no_config.yml +2 -0
- data/vendor/assets/javascripts/i18n.js +63 -43
- data/vendor/assets/javascripts/i18n/translations.js.erb +7 -0
- metadata +23 -31
data/Gemfile.lock
CHANGED
@@ -1,40 +1,40 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
i18n-js (2.
|
4
|
+
i18n-js (2.1.1)
|
5
5
|
i18n
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activesupport (3.
|
11
|
-
|
12
|
-
|
13
|
-
diff-lcs (1.1.
|
10
|
+
activesupport (3.1.1)
|
11
|
+
multi_json (~> 1.0)
|
12
|
+
coderay (0.9.8)
|
13
|
+
diff-lcs (1.1.3)
|
14
14
|
fakeweb (1.3.0)
|
15
15
|
i18n (0.6.0)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
method_source (0.6.7)
|
17
|
+
ruby_parser (>= 2.3.1)
|
18
|
+
multi_json (1.0.3)
|
19
|
+
notifier (0.1.4)
|
20
|
+
pry (0.9.7.4)
|
21
|
+
coderay (~> 0.9.8)
|
22
|
+
method_source (~> 0.6.7)
|
23
|
+
ruby_parser (>= 2.3.1)
|
24
|
+
slop (~> 2.1.0)
|
25
|
+
rake (0.9.2.2)
|
26
|
+
rspec (2.7.0)
|
27
|
+
rspec-core (~> 2.7.0)
|
28
|
+
rspec-expectations (~> 2.7.0)
|
29
|
+
rspec-mocks (~> 2.7.0)
|
30
|
+
rspec-core (2.7.1)
|
31
|
+
rspec-expectations (2.7.0)
|
26
32
|
diff-lcs (~> 1.1.2)
|
27
|
-
rspec-mocks (2.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
ruby-debug19 (0.11.6)
|
33
|
-
columnize (>= 0.3.1)
|
34
|
-
linecache19 (>= 0.5.11)
|
35
|
-
ruby-debug-base19 (>= 0.11.19)
|
36
|
-
ruby_core_source (0.1.5)
|
37
|
-
archive-tar-minitar (>= 0.5.2)
|
33
|
+
rspec-mocks (2.7.0)
|
34
|
+
ruby_parser (2.3.1)
|
35
|
+
sexp_processor (~> 3.0)
|
36
|
+
sexp_processor (3.0.8)
|
37
|
+
slop (2.1.0)
|
38
38
|
spec-js (0.1.0.beta.3)
|
39
39
|
notifier
|
40
40
|
|
@@ -45,7 +45,7 @@ DEPENDENCIES
|
|
45
45
|
activesupport (>= 3.0.0)
|
46
46
|
fakeweb
|
47
47
|
i18n-js!
|
48
|
+
pry
|
48
49
|
rake
|
49
50
|
rspec (~> 2.6)
|
50
|
-
ruby-debug19
|
51
51
|
spec-js (~> 0.1.0.beta.0)
|
data/README.rdoc
CHANGED
@@ -18,18 +18,16 @@ Run <tt>rake i18n:js:setup</tt> to copy <tt>i18n.js</tt> to your javascript dire
|
|
18
18
|
|
19
19
|
==== Rails >= 3.1
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
Next add the following lines to your application.js to make the javascripts and translations available to your app:
|
21
|
+
Add the following lines to your application.js to make the javascripts and translations available to your app:
|
24
22
|
|
25
23
|
//= require i18n
|
26
24
|
//= require i18n/translations
|
27
25
|
|
28
|
-
If
|
26
|
+
If asset pipeline has been disabled for your Rails application, then you will need to run <tt>rake i18n:js:setup</tt> to copy <tt>i18n-js.yml</tt> to your config folder (if not already present).
|
29
27
|
|
30
28
|
==== Exporting translations
|
31
29
|
|
32
|
-
You can export the translations file by running
|
30
|
+
You can export the translations file by running <tt>rake i18n:js:export</tt>.
|
33
31
|
Translations will be automatically exported in development mode.
|
34
32
|
|
35
33
|
==== Configuration
|
@@ -52,6 +50,14 @@ If <tt>only</tt> is omitted all the translations will be saved. Also, make sure
|
|
52
50
|
- file: 'public/javascripts/pt-BR.js'
|
53
51
|
only: 'pt-BR.*'
|
54
52
|
|
53
|
+
Optionaly, you can auto generate a translation file per available locale if you specify the <tt>%{locale}</tt> placeholder.
|
54
|
+
|
55
|
+
translations:
|
56
|
+
- file: "public/javascripts/i18n/%{locale}.js"
|
57
|
+
only: '*'
|
58
|
+
- file: "public/javascripts/frontend/i18n/%{locale}.js"
|
59
|
+
only: ['frontend', 'users']
|
60
|
+
|
55
61
|
To find more examples on how to use the configuration file please refer to the tests.
|
56
62
|
|
57
63
|
=== On the Javascript
|
@@ -63,7 +69,7 @@ Set your locale is easy as
|
|
63
69
|
I18n.currentLocale();
|
64
70
|
// pt-BR
|
65
71
|
|
66
|
-
In practice, you'll have something like the following in your application.html.erb
|
72
|
+
In practice, you'll have something like the following in your <tt>application.html.erb</tt>:
|
67
73
|
|
68
74
|
<script type="text/javascript">
|
69
75
|
I18n.defaultLocale = "<%= I18n.default_locale %>";
|
@@ -73,6 +79,8 @@ In practice, you'll have something like the following in your application.html.e
|
|
73
79
|
You can use translate your messages:
|
74
80
|
|
75
81
|
I18n.t("some.scoped.translation");
|
82
|
+
// or translate with explicite setting of locale
|
83
|
+
I18n.t("some.scoped.translation", {locale: "fr"});
|
76
84
|
|
77
85
|
You can also interpolate values:
|
78
86
|
|
@@ -92,6 +100,19 @@ You can set default values for missing scopes:
|
|
92
100
|
// with interpolation
|
93
101
|
I18n.t("noun", {defaultValue: "I'm a {{noun}}", noun: "Mac"});
|
94
102
|
|
103
|
+
Translation fallback can be handled by taking from I18n.defaultLocale.
|
104
|
+
To allow this in your application.html.erb specify:
|
105
|
+
|
106
|
+
<script type="text/javascript">
|
107
|
+
I18n.fallbacks = true;
|
108
|
+
</script>
|
109
|
+
|
110
|
+
Then missing translation will be taken from your I18n.defaultLocale.
|
111
|
+
Example:
|
112
|
+
// if I18n.defaultLocale = "en" and translation doesn't exist for I18n.locale = "de"
|
113
|
+
I18n.t("some.missing.scope");
|
114
|
+
// this key will be taken from "en" locale scope
|
115
|
+
|
95
116
|
Pluralization is possible as well:
|
96
117
|
|
97
118
|
I18n.t("inbox.counting", {count: 10}); // You have 10 messages
|
@@ -258,7 +279,7 @@ First, install all dependencies.
|
|
258
279
|
|
259
280
|
bundle install
|
260
281
|
|
261
|
-
Then just run
|
282
|
+
Then just run <tt>rake spec</tt>.
|
262
283
|
|
263
284
|
== License
|
264
285
|
|
data/i18n-js.gemspec
CHANGED
@@ -21,8 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_development_dependency "fakeweb"
|
22
22
|
s.add_development_dependency "activesupport", ">= 3.0.0"
|
23
23
|
s.add_development_dependency "rspec", "~> 2.6"
|
24
|
-
s.add_development_dependency "ruby-debug19"
|
25
24
|
s.add_development_dependency "spec-js", "~> 0.1.0.beta.0"
|
26
25
|
s.add_development_dependency "rake"
|
27
|
-
s.add_development_dependency "
|
26
|
+
s.add_development_dependency "pry"
|
28
27
|
end
|
data/lib/i18n-js.rb
CHANGED
@@ -11,12 +11,25 @@ module SimplesIdeias
|
|
11
11
|
# deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
12
12
|
MERGER = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2 }
|
13
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
|
+
|
14
27
|
def config_file
|
15
28
|
Rails.root.join("config/i18n-js.yml")
|
16
29
|
end
|
17
30
|
|
18
31
|
def export_dir
|
19
|
-
if
|
32
|
+
if has_asset_pipeline?
|
20
33
|
"app/assets/javascripts/i18n"
|
21
34
|
else
|
22
35
|
"public/javascripts"
|
@@ -30,25 +43,46 @@ module SimplesIdeias
|
|
30
43
|
# Export translations to JavaScript, considering settings
|
31
44
|
# from configuration file
|
32
45
|
def export!
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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?
|
49
77
|
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def translation_segments
|
82
|
+
if config? && config[:translations]
|
83
|
+
configured_segments
|
50
84
|
else
|
51
|
-
|
85
|
+
{"#{export_dir}/translations.js" => translations}
|
52
86
|
end
|
53
87
|
end
|
54
88
|
|
@@ -77,7 +111,7 @@ module SimplesIdeias
|
|
77
111
|
# Retrieve an updated JavaScript library from Github.
|
78
112
|
def update!
|
79
113
|
require "open-uri"
|
80
|
-
contents = open("
|
114
|
+
contents = open("https://raw.github.com/fnando/i18n-js/master/vendor/assets/javascripts/i18n.js").read
|
81
115
|
File.open(javascript_file, "w+") {|f| f << contents}
|
82
116
|
end
|
83
117
|
|
@@ -140,3 +174,4 @@ module SimplesIdeias
|
|
140
174
|
end
|
141
175
|
end
|
142
176
|
end
|
177
|
+
|
data/lib/i18n-js/engine.rb
CHANGED
@@ -1,7 +1,59 @@
|
|
1
1
|
module SimplesIdeias
|
2
2
|
module I18n
|
3
3
|
class Engine < ::Rails::Engine
|
4
|
-
|
4
|
+
I18N_TRANSLATIONS_ASSET = "i18n/translations"
|
5
|
+
|
6
|
+
initializer "i18n-js.asset_dependencies", :after => "sprockets.environment" do
|
7
|
+
next unless SimplesIdeias::I18n.has_asset_pipeline?
|
8
|
+
|
9
|
+
config = Rails.root.join("config", "i18n-js.yml")
|
10
|
+
cache_file = I18n::Engine.load_path_hash_cache
|
11
|
+
|
12
|
+
Rails.application.assets.register_preprocessor "application/javascript", :"i18n-js_dependencies" do |context, data|
|
13
|
+
if context.logical_path == I18N_TRANSLATIONS_ASSET
|
14
|
+
context.depend_on(config)
|
15
|
+
# also set up dependencies on every locale file
|
16
|
+
::I18n.load_path.each {|path| context.depend_on(path)}
|
17
|
+
|
18
|
+
# Set up a dependency on the contents of the load path
|
19
|
+
# itself. In some situations it is possible to get here
|
20
|
+
# before the path hash cache file has been written; in
|
21
|
+
# this situation, write it now.
|
22
|
+
I18n::Engine.write_hash! unless File.exists?(cache_file)
|
23
|
+
context.depend_on(cache_file)
|
24
|
+
end
|
25
|
+
|
26
|
+
data
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# rewrite path cache hash at startup and before each request in development
|
31
|
+
config.to_prepare do
|
32
|
+
SimplesIdeias::I18n::Engine.write_hash_if_changed unless Rails.env.production?
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.load_path_hash_cache
|
36
|
+
@load_path_hash_cache ||= File.join(Rails.application.paths["tmp"].first, "i18n-js.i18n_path_cache.dat")
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.write_hash_if_changed
|
40
|
+
load_path_hash = ::I18n.load_path.hash
|
41
|
+
|
42
|
+
if load_path_hash != cached_load_path_hash
|
43
|
+
self.cached_load_path_hash = load_path_hash
|
44
|
+
write_hash!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.write_hash!
|
49
|
+
File.open(load_path_hash_cache, "w") do |f|
|
50
|
+
f.write(cached_load_path_hash)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
attr_accessor :cached_load_path_hash
|
56
|
+
end
|
5
57
|
end
|
6
58
|
end
|
7
59
|
end
|
data/lib/i18n-js/middleware.rb
CHANGED
@@ -26,26 +26,33 @@ module SimplesIdeias
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
# Check if translations should be regenerated.
|
30
|
+
# ONLY REGENERATE when these conditions are met:
|
31
|
+
#
|
32
|
+
# # Cache file doesn't exist
|
33
|
+
# # Translations and cache size are different (files were removed/added)
|
34
|
+
# # Translation file has been updated
|
35
|
+
#
|
29
36
|
def verify_locale_files!
|
30
37
|
valid_cache = []
|
31
|
-
|
38
|
+
new_cache = {}
|
32
39
|
|
33
40
|
valid_cache.push cache_path.exist?
|
34
|
-
valid_cache.push ::I18n.load_path.size == cache.size
|
41
|
+
valid_cache.push ::I18n.load_path.uniq.size == cache.size
|
35
42
|
|
36
43
|
::I18n.load_path.each do |path|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
changed_files << path if file_has_changed
|
41
|
-
cache[path] = change
|
44
|
+
changed_at = File.mtime(path).to_i
|
45
|
+
valid_cache.push changed_at == cache[path]
|
46
|
+
new_cache[path] = changed_at
|
42
47
|
end
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
unless valid_cache.all?
|
50
|
+
File.open(cache_path, "w+") do |file|
|
51
|
+
file << new_cache.to_yaml
|
52
|
+
end
|
47
53
|
|
48
|
-
|
54
|
+
SimplesIdeias::I18n.export!
|
55
|
+
end
|
49
56
|
end
|
50
57
|
end
|
51
58
|
end
|
data/lib/i18n-js/railtie.rb
CHANGED
@@ -6,7 +6,7 @@ module SimplesIdeias
|
|
6
6
|
end
|
7
7
|
|
8
8
|
initializer "i18n-js.initialize" do |app|
|
9
|
-
app.config.middleware.use(Middleware) if Rails.env.development?
|
9
|
+
app.config.middleware.use(Middleware) if Rails.env.development? && !SimplesIdeias::I18n.has_asset_pipeline?
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/i18n-js/version.rb
CHANGED
data/spec/i18n_spec.js
CHANGED
@@ -135,6 +135,22 @@ describe("I18n.js", function(){
|
|
135
135
|
expect(I18n.t("greetings.stranger")).toBeEqualTo("Hello stranger!");
|
136
136
|
});
|
137
137
|
|
138
|
+
specify("translation with default locale option", function(){
|
139
|
+
expect(I18n.t("hello", {locale: "en"})).toBeEqualTo("Hello World!");
|
140
|
+
expect(I18n.t("hello", {locale: "pt-BR"})).toBeEqualTo("Olá Mundo!");
|
141
|
+
});
|
142
|
+
|
143
|
+
specify("translation should fall if locale is missing", function(){
|
144
|
+
I18n.locale = "pt-BR";
|
145
|
+
expect(I18n.t("greetings.stranger")).toBeEqualTo("[missing \"pt-BR.greetings.stranger\" translation]");
|
146
|
+
});
|
147
|
+
|
148
|
+
specify("translation should handle fallback if I18n.fallbacks == true", function(){
|
149
|
+
I18n.locale = "pt-BR";
|
150
|
+
I18n.fallbacks = true;
|
151
|
+
expect(I18n.t("greetings.stranger")).toBeEqualTo("Hello stranger!");
|
152
|
+
});
|
153
|
+
|
138
154
|
specify("single interpolation", function(){
|
139
155
|
actual = I18n.t("greetings.name", {name: "John Doe"});
|
140
156
|
expect(actual).toBeEqualTo("Hello John Doe!");
|
data/spec/i18n_spec.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
if File.basename(Rails.root) != "tmp"
|
4
|
-
|
4
|
+
abort <<-TXT
|
5
5
|
\e[31;5m
|
6
6
|
WARNING: That will remove your project!
|
7
7
|
Please go to #{File.expand_path(File.dirname(__FILE__) + "/..")} and run `rake spec`\e[0m
|
8
8
|
TXT
|
9
|
-
exit 1
|
10
9
|
end
|
11
10
|
|
12
11
|
describe SimplesIdeias::I18n do
|
@@ -88,10 +87,16 @@ describe SimplesIdeias::I18n do
|
|
88
87
|
File.should be_file(Rails.root.join("public/javascripts/tudo.js"))
|
89
88
|
end
|
90
89
|
|
90
|
+
it "ignores an empty config file" do
|
91
|
+
set_config "no_config.yml"
|
92
|
+
SimplesIdeias::I18n.export!
|
93
|
+
Rails.root.join(SimplesIdeias::I18n.export_dir, "translations.js").should be_file
|
94
|
+
end
|
95
|
+
|
91
96
|
it "exports to a JS file per available locale" do
|
92
97
|
set_config "js_file_per_locale.yml"
|
93
98
|
SimplesIdeias::I18n.export!
|
94
|
-
|
99
|
+
|
95
100
|
File.should be_file(Rails.root.join("public/javascripts/i18n/en.js"))
|
96
101
|
end
|
97
102
|
|
@@ -154,7 +159,7 @@ describe SimplesIdeias::I18n do
|
|
154
159
|
end
|
155
160
|
|
156
161
|
it "updates the javascript library" do
|
157
|
-
FakeWeb.register_uri(:get, "
|
162
|
+
FakeWeb.register_uri(:get, "https://raw.github.com/fnando/i18n-js/master/vendor/assets/javascripts/i18n.js", :body => "UPDATED")
|
158
163
|
|
159
164
|
SimplesIdeias::I18n.setup!
|
160
165
|
SimplesIdeias::I18n.update!
|
@@ -162,24 +167,28 @@ describe SimplesIdeias::I18n do
|
|
162
167
|
end
|
163
168
|
|
164
169
|
describe "#export_dir" do
|
165
|
-
it "detects
|
166
|
-
|
167
|
-
Rails.stub_chain(:configuration, :assets, :enabled => true)
|
170
|
+
it "detects asset pipeline support" do
|
171
|
+
SimplesIdeias::I18n.stub :has_asset_pipeline? => true
|
168
172
|
SimplesIdeias::I18n.export_dir == "vendor/assets/javascripts"
|
169
173
|
end
|
170
174
|
|
171
|
-
it "detects Rails 3.1 with asset pipeline disabled" do
|
172
|
-
Rails.version = "3.1"
|
173
|
-
Rails.stub_chain(:configuration, :assets, :enabled => false)
|
174
|
-
SimplesIdeias::I18n.export_dir == "public/javascripts"
|
175
|
-
end
|
176
|
-
|
177
175
|
it "detects older Rails" do
|
178
|
-
|
176
|
+
SimplesIdeias::I18n.stub :has_asset_pipeline? => false
|
179
177
|
SimplesIdeias::I18n.export_dir.to_s.should == "public/javascripts"
|
180
178
|
end
|
181
179
|
end
|
182
180
|
|
181
|
+
describe "#has_asset_pipeline?" do
|
182
|
+
it "detects support" do
|
183
|
+
Rails.stub_chain(:configuration, :assets, :enabled => true)
|
184
|
+
SimplesIdeias::I18n.should have_asset_pipeline
|
185
|
+
end
|
186
|
+
|
187
|
+
it "skips support" do
|
188
|
+
SimplesIdeias::I18n.should_not have_asset_pipeline
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
183
192
|
private
|
184
193
|
# Set the configuration as the current one
|
185
194
|
def set_config(path)
|
@@ -193,3 +202,4 @@ describe SimplesIdeias::I18n do
|
|
193
202
|
SimplesIdeias::I18n.translations
|
194
203
|
end
|
195
204
|
end
|
205
|
+
|
@@ -4,6 +4,9 @@ var I18n = I18n || {};
|
|
4
4
|
// Set default locale to english
|
5
5
|
I18n.defaultLocale = "en";
|
6
6
|
|
7
|
+
// Set default handling of translation fallbacks to false
|
8
|
+
I18n.fallbacks = false;
|
9
|
+
|
7
10
|
// Set default separator
|
8
11
|
I18n.defaultSeparator = ".";
|
9
12
|
|
@@ -13,18 +16,20 @@ I18n.locale = null;
|
|
13
16
|
// Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.
|
14
17
|
I18n.PLACEHOLDER = /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm;
|
15
18
|
|
16
|
-
I18n.isValidNode = function(obj, node) {
|
17
|
-
|
18
|
-
var undef;
|
19
|
-
return obj[node] !== null && obj[node] !== undef;
|
19
|
+
I18n.isValidNode = function(obj, node, undefined) {
|
20
|
+
return obj[node] !== null && obj[node] !== undefined;
|
20
21
|
}
|
21
22
|
|
22
23
|
I18n.lookup = function(scope, options) {
|
23
|
-
var
|
24
|
-
|
25
|
-
|
24
|
+
var options = options || {}
|
25
|
+
, lookupInitialScope = scope
|
26
|
+
, translations = this.prepareOptions(I18n.translations)
|
27
|
+
, messages = translations[options.locale || I18n.currentLocale()]
|
28
|
+
, options = this.prepareOptions(options)
|
29
|
+
, currentScope
|
30
|
+
;
|
26
31
|
|
27
|
-
if (!messages)
|
32
|
+
if (!messages){
|
28
33
|
return;
|
29
34
|
}
|
30
35
|
|
@@ -39,10 +44,13 @@ I18n.lookup = function(scope, options) {
|
|
39
44
|
scope = scope.split(this.defaultSeparator);
|
40
45
|
|
41
46
|
while (scope.length > 0) {
|
42
|
-
|
47
|
+
currentScope = scope.shift();
|
43
48
|
messages = messages[currentScope];
|
44
49
|
|
45
50
|
if (!messages) {
|
51
|
+
if (I18n.fallbacks && !options.fallback) {
|
52
|
+
messages = I18n.lookup(lookupInitialScope, this.prepareOptions({ locale: I18n.defaultLocale, fallback: true }, options));
|
53
|
+
}
|
46
54
|
break;
|
47
55
|
}
|
48
56
|
}
|
@@ -61,9 +69,10 @@ I18n.lookup = function(scope, options) {
|
|
61
69
|
// #=> {name: "John Doe", role: "user"}
|
62
70
|
//
|
63
71
|
I18n.prepareOptions = function() {
|
64
|
-
var options = {}
|
65
|
-
|
66
|
-
|
72
|
+
var options = {}
|
73
|
+
, opts
|
74
|
+
, count = arguments.length
|
75
|
+
;
|
67
76
|
|
68
77
|
for (var i = 0; i < count; i++) {
|
69
78
|
opts = arguments[i];
|
@@ -84,14 +93,16 @@ I18n.prepareOptions = function() {
|
|
84
93
|
|
85
94
|
I18n.interpolate = function(message, options) {
|
86
95
|
options = this.prepareOptions(options);
|
87
|
-
var matches = message.match(this.PLACEHOLDER)
|
96
|
+
var matches = message.match(this.PLACEHOLDER)
|
97
|
+
, placeholder
|
98
|
+
, value
|
99
|
+
, name
|
100
|
+
;
|
88
101
|
|
89
102
|
if (!matches) {
|
90
103
|
return message;
|
91
104
|
}
|
92
105
|
|
93
|
-
var placeholder, value, name;
|
94
|
-
|
95
106
|
for (var i = 0; placeholder = matches[i]; i++) {
|
96
107
|
name = placeholder.replace(this.PLACEHOLDER, "$1");
|
97
108
|
|
@@ -193,8 +204,9 @@ I18n.parseDate = function(date) {
|
|
193
204
|
};
|
194
205
|
|
195
206
|
I18n.toTime = function(scope, d) {
|
196
|
-
var date = this.parseDate(d)
|
197
|
-
|
207
|
+
var date = this.parseDate(d)
|
208
|
+
, format = this.lookup(scope)
|
209
|
+
;
|
198
210
|
|
199
211
|
if (date.toString().match(/invalid/i)) {
|
200
212
|
return date.toString();
|
@@ -213,21 +225,23 @@ I18n.strftime = function(date, format) {
|
|
213
225
|
if (!options) {
|
214
226
|
return date.toString();
|
215
227
|
}
|
228
|
+
|
216
229
|
options.meridian = options.meridian || ["AM", "PM"];
|
217
230
|
|
218
|
-
var weekDay = date.getDay()
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
+
var weekDay = date.getDay()
|
232
|
+
, day = date.getDate()
|
233
|
+
, year = date.getFullYear()
|
234
|
+
, month = date.getMonth() + 1
|
235
|
+
, hour = date.getHours()
|
236
|
+
, hour12 = hour
|
237
|
+
, meridian = hour > 11 ? 1 : 0
|
238
|
+
, secs = date.getSeconds()
|
239
|
+
, mins = date.getMinutes()
|
240
|
+
, offset = date.getTimezoneOffset()
|
241
|
+
, absOffsetHours = Math.floor(Math.abs(offset / 60))
|
242
|
+
, absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60)
|
243
|
+
, timezoneoffset = (offset > 0 ? "-" : "+") + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes)
|
244
|
+
;
|
231
245
|
|
232
246
|
if (hour12 > 12) {
|
233
247
|
hour12 = hour12 - 12;
|
@@ -275,21 +289,23 @@ I18n.toNumber = function(number, options) {
|
|
275
289
|
{precision: 3, separator: ".", delimiter: ",", strip_insignificant_zeros: false}
|
276
290
|
);
|
277
291
|
|
278
|
-
var negative = number < 0
|
279
|
-
|
280
|
-
|
292
|
+
var negative = number < 0
|
293
|
+
, string = Math.abs(number).toFixed(options.precision).toString()
|
294
|
+
, parts = string.split(".")
|
295
|
+
, precision
|
296
|
+
, buffer = []
|
297
|
+
, formattedNumber
|
298
|
+
;
|
281
299
|
|
282
300
|
number = parts[0];
|
283
|
-
|
284
|
-
|
285
|
-
var n = [];
|
301
|
+
precision = parts[1];
|
286
302
|
|
287
303
|
while (number.length > 0) {
|
288
|
-
|
304
|
+
buffer.unshift(number.substr(Math.max(0, number.length - 3), 3));
|
289
305
|
number = number.substr(0, number.length -3);
|
290
306
|
}
|
291
307
|
|
292
|
-
|
308
|
+
formattedNumber = buffer.join(options.delimiter);
|
293
309
|
|
294
310
|
if (options.precision > 0) {
|
295
311
|
formattedNumber += options.separator + parts[1];
|
@@ -307,7 +323,8 @@ I18n.toNumber = function(number, options) {
|
|
307
323
|
|
308
324
|
formattedNumber = formattedNumber
|
309
325
|
.replace(regex.zeros, "")
|
310
|
-
.replace(regex.separator, "")
|
326
|
+
.replace(regex.separator, "")
|
327
|
+
;
|
311
328
|
}
|
312
329
|
|
313
330
|
return formattedNumber;
|
@@ -324,7 +341,8 @@ I18n.toCurrency = function(number, options) {
|
|
324
341
|
number = this.toNumber(number, options);
|
325
342
|
number = options.format
|
326
343
|
.replace("%u", options.unit)
|
327
|
-
.replace("%n", number)
|
344
|
+
.replace("%n", number)
|
345
|
+
;
|
328
346
|
|
329
347
|
return number;
|
330
348
|
};
|
@@ -358,7 +376,8 @@ I18n.toHumanSize = function(number, options) {
|
|
358
376
|
number = this.toNumber(size, options);
|
359
377
|
number = options.format
|
360
378
|
.replace("%u", unit)
|
361
|
-
.replace("%n", number)
|
379
|
+
.replace("%n", number)
|
380
|
+
;
|
362
381
|
|
363
382
|
return number;
|
364
383
|
};
|
@@ -408,8 +427,9 @@ I18n.pluralize = function(count, scope, options) {
|
|
408
427
|
};
|
409
428
|
|
410
429
|
I18n.missingTranslation = function() {
|
411
|
-
var message = '[missing "' + this.currentLocale()
|
412
|
-
|
430
|
+
var message = '[missing "' + this.currentLocale()
|
431
|
+
, count = arguments.length
|
432
|
+
;
|
413
433
|
|
414
434
|
for (var i = 0; i < count; i++) {
|
415
435
|
message += "." + arguments[i];
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: i18n
|
16
|
-
requirement: &
|
16
|
+
requirement: &70281327448420 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70281327448420
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: fakeweb
|
27
|
-
requirement: &
|
27
|
+
requirement: &70281327447820 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70281327447820
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activesupport
|
38
|
-
requirement: &
|
38
|
+
requirement: &70281327437540 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 3.0.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70281327437540
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &70281327436980 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,21 +54,10 @@ dependencies:
|
|
54
54
|
version: '2.6'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: ruby-debug19
|
60
|
-
requirement: &70095310293060 !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
|
-
requirements:
|
63
|
-
- - ! '>='
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
version: '0'
|
66
|
-
type: :development
|
67
|
-
prerelease: false
|
68
|
-
version_requirements: *70095310293060
|
57
|
+
version_requirements: *70281327436980
|
69
58
|
- !ruby/object:Gem::Dependency
|
70
59
|
name: spec-js
|
71
|
-
requirement: &
|
60
|
+
requirement: &70281327436280 !ruby/object:Gem::Requirement
|
72
61
|
none: false
|
73
62
|
requirements:
|
74
63
|
- - ~>
|
@@ -76,10 +65,10 @@ dependencies:
|
|
76
65
|
version: 0.1.0.beta.0
|
77
66
|
type: :development
|
78
67
|
prerelease: false
|
79
|
-
version_requirements: *
|
68
|
+
version_requirements: *70281327436280
|
80
69
|
- !ruby/object:Gem::Dependency
|
81
70
|
name: rake
|
82
|
-
requirement: &
|
71
|
+
requirement: &70281327435620 !ruby/object:Gem::Requirement
|
83
72
|
none: false
|
84
73
|
requirements:
|
85
74
|
- - ! '>='
|
@@ -87,10 +76,10 @@ dependencies:
|
|
87
76
|
version: '0'
|
88
77
|
type: :development
|
89
78
|
prerelease: false
|
90
|
-
version_requirements: *
|
79
|
+
version_requirements: *70281327435620
|
91
80
|
- !ruby/object:Gem::Dependency
|
92
|
-
name:
|
93
|
-
requirement: &
|
81
|
+
name: pry
|
82
|
+
requirement: &70281327434980 !ruby/object:Gem::Requirement
|
94
83
|
none: false
|
95
84
|
requirements:
|
96
85
|
- - ! '>='
|
@@ -98,7 +87,7 @@ dependencies:
|
|
98
87
|
version: '0'
|
99
88
|
type: :development
|
100
89
|
prerelease: false
|
101
|
-
version_requirements: *
|
90
|
+
version_requirements: *70281327434980
|
102
91
|
description: It's a small library to provide the Rails I18n translations on the Javascript.
|
103
92
|
email:
|
104
93
|
- fnando.vieira@gmail.com
|
@@ -128,10 +117,12 @@ files:
|
|
128
117
|
- spec/resources/locales.yml
|
129
118
|
- spec/resources/multiple_conditions.yml
|
130
119
|
- spec/resources/multiple_files.yml
|
120
|
+
- spec/resources/no_config.yml
|
131
121
|
- spec/resources/no_scope.yml
|
132
122
|
- spec/resources/simple_scope.yml
|
133
123
|
- spec/spec_helper.rb
|
134
124
|
- vendor/assets/javascripts/i18n.js
|
125
|
+
- vendor/assets/javascripts/i18n/translations.js.erb
|
135
126
|
homepage: http://rubygems.org/gems/i18n-js
|
136
127
|
licenses: []
|
137
128
|
post_install_message:
|
@@ -146,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
137
|
version: '0'
|
147
138
|
segments:
|
148
139
|
- 0
|
149
|
-
hash:
|
140
|
+
hash: -2888069354346865938
|
150
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
142
|
none: false
|
152
143
|
requirements:
|
@@ -155,10 +146,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
146
|
version: '0'
|
156
147
|
segments:
|
157
148
|
- 0
|
158
|
-
hash:
|
149
|
+
hash: -2888069354346865938
|
159
150
|
requirements: []
|
160
151
|
rubyforge_project:
|
161
|
-
rubygems_version: 1.8.
|
152
|
+
rubygems_version: 1.8.11
|
162
153
|
signing_key:
|
163
154
|
specification_version: 3
|
164
155
|
summary: It's a small library to provide the Rails I18n translations on the Javascript.
|
@@ -171,6 +162,7 @@ test_files:
|
|
171
162
|
- spec/resources/locales.yml
|
172
163
|
- spec/resources/multiple_conditions.yml
|
173
164
|
- spec/resources/multiple_files.yml
|
165
|
+
- spec/resources/no_config.yml
|
174
166
|
- spec/resources/no_scope.yml
|
175
167
|
- spec/resources/simple_scope.yml
|
176
168
|
- spec/spec_helper.rb
|