Add german and traditional chinese

This commit is contained in:
the1812 2019-03-27 17:25:19 +08:00
parent 5046d02d91
commit f8eff2afeb
13 changed files with 220 additions and 139 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -359,6 +359,7 @@ function loadResources()
{ {
const resource = new Resource(data.path, data.styles); const resource = new Resource(data.path, data.styles);
resource.key = key; resource.key = key;
resource.dropdown = data.dropdown;
if (data.displayNames) if (data.displayNames)
{ {
resource.displayName = data.displayNames[key]; resource.displayName = data.displayNames[key];
@ -1545,6 +1546,12 @@ Resource.manifest = {
i18nJapanese: { i18nJapanese: {
path: "i18n.ja-JP.min.js", path: "i18n.ja-JP.min.js",
}, },
i18nTraditionalChinese: {
path: "i18n.zh-TW.min.js",
},
i18nGerman: {
path: "i18n.de-DE.min.js",
},
i18n: { i18n: {
path: "i18n.min.js", path: "i18n.min.js",
style: "important", style: "important",
@ -1886,6 +1893,7 @@ class ResourceManager
} }
} }
await Promise.all(Object.values(Resource.manifest) await Promise.all(Object.values(Resource.manifest)
.concat(Object.values(Resource.all))
.filter(it => it.dropdown) .filter(it => it.dropdown)
.map(it => applyDropdownOption(it.dropdown)) .map(it => applyDropdownOption(it.dropdown))
); );

View File

@ -359,6 +359,7 @@ function loadResources()
{ {
const resource = new Resource(data.path, data.styles); const resource = new Resource(data.path, data.styles);
resource.key = key; resource.key = key;
resource.dropdown = data.dropdown;
if (data.displayNames) if (data.displayNames)
{ {
resource.displayName = data.displayNames[key]; resource.displayName = data.displayNames[key];
@ -1545,6 +1546,12 @@ Resource.manifest = {
i18nJapanese: { i18nJapanese: {
path: "i18n.ja-JP.min.js", path: "i18n.ja-JP.min.js",
}, },
i18nTraditionalChinese: {
path: "i18n.zh-TW.min.js",
},
i18nGerman: {
path: "i18n.de-DE.min.js",
},
i18n: { i18n: {
path: "i18n.min.js", path: "i18n.min.js",
style: "important", style: "important",
@ -1886,6 +1893,7 @@ class ResourceManager
} }
} }
await Promise.all(Object.values(Resource.manifest) await Promise.all(Object.values(Resource.manifest)
.concat(Object.values(Resource.all))
.filter(it => it.dropdown) .filter(it => it.dropdown)
.map(it => applyDropdownOption(it.dropdown)) .map(it => applyDropdownOption(it.dropdown))
); );

View File

@ -11,6 +11,7 @@ export function loadResources()
{ {
const resource = new Resource(data.path, data.styles); const resource = new Resource(data.path, data.styles);
resource.key = key; resource.key = key;
resource.dropdown = data.dropdown;
if (data.displayNames) if (data.displayNames)
{ {
resource.displayName = data.displayNames[key]; resource.displayName = data.displayNames[key];

View File

@ -250,6 +250,7 @@ export class ResourceManager
} }
} }
await Promise.all(Object.values(Resource.manifest) await Promise.all(Object.values(Resource.manifest)
.concat(Object.values(Resource.all))
.filter(it => it.dropdown) .filter(it => it.dropdown)
.map(it => applyDropdownOption(it.dropdown)) .map(it => applyDropdownOption(it.dropdown))
); );

View File

@ -493,6 +493,12 @@ Resource.manifest = {
i18nJapanese: { i18nJapanese: {
path: "i18n.ja-JP.min.js", path: "i18n.ja-JP.min.js",
}, },
i18nTraditionalChinese: {
path: "i18n.zh-TW.min.js",
},
i18nGerman: {
path: "i18n.de-DE.min.js",
},
i18n: { i18n: {
path: "i18n.min.js", path: "i18n.min.js",
style: "important", style: "important",

1
min/i18n.de-DE.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(r,e)=>{const n=new Map([[`*`,[]]]);return{export:{map:n}}}})();

2
min/i18n.min.js vendored
View File

@ -1 +1 @@
(()=>{return(e,t)=>{(async()=>{const s={"日本語":"ja-JP",English:"en-US"};const{map:a}=await t.importAsync(`i18n.${s[e.i18nLanguage]}`);class n{accepts(e){return e.nodeType===Node.ELEMENT_NODE}getValue(e){return e.nodeValue}setValue(e,t){e.nodeValue=t}getElement(e){return e}translate(e){const t=this.getValue(e);if(!t||typeof t!=="string"){return}const s=a.get(t.trim());if(s===undefined){return}if(typeof s==="string"){this.setValue(e,s)}else if(Array.isArray(s)){let t=null;for(const a of s){if(typeof a==="string"){t=a}else{const{text:s,selector:n}=a;if(this.getElement(e).matches(n)){t=s}}}if(t!==null){this.setValue(e,t)}}else{const{text:t,selector:a}=s;if(this.getElement(e).matches(a)){this.setValue(e,t)}}}static walk(e,t){const s=document.createTreeWalker(e,NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT,null,false);let a=s.nextNode();while(a){t(a);a=s.nextNode()}}static translate(e){if(e.nodeType===Node.TEXT_NODE){n.textNode.translate(e);return}n.walk(e,e=>{for(const t of n.allTranslators){if(t.accepts(e)){t.translate(e)}}})}static translateCssMatches(){const e=a.get("*");if(!e){return}for(const{selector:t,text:s}of e){const e=document.querySelector(t);if(e){[...e.childNodes].filter(e=>e.nodeType===Node.TEXT_NODE).forEach(e=>e.nodeValue=s)}}}}class r extends n{accepts(e){return e.nodeType===Node.TEXT_NODE}getElement(e){return e.parentElement}}class l extends n{getValue(e){return e.getAttribute("title")}setValue(e,t){e.setAttribute("title",t)}}class o extends n{accepts(e){return e.nodeName==="INPUT"&&e.type.toUpperCase()==="TEXT"||e.nodeName==="TEXTAREA"}getValue(e){return e.getAttribute("placeholder")}setValue(e,t){e.setAttribute("placeholder",t)}}n.textNode=new r;n.title=new l;n.placeholder=new o;n.allTranslators=[n.textNode,n.title,n.placeholder];n.translate(document.body);n.translateCssMatches();Observer.childListSubtree("body",e=>{e.forEach(e=>{if(e.addedNodes.length>0){n.translateCssMatches()}e.addedNodes.forEach(e=>{n.translate(e)})})})})()}})(); (()=>{return(e,t)=>{const s={"日本語":"ja-JP",English:"en-US","正體中文":"zh-TW",Deutsch:"de-DE"};class a{accepts(e){return e.nodeType===Node.ELEMENT_NODE}getValue(e){return e.nodeValue}setValue(e,t){e.nodeValue=t}getElement(e){return e}translate(e){const t=this.getValue(e);if(!t||typeof t!=="string"){return}const s=map.get(t.trim());if(s===undefined){return}if(typeof s==="string"){this.setValue(e,s)}else if(Array.isArray(s)){let t=null;for(const a of s){if(typeof a==="string"){t=a}else{const{text:s,selector:r}=a;if(this.getElement(e).matches(r)){t=s}}}if(t!==null){this.setValue(e,t)}}else{const{text:t,selector:a}=s;if(this.getElement(e).matches(a)){this.setValue(e,t)}}}static walk(e,t){const s=document.createTreeWalker(e,NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT,null,false);let a=s.nextNode();while(a){t(a);a=s.nextNode()}}static translate(e){if(e.nodeType===Node.TEXT_NODE){a.textNode.translate(e);return}a.walk(e,e=>{for(const t of a.allTranslators){if(t.accepts(e)){t.translate(e)}}})}static translateCssMatches(){const e=map.get("*");if(!e){return}for(const{selector:t,text:s}of e){const e=document.querySelector(t);if(e){[...e.childNodes].filter(e=>e.nodeType===Node.TEXT_NODE).forEach(e=>e.nodeValue=s)}}}}class r extends a{accepts(e){return e.nodeType===Node.TEXT_NODE}getElement(e){return e.parentElement}}class l extends a{getValue(e){return e.getAttribute("title")}setValue(e,t){e.setAttribute("title",t)}}class n extends a{accepts(e){return e.nodeName==="INPUT"&&e.type.toUpperCase()==="TEXT"||e.nodeName==="TEXTAREA"}getValue(e){return e.getAttribute("placeholder")}setValue(e,t){e.setAttribute("placeholder",t)}}a.textNode=new r;a.title=new l;a.placeholder=new n;a.allTranslators=[a.textNode,a.title,a.placeholder];(async()=>{const{map:r}=await t.importAsync(`i18n.${s[e.i18nLanguage]}`);a.translate(document.body);a.translateCssMatches();Observer.childListSubtree("body",e=>{e.forEach(e=>{if(e.addedNodes.length>0){a.translateCssMatches()}e.addedNodes.forEach(e=>{a.translate(e)})})})})();return{export:{Translator:a,TextNodeTranslator:r,TitleTranslator:l,PlaceholderTranslator:n}}}})();

1
min/i18n.zh-TW.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(r,e)=>{const n=new Map([[`*`,[]]]);return{export:{map:n}}}})();

9
utils/i18n/i18n.de-DE.js Normal file
View File

@ -0,0 +1,9 @@
export const map = new Map([
/* Your translation here */
[`*`, [
/* CSS translation here */
]],
]);
export default {
export: { map },
};

View File

@ -1,12 +1,11 @@
(async () => const languageCodeMap = {
{
const languageCodeMap = {
"日本語": "ja-JP", "日本語": "ja-JP",
"English": "en-US", "English": "en-US",
}; "正體中文": "zh-TW",
const { map } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`); "Deutsch": "de-DE",
class Translator };
{ export class Translator
{
accepts(node) { return node.nodeType === Node.ELEMENT_NODE; } accepts(node) { return node.nodeType === Node.ELEMENT_NODE; }
getValue(node) { return node.nodeValue; } getValue(node) { return node.nodeValue; }
setValue(node, value) { node.nodeValue = value; } setValue(node, value) { node.nodeValue = value; }
@ -104,36 +103,41 @@
} }
} }
} }
} }
class TextNodeTranslator extends Translator export class TextNodeTranslator extends Translator
{ {
accepts(node) { return node.nodeType === Node.TEXT_NODE; } accepts(node) { return node.nodeType === Node.TEXT_NODE; }
getElement(node) getElement(node)
{ {
return node.parentElement; return node.parentElement;
} }
} }
class TitleTranslator extends Translator export class TitleTranslator extends Translator
{ {
getValue(node) { return node.getAttribute("title"); } getValue(node) { return node.getAttribute("title"); }
setValue(node, value) setValue(node, value)
{ {
node.setAttribute("title", value); node.setAttribute("title", value);
} }
} }
class PlaceholderTranslator extends Translator export class PlaceholderTranslator extends Translator
{ {
accepts(node) { return node.nodeName === "INPUT" && node.type.toUpperCase() === "TEXT" || node.nodeName === "TEXTAREA"; } accepts(node) { return node.nodeName === "INPUT" && node.type.toUpperCase() === "TEXT" || node.nodeName === "TEXTAREA"; }
getValue(node) { return node.getAttribute("placeholder"); } getValue(node) { return node.getAttribute("placeholder"); }
setValue(node, value) setValue(node, value)
{ {
node.setAttribute("placeholder", value); node.setAttribute("placeholder", value);
} }
} }
Translator.textNode = new TextNodeTranslator;
Translator.title = new TitleTranslator; Translator.textNode = new TextNodeTranslator;
Translator.placeholder = new PlaceholderTranslator; Translator.title = new TitleTranslator;
Translator.allTranslators = [Translator.textNode, Translator.title, Translator.placeholder]; Translator.placeholder = new PlaceholderTranslator;
Translator.allTranslators = [Translator.textNode, Translator.title, Translator.placeholder];
(async () =>
{
const { map } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
Translator.translate(document.body); Translator.translate(document.body);
Translator.translateCssMatches(); Translator.translateCssMatches();
@ -152,3 +156,16 @@
}); });
}); });
})(); })();
export default {
export: {
Translator,
TextNodeTranslator,
TitleTranslator,
PlaceholderTranslator,
},
// dropdown: {
// key: "i18nLanguage",
// items: Object.keys(languageCodeMap),
// },
};

9
utils/i18n/i18n.zh-TW.js Normal file
View File

@ -0,0 +1,9 @@
export const map = new Map([
/* Your translation here */
[`*`, [
/* CSS translation here */
]],
]);
export default {
export: { map },
};