mirror of
https://github.com/cupcakearmy/svelte-i18n.git
synced 2024-06-30 18:54:49 +02: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'
|
// set the key name to look for a locale on 'window.location.hash'
|
||||||
// 'example.com#locale=en-US'
|
// 'example.com#locale=en-US'
|
||||||
hash: 'locale',
|
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',
|
ask: 'Por favor, digite seu nome',
|
||||||
message: 'Olá {name}, como vai?',
|
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}}',
|
cats: 'Tenho {n, number} {n,plural,=0{gatos}one{gato}other{gatos}}',
|
||||||
},
|
},
|
||||||
en: {
|
en: {
|
||||||
|
@ -92,7 +97,8 @@ dictionary.set({
|
||||||
ask: 'Please type your name',
|
ask: 'Please type your name',
|
||||||
message: 'Hello {name}, how are you?',
|
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}}',
|
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('-'))
|
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
|
// todo add a urlPattern method/regexp
|
||||||
export const getClientLocale = ({
|
export const getClientLocale = ({
|
||||||
navigator,
|
navigator,
|
||||||
hash,
|
hash,
|
||||||
search,
|
search,
|
||||||
|
pathname,
|
||||||
|
hostname,
|
||||||
default: defaultLocale,
|
default: defaultLocale,
|
||||||
}: {
|
}: {
|
||||||
navigator?: boolean
|
navigator?: boolean
|
||||||
hash?: string
|
hash?: string | RegExp
|
||||||
search?: string
|
search?: string | RegExp
|
||||||
fallback?: string
|
fallback?: string
|
||||||
default?: string
|
default?: string
|
||||||
|
pathname?: RegExp
|
||||||
|
hostname?: RegExp
|
||||||
}) => {
|
}) => {
|
||||||
let locale
|
let locale
|
||||||
|
|
||||||
const getFromURL = (urlPart: string, key: string) => {
|
if (typeof window === 'undefined') {
|
||||||
const keyVal = urlPart
|
return defaultLocale
|
||||||
.substr(1)
|
|
||||||
.split('&')
|
|
||||||
.find(i => i.indexOf(key) === 0)
|
|
||||||
|
|
||||||
if (keyVal) {
|
|
||||||
return keyVal.split('=').pop()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// istanbul ignore else
|
if (hostname) {
|
||||||
if (typeof window !== 'undefined') {
|
locale = getMatch(window.location.hostname, hostname)
|
||||||
if (navigator) {
|
if (locale) return locale
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(() => {
|
beforeEach(() => {
|
||||||
delete window.location
|
delete window.location
|
||||||
window.location = {
|
window.location = {
|
||||||
|
pathname: '/',
|
||||||
|
hostname: 'example.com',
|
||||||
hash: '',
|
hash: '',
|
||||||
search: '',
|
search: '',
|
||||||
} as any
|
} as any
|
||||||
|
@ -120,13 +122,11 @@ describe('utilities', () => {
|
||||||
|
|
||||||
it('should get the locale based on the passed hash parameter', () => {
|
it('should get the locale based on the passed hash parameter', () => {
|
||||||
window.location.hash = '#locale=en-US&lang=pt-BR'
|
window.location.hash = '#locale=en-US&lang=pt-BR'
|
||||||
expect(getClientLocale({ hash: 'locale' })).toBe('en-US')
|
|
||||||
expect(getClientLocale({ hash: 'lang' })).toBe('pt-BR')
|
expect(getClientLocale({ hash: 'lang' })).toBe('pt-BR')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get the locale based on the passed search parameter', () => {
|
it('should get the locale based on the passed search parameter', () => {
|
||||||
window.location.search = '?locale=en-US&lang=pt-BR'
|
window.location.search = '?locale=en-US&lang=pt-BR'
|
||||||
expect(getClientLocale({ search: 'locale' })).toBe('en-US')
|
|
||||||
expect(getClientLocale({ search: 'lang' })).toBe('pt-BR')
|
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', () => {
|
it('should get the fallback locale', () => {
|
||||||
expect(getClientLocale({ navigator: false, default: 'pt' })).toBe('pt')
|
window.location.pathname = '/en-US/foo/'
|
||||||
expect(getClientLocale({ hash: 'locale', default: 'pt' })).toBe('pt')
|
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