opal-i18next 0.2.0 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a608d9ba3fba9ee08cc35ee247cad22a5c89c9950232c7f9f70c73e588d6da9a
4
- data.tar.gz: 8e82b9dadb4b73f55d5156ac1deccfe7c1b17f1c64abec548734c33f7b9c040b
3
+ metadata.gz: 44c564b588879276f62325e8812dcab71272bffbd1c97e5cb122a0ef00039314
4
+ data.tar.gz: 0e588fd5cc1a8bc63d5060b52e862b9dbe7375f96673971eb421baca723aaf46
5
5
  SHA512:
6
- metadata.gz: 904501d0d9ef54c0c23a011cb5326db007e06f5d6ae42880e778330ce68003e3b667a6d5c19b92a3be4ee95f9dcc7b1c147e4fd2e732208139038f0bb85ba74e
7
- data.tar.gz: 7494d5183b943f29a92745405684c97569bff3309396f7abc9eebdf558185c0c616e3e68c6156d8866ba3f4be8cf1a4774a99d8d5c172242a4674152ac872240
6
+ metadata.gz: 76a08af7bd190a3538c98e47112a69cf183d6ec023b959af778e25f7b55effcaa64f34dbb0eff19de8dd674c3017b726c1b09ed92315f1f582d216eb337dd32d
7
+ data.tar.gz: c58800b3e827727ccac4ac8d001ca2444ff30e378ee38c1053edc8083f30b84af6cbd6f79b5d48eb6b8112c0a470423eb392d607dcf7d467fb06e4a94d6af578
@@ -2,29 +2,42 @@ require "opal"
2
2
  require "native"
3
3
  require "json"
4
4
 
5
- # Uses PromiseV2 if present
6
- # @see https://opalrb.com/docs/guides/v1.5.1/async PromiseV2
7
- module I18next
5
+ # Uses PromiseV2 if present
6
+ # @see https://opalrb.com/docs/guides/v1.5.1/async PromiseV2
7
+ module I18next
8
8
 
9
9
  Promise = defined?(PromiseV2) ? PromiseV2 : ::Promise
10
10
 
11
11
  # {I18next} is a basic wrapper around the JavaScript {https://www.i18next.com i18next module}.
12
12
  #
13
13
  # It wraps i18next methods {https://www.i18next.com/overview/api#addResource addResource},
14
+ # {https://www.i18next.com/overview/api#addResourceBundle addResourceBundle},
14
15
  # {https://www.i18next.com/overview/api#addResources addResources},
15
16
  # {https://www.i18next.com/overview/api#changelanguage changeLanguage},
16
17
  # {https://www.i18next.com/overview/api#dir dir},
17
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},
18
21
  # {https://www.i18next.com/overview/api#getResource getResource},
19
22
  # {https://www.i18next.com/overview/api#getResourceBundle getResourceBundle},
23
+ # {https://www.i18next.com/overview/api#hasResourceBundle hasResourceBundle},
20
24
  # {https://www.i18next.com/overview/api#init init},
21
25
  # {https://www.i18next.com/overview/api#language language},
22
26
  # {https://www.i18next.com/overview/api#languages languages},
27
+ # {https://www.i18next.com/overview/api#loadLanguages loadLanguages},
23
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},
24
32
  # {https://www.i18next.com/overview/api#resolvedLanguage resolvedLanguage},
25
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},
26
35
  # {https://www.i18next.com/overview/api#t t}, and
27
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
+ #
28
41
  # It also provides method {#import_js_module} for loading {https://www.i18next.com/overview/plugins-and-utils i18next plugins}.
29
42
  class I18next
30
43
 
@@ -59,8 +72,10 @@ require "json"
59
72
  #
60
73
  # @param js_module a plugin's JavaScript module that was imported
61
74
  # by method {#import_js_module}
75
+ # @return [I18next::I18next] self
62
76
  def use(js_module)
63
77
  `#{@i18next}.use(js_module.default)`
78
+ self
64
79
  end
65
80
 
66
81
  # Initializes {https://www.i18next.com/overview/api#init i18next}
@@ -111,9 +126,24 @@ require "json"
111
126
  `#{@i18next}.exists(key)`
