imba-localization 0.1.4 β 0.1.6
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.
- package/README.md +226 -46
- package/components.d.ts +4 -0
- package/components.imba +49 -0
- package/index.imba +2 -1
- package/index.js +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,90 +1,270 @@
|
|
|
1
1
|
|
|
2
|
-
# JSON Localization for Imba
|
|
2
|
+
# π JSON Localization for Imba
|
|
3
3
|
|
|
4
|
-
A lightweight Imba module for loading and handling JSON-based localization files in web applications. This utility fetches a localization file, selects the appropriate language based on the user's browser settings (or falls back to a default), and allows you to easily access localized strings throughout your application.
|
|
4
|
+
A lightweight Imba module for loading and handling JSON-based localization files in web applications. This utility fetches a localization file, selects the appropriate language based on the user's browser settings (or falls back to a default), and allows you to easily access localized strings throughout your application. Package includes helpful components for language selection and localization management.
|
|
5
5
|
|
|
6
6
|
## β¨ Features
|
|
7
7
|
|
|
8
|
-
-
|
|
9
|
-
- Falls back to a default language
|
|
10
|
-
- Proxy-based access to translation strings
|
|
11
|
-
-
|
|
12
|
-
- Simple to use in any Imba-based web application
|
|
8
|
+
- π **Automatic language detection** - Uses the user's browser language settings
|
|
9
|
+
- π **Smart fallback system** - Falls back to a default language when needed
|
|
10
|
+
- π§ **Intuitive access** - Proxy-based access to translation strings
|
|
11
|
+
- π‘ **Event handling** - Support for `onready`, `onchange`, and `onerror` events
|
|
12
|
+
- π **Simple integration** - Easy to use in any Imba-based web application
|
|
13
|
+
- π§© **<LanguageSelector>** - Plug and play component for switching languages
|
|
14
|
+
|
|
15
|
+
## π Notes
|
|
16
|
+
|
|
17
|
+
- Language detection uses the first two characters from `navigator.language` (e.g., `en` from `en-US`)
|
|
18
|
+
- If the preferred language isn't available in your JSON file, it falls back to the default language
|
|
19
|
+
- Returns an empty string for missing translation keys instead of throwing errors
|
|
20
|
+
|
|
13
21
|
|
|
14
22
|
## π¦ Installation
|
|
15
23
|
|
|
16
|
-
Just include the module in your project or copy the class directly into your codebase.
|
|
17
24
|
```bash
|
|
25
|
+
# NodeJs
|
|
18
26
|
npm install imba-localization
|
|
27
|
+
# or Bun
|
|
28
|
+
bun add imba-localization
|
|
19
29
|
```
|
|
20
30
|
|
|
21
|
-
## π
|
|
31
|
+
## π Quick Start
|
|
32
|
+
|
|
33
|
+
### 1οΈβ£ Preload the localization file
|
|
34
|
+
|
|
35
|
+
Add this to your HTML head to load the localization file simultaneously with your application:
|
|
22
36
|
|
|
23
|
-
First of all, preload the localization file in HTML head, so it is loaded simultaniously with the application itself:
|
|
24
37
|
```html
|
|
25
38
|
<!DOCTYPE html>
|
|
26
39
|
<html lang="en">
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
<head>
|
|
41
|
+
<!-- Other head elements -->
|
|
42
|
+
<link rel="preload" href="path/to/lang.json" as="fetch" type="application/json" crossorigin="anonymous"/>
|
|
43
|
+
</head>
|
|
44
|
+
<body>
|
|
45
|
+
<!-- Your app -->
|
|
46
|
+
</body>
|
|
34
47
|
</html>
|
|
35
48
|
```
|
|
36
|
-
Such localization file can be placed on any static hosting. In my experience Github Pages works perfectly for that purpose. Moreover, it also allows to update localization by just pushing updated file to the repository.
|
|
37
49
|
|
|
38
|
-
|
|
50
|
+
> π‘ **Tip:** You can host your localization file on GitHub Pages or any static hosting service, making it easy to update translations without redeploying your application.
|
|
51
|
+
|
|
52
|
+
### 2οΈβ£ Initialize in your Imba app
|
|
39
53
|
|
|
40
54
|
```imba
|
|
41
55
|
# app.imba
|
|
56
|
+
import { Localization } from 'imba-localization'
|
|
42
57
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# To create an instance pass the address to the JSON and (optionally) default language
|
|
46
|
-
const loc = new Localization("ADDRESS_TO_JSON", "en")
|
|
58
|
+
# Create an instance with the JSON URL and optional default language
|
|
59
|
+
const loc = new Localization("path/to/lang.json", "en")
|
|
47
60
|
|
|
61
|
+
# Set up event handlers
|
|
48
62
|
loc.onready = do
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
console.log loc.hello
|
|
53
|
-
#
|
|
54
|
-
|
|
63
|
+
console.log "Localization loaded!"
|
|
64
|
+
|
|
65
|
+
# Access translations in various ways:
|
|
66
|
+
console.log loc.hello # Using dot notation
|
|
67
|
+
console.log loc['goodbye'] # Using bracket notation
|
|
68
|
+
console.log loc['user']['profile'] # Accessing nested properties
|
|
55
69
|
|
|
56
|
-
loc.onerror = do(
|
|
57
|
-
|
|
70
|
+
loc.onerror = do(error, details)
|
|
71
|
+
# The Localization object can return following types of errors:
|
|
72
|
+
# 'no_localization_file' - if there were a problem when downloading JSON file
|
|
73
|
+
# 'no_default_localization' - if there is no localization in the file for the default language
|
|
74
|
+
# 'no_localization_key' - if there is no requiered (from the interface) key in the file
|
|
75
|
+
console.error "Localization error:", error, details
|
|
58
76
|
|
|
59
|
-
loc.
|
|
60
|
-
|
|
77
|
+
loc.onchange = do(lang_key)
|
|
78
|
+
console.log "Language changed to:", lang_key
|
|
61
79
|
|
|
62
|
-
#
|
|
63
|
-
loc.active
|
|
80
|
+
# Get the current localization code
|
|
81
|
+
console.log loc.active
|
|
64
82
|
|
|
65
|
-
#
|
|
66
|
-
|
|
83
|
+
# Switch the active language
|
|
84
|
+
loc.active = "fr" # Changes to French if available
|
|
85
|
+
|
|
86
|
+
# Loop through all the localizations
|
|
87
|
+
for key, data of loc.languages
|
|
88
|
+
console.log key, data
|
|
89
|
+
|
|
90
|
+
# Get all the keys for the active language
|
|
91
|
+
console.log loc.languages[loc.active]
|
|
67
92
|
|
|
68
93
|
```
|
|
69
94
|
|
|
70
|
-
## π JSON
|
|
95
|
+
## π JSON Structure
|
|
71
96
|
|
|
72
|
-
|
|
97
|
+
Your localization file should follow this format:
|
|
73
98
|
|
|
74
99
|
```json
|
|
75
100
|
{
|
|
76
101
|
"en": {
|
|
77
|
-
"
|
|
78
|
-
"goodbye": "Goodbye"
|
|
102
|
+
"welcome": "Welcome",
|
|
103
|
+
"goodbye": "Goodbye",
|
|
104
|
+
"user": {
|
|
105
|
+
"profile": "Profile",
|
|
106
|
+
"settings": "Settings"
|
|
107
|
+
}
|
|
79
108
|
},
|
|
80
109
|
"fr": {
|
|
81
|
-
"
|
|
82
|
-
"goodbye": "Au revoir"
|
|
110
|
+
"welcome": "Bienvenue",
|
|
111
|
+
"goodbye": "Au revoir",
|
|
112
|
+
"user": {
|
|
113
|
+
"profile": "Profil",
|
|
114
|
+
"settings": "Paramètres"
|
|
115
|
+
}
|
|
83
116
|
}
|
|
84
117
|
}
|
|
85
118
|
```
|
|
86
119
|
|
|
87
|
-
##
|
|
120
|
+
## π οΈ API Reference
|
|
121
|
+
|
|
122
|
+
### Constructor
|
|
123
|
+
|
|
124
|
+
```imba
|
|
125
|
+
new Localization(url, default = 'en')
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- `url`: Path to your JSON localization file
|
|
129
|
+
- `default`: Fallback language code (defaults to 'en')
|
|
130
|
+
|
|
131
|
+
### Properties
|
|
132
|
+
|
|
133
|
+
- `active`: Get or set the code of the active language
|
|
134
|
+
- `languages`: Object containing all loaded language data
|
|
135
|
+
- `preferred`: Detected browser language (first 2 characters of `navigator.language`)
|
|
136
|
+
|
|
137
|
+
### Events
|
|
138
|
+
|
|
139
|
+
- `onready`: Called when localization data is successfully loaded
|
|
140
|
+
- `onerror`: Called when an error occurs (`error`, `details`)
|
|
141
|
+
- `onchange`: Called when the active language changes (`lang_key`)
|
|
142
|
+
|
|
143
|
+
## π§© Components
|
|
144
|
+
|
|
145
|
+
### LanguageSelector
|
|
146
|
+
|
|
147
|
+
A customizable dropdown component that allows users to select from available in the JSON localization file languages.
|
|
148
|
+
|
|
149
|
+
```imba
|
|
150
|
+
import { Localization } from 'imba-localization'
|
|
151
|
+
const loc = new Localization("path/to/lang.json", "en")
|
|
152
|
+
|
|
153
|
+
import { LanguageSelector } from 'imba-localization/components'
|
|
154
|
+
|
|
155
|
+
# In your UI component
|
|
156
|
+
tag AppHeader
|
|
157
|
+
<self>
|
|
158
|
+
<LanguageSelector engine=loc> # engine attribute is mandatory
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
To make this component work as intended, your JSON file will need some adjustments. For each supported language you will need to define the display name for the language and also the country code for the flag to show (for example `en` language is used in `gb` and `us` countries):
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
"en": {
|
|
165
|
+
"$": {
|
|
166
|
+
"name": "English",
|
|
167
|
+
"flag": "us"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Visual Customization
|
|
173
|
+
|
|
174
|
+
Here are CSS classes (and one variable) you can redefine:
|
|
175
|
+
```imba
|
|
176
|
+
css
|
|
177
|
+
$ease: 0.5s
|
|
178
|
+
.main
|
|
179
|
+
cursor:pointer
|
|
180
|
+
rd:8px px:15px py:8px
|
|
181
|
+
bgc:light-dark(#000000/10, #FFFFFF/20)
|
|
182
|
+
fw:500 fs:13px
|
|
183
|
+
ead:$ease
|
|
184
|
+
.main-active
|
|
185
|
+
bgc:light-dark(#000000/20, #FFFFFF/30)
|
|
186
|
+
.main-flag
|
|
187
|
+
mr:10px rd:50% w:20px h:20px
|
|
188
|
+
.main-name
|
|
189
|
+
mr:10px
|
|
190
|
+
.main-arrow
|
|
191
|
+
w:16px h:16px ml:auto
|
|
192
|
+
fill:light-dark(#000000,#FFFFFF)
|
|
193
|
+
scale-y:-1
|
|
194
|
+
ead:$ease
|
|
195
|
+
.menu
|
|
196
|
+
t:100% l:50% x:-50% mt:2px rd:8px rd:8px py:5px zi:999
|
|
197
|
+
fw:500 fs:13px
|
|
198
|
+
backdrop-filter:blur(20px)
|
|
199
|
+
bgc:light-dark(#000000/5, #FFFFFF/10)
|
|
200
|
+
ead:$ease
|
|
201
|
+
.menu-item
|
|
202
|
+
cursor:pointer
|
|
203
|
+
d:hflex px:10px py:5px rd:8px m:5px
|
|
204
|
+
bg@hover:light-dark(#000000/10, #FFFFFF/20)
|
|
205
|
+
.menu-item-icon
|
|
206
|
+
h:20px w:20px mr:10px rd:50%
|
|
207
|
+
.menu-item-text
|
|
208
|
+
fs:13px
|
|
209
|
+
```
|
|
210
|
+
LanguageSelector can be easily customized through CSS and Imba tag (class) inheritance. Here how the above classes can be adjusted via the inheritance:
|
|
211
|
+
|
|
212
|
+
```imba
|
|
213
|
+
import { LanguageSelector } from 'imba-localization/components'
|
|
214
|
+
|
|
215
|
+
# Create an inheritent class
|
|
216
|
+
tag Languages < LanguageSelector
|
|
217
|
+
css
|
|
218
|
+
$ease: 1s
|
|
219
|
+
.menu-item rd:2px
|
|
220
|
+
.menu-item-icon h:30px w:30px
|
|
221
|
+
|
|
222
|
+
# Using the adjusted component
|
|
223
|
+
tag MyApp
|
|
224
|
+
<self>
|
|
225
|
+
<Languages engine=loc>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Flag collections
|
|
229
|
+
|
|
230
|
+
You can redefine the collection of flag icons through the `icons` attribute:
|
|
231
|
+
|
|
232
|
+
```imba
|
|
233
|
+
<LanguageSelector icons='https://flagicons.lipis.dev/flags/4x3/##.svg'>
|
|
234
|
+
```
|
|
235
|
+
There are many flag collections out there:
|
|
236
|
+
- https://kapowaz.github.io/square-flags/flags/##.svg (default one)
|
|
237
|
+
- https://hatscripts.github.io/circle-flags/flags/##.svg
|
|
238
|
+
- https://flagcdn.com/##.svg
|
|
239
|
+
- https://cdn.simplelocalize.io/public/v1/flags/##.svg
|
|
240
|
+
- https://cdn.jsdelivr.net/gh/hampusborgos/country-flags@main/svg/##.svg
|
|
241
|
+
- https://flagicons.lipis.dev/flags/4x3/##.svg
|
|
242
|
+
|
|
243
|
+
You can use any other collection you prefer, just change the actual country code to `##` in the url, so the component could replace it with the actual code to obtain a flag for a needed country.
|
|
244
|
+
|
|
245
|
+
#### Dropdown arrow customization
|
|
246
|
+
|
|
247
|
+
You can use any arrow icon you prefer (or remove it though CSS) by passing a tag of the image to the LanguageSelector `arrow` attribute:
|
|
248
|
+
|
|
249
|
+
```imba
|
|
250
|
+
tag SomeIcon
|
|
251
|
+
<self>
|
|
252
|
+
<svg viewBox="..." xmlns="http://www.w3.org/2000/svg">
|
|
253
|
+
<path d="...">
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
<LanguageSelector arrow=SomeIcon>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### ArrowIcon
|
|
260
|
+
|
|
261
|
+
The default arrow icon used in the LanguageSelector component is available as a separate icon (in case for some reason you don't want to use [imba-phosphor-icons](https://www.npmjs.com/package/imba-phosphor-icons) package by Sindre).
|
|
262
|
+
|
|
263
|
+
```imba
|
|
264
|
+
import {ArrowIcon} from 'imba-localization/components'
|
|
88
265
|
|
|
89
|
-
|
|
90
|
-
|
|
266
|
+
tag App
|
|
267
|
+
<self>
|
|
268
|
+
<ArrowIcon>
|
|
269
|
+
css w:20px h:20px stroke:red
|
|
270
|
+
```
|
package/components.d.ts
ADDED
package/components.imba
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export tag ArrowIcon
|
|
2
|
+
<self>
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
|
|
4
|
+
<path d="M213.66,165.66a8,8,0,0,1-11.32,0L128,91.31,53.66,165.66a8,8,0,0,1-11.32-11.32l80-80a8,8,0,0,1,11.32,0l80,80A8,8,0,0,1,213.66,165.66Z">
|
|
5
|
+
|
|
6
|
+
export tag LanguageSelector
|
|
7
|
+
engine
|
|
8
|
+
icons = "https://kapowaz.github.io/square-flags/flags/##.svg"
|
|
9
|
+
#dropdown = false
|
|
10
|
+
arrow = ArrowIcon
|
|
11
|
+
|
|
12
|
+
def onselect key
|
|
13
|
+
#dropdown = false
|
|
14
|
+
engine.active = key
|
|
15
|
+
|
|
16
|
+
css
|
|
17
|
+
$ease: 0.5s
|
|
18
|
+
.main rd:8px px:15px py:8px cursor:pointer bgc:light-dark(#000000/10, #FFFFFF/20) fw:500 fs:13px ead:$ease
|
|
19
|
+
.main-active bgc:light-dark(#000000/20, #FFFFFF/30)
|
|
20
|
+
.main-flag mr:10px rd:50% w:20px h:20px
|
|
21
|
+
.main-name mr:10px
|
|
22
|
+
.main-arrow w:16px h:16px fill:light-dark(#000000,#FFFFFF) ml:auto scale-y:-1 ead:$ease
|
|
23
|
+
.menu t:100% l:50% x:-50% zi:999 backdrop-filter:blur(20px) mt:2px rd:8px rd:8px py:5px bgc:light-dark(#000000/5, #FFFFFF/10) fw:500 fs:13px ead:$ease
|
|
24
|
+
.menu-item d:hflex px:10px py:5px rd:8px cursor:pointer bg@hover:light-dark(#000000/10, #FFFFFF/20) m:5px
|
|
25
|
+
.menu-item-icon h:20px w:20px mr:10px rd:50%
|
|
26
|
+
.menu-item-text fs:13px
|
|
27
|
+
|
|
28
|
+
def icon country
|
|
29
|
+
return icons.replace('##',country)
|
|
30
|
+
|
|
31
|
+
def mouseleave e
|
|
32
|
+
const rect = self.getBoundingClientRect!
|
|
33
|
+
const menu = $menu.getBoundingClientRect!
|
|
34
|
+
const inside = e.clientY >= menu.bottom || e.clientY <= rect.top || (e.clientX <= rect.left and e.clientY <= rect.bottom) || (e.clientX <= menu.left and e.clientY >= menu.top) || (e.clientX >= rect.right and e.clientY <= rect.bottom) || (e.clientX >= menu.right and e.clientY >= menu.top)
|
|
35
|
+
#dropdown = !inside
|
|
36
|
+
|
|
37
|
+
<self [pos:rel] @mouseenter=(#dropdown = true) @mouseleave=mouseleave>
|
|
38
|
+
<div.main [pos:rel d:hcc] .main-active=#dropdown>
|
|
39
|
+
<img.main-flag src=icon(engine[engine.active].$.flag)>
|
|
40
|
+
<div.main-name> engine.$.name
|
|
41
|
+
<{arrow}.main-arrow [scale-y:1]=#dropdown>
|
|
42
|
+
|
|
43
|
+
if #dropdown
|
|
44
|
+
<div$menu.menu [pos:abs w:100% > max-content o@off:0] ease>
|
|
45
|
+
for own key, value of engine.languages
|
|
46
|
+
<div.menu-item @click=onselect(key) [d:none]=(key == engine.active)>
|
|
47
|
+
<img.menu-item-icon src=icon(value.$.flag)>
|
|
48
|
+
<span.menu-item-text> value.$.name
|
|
49
|
+
|
package/index.imba
CHANGED
|
@@ -19,6 +19,7 @@ export class Localization
|
|
|
19
19
|
return Reflect.get(target, p, receiver) if self[p]
|
|
20
20
|
return target.languages[p] if target.languages[p]
|
|
21
21
|
return target.languages[active][p] if target.languages[active] and target.languages[active][p]
|
|
22
|
+
onerror('no_localization_key', p) if onerror isa Function
|
|
22
23
|
return ''
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -32,7 +33,7 @@ export class Localization
|
|
|
32
33
|
languages = data if data
|
|
33
34
|
if !languages[default]
|
|
34
35
|
if onerror isa Function
|
|
35
|
-
onerror('no_default_localization')
|
|
36
|
+
onerror('no_default_localization', default)
|
|
36
37
|
else
|
|
37
38
|
console.log('There is no Localization for the default language', default)
|
|
38
39
|
return
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var S=Symbol.for("#__init__"),I=Symbol.for("#__initor__"),W=Symbol.for("#__inited__"),H=Symbol.for("#__hooks__"),O=Symbol.for("#__patch__"),K=Symbol.for("#has"),X=Symbol.for("#meta"),Y=Symbol.for("imba"),c=Symbol.for("#__mixin__"),M=Symbol.for("#matcher"),C=Symbol.for("#L"),j=Symbol.for("#appendChild"),i=Symbol.for("#afterVisit"),d=Symbol.for("#beforeReconcile"),g=Symbol.for("#afterReconcile"),y=Symbol.for("##up");var G={IsExtension:1,IsTag:2,HasDescriptors:4,HasSuperCalls:8,HasConstructor:16,HasFields:32,HasMixins:64,HasInitor:128,HasDecorators:256,IsObjectExtension:512},U=new Map,Z=globalThis[Y]||={counter:0,classes:U};function E(h,n={}){return U.has(h)||U.set(h,{symbol:Symbol(h.name),parent:Object.getPrototypeOf(h.prototype)?.constructor,for:h,uses:null,inits:null,id:Z.counter++,...n}),U.get(h)}function q(h,n){return typeof n==="string"?typeof h===n:n?.[Symbol.hasInstance]?.(h)}function A(h,n){if(!h||!n)return!1;if(h.get)return n.get===h.get;if(h.set)return n.set===h.set;if(h.value)return h.value===n.value}function J(h,n,f,u={}){let r=h.constructor;if(!f&&n){if(f=Object.getOwnPropertyDescriptors(n),delete f.constructor,f[S])console.warn(`Cannot define plain fields when extending class ${r.name}`),delete f[S]}let o=E(r);if(o&&o.augments){let F=new Map;for(let z of Object.keys(f)){let w=Object.getOwnPropertyDescriptor(h,z);for(let v of o.augments){let T=F.get(v);T||F.set(v,T={});let B=Object.getOwnPropertyDescriptor(v.prototype,z);if(B&&!A(w,B))console.warn("wont extend",z,B,w);else T[z]=f[z]}}for(let[z,w]of F)if(Object.keys(w).length)J(z.prototype,null,w)}return Object.defineProperties(h,f),h}function L(h,n){let f=E(h),u=E(n);if(u.parent){if(!(h.prototype instanceof u.parent))throw new Error(`Mixin ${n.name} has superclass not present in target class`)}if(!u.augments){u.augments=new Set;let o=u.ref=Symbol(n.name),F=Object[Symbol.hasInstance];n.prototype[o]=!0,Object.defineProperty(n,Symbol.hasInstance,{value:function(z){return this===n?z&&!!z[o]:F.call(this,z)}})}if(h.prototype[u.ref])return h;if(u.uses)for(let o of u.uses)L(h,o);u.augments.add(h),f.uses||=[],f.uses.push(n);let r=Object.getOwnPropertyDescriptors(n.prototype);if(delete r.constructor,r[S])f.inits||=[],f.inits.push(n.prototype[S]),delete r[S];if(Object.defineProperties(h.prototype,r),n?.mixed instanceof Function)n.mixed(h);return h}var P={cache:{},self:null,target:null,proxy:new Proxy({},{apply:(h,n,...f)=>{return P.target[n].apply(P.self,f)},get:(h,n)=>{return Reflect.get(P.target,n,P.self)},set:(h,n,f,u)=>{return Reflect.set(P.target,n,f,P.self)}})};function N(h,n,f,u,r=null){let o=Object.getPrototypeOf(h.prototype),F=u&G.HasMixins,z;if(F)U.set(h,U.get(o.constructor)),o=Object.getPrototypeOf(o);if(r){let v=u&G.IsObjectExtension?r:r.prototype,T=E(h);if(T.uses){if(r===v)console.warn("Cannot extend object with mixins");for(let B of T.uses)L(r,B)}if(u&G.HasSuperCalls)P.cache[n]=Object.create(Object.getPrototypeOf(v),Object.getOwnPropertyDescriptors(v));return J(v,h.prototype),r}let w=o?.constructor;if(z=E(h,{symbol:n}),Object.defineProperty(h,X,{value:z,enumerable:!1,configurable:!0}),f&&h.name!==f)Object.defineProperty(h,"name",{value:f,configurable:!0});if(z.flags=u,u&G.HasConstructor)h.prototype[I]=n;if(z.uses)for(let v of z.uses)v.mixes?.(h);if(w?.inherited instanceof Function)w.inherited(h);return h}function Q(h,n){if(h[I]===n)h[W]?.(),h[H]&&h[H].inited(h)}var R=Symbol.for("#active"),V=Symbol();class D{[S](h=null,n=!0,f=!0){var u;this.onready=h?h.onready:void 0,this.onerror=h?h.onerror:void 0,this.onchange=h?h.onchange:void 0,this.languages=h&&(u=h.languages)!==void 0?u:{},this.preferred=h&&(u=h.preferred)!==void 0?u:(window?.navigator?.language||"en-US").slice(0,2),this[R]=h?h[R]:void 0,this.default=h?h.default:void 0}constructor(h,n="en"){var f=this;return this[S](),this.default=n,window.fetch(h).then(function(u){return u.json()}).then(function(u){return f._finalize(u,void 0)}).catch(function(u){return f._finalize(void 0,u)}),new Proxy(this,{get:function(u,r,o){if(f[r])return Reflect.get(u,r,o);if(u.languages[r])return u.languages[r];if(u.languages[f.active]&&u.languages[f.active][r])return u.languages[f.active][r];if(q(f.onerror,Function))f.onerror("no_localization_key",r);return""}});Q(this,V)}_finalize(h,n){if(n){if(q(this.onerror,Function))this.onerror("no_localization_file",n);else console.log("Localization file was not loaded",n);return}if(h)this.languages=h;if(!this.languages[this.default]){if(q(this.onerror,Function))this.onerror("no_default_localization",this.default);else console.log("There is no Localization for the default language",this.default);return}if(this.active=this.preferred,q(this.onready,Function))return this.onready()}get active(){return this.languages[this[R]]?this[R]:this.default}set active(h){if(h&&this.languages[h])this[R]=h;else this[R]=this.languages[this.preferred]?this.preferred:this.default;if(q(this.onchange,Function))this.onchange(this[R])}static{N(this,V,"Localization",16)}}export{D as Localization};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imba-localization",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/HeapVoid/imba-localization.git"
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"type": "module",
|
|
23
23
|
"files": [
|
|
24
24
|
"index.imba",
|
|
25
|
-
"index.js"
|
|
25
|
+
"index.js",
|
|
26
|
+
"components.imba",
|
|
27
|
+
"components.d.ts"
|
|
26
28
|
]
|
|
27
29
|
}
|