opal-i18next 0.1.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0516e89ca4d90cf26eef7829ab80c86d67f8f05b0f1a8ef64e8c4cecefad15ae
4
- data.tar.gz: 5c4504a1bedaa4da8fcd536d152d11bfa4f42accb6113d70d78451b395e8c27d
3
+ metadata.gz: 44c564b588879276f62325e8812dcab71272bffbd1c97e5cb122a0ef00039314
4
+ data.tar.gz: 0e588fd5cc1a8bc63d5060b52e862b9dbe7375f96673971eb421baca723aaf46
5
5
  SHA512:
6
- metadata.gz: 9d492d66d45cd386d2a1fb90628bf77ee38af460325288c314e30d348eb362268b9f76e958e00c01d6568aec2f13d88edcff07ede09463360837cab5a3ab9914
7
- data.tar.gz: ade7cf0f354a91b067c093a7e52a22fa0a47f34dc2855d73c4a7ebc13da085714958956e57ef18f8df07dedf0a06f32efa46ec86427cbb924aa537e248c67d26
6
+ metadata.gz: 76a08af7bd190a3538c98e47112a69cf183d6ec023b959af778e25f7b55effcaa64f34dbb0eff19de8dd674c3017b726c1b09ed92315f1f582d216eb337dd32d
7
+ data.tar.gz: c58800b3e827727ccac4ac8d001ca2444ff30e378ee38c1053edc8083f30b84af6cbd6f79b5d48eb6b8112c0a470423eb392d607dcf7d467fb06e4a94d6af578
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private opal/i18next/**/*.rb
@@ -1,22 +1,51 @@
1
1
  require "opal"
2
2
  require "native"
3
+ require "json"
3
4
 
4
- # Uses PromiseV2 if present
5
- # @see https://opalrb.com/docs/guides/v1.5.1/async PromiseV2
6
- module I18next
5
+ # Uses PromiseV2 if present
6
+ # @see https://opalrb.com/docs/guides/v1.5.1/async PromiseV2
7
+ module I18next
7
8
 
8
9
  Promise = defined?(PromiseV2) ? PromiseV2 : ::Promise
9
10
 
10
11
  # {I18next} is a basic wrapper around the JavaScript {https://www.i18next.com i18next module}.
11
12
  #
12
- # It wraps i18next methods {https://www.i18next.com/overview/api#init init},
13
- # {https://www.i18next.com/overview/api#use use},
14
- # {https://www.i18next.com/overview/api#t t},
15
- # {https://www.i18next.com/overview/api#changelanguage changeLanguage}, and
16
- # {https://www.i18next.com/overview/api#language language}.
13
+ # It wraps i18next methods {https://www.i18next.com/overview/api#addResource addResource},
14
+ # {https://www.i18next.com/overview/api#addResourceBundle addResourceBundle},
15
+ # {https://www.i18next.com/overview/api#addResources addResources},
16
+ # {https://www.i18next.com/overview/api#changelanguage changeLanguage},
17
+ # {https://www.i18next.com/overview/api#dir dir},
18
+ # {https://www.i18next.com/overview/api#exists exists},
19
+ # {https://www.i18next.com/overview/api#getDataByLanguage getDataByLanguage},
20
+ # {https://www.i18next.com/overview/api#getFixedT getFixedT},
21
+ # {https://www.i18next.com/overview/api#getResource getResource},
22
+ # {https://www.i18next.com/overview/api#getResourceBundle getResourceBundle},
23
+ # {https://www.i18next.com/overview/api#hasResourceBundle hasResourceBundle},
24
+ # {https://www.i18next.com/overview/api#init init},
25
+ # {https://www.i18next.com/overview/api#language language},
26
+ # {https://www.i18next.com/overview/api#languages languages},
27
+ # {https://www.i18next.com/overview/api#loadLanguages loadLanguages},
28
+ # {https://www.i18next.com/overview/api#loadNamespaces loadNamespaces},
29
+ # {https://www.i18next.com/overview/api#events off},
30
+ # {https://www.i18next.com/overview/api#events on},
31
+ # {https://www.i18next.com/overview/api#removeResourceBundle removeResourceBundle},
32
+ # {https://www.i18next.com/overview/api#resolvedLanguage resolvedLanguage},
33
+ # {https://www.i18next.com/overview/api#setDefaultNamespace setDefaultNamespace},
34
+ # {https://www.i18next.com/overview/api#https://www.i18next.com/overview/api#store-events store.on},
35
+ # {https://www.i18next.com/overview/api#t t}, and
36
+ # {https://www.i18next.com/overview/api#use use}.
37
+ #
38
+ # It can handle {https://www.i18next.com/overview/api#events i18next events}. See methods on
39
+ # and off.
40
+ #
17
41
  # It also provides method {#import_js_module} for loading {https://www.i18next.com/overview/plugins-and-utils i18next plugins}.
