mirror of https://github.com/rancher/dashboard.git
137 lines
3.5 KiB
JavaScript
137 lines
3.5 KiB
JavaScript
/* eslint-disable no-console */
|
|
import { escapeHtml } from '../utils/string';
|
|
import { watchEffect, ref, h } from 'vue';
|
|
import { useStore } from 'vuex';
|
|
|
|
export function stringFor(store, key, args, raw = false, escapehtml = true) {
|
|
const translation = store.getters['i18n/t'](key, args);
|
|
|
|
let out;
|
|
|
|
if ( translation !== undefined ) {
|
|
out = translation;
|
|
} else if ( args && Object.keys(args).length ) {
|
|
const argStr = Object.keys(args).map((k) => `${ k }: ${ args[k] }`).join(', ');
|
|
|
|
out = `%${ key }(${ argStr })%`;
|
|
raw = true;
|
|
} else {
|
|
out = `%${ key }%`;
|
|
}
|
|
|
|
if ( raw ) {
|
|
return out;
|
|
} else if (escapehtml) {
|
|
return escapeHtml(out);
|
|
} else {
|
|
return out;
|
|
}
|
|
}
|
|
|
|
function directive(el, binding, vnode /*, oldVnode */) {
|
|
const { instance } = binding;
|
|
const raw = binding.modifiers && binding.modifiers.raw === true;
|
|
const str = stringFor(instance.$store, binding.value, {}, raw);
|
|
|
|
if ( binding.arg ) {
|
|
el.setAttribute(binding.arg, str);
|
|
} else {
|
|
el.innerHTML = str;
|
|
}
|
|
}
|
|
|
|
export function directiveSsr(vnode, binding) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn('Function `directiveSsr` is deprecated. Please install i18n as a vue plugin: `vueApp.use(i18n)`');
|
|
|
|
const { context } = vnode;
|
|
const raw = binding.modifiers && binding.modifiers.raw === true;
|
|
const str = stringFor(context.$store, binding.value, {}, raw);
|
|
|
|
if ( binding.arg ) {
|
|
vnode.data.attrs[binding.arg] = str;
|
|
} else {
|
|
vnode.data.domProps = { innerHTML: str };
|
|
}
|
|
}
|
|
|
|
const i18n = {
|
|
name: 'i18n',
|
|
install: (vueApp, _options) => {
|
|
if (vueApp.config.globalProperties.t && vueApp.directive('t') && vueApp.component('t')) {
|
|
// eslint-disable-next-line no-console
|
|
console.debug('Skipping i18n install. Directive, component, and option already exist.');
|
|
}
|
|
|
|
vueApp.config.globalProperties.t = function(key, args, raw) {
|
|
return stringFor(this.$store, key, args, raw);
|
|
};
|
|
|
|
// InnerHTML: <some-tag v-t="'some.key'" />
|
|
// As an attribute: <some-tag v-t:title="'some.key'" />
|
|
vueApp.directive('t', {
|
|
beforeMount() {
|
|
directive(...arguments);
|
|
},
|
|
updated() {
|
|
directive(...arguments);
|
|
},
|
|
});
|
|
|
|
// Basic (but you might want the directive above): <t k="some.key" />
|
|
// With interpolation: <t k="some.key" count="1" :foo="bar" />
|
|
vueApp.component('t', {
|
|
inheritAttrs: false,
|
|
props: {
|
|
k: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
raw: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
tag: {
|
|
type: [String, Object],
|
|
default: 'span'
|
|
},
|
|
escapehtml: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
class: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
setup(props, ctx) {
|
|
const msg = ref('');
|
|
const store = useStore();
|
|
|
|
// Update msg whenever k, $attrs, raw, or escapehtml changes
|
|
watchEffect(() => {
|
|
msg.value = stringFor(store, props.k, ctx.attrs, props.raw, props.escapehtml);
|
|
});
|
|
|
|
return { msg };
|
|
},
|
|
render() {
|
|
if (this.raw) {
|
|
return h(
|
|
this.tag,
|
|
{ class: this.class, innerHTML: this.msg }
|
|
);
|
|
} else {
|
|
return h(
|
|
this.tag,
|
|
{ class: this.class },
|
|
[this.msg]
|
|
);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
export default i18n;
|