Support regex translation

This commit is contained in:
the1812 2019-04-08 23:06:34 +08:00
parent fd171b921d
commit 545c8e5dba
14 changed files with 322 additions and 270 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

@ -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}}}})();

View File

@ -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}}}})();

File diff suppressed because one or more lines are too long

2
min/i18n.min.css vendored
View File

@ -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
View File

@ -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}}}})();

View File

@ -44,6 +44,10 @@
{
width: 100% !important;
}
.gui-settings-box
{
width: 450px !important;
}
#page-follows .follow-sidenav .text
{
min-width: 78px !important;
@ -82,7 +86,7 @@
}
.dashboard li.collection
{
margin: 0px 24px 0 8px !important;
margin: 0 10px 0 0px !important;
}
.bili-search .rocket-con
{
@ -141,4 +145,8 @@
.author-info .communicate-btn:active
{
font-size: 12px !important;
}
.dashboard li.like
{
border-color: transparent !important;
}

View File

@ -4,6 +4,9 @@ export const map = new Map([
/* CSS translation here */
]],
]);
export const regex = new Map([
/* Regex translation here */
]);
export default {
export: { map },
export: { map, regex },
};

View File

@ -172,6 +172,9 @@ export const map = new Map([
]],
]);
export const regex = new Map([
/* Regex translation here */
]);
export default {
export: { map },
export: { map, regex },
};

View File