112
127
  end
113
128
 
114
- # @private
115
- def get_fixed_t
116
- raise 'Not implemented'
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
117
147
  end
118
148
 
119
149
  # @see https://www.i18next.com/overview/api#languages The i18next languages method
@@ -129,7 +159,7 @@ require "json"
129
159
  end
130
160
 
131
161
  # Loads additional namespaces not defined in init options
132
- # @param [String, Array<String>] ns one or more namespaces
162
+ # @param ns [String, Array<String>] one or more namespaces
133
163
  # @return [Promise] a promise that resolves when the namespaces have been loaded
134
164
  # @see https://www.i18next.com/overview/api#loadNamespaces The i18next loadNamespaces method
135
165
  def load_namespaces(ns)
@@ -144,9 +174,20 @@ require "json"
144
174
  promise
145
175
  end
146
176
 
147
- # @private
148
- def load_languages(*lngs)
149
- raise 'Not implemented'
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
150
191
  end
151
192
 
152
193
  # @private
@@ -184,16 +225,6 @@ require "json"
184
225
  raise 'Not implemented'
185
226
  end
186
227
 
187
- # @private
188
- def off
189
- raise 'Not implemented'
190
- end
191
-
192
- # @private
193
- def on
194
- raise 'Not implemented'
195
- end
196
-
197
228
  # Gets one value by given key.
198
229
  # @see https://www.i18next.com/overview/api#getResource The i18next getResource method
199
230
  def get_resource(lng, ns, key, options = {})
@@ -213,32 +244,129 @@ require "json"
213
244
  `#{@i18next}.addResources(lng, ns, #{resources.to_n})`
214
245
  end
215
246
 
216
- # @private
217
- def add_resource_bundle(lng, ns, resouces, deep, overwrite)
218
- raise 'Not implemented'
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)`
219
255
  end
220
256
 
221
- # @private
257
+ # Checks if a resource bundle exists
258
+ # @param lng [String] language
259
+ # @param ns [String] namespace
222
260
  def has_resource_bundle(lng, ns)
223
- raise 'Not implemented'
261
+ `#{@i18next}.hasResourceBundle(lng, ns)`
224
262
  end
225
263
 
226
- # @private
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
227
268
  def get_data_by_language(lng)
228
- raise 'Not implemented'
269
+ js_obj_to_ruby_hash(`#{@i18next}.getDataByLanguage(lng)`)
229
270
  end
230
271
 
231
272
  # Gets a resource bundle.
232
273
  # @return [Hash] key/value pairs
233
274
  # @see https://www.i18next.com/overview/api#getResourceBundle The i18next getResourceBundle method
234
275
  def get_resource_bundle(lng, ns)
235
- JSON.parse(`JSON.stringify(#{@i18next}.getResourceBundle(lng, ns))`)
276
+ js_obj_to_ruby_hash(`#{@i18next}.getResourceBundle(lng, ns)`)
236
277
  end
237
278
 
238
- # @private
279
+ # Removes a resource bundle exists
280
+ # @param lng [String] language
281
+ # @param ns [String] namespace
239
282
  def remove_resource_bundle(lng, ns)
240
- raise 'Not implemented'
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
241
328
  end
242
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)`)
370
+ end
243
371
  end
244
372
  end
@@ -1,3 +1,3 @@
1
1
  module I18next
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
data/opal-i18next.gemspec CHANGED
@@ -6,10 +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
- addResource, addResources, changeLanguage, dir, exists, getResource,
10
- getResourceBundle, init, language, languages, loadNamespaces, resolvedLanguage,
11
- t, and use. It also provides method import_js_module for
12
- 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.
13
14
  DESC
14
15
  spec.authors = ["Larry North"]
15
16
 
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.2.0
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-31 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,10 +26,11 @@ 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
- addResource, addResources, changeLanguage, dir, exists, getResource,
30
- getResourceBundle, init, language, languages, loadNamespaces, resolvedLanguage,
31
- t, and use. It also provides method import_js_module for
32
- 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.
33
34
  email:
34
35
  - lnorth@swnorth.com
35
36
  executables: []