您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
辅助编辑E绅士画廊的标签
// ==UserScript== // @name ETTHelper-TagEditer // @name:zh-CN E绅士标签翻译辅助工具-标签编辑 // @namespace EhTagTranslation // @description Help to edit the gallery's tags. // @description:zh-CN 辅助编辑E绅士画廊的标签 // @include *://exhentai.org/g/* // @include *://e-hentai.org/g/* // @version 1.4.6 // @author Mapaler <[email protected]> // @copyright 2019+, Mapaler <[email protected]> // @homepage https://github.com/EhTagTranslation/UserScripts // @supportURL https://github.com/EhTagTranslation/UserScripts/issues // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // ==/UserScript== const scriptVersion = (defaultVersion=>typeof GM_info != "undefined" ? GM_info.script.version.replace(/(^\s*)|(\s*$)/g, "") : defaultVersion)("unknown"); //本程序的版本 const scriptName = (defaultName=>{ if (typeof(GM_info)!="undefined") { if (GM_info.script.name_i18n) { const i18n = navigator.language.replace("-","_"); //获取浏览器语言 return GM_info.script.name_i18n[i18n]; //支持Tampermonkey } else { return GM_info.script.localizedName || //支持Greasemonkey 油猴子 3.x GM_info.script.name; //支持Violentmonkey 暴力猴 } }else { return defaultName; } })("ETTWikiHelper-TagEditer"); //本程序的名称 //限定数值最大最小值 function limitMaxAndMin(num,max,min) { return Math.max(Math.min(num, max), min); } //默认CSS内容 const ewh_tag_styleText_Default = ` /* fallback */ @font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(https://fonts.gstatic.com/s/materialicons/v90/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2'); } .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; word-wrap: normal; direction: ltr; -moz-font-feature-settings: 'liga'; -moz-osx-font-smoothing: grayscale; } #gd4.ewh-float { /*浮动窗体*/ position: fixed; top: 10%; left: 10%; background-color : inherit; margin: 0 !important; padding: 0 !important; border-style: ridge; border-width: 3px; border-color: #eee black black #eee; opacity: 0.8; } .ewh-bar-floatcaption { /*标题栏整体*/ height: 22px; position: relative; } .ewh-cpttext-box { /*标题栏文字框*/ width: 100%; height: 100%; float: left; color: white; line-height: 22px; font-size: 14px; background-image: linear-gradient(to right,#808080,#B7B5BB); } .ewh-float .ewh-cpttext-box { /*浮动时的标题颜色*/ background-image: linear-gradient(to right,#000280,#0F80CD); } .ewh-cpttext-box::before{ /*标题图标*/ content: "🏷️"; } .ewh-cpttext-box span { /*标题文字*/ pointer-events:none; user-select: none; } .ewh-cptbtn-box { /*标题按钮框*/ height: 100%; position: absolute; top: 0; right: 8px; line-height: 22px; } .ewh-cpt-btn { /*平时的按钮*/ vertical-align: middle; padding: 0; font-size: 14px; margin-top:-2px; height: 18px; width: 20px; background-color: #c0c0c0; border-style: outset; border-width: 2px; border-color: white black black white; } .ewh-cpt-rag { /*平时的范围拖动条*/ vertical-align: middle; padding: 0; font-size: 14px; margin-top:0; height: 18px; width: 100px; } .ewh-cpt-btn:active { /*按钮按下时的凹陷*/ background-color: #d8d8d8; padding-left: 1px !important; padding-top: 1px !important; border-style: inset; border-color: black white white black; } .ewh-cpt-btn:focus { /*激活后的虚线*/ outline: dotted 1px black; } .ewh-btn-closefloat,.ewh-rag-opacity { /*平时隐藏关闭浮动的按钮*/ display: none; } .ewh-float .ewh-btn-closefloat,.ewh-float .ewh-rag-opacity { /*浮动时显示关闭浮动的按钮*/ display: unset; } .ewh-float .ewh-btn-openfloat{ /*浮动时隐藏开启浮动的按钮*/ display: none; } .ewh-bar-tagsearch{ position: relative; } .ewh-ipt-tagsearch{ width: 200px; box-sizing: border-box; } .ewh-tagsearchtext,.ewh-tagsearchlink{ font-size: 10pt; } .ewh-bar-tagsearch a::before{ font-size: 10pt; font-weight: bold; } .ewh-bar-tagsearch a::after{ font-size: 10pt; background: #c0c0c0; color:black; border-style: ridge; border-width: 3px; border-color: #eee black black #eee; position:absolute; z-index:999; padding:8px; min-width:150px; max-width:500px; white-space:pre-wrap; opacity: 0; transition: opacity 0.1s; top:28px; left:45%; pointer-events:none; font-weight: 400; line-height: 20px; } .ewh-bar-tagsearch a:hover::after{ opacity: 1; } `; //获取Tag编辑区 var ewhWindow = document.querySelector("#gd4"); //增加浮动窗标题栏 var divCaptionBar = ewhWindow.insertBefore(document.createElement("div"),gd4.firstChild); divCaptionBar.className = "ewh-bar-floatcaption"; //生成辅助器CSS var ewh_tag_style = divCaptionBar.appendChild(document.createElement("style")); ewh_tag_style.type = "text/css"; ewh_tag_style.appendChild(document.createTextNode(ewh_tag_styleText_Default)); //生成标题栏文字 var divCaption = divCaptionBar.appendChild(document.createElement("div")); divCaption.className = "ewh-cpttext-box"; divCaption.appendChild(document.createElement("span")).appendChild(document.createTextNode(scriptName)); //添加窗体鼠标拖拽移动 var windowPosition = ewhWindow.position = [0, 0]; //[X,Y] 用以储存窗体开始拖动时的鼠标相对窗口坐标差值。 divCaption.addEventListener("mousedown", function(e) { //按下鼠标则添加移动事件 if (!ewhWindow.classList.contains("ewh-float")) return; //如果不是浮动窗体直接结束 var eX = limitMaxAndMin(e.clientX,document.documentElement.clientWidth,0), eY = limitMaxAndMin(e.clientY,document.documentElement.clientHeight,0); //不允许鼠标超出网页。 windowPosition[0] = eX - ewhWindow.offsetLeft; windowPosition[1] = eY - ewhWindow.offsetTop; var handler_mousemove = function(e) { //移动鼠标则修改窗体坐标 var eX = limitMaxAndMin(e.clientX,document.documentElement.clientWidth,0), eY = limitMaxAndMin(e.clientY,document.documentElement.clientHeight,0); //不允许鼠标超出网页。 ewhWindow.style.left = (eX - windowPosition[0]) + 'px'; ewhWindow.style.top = (eY - windowPosition[1]) + 'px'; }; var handler_mouseup = function(e) { //抬起鼠标则取消移动事件 document.removeEventListener("mousemove", handler_mousemove); if (ewhWindow.style.left) GM_setValue("floatwindow-left",ewhWindow.style.left); //储存窗体位置 if (ewhWindow.style.top) GM_setValue("floatwindow-top",ewhWindow.style.top); //储存窗体位置 }; document.addEventListener("mousemove", handler_mousemove); document.addEventListener("mouseup", handler_mouseup, { once: true }); }); //生成标题栏按钮 var divButtonBox = divCaptionBar.appendChild(document.createElement("div")); divButtonBox.className = "ewh-cptbtn-box"; //生成修改设置的按钮 var ragOpacity = divButtonBox.appendChild(document.createElement("input")); ragOpacity.className = "ewh-cpt-rag ewh-rag-opacity"; ragOpacity.type = "range"; ragOpacity.max = 1; ragOpacity.min = 0.5; ragOpacity.step = 0.01; ragOpacity.title = "窗体不透明度"; ragOpacity.onchange = ragOpacity.oninput = function(){ ewhWindow.style.opacity = this.value; }; ragOpacity.onchange = function(){ ragOpacity.oninput(); if (ewhWindow.style.opacity) GM_setValue("floatwindow-opacity",ewhWindow.style.opacity); //储存窗体透明度 }; //生成打开浮动状态的按钮 var btnOpenFloat = divButtonBox.appendChild(document.createElement("button")); btnOpenFloat.className = "ewh-cpt-btn material-icons ewh-btn-openfloat"; btnOpenFloat.title = "浮动标签编辑框"; btnOpenFloat.appendChild(document.createElement("span").appendChild(document.createTextNode("open_in_new"))); btnOpenFloat.onclick = function(){ //ewhWindow.setAttribute("style",ewhWindow.getAttribute("style_bak")); //ewhWindow.removeAttribute("style_bak"); ewhWindow.classList.add("ewh-float"); ewhWindow.style.left = GM_getValue("floatwindow-left"); ewhWindow.style.top = GM_getValue("floatwindow-top"); ewhWindow.style.opacity = ragOpacity.value = GM_getValue("floatwindow-opacity") || 0.8; }; GM_registerMenuCommand("打开浮动标签编辑框", btnOpenFloat.onclick); //生成关闭浮动状态的按钮 var btnCloseFloat = divButtonBox.appendChild(document.createElement("button")); btnCloseFloat.className = "ewh-cpt-btn material-icons ewh-btn-closefloat"; btnCloseFloat.title = "关闭浮动窗体"; btnCloseFloat.appendChild(document.createElement("span").appendChild(document.createTextNode("close"))); btnCloseFloat.onclick = function(){ //ewhWindow.setAttribute("style_bak",ewhWindow.getAttribute("style")); if (ewhWindow.style.left) GM_setValue("floatwindow-left",ewhWindow.style.left); //储存窗体位置 if (ewhWindow.style.top) GM_setValue("floatwindow-top",ewhWindow.style.top); //储存窗体位置 if (ewhWindow.style.opacity) GM_setValue("floatwindow-opacity",ewhWindow.style.opacity); //储存窗体透明度 ewhWindow.removeAttribute("style"); ewhWindow.classList.remove("ewh-float"); }; GM_registerMenuCommand("重置浮动窗位置与透明度", function(){ btnCloseFloat.onclick(); //先关掉窗体,然后删除设置 GM_deleteValue("floatwindow-left"); GM_deleteValue("floatwindow-top"); GM_deleteValue("floatwindow-opacity"); }); var nameSpaceC = { artist:"艺术家", female:"女性", male:"男性", parody:"原作", character:"角色", group:"团队", language:"语言", reclass:"重新分类", misc:"杂项" }; //获取标签数据列表 var tagdatalist = document.querySelector("#tbs-tags"); var tagData; //获取真实标签输入框 var newTagText = document.querySelector("#newtagfield"); if (!tagdatalist) //没有ETS,但有ETS扩展版的处理方式 { var tagDataStr = localStorage.getItem("EhSyringe.tag-list"); //ETS扩展版1.2.1的数据 if (typeof(tagDataStr) == "string") { tagData = JSON.parse(tagDataStr); tagdatalist = document.createElement("datalist"); tagdatalist.id = "tbs-tags"; newTagText.setAttribute("list","tbs-tags"); tagData.forEach(function(tag){ tagdatalist.appendChild(new Option(nameSpaceC[tag.namespace]+":"+tag.name,tag.search)); }) newTagText.insertAdjacentElement('afterend',tagdatalist); } } if (tagdatalist) //如果存在则生成标签搜索框 { var taglist = tagdatalist.options; //增加标签搜索框箱子 var divSearchBar = ewhWindow.insertBefore(document.createElement("div"),document.querySelector("#tagmenu_act")); divSearchBar.className = "ewh-bar-tagsearch"; //增加标签搜索框 var iptTagSearch = divSearchBar.appendChild(document.createElement("input")); iptTagSearch.type = "text"; iptTagSearch.placeholder = "🔍标签搜索:回车附加到下方▼"; iptTagSearch.setAttribute("list","tbs-tags"); iptTagSearch.className="ewh-ipt-tagsearch"; //增加标签搜索提醒文字 var spnTagSearchInfo = divSearchBar.appendChild(document.createElement("span")); spnTagSearchInfo.className="ewh-tagsearchtext"; //增加标签搜索提醒标签 var aTagSearchInfo = divSearchBar.appendChild(document.createElement("a")); aTagSearchInfo.className="ewh-tagsearchlink"; iptTagSearch.onkeypress = function(e){ if(e.key == "Enter"){ //回车,将内容附加到真实Tag框,并清空搜索框 var _this = this; if (_this.value.length == 0) { //如果什么都没输入,相当于提交 spnTagSearchInfo.innerHTML = ""; aTagSearchInfo.removeAttribute("id"); aTagSearchInfo.innerHTML = ""; if (newTagText.value.length > 0)tag_from_field(); //如果输入框有内容点击Tag提交 return; }; var clabel = false, useGuess = false, guess = false; var tagC; if (tagData) //如果有JSON数据,直接使用 { //扩展版的JSON数据 var searchRes = tagData.filter(function(tag){ //搜索绝对等于的 return tag.search == _this.value; }); if (searchRes.length<1) { //猜测式搜索 searchRes = tagData.filter(function(tag){ return tag.name.indexOf(_this.value)>=0 || tag.key.indexOf(_this.value)>=0; //有非tag字符时才搜索中文,其他时候搜索key }); if (searchRes.length>0) { guess = true; //标记为猜的 _this.value = searchRes[0].search; //目前的输入修改为猜的tag } } if (searchRes.length>0) { tagC = searchRes[0]; clabel = tagC.name; } }else { //脚本版的数据 if (_this.value.replace(/[\w\:\"\s\-\.\'\$]/,"").length>0) useGuess = true; //如果存在非tag字符,则尝试搜索中文。 for (var ti=0;ti<taglist.length;ti++) { //循环搜索列表中是否已存在这个Tag if (taglist[ti].value == _this.value) { clabel = taglist[ti].label; break; }else if(useGuess && taglist[ti].label.indexOf(_this.value)>0) { clabel = taglist[ti].label; guess = true; //标记为猜的 _this.value = taglist[ti].value; //目前的输入修改为猜的tag break; } } } if (clabel) { var shortTag; if (tagData) { //扩展版的JSON数据 shortTag = (tagC.namespace=="misc"?"":(tagC.namespace.substr(0,1) + ":")) + tagC.key; //缩减Tag长度,以便一次能多提交一些Tag }else { //脚本版的数据 var regArr = /^(\w+):"?([\w+\s\-\'\.]+)\$?"?$/ig.exec(_this.value); shortTag = (regArr[1]=="misc"?"":(regArr[1].substr(0,1) + ":")) + regArr[2]; //缩减Tag长度,以便一次能多提交一些Tag } if ((newTagText.value+","+shortTag).length>200) { spnTagSearchInfo.innerHTML = "⛔超长(原始标签输入框限定200字符)"; if (!tagData) aTagSearchInfo.removeAttribute("id"); aTagSearchInfo.innerHTML = ""; }else { newTagText.value = (newTagText.value.length>0)?(newTagText.value+","+shortTag):shortTag; spnTagSearchInfo.innerHTML = (guess?"程序猜测你想添加":"你添加了")+" " + (tagData?nameSpaceC[tagC.namespace]:clabel.split(":")[0]) + ":"; if (!tagData) aTagSearchInfo.id = "ta_" + (regArr[1]=="misc"?"":regArr[1]+":") + regArr[2].replace(/\s/igm,"_"); aTagSearchInfo.innerHTML = clabel; _this.value = ""; } }else { spnTagSearchInfo.innerHTML = "☹️数据库里没有这个标签"; if (!tagData) aTagSearchInfo.removeAttribute("id"); aTagSearchInfo.innerHTML = ""; } } }; }