@ -11,158 +11,158 @@ export const map = new Map([
[`稍后再看`, `後で見る`],
[`收藏`, `お気に入り`],
[`历史`, `視聴履歴`],
[`关注`,`フォロー`],
[`粉丝`,`ファン`],
[`更多`,`もっと`],
[`排行`,`ランキング`],
[`图片`,`ピクチャ`],
[`视频`,`ビデオ`],
[`番剧`,`番組`],
[`音乐`,`音楽`],
[`时尚`,`潮流`],
[`电影`,`劇場`],
[`影视`,`映画`],
[`放映厅`,`映画館`],
[`广告`,`広告`],
[`广场`,`広場`],
[`发布`,`発表`],
[`举报`,`通報`],
[`首页`,`ホーム`],
[`热门`,`人気`],
[`周一`,``],
[`周二`,``],
[`周三`,``],
[`周四`,``],
[`周五`,``],
[`周六`,``],
[`周日`,``],
[`发送`,`送信`],
[`取消`,`取り消し`],
[`关闭`,`閉じる`],
[`表情`,`ステッカー`],
[`小视频`,`短いビデオ`],
[`查看更多`,`もっと見る`],
[`查看全部`,`すべて表示`],
[`关注`, `フォロー`],
[`粉丝`, `ファン`],
[`更多`, `もっと`],
[`排行`, `ランキング`],
[`图片`, `ピクチャ`],
[`视频`, `ビデオ`],
[`番剧`, `番組`],
[`音乐`, `音楽`],
[`时尚`, `潮流`],
[`电影`, `劇場`],
[`影视`, `映画`],
[`放映厅`, `映画館`],
[`广告`, `広告`],
[`广场`, `広場`],
[`发布`, `発表`],
[`举报`, `通報`],
[`首页`, `ホーム`],
[`热门`, `人気`],
[`周一`, ``],
[`周二`, ``],
[`周三`, ``],
[`周四`, ``],
[`周五`, ``],
[`周六`, ``],
[`周日`, ``],
[`发送`, `送信`],
[`取消`, `取り消し`],
[`关闭`, `閉じる`],
[`表情`, `ステッカー`],
[`小视频`, `短いビデオ`],
[`查看更多`, `もっと見る`],
[`查看全部`, `すべて表示`],
[`播放历史`, `視聴履歴`],
[`删除`,`削除`],
[`确认`,`確認`],
[`取消关注`,`フォロー解除`],
[`全部`,`全て`],
[`投稿视频`,`ビデオ`],
[`公告栏`,`掲示板`],
[`正在直播`,`生放送中`],
[`虚拟主播`,`Vtuber`],
[`房间标题`,`タイトル`],
[`设置`,`設定`],
[`频道`,`チャンネル`],
[`标签`,`タグ`],
[`关注数`,`フォロー数`],
[`粉丝数`,`ファン数`],
[`相簿`,`アルバム`],
[`我的频道`,`私のチャンネル`],
[`我的视频`,`私のビデオ`],
[`我的音频`,`私の音楽`],
[`我的音乐`,`私の音楽`],
[`我的专栏`,`私のコラム`],
[`我的相簿`,`私のアルバム`],
[`我的关注`,`私のフォロー`],
[`我的粉丝`,`私のファン`],
[`我的消息`,`DM`],
[`系统通知`,`システム`],
[`网游`,`オンライン`],
[`手游`,`モバイル`],
[`单机`,`単機ゲーム`],
[`电台`,`ラジオ`],
[`绘画`,`絵画`],
[`热门话题`,`人気話題`],
[`热门排行`,`人気ランキング`],
[`我关注的话题`,`私の話題`],
[`有什么想和大家分享的?`,`何をみんなと共有したいのですか`],
[`有新动态,点击查看`,`新しい情報がある、クリックして見る`],
[`刚刚`,`さっき`],
[`转发动态`,`転送した`],
[`转发`,`転送`],
[`投稿了`,`投稿した`],
[`历史动态`,`歴史情報`],
[`在线人数`,`オンライン`],
[`追番`,`番組`],
[`评论`,`コメント`],
[`新番时间表`,`番組時間表`],
[`小黑屋`,`公開処刑`],
[`摄影`,`撮影`],
[`其他`,`他の`],
[`下载`,`ダウンロード`],
[`更新了`,`更新した`],
[`排行榜`,`ランキング`],
[`推荐`,`推薦`],
[`播放`,`再生`],
[`弹幕`,`弾幕`],
[`已结束`,`終わり`],
[`电视剧`,`ドラマ`],
[`上一页`,`前へ`],
[`下一页`,`次へ`],
[`搜索`,`検索`],
[`直播中`,`生放送中`],
[`个人中心`,`個人センター`],
[`等级`,`レベル`],
[`直播中心`,`生放送センター`],
[`主页`,`ホーム`],
[`排序`,`序列`],
[`移除`,`削除`],
[`复制`,`コピー`],
[`换一换`,`更新`],
[`特别推荐`,`特別推薦`],
[`热门榜单`,`人気ランキング`],
[`播放全部`,`すべて放送`],
[`观看历史`,`視聴履歴`],
[`个人收益`,`個人収益`],
[`同时转发到我的动态`,`同時に転送もする`],
[`人气值`,`人気値`],
[`话题`,`話題`],
[`活动`,`活動`],
[`活动中心`,`活動中心`],
[`消息中心`,`ニュースセンター`],
[`专栏投稿`,`コラム`],
[`音频投稿`,`音楽`],
[`视频投稿`,`ビデオ`],
[`相簿投稿`,`アルバム`],
[`上传视频`,`アップロード`],
[`退出登录`,`ログアウト`],
[`回复我的`,`返信`],
[`领取`,`受け取り`],
[`样式`,`スタイル`],
[`工具`,`道具`],
[`触摸`,`タッチスクリーン`],
[`指定播放器布局`,'プレーヤーレイアウト'],
[`视频区布局`,`ビデオ`],
[`番剧区布局`,`番組`],
[`使用默认播放器模式`,`プレーヤーモード`],
[`默认播放器模式`,`デフォルト・モード`],
[`播放时应用模式`,`再生時に使う`],
[`播放时自动关灯`,`再生時はライトを消す`],
[`使用默认视频画质`,`映像画質`],
[`画质设定`,`画質設定`],
[`使用默认弹幕设置`,`弾幕設定`],
[`开启弹幕`,`弾幕を開ける`],
[`记住弹幕设置`,'シールド設定を覚える'],
[`自动展开弹幕列表`,`弾幕のリストを展開する`],
[`自动展开视频简介`,`ビデオ紹介を展開する`],
[`自动从历史记录点播放`,`歴史記録から再生します`],
[`自动播放视频`,`ビデオを自動再生する`],
[`跳过充电鸣谢`,`エンディングをスキップ`],
[`启用逐帧调整`,`フレーム毎に調整する`],
[`主题颜色`,`テーマカラー`],
[`样式调整`,`スタイルの調整`],
[`顶栏(对横幅)透明度`,`(横断幕に)トップバーの透明度`],
[`夜间模式`,`ナイトモード`],
[`夜间模式计划时段`,`ナイトモード计画タイム`],
[`首页使用紧凑布局`,`トップページにコンパクトなレイアウトを使う`],
[`简化评论区`,`コメントエリアの簡潔化`],
[`简化直播间`,`生放送ページの簡潔化`],
[`搜索栏置顶`,`検索欄がトップになる`],
[`显示顶部横幅`,`トップの横断幕を表示する`],
[`显示排行榜图标`,`ランキングのアイコンを表示する`],
[`模糊视频控制栏背景`,`ビデオ制御欄の背景がぼやける`],
[`删除`, `削除`],
[`确认`, `確認`],
[`取消关注`, `フォロー解除`],
[`全部`, `全て`],
[`投稿视频`, `ビデオ`],
[`公告栏`, `掲示板`],
[`正在直播`, `生放送中`],
[`虚拟主播`, `Vtuber`],
[`房间标题`, `タイトル`],
[`设置`, `設定`],
[`频道`, `チャンネル`],
[`标签`, `タグ`],
[`关注数`, `フォロー数`],
[`粉丝数`, `ファン数`],
[`相簿`, `アルバム`],
[`我的频道`, `私のチャンネル`],
[`我的视频`, `私のビデオ`],
[`我的音频`, `私の音楽`],
[`我的音乐`, `私の音楽`],
[`我的专栏`, `私のコラム`],
[`我的相簿`, `私のアルバム`],
[`我的关注`, `私のフォロー`],
[`我的粉丝`, `私のファン`],
[`我的消息`, `DM`],
[`系统通知`, `システム`],
[`网游`, `オンライン`],
[`手游`, `モバイル`],
[`单机`, `単機ゲーム`],
[`电台`, `ラジオ`],
[`绘画`, `絵画`],
[`热门话题`, `人気話題`],
[`热门排行`, `人気ランキング`],
[`我关注的话题`, `私の話題`],
[`有什么想和大家分享的?`, `何をみんなと共有したいのですか`],
[`有新动态,点击查看`, `新しい情報がある、クリックして見る`],
[`刚刚`, `さっき`],
[`转发动态`, `転送した`],
[`转发`, `転送`],
[`投稿了`, `投稿した`],
[`历史动态`, `歴史情報`],
[`在线人数`, `オンライン`],
[`追番`, `番組`],
[`评论`, `コメント`],
[`新番时间表`, `番組時間表`],
[`小黑屋`, `公開処刑`],
[`摄影`, `撮影`],
[`其他`, `他の`],
[`下载`, `ダウンロード`],
[`更新了`, `更新した`],
[`排行榜`, `ランキング`],
[`推荐`, `推薦`],
[`播放`, `再生`],
[`弹幕`, `弾幕`],
[`已结束`, `終わり`],
[`电视剧`, `ドラマ`],
[`上一页`, `前へ`],
[`下一页`, `次へ`],
[`搜索`, `検索`],
[`直播中`, `生放送中`],
[`个人中心`, `個人センター`],
[`等级`, `レベル`],
[`直播中心`, `生放送センター`],
[`主页`, `ホーム`],
[`排序`, `序列`],
[`移除`, `削除`],
[`复制`, `コピー`],
[`换一换`, `更新`],
[`特别推荐`, `特別推薦`],
[`热门榜单`, `人気ランキング`],
[`播放全部`, `すべて放送`],
[`观看历史`, `視聴履歴`],
[`个人收益`, `個人収益`],
[`同时转发到我的动态`, `同時に転送もする`],
[`人气值`, `人気値`],
[`话题`, `話題`],
[`活动`, `活動`],
[`活动中心`, `活動中心`],
[`消息中心`, `ニュースセンター`],
[`专栏投稿`, `コラム`],
[`音频投稿`, `音楽`],
[`视频投稿`, `ビデオ`],
[`相簿投稿`, `アルバム`],
[`上传视频`, `アップロード`],
[`退出登录`, `ログアウト`],
[`回复我的`, `返信`],
[`领取`, `受け取り`],
[`样式`, `スタイル`],
[`工具`, `道具`],
[`触摸`, `タッチスクリーン`],
[`指定播放器布局`, 'プレーヤーレイアウト'],
[`视频区布局`, `ビデオ`],
[`番剧区布局`, `番組`],
[`使用默认播放器模式`, `プレーヤーモード`],
[`默认播放器模式`, `デフォルト・モード`],
[`播放时应用模式`, `再生時に使う`],
[`播放时自动关灯`, `再生時はライトを消す`],
[`使用默认视频画质`, `映像画質`],
[`画质设定`, `画質設定`],
[`使用默认弹幕设置`, `弾幕設定`],
[`开启弹幕`, `弾幕を開ける`],
[`记住弹幕设置`, 'シールド設定を覚える'],
[`自动展开弹幕列表`, `弾幕のリストを展開する`],
[`自动展开视频简介`, `ビデオ紹介を展開する`],
[`自动从历史记录点播放`, `歴史記録から再生します`],
[`自动播放视频`, `ビデオを自動再生する`],
[`跳过充电鸣谢`, `エンディングをスキップ`],
[`启用逐帧调整`, `フレーム毎に調整する`],
[`主题颜色`, `テーマカラー`],
[`样式调整`, `スタイルの調整`],
[`顶栏(对横幅)透明度`, `(横断幕に)トップバーの透明度`],
[`夜间模式`, `ナイトモード`],
[`夜间模式计划时段`, `ナイトモード计画タイム`],
[`首页使用紧凑布局`, `トップページにコンパクトなレイアウトを使う`],
[`简化评论区`, `コメントエリアの簡潔化`],
[`简化直播间`, `生放送ページの簡潔化`],
[`搜索栏置顶`, `検索欄がトップになる`],
[`显示顶部横幅`, `トップの横断幕を表示する`],
[`显示排行榜图标`, `ランキングのアイコンを表示する`],
[`模糊视频控制栏背景`, `ビデオ制御欄の背景がぼやける`],
[`动画`, {
selector: `.elevator-module .nav-list .item`,
not: true,
@ -223,99 +223,102 @@ export const map = new Map([
not: true,
text: `全画面`,
}],
[`登录`,`ログイン`],
[`注册`,`登録`],
[`我的直播间`,`私のスタジオ`],
[`直播间`,`スタジオ`],
[`订阅`,`登録チャンネル`],
[`主站空间`,`個人センター`],
[`播放数`,`再生数`],
[`综合`,`すべて`],
[`用户`,`ユーザー`],
[`投稿管理`,`ダッシュボード`],
[`个人信息`,`個人情報`],
[`开播设置`,`放送設定`],
[`直播分类`,`カテゴリ`],
[`修改分区`,`カテゴリを変更`],
[`房间标题`,`タイトル`],
[`开始直播`,`放送開始`],
[`停止直播`,`放送中止`],
[`主播公告`,`チャンネル公告`],
[`简介`,`概要`],
[`直播封面`,`サムネイル`],
[`我的个人标签`,`私のタグ`],
[`个人简介`,`概要`],
[`直播间信息`,`スタジオ情報`],
[`我的船员`,`私のクルー`],
[`直播数据`,`アナリティクス`],
[`数据总览`,`データ概要`],
[`直播时长`,`総再生時間`],
[`最高人气值`,`最大人気値`],
[`金仓鼠`,`金ハムスター`],
[`贝壳`,`貝殻`],
[`直播收益(金仓鼠)`,`投げ銭(金ハムスター)`],
[`直播收益`,`投げ銭`],
[`新增关注数`,`新しい登録者`],
[`人均观看时长`,`平均視聴時間`],
[`礼物流水`,`ギフト記録`],
[`礼物统计`,`ギフト一覧`],
[`消费排行`,`ランキング`],
[`更多>>`,`もっと>>`],
[`主播`,`配信者`],
[`未开播`,`待機中`],
[`金瓜子`,`金ヒマワリの種`],
[`银瓜子`,`銀ヒマワリの種`],
[`残忍取关`,`フォロー解除`],
[`再考虑一下`,`考え直す`],
[`已关注`,`フォロー中`],
[`七日榜`,`週間rank`],
[`舰队`,`艦隊`],
[`房管`,`管理者`],
[`分享`,`シェア`],
[`轮播`,`再放送`],
[`闲置`,`待機中`],
[`回复`,`リプレイ`],
[`查看更多评论`,`もっと見る`],
[`英雄联盟`,`LOL`],
[`APEX英雄`,`Apex Legends`],
[`守望先锋`,`Overwatch`],
[`绝地求生`,`PUBG`],
[`王者荣耀`,`伝説対決`],
[`第五人格`,`Identity V`],
[`绝地求生:刺激战场`,`PUBG Mobile`],
[`崩坏3`,`崩壊3rd`],
[`主机游戏`,`テレビゲーム`],
[`我的世界`,`マイクラ`],
[`怪物猎人:世界`,`モンハンワールド`],
[`只狼:影逝二度`,`SEKIRO/隻狼`],
[`鬼泣5`,`デビルメイクライ5`],
[`视频唱见`,`顔出し歌枠`],
[`舞见`,`踊り枠`],
[`视频聊天`,`顔出し雑談枠`],
[`才艺`,`タレントショー`],
[`唱见电台`,`歌枠`],
[`声优`,`声優`],
[`聊天电台`,`雑談枠`],
[`同人绘画`,`同人`],
[`原创绘画`,`オリジナル`],
[`临摹绘画`,`模写`],
[`其他绘画`,`他の絵`],
[`扭蛋机`,`ガチャ`],
[`我关注的直播`,`フォローした配信`],
[`我关注的动态`,`フォローした情報`],
[`按热度排序`,`人気多い順位`],
[`全部评论`,`すべて`],
[`发消息`,`DMを送る`],
[`点赞`,`いいね!`],
[`浏览`,`閲覧数`],
[`收藏`,`ブックマーク`],
[`支持`,`いいね!`],
[`发表评论`,`コメント`],
[`登录`, `ログイン`],
[`注册`, `登録`],
[`我的直播间`, `私のスタジオ`],
[`直播间`, `スタジオ`],
[`订阅`, `登録チャンネル`],
[`主站空间`, `個人センター`],
[`播放数`, `再生数`],
[`综合`, `すべて`],
[`用户`, `ユーザー`],
[`投稿管理`, `ダッシュボード`],
[`个人信息`, `個人情報`],
[`开播设置`, `放送設定`],
[`直播分类`, `カテゴリ`],
[`修改分区`, `カテゴリを変更`],
[`房间标题`, `タイトル`],
[`开始直播`, `放送開始`],
[`停止直播`, `放送中止`],
[`主播公告`, `チャンネル公告`],
[`简介`, `概要`],
[`直播封面`, `サムネイル`],
[`我的个人标签`, `私のタグ`],
[`个人简介`, `概要`],
[`直播间信息`, `スタジオ情報`],
[`我的船员`, `私のクルー`],
[`直播数据`, `アナリティクス`],
[`数据总览`, `データ概要`],
[`直播时长`, `総再生時間`],
[`最高人气值`, `最大人気値`],
[`金仓鼠`, `金ハムスター`],
[`贝壳`, `貝殻`],
[`直播收益(金仓鼠)`, `投げ銭(金ハムスター)`],
[`直播收益`, `投げ銭`],
[`新增关注数`, `新しい登録者`],
[`人均观看时长`, `平均視聴時間`],
[`礼物流水`, `ギフト記録`],
[`礼物统计`, `ギフト一覧`],
[`消费排行`, `ランキング`],
[`更多>>`, `もっと>>`],
[`主播`, `配信者`],
[`未开播`, `待機中`],
[`金瓜子`, `金ヒマワリの種`],
[`银瓜子`, `銀ヒマワリの種`],
[`残忍取关`, `フォロー解除`],
[`再考虑一下`, `考え直す`],
[`已关注`, `フォロー中`],
[`七日榜`, `週間rank`],
[`舰队`, `艦隊`],
[`房管`, `管理者`],
[`分享`, `シェア`],
[`轮播`, `再放送`],
[`闲置`, `待機中`],
[`回复`, `リプレイ`],
[`查看更多评论`, `もっと見る`],
[`英雄联盟`, `LOL`],
[`APEX英雄`, `Apex Legends`],
[`守望先锋`, `Overwatch`],
[`绝地求生`, `PUBG`],
[`王者荣耀`, `伝説対決`],
[`第五人格`, `Identity V`],
[`绝地求生:刺激战场`, `PUBG Mobile`],
[`崩坏3`, `崩壊3rd`],
[`主机游戏`, `テレビゲーム`],
[`我的世界`, `マイクラ`],
[`怪物猎人:世界`, `モンハンワールド`],
[`只狼:影逝二度`, `SEKIRO/隻狼`],
[`鬼泣5`, `デビルメイクライ5`],
[`视频唱见`, `顔出し歌枠`],
[`舞见`, `踊り枠`],
[`视频聊天`, `顔出し雑談枠`],
[`才艺`, `タレントショー`],
[`唱见电台`, `歌枠`],
[`声优`, `声優`],
[`聊天电台`, `雑談枠`],
[`同人绘画`, `同人`],
[`原创绘画`, `オリジナル`],
[`临摹绘画`, `模写`],
[`其他绘画`, `他の絵`],
[`扭蛋机`, `ガチャ`],
[`我关注的直播`, `フォローした配信`],
[`我关注的动态`, `フォローした情報`],
[`按热度排序`, `人気多い順位`],
[`全部评论`, `すべて`],
[`发消息`, `DMを送る`],
[`点赞`, `いいね!`],
[`浏览`, `閲覧数`],
[`收藏`, `ブックマーク`],
[`支持`, `いいね!`],
[`发表评论`, `コメント`],
[`*`, [
/* CSS translation here */
]],
]);
export const regex = new Map([
[/浏览:([0-9\.a-z])/, `閲覧数:$1`],
]);
export default {
export: { map },
export: { map, regex },
};

View File

@ -15,9 +15,13 @@ export class Translator {
}
const translation = Translator.map.get(value.trim());
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);
}
else if (Array.isArray(translation)) {
@ -103,8 +107,9 @@ Translator.title = new TitleTranslator;
Translator.placeholder = new PlaceholderTranslator;
Translator.allTranslators = [Translator.textNode, Translator.title, Translator.placeholder];
(async () => {
const { map } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
const { map, regex } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
Translator.map = map;
Translator.regex = [...regex.entries()];
Translator.translate(document.body);
Translator.translateCssMatches();
Observer.observe("body", records => {

View File

@ -22,11 +22,14 @@ export const map = new Map([
/* CSS translation here */
]],
]);
export const regex = new Map([
/* Regex translation here */
]);
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>
```
### 使用正则翻译
当原文本包含一段不确定内容时, 可以使用正则翻译来匹配, 需要翻译者对正则表达式有一定了解. 这种翻译放在这一区域: (`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样式来调整.
@ -202,8 +220,12 @@ export const map = new Map([
/* CSS translation here */
]],
]);
export const regex = new Map([
[/(\d+)次播放/, `Played $1 times`],
/* Regex translation here */
]);
export default {
export: { map },
export: { map, regex },
};
```
该文件能够将类似以下的网页内容
@ -217,6 +239,7 @@ export default {
<a class="xxx">其他</a>
<a class="yyy">其他</a>
<a class="zzz">其他</a>
<a>233次播放</a>
```
翻译为
```html
@ -228,5 +251,5 @@ export default {
<a class="ccc">Follow</a>
<a class="xxx">XXX</a>
<a class="yyy">YYY</a>
<a class="zzz">其他</a>
<a>Played 233 times</a>
```

View File

@ -10,6 +10,7 @@ export class Translator
static placeholder: PlaceholderTranslator;
static allTranslators: Translator[];
static map: Map<string, any>;
static regex: [RegExp, string][];
accepts(node: Node) { return node.nodeType === Node.ELEMENT_NODE; }
getValue(node: Node) { return node.nodeValue; }
@ -25,9 +26,14 @@ export class Translator
const translation = Translator.map.get(value.trim());
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);
}
@ -142,8 +148,9 @@ Translator.allTranslators = [Translator.textNode, Translator.title, Translator.p
(async () =>
{
const { map } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
const { map, regex } = await import(`./i18n.${languageCodeMap[settings.i18nLanguage]}`);
Translator.map = map;
Translator.regex = [...regex.entries()];
Translator.translate(document.body);
Translator.translateCssMatches();