Skip to content

Commit 7344f2c

Browse files
author
Sebi Nemeth
committed
int vue3 & demo app
1 parent 49015e1 commit 7344f2c

22 files changed

+1596
-102
lines changed

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"i18n-ally.localesPaths": [
3+
"src/demo/lang"
4+
]
5+
}

dist/demo/i18n.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export declare const i18n: import("vue-i18n").I18n<any, {}, {}, string, false>;

dist/demo/i18n.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createI18n } from "vue-i18n";
2+
import en from './lang/en.json';
3+
import hu from './lang/hu.json';
4+
import { encodeMessages } from "..";
5+
export const i18n = createI18n({
6+
legacy: false,
7+
locale: 'en',
8+
fallbackLocale: 'en',
9+
messages: encodeMessages({
10+
en,
11+
hu,
12+
}),
13+
});

dist/demo/lang/en.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"LTPlugin": {
3+
"HelloWorld": "Hello world",
4+
"WelcomeToLT": "Welcome to {app}",
5+
"Messages": "You have no messages | You have a message | You have more messages",
6+
"MessagesCount": "{n} message | {n} messages",
7+
"Attrs": {
8+
"ImageAlt": "Image alt",
9+
"ImageTitle": "Image title"
10+
}
11+
}
12+
}

dist/demo/lang/hu.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"LTPlugin": {
3+
"HelloWorld": "Szia világ",
4+
"WelcomeToLT": "Üdvözöl a(z) {app}",
5+
"Messages": "Nincs új üzeneted | Egy új üzenet | Több új üzenet",
6+
"MessagesCount": "{n} új üzenet",
7+
"Attrs": {
8+
"ImageAlt": "Képleírás",
9+
"ImageTitle": "Képcím"
10+
}
11+
}
12+
}

dist/demo/main.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './style.css';

dist/demo/main.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { createApp } from 'vue';
2+
import './style.css';
3+
import App from './App.vue';
4+
import { i18n } from './i18n';
5+
import { LiveTranslatorPlugin } from '../index';
6+
const app = createApp(App);
7+
app.use(i18n);
8+
app.use(LiveTranslatorPlugin, {
9+
translationLink(meta) {
10+
return `?meta=${encodeURIComponent(JSON.stringify(meta))}`;
11+
},
12+
persist: true,
13+
});
14+
app.mount('#app');

dist/index.d.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import VueI18n from 'vue-i18n';
21
export type TranslationMeta = {
32
locale: string;
43
message: string;
54
values?: object;
65
path: string;
76
};
87
type LiveTranslatorPluginOptions = {
9-
i18n: VueI18n;
108
translationLink: (meta: TranslationMeta) => string;
119
persist?: boolean;
1210
};
11+
export declare function encodeMessages(messagesObject: any): any;
1312
export declare const LiveTranslatorPlugin: {
1413
install(app: any, options: LiveTranslatorPluginOptions): void;
1514
};

dist/index.js

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import throttle from 'lodash/throttle';
2+
import forIn from 'lodash/forIn';
3+
import cloneDeep from 'lodash/cloneDeep';
4+
import set from 'lodash/set';
25
const css = `
36
.live-translator-enable-button {
47
position: fixed !important;
@@ -57,6 +60,31 @@ const css = `
5760
box-shadow: 0px 0px 5px #00c0ff !important;
5861
}
5962
`;
63+
function deepForIn(object, fn) {
64+
const iteratee = (v, k) => {
65+
if (typeof v === 'object') {
66+
forIn(v, (childV, childK) => iteratee(childV, `${k}.${childK}`));
67+
}
68+
else {
69+
fn(v, k);
70+
}
71+
};
72+
forIn(object, iteratee);
73+
}
74+
export function encodeMessages(messagesObject) {
75+
const messages = cloneDeep(messagesObject);
76+
forIn(messages, (localeMessages, locale) => {
77+
deepForIn(localeMessages, (message, path) => {
78+
const meta = ZeroWidthEncoder.encode(JSON.stringify({
79+
locale,
80+
message,
81+
path,
82+
}));
83+
set(localeMessages, path, meta + message);
84+
});
85+
});
86+
return messages;
87+
}
6088
class ZeroWidthEncoder {
6189
static START = '\u200B';
6290
static ZERO = '\u200C';
@@ -134,35 +162,11 @@ class LiveTranslatorManager {
134162
this._enableButton.appendChild(this._indicator);
135163
this._enableButton.addEventListener('click', () => {
136164
this.toggle();
137-
this.refreshI18n();
138165
this.render();
139166
});
140167
document.body.appendChild(this._enableButton);
141168
// initialize encode
142-
const originalFormatter = this._options.i18n.formatter;
143-
const self = this;
144-
this._options.i18n.formatter = {
145-
interpolate(message, values, path) {
146-
const original = originalFormatter.interpolate(message, values, path);
147-
let meta = '';
148-
try {
149-
// filter nested objects, replace inner objects with string 'object'
150-
// this is needed when values from <i18n> tags are circular dependent objects
151-
const filteredValues = Object.fromEntries(Object.entries(values || {})
152-
.map(([key, value]) => [key, typeof value !== 'object' ? value : 'object']));
153-
meta = ZeroWidthEncoder.encode(JSON.stringify({
154-
message,
155-
values: filteredValues,
156-
path,
157-
locale: self._options.i18n.locale,
158-
}));
159-
}
160-
catch (exception) {
161-
console.warn(message, values, path, self._options.i18n.locale, exception);
162-
}
163-
return (original && meta && self._enabled) ? [meta, ...original] : original;
164-
},
165-
};
169+
// encode is moved to i18n.ts file
166170
// initialize decode & render
167171
const throttler = throttle(() => this.render(), 800);
168172
const observer = new MutationObserver(throttler);
@@ -174,14 +178,8 @@ class LiveTranslatorManager {
174178
});
175179
document.documentElement.addEventListener('mousemove', throttler);
176180
// render for the first time
177-
this.refreshI18n();
178181
this.render();
179182
}
180-
refreshI18n() {
181-
const originalLocale = this._options.i18n.locale;
182-
this._options.i18n.locale = '';
183-
this._options.i18n.locale = originalLocale;
184-
}
185183
toggle(enable) {
186184
if (enable !== undefined) {
187185
this._enabled = enable;

index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Vue i18n Live Translator plugin</title>
7+
</head>
8+
<body>
9+
<div id="app"></div>
10+
<script type="module" src="/src/demo/main.ts"></script>
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)