Merge pull request #130 in YR/star-web-components from l10n to master
* commit '722062d545e8435e63b028727e7c22ff223c9f17': TASK: #103629 - (star-web-elements) 添加国际化帮助类 TASK: #103629 - 组件增添国际化功能
This commit is contained in:
commit
8b0e43bfc2
|
@ -0,0 +1,179 @@
|
|||
import {StarBaseElement} from './star-base-element'
|
||||
|
||||
interface PropertiesParser {
|
||||
patterns: {[type: string]: RegExp}
|
||||
entryIds: object
|
||||
init: () => void
|
||||
parse: (ctx: any, source: string) => any[]
|
||||
parseEntity: (id: string, value: string, ast: string[]) => void
|
||||
setEntityValue: (
|
||||
id: string,
|
||||
attr: string,
|
||||
key: string,
|
||||
rawValue: string,
|
||||
ast: any[]
|
||||
) => any
|
||||
parseString: (str: string) => any[]
|
||||
unescapeString: (str: string) => string
|
||||
parseIndex: (str: string) => (string | {t: string; v: string})[]
|
||||
}
|
||||
|
||||
class L10nHelper {
|
||||
/* 开启了国际化功能的组件 */
|
||||
updateArray: Set<StarBaseElement> = new Set()
|
||||
// TODO: fluent.js 替换完后更改此处
|
||||
l10n: any
|
||||
/* 国际化资源转化器 */
|
||||
PropertiesParser?: PropertiesParser
|
||||
suspending: Function[] = []
|
||||
constructor() {
|
||||
this.init()
|
||||
}
|
||||
|
||||
init = (): void => {
|
||||
// @ts-ignore
|
||||
const l10n = navigator.mozL10n
|
||||
if (!l10n) {
|
||||
return document.addEventListener('readystatechange', this.init, {
|
||||
once: true,
|
||||
})
|
||||
}
|
||||
this.l10n = l10n
|
||||
|
||||
/* 变更语言时, 刷新组件 */
|
||||
window.addEventListener('languagechange', () => {
|
||||
this.updateArray.forEach((element) => element.requestUpdate())
|
||||
})
|
||||
|
||||
if (this.suspending.length) {
|
||||
this.suspending.forEach((fun) => fun())
|
||||
}
|
||||
|
||||
this.loadAllLocales()
|
||||
}
|
||||
|
||||
/* 空闲时加载所有国际化资源, 防止语言切换时闪烁 */
|
||||
loadAllLocales = () => {
|
||||
requestIdleCallback(() => {
|
||||
const availableLocales: string[] = this.l10n.ctx.availableLocales
|
||||
const shouldRequest: string[] = []
|
||||
availableLocales.forEach((lang) => {
|
||||
const locale = this.l10n.ctx.getLocale(lang)
|
||||
if (!locale.isReady) {
|
||||
shouldRequest.push(lang)
|
||||
}
|
||||
})
|
||||
|
||||
shouldRequest.length && this.l10n.ctx.requestLocales(...shouldRequest)
|
||||
})
|
||||
}
|
||||
|
||||
observe = (el: StarBaseElement) => {
|
||||
this.updateArray.add(el)
|
||||
}
|
||||
|
||||
unobserve = (el: StarBaseElement) => {
|
||||
this.updateArray.delete(el)
|
||||
}
|
||||
|
||||
/* 添加国际化资源 */
|
||||
addLocaleSrc = (json: {[lang: string]: {[l10nId: string]: string}}): void => {
|
||||
if (!this.l10n || !this.l10n.ctx.isReady) {
|
||||
this.suspending.push(this.addLocaleSrc.bind(this, json))
|
||||
return
|
||||
}
|
||||
this.initParser().then(() => {
|
||||
for (const language in json) {
|
||||
const context = json[language]
|
||||
const ast = this.parse(context)
|
||||
const locale = this.l10n.ctx.getLocale(language)
|
||||
locale.addAST(ast)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* 初始化转化器 */
|
||||
initParser = () => {
|
||||
if (this.l10n.ctx.isReady && this.PropertiesParser) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return new Promise((res) => {
|
||||
this.l10n.once(() => {
|
||||
this.PropertiesParser = this.l10n._getInternalAPI()
|
||||
.PropertiesParser as PropertiesParser
|
||||
this.PropertiesParser.init()
|
||||
res(void 0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
parse = (context: {[l10nId: string]: string}) => {
|
||||
let str = ''
|
||||
for (const key in context) {
|
||||
const value = context[key]
|
||||
str += `${key}=${value}\n`
|
||||
}
|
||||
|
||||
return this.PropertiesParser!.parse(null, str)
|
||||
}
|
||||
|
||||
get = (id: string, ctxdata: any) => {
|
||||
let result = ''
|
||||
|
||||
if (this.l10n) {
|
||||
if (this.l10n.ctx.isReady) {
|
||||
// 如果L10n已经准备好, 则获取对应国际化结果
|
||||
if (this.l10n.ctx.getLocale(navigator.language).isReady) {
|
||||
result = this.l10n.get(id, ctxdata)
|
||||
if (!result) {
|
||||
console.warn(
|
||||
'l10n get nothing by id:',
|
||||
id,
|
||||
'; and ctxdata:',
|
||||
ctxdata
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// 相应的国际化资源未准备完成, 待完成后重新刷新
|
||||
this.openLocaleListener()
|
||||
}
|
||||
} else {
|
||||
// L10n还没有准备好, 等待L10n准备完毕后, 刷新小组件
|
||||
this.openL10nReadyListener()
|
||||
}
|
||||
} else {
|
||||
console.warn('l10n is not exist!')
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/* 等待国际化资源加载, 添加加载成功的事件监听 */
|
||||
_localeListening: boolean = false
|
||||
openLocaleListener = () => {
|
||||
if (!this._localeListening) {
|
||||
this._localeListening = true
|
||||
const cb = () => {
|
||||
this.updateArray.forEach((el) => el.requestUpdate())
|
||||
this.l10n.ctx.removeEventListener('request-locales-done', cb)
|
||||
this._localeListening = false
|
||||
}
|
||||
this.l10n.ctx.addEventListener('request-locales-done', cb)
|
||||
}
|
||||
}
|
||||
|
||||
/* 等待L10n准备完毕, 添加准备完毕的事件监听 */
|
||||
_readyListening: boolean = false
|
||||
openL10nReadyListener = () => {
|
||||
if (!this._readyListening) {
|
||||
this._readyListening = true
|
||||
this.l10n.once(() => {
|
||||
this.updateArray.forEach((el) => el.requestUpdate())
|
||||
this._readyListening = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const l10nHelper = new L10nHelper()
|
|
@ -5,6 +5,7 @@ import GestureDetector, {
|
|||
} from '../../lib/gesture/gesture-detector'
|
||||
import {autoPxStyle} from './auto-px-style'
|
||||
import {globalStyles} from './global-style'
|
||||
import {l10nHelper} from './custome_element_l10n'
|
||||
|
||||
declare global {
|
||||
var loadStarMixin: boolean
|
||||
|
@ -113,6 +114,16 @@ export type StarElementEventMap = HTMLElementEventMap & GestureEvents
|
|||
export class StarBaseElement extends StarMixin(LitElement) {
|
||||
gestureDetector!: GestureDetector
|
||||
|
||||
disconnectedCallback(): void {
|
||||
super.disconnectedCallback()
|
||||
this._l10n && l10nHelper.observe(this)
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback()
|
||||
this._l10n && l10nHelper.unobserve(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动手势监听框架
|
||||
*/
|
||||
|
@ -126,6 +137,35 @@ export class StarBaseElement extends StarMixin(LitElement) {
|
|||
GestureDetector.disembedded(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态添加国际化资源
|
||||
*/
|
||||
addLocaleSrc(json: {[lang: string]: {[l10nId: string]: string}}): void {
|
||||
l10nHelper.addLocaleSrc(json)
|
||||
}
|
||||
|
||||
/* 该组件是否启用了国际化功能, 用于判断是否因系统语言变化而刷新 */
|
||||
_languageChangeObserve: boolean = false
|
||||
get _l10n() {
|
||||
return this._languageChangeObserve
|
||||
}
|
||||
|
||||
set _l10n(value) {
|
||||
if (value) {
|
||||
if (!this._languageChangeObserve) {
|
||||
l10nHelper.observe(this)
|
||||
}
|
||||
} else {
|
||||
l10nHelper.unobserve(this)
|
||||
}
|
||||
this._languageChangeObserve = value
|
||||
}
|
||||
/* 根据 id 和传值 ctxdata 获取国际化结果 */
|
||||
$l = (id: string, ctxdata?: string) => {
|
||||
this._l10n = true
|
||||
return l10nHelper.get(id, ctxdata)
|
||||
}
|
||||
|
||||
public static get styles(): CSSResultArray {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -4,5 +4,9 @@
|
|||
"composite": true,
|
||||
"rootDir": "../../"
|
||||
},
|
||||
"include": ["*.ts", "../../lib/gesture/gesture-detector.ts"]
|
||||
"include": [
|
||||
"*.ts",
|
||||
"../../lib/gesture/gesture-detector.ts",
|
||||
"../../../../typings/"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue