Skip to content
This repository has been archived by the owner on Dec 31, 2024. It is now read-only.

Commit

Permalink
feat(lang): support lang reactive changing
Browse files Browse the repository at this point in the history
Closes #2 #15
  • Loading branch information
kazupon committed Apr 13, 2016
1 parent f7d597a commit 203ee85
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 25 deletions.
35 changes: 35 additions & 0 deletions config/webpack.dev.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
var webpack = require('webpack')

module.exports = {
entry: './index.js',
output: {
path: './',
publicPath: '/',
filename: 'build.js'
},
devtool: 'source-map',
module: {
preLoaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader'
}],
loaders: [{
test: /\.js$/,
exclude: /node_modules|vue\/dist/,
loader: 'babel',
query: {
presets: ['es2015']
}
}]
},
devServer: {
contentBase: './',
port: 8080,
hot: true,
inline: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"rollup-plugin-babel": "^2.4.0",
"rollup-plugin-replace": "^1.1.0",
"uglify-js": "^2.6.1",
"vue": "^0.12.0",
"vue": "^1.0.21",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"
},
Expand Down Expand Up @@ -84,6 +84,7 @@
"coolkids": "VUE_I18N_TYPE=sauce SAUCE=batch1 karma start config/karma.conf.js",
"coverage": "VUE_I18N_TYPE=coverage karma start config/karma.conf.js",
"coveralls": "VUE_I18N_TYPE=coveralls karma start config/karma.conf.js",
"proto": "webpack-dev-server --quite --config config/webpack.dev.conf.js --host 0.0.0.0",
"dev": "webpack-dev-server --quiet --config config/webpack.test.conf.js",
"e2e": "webpack-dev-server --quiet --config config/webpack.e2e.conf.js & mocha -t 20000 --compilers js:espower-babel/guess test/e2e/test.js && kill $! || (kill $! && exit 1)",
"ie": "VUE_I18N_TYPE=sauce SAUCE=batch2 karma start config/karma.conf.js",
Expand Down
30 changes: 30 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { getWatcher, getDep } from './util'

export default function (Vue, langVM) {
const Watcher = getWatcher(langVM)
const Dep = getDep(langVM)

function makeComputedGetter (getter, owner) {
let watcher = new Watcher(owner, getter, null, {
lazy: true
})

return function computedGetter () {
if (watcher.dirty) {
watcher.evaluate()
}
if (Dep.target) {
watcher.depend()
}
return watcher.value
}
}

// define Vue.config.lang configration
Object.defineProperty(Vue.config, 'lang', {
enumerable: true,
configurable: true,
get: makeComputedGetter(() => { return langVM.lang }, langVM),
set: Vue.util.bind((val) => { langVM.lang = val }, langVM)
})
}
38 changes: 18 additions & 20 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import util, { warn } from './util'
import extend from './extend'
import { warn } from './util'
import Override from './override'
import Config from './config'
import Extend from './extend'

let langVM // singleton


/**
Expand All @@ -15,26 +19,20 @@ function plugin (Vue, opts = { lang: 'en', locales: {} }) {
return
}

defineConfig(Vue.config, opts.lang)
extend(Vue, opts.locales)
}

setupLangVM(Vue, opts.lang)

/**
* defineConfig
*
* This function define `lang` property to `Vue.config`.
*
* @param {Object} config
* @param {String} lang
* @private
*/
Override(Vue, langVM)
Config(Vue, langVM)
Extend(Vue, opts.locales)
}

function defineConfig (config, lang) {
Object.defineProperty(config, 'lang', {
get: () => { return lang },
set: (val) => { lang = val }
})
function setupLangVM (Vue, lang) {
const silent = Vue.config.silent
Vue.config.silent = true
if (!langVM) {
langVM = new Vue({ data: { lang: lang } })
}
Vue.config.silent = silent
}

plugin.version = '2.4.1'
Expand Down
40 changes: 40 additions & 0 deletions src/override.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export default function (Vue, langVM) {
// override _init
const init = Vue.prototype._init
Vue.prototype._init = function (options) {
options = options || {}
let root = options._parent || options.parent || this
let lang = root.$lang

if (lang) {
this.$lang = lang
} else {
this.$lang = langVM
}

this._langUnwatch = this.$lang.$watch('lang', (a, b) => {
update(this)
})

init.call(this, options)
}

// override _destroy
const destroy = Vue.prototype._destroy
Vue.prototype._destroy = function () {
if (this._langUnwatch) {
this._langUnwatch()
this._langUnwatch = null
}

this.$lang = null
destroy.apply(this, arguments)
}
}

function update (vm) {
let i = vm._watchers.length
while (i--) {
vm._watchers[i].update(true) // shallow updates
}
}
14 changes: 10 additions & 4 deletions test/specs/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,15 +291,21 @@ describe('i18n', () => {
})

context('ja', () => {
it('should translate with japanese', () => {
it('should translate with japanese', (done) => {
Vue.config.lang = 'ja'
assert(vm.$t('message.hello') === locales.ja.message.hello)
Vue.nextTick(() => {
assert(vm.$t('message.hello') === locales.ja.message.hello)
done()
})
})

context('en', () => {
it('should translate with english', () => {
it('should translate with english', (done) => {
Vue.config.lang = 'en'
assert(vm.$t('message.hello') === locales.en.message.hello)
Vue.nextTick(() => {
assert(vm.$t('message.hello') === locales.en.message.hello)
done()
})
})
})
})
Expand Down

0 comments on commit 203ee85

Please sign in to comment.