- // ==UserScript==
- // @name HV简称替换为中文
- // @namespace http://tampermonkey.net/
- // @version 1.0.2
- // @description 受不了简称了
- // @author aotmd
- // @match https://forums.e-hentai.org/index.php?showtopic=*
- // @match https://ehwiki.org/wiki/Acronyms/Chinese
- // @noframes
- // @license MIT
- // @run-at document-body
- // @grant none
- // ==/UserScript==
- //简称来源:https://ehwiki.org/wiki/Acronyms/Chinese
- /*生成脚本:
- let a=document.querySelectorAll("#mw-content-text > div > table > tbody > tr")
- let s="";
- for ( let i = 0; i < a.length; i++ ) {
- s+="\'"+a[i].children[0].innerText+"\'"+":\'"+a[i].children[2].innerText+"\',\n"
- }
- */
- /*
- 参见:https://forums.e-hentai.org/index.php?showtopic=189266
- 参见:https://forums.e-hentai.org/index.php?showtopic=256084&st=0&p=6092109&#entry6092109
- 参见:https://ehwiki.org/wiki/Acronyms/Chinese
- */
- ( function() {
- let map = {
- '10B': 'T氏、天妇罗、菠萝、大菠萝',
- '1H': '单手武器/战斗风格:单手',
- '2H': '双手武器/战斗风格:双手',
- 'AAB': '攻击准确度奖励:这边指的是物理性质',
- 'AB': '训练:技能推广',
- 'ADB': '攻击伤害奖励',
- 'AF': '咒语:奥术集成',
- 'AGI': '主要属性奖励:敏捷',
- 'AL': '训练:善于学习者',
- 'AoE': '范围效果',
- 'AP': '技能点',
- 'Arch': '潜能:大法师',
- 'AS': '行动速度',
- 'B': '负重',
- 'Bur':'负重',
- 'BC': '后缀:战法师',
- 'BoD': '黏合剂:毁灭',
- 'BoP': '黏合剂:守护',
- 'BoS': '黏合剂:杀戮',
- 'But': '潜能:屠夫',
- 'BW': '特效:流血',
- 'C': '绅士幣',
- 'Cap': '潜能:魔力电容',
- 'CM': '特效:魔力合流',
- 'CoD': '货到付款',
- 'CR': '罕见素材:Crystallized Phazon',
- 'DEX': '主要属性奖励:灵巧',
- 'DMM': '罕见素材:Defense Matrix Modulator',
- 'DNP': '请勿张贴',
- 'DOT': '持续伤害',
- 'DW': '战斗风格:双持',
- 'DwD': '竞技场:与龙共舞/与龙共舞的敌人',
- 'DX': '解剔除',
- 'Eco': '潜能:节能装置',
- 'ED': '能量饮料/有效伤害/竞技场:永恆的黑暗',
- 'EDB': '元素伤害奖励',
- 'EH': 'E变态',
- 'E-H': 'E变态',
- 'EHG': 'E变态图库',
- 'EHP': '有效生命值',
- 'EHT': 'E变态BT伺服器',
- 'Ele': '元素类型前缀',
- 'Emax': '精致装备上某数值的顶点。',
- 'Exmax': '精致装备上某数值的顶点。',
- 'END': '主要属性奖励:体质',
- 'EoD': '竞技场:世界末日/竞技场:死亡前夕',
- 'ET': '特效:以太水龙头',
- 'Eth': '前缀:空灵',
- 'EW': '后缀:地行者',
- 'EXP': '经验值',
- 'Exq': '品质:精致',
- 'Fat': '潜能:致命性',
- 'FB': '技巧:狂乱百裂斩',
- 'FoS': '额外能力:雪花的信徒',
- 'FRD': '技巧:龙吼',
- 'FSM': '敌人:飞行义大利面怪物',
- 'GF': '压榨界',
- 'GLT': '黄金彩券',
- 'GP': '图库点数',
- 'GS': '金星',
- 'GSC': '金星俱乐部',
- 'H': 'Hath',
- 'H@H': 'Hentai@Home',
- 'Hellfest': '地狱榨:地狱难度的压榨界',
- 'HG': '高阶素材',
- 'HGC': '高阶布料素材',
- 'HGL': '高阶皮革素材',
- 'HGM': '高阶金属素材',
- 'HGW': '高阶木材素材',
- 'HP': '生命值',
- 'HS': '咒语:穿心',
- 'HV': '变态之道:呼应我要成为大变态',
- 'Hverse': '变态之道:呼应我要成为大变态',
- 'I': '干扰',
- 'Int':'干扰',
- 'IA': '额外能力:天赋奥术',
- 'INT': '主要属性奖励:智力',
- 'IPU': '敌人:隐形粉红独角兽',
- 'ISB': '道具店机器人',
- 'IW': '道具界',
- 'IWBTH': '难易度:我要成为大变态',
- 'Jug': '潜能:重装盔甲',
- 'LE': '终极万能药',
- 'Leg': '品质:传奇',
- 'LG': '低阶素材',
- 'Lmax': '传奇装备上某数值的顶点。',
- 'LotD': '训练:抽签运',
- 'MAB': '魔法准确度奖励',
- 'Mag': '品质:华丽',
- 'Mat': '素材',
- 'MDB': '魔法伤害奖励',
- 'Mit': '伤缓',
- 'MG': '中阶素材',
- 'ML': '怪物实验室',
- 'MM': '莫古利邮务',
- 'Mmax': '华丽装备上某数值的顶点。',
- 'MMI': '魔法缓伤:缓伤意思就像缓冲,让伤害值踩煞车,所以此数值无法达到 100%',
- 'MMit': '魔法缓伤:缓伤意思就像缓冲,让伤害值踩煞车,所以此数值无法达到 100%',
- 'MP': '魔力值',
- 'MPB': '魔法熟练度奖励',
- 'MPV': '多页阅读器',
- 'NS': '命名空间',
- 'OC': '斗气:以前翻作怒气,但西方人应该比较熟悉斗气吧',
- 'OFC': '技巧:友情小马砲',
- 'PA': '特效:破甲',
- 'PAB': '主要属性奖励',
- 'PB': '回本',
- 'RE': '随机遭遇',
- 'Pen': '潜能:渗透',
- 'PFUDOR': '难易度:粉红毛毛独角兽在彩虹上头舞动',
- 'PL': '战斗力',
- 'PM': '私人讯息',
- 'PMI': '物理缓伤',
- 'PMit':'物理缓伤',
- 'PXP': '潜经验:难得中文也能取字首,自认为念起来还颇顺口的',
- 'QM': '训练:军需官',
- 'RA': '罕见素材:Repurposed Actuator',
- 'RL': '敌人:现实生活',
- 'RNG': '随机数发生器',
- 'RoB': '浴血擂台',
- 'ROI': '投资报酬率',
- 'RP': '角色扮演 (论坛,避免使用)/真人色情 (在剔除日志里用简写)',
- 'SD': '后缀:影舞者',
- 'SF': '罕见素材:Shade Fragment',
- 'SG': '敌人:女高中生',
- 'Smax': '优秀装备上某数值的顶点。',
- 'SoL': '咒语:生命火花',
- 'SP': '灵力值',
- 'SS': '灵动架式/咒语:灵力盾',
- 'STR': '主要属性奖励:力量',
- 'SV': '咒语:影纱',
- 't/s': '每秒刷数',
- 'TpS': '每秒刷数',
- 'T&T': '竞技场:命运三女神与树/命运三女神与树的敌人',
- 'TT': '竞技场:命运三女神与树/命运三女神与树的敌人',
- 'ToB': '血令牌',
- 'ToS': '服务条款',
- 'TT&T': '浴血擂台:九死一树',
- 'TTT': '浴血擂台:九死一树',
- 'WIS': '主要属性奖励:感知',
- 'WTB': '愿意购买',
- 'WTS': '愿意卖出',
- 'WTT': '愿意交换',
- /*自定义部分:*/
- 'CS':'施法速度',
- 'Prof':'熟练度加成',
- 'PF':'熟练度系数',
- 'Evade':'回避',
- 'Resist':'抵抗',
-
- }
- const 递归 = ( function 闭包() {
- /**
- * 递归处理到每个节点
- * @param el 要处理的节点
- * @param func 调用的函数
- */
- function 主控( el, func ) {
- const nodeList = el.childNodes;
- /*先处理自己*/
- 统一处理( el, false, func );
- for ( let i = 0; i < nodeList.length; i++ ) {
- const node = nodeList[ i ];
- 统一处理( node, true, func );
- }
- }
-
- /**
- * 捕获指定节点,属性和属性内容,并执行指定函数.
- * @param el 要处理的节点
- * @param recursion 是否递归
- * @param func 调用的函数
- */
- function 统一处理( el, recursion, func ) {
- if ( el.nodeType === 1 ) {
- //为元素则递归
- if ( recursion ) {
- 主控( el, func );
- }
- } else if ( el.nodeType === 3 ) {
- if ( !el.nodeValue || !el.nodeValue.length ) return;
- //为文本节点则处理数据
- func( el, 'Text', el.nodeValue );
- }
- }
-
- return 主控;
- } )();
-
- if ( typeof observerMap === 'undefined' ) observerMap = new Map();
- /**
- * 修改后的函数,在触发事件后会对其他相同config的obs排队依次触发,节流10并去重大大提升性能.
- * dom修改事件,包括属性,内容,节点修改
- * @param document 侦听对象
- * @param func 执行函数,可选参数(records),表示更改的节点
- * @param config 侦听的配置
- */
- function dom修改事件( document, func, config = {
- attributes: true,
- childList: true,
- characterData: true,
- subtree: true
- } ) {
- const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
- //将配置对象序列化为字符串,做为key.
- const serializedConfig = JSON.stringify( Object.entries( config ).sort() );
- let throttleTimeout;
- let recordsArr = [];
- const observer = new MutationObserver( function( records ) {
- clearTimeout( throttleTimeout );
- // 记录变化
- recordsArr.push( ...records );
- throttleTimeout = setTimeout( () => {
- // 从recordedMutations数组中移除重复项
- recordsArr = removeDuplicates( recordsArr );
- let observers = observerMap.get( serializedConfig ) || [];
- // 在每次变化前暂停相同 config 的所有观察器实例
- observers.forEach( obs => obs.observer.disconnect() );
- // 对拥有相同观察器实例的文档执行各自的函数
- observers.forEach( obs => {
- try {
- obs.func( recordsArr );
- } catch ( e ) {
- console.error( e );
- }
- } );
- // 在执行完毕后重新启用相同 config 的所有观察器实例
- observers.forEach( obs => obs.observer.observe( document, config ) );
- // 清空记录的修改
- recordsArr = [];
- }, 10 );
- } );
-
- // 将观察器实例和对应的函数添加到对应 config 的数组中
- let observers = observerMap.get( serializedConfig ) || [];
- observers.push( {
- observer,
- func
- } );
- observerMap.set( serializedConfig, observers );
-
- // 开启侦听
- observer.observe( document, config );
- /**
- * 从后面开始去重,并保留靠后的元素.
- * @param arr
- * @returns {*}
- */
- function removeDuplicates( arr ) {
- return arr.reduceRight( ( unique, item ) => {
- // 检查当前元素是否已存在于结果数组中,如果不存在,则将其添加到数组中
- if ( !unique.some( i => (
- i.type === item.type &&
- i.target === item.target &&
- i.attributeName === item.attributeName
- ) ) ) {
- unique.push( item ); // 将不重复的元素添加到结果数组中
- }
- return unique;
- }, [] );
- }
- }
-
-
- /*当body发生变化时执行*/
- dom修改事件( document.body, ( records ) => {
- console.time( '替换,时间' );
- for ( let i = 0, len = records.length; i < len; i++ ) {
- 递归( records[ i ].target, 替换 );
- }
- console.timeEnd( '替换,时间' );
- } );
-
- addStyle( `
- ruby {
- text-indent: 0px;
- }
- ruby > rt {
- display: block;
- font-size: 50%;
- text-align: start;
- }
- rt {
- text-indent: 0px;
- line-height: normal;
- -webkit-text-emphasis: none;
- }
- ` );
-
- function 替换( node, attribute, value ) {
- value = value.trim();
- if ( attribute == 'Text' ) {
- if ( node.parentNode.nodeName == 'RT' || node.parentNode.nodeName == 'RUBY' ) {
- return;
- }
- }
- let text = value;
-
- // 遍历映射表进行替换
- for ( let abbr in map ) {
- let regex = new RegExp( `\\b${abbr}\\b`, 'g' ); // 精确匹配简写
- if ( regex.test( text ) ) {
- // 使用ruby标签替换简写
- text = text.replace( regex, `<ruby>${map[abbr]}<rt>${abbr}</rt></ruby>` );
- }
- }
-
- // 创建一个包含替换后的HTML的新节点
- let span = document.createElement( 'span' );
- span.innerHTML = text;
-
- // 替换原有的文本节点
- node.parentNode.replaceChild( span, node );
- }
- //添加css样式
- function addStyle( rules ) {
- let styleElement = document.createElement( 'style' );
- styleElement[ "type" ] = 'text/css';
- document.getElementsByTagName( 'head' )[ 0 ].appendChild( styleElement );
- styleElement.appendChild( document.createTextNode( rules ) );
- }
- } )();