/* @flow */ import VueI18n from './index' import { isPlainObject, warn, error, merge } from './util' /** * Mixin * * If `bridge` mode, empty mixin is returned, * else regulary mixin implementation is returned. */ export default function defineMixin (bridge: boolean = false) { function mounted (): void { if (this !== this.$root && this.$options.__INTLIFY_META__ && this.$el) { this.$el.setAttribute('data-intlify', this.$options.__INTLIFY_META__) } } return bridge ? { mounted } // delegate `vue-i18n-bridge` mixin implementation : { // regulary beforeCreate (): void { const options: any = this.$options options.i18n = options.i18n || ((options.__i18nBridge || options.__i18n) ? {} : null) if (options.i18n) { if (options.i18n instanceof VueI18n) { // init locale messages via custom blocks if ((options.__i18nBridge || options.__i18n)) { try { let localeMessages = options.i18n && options.i18n.messages ? options.i18n.messages : {} const __i18n = options.__i18nBridge || options.__i18n __i18n.forEach(resource => { localeMessages = merge(localeMessages, JSON.parse(resource)) }) Object.keys(localeMessages).forEach((locale: Locale) => { options.i18n.mergeLocaleMessage(locale, localeMessages[locale]) }) } catch (e) { if (process.env.NODE_ENV !== 'production') { error(`Cannot parse locale messages via custom blocks.`, e) } } } this._i18n = options.i18n this._i18nWatcher = this._i18n.watchI18nData() } else if (isPlainObject(options.i18n)) { const rootI18n = this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n ? this.$root.$i18n : null // component local i18n if (rootI18n) { options.i18n.root = this.$root options.i18n.formatter = rootI18n.formatter options.i18n.fallbackLocale = rootI18n.fallbackLocale options.i18n.formatFallbackMessages = rootI18n.formatFallbackMessages options.i18n.silentTranslationWarn = rootI18n.silentTranslationWarn options.i18n.silentFallbackWarn = rootI18n.silentFallbackWarn options.i18n.pluralizationRules = rootI18n.pluralizationRules options.i18n.preserveDirectiveContent = rootI18n.preserveDirectiveContent } // init locale messages via custom blocks if ((options.__i18nBridge || options.__i18n)) { try { let localeMessages = options.i18n && options.i18n.messages ? options.i18n.messages : {} const __i18n = options.__i18nBridge || options.__i18n __i18n.forEach(resource => { localeMessages = merge(localeMessages, JSON.parse(resource)) }) options.i18n.messages = localeMessages } catch (e) { if (process.env.NODE_ENV !== 'production') { warn(`Cannot parse locale messages via custom blocks.`, e) } } } const { sharedMessages } = options.i18n if (sharedMessages && isPlainObject(sharedMessages)) { options.i18n.messages = merge(options.i18n.messages, sharedMessages) } this._i18n = new VueI18n(options.i18n) this._i18nWatcher = this._i18n.watchI18nData() if (options.i18n.sync === undefined || !!options.i18n.sync) { this._localeWatcher = this.$i18n.watchLocale() } if (rootI18n) { rootI18n.onComponentInstanceCreated(this._i18n) } } else { if (process.env.NODE_ENV !== 'production') { warn(`Cannot be interpreted 'i18n' option.`) } } } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) { // root i18n this._i18n = this.$root.$i18n } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) { // parent i18n this._i18n = options.parent.$i18n } }, beforeMount (): void { const options: any = this.$options options.i18n = options.i18n || ((options.__i18nBridge || options.__i18n) ? {} : null) if (options.i18n) { if (options.i18n instanceof VueI18n) { // init locale messages via custom blocks this._i18n.subscribeDataChanging(this) this._subscribing = true } else if (isPlainObject(options.i18n)) { this._i18n.subscribeDataChanging(this) this._subscribing = true } else { if (process.env.NODE_ENV !== 'production') { warn(`Cannot be interpreted 'i18n' option.`) } } } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) { this._i18n.subscribeDataChanging(this) this._subscribing = true } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) { this._i18n.subscribeDataChanging(this) this._subscribing = true } }, mounted, beforeDestroy (): void { if (!this._i18n) { return } const self = this this.$nextTick(() => { if (self._subscribing) { self._i18n.unsubscribeDataChanging(self) delete self._subscribing } if (self._i18nWatcher) { self._i18nWatcher() self._i18n.destroyVM() delete self._i18nWatcher } if (self._localeWatcher) { self._localeWatcher() delete self._localeWatcher } }) } } }