mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Support regex translation
This commit is contained in:
parent
fd171b921d
commit
545c8e5dba
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
min/i18n.de-DE.min.js
vendored
2
min/i18n.de-DE.min.js
vendored
@ -1 +1 @@
|
|||||||
(()=>{return(r,e)=>{const n=new Map([[`*`,[]]]);return{export:{map:n}}}})();
|
(()=>{return(e,n)=>{const r=new Map([[`*`,[]]]);const t=new Map([]);return{export:{map:r,regex:t}}}})();
|
||||||
2
min/i18n.en-US.min.js
vendored
2
min/i18n.en-US.min.js
vendored
@ -1 +1 @@
|
|||||||
(()=>{return(e,t)=>{const o=new Map([[`主站`,`Home`],[`画友`,`Painting`],[`音频`,`Music`],[`游戏中心`,`Game`],[`直播`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Live`}],[`会员购`,`Shop`],[`漫画`,`Comic`],[`下载APP`,`APP`],[`大会员`,`VIP`],[`年度大会员`,`Annual VIP`],[`消息`,`Message`],[`动态`,`Activity`],[`稍后再看`,`Watchlater`],[`已加稍后再看`,`Added`],[`移除`,`Remove`],[`收藏`,`Favorite`],[`历史`,`History`],[`投稿`,`Upload`],[`关注`,[`Follow`,{selector:`.user-panel .text, .n .n-data .n-data-k`,text:`Following`}]],[`关注数`,`Following`],[`粉丝`,`Followers`],[`粉丝数`,`Followers`],[`已关注`,`Following`],[`回复我的`,`Reply`],[`@我的`,`@Mentioned`],[`收到的赞`,`Likes`],[`系统通知`,`System`],[`我的消息`,`Whisper`],[`主页`,`Home`],[`频道`,`Channel`],[`订阅`,`Subscriptions`],[`设置`,`Settings`],[`搜索`,`Search`],[`搜索视频`,`Search videos`],[`搜索设置项`,`Search settings`],[`查看全部`,`View more`],[`查看更多`,`View more`],[`视频`,`Video`],[`专栏`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Column`}],[`转发`,`Forward`],[`评论`,`Reviews`],[`赞`,`Like`],[`视角:`,`View: `],[`我自己`,`Myself`],[`新访客`,`New visitors`],[`我的粉丝`,`Followers`],[`暂时没有新动态了哦!`,`Nothing new at this moment...`],[`历史动态`,`History`],[`投稿了`,`posted`],[`更新了`,`updated`],[`番剧`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Bangumi`}],[`样式`,`Style`],[`工具`,`Tools`],[`触摸`,`Touch`],[`其他`,`Other`],[`附加功能`,`Add-on features`],[`空空如也哦...`,`Nothing...`],[`正在直播`,`Live broadcasting`],[`投稿视频`,`Posted video`],[`展开全文`,`Expand`],[`动画`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Anime`}],[`科技`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Tech`}],[`游戏`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Game`}],[`生活`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Life`}],[`国创`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Native`}],[`音乐`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Music`}],[`舞蹈`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Dance`}],[`数码`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Digital`}],[`鬼畜`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Kichiku`}],[`时尚`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Fashion`}],[`广告`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Ads`}],[`娱乐`,[{selector:`.elevator-module .nav-list .item`,not:true,text:`Entertainment`},{selector:`.primary-menu .nav-menu li .nav-name`,text:`Entmt`}]],[`电影`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Movie`}],[`TV剧`,{selector:`.elevator-module .nav-list .item`,not:true,text:`TV drama`}],[`影视`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Film`}],[`纪录片`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Documentary`}],[`放映厅`,`Cinema`],[`广场`,`Plaza`],[`小黑屋`,`Blackroom`],[`*`,[]]]);return{export:{map:o}}}})();
|
(()=>{return(e,t)=>{const o=new Map([[`主站`,`Home`],[`画友`,`Painting`],[`音频`,`Music`],[`游戏中心`,`Game`],[`直播`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Live`}],[`会员购`,`Shop`],[`漫画`,`Comic`],[`下载APP`,`APP`],[`大会员`,`VIP`],[`年度大会员`,`Annual VIP`],[`消息`,`Message`],[`动态`,`Activity`],[`稍后再看`,`Watchlater`],[`已加稍后再看`,`Added`],[`移除`,`Remove`],[`收藏`,`Favorite`],[`历史`,`History`],[`投稿`,`Upload`],[`关注`,[`Follow`,{selector:`.user-panel .text, .n .n-data .n-data-k`,text:`Following`}]],[`关注数`,`Following`],[`粉丝`,`Followers`],[`粉丝数`,`Followers`],[`已关注`,`Following`],[`回复我的`,`Reply`],[`@我的`,`@Mentioned`],[`收到的赞`,`Likes`],[`系统通知`,`System`],[`我的消息`,`Whisper`],[`主页`,`Home`],[`频道`,`Channel`],[`订阅`,`Subscriptions`],[`设置`,`Settings`],[`搜索`,`Search`],[`搜索视频`,`Search videos`],[`搜索设置项`,`Search settings`],[`查看全部`,`View more`],[`查看更多`,`View more`],[`视频`,`Video`],[`专栏`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Column`}],[`转发`,`Forward`],[`评论`,`Reviews`],[`赞`,`Like`],[`视角:`,`View: `],[`我自己`,`Myself`],[`新访客`,`New visitors`],[`我的粉丝`,`Followers`],[`暂时没有新动态了哦!`,`Nothing new at this moment...`],[`历史动态`,`History`],[`投稿了`,`posted`],[`更新了`,`updated`],[`番剧`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Bangumi`}],[`样式`,`Style`],[`工具`,`Tools`],[`触摸`,`Touch`],[`其他`,`Other`],[`附加功能`,`Add-on features`],[`空空如也哦...`,`Nothing...`],[`正在直播`,`Live broadcasting`],[`投稿视频`,`Posted video`],[`展开全文`,`Expand`],[`动画`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Anime`}],[`科技`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Tech`}],[`游戏`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Game`}],[`生活`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Life`}],[`国创`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Native`}],[`音乐`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Music`}],[`舞蹈`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Dance`}],[`数码`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Digital`}],[`鬼畜`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Kichiku`}],[`时尚`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Fashion`}],[`广告`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Ads`}],[`娱乐`,[{selector:`.elevator-module .nav-list .item`,not:true,text:`Entertainment`},{selector:`.primary-menu .nav-menu li .nav-name`,text:`Entmt`}]],[`电影`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Movie`}],[`TV剧`,{selector:`.elevator-module .nav-list .item`,not:true,text:`TV drama`}],[`影视`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Film`}],[`纪录片`,{selector:`.elevator-module .nav-list .item`,not:true,text:`Documentary`}],[`放映厅`,`Cinema`],[`广场`,`Plaza`],[`小黑屋`,`Blackroom`],[`*`,[]]]);const l=new Map([]);return{export:{map:o,regex:l}}}})();
|
||||||
2
min/i18n.ja-JP.min.js
vendored
2
min/i18n.ja-JP.min.js
vendored
File diff suppressed because one or more lines are too long
2
min/i18n.min.css
vendored
2
min/i18n.min.css
vendored
@ -1 +1 @@
|
|||||||
#page-follows .follow-sidenav .text,.admin-list-cntr .rank-cntr .item .admin-icon,.attention-btn-ctnr .left-part,.author-info .communicate-btn,.author-info .favourite-btn,.bili-search .nav-wrap .wrap>.sub,.dashboard li.like,.h .h-f-btn,.live-sidebar-ctnr .sidebar-btn,.n .n-data,.textarea-container .comm-tool .comm-emoji,.textarea-container .comm-tool .comm-submit,.up-info .up-focus-btn{width:auto!important}.bb-comment .comment-send .comment-emoji{width:max-content!important}.live-panel .more-button,.tag-panel .more-button{width:44px!important}.link-navbar .main-ctnr .nav-logo{width:70px!important}.bili-header-m .profile-m .grade .bar{width:160px!important}.bili-search .contain,.link-navbar .main-ctnr{width:90%!important}.bili-search .video.list{width:calc(100% - 172px)!important}.bili-search .video.list .des{width:100%!important}#page-follows .follow-sidenav .text{min-width:78px!important}.h .h-f-btn{min-width:76px!important}.primary-menu .nav-menu .nav-name,.primary-menu .nav-menu .side-nav .side-link span{white-space:pre!important}.admin-list-cntr .rank-cntr .item .admin-icon,.attention-btn-ctnr .left-part,.bb-comment .comment-send .comment-emoji,.h .h-f-btn,.textarea-container .comm-tool .comm-emoji,.textarea-container .comm-tool .comm-submit,.up-info .up-focus-btn{padding:0 8px!important}.n .n-data{padding:10px 8px!important}.user-panel-ctnr .user-panel .content-ctnr .ctrl-btn:nth-child(2n){padding-left:8px!important}.dashboard li.share .text{padding-top:15px!important}.dashboard li.collection{margin:0 24px 0 8px!important}.bili-search .rocket-con{margin-left:40%!important}.bili-search .video.matrix:nth-child(5n){margin-right:32px!important}.dynamic-m .dyn_menu .line,.nav-wrap .hover-bar,.tab-bar .line{display:none!important}.tab-bar .tab .tab-text.selected{color:var(--theme-color)!important;border-bottom:2px solid!important;box-sizing:border-box!important}.live-panel .more-button{transform:translateX(-9px)!important}.bilibili-player-ending-panel-box-functions .bilibili-player-upinfo-spans>div{align-items:center!important}.dashboard li.collection>div:first-child,.user-panel-ctnr .user-panel .content-ctnr .section-block{display:flex!important;align-items:center!important;flex-direction:column!important}.dashboard li.share{display:inline-flex!important;align-items:center!important;flex-direction:column!important}.user-panel-ctnr .user-panel .content-ctnr .ctrl-btn{float:none!important}#area-list ul li dd{font-size:18px!important}.author-info .communicate-btn,.author-info .communicate-btn:active,.author-info .favourite-btn,.author-info .favourite-btn:active{font-size:12px!important}
|
#page-follows .follow-sidenav .text,.admin-list-cntr .rank-cntr .item .admin-icon,.attention-btn-ctnr .left-part,.author-info .communicate-btn,.author-info .favourite-btn,.bili-search .nav-wrap .wrap>.sub,.dashboard li.like,.h .h-f-btn,.live-sidebar-ctnr .sidebar-btn,.n .n-data,.textarea-container .comm-tool .comm-emoji,.textarea-container .comm-tool .comm-submit,.up-info .up-focus-btn{width:auto!important}.bb-comment .comment-send .comment-emoji{width:max-content!important}.live-panel .more-button,.tag-panel .more-button{width:44px!important}.link-navbar .main-ctnr .nav-logo{width:70px!important}.bili-header-m .profile-m .grade .bar{width:160px!important}.bili-search .contain,.link-navbar .main-ctnr{width:90%!important}.bili-search .video.list{width:calc(100% - 172px)!important}.bili-search .video.list .des{width:100%!important}.gui-settings-box{width:450px!important}#page-follows .follow-sidenav .text{min-width:78px!important}.h .h-f-btn{min-width:76px!important}.primary-menu .nav-menu .nav-name,.primary-menu .nav-menu .side-nav .side-link span{white-space:pre!important}.admin-list-cntr .rank-cntr .item .admin-icon,.attention-btn-ctnr .left-part,.bb-comment .comment-send .comment-emoji,.h .h-f-btn,.textarea-container .comm-tool .comm-emoji,.textarea-container .comm-tool .comm-submit,.up-info .up-focus-btn{padding:0 8px!important}.n .n-data{padding:10px 8px!important}.user-panel-ctnr .user-panel .content-ctnr .ctrl-btn:nth-child(2n){padding-left:8px!important}.dashboard li.share .text{padding-top:15px!important}.dashboard li.collection{margin:0 10px 0 0!important}.bili-search .rocket-con{margin-left:40%!important}.bili-search .video.matrix:nth-child(5n){margin-right:32px!important}.dynamic-m .dyn_menu .line,.nav-wrap .hover-bar,.tab-bar .line{display:none!important}.tab-bar .tab .tab-text.selected{color:var(--theme-color)!important;border-bottom:2px solid!important;box-sizing:border-box!important}.live-panel .more-button{transform:translateX(-9px)!important}.bilibili-player-ending-panel-box-functions .bilibili-player-upinfo-spans>div{align-items:center!important}.dashboard li.collection>div:first-child,.user-panel-ctnr .user-panel .content-ctnr .section-block{display:flex!important;align-items:center!important;flex-direction:column!important}.dashboard li.share{display:inline-flex!important;align-items:center!important;flex-direction:column!important}.user-panel-ctnr .user-panel .content-ctnr .ctrl-btn{float:none!important}#area-list ul li dd{font-size:18px!important}.author-info .communicate-btn,.author-info .communicate-btn:active,.author-info .favourite-btn,.author-info .favourite-btn:active{font-size:12px!important}.dashboard li.like{border-color:transparent!important}
|
||||||
2
min/i18n.min.js
vendored
2
min/i18n.min.js
vendored
@ -1 +1 @@
|
|||||||
(()=>{return(e,t)=>{const a={"日本語":"ja-JP",English:"en-US",Deutsch:"de-DE"};class r{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"||t==="*"){return}const a=r.map.get(t.trim());if(a===undefined){return}if(typeof a==="string"){this.setValue(e,a)}else if(Array.isArray(a)){let t=null;for(const r of a){if(typeof r==="string"){t=r}else{const{text:a,selector:s,not:l}=r;if(this.getElement(e).matches(s)!==Boolean(l)){t=a}}}if(t!==null){this.setValue(e,t)}}else{const{text:t,selector:r,not:s}=a;if(this.getElement(e).matches(r)!==Boolean(s)){this.setValue(e,t)}}}static walk(e,t){const a=document.createTreeWalker(e,NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT,null,false);let r=a.nextNode();while(r){t(r);r=a.nextNode()}}static translate(e){if(e.nodeType===Node.TEXT_NODE){r.textNode.translate(e);return}r.walk(e,e=>{for(const t of r.allTranslators){if(t.accepts(e)){t.translate(e)}}})}static translateCssMatches(){const e=r.map.get("*");if(!e){return}for(const{selector:t,text:a}of e){const e=document.querySelector(t);if(e){[...e.childNodes].filter(e=>e.nodeType===Node.TEXT_NODE).forEach(e=>e.nodeValue=a)}}}}class s extends r{accepts(e){return e.nodeType===Node.TEXT_NODE}getElement(e){return e.parentElement}}class l extends r{getValue(e){return e.getAttribute("title")}setValue(e,t){e.setAttribute("title",t)}}class n extends r{getValue(e){return e.getAttribute("placeholder")}setValue(e,t){e.setAttribute("placeholder",t)}}r.textNode=new s;r.title=new l;r.placeholder=new n;r.allTranslators=[r.textNode,r.title,r.placeholder];(async()=>{const{map:s}=await t.importAsync(`i18n.${a[e.i18nLanguage]}`);r.map=s;r.translate(document.body);r.translateCssMatches();Observer.observe("body",e=>{e.forEach(e=>{if(e.type==="childList"){if(e.addedNodes.length>0){r.translateCssMatches()}e.addedNodes.forEach(e=>{r.translate(e)})}else if(e.type==="characterData"){r.textNode.translate(e.target)}})},{characterData:true,childList:true,subtree:true})})();return{export:{Translator:r,TextNodeTranslator:s,TitleTranslator:l,PlaceholderTranslator:n}}}})();
|
(()=>{return(e,t)=>{const a={"日本語":"ja-JP",English:"en-US",Deutsch:"de-DE"};class s{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"||t==="*"){return}const a=s.map.get(t.trim());if(a===undefined){const a=s.regex.find(([e])=>e.test(t));if(a){const[s,r]=a;this.setValue(e,t.replace(s,r))}}else if(typeof a==="string"){this.setValue(e,a)}else if(Array.isArray(a)){let t=null;for(const s of a){if(typeof s==="string"){t=s}else{const{text:a,selector:r,not:l}=s;if(this.getElement(e).matches(r)!==Boolean(l)){t=a}}}if(t!==null){this.setValue(e,t)}}else{const{text:t,selector:s,not:r}=a;if(this.getElement(e).matches(s)!==Boolean(r)){this.setValue(e,t)}}}static walk(e,t){const a=document.createTreeWalker(e,NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT,null,false);let s=a.nextNode();while(s){t(s);s=a.nextNode()}}static translate(e){if(e.nodeType===Node.TEXT_NODE){s.textNode.translate(e);return}s.walk(e,e=>{for(const t of s.allTranslators){if(t.accepts(e)){t.translate(e)}}})}static translateCssMatches(){const e=s.map.get("*");if(!e){return}for(const{selector:t,text:a}of e){const e=document.querySelector(t);if(e){[...e.childNodes].filter(e=>e.nodeType===Node.TEXT_NODE).forEach(e=>e.nodeValue=a)}}}}class r extends s{accepts(e){return e.nodeType===Node.TEXT_NODE}getElement(e){return e.parentElement}}class l extends s{getValue(e){return e.getAttribute("title")}setValue(e,t){e.setAttribute("title",t)}}class n extends s{getValue(e){return e.getAttribute("placeholder")}setValue(e,t){e.setAttribute("placeholder",t)}}s.textNode=new r;s.title=new l;s.placeholder=new n;s.allTranslators=[s.textNode,s.title,s.placeholder];(async()=>{const{map:r,regex:l}=await t.importAsync(`i18n.${a[e.i18nLanguage]}`);s.map=r;s.regex=[...l.entries()];s.translate(document.body);s.translateCssMatches();Observer.observe("body",e=>{e.forEach(e=>{if(e.type==="childList"){if(e.addedNodes.length>0){s.translateCssMatches()}e.addedNodes.forEach(e=>{s.translate(e)})}else if(e.type==="characterData"){s.textNode.translate(e.target)}})},{characterData:true,childList:true,subtree:true})})();return{export:{Translator:s,TextNodeTranslator:r,TitleTranslator:l,PlaceholderTranslator:n}}}})();
|
||||||
@ -44,6 +44,10 @@
|
|||||||
{
|
{
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
.gui-settings-box
|
||||||
|
{
|
||||||
|
width: 450px !important;
|
||||||
|
}
|
||||||
#page-follows .follow-sidenav .text
|
#page-follows .follow-sidenav .text
|
||||||
{
|
{
|
||||||
min-width: 78px !important;
|
min-width: 78px !important;
|
||||||
@ -82,7 +86,7 @@
|
|||||||
}
|
}
|
||||||
.dashboard li.collection
|
.dashboard li.collection
|
||||||
{
|
{
|
||||||
margin: 0px 24px 0 8px !important;
|
margin: 0 10px 0 0px !important;
|
||||||
}
|
}
|
||||||
.bili-search .rocket-con
|
.bili-search .rocket-con
|
||||||
{
|
{
|
||||||
@ -142,3 +146,7 @@
|
|||||||
{
|
{
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
}
|
}
|
||||||
|
.dashboard li.like
|
||||||
|
{
|
||||||
|
border-color: transparent !important;
|
||||||
|
}
|
||||||
@ -4,6 +4,9 @@ export const map = new Map([
|
|||||||
/* CSS translation here */
|
/* CSS translation here */
|
||||||
]],
|
]],
|
||||||
]);
|
]);
|
||||||
|
export const regex = new Map([
|
||||||
|
/* Regex translation here */
|
||||||
|
]);
|
||||||
export default {
|
export default {
|
||||||
export: { map },
|
export: { map, regex },
|
||||||
};
|
};
|
||||||
@ -172,6 +172,9 @@ export const map = new Map([
|
|||||||
|
|
||||||
]],
|
]],
|
||||||
]);
|
]);
|
||||||
|
export const regex = new Map([
|
||||||
|
/* Regex translation here */
|
||||||
|
]);
|
||||||
export default {
|
export default {
|
||||||
export: { map },
|
export: { map, regex },
|
||||||
};
|
};
|
||||||
@ -316,6 +316,9 @@ export const map = new Map([
|
|||||||
|
|
||||||
]],
|
]],
|
||||||
]);
|
]);
|
||||||
|
export const regex = new Map([
|
||||||
|
[/浏览:([0-9\.a-z])/, `閲覧数:$1`],
|
||||||
|
]);
|
||||||
export default {
|
export default {
|
||||||
export: { map },
|
export: { map, regex },
|
||||||
};
|
};
|
||||||
@ -15,9 +15,13 @@ export class Translator {
|
|||||||
}
|
}
|
||||||
const translation = Translator.map.get(value.trim());
|
const translation = Translator.map.get(value.trim());
|
||||||
if (translation === undefined) {
|
if (translation === undefined) {
|
||||||
return;
|
const result = Translator.regex.find(([r]) => r.test(value));
|
||||||
|
if (result) {
|
||||||
|
const [regex, replacement] = result;
|
||||||
|
this.setValue(node, value.replace(regex, replacement));
|
||||||
}
|
}
|
||||||
if (typeof translation === "string") {
|
}
|
||||||
|
else if (typeof translation === "string") {
|
||||||
this.setValue(node, translation);
|
this.setValue(node, translation);
|
||||||
}
|
}
|
||||||
else if (Array.isArray(translation)) {
|
else if (Array.isArray(translation)) {
|
||||||
@ -103,8 +107,9 @@ Translator.title = new TitleTranslator;
|
|||||||
Translator.placeholder = new PlaceholderTranslator;
|
Translator.placeholder = new PlaceholderTranslator;
|
||||||
Translator.allTranslators = [Translator.textNode, Translator.title, Translator.placeholder];
|
Translator.allTranslators = [Translator.textNode, Translator.title, Translator.placeholder];
|
||||||
(async () => {
|
(async () => {
|
||||||
const { map } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
|
const { map, regex } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
|
||||||
Translator.map = map;
|
Translator.map = map;
|
||||||
|
Translator.regex = [...regex.entries()];
|
||||||
Translator.translate(document.body);
|
Translator.translate(document.body);
|
||||||
Translator.translateCssMatches();
|
Translator.translateCssMatches();
|
||||||
Observer.observe("body", records => {
|
Observer.observe("body", records => {
|
||||||
|
|||||||
@ -22,11 +22,14 @@ export const map = new Map([
|
|||||||
/* CSS translation here */
|
/* CSS translation here */
|
||||||
]],
|
]],
|
||||||
]);
|
]);
|
||||||
|
export const regex = new Map([
|
||||||
|
/* Regex translation here */
|
||||||
|
]);
|
||||||
export default {
|
export default {
|
||||||
export: { map },
|
export: { map, regex },
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
3. 在`/* Your translation here */`上方添加翻译, 或在`/* CSS translation here */`上方添加选择器翻译, 详细语法见下一节.
|
3. 在`/* Your translation here */`上方添加翻译, 或在`/* CSS translation here */`上方添加选择器翻译, 在`/* Regex translation here */`上方添加正则翻译, 详细语法见下一节.
|
||||||
|
|
||||||
## 翻译语法
|
## 翻译语法
|
||||||
有多种翻译方式可供选择.
|
有多种翻译方式可供选择.
|
||||||
@ -170,6 +173,21 @@ export default {
|
|||||||
<a class="xxx yyy">Home3</a>
|
<a class="xxx yyy">Home3</a>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 使用正则翻译
|
||||||
|
当原文本包含一段不确定内容时, 可以使用正则翻译来匹配, 需要翻译者对正则表达式有一定了解. 这种翻译放在这一区域: (`export const regex`)
|
||||||
|
```js
|
||||||
|
export const regex = new Map([
|
||||||
|
/* Regex translation here */
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
例如, 要将`浏览:23.3w`翻译为`Read: 23.3w`, 则添加:
|
||||||
|
```js
|
||||||
|
[/浏览:([0-9\.a-z])/, `Read: $1`],
|
||||||
|
```
|
||||||
|
第一个元素是正则表达式, 用一对斜杠(`/`)包围, 语法可在[MDN文档](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions)中学习. 第二个元素是替换文本. 在这个例子中, `$1`指代原文本中的浏览量数字, 利用了正则表达式的分组功能, 详见文档中的["使用括号的子字符串匹配"](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions#%E4%BD%BF%E7%94%A8%E6%8B%AC%E5%8F%B7%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8C%B9%E9%85%8D_2)一节.
|
||||||
|
|
||||||
|
|
||||||
## 调整界面元素
|
## 调整界面元素
|
||||||
一些界面元素的尺寸是固定大小, 如果添加翻译后, 无法适应翻译后的文本长度, 可以在`i18n.css`中添加CSS样式来调整.
|
一些界面元素的尺寸是固定大小, 如果添加翻译后, 无法适应翻译后的文本长度, 可以在`i18n.css`中添加CSS样式来调整.
|
||||||
|
|
||||||
@ -202,8 +220,12 @@ export const map = new Map([
|
|||||||
/* CSS translation here */
|
/* CSS translation here */
|
||||||
]],
|
]],
|
||||||
]);
|
]);
|
||||||
|
export const regex = new Map([
|
||||||
|
[/(\d+)次播放/, `Played $1 times`],
|
||||||
|
/* Regex translation here */
|
||||||
|
]);
|
||||||
export default {
|
export default {
|
||||||
export: { map },
|
export: { map, regex },
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
该文件能够将类似以下的网页内容
|
该文件能够将类似以下的网页内容
|
||||||
@ -217,6 +239,7 @@ export default {
|
|||||||
<a class="xxx">其他</a>
|
<a class="xxx">其他</a>
|
||||||
<a class="yyy">其他</a>
|
<a class="yyy">其他</a>
|
||||||
<a class="zzz">其他</a>
|
<a class="zzz">其他</a>
|
||||||
|
<a>233次播放</a>
|
||||||
```
|
```
|
||||||
翻译为
|
翻译为
|
||||||
```html
|
```html
|
||||||
@ -228,5 +251,5 @@ export default {
|
|||||||
<a class="ccc">Follow</a>
|
<a class="ccc">Follow</a>
|
||||||
<a class="xxx">XXX</a>
|
<a class="xxx">XXX</a>
|
||||||
<a class="yyy">YYY</a>
|
<a class="yyy">YYY</a>
|
||||||
<a class="zzz">其他</a>
|
<a>Played 233 times</a>
|
||||||
```
|
```
|
||||||
@ -10,6 +10,7 @@ export class Translator
|
|||||||
static placeholder: PlaceholderTranslator;
|
static placeholder: PlaceholderTranslator;
|
||||||
static allTranslators: Translator[];
|
static allTranslators: Translator[];
|
||||||
static map: Map<string, any>;
|
static map: Map<string, any>;
|
||||||
|
static regex: [RegExp, string][];
|
||||||
|
|
||||||
accepts(node: Node) { return node.nodeType === Node.ELEMENT_NODE; }
|
accepts(node: Node) { return node.nodeType === Node.ELEMENT_NODE; }
|
||||||
getValue(node: Node) { return node.nodeValue; }
|
getValue(node: Node) { return node.nodeValue; }
|
||||||
@ -25,9 +26,14 @@ export class Translator
|
|||||||
const translation = Translator.map.get(value.trim());
|
const translation = Translator.map.get(value.trim());
|
||||||
if (translation === undefined)
|
if (translation === undefined)
|
||||||
{
|
{
|
||||||
return;
|
const result = Translator.regex.find(([r]) => r.test(value));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
const [regex, replacement] = result;
|
||||||
|
this.setValue(node, value.replace(regex, replacement));
|
||||||
}
|
}
|
||||||
if (typeof translation === "string")
|
}
|
||||||
|
else if (typeof translation === "string")
|
||||||
{
|
{
|
||||||
this.setValue(node, translation);
|
this.setValue(node, translation);
|
||||||
}
|
}
|
||||||
@ -142,8 +148,9 @@ Translator.allTranslators = [Translator.textNode, Translator.title, Translator.p
|
|||||||
|
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const { map } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
|
const { map, regex } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
|
||||||
Translator.map = map;
|
Translator.map = map;
|
||||||
|
Translator.regex = [...regex.entries()];
|
||||||
|
|
||||||
Translator.translate(document.body);
|
Translator.translate(document.body);
|
||||||
Translator.translateCssMatches();
|
Translator.translateCssMatches();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user