i18n-js 3.9.2 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +4 -0
- data/.github/FUNDING.yml +1 -1
- data/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +38 -0
- data/.github/dependabot.yml +15 -0
- data/.github/workflows/ruby-tests.yml +52 -0
- data/.gitignore +11 -7
- data/.rubocop.yml +16 -0
- data/CHANGELOG.md +17 -569
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +79 -0
- data/Gemfile +3 -0
- data/LICENSE.md +20 -0
- data/MIGRATING_FROM_V3_TO_V4.md +191 -0
- data/README.md +206 -997
- data/Rakefile +10 -20
- data/exe/i18n +5 -0
- data/i18n-js.gemspec +48 -29
- data/lib/guard/i18n-js/templates/Guardfile +10 -0
- data/lib/guard/i18n-js/version.rb +13 -0
- data/lib/guard/i18n-js.rb +95 -0
- data/lib/i18n-js/cli/check_command.rb +157 -0
- data/lib/i18n-js/cli/command.rb +69 -0
- data/lib/i18n-js/cli/export_command.rb +95 -0
- data/lib/i18n-js/cli/init_command.rb +52 -0
- data/lib/i18n-js/cli/ui.rb +64 -0
- data/lib/i18n-js/cli/version_command.rb +18 -0
- data/lib/i18n-js/cli.rb +55 -0
- data/lib/i18n-js/listen.rb +95 -0
- data/lib/i18n-js/schema.rb +104 -0
- data/lib/i18n-js/version.rb +5 -0
- data/lib/i18n-js.rb +73 -1
- metadata +127 -199
- data/.editorconfig +0 -24
- data/.github/workflows/tests.yaml +0 -106
- data/.npmignore +0 -27
- data/Appraisals +0 -52
- data/app/assets/javascripts/i18n/filtered.js.erb +0 -23
- data/app/assets/javascripts/i18n/shims.js +0 -240
- data/app/assets/javascripts/i18n/translations.js +0 -3
- data/app/assets/javascripts/i18n.js +0 -1095
- data/gemfiles/i18n_0_6.gemfile +0 -7
- data/gemfiles/i18n_0_7.gemfile +0 -7
- data/gemfiles/i18n_0_8.gemfile +0 -7
- data/gemfiles/i18n_0_9.gemfile +0 -7
- data/gemfiles/i18n_1_0.gemfile +0 -7
- data/gemfiles/i18n_1_1.gemfile +0 -7
- data/gemfiles/i18n_1_10.gemfile +0 -7
- data/gemfiles/i18n_1_2.gemfile +0 -7
- data/gemfiles/i18n_1_3.gemfile +0 -7
- data/gemfiles/i18n_1_4.gemfile +0 -7
- data/gemfiles/i18n_1_5.gemfile +0 -7
- data/gemfiles/i18n_1_6.gemfile +0 -7
- data/gemfiles/i18n_1_7.gemfile +0 -7
- data/gemfiles/i18n_1_8.gemfile +0 -7
- data/gemfiles/i18n_1_9.gemfile +0 -7
- data/i18njs.png +0 -0
- data/lib/i18n/js/dependencies.rb +0 -67
- data/lib/i18n/js/engine.rb +0 -87
- data/lib/i18n/js/fallback_locales.rb +0 -70
- data/lib/i18n/js/formatters/base.rb +0 -25
- data/lib/i18n/js/formatters/js.rb +0 -39
- data/lib/i18n/js/formatters/json.rb +0 -13
- data/lib/i18n/js/middleware.rb +0 -82
- data/lib/i18n/js/private/config_store.rb +0 -31
- data/lib/i18n/js/private/hash_with_symbol_keys.rb +0 -36
- data/lib/i18n/js/segment.rb +0 -81
- data/lib/i18n/js/utils.rb +0 -91
- data/lib/i18n/js/version.rb +0 -7
- data/lib/i18n/js.rb +0 -274
- data/lib/rails/generators/i18n/js/config/config_generator.rb +0 -19
- data/lib/rails/generators/i18n/js/config/templates/i18n-js.yml +0 -27
- data/lib/tasks/export.rake +0 -8
- data/package.json +0 -25
- data/spec/fixtures/custom_path.yml +0 -5
- data/spec/fixtures/default.yml +0 -5
- data/spec/fixtures/erb.yml +0 -5
- data/spec/fixtures/except_condition.yml +0 -7
- data/spec/fixtures/js_available_locales_custom.yml +0 -1
- data/spec/fixtures/js_export_dir_custom.yml +0 -7
- data/spec/fixtures/js_export_dir_none.yml +0 -6
- data/spec/fixtures/js_extend_parent.yml +0 -6
- data/spec/fixtures/js_extend_segment.yml +0 -6
- data/spec/fixtures/js_file_per_locale.yml +0 -7
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml +0 -4
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml +0 -6
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml +0 -4
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml +0 -4
- data/spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml +0 -4
- data/spec/fixtures/js_file_per_locale_without_fallbacks.yml +0 -4
- data/spec/fixtures/js_file_with_namespace_prefix_and_pretty_print.yml +0 -9
- data/spec/fixtures/js_sort_translation_keys_false.yml +0 -6
- data/spec/fixtures/js_sort_translation_keys_true.yml +0 -6
- data/spec/fixtures/json_only.yml +0 -18
- data/spec/fixtures/locales.yml +0 -133
- data/spec/fixtures/merge_plurals.yml +0 -6
- data/spec/fixtures/merge_plurals_with_no_overrides.yml +0 -4
- data/spec/fixtures/merge_plurals_with_partial_overrides.yml +0 -4
- data/spec/fixtures/millions.yml +0 -4
- data/spec/fixtures/multiple_conditions.yml +0 -7
- data/spec/fixtures/multiple_conditions_per_locale.yml +0 -7
- data/spec/fixtures/multiple_files.yml +0 -7
- data/spec/fixtures/no_config.yml +0 -2
- data/spec/fixtures/no_scope.yml +0 -4
- data/spec/fixtures/simple_scope.yml +0 -5
- data/spec/js/currency.spec.js +0 -62
- data/spec/js/current_locale.spec.js +0 -19
- data/spec/js/dates.spec.js +0 -276
- data/spec/js/defaults.spec.js +0 -31
- data/spec/js/extend.spec.js +0 -110
- data/spec/js/interpolation.spec.js +0 -124
- data/spec/js/jasmine/MIT.LICENSE +0 -20
- data/spec/js/jasmine/jasmine-html.js +0 -190
- data/spec/js/jasmine/jasmine.css +0 -166
- data/spec/js/jasmine/jasmine.js +0 -2476
- data/spec/js/jasmine/jasmine_favicon.png +0 -0
- data/spec/js/json_parsable.spec.js +0 -14
- data/spec/js/locales.spec.js +0 -31
- data/spec/js/localization.spec.js +0 -78
- data/spec/js/numbers.spec.js +0 -174
- data/spec/js/placeholder.spec.js +0 -24
- data/spec/js/pluralization.spec.js +0 -228
- data/spec/js/prepare_options.spec.js +0 -41
- data/spec/js/require.js +0 -2083
- data/spec/js/specs.html +0 -49
- data/spec/js/specs_requirejs.html +0 -72
- data/spec/js/translate.spec.js +0 -304
- data/spec/js/translations.js +0 -188
- data/spec/js/utility_functions.spec.js +0 -20
- data/spec/ruby/i18n/js/fallback_locales_spec.rb +0 -84
- data/spec/ruby/i18n/js/segment_spec.rb +0 -286
- data/spec/ruby/i18n/js/utils_spec.rb +0 -138
- data/spec/ruby/i18n/js_spec.rb +0 -797
- data/spec/spec_helper.rb +0 -80
- data/yarn.lock +0 -138
data/gemfiles/i18n_0_6.gemfile
DELETED
data/gemfiles/i18n_0_7.gemfile
DELETED
data/gemfiles/i18n_0_8.gemfile
DELETED
data/gemfiles/i18n_0_9.gemfile
DELETED
data/gemfiles/i18n_1_0.gemfile
DELETED
data/gemfiles/i18n_1_1.gemfile
DELETED
data/gemfiles/i18n_1_10.gemfile
DELETED
data/gemfiles/i18n_1_2.gemfile
DELETED
data/gemfiles/i18n_1_3.gemfile
DELETED
data/gemfiles/i18n_1_4.gemfile
DELETED
data/gemfiles/i18n_1_5.gemfile
DELETED
data/gemfiles/i18n_1_6.gemfile
DELETED
data/gemfiles/i18n_1_7.gemfile
DELETED
data/gemfiles/i18n_1_8.gemfile
DELETED
data/gemfiles/i18n_1_9.gemfile
DELETED
data/i18njs.png
DELETED
Binary file
|
data/lib/i18n/js/dependencies.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
module I18n
|
2
|
-
module JS
|
3
|
-
# When using `safe_gem_check` to check for a pre-release version of gem,
|
4
|
-
# we need to specify pre-release version suffix in version constraint
|
5
|
-
module Dependencies
|
6
|
-
class << self
|
7
|
-
def rails?
|
8
|
-
defined?(Rails) && Rails.respond_to?(:version)
|
9
|
-
end
|
10
|
-
|
11
|
-
def sprockets_rails_v2_plus?
|
12
|
-
safe_gem_check("sprockets-rails", ">= 2")
|
13
|
-
end
|
14
|
-
|
15
|
-
# This cannot be called at class definition time
|
16
|
-
# Since not all libraries are loaded
|
17
|
-
#
|
18
|
-
# Call this in an initializer
|
19
|
-
def using_asset_pipeline?
|
20
|
-
assets_pipeline_available =
|
21
|
-
(rails3? || rails4? || rails5? || rails6? || rails7?) &&
|
22
|
-
Rails.respond_to?(:application) &&
|
23
|
-
Rails.application.config.respond_to?(:assets)
|
24
|
-
rails3_assets_enabled =
|
25
|
-
rails3? &&
|
26
|
-
assets_pipeline_available &&
|
27
|
-
Rails.application.config.assets.enabled != false
|
28
|
-
|
29
|
-
assets_pipeline_available && (rails4? || rails5? || rails6? || rails7? || rails3_assets_enabled)
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def rails3?
|
35
|
-
rails? && Rails.version.to_i == 3
|
36
|
-
end
|
37
|
-
|
38
|
-
def rails4?
|
39
|
-
rails? && Rails.version.to_i == 4
|
40
|
-
end
|
41
|
-
|
42
|
-
def rails5?
|
43
|
-
rails? && Rails.version.to_i == 5
|
44
|
-
end
|
45
|
-
|
46
|
-
def rails6?
|
47
|
-
rails? && Rails.version.to_i == 6
|
48
|
-
end
|
49
|
-
|
50
|
-
def rails7?
|
51
|
-
rails? && Rails.version.to_i == 7
|
52
|
-
end
|
53
|
-
|
54
|
-
def safe_gem_check(*args)
|
55
|
-
if Gem::Specification.respond_to?(:find_by_name)
|
56
|
-
Gem::Specification.find_by_name(*args)
|
57
|
-
elsif Gem.respond_to?(:available?)
|
58
|
-
Gem.available?(*args)
|
59
|
-
end
|
60
|
-
rescue Gem::LoadError
|
61
|
-
false
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
data/lib/i18n/js/engine.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
require "i18n/js"
|
2
|
-
|
3
|
-
module I18n
|
4
|
-
module JS
|
5
|
-
# @api private
|
6
|
-
# The class cannot be private
|
7
|
-
class SprocketsExtension
|
8
|
-
# Actual definition is placed below
|
9
|
-
end
|
10
|
-
|
11
|
-
class Engine < ::Rails::Engine
|
12
|
-
# See https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
|
13
|
-
# for reference of supporting multiple versions
|
14
|
-
|
15
|
-
# `sprockets.environment` was used for 1.x of `sprockets-rails`
|
16
|
-
# https://github.com/rails/sprockets-rails/issues/227
|
17
|
-
#
|
18
|
-
# References for current values:
|
19
|
-
#
|
20
|
-
# Here is where sprockets are attached with Rails. There is no 'sprockets.environment' mentioned.
|
21
|
-
# https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb
|
22
|
-
#
|
23
|
-
# Finisher hook is the place which should be used as border.
|
24
|
-
# https://guides.rubyonrails.org/configuring.html#initializers
|
25
|
-
#
|
26
|
-
# For detail see Pull Request:
|
27
|
-
# https://github.com/fnando/i18n-js/pull/371
|
28
|
-
initializer "i18n-js.register_preprocessor", after: :engines_blank_point, before: :finisher_hook do
|
29
|
-
# This must be called inside initializer block
|
30
|
-
# For details see comments for `using_asset_pipeline?`
|
31
|
-
next unless JS::Dependencies.using_asset_pipeline?
|
32
|
-
|
33
|
-
# From README of 2.x & 3.x of `sprockets-rails`
|
34
|
-
# It seems the `configure` block is preferred way to call `register_preprocessor`
|
35
|
-
# Not sure if this will break older versions of rails
|
36
|
-
#
|
37
|
-
# https://github.com/rails/sprockets-rails/blob/v2.3.3/README.md
|
38
|
-
# https://github.com/rails/sprockets-rails/blob/v3.0.0/README.md
|
39
|
-
if JS::Dependencies.sprockets_rails_v2_plus?
|
40
|
-
Rails.application.config.assets.configure do |config|
|
41
|
-
config.register_preprocessor("application/javascript", ::I18n::JS::SprocketsExtension)
|
42
|
-
end
|
43
|
-
elsif Rails.application.assets.respond_to?(:register_preprocessor)
|
44
|
-
Rails.application.assets.register_preprocessor("application/javascript", ::I18n::JS::SprocketsExtension)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# @api private
|
50
|
-
class SprocketsExtension
|
51
|
-
def initialize(filename, &block)
|
52
|
-
@filename = filename
|
53
|
-
@source = block.call
|
54
|
-
end
|
55
|
-
|
56
|
-
def render(context, empty_hash_wtf)
|
57
|
-
self.class.run(@filename, @source, context)
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.run(filename, source, context)
|
61
|
-
if context.logical_path == "i18n/filtered"
|
62
|
-
::I18n.load_path.each { |path| context.depend_on(File.expand_path(path)) }
|
63
|
-
|
64
|
-
# Absolute path is required or
|
65
|
-
# Sprockets assumes it's a logical path
|
66
|
-
#
|
67
|
-
# Calling `depend on` with an absent file
|
68
|
-
# will invoke `resolve` and will throw an error in the end
|
69
|
-
if I18n::JS.config_file_exists?
|
70
|
-
context.depend_on(File.expand_path(I18n::JS.config_file_path))
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
source
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.call(input)
|
78
|
-
filename = input[:filename]
|
79
|
-
source = input[:data]
|
80
|
-
context = input[:environment].context_class.new(input)
|
81
|
-
|
82
|
-
result = run(filename, source, context)
|
83
|
-
context.metadata.merge(data: result)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
module I18n
|
2
|
-
module JS
|
3
|
-
class FallbackLocales
|
4
|
-
attr_reader :fallbacks, :locale
|
5
|
-
|
6
|
-
def initialize(fallbacks, locale)
|
7
|
-
@fallbacks = fallbacks
|
8
|
-
@locale = locale
|
9
|
-
end
|
10
|
-
|
11
|
-
def each
|
12
|
-
locales.each { |locale| yield(locale) }
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [Array<String, Symbol>]
|
16
|
-
# An Array of locales to use as fallbacks for given locale.
|
17
|
-
def locales
|
18
|
-
locales = case fallbacks
|
19
|
-
when true
|
20
|
-
default_fallbacks
|
21
|
-
when :default_locale
|
22
|
-
[::I18n.default_locale]
|
23
|
-
when Symbol, String
|
24
|
-
[fallbacks.to_sym]
|
25
|
-
when Array
|
26
|
-
ensure_valid_fallbacks_as_array!
|
27
|
-
fallbacks
|
28
|
-
when Hash
|
29
|
-
Array(fallbacks[locale] || default_fallbacks)
|
30
|
-
else
|
31
|
-
fail ArgumentError, "fallbacks must be: true, :default_locale an Array or a Hash - given: #{fallbacks}"
|
32
|
-
end
|
33
|
-
|
34
|
-
locales.map! { |locale| locale.to_sym }
|
35
|
-
locales
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
# @return [Array<String, Symbol>] An Array of locales.
|
41
|
-
def default_fallbacks
|
42
|
-
if using_i18n_fallbacks_module?
|
43
|
-
I18n.fallbacks[locale]
|
44
|
-
else
|
45
|
-
[::I18n.default_locale]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# @return
|
50
|
-
# true if we can safely use I18n.fallbacks, false otherwise.
|
51
|
-
#
|
52
|
-
# @note
|
53
|
-
# We should implement this as `I18n.respond_to?(:fallbacks)`, but
|
54
|
-
# once I18n::Backend::Fallbacks is included, I18n will _always_
|
55
|
-
# respond to :fallbacks. Even if we switch the backend to one
|
56
|
-
# without fallbacks!
|
57
|
-
#
|
58
|
-
# Maybe this should be fixed within I18n.
|
59
|
-
def using_i18n_fallbacks_module?
|
60
|
-
I18n::JS.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
|
61
|
-
end
|
62
|
-
|
63
|
-
def ensure_valid_fallbacks_as_array!
|
64
|
-
return if fallbacks.all? { |e| e.is_a?(String) || e.is_a?(Symbol) }
|
65
|
-
|
66
|
-
fail ArgumentError, "If fallbacks is passed as Array, it must ony include Strings or Symbols. Given: #{fallbacks}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module I18n
|
2
|
-
module JS
|
3
|
-
module Formatters
|
4
|
-
class Base
|
5
|
-
def initialize(js_extend: false, namespace: nil, pretty_print: false, prefix: nil, suffix: nil)
|
6
|
-
@js_extend = js_extend
|
7
|
-
@namespace = namespace
|
8
|
-
@pretty_print = pretty_print
|
9
|
-
@prefix = prefix
|
10
|
-
@suffix = suffix
|
11
|
-
end
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
|
-
def format_json(translations)
|
16
|
-
if @pretty_print
|
17
|
-
::JSON.pretty_generate(translations)
|
18
|
-
else
|
19
|
-
translations.to_json
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require "i18n/js/formatters/base"
|
2
|
-
|
3
|
-
module I18n
|
4
|
-
module JS
|
5
|
-
module Formatters
|
6
|
-
class JS < Base
|
7
|
-
JSON_ESCAPE_MAP = {
|
8
|
-
"'" => "\\'",
|
9
|
-
"\\" => "\\\\"
|
10
|
-
}.freeze
|
11
|
-
private_constant :JSON_ESCAPE_MAP
|
12
|
-
|
13
|
-
def format(translations)
|
14
|
-
contents = header
|
15
|
-
translations.each do |locale, translations_for_locale|
|
16
|
-
contents << line(locale, format_json(translations_for_locale))
|
17
|
-
end
|
18
|
-
contents << (@suffix || '')
|
19
|
-
end
|
20
|
-
|
21
|
-
protected
|
22
|
-
|
23
|
-
def header
|
24
|
-
text = @prefix || ''
|
25
|
-
text + %(#{@namespace}.translations || (#{@namespace}.translations = {});\n)
|
26
|
-
end
|
27
|
-
|
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) }}'))
|
30
|
-
if @js_extend
|
31
|
-
%(#{@namespace}.translations["#{locale}"] = I18n.extend((#{@namespace}.translations["#{locale}"] || {}), #{json_literal});\n)
|
32
|
-
else
|
33
|
-
%(#{@namespace}.translations["#{locale}"] = #{json_literal};\n)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/i18n/js/middleware.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
|
3
|
-
module I18n
|
4
|
-
module JS
|
5
|
-
class Middleware
|
6
|
-
def initialize(app)
|
7
|
-
@app = app
|
8
|
-
clear_cache
|
9
|
-
end
|
10
|
-
|
11
|
-
def call(env)
|
12
|
-
@cache = nil
|
13
|
-
verify_locale_files!
|
14
|
-
@app.call(env)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
def cache_path
|
19
|
-
@cache_path ||= cache_dir.join("i18n-js.yml")
|
20
|
-
end
|
21
|
-
|
22
|
-
def cache_dir
|
23
|
-
@cache_dir ||= Rails.root.join("tmp/cache")
|
24
|
-
end
|
25
|
-
|
26
|
-
def cache
|
27
|
-
@cache ||= begin
|
28
|
-
if cache_path.exist?
|
29
|
-
YAML.load_file(cache_path) || {}
|
30
|
-
else
|
31
|
-
{}
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def clear_cache
|
37
|
-
# `File.delete` will raise error when "multiple worker"
|
38
|
-
# Are running at the same time, like in a parallel test
|
39
|
-
#
|
40
|
-
# `FileUtils.rm_f` is tested manually
|
41
|
-
#
|
42
|
-
# See https://github.com/fnando/i18n-js/issues/436
|
43
|
-
FileUtils.rm_f(cache_path) if File.exist?(cache_path)
|
44
|
-
end
|
45
|
-
|
46
|
-
def save_cache(new_cache)
|
47
|
-
# path could be a symbolic link
|
48
|
-
FileUtils.mkdir_p(cache_dir) unless File.exist?(cache_dir)
|
49
|
-
File.open(cache_path, "w+") do |file|
|
50
|
-
file << new_cache.to_yaml
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Check if translations should be regenerated.
|
55
|
-
# ONLY REGENERATE when these conditions are met:
|
56
|
-
#
|
57
|
-
# # Cache file doesn't exist
|
58
|
-
# # Translations and cache size are different (files were removed/added)
|
59
|
-
# # Translation file has been updated
|
60
|
-
#
|
61
|
-
def verify_locale_files!
|
62
|
-
valid_cache = []
|
63
|
-
new_cache = {}
|
64
|
-
|
65
|
-
valid_cache.push cache_path.exist?
|
66
|
-
valid_cache.push ::I18n.load_path.uniq.size == cache.size
|
67
|
-
|
68
|
-
::I18n.load_path.each do |path|
|
69
|
-
changed_at = File.mtime(path).to_i
|
70
|
-
valid_cache.push changed_at == cache[path]
|
71
|
-
new_cache[path] = changed_at
|
72
|
-
end
|
73
|
-
|
74
|
-
return if valid_cache.all?
|
75
|
-
|
76
|
-
save_cache(new_cache)
|
77
|
-
|
78
|
-
::I18n::JS.export
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "singleton"
|
4
|
-
|
5
|
-
module I18n
|
6
|
-
module JS
|
7
|
-
# @api private
|
8
|
-
module Private
|
9
|
-
# Caching implementation for I18n::JS.config
|
10
|
-
#
|
11
|
-
# @api private
|
12
|
-
class ConfigStore
|
13
|
-
include Singleton
|
14
|
-
|
15
|
-
def fetch
|
16
|
-
return @config if @config
|
17
|
-
|
18
|
-
yield.tap do |obj|
|
19
|
-
raise ArgumentError, "unexpected falsy object from block" unless obj
|
20
|
-
|
21
|
-
@config = obj
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def flush_cache
|
26
|
-
@config = nil
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module I18n
|
2
|
-
module JS
|
3
|
-
# @api private
|
4
|
-
module Private
|
5
|
-
# Hash with string keys converted to symbol keys
|
6
|
-
# Used for handling values read on YAML
|
7
|
-
#
|
8
|
-
# @api private
|
9
|
-
class HashWithSymbolKeys < ::Hash
|
10
|
-
# An instance can only be created by passing in another hash
|
11
|
-
def initialize(hash)
|
12
|
-
raise TypeError unless hash.is_a?(::Hash)
|
13
|
-
|
14
|
-
hash.each_key do |key|
|
15
|
-
# Objects like `Integer` does not have `to_sym`
|
16
|
-
new_key = key.respond_to?(:to_sym) ? key.to_sym : key
|
17
|
-
self[new_key] = hash[key]
|
18
|
-
end
|
19
|
-
|
20
|
-
self.default = hash.default if hash.default
|
21
|
-
self.default_proc = hash.default_proc if hash.default_proc
|
22
|
-
|
23
|
-
freeze
|
24
|
-
end
|
25
|
-
|
26
|
-
# From AS Core extension
|
27
|
-
def slice(*keys)
|
28
|
-
hash = keys.each_with_object(Hash.new) do |k, hash|
|
29
|
-
hash[k] = self[k] if has_key?(k)
|
30
|
-
end
|
31
|
-
self.class.new(hash)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/lib/i18n/js/segment.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
require "i18n/js/private/hash_with_symbol_keys"
|
2
|
-
require "i18n/js/formatters/js"
|
3
|
-
require "i18n/js/formatters/json"
|
4
|
-
|
5
|
-
module I18n
|
6
|
-
module JS
|
7
|
-
|
8
|
-
# Class which enscapulates a translations hash and outputs a single JSON translation file
|
9
|
-
class Segment
|
10
|
-
OPTIONS = [:namespace, :pretty_print, :js_extend, :prefix, :suffix, :sort_translation_keys, :json_only].freeze
|
11
|
-
LOCALE_INTERPOLATOR = /%\{locale\}/
|
12
|
-
|
13
|
-
attr_reader *([:file, :translations] | OPTIONS)
|
14
|
-
|
15
|
-
def initialize(file, translations, options = {})
|
16
|
-
@file = file
|
17
|
-
# `#slice` will be used
|
18
|
-
# But when activesupport is absent,
|
19
|
-
# the core extension from `i18n` gem will be used instead
|
20
|
-
# And it's causing errors (at least in test)
|
21
|
-
#
|
22
|
-
# So the input is wrapped by our class for better `#slice`
|
23
|
-
@translations = Private::HashWithSymbolKeys.new(translations)
|
24
|
-
@namespace = options[:namespace] || 'I18n'
|
25
|
-
@pretty_print = !!options[:pretty_print]
|
26
|
-
@js_extend = options.key?(:js_extend) ? !!options[:js_extend] : true
|
27
|
-
@prefix = options.key?(:prefix) ? options[:prefix] : nil
|
28
|
-
@suffix = options.key?(:suffix) ? options[:suffix] : nil
|
29
|
-
@sort_translation_keys = options.key?(:sort_translation_keys) ? !!options[:sort_translation_keys] : true
|
30
|
-
@json_only = options.key?(:json_only) ? !!options[:json_only] : false
|
31
|
-
end
|
32
|
-
|
33
|
-
# Saves JSON file containing translations
|
34
|
-
def save!
|
35
|
-
if @file =~ LOCALE_INTERPOLATOR
|
36
|
-
I18n::JS.js_available_locales.each do |locale|
|
37
|
-
write_file(file_for_locale(locale), @translations.slice(locale))
|
38
|
-
end
|
39
|
-
else
|
40
|
-
write_file
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
protected
|
45
|
-
|
46
|
-
def file_for_locale(locale)
|
47
|
-
@file.gsub(LOCALE_INTERPOLATOR, locale.to_s)
|
48
|
-
end
|
49
|
-
|
50
|
-
def write_file(_file = @file, _translations = @translations)
|
51
|
-
FileUtils.mkdir_p File.dirname(_file)
|
52
|
-
_translations = Utils.deep_key_sort(_translations) if @sort_translation_keys
|
53
|
-
_translations = Utils.deep_remove_procs(_translations)
|
54
|
-
contents = formatter.format(_translations)
|
55
|
-
|
56
|
-
return if File.exist?(_file) && File.read(_file) == contents
|
57
|
-
|
58
|
-
File.open(_file, "w+") do |f|
|
59
|
-
f << contents
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def formatter
|
64
|
-
if @json_only
|
65
|
-
Formatters::JSON.new(**formatter_options)
|
66
|
-
else
|
67
|
-
Formatters::JS.new(**formatter_options)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def formatter_options
|
72
|
-
{ js_extend: @js_extend,
|
73
|
-
namespace: @namespace,
|
74
|
-
pretty_print: @pretty_print,
|
75
|
-
prefix: @prefix,
|
76
|
-
suffix: @suffix
|
77
|
-
}
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|