const osLocale = require ( "os-locale" ) ;
const fs = require ( "fs" ) ;
const path = require ( "path" ) ;
let cache = {
defaultLocale : "en" ,
availableLocales : [ ] ,
canonicalLocales : [ ] ,
locales : [ ]
} ;
let i18n = { } ;
i18n . _ _ = function ( name ) {
i18n . getLocale ( ) ;
let string = i18n . getLocaleData ( cache . locale ) [ name ] || i18n . getLocaleData ( cache . defaultLocale ) [ name ] ;
if ( ! string ) {
let underscoreIndex = cache . locale . indexOf ( "-" ) ;
if ( underscoreIndex !== - 1 ) {
let localeBaseCode = cache . locale . substring ( 0 , underscoreIndex ) ;
if ( i18n . localeExists ( localeBaseCode ) ) {
string = i18n . getLocaleData ( localeBaseCode ) [ name ] ;
}
}
}
if ( string ) {
if ( arguments . length === 1 ) {
return string ;
} else {
for ( let i = 0 , l = arguments . length - 1 ; i < l ; i ++ ) {
string = string . replace ( "$" + i , arguments [ 1 + i ] ) ;
}
return string ;
}
} else {
console . warn ( ` String " ${ name } " does not exist. ` )
}
} ;
i18n . localeExists = function ( locale ) {
return i18n . getAvailableLocales ( ) . indexOf ( locale ) !== - 1 ;
} ;
i18n . getLocaleData = function ( locale ) {
if ( ! cache . locales [ locale ] ) {
cache . locales [ locale ] = i18n . readLocaleFile ( locale ) ;
}
return cache . locales [ locale ] ;
} ;
i18n . readLocaleFile = function ( locale ) {
let localeData = JSON . parse ( fs . readFileSync (
path . join ( _ _dirname , ".." , "locales" , locale + ".json" ) ,
{ encoding : "utf8" }
) ) ;
if ( localeData . _ _redirect _ _ ) {
let redirectedLocaleData = JSON . parse ( fs . readFileSync (
path . join ( _ _dirname , ".." , "locales" , localeData . _ _redirect _ _ + ".json" ) ,
{ encoding : "utf8" }
) ) ;
redirectedLocaleData . _ _is _redirected _ _ = true ;
redirectedLocaleData . _ _canonical _ _ = localeData . _ _redirect _ _ ;
return redirectedLocaleData ;
} else {
return localeData ;
}
} ;
i18n . doDOMReplacement = function ( ) {
let elems0 = document . getElementsByClassName ( "i18n" ) ;
for ( let i = 0 , l = elems0 . length ; i < l ; i ++ ) {
elems0 [ i ] . innerHTML = i18n . _ _ ( elems0 [ i ] . dataset . i18nName ) ;
}
let elems1 = document . getElementsByClassName ( "i18n-attr" ) ;
for ( let i = 0 , l = elems1 . length ; i < l ; i ++ ) {
let mappings = elems1 [ i ] . dataset . i18nMap . split ( ";" ) ;
for ( let j = 0 , m = mappings . length ; j < m ; j ++ ) {
let keyVal = mappings [ j ] . split ( ":" ) ;
elems1 [ i ] . setAttribute ( keyVal [ 0 ] , i18n . _ _ ( keyVal [ 1 ] ) ) ;
}
}
} ;
i18n . setLocale = function ( locale ) {
if ( i18n . localeExists ( locale ) ) {
cache . locale = locale ;
return true ;
}
return false ;
} ;
i18n . getLocale = function ( ) {
if ( ! cache . locale ) {
let systemLocale = osLocale . sync ( ) ;
let availableLocales = i18n . getAvailableLocales ( ) ;
if ( availableLocales . indexOf ( systemLocale ) !== - 1 ) {
cache . locale = systemLocale ;
} else if ( availableLocales . indexOf ( systemLocale . split ( "-" ) [ 0 ] ) !== - 1 ) {
cache . locale = systemLocale . split ( "-" ) [ 0 ] ;
} else {
var looseLocaleMatch ;
for ( let i = 0 , l = availableLocales . length ; i < l ; i ++ ) {
if ( availableLocales [ i ] . split ( "-" ) [ 0 ] === systemLocale . split ( "-" ) [ 0 ] ) {
looseLocaleMatch = availableLocales [ i ] ;
break ;
}
}
if ( looseLocaleMatch ) {
cache . locale = looseLocaleMatch ;
} else {
cache . locale = cache . defaultLocale ;
}
}
}
return cache . locale ;
} ;
i18n . getCanonicalLocale = function ( ) {
i18n . getLocale ( ) ;
if ( ! cache . locales [ cache . locale ] ) {
cache . locales [ cache . locale ] = i18n . readLocaleFile ( cache . locale ) ;
}
if ( cache . locales [ cache . locale ] . _ _canonical _ _ ) {
return cache . locales [ cache . locale ] . _ _canonical _ _ ;
} else {
return cache . locale ;
}
} ;
i18n . getAvailableLocales = function ( canonicalOnly ) {
if ( ! cache . availableLocales . length ) {
let filenames = fs . readdirSync ( path . join ( _ _dirname , ".." , "locales" ) ) ;
for ( let i = 0 , l = filenames . length ; i < l ; i ++ ) {
cache . availableLocales . push ( filenames [ i ] . split ( "." ) [ 0 ] ) ;
}
}
if ( canonicalOnly ) {
return i18n . getCanonicalLocales ( ) ;
} else {
return cache . availableLocales ;
}
} ;
i18n . getCanonicalLocales = function ( ) {
i18n . getAvailableLocales ( ) ;
if ( ! cache . canonicalLocales . length ) {
for ( let i = 0 , l = cache . availableLocales . length ; i < l ; i ++ ) {
if ( ! i18n . readLocaleFile ( cache . availableLocales [ i ] ) . hasOwnProperty ( "__is_redirected__" ) ) {
cache . canonicalLocales . push ( cache . availableLocales [ i ] ) ;
}
}
}
return cache . canonicalLocales ;
} ;
i18n . getDefaultLocale = function ( ) {
return cache . defaultLocale ;
} ;
module . exports = i18n ;