Skip to content

Commit

Permalink
refactor: add 'locale' option for selecting locale
Browse files Browse the repository at this point in the history
BREAKING CHANGE: instead of using order of bundles for selecting locale
'locale' property on fluent object should be used
  • Loading branch information
Demivan committed Jul 12, 2020
1 parent 69e5423 commit 56a1aac
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 15 deletions.
6 changes: 4 additions & 2 deletions packages/fluent-vue/__tests__/changeLanguage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe('language change', () => {
bundleUk = new FluentBundle('uk-UA')

const fluent = new FluentVue({
locale: ['uk-UA', 'en-US'],
bundles: [bundleUk, bundleEn],
})

Expand Down Expand Up @@ -72,7 +73,7 @@ describe('language change', () => {
expect(mounted.html()).toEqual(`<a href="/foo">link text</a>`)
})

it('updates when updating bundles array', async () => {
it('updates when changing current locale', async () => {
// Arrange
const localVue = createLocalVue()
localVue.use(FluentVue)
Expand All @@ -81,6 +82,7 @@ describe('language change', () => {
bundleUk = new FluentBundle('uk-UA')

const fluent = new FluentVue({
locale: 'uk-UA',
bundles: [bundleUk, bundleEn],
})

Expand Down Expand Up @@ -108,7 +110,7 @@ describe('language change', () => {

expect(mounted.html()).toEqual(`<a href="/foo">текст посилання</a>`)

fluent.bundles = [bundleEn, bundleUk]
fluent.locale = 'en'

await Vue.nextTick()

Expand Down
1 change: 1 addition & 0 deletions packages/fluent-vue/__tests__/errorHandling.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe('vue integration', () => {
)

const fluent = new FluentVue({
locale: 'en-US',
bundles: [bundle],
})

Expand Down
1 change: 1 addition & 0 deletions packages/fluent-vue/__tests__/vue/component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('component', () => {
bundle = new FluentBundle('en-US')

const fluent = new FluentVue({
locale: 'en-US',
bundles: [bundle],
})

Expand Down
1 change: 1 addition & 0 deletions packages/fluent-vue/__tests__/vue/customComponents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('method', () => {
bundle = new FluentBundle('en-US')

const fluent = new FluentVue({
locale: 'en-US',
bundles: [bundle],
})

Expand Down
1 change: 1 addition & 0 deletions packages/fluent-vue/__tests__/vue/directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('directive', () => {
bundle = new FluentBundle('en-US')

const fluent = new FluentVue({
locale: 'en-US',
bundles: [bundle],
})

Expand Down
3 changes: 2 additions & 1 deletion packages/fluent-vue/__tests__/vue/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ describe('vue integration', () => {
)

const fluent = new FluentVue({
bundles: [bundle],
locale: 'en-US',
bundles: [bundle]
})

const options = {
Expand Down
1 change: 1 addition & 0 deletions packages/fluent-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"dependencies": {
"@fluent/sequence": "^0.5.0",
"@fluent/langneg": "^0.5.0",
"cached-iterable": "^0.3.0",
"tslib": "^1.11.1"
},
Expand Down
44 changes: 36 additions & 8 deletions packages/fluent-vue/src/fluentVue.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Vue, { VueConstructor } from 'vue'
import { CachedSyncIterable } from 'cached-iterable'
import { mapBundleSync } from '@fluent/sequence'
import { negotiateLanguages } from '@fluent/langneg'
import { warn } from './util/warn'

import { FluentBundle, FluentArgument } from '@fluent/bundle'
Expand All @@ -14,7 +15,9 @@ import { Pattern } from '@fluent/bundle/esm/ast'
export default class FluentVue implements FluentVueObject {
private subscribers: Map<IUpdatable, boolean>
private bundlesIterable: Iterable<FluentBundle>
private _bundles: FluentBundle[]
private _locale: string|string[]

allBundles: FluentBundle[]

/**
* Add object to list of objects to notify
Expand All @@ -31,13 +34,14 @@ export default class FluentVue implements FluentVueObject {
this.subscribers.delete(updatable)
}

get bundles(): FluentBundle[] {
return this._bundles
get locale(): string|string[] {
return this._locale
}

set bundles(bundles: FluentBundle[]) {
this._bundles = bundles
this.bundlesIterable = CachedSyncIterable.from(this.bundles)
set locale (value: string|string[]) {
this._locale = value
const orderedBundles = this.getOrderedBundles(value, this.allBundles)
this.bundlesIterable = CachedSyncIterable.from(orderedBundles)

for (const subscriber of this.subscribers.keys()) {
subscriber.$forceUpdate()
Expand All @@ -52,8 +56,32 @@ export default class FluentVue implements FluentVueObject {
*/
constructor(options: FluentVueOptions) {
this.subscribers = new Map<Vue, boolean>()
this._bundles = options.bundles
this.bundlesIterable = CachedSyncIterable.from(this.bundles)
this.allBundles = options.bundles
this._locale = options.locale
const orderedBundles = this.getOrderedBundles(options.locale, this.allBundles)
this.bundlesIterable = CachedSyncIterable.from(orderedBundles)
}

private getOrderedBundles (requestedLocale: string|string[], bundles: FluentBundle[]): FluentBundle[] {
if (!Array.isArray(requestedLocale)) {
requestedLocale = [requestedLocale]
}

const avaliableLocales = bundles.flatMap(bundle => bundle.locales)
const negotiatedLocales = negotiateLanguages(
requestedLocale,
avaliableLocales, {
strategy: 'filtering'
})

const newBundles = negotiatedLocales
.map(locale => bundles.find(bundle => bundle.locales.includes(locale)))

const dedupeBundles = newBundles
.filter((bundle, i) => newBundles.indexOf(bundle) === i)
.filter(bundle => bundle != null) as FluentBundle[]

return dedupeBundles
}

getBundle(key: string): FluentBundle | null {
Expand Down
3 changes: 3 additions & 0 deletions packages/fluent-vue/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ export interface FluentVueObject {
}

export interface FluentVueOptions {
/** Currently selected locale */
locale: string|string[],
/** List of bundles used in application */
bundles: FluentBundle[]
}
9 changes: 5 additions & 4 deletions packages/fluent-vue/src/mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default {
// If we override messages in a component
// create new FluentVue instance with new bundles
if (this.$options.__fluent) {
const bundles = fluent.bundles
const bundles = fluent.allBundles
.map(bundle => {
// Copy options to new bundle
const newBundle = new FluentBundle(bundle.locales, {
Expand All @@ -46,17 +46,18 @@ export default {
})

// Add new messages to bundles
for (const [lang, resources] of Object.entries(this.$options.__fluent)) {
const bundle = bundles.find(bundle => bundle.locales.join(' ') === lang)
for (const [locale, resources] of Object.entries(this.$options.__fluent)) {
const bundle = bundles.find(bundle => bundle.locales.includes(locale))
if (!bundle) {
warn(`Component ${this.$options.name} overides translations for locale "${lang}" that is not in your bundles`)
warn(`Component ${this.$options.name} overides translations for locale "${locale}" that is not in your bundles`)
continue
}

bundle.addResource(resources, { allowOverrides: true })
}

this._fluent = new FluentVue({
locale: fluent.locale,
bundles
})

Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@
resolved "https://registry.yarnpkg.com/@fluent/dedent/-/dedent-0.2.0.tgz#e2a08df6e0e0114f9515a14364b5d8ffd13cf9ef"
integrity sha512-Hlp2wOdNGMqCwBFphGwX8U9CE5qoeZVegnxap4OVK+YzvZb29fR3Lv8xNA0Kdk3cUWFrd+x/ux71PqxbXX71ng==

"@fluent/langneg@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@fluent/langneg/-/langneg-0.5.0.tgz#de448070efa16c8fb6cc4af1629663f01e10689b"
integrity sha512-jv0g3YO5byz29HXEE6DBzAog60q726mwV2nIoekEX590JVh+mbd6/ZXT5/l4mN2BMlrelzyscCTffKI4XScVtg==

"@fluent/sequence@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@fluent/sequence/-/sequence-0.5.0.tgz#6349b614711df2d8ed256598fa31a757fe032539"
Expand Down

0 comments on commit 56a1aac

Please sign in to comment.