vue-inter
Version:
Simple i18n for Vue.js
156 lines (122 loc) • 3.81 kB
JavaScript
import assign from 'nano-assign';
var defaultTemplate = (function (tpl, data) {
if (!data) { return tpl; }
var re = /{(.*?)}/g;
return tpl.replace(re, function (_, key) {
var ret = data;
for (var i = 0, list = key.split('.'); i < list.length; i += 1) {
var prop = list[i];
ret = ret ? ret[prop] : '';
}
return ret || '';
});
});
function getPathSegments(path) {
var pathArr = path.split('.');
var parts = [];
for (var i = 0; i < pathArr.length; i++) {
var p = pathArr[i];
while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) {
p = p.slice(0, -1) + '.';
p += pathArr[++i];
}
parts.push(p);
}
return parts;
}
function getProp (data, path) {
return getPathSegments(path).reduce(function (obj, k) { return obj && obj[k]; }, data);
}
var FormatMessage = {
name: 'FormatMessage',
functional: true,
props: {
path: {
type: String,
required: true
},
data: {
type: Object
},
defaultMessage: {
type: String
},
tag: {
type: [String, Object],
default: 'span'
}
},
render: function render(h, ref) {
var props = ref.props;
var data = ref.data;
var listeners = ref.listeners;
var parent = ref.parent;
var inter = parent.$inter;
var message = inter.formatMessage({
path: props.path,
defaultMessage: props.defaultMessage
}, props.data);
return h(props.tag, assign({}, data, {
on: listeners
}), [message]);
}
};
var Vue;
var Inter = function Inter(ref) {
var locale = ref.locale;
var messages = ref.messages; if ( messages === void 0 ) messages = {};
var template = ref.template; if ( template === void 0 ) template = defaultTemplate;
if (process.env.NODE_ENV === 'development' && !Vue) {
throw new Error('You have to install `vue-inter` first: Vue.use(Inter)');
}
this.template = template;
this.messages = messages;
Vue.util.defineReactive(this, '__locale', locale);
};
var prototypeAccessors = { currentLocale: { configurable: true },availableLocales: { configurable: true } };
Inter.install = function install (_Vue) {
Vue = _Vue;
Vue.mixin({
beforeCreate: function beforeCreate() {
this.$inter = this.$options.inter || this.$parent && this.$parent.$inter;
}
});
Vue.component(FormatMessage.name, FormatMessage);
};
Inter.prototype.formatMessage = function formatMessage (messageDescriptor) {
var data = [], len = arguments.length - 1;
while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ];
if (typeof messageDescriptor !== 'object') {
throw new TypeError('messageDescriptor in .formatMessage must be an object.');
}
var path = messageDescriptor.path;
var defaultMessage = messageDescriptor.defaultMessage;
var localeData = this.messages[this.currentLocale]; // Get message from path
var message = path && getProp(localeData, path);
if (typeof message === 'function') {
return message.apply(void 0, data);
}
if (typeof message === 'undefined') {
// Fallback to defaultMessage
// Fallback to path literal
message = typeof defaultMessage === 'undefined' ? path : defaultMessage;
}
return (ref = this).template.apply(ref, [ message ].concat( data ));
var ref;
};
prototypeAccessors.currentLocale.get = function () {
return this.__locale;
};
Inter.prototype.setCurrentLocale = function setCurrentLocale (locale) {
this.__locale = locale;
return this;
};
Inter.prototype.setLocaleData = function setLocaleData (locale, localData) {
this.messages[locale] = localData;
return this;
};
prototypeAccessors.availableLocales.get = function () {
return Object.keys(this.messages);
};
Object.defineProperties( Inter.prototype, prototypeAccessors );
export default Inter;