mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Add german and traditional chinese
This commit is contained in:
parent
5046d02d91
commit
f8eff2afeb
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -359,6 +359,7 @@ function loadResources()
|
||||
{
|
||||
const resource = new Resource(data.path, data.styles);
|
||||
resource.key = key;
|
||||
resource.dropdown = data.dropdown;
|
||||
if (data.displayNames)
|
||||
{
|
||||
resource.displayName = data.displayNames[key];
|
||||
@ -1545,6 +1546,12 @@ Resource.manifest = {
|
||||
i18nJapanese: {
|
||||
path: "i18n.ja-JP.min.js",
|
||||
},
|
||||
i18nTraditionalChinese: {
|
||||
path: "i18n.zh-TW.min.js",
|
||||
},
|
||||
i18nGerman: {
|
||||
path: "i18n.de-DE.min.js",
|
||||
},
|
||||
i18n: {
|
||||
path: "i18n.min.js",
|
||||
style: "important",
|
||||
@ -1886,6 +1893,7 @@ class ResourceManager
|
||||
}
|
||||
}
|
||||
await Promise.all(Object.values(Resource.manifest)
|
||||
.concat(Object.values(Resource.all))
|
||||
.filter(it => it.dropdown)
|
||||
.map(it => applyDropdownOption(it.dropdown))
|
||||
);
|
||||
|
||||
@ -359,6 +359,7 @@ function loadResources()
|
||||
{
|
||||
const resource = new Resource(data.path, data.styles);
|
||||
resource.key = key;
|
||||
resource.dropdown = data.dropdown;
|
||||
if (data.displayNames)
|
||||
{
|
||||
resource.displayName = data.displayNames[key];
|
||||
@ -1545,6 +1546,12 @@ Resource.manifest = {
|
||||
i18nJapanese: {
|
||||
path: "i18n.ja-JP.min.js",
|
||||
},
|
||||
i18nTraditionalChinese: {
|
||||
path: "i18n.zh-TW.min.js",
|
||||
},
|
||||
i18nGerman: {
|
||||
path: "i18n.de-DE.min.js",
|
||||
},
|
||||
i18n: {
|
||||
path: "i18n.min.js",
|
||||
style: "important",
|
||||
@ -1886,6 +1893,7 @@ class ResourceManager
|
||||
}
|
||||
}
|
||||
await Promise.all(Object.values(Resource.manifest)
|
||||
.concat(Object.values(Resource.all))
|
||||
.filter(it => it.dropdown)
|
||||
.map(it => applyDropdownOption(it.dropdown))
|
||||
);
|
||||
|
||||
@ -11,6 +11,7 @@ export function loadResources()
|
||||
{
|
||||
const resource = new Resource(data.path, data.styles);
|
||||
resource.key = key;
|
||||
resource.dropdown = data.dropdown;
|
||||
if (data.displayNames)
|
||||
{
|
||||
resource.displayName = data.displayNames[key];
|
||||
|
||||
@ -250,6 +250,7 @@ export class ResourceManager
|
||||
}
|
||||
}
|
||||
await Promise.all(Object.values(Resource.manifest)
|
||||
.concat(Object.values(Resource.all))
|
||||
.filter(it => it.dropdown)
|
||||
.map(it => applyDropdownOption(it.dropdown))
|
||||
);
|
||||
|
||||
@ -493,6 +493,12 @@ Resource.manifest = {
|
||||
i18nJapanese: {
|
||||
path: "i18n.ja-JP.min.js",
|
||||
},
|
||||
i18nTraditionalChinese: {
|
||||
path: "i18n.zh-TW.min.js",
|
||||
},
|
||||
i18nGerman: {
|
||||
path: "i18n.de-DE.min.js",
|
||||
},
|
||||
i18n: {
|
||||
path: "i18n.min.js",
|
||||
style: "important",
|
||||
|
||||
1
min/i18n.de-DE.min.js
vendored
Normal file
1
min/i18n.de-DE.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(()=>{return(r,e)=>{const n=new Map([[`*`,[]]]);return{export:{map:n}}}})();
|
||||
2
min/i18n.min.js
vendored
2
min/i18n.min.js
vendored
@ -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
1
min/i18n.zh-TW.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(()=>{return(r,e)=>{const n=new Map([[`*`,[]]]);return{export:{map:n}}}})();
|
||||
9
utils/i18n/i18n.de-DE.js
Normal file
9
utils/i18n/i18n.de-DE.js
Normal file
@ -0,0 +1,9 @@
|
||||
export const map = new Map([
|
||||
/* Your translation here */
|
||||
[`*`, [
|
||||
/* CSS translation here */
|
||||
]],
|
||||
]);
|
||||
export default {
|
||||
export: { map },
|
||||
};
|
||||
@ -1,139 +1,143 @@
|
||||
const languageCodeMap = {
|
||||
"日本語": "ja-JP",
|
||||
"English": "en-US",
|
||||
"正體中文": "zh-TW",
|
||||
"Deutsch": "de-DE",
|
||||
};
|
||||
export class Translator
|
||||
{
|
||||
accepts(node) { return node.nodeType === Node.ELEMENT_NODE; }
|
||||
getValue(node) { return node.nodeValue; }
|
||||
setValue(node, value) { node.nodeValue = value; }
|
||||
getElement(node) { return node; }
|
||||
translate(node)
|
||||
{
|
||||
const value = this.getValue(node);
|
||||
if (!value || typeof value !== "string")
|
||||
{
|
||||
return;
|
||||
}
|
||||
const translation = map.get(value.trim());
|
||||
if (translation === undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (typeof translation === "string")
|
||||
{
|
||||
this.setValue(node, translation);
|
||||
}
|
||||
else if (Array.isArray(translation))
|
||||
{
|
||||
let finalTranslation = null;
|
||||
for (const subTranslation of translation)
|
||||
{
|
||||
if (typeof subTranslation === "string")
|
||||
{
|
||||
finalTranslation = subTranslation;
|
||||
}
|
||||
else
|
||||
{
|
||||
const { text, selector } = subTranslation;
|
||||
if (this.getElement(node).matches(selector))
|
||||
{
|
||||
finalTranslation = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (finalTranslation !== null)
|
||||
{
|
||||
this.setValue(node, finalTranslation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const { text, selector } = translation;
|
||||
if (this.getElement(node).matches(selector))
|
||||
{
|
||||
this.setValue(node, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
// https://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page
|
||||
static walk(rootElement, action)
|
||||
{
|
||||
const walker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, null, false);
|
||||
let node = walker.nextNode();
|
||||
while (node)
|
||||
{
|
||||
action(node);
|
||||
node = walker.nextNode();
|
||||
}
|
||||
}
|
||||
static translate(rootElement)
|
||||
{
|
||||
if (rootElement.nodeType === Node.TEXT_NODE)
|
||||
{
|
||||
Translator.textNode.translate(rootElement);
|
||||
return;
|
||||
}
|
||||
Translator.walk(rootElement, node =>
|
||||
{
|
||||
for (const translator of Translator.allTranslators)
|
||||
{
|
||||
if (translator.accepts(node))
|
||||
{
|
||||
translator.translate(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
static translateCssMatches()
|
||||
{
|
||||
const selectors = map.get("*");
|
||||
if (!selectors)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (const { selector, text } of selectors)
|
||||
{
|
||||
const element = document.querySelector(selector);
|
||||
if (element)
|
||||
{
|
||||
[...element.childNodes].filter(it => it.nodeType === Node.TEXT_NODE).forEach(it => it.nodeValue = text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export class TextNodeTranslator extends Translator
|
||||
{
|
||||
accepts(node) { return node.nodeType === Node.TEXT_NODE; }
|
||||
getElement(node)
|
||||
{
|
||||
return node.parentElement;
|
||||
}
|
||||
}
|
||||
export class TitleTranslator extends Translator
|
||||
{
|
||||
getValue(node) { return node.getAttribute("title"); }
|
||||
setValue(node, value)
|
||||
{
|
||||
node.setAttribute("title", value);
|
||||
}
|
||||
}
|
||||
export class PlaceholderTranslator extends Translator
|
||||
{
|
||||
accepts(node) { return node.nodeName === "INPUT" && node.type.toUpperCase() === "TEXT" || node.nodeName === "TEXTAREA"; }
|
||||
getValue(node) { return node.getAttribute("placeholder"); }
|
||||
setValue(node, value)
|
||||
{
|
||||
node.setAttribute("placeholder", value);
|
||||
}
|
||||
}
|
||||
|
||||
Translator.textNode = new TextNodeTranslator;
|
||||
Translator.title = new TitleTranslator;
|
||||
Translator.placeholder = new PlaceholderTranslator;
|
||||
Translator.allTranslators = [Translator.textNode, Translator.title, Translator.placeholder];
|
||||
|
||||
(async () =>
|
||||
{
|
||||
const languageCodeMap = {
|
||||
"日本語": "ja-JP",
|
||||
"English": "en-US",
|
||||
};
|
||||
const { map } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
|
||||
class Translator
|
||||
{
|
||||
accepts(node) { return node.nodeType === Node.ELEMENT_NODE; }
|
||||
getValue(node) { return node.nodeValue; }
|
||||
setValue(node, value) { node.nodeValue = value; }
|
||||
getElement(node) { return node; }
|
||||
translate(node)
|
||||
{
|
||||
const value = this.getValue(node);
|
||||
if (!value || typeof value !== "string")
|
||||
{
|
||||
return;
|
||||
}
|
||||
const translation = map.get(value.trim());
|
||||
if (translation === undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (typeof translation === "string")
|
||||
{
|
||||
this.setValue(node, translation);
|
||||
}
|
||||
else if (Array.isArray(translation))
|
||||
{
|
||||
let finalTranslation = null;
|
||||
for (const subTranslation of translation)
|
||||
{
|
||||
if (typeof subTranslation === "string")
|
||||
{
|
||||
finalTranslation = subTranslation;
|
||||
}
|
||||
else
|
||||
{
|
||||
const { text, selector } = subTranslation;
|
||||
if (this.getElement(node).matches(selector))
|
||||
{
|
||||
finalTranslation = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (finalTranslation !== null)
|
||||
{
|
||||
this.setValue(node, finalTranslation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const { text, selector } = translation;
|
||||
if (this.getElement(node).matches(selector))
|
||||
{
|
||||
this.setValue(node, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
// https://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page
|
||||
static walk(rootElement, action)
|
||||
{
|
||||
const walker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, null, false);
|
||||
let node = walker.nextNode();
|
||||
while (node)
|
||||
{
|
||||
action(node);
|
||||
node = walker.nextNode();
|
||||
}
|
||||
}
|
||||
static translate(rootElement)
|
||||
{
|
||||
if (rootElement.nodeType === Node.TEXT_NODE)
|
||||
{
|
||||
Translator.textNode.translate(rootElement);
|
||||
return;
|
||||
}
|
||||
Translator.walk(rootElement, node =>
|
||||
{
|
||||
for (const translator of Translator.allTranslators)
|
||||
{
|
||||
if (translator.accepts(node))
|
||||
{
|
||||
translator.translate(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
static translateCssMatches()
|
||||
{
|
||||
const selectors = map.get("*");
|
||||
if (!selectors)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (const { selector, text } of selectors)
|
||||
{
|
||||
const element = document.querySelector(selector);
|
||||
if (element)
|
||||
{
|
||||
[...element.childNodes].filter(it => it.nodeType === Node.TEXT_NODE).forEach(it => it.nodeValue = text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class TextNodeTranslator extends Translator
|
||||
{
|
||||
accepts(node) { return node.nodeType === Node.TEXT_NODE; }
|
||||
getElement(node)
|
||||
{
|
||||
return node.parentElement;
|
||||
}
|
||||
}
|
||||
class TitleTranslator extends Translator
|
||||
{
|
||||
getValue(node) { return node.getAttribute("title"); }
|
||||
setValue(node, value)
|
||||
{
|
||||
node.setAttribute("title", value);
|
||||
}
|
||||
}
|
||||
class PlaceholderTranslator extends Translator
|
||||
{
|
||||
accepts(node) { return node.nodeName === "INPUT" && node.type.toUpperCase() === "TEXT" || node.nodeName === "TEXTAREA"; }
|
||||
getValue(node) { return node.getAttribute("placeholder"); }
|
||||
setValue(node, value)
|
||||
{
|
||||
node.setAttribute("placeholder", value);
|
||||
}
|
||||
}
|
||||
Translator.textNode = new TextNodeTranslator;
|
||||
Translator.title = new TitleTranslator;
|
||||
Translator.placeholder = new PlaceholderTranslator;
|
||||
Translator.allTranslators = [Translator.textNode, Translator.title, Translator.placeholder];
|
||||
|
||||
Translator.translate(document.body);
|
||||
Translator.translateCssMatches();
|
||||
@ -151,4 +155,17 @@
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
})();
|
||||
|
||||
export default {
|
||||
export: {
|
||||
Translator,
|
||||
TextNodeTranslator,
|
||||
TitleTranslator,
|
||||
PlaceholderTranslator,
|
||||
},
|
||||
// dropdown: {
|
||||
// key: "i18nLanguage",
|
||||
// items: Object.keys(languageCodeMap),
|
||||
// },
|
||||
};
|
||||
9
utils/i18n/i18n.zh-TW.js
Normal file
9
utils/i18n/i18n.zh-TW.js
Normal file
@ -0,0 +1,9 @@
|
||||
export const map = new Map([
|
||||
/* Your translation here */
|
||||
[`*`, [
|
||||
/* CSS translation here */
|
||||
]],
|
||||
]);
|
||||
export default {
|
||||
export: { map },
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user