Skip to content

Commit

Permalink
⚡ improvement(path): tweak for ssr
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon committed May 14, 2017
1 parent e7bcfb1 commit eb21921
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 53 deletions.
8 changes: 5 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
canUseNumberFormat
} from './util'
import BaseFormatter from './format'
import getPathValue from './path'
import I18nPath from './path'

import type { PathValue } from './path'

Expand All @@ -34,6 +34,7 @@ export default class VueI18n {
_silentTranslationWarn: boolean
_dateTimeFormatters: Object
_numberFormatters: Object
_path: I18nPath

constructor (options: I18nOptions = {}) {
const locale: Locale = options.locale || 'en-US'
Expand All @@ -55,10 +56,11 @@ export default class VueI18n {
: !!options.silentTranslationWarn
this._dateTimeFormatters = {}
this._numberFormatters = {}
this._path = new I18nPath()

this._exist = (message: Object, key: Path): boolean => {
if (!message || !key) { return false }
return !isNull(getPathValue(message, key))
return !isNull(this._path.getPathValue(message, key))
}

this._initVM({
Expand Down Expand Up @@ -169,7 +171,7 @@ export default class VueI18n {
): any {
if (!message) { return null }

const pathRet: PathValue = getPathValue(message, key)
const pathRet: PathValue = this._path.getPathValue(message, key)
if (Array.isArray(pathRet)) { return pathRet }

let ret: mixed
Expand Down
86 changes: 45 additions & 41 deletions src/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import { isObject, isPlainObject, hasOwn } from './util'
* Vue.js Path parser
*/

// cache
const pathCache: { [key: Path]: any } = Object.create(null)

// actions
const APPEND = 0
const PUSH = 1
Expand Down Expand Up @@ -261,21 +258,6 @@ function parse (path: Path): ?Array<string> {
}
}

/**
* External parse that check for a cache hit first
*/

function parsePath (path: Path): Array<string> {
let hit: ?Array<string> = pathCache[path]
if (!hit) {
hit = parse(path)
if (hit) {
pathCache[path] = hit
}
}
return hit || []
}

export type PathValue = PathValueObject | PathValueArray | string | number | boolean | null
export type PathValueObject = { [key: string]: PathValue }
export type PathValueArray = Array<PathValue>
Expand All @@ -295,31 +277,53 @@ function empty (target: any): boolean {
return true
}

/**
* Get path value from path string
*/
export default function getPathValue (obj: mixed, path: Path): PathValue {
if (!isObject(obj)) { return null }

const paths: Array<string> = parsePath(path)
if (empty(paths)) {
return null
} else {
const length: number = paths.length
let ret: any = null
let last: any = obj
let i: number = 0
while (i < length) {
const value: any = last[paths[i]]
if (value === undefined) {
last = null
break
export default class I18nPath {
_cache: Object

constructor () {
this._cache = Object.create(null)
}

/**
* External parse that check for a cache hit first
*/
parsePath (path: Path): Array<string> {
let hit: ?Array<string> = this._cache[path]
if (!hit) {
hit = parse(path)
if (hit) {
this._cache[path] = hit
}
last = value
i++
}
return hit || []
}

/**
* Get path value from path string
*/
getPathValue (obj: mixed, path: Path): PathValue {
if (!isObject(obj)) { return null }

ret = last
return ret
const paths: Array<string> = this.parsePath(path)
if (empty(paths)) {
return null
} else {
const length: number = paths.length
let ret: any = null
let last: any = obj
let i: number = 0
while (i < length) {
const value: any = last[paths[i]]
if (value === undefined) {
last = null
break
}
last = value
i++
}

ret = last
return ret
}
}
}
20 changes: 11 additions & 9 deletions test/unit/path.test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import getPathValue from '../../src/path'
import I18nPath from '../../src/path'

describe('path', () => {
const path = new I18nPath()

describe('primivite', () => {
it('should get path value', () => {
assert.equal(getPathValue({ a: { b: 1 } }, 'a.b'), 1)
assert.equal(path.getPathValue({ a: { b: 1 } }, 'a.b'), 1)
})
})

describe('object', () => {
it('should get path value', () => {
const val = getPathValue({ a: { b: 1 } }, 'a')
const val = path.getPathValue({ a: { b: 1 } }, 'a')
assert.equal(val.b, 1)
})
})

describe('number key in object', () => {
it('should get path value', () => {
assert.equal(
getPathValue({ errors: { '1': 'error number 1' } }, 'errors[1]'),
path.getPathValue({ errors: { '1': 'error number 1' } }, 'errors[1]'),
'error number 1'
)
})
Expand All @@ -26,7 +28,7 @@ describe('path', () => {
describe('array index path', () => {
it('should get value', () => {
assert.equal(
getPathValue({ errors: ['error number 0'] }, 'errors[0]'),
path.getPathValue({ errors: ['error number 0'] }, 'errors[0]'),
'error number 0'
)
})
Expand All @@ -35,27 +37,27 @@ describe('path', () => {
describe('array path', () => {
it('should get path value', () => {
assert.equal(
getPathValue({ errors: ['error number 0'] }, 'errors')[0],
path.getPathValue({ errors: ['error number 0'] }, 'errors')[0],
'error number 0'
)
})
})

describe('not found', () => {
it('should not get null', () => {
assert.equal(getPathValue({}, 'a.b'), null)
assert.equal(path.getPathValue({}, 'a.b'), null)
})
})

describe('obj: primitive', () => {
it('should not get null', () => {
assert.equal(getPathValue(10, 'a.b'), null)
assert.equal(path.getPathValue(10, 'a.b'), null)
})
})

describe('obj: null', () => {
it('should not get null', () => {
assert.equal(getPathValue(null, 'a.b'), null)
assert.equal(path.getPathValue(null, 'a.b'), null)
})
})
})

0 comments on commit eb21921

Please sign in to comment.