From eb219212779f1770048b100d33b734084dc42df4 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Sun, 14 May 2017 22:06:30 +0900 Subject: [PATCH] :zap: improvement(path): tweak for ssr --- src/index.js | 8 ++-- src/path.js | 86 ++++++++++++++++++++++-------------------- test/unit/path.test.js | 20 +++++----- 3 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/index.js b/src/index.js index ae8025551..6f025275d 100644 --- a/src/index.js +++ b/src/index.js @@ -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' @@ -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' @@ -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({ @@ -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 diff --git a/src/path.js b/src/path.js index 9dfcfa73d..e419587e6 100644 --- a/src/path.js +++ b/src/path.js @@ -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 @@ -261,21 +258,6 @@ function parse (path: Path): ?Array { } } -/** - * External parse that check for a cache hit first - */ - -function parsePath (path: Path): Array { - let hit: ?Array = 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 @@ -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 = 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 { + let hit: ?Array = 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 = 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 + } } } diff --git a/test/unit/path.test.js b/test/unit/path.test.js index 2885156d5..b5349b75c 100644 --- a/test/unit/path.test.js +++ b/test/unit/path.test.js @@ -1,15 +1,17 @@ -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) }) }) @@ -17,7 +19,7 @@ describe('path', () => { 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' ) }) @@ -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' ) }) @@ -35,7 +37,7 @@ 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' ) }) @@ -43,19 +45,19 @@ describe('path', () => { 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) }) }) })