mi-intl 0.7.0 → 0.9.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.
- package/README.md +1 -19
- package/dist/cookie.js +5 -3
- package/dist/intl-message.js +25 -1
- package/dist/intl-provider.js +11 -4
- package/package.json +4 -3
- package/src/cookie.js +3 -3
- package/src/intl-message.js +35 -15
- package/src/intl-provider.js +15 -5
- package/types/intl-message.d.ts +18 -11
package/README.md
CHANGED
|
@@ -29,25 +29,7 @@ import { MiIntlProvider, MiIntlMessage, IntlConsumer } from 'mi-intl'
|
|
|
29
29
|
|
|
30
30
|
// define tag for intl-provider
|
|
31
31
|
define('mi-intl-provider', MiIntlProvider)
|
|
32
|
-
|
|
33
|
-
// connects to MiIntlProvider using IntlConsumer
|
|
34
|
-
define(
|
|
35
|
-
'mi-message',
|
|
36
|
-
class extends MiIntlMessage {
|
|
37
|
-
static get properties () {
|
|
38
|
-
return { label: {}, value: {} }
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
render() {
|
|
42
|
-
this.update()
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
update() {
|
|
46
|
-
// this.t() is provided by MiIntlMessage
|
|
47
|
-
this.renderRoot.textContent = this.t(this.label, { value: this.value })
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
)
|
|
32
|
+
define('mi-message', MiIntlMessage)
|
|
51
33
|
|
|
52
34
|
// define lang selector
|
|
53
35
|
define(
|
package/dist/cookie.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
function cookieParse(cookieStr = "") {
|
|
2
|
-
const parts = cookieStr.split(/\s*;\s*/), cookies =
|
|
2
|
+
const parts = cookieStr.split(/\s*;\s*/), cookies = Object.create(null);
|
|
3
3
|
for (const part of parts) {
|
|
4
4
|
const [key, val] = part.split('=');
|
|
5
|
-
if (key) {
|
|
5
|
+
if (key && !Object.prototype.hasOwnProperty.call(Object.prototype, key)) {
|
|
6
6
|
const value = decodeURIComponent(val);
|
|
7
7
|
cookies[key] = value;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
return
|
|
10
|
+
return {
|
|
11
|
+
...cookies
|
|
12
|
+
};
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
|
package/dist/intl-message.js
CHANGED
|
@@ -1,15 +1,39 @@
|
|
|
1
|
-
import { MiElement } from 'mi-element';
|
|
1
|
+
import { MiElement, escHtml } from 'mi-element';
|
|
2
2
|
|
|
3
3
|
import { IntlConsumer } from './intl-consumer.js';
|
|
4
4
|
|
|
5
5
|
class MiIntlMessage extends MiElement {
|
|
6
6
|
#context;
|
|
7
|
+
static get properties() {
|
|
8
|
+
return {
|
|
9
|
+
label: {},
|
|
10
|
+
value: {},
|
|
11
|
+
unsafeHtml: {
|
|
12
|
+
type: Boolean,
|
|
13
|
+
initial: !1
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
7
17
|
constructor() {
|
|
8
18
|
super(), this.#context = new IntlConsumer(this);
|
|
9
19
|
}
|
|
10
20
|
t(label, value) {
|
|
11
21
|
return this.#context.value.t(label, value);
|
|
12
22
|
}
|
|
23
|
+
update() {
|
|
24
|
+
if ('string' == typeof this.value) try {
|
|
25
|
+
this.value = JSON.parse(this.value);
|
|
26
|
+
} catch {
|
|
27
|
+
this.value = {
|
|
28
|
+
value: this.value
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (this.unsafeHtml) {
|
|
32
|
+
const escValue = {};
|
|
33
|
+
for (const [key, val] of Object.entries(this.value || {})) escValue[key] = escHtml(val);
|
|
34
|
+
this.renderRoot.innerHTML = this.t(this.label, escValue);
|
|
35
|
+
} else this.renderRoot.textContent = this.t(this.label, this.value);
|
|
36
|
+
}
|
|
13
37
|
}
|
|
14
38
|
|
|
15
39
|
export { MiIntlMessage };
|
package/dist/intl-provider.js
CHANGED
|
@@ -46,13 +46,12 @@ class MiIntlProvider extends MiElement {
|
|
|
46
46
|
this.i18n = new I18n(options), this.changeLanguage(options?.lng).catch(console.error);
|
|
47
47
|
}
|
|
48
48
|
_contextValue() {
|
|
49
|
-
const {
|
|
50
|
-
t: () => '',
|
|
49
|
+
const {lng: lng, getLanguages: getLanguages} = this.i18n ?? {
|
|
51
50
|
lng: '',
|
|
52
51
|
getLanguages: () => []
|
|
53
52
|
};
|
|
54
53
|
return {
|
|
55
|
-
t: t,
|
|
54
|
+
t: (label, values) => this.i18n?.t(label, values) ?? '',
|
|
56
55
|
lng: lng,
|
|
57
56
|
getLanguages: getLanguages,
|
|
58
57
|
changeLanguage: this.changeLanguage.bind(this),
|
|
@@ -62,7 +61,15 @@ class MiIntlProvider extends MiElement {
|
|
|
62
61
|
async changeLanguage(lng) {
|
|
63
62
|
this.loading = !0, await (this.i18n?.changeLanguage(lng).finally(() => {
|
|
64
63
|
this.requestUpdate();
|
|
65
|
-
}))
|
|
64
|
+
}));
|
|
65
|
+
for (let i = 0; i < 2; i++) await requestAnimationFrameP();
|
|
66
|
+
this.dispatchEvent(new CustomEvent('language-changed', {
|
|
67
|
+
detail: {
|
|
68
|
+
lng: lng
|
|
69
|
+
},
|
|
70
|
+
bubbles: !0,
|
|
71
|
+
composed: !0
|
|
72
|
+
})), this.loading = !1;
|
|
66
73
|
}
|
|
67
74
|
render() {
|
|
68
75
|
const {version: version, lng: lng, defaultNs: defaultNs, localesPath: localesPath, useLabel: useLabel, debug: debug, supportedLngs: supportedLngs, ns: ns} = this;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mi-intl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "i18n for mi-element",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
@@ -36,8 +36,9 @@
|
|
|
36
36
|
"types"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"intl-messageformat-tiny": "^1.
|
|
40
|
-
"mi-
|
|
39
|
+
"intl-messageformat-tiny": "^1.2.0",
|
|
40
|
+
"mi-signal": "^0.9.0",
|
|
41
|
+
"mi-element": "0.9.0"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@eslint/js": "^9.39.2",
|
package/src/cookie.js
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export function cookieParse(cookieStr = '') {
|
|
10
10
|
const parts = cookieStr.split(/\s*;\s*/)
|
|
11
|
-
const cookies =
|
|
11
|
+
const cookies = Object.create(null)
|
|
12
12
|
for (const part of parts) {
|
|
13
13
|
const [key, val] = part.split('=')
|
|
14
|
-
if (key) {
|
|
14
|
+
if (key && !Object.prototype.hasOwnProperty.call(Object.prototype, key)) {
|
|
15
15
|
const value = decodeURIComponent(val)
|
|
16
16
|
cookies[key] = value
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
return cookies
|
|
19
|
+
return { ...cookies }
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
package/src/intl-message.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MiElement } from 'mi-element'
|
|
1
|
+
import { MiElement, escHtml } from 'mi-element'
|
|
2
2
|
import { IntlConsumer } from './intl-consumer.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -8,34 +8,54 @@ import { IntlConsumer } from './intl-consumer.js'
|
|
|
8
8
|
* import { define } from 'mi-element'
|
|
9
9
|
* import { MiIntlMessage } from 'mi-intl'
|
|
10
10
|
*
|
|
11
|
-
* define('mi-message',
|
|
12
|
-
*
|
|
13
|
-
* static get properties() {
|
|
14
|
-
* return { label: {}, value: {} }
|
|
15
|
-
* }
|
|
16
|
-
* update() {
|
|
17
|
-
* this.renderRoot.textContent = this.t(this.label, this.value)
|
|
18
|
-
* }
|
|
19
|
-
* }
|
|
20
|
-
* )
|
|
11
|
+
* define('mi-message', MiIntlMessage)
|
|
12
|
+
* // then use <mi-message label="my.label" value='{ "count": 5 }'></mi-message> in your template
|
|
21
13
|
* ```
|
|
22
14
|
*/
|
|
23
15
|
export class MiIntlMessage extends MiElement {
|
|
24
16
|
#context
|
|
25
17
|
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
label: {},
|
|
21
|
+
value: {},
|
|
22
|
+
unsafeHtml: { type: Boolean, initial: false }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
26
|
constructor() {
|
|
27
27
|
super()
|
|
28
28
|
this.#context = new IntlConsumer(this)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @param {string} label
|
|
33
|
+
* @param {object} [value]
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
31
36
|
t(label, value) {
|
|
32
37
|
return this.#context.value.t(label, value)
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
/*
|
|
36
40
|
update() {
|
|
37
|
-
//
|
|
38
|
-
//
|
|
41
|
+
// ensure value is an object for interpolation, if it's a string
|
|
42
|
+
// try to parse it as JSON otherwise use it as a value property
|
|
43
|
+
if (typeof this.value === 'string') {
|
|
44
|
+
try {
|
|
45
|
+
this.value = JSON.parse(this.value)
|
|
46
|
+
} catch {
|
|
47
|
+
this.value = { value: this.value }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (this.unsafeHtml) {
|
|
51
|
+
// escape values for interpolation to prevent XSS
|
|
52
|
+
const escValue = {}
|
|
53
|
+
for (const [key, val] of Object.entries(this.value || {})) {
|
|
54
|
+
escValue[key] = escHtml(val)
|
|
55
|
+
}
|
|
56
|
+
this.renderRoot.innerHTML = this.t(this.label, escValue)
|
|
57
|
+
} else {
|
|
58
|
+
this.renderRoot.textContent = this.t(this.label, this.value)
|
|
59
|
+
}
|
|
39
60
|
}
|
|
40
|
-
*/
|
|
41
61
|
}
|
package/src/intl-provider.js
CHANGED
|
@@ -48,8 +48,10 @@ export class MiIntlProvider extends MiElement {
|
|
|
48
48
|
* @returns {IntlContext}
|
|
49
49
|
*/
|
|
50
50
|
_contextValue() {
|
|
51
|
-
const
|
|
52
|
-
|
|
51
|
+
const t = (label, values) => this.i18n?.t(label, values) ?? ''
|
|
52
|
+
|
|
53
|
+
const { lng, getLanguages } = this.i18n ?? {
|
|
54
|
+
t,
|
|
53
55
|
lng: '',
|
|
54
56
|
getLanguages: () => []
|
|
55
57
|
}
|
|
@@ -71,9 +73,17 @@ export class MiIntlProvider extends MiElement {
|
|
|
71
73
|
await this.i18n?.changeLanguage(lng).finally(() => {
|
|
72
74
|
this.requestUpdate()
|
|
73
75
|
})
|
|
74
|
-
// need to wait two
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
// need to wait two animation frames until all updates have been propagated
|
|
77
|
+
for (let i = 0; i < 2; i++) {
|
|
78
|
+
await requestAnimationFrameP()
|
|
79
|
+
}
|
|
80
|
+
this.dispatchEvent(
|
|
81
|
+
new CustomEvent('language-changed', {
|
|
82
|
+
detail: { lng },
|
|
83
|
+
bubbles: true,
|
|
84
|
+
composed: true
|
|
85
|
+
})
|
|
86
|
+
)
|
|
77
87
|
this.loading = false
|
|
78
88
|
}
|
|
79
89
|
|
package/types/intl-message.d.ts
CHANGED
|
@@ -5,20 +5,27 @@
|
|
|
5
5
|
* import { define } from 'mi-element'
|
|
6
6
|
* import { MiIntlMessage } from 'mi-intl'
|
|
7
7
|
*
|
|
8
|
-
* define('mi-message',
|
|
9
|
-
*
|
|
10
|
-
* static get properties() {
|
|
11
|
-
* return { label: {}, value: {} }
|
|
12
|
-
* }
|
|
13
|
-
* update() {
|
|
14
|
-
* this.renderRoot.textContent = this.t(this.label, this.value)
|
|
15
|
-
* }
|
|
16
|
-
* }
|
|
17
|
-
* )
|
|
8
|
+
* define('mi-message', MiIntlMessage)
|
|
9
|
+
* // then use <mi-message label="my.label" value='{ "count": 5 }'></mi-message> in your template
|
|
18
10
|
* ```
|
|
19
11
|
*/
|
|
20
12
|
export class MiIntlMessage extends MiElement {
|
|
21
|
-
|
|
13
|
+
static get properties(): {
|
|
14
|
+
label: {};
|
|
15
|
+
value: {};
|
|
16
|
+
unsafeHtml: {
|
|
17
|
+
type: BooleanConstructor;
|
|
18
|
+
initial: boolean;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* @param {string} label
|
|
23
|
+
* @param {object} [value]
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
26
|
+
t(label: string, value?: object): any;
|
|
27
|
+
update(): void;
|
|
28
|
+
value: any;
|
|
22
29
|
#private;
|
|
23
30
|
}
|
|
24
31
|
import { MiElement } from 'mi-element';
|