mirror of
https://github.com/cupcakearmy/svelte-i18n.git
synced 2024-11-16 09:59:58 +01:00
feat: 🎸 add pathname and hostname pattern matching
This commit is contained in:
parent
bf5ad6e387
commit
b19b69050e
12
README.md
12
README.md
@ -58,7 +58,11 @@ locale.set(
|
||||
// set the key name to look for a locale on 'window.location.hash'
|
||||
// 'example.com#locale=en-US'
|
||||
hash: 'locale',
|
||||
}),
|
||||
// define a pattern to look in the window.location.pathname. It returns the first capturing group.
|
||||
pathname: /^\/(.*?)\//,
|
||||
// define a pattern to look in the window.location.hostname. It returns the first capturing group.
|
||||
hostname: /^\/(.*?)\//,
|
||||
})
|
||||
)
|
||||
```
|
||||
|
||||
@ -82,7 +86,8 @@ dictionary.set({
|
||||
ask: 'Por favor, digite seu nome',
|
||||
message: 'Olá {name}, como vai?',
|
||||
},
|
||||
photos: 'Você {n, plural, =0 {não tem fotos.} =1 {tem uma foto.} other {tem # fotos.}}',
|
||||
photos:
|
||||
'Você {n, plural, =0 {não tem fotos.} =1 {tem uma foto.} other {tem # fotos.}}',
|
||||
cats: 'Tenho {n, number} {n,plural,=0{gatos}one{gato}other{gatos}}',
|
||||
},
|
||||
en: {
|
||||
@ -92,7 +97,8 @@ dictionary.set({
|
||||
ask: 'Please type your name',
|
||||
message: 'Hello {name}, how are you?',
|
||||
},
|
||||
photos: 'You have {n, plural, =0 {no photos.} =1 {one photo.} other {# photos.}}',
|
||||
photos:
|
||||
'You have {n, plural, =0 {no photos.} =1 {one photo.} other {# photos.}}',
|
||||
cats: 'I have {n, number} {n,plural,one{cat}other{cats}}',
|
||||
},
|
||||
})
|
||||
|
@ -23,47 +23,77 @@ export function getLocalesFrom(locale: string) {
|
||||
return locale.split('-').map((_, i, arr) => arr.slice(0, i + 1).join('-'))
|
||||
}
|
||||
|
||||
const getFromURL = (urlPart: string, key: string) => {
|
||||
const keyVal = urlPart
|
||||
.substr(1)
|
||||
.split('&')
|
||||
.find(i => i.indexOf(key) === 0)
|
||||
|
||||
if (keyVal) {
|
||||
return keyVal.split('=').pop()
|
||||
}
|
||||
}
|
||||
|
||||
const getMatch = (base: string, pattern: RegExp) => {
|
||||
const match = pattern.exec(base)
|
||||
if (!match) return null
|
||||
return match[1] || null
|
||||
}
|
||||
|
||||
// todo add a urlPattern method/regexp
|
||||
export const getClientLocale = ({
|
||||
navigator,
|
||||
hash,
|
||||
search,
|
||||
pathname,
|
||||
hostname,
|
||||
default: defaultLocale,
|
||||
}: {
|
||||
navigator?: boolean
|
||||
hash?: string
|
||||
search?: string
|
||||
hash?: string | RegExp
|
||||
search?: string | RegExp
|
||||
fallback?: string
|
||||
default?: string
|
||||
pathname?: RegExp
|
||||
hostname?: RegExp
|
||||
}) => {
|
||||
let locale
|
||||
|
||||
const getFromURL = (urlPart: string, key: string) => {
|
||||
const keyVal = urlPart
|
||||
.substr(1)
|
||||
.split('&')
|
||||
.find(i => i.indexOf(key) === 0)
|
||||
|
||||
if (keyVal) {
|
||||
return keyVal.split('=').pop()
|
||||
}
|
||||
if (typeof window === 'undefined') {
|
||||
return defaultLocale
|
||||
}
|
||||
|
||||
// istanbul ignore else
|
||||
if (typeof window !== 'undefined') {
|
||||
if (navigator) {
|
||||
// istanbul ignore next
|
||||
locale = window.navigator.language || window.navigator.languages[0]
|
||||
}
|
||||
|
||||
if (search && !locale) {
|
||||
locale = getFromURL(window.location.search, search)
|
||||
}
|
||||
|
||||
if (hash && !locale) {
|
||||
locale = getFromURL(window.location.hash, hash)
|
||||
}
|
||||
if (hostname) {
|
||||
locale = getMatch(window.location.hostname, hostname)
|
||||
if (locale) return locale
|
||||
}
|
||||
|
||||
return locale || defaultLocale
|
||||
if (pathname) {
|
||||
locale = getMatch(window.location.pathname, pathname)
|
||||
if (locale) return locale
|
||||
}
|
||||
|
||||
if (navigator) {
|
||||
// istanbul ignore else
|
||||
locale = window.navigator.language || window.navigator.languages[0]
|
||||
if (locale) return locale
|
||||
}
|
||||
|
||||
if (search) {
|
||||
locale =
|
||||
typeof search === 'string'
|
||||
? getFromURL(window.location.search, search)
|
||||
: getMatch(window.location.search, search)
|
||||
if (locale) return locale
|
||||
}
|
||||
|
||||
if (hash) {
|
||||
locale =
|
||||
typeof hash === 'string'
|
||||
? getFromURL(window.location.hash, hash)
|
||||
: getMatch(window.location.hash, hash)
|
||||
if (locale) return locale
|
||||
}
|
||||
|
||||
return defaultLocale
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ describe('utilities', () => {
|
||||
beforeEach(() => {
|
||||
delete window.location
|
||||
window.location = {
|
||||
pathname: '/',
|
||||
hostname: 'example.com',
|
||||
hash: '',
|
||||
search: '',
|
||||
} as any
|
||||
@ -120,13 +122,11 @@ describe('utilities', () => {
|
||||
|
||||
it('should get the locale based on the passed hash parameter', () => {
|
||||
window.location.hash = '#locale=en-US&lang=pt-BR'
|
||||
expect(getClientLocale({ hash: 'locale' })).toBe('en-US')
|
||||
expect(getClientLocale({ hash: 'lang' })).toBe('pt-BR')
|
||||
})
|
||||
|
||||
it('should get the locale based on the passed search parameter', () => {
|
||||
window.location.search = '?locale=en-US&lang=pt-BR'
|
||||
expect(getClientLocale({ search: 'locale' })).toBe('en-US')
|
||||
expect(getClientLocale({ search: 'lang' })).toBe('pt-BR')
|
||||
})
|
||||
|
||||
@ -136,9 +136,18 @@ describe('utilities', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should get the default locale', () => {
|
||||
expect(getClientLocale({ default: 'pt' })).toBe('pt')
|
||||
})
|
||||
|
||||
it('should get the fallback locale', () => {
|
||||
expect(getClientLocale({ navigator: false, default: 'pt' })).toBe('pt')
|
||||
expect(getClientLocale({ hash: 'locale', default: 'pt' })).toBe('pt')
|
||||
window.location.pathname = '/en-US/foo/'
|
||||
expect(getClientLocale({ pathname: /^\/(.*?)\// })).toBe('en-US')
|
||||
})
|
||||
|
||||
it('should get the fallback locale', () => {
|
||||
window.location.hostname = 'pt.example.com'
|
||||
expect(getClientLocale({ hostname: /^.*?\./ })).toBe('pt')
|
||||
})
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user