// ==UserScript== // @name Pixiv 辅助翻译 // @namespace https://greasyfork.org/users/159546 // @version 1.1.7 // @description 现已支持标签TAG、作品详情页对标题和说明,以及评论区翻译! // @author LEORChn // @include *://www.pixiv.net/* // @run-at document-start // @grant GM_xmlhttpRequest // @connect translate.google.cn // @downloadURL https://update.greasyfork.icu/scripts/372551/Pixiv%20%E8%BE%85%E5%8A%A9%E7%BF%BB%E8%AF%91.user.js // @updateURL https://update.greasyfork.icu/scripts/372551/Pixiv%20%E8%BE%85%E5%8A%A9%E7%BF%BB%E8%AF%91.meta.js // ==/UserScript== var tag_trans=[ // 图型类 '漫画','漫画', 'うごイラ','动图', '厚塗り','多层上色', 'オリジナル','原创', // 角色类型类 'UTAU獣人','兽人虚拟歌手', 'ケモノ','野兽', 'wolf','狼', 'オオカミ','狼', 'ハスキー','哈士奇', 'kemono','毛怪', 'furry','兽人', '獣人','兽人', // 这个是日文的 '獸人','兽人', // 这个是繁体的 'オスケモ','雄兽', 'デブケモ','胖兽', 'ケモホモ','兽人同性向', 'ケモ交尾','兽性', // 作品名称类 '東京放課後サモナーズ','东京放课后召唤师', // 我在2018年9月初玩过,几号来着忘了 '放サモ','东放', 'housamo','东放', 'あらしのよるに','翡翠森林狼与羊(暴风雨之夜)', // 我在2019年3月初左右观看完了这个动画 'ひみつのともだち','秘密的朋友', 'ゼロから始める魔法の書','从零开始的魔法书', // 我在2019年5月8日14时观看完了这个动画,17时35分开始观看第12话,17时58分观看完毕撒花 // 人物名称类 '狼音アロ','狼音阿罗', 'モリタカ','犬塚戍孝', '犬塚モリタカ','犬塚戍孝', 'ホロケウカムイ','狼神神威', //ID为 20880639 的作者似乎打错了这个标签所以替换不到 'テムジン','铁木真', 'ガルム','加姆', 'ノーマッド(放サモ)','诺曼德(东放)', // 东京放课后里的虎兽人所用的化名 '主5','5号主人公(东放)', '獣の傭兵','佣兵(零书)', // 着装类 'ふんどし','兜裆布', '褌','兜裆布', 'ラバースーツ','橡胶紧身衣', '靴下','袜子', // 器官类 '腹筋','腹肌', 'ㄋㄟㄋㄟ','胸部', // 行为类 '金的','捣蛋', '猿轡','封口', '目隠し','蒙眼', '拘束','捆绑Play' ]; (function(){ recheck(); })(); function recheck(){ init(); if(load())return; setTimeout(recheck,100); } function init(){ // call once when start loading page if(ft('body').length==0) return; main_daemon(); //inited=true; // } function load(){ // call once when loaded page if(document.readyState.toLowerCase()=='complete'){ main_daemon();// write code here return true; } } var daemonLauncher; function main_daemon(){ if(daemonLauncher) return; daemonLauncher = setInterval(main_do, 3000); main_do(); } function main_do(){ tagTranslate_illust(); // 个人空间 > 作品列表页面 - 标签 tagTranslate_illust_single(); // 作品页面 - 标签 tagTranslate_bookmark(); // 个人空间 > 我的收藏页面 - 标签 tagTranslate_addBookmark(); // 作品页面 > 编辑心页面 - 添加收藏时的可选择标签 tagTranslate_member_tag_all(); // 个人空间 - 所有绘制的作品包含的标签(包含频率降序) detailTranslate_illust(); // 作品页面 - 自动翻译作品标题和简介 button_trans_comment(); // 作品页面 - 添加评论翻译的按钮 unblock_popular_illust_overlay(); // 搜索页面 - 有作品在“查看更多「xxx」的热门作品”面板的下方,点击该面板提示开通会员,用这个隐藏会员面板 popup_popular_order(); // 【预想】搜索页面 - 突破会员限制 delete_illust_expanded_ad(); // 作品页面 - 在展开多页作品后最底部会出现广告,删除它以节省滚动操作 } // ========== 功能性 function unblock_popular_illust_overlay(){ // 搜索页面 热门作品提示 var v = $$('.popular-introduction-overlay'); for(var i=0; iul>li'); if(tags.length==0)return; for(var li=0;li1) c[1].remove(); } } } // ----- 作品页标题和说明 以下 var ID_TRANSLATION_SOURCE='leorchn_icon_google_translate', ICON_TRANSLATION_SOURCE='https://translate.google.cn/favicon.ico', ID_TRANSLATED_TITLE = 'leorchn_translated_title', ID_TRANSLATED_DESC = 'leorchn_translated_desc', block_detail_root; function detailTranslate_illust(){ if(!location.pathname.startsWith('/artworks/')) return; // if(!location.href.includes('mode=medium')) return; var detail_block_post_time = $('figcaption div[title]'); if(!detail_block_post_time) return; block_detail_root = detail_block_post_time.parentElement; if(!fv(ID_TRANSLATION_SOURCE)){ var img=ct('img'); img.id=ID_TRANSLATION_SOURCE; img.src=ICON_TRANSLATION_SOURCE; img.style.cssText='width:24px; float:right'; block_detail_root.insertBefore(img, block_detail_root.children[0]); } trans_title(); trans_desc(); } function trans_title(){ // 作品标题 var p=$('figcaption div>h1'), d=fv(ID_TRANSLATED_TITLE); if(!p) return; if(d){ if(d.title == d.innerText){ // 标题块中缓存的原文与自身内容一致,表示翻译完成但与原文一致或无法翻译 p.style.backgroundColor='#c0e0ff'; // 译文等于原文自身,给原文块加蓝底表示无需翻译 d.style.display='none'; } if(d.title == p.innerText) return; // 标题块中缓存的与原文一致,表示页面没有变化,取消翻译 p.style.backgroundColor=''; // 页面有变化,如果修改过蓝底的就重置它 d.parentElement.remove(); d = undefined; } /* 要解释为什么不能在这两个if之间用else连起来,先看看进入下一个if的两种情况: 1.新建页面,没有找到翻译块 2.页面更改,并进入了上一个if。并且没有触碰到return,导致d被设为undefined 很明显,2号情况决定了这俩if不能用else连起来 */ if(!d){ // 因为标题块没有双层嵌套,二次读取会导致缓存文字块被误翻译 var q = ct('h1'); d = trans_create_block(''); q.className = p.className; d.id=ID_TRANSLATED_TITLE; d.title=p.innerText; // 标题块中缓存原文 q.appendChild(d); p.parentElement.insertBefore(q, p.nextElementSibling); } googleTranslateProxy(p.innerText, fv(ID_TRANSLATED_TITLE), trans_title); } function trans_desc(){ // 作品描述 var p=$('figcaption div>h1+div>div'), d=fv(ID_TRANSLATED_DESC); if(!p) return; if(d){ if(p.innerText.replace(/\s/g,'') == d.innerText.replace(/\s/g,'')){ // 标题块中缓存的原文与自身内容一致,表示翻译完成但与原文一致或无法翻译 p.style.backgroundColor='#c0e0ff'; // 译文等于原文自身,给原文块加蓝底表示无需翻译 d.style.display='none'; } if(d.title == p.innerText) return; // 标题块中缓存的与原文一致,表示页面没有变化,取消翻译 p.style.backgroundColor=''; // 页面有变化,如果修改过蓝底的就重置它 d.remove(); d = undefined; } // 这里还用复制一遍解释么,标题块那个方法里有过了 if(!d){ d = trans_create_block('') d.id=ID_TRANSLATED_DESC; d.title=p.innerText; // 标题块中缓存原文 p.parentElement.appendChild(d); } googleTranslateProxy(p.innerText.replace(/\n/g, CRLF), fv(ID_TRANSLATED_DESC), trans_desc); } // ----- 评论区翻译按钮 以下 var ID_COMMENT_TRANSLATE_TRIGGER = 'leorchn_comment_translate_trigger', ID_COMMENT_TRANSLATION_BLOCK = 'leorchn_comment_translation_block'; function button_trans_comment(){ var p=$$('main section li div>span+span+span'); for(var i=0;inav+div>div>div>ul>li'); if(tags.length==0)return; for(var li=0;li 4500){ postTo.style.display = 'none'; } googleTranslate(origText, function(r){ if(!r.responseText || r.responseText.length<20) if(googleTranslateProxy(origText, postTo) || true) return; trans_create_block(r.responseText, postTo); if(postTo.style.display == 'none') postTo.style.display = ''; // 已翻译完成,取消隐藏(如果之前觉得这个翻译块没有翻译成功的希望并被隐藏的话) if(invokeWhenFinish) try{ invokeWhenFinish(); }catch(e){} }); } function googleTranslate_get(origin){ return new RegExp('(.*)<\\/div>