18
42
  class I18next
19
43
 
44
+ # Each I18next instance has its own i18next Javascript module
45
+ def initialize
46
+ @i18next = `i18next.createInstance()`
47
+ end
48
+
20
49
  # Imports a JavaScript module (ESM)
21
50
  #
22
51
  # Use this method to import {https://www.i18next.com/overview/plugins-and-utils i18next JavaScript plugins}
@@ -43,17 +72,19 @@ require "native"
43
72
  #
44
73
  # @param js_module a plugin's JavaScript module that was imported
45
74
  # by method {#import_js_module}
75
+ # @return [I18next::I18next] self
46
76
  def use(js_module)
47
- `i18next.use(js_module.default)`
77
+ `#{@i18next}.use(js_module.default)`
78
+ self
48
79
  end
49
80
 
50
81
  # Initializes {https://www.i18next.com/overview/api#init i18next}
51
- # @param options [Hash] a hash with keys matching the {https://www.i18next.com/overview/configuration-options i18next options}
82
+ # @param options [Hash] a hash with keys matching the {https://www.i18next.com/overview/configuration-options i18next options}.
52
83
  # @return [Promise] a promise that resolves when i18next has been initialized
53
- def init(options)
84
+ def init(options = {})
54
85
  promise = Promise.new
55
86
  `
56
- i18next.init(#{options.to_n})
87
+ #{@i18next}.init(#{options.to_n})
57
88
  .then(
58
89
  t => {
59
90
  promise.$resolve(t);
@@ -69,9 +100,9 @@ require "native"
69
100
  def change_language(language)
70
101
  promise = Promise.new
71
102
  `
