-
Notifications
You must be signed in to change notification settings - Fork 56
/
vuex-i18n-store.js
196 lines (150 loc) · 4.59 KB
/
vuex-i18n-store.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/* vuex-i18n-store defines a vuex module to store locale translations. Make sure
** to also include the file vuex-i18n.js to enable easy access to localized
** strings in your vue components.
*/
// define a simple vuex module to handle locale translations
const i18nVuexModule = {
namespaced: true,
state: {
locale: null,
fallback: null,
translations: {}
},
mutations: {
// set the current locale
SET_LOCALE(state, payload) {
state.locale = payload.locale;
},
// add a new locale
ADD_LOCALE(state, payload) {
// reduce the given translations to a single-depth tree
var translations = flattenTranslations(payload.translations);
if (state.translations.hasOwnProperty(payload.locale)) {
// get the existing translations
let existingTranslations = state.translations[payload.locale];
// merge the translations
state.translations[payload.locale] = Object.assign({}, existingTranslations, translations);
} else {
// just set the locale if it does not yet exist
state.translations[payload.locale] = translations;
}
// make sure to notify vue of changes (this might break with new vue versions)
try {
if (state.translations.__ob__) {
state.translations.__ob__.dep.notify();
}
} catch(ex) {}
},
// replace existing locale information with new translations
REPLACE_LOCALE(state, payload) {
// reduce the given translations to a single-depth tree
var translations = flattenTranslations(payload.translations);
// replace the translations entirely
state.translations[payload.locale] = translations;
// make sure to notify vue of changes (this might break with new vue versions)
try {
if (state.translations.__ob__) {
state.translations.__ob__.dep.notify();
}
} catch(ex) {}
},
// remove a locale from the store
REMOVE_LOCALE(state, payload) {
// check if the given locale is present in the state
if (state.translations.hasOwnProperty(payload.locale)) {
// check if the current locale is the given locale to remvoe
if (state.locale === payload.locale) {
// reset the current locale
state.locale = null;
}
// create a copy of the translations object
let translationCopy = Object.assign({}, state.translations);
// remove the given locale
delete translationCopy[payload.locale];
// set the state to the new object
state.translations = translationCopy;
}
},
SET_FALLBACK_LOCALE(state, payload) {
state.fallback = payload.locale;
}
},
actions: {
// set the current locale
setLocale(context, payload) {
context.commit({
type: 'SET_LOCALE',
locale: payload.locale
});
},
// add or extend a locale with translations
addLocale(context, payload) {
context.commit({
type: 'ADD_LOCALE',
locale: payload.locale,
translations: payload.translations
});
},
// replace locale information
replaceLocale(context, payload) {
context.commit({
type: 'REPLACE_LOCALE',
locale: payload.locale,
translations: payload.translations
});
},
// remove the given locale translations
removeLocale(context, payload) {
context.commit({
type: 'REMOVE_LOCALE',
locale: payload.locale,
translations: payload.translations
});
},
setFallbackLocale(context, payload) {
context.commit({
type: 'SET_FALLBACK_LOCALE',
locale: payload.locale
});
}
}
};
// flattenTranslations will convert object trees for translations into a
// single-depth object tree
const flattenTranslations = function flattenTranslations(translations) {
let toReturn = {};
for (let i in translations) {
// check if the property is present
if (!translations.hasOwnProperty(i)) {
continue;
}
// get the type of the property
let objType = typeof translations[i];
// allow unflattened array of strings
if (isArray(translations[i])) {
let count = translations[i].length;
for (let index = 0; index < count; index++) {
let itemType = typeof translations[i][index];
if (itemType !== 'string') {
console.warn('i18n:','currently only arrays of strings are fully supported', translations[i]);
break;
}
}
toReturn[i] = translations[i];
} else if (objType == 'object' && objType !== null) {
let flatObject = flattenTranslations(translations[i]);
for (let x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;
toReturn[i + '.' + x] = flatObject[x];
}
} else {
toReturn[i] = translations[i];
}
}
return toReturn;
};
// check if the given object is an array
function isArray(obj) {
return !!obj && Array === obj.constructor;
}
export default i18nVuexModule;