72
- i18next.changeLanguage(language).then(
73
- t => {
74
- promise.$resolve(t)
103
+ #{@i18next}.changeLanguage(language).then(
104
+ () => {
105
+ promise.$resolve()
75
106
  });
76
107
  `
77
108
  promise
@@ -79,14 +110,263 @@ require "native"
79
110
 
80
111
  # @return [String] the current {https://www.i18next.com/overview/api#language i18next} language
81
112
  def language
82
- `i18next.language`
113
+ `#{@i18next}.language`
83
114
  end
84
115
 
85
116
  # The {https://www.i18next.com/overview/api#t i18next} translation associated with a key
86
- # @param [String] key a key that references a translation, single key only
87
- # @return [String] the translation associated with the key
88
- def t(key)
89
- `i18next.t(key)`
117
+ # @param [String, Array<String>] key one or more keys that reference translations
118
+ # @param [Hash] options options for formatters, post processors, etc.
119
+ # @return [String] the translation associated with the first key that resolves
120
+ def t(key, options={})
121
+ `#{@i18next}.t(key, #{options.to_n})`
122
+ end
123
+
124
+ # @return [Boolean] true if the key exists
125
+ def exists(key)
126
+ `#{@i18next}.exists(key)`
127
+ end
128
+
129
+ # Returns a Proc that acts a +t+ method that defaults to a language and namespace.
130
+ # @example When calling the returned Proc, use brackets, not parentheses
131
+ # en = get_fixed_t("en")
132
+ # translation = en["key"]
133
+ # @param lng [String] language
134
+ # @param ns [String] namespace
135
+ # @param key_prefix [String] key prefix
136
+ # @see https://www.i18next.com/overview/api#getFixedT The i18next getFixedT method
137
+ def get_fixed_t(lng = nil, ns = nil, key_prefix = nil)
138
+ if key_prefix && ns && lng
139
+ `#{@i18next}.getFixedT(lng, ns, key_prefix)`
140
+ elsif ns && lng
141
+ `#{@i18next}.getFixedT(lng, ns)`
142
+ elsif lng
143
+ `#{@i18next}.getFixedT(lng)`
144
+ else
145
+ `#{@i18next}.getFixedT()`
146
+ end
147
+ end
148
+
149
+ # @see https://www.i18next.com/overview/api#languages The i18next languages method
150
+ # @return language codes that will be used to look up the translation value
151
+ def languages
152
+ `#{@i18next}.languages`
153
+ end
154
+
155
+ # @see https://www.i18next.com/overview/api#resolvedLanguage The i18next resolvedLanguage method
156
+ # @return the current resolved language
157
+ def resolved_language
158
+ `#{@i18next}.resolvedLanguage`
159
+ end
160
+
161
+ # Loads additional namespaces not defined in init options
162
+ # @param ns [String, Array<String>] one or more namespaces
163
+ # @return [Promise] a promise that resolves when the namespaces have been loaded
164
+ # @see https://www.i18next.com/overview/api#loadNamespaces The i18next loadNamespaces method
165
+ def load_namespaces(ns)
166
+ promise = Promise.new
167
+ `
168
+ #{@i18next}.loadNamespaces(ns)
169
+ .then(
170
+ () => {
171
+ promise.$resolve()
172
+ });
173
+ `
174
+ promise
175
+ end
176
+
177
+ # Loads additional languages not defined in init options (preload).
178
+ # @param lngs [String, Array<String>] one or more languages
179
+ # @return [Promise] a promise that resolves when the languages have been loaded
180
+ # @see https://www.i18next.com/overview/api#loadLanguages The i18next loadLanguages method
181
+ def load_languages(lngs)
182
+ promise = Promise.new
183
+ `
184
+ #{@i18next}.loadLanguages(lngs)
185
+ .then(
186
+ () => {
187
+ promise.$resolve()
188
+ });
189
+ `
190
+ promise
191
+ end
192
+
193
+ # @private
194
+ def reload_resources
195
+ raise 'Not implemented'
196
+ end
197
+
198
+ # Changes the default namespace.
199
+ # @param ns [String] new default namespace
200
+ # @see https://www.i18next.com/overview/api#setDefaultNamespace The i18next setDefaultNamespace method
201
+ def set_default_namespace(ns)
202
+ `#{@i18next}.setDefaultNamespace(ns)`
203
+ end
204
+
205
+ # Get a language's reading direction
206
+ # @param lng [String] the language; if omitted, the current language is used
207
+ # @return "ltr" or "rtl"
208
+ # @see https://www.i18next.com/overview/api#dir The i18next dir method
209
+ def dir(lng)
210
+ `#{@i18next}.dir(lng)`
211
+ end
212
+
213
+ # @private
214
+ def format(data, format, lng)
215
+ raise 'Not implemented'
216
+ end
217
+
218
+ # @private
219
+ def create_instance(options)
220
+ raise 'Not implemented'
221
+ end
222
+
223
+ # @private
224
+ def clone_instance(options)
225
+ raise 'Not implemented'
226
+ end
227
+
228
+ # Gets one value by given key.
229
+ # @see https://www.i18next.com/overview/api#getResource The i18next getResource method
230
+ def get_resource(lng, ns, key, options = {})
231
+ `#{@i18next}.getResource(lng, ns, key, options)`
232
+ end
233
+
234
+ # Adds one key/value.
235
+ # @see https://www.i18next.com/overview/api#addResource The i18next addResource method
236
+ def add_resource(lng, ns, key, value, options = {})
237
+ `#{@i18next}.addResource(lng, ns, key, value, options)`
238
+ end
239
+
240
+ # Adds multiple key/values.
241
+ # @param resources [Hash] key/value pairs
242
+ # @see https://www.i18next.com/overview/api#addResources The i18next addResources method
243
+ def add_resources(lng, ns, resources)
244
+ `#{@i18next}.addResources(lng, ns, #{resources.to_n})`
245
+ end
246
+
247
+ # Adds a complete bundle
248
+ # @param lng [String] bundle language
249
+ # @param ns [String] bundel namespace
250
+ # @param deep [Boolean] if true will extend existing translations in the bundle
251
+ # @param overwrite [Boolean] if true it will overwrite existing translations in the bundle
252
+ # @see https://www.i18next.com/overview/api#addResourceBundle The i18next addResourceBundle method
253
+ def add_resource_bundle(lng, ns, resources, deep = false, overwrite = false)
254
+ `#{@i18next}.addResources(lng, ns, #{resources.to_n}, deep, overwrite)`
255
+ end
256
+
257
+ # Checks if a resource bundle exists
258
+ # @param lng [String] language
259
+ # @param ns [String] namespace
260
+ def has_resource_bundle(lng, ns)
261
+ `#{@i18next}.hasResourceBundle(lng, ns)`
262
+ end
263
+
264
+ # Returns resource data for a language.
265
+ # @param lng [String] language
266
+ # @return resource data
267
+ # @see https://www.i18next.com/overview/api#getDataByLanguage The i18next getDataByLanguage method
268
+ def get_data_by_language(lng)
269
+ js_obj_to_ruby_hash(`#{@i18next}.getDataByLanguage(lng)`)
270
+ end
271
+
272
+ # Gets a resource bundle.
273
+ # @return [Hash] key/value pairs
274
+ # @see https://www.i18next.com/overview/api#getResourceBundle The i18next getResourceBundle method
275
+ def get_resource_bundle(lng, ns)
276
+ js_obj_to_ruby_hash(`#{@i18next}.getResourceBundle(lng, ns)`)
277
+ end
278
+
279
+ # Removes a resource bundle exists
280
+ # @param lng [String] language
281
+ # @param ns [String] namespace
282
+ def remove_resource_bundle(lng, ns)
283
+ `#{@i18next}.removeResourceBundle(lng, ns)`
284
+ end
285
+
286
+ # Create a listener for an i18next event.
287
+ # @param event [String] event name
288
+ # @param &listener [block] an event listener that is passed event-dependent arguments
289
+ # @return [Proc] the listener, which can be used to unsubscribe it via method off(event, listener)
290
+ # @see https://www.i18next.com/overview/api#events The i18next events
291
+ # @see #off
292
+ def on(event, &listener)
293
+ # Some events require special listeners because those events return JavaScript objects
294
+ # to the listeners, and those object must be converted to Ruby Hashes.
295
+ case event
296
+ when "initialized"
297
+ _onInitialized(listener)
298
+ when "loaded"
299
+ _onLoaded(listener)
300
+ else
301
+ `#{@i18next}.on(event, listener)`
302
+ end
303
+ listener
304
+ end
305
+
306
+ # Create a listener for an i18next store event.
307
+ #
308
+ # Only available after the init call.
309
+ #
310
+ # @param event [String] event name ("added" or "removed")
311
+ # @param &listener [block] an event listener that is passed language and namespace arguments
312
+ # @return [Proc] the listener, which can be used to unsubscribe it via method off(event, listener)
313
+ # @see https://www.i18next.com/overview/api#store-events The i18next store events
314
+ def store_on(event, &listener)
315
+ `#{@i18next}.store.on(event, listener)`
316
+ listener
317
+ end
318
+
319
+ # Unsubscribes an event's listener(s)
320
+ # @param event [String] event name
321
+ # @param listener [Proc] the listener to unsubscribe; if absent, unsubscribe all listeners
322
+ def off(event, listener = nil)
323
+ if listener
324
+ `#{@i18next}.off(event, listener)`
325
+ else
326
+ `#{@i18next}.off(event)`
327
+ end
328
+ end
329
+
330
+ private
331
+
332
+ # @private
333
+ # Create a listener for the i18next initialized event.
334
+ # @param &listener [Proc] an event listener block that is passed initialized options Hash
335
+ # @see https://www.i18next.com/overview/api#oninitialized The i18next initialized event
336
+ def _onInitialized(listener)
337
+ `
338
+ #{@i18next}.on("initialized", (options) => {
339
+ // Convert the JavaScript options object to a string and
340
+ // then convert that string to a Ruby hash that is passed
341
+ // to the listener.
342
+ listener.$call(Opal.JSON.$parse(JSON.stringify(options)))
343
+ })
344
+ `
345
+ end
346
+
347
+ # @private
348
+ # Create a listener for the i18next loaded event.
349
+ # @param listener [Proc] an event listener block that is passed loaded Hash
350
+ # @see https://www.i18next.com/overview/api#onloaded The i18next onLoaded event
351
+ def _onLoaded(listener)
352
+ `
353
+ #{@i18next}.on("loaded", (loaded) => {
354
+ // Convert the JavaScript load object to a string and
355
+ // then convert that string to a Ruby hash that is passed
356
+ // to the listener.
357
+ listener.$call(Opal.JSON.$parse(JSON.stringify(loaded)))
358
+ })
359
+ `
360
+ end
361
+
362
+ # @private
363
+ # Convert a JavaScript obj to a Ruby Hash.
364
+ # @param js_obj JavaScript object
365
+ # @return [Hash] Ruby Hash
366
+ def js_obj_to_ruby_hash(js_obj)
367
+ # Convert the JavaScript object to a string and then convert that string
368
+ # to a Ruby hash.
369
+ JSON.parse(`JSON.stringify(js_obj)`)
90
370
  end
91
371
  end
92
372
  end
@@ -1,3 +1,3 @@
1
1
  module I18next
2
- VERSION = '0.1.2'
2
+ VERSION = '0.3.0'
3
3
  end
data/opal-i18next.gemspec CHANGED
@@ -6,8 +6,11 @@ Gem::Specification.new do |spec|
6
6
  spec.summary = "An Opal wrapper for the JavaScript i18next module."
7
7
  spec.description = <<~DESC
8
8
  A basic Opal wrapper for the JavaScript i18next module that supports methods
9
- init, use, t, changeLanguage, and language. It also provides method
10
- import_js_module for loading i18next plugins.
9
+ addResource, addResourceBundle, addResources, changeLanguage, dir, exists,
10
+ getDataByLanguage, getFixedT, getResource, getResourceBundle, hasResourceBundle,
11
+ init, language, languages, loadLanguages, loadNamespaces, off, on,
12
+ removeResourceBundle, resolvedLanguage, store.on, t, and use. It also
13
+ provides method import_js_module for loading i18next plugins.
11
14
  DESC
12
15
  spec.authors = ["Larry North"]
13
16
 
@@ -22,6 +25,7 @@ Gem::Specification.new do |spec|
22
25
  }
23
26
 
24
27
  spec.files += Dir["*.gemspec"]
28
+ spec.files += Dir[".yardopts"]
25
29
  spec.files += Dir["lib/**/*"]
26
30
  spec.files += Dir["opal/**/*"]
27
31
  spec.require_paths = ["lib"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-i18next
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Larry North
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-24 00:00:00.000000000 Z
11
+ date: 2022-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -26,14 +26,18 @@ dependencies:
26
26
  version: 1.5.0
27
27
  description: |
28
28
  A basic Opal wrapper for the JavaScript i18next module that supports methods
29
- init, use, t, changeLanguage, and language. It also provides method
30
- import_js_module for loading i18next plugins.
29
+ addResource, addResourceBundle, addResources, changeLanguage, dir, exists,
30
+ getDataByLanguage, getFixedT, getResource, getResourceBundle, hasResourceBundle,
31
+ init, language, languages, loadLanguages, loadNamespaces, off, on,
32
+ removeResourceBundle, resolvedLanguage, store.on, t, and use. It also
33
+ provides method import_js_module for loading i18next plugins.
31
34
  email:
32
35
  - lnorth@swnorth.com
33
36
  executables: []
34
37
  extensions: []
35
38
  extra_rdoc_files: []
36
39
  files:
40
+ - ".yardopts"
37
41
  - lib/opal-i18next.rb
38
42
  - lib/opal/i18next.rb
39
43
  - opal-i18next.gemspec