// ==UserScript== // @name 不翻译英文网站上的代码 // @namespace http://codeexpander.com/ // @version 1.0.3 // @description 避免google网页翻译任何英文站点中的代码, 持续更新 // @author xudaolong // @license MIT // @match http://*/* // @include https://*/* // @downloadURL https://update.greasyfork.icu/scripts/394305/%E4%B8%8D%E7%BF%BB%E8%AF%91%E8%8B%B1%E6%96%87%E7%BD%91%E7%AB%99%E4%B8%8A%E7%9A%84%E4%BB%A3%E7%A0%81.user.js // @updateURL https://update.greasyfork.icu/scripts/394305/%E4%B8%8D%E7%BF%BB%E8%AF%91%E8%8B%B1%E6%96%87%E7%BD%91%E7%AB%99%E4%B8%8A%E7%9A%84%E4%BB%A3%E7%A0%81.meta.js // ==/UserScript== /* jshint esversion: 6 */ ;(function () { 'use strict' // debug log const isDev = false const log = (...args) => { isDev && console.log(args) } const style = 'font-size: inherit;' const addCodeEle = function (ele) { ele.innerHTML = '' + ele.innerHTML + '' } const addCodeEleNoColor = function (ele) { ele.innerHTML = '' + String(ele.innerHTML).trim() + '' } const addCodeEleWithTextNoColor = function (ele) { var txt=document.createElement("span"); txt.innerHTML= `${ele.innerHTML}`; ele.innerHTML = `${ele.innerHTML}` if(ele.nextSibling){ ele.parentNode.insertBefore(txt, ele.nextSibling); }else{ ele.parentNode.appendChild(txt); } } const hasCodeEleChild = function (ele) { return !!ele.querySelector('code') } const addPreEle = function (ele) { ele.innerHTML = `
${
      ele.innerHTML
    }
` } const hasPreEleChild = function (ele) { return !!ele.querySelector('code') } const _ = {} _.debounce = function (func, wait) { var lastCallTime var lastThis var lastArgs var timerId function startTimer (timerExpired, wait) { return setTimeout(timerExpired, wait) } function remainingWait (time) { const timeSinceLastCall = time - lastCallTime const timeWaiting = wait - timeSinceLastCall return timeWaiting } function shoudInvoking (time) { return lastCallTime !== undefined && time - lastCallTime >= wait } function timerExpired () { const time = Date.now() if (shoudInvoking(time)) { return invokeFunc() } timerId = startTimer(timerExpired, remainingWait(time)) } function invokeFunc () { timerId = undefined const args = lastArgs const thisArg = lastThis let result = func.apply(thisArg, args) lastArgs = lastThis = undefined return result } function debounced (...args) { let time = Date.now() lastThis = this lastArgs = args lastCallTime = time if (timerId === undefined) { timerId = startTimer(timerExpired, wait) } } return debounced } // 不要翻译文件名与目录 const doNotTranslateFilenamesAndDirectories = () => { const fileAndDirectory = document.querySelectorAll( '.file-wrap .js-navigation-item .js-navigation-open' ) ;[...fileAndDirectory].forEach(item => { if (!hasPreEleChild(item)) { addCodeEleNoColor(item) } }) } // 不要翻译代码内容页 const doNotTranslateCodeContentPages = () => { const codeContainer = document.querySelector('.js-file-line-container') if (codeContainer) { const main = document.querySelector('main') if (main.parentNode.nodeName !== 'CODE') { main.parentNode.innerHTML = `${main.parentNode.innerHTML}` } } } // 不要翻译标题 const doNotTranslateTitle = () => { ;['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'strong'].forEach(item => { const itemEle = document.querySelectorAll(item) // 没找到就退出 if (!itemEle) return false ;[...itemEle].forEach(el => { // 如果是 issues 标题就退出 if (el.classList.contains('gh-header-title')) return false if (!hasCodeEleChild(el)) { addCodeEleNoColor(el) } }) }) ///** ;['li a', 'p a'].forEach(item => { const itemEle = document.querySelectorAll(item) // 没找到就退出 if (!itemEle) return false ;[...itemEle].forEach(el => { // 如果是 issues 标题就退出 if (el.classList.contains('gh-header-title')) return false if (!hasCodeEleChild(el)) { addCodeEleNoColor(el) } }) }) //**/ } // 不要翻译代码 const doNotTranslateCode = () => { const files = document.querySelectorAll('.file') const pres = document.querySelectorAll('pre') if (files.length > 0) { if (window.location.href.search(/.md/i) !== -1) { if (pres.length > 0) { pres.forEach(function (pre) { if (!hasCodeEleChild(pre)) addCodeEle(pre) }) } } else { files.forEach(function (file) { if (!hasCodeEleChild(file)) addCodeEle(file) }) } } else if (pres.length > 0) { pres.forEach(function (pre) { if (!hasCodeEleChild(pre)) addCodeEle(pre) }) } } const option = { childList: true, subtree: true } let time = 0 const initObserve = (observer) => { observer.observe(document.querySelector('body'), option) } const doNotTranslate = function (mutations, observer) { // 处于过于频繁的 DOM 变更时, 暂停监听 50ms, 并放弃累积的未处理的变更事件 if (time >= 20) { observer.disconnect() observer.takeRecords() time = 0 setTimeout(function () { initObserve() }, 50) } // 不要翻译文件名与目录 doNotTranslateFilenamesAndDirectories() // 不要翻译代码内容页 doNotTranslateCodeContentPages() // 不要翻译代码 doNotTranslateCode() // 不要翻译标题 doNotTranslateTitle() time++ log(`第${time}次执行: doNotTranslate`) } const noZhPage = () => { return ['zh-CN'].includes(document.getElementsByTagName('html')[0].lang) || /.*[\u4e00-\u9fa5]+.*$/.test((document.head.querySelector("title") || {}).text) } if(noZhPage()) return const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver const mo = new MutationObserver(_.debounce(doNotTranslate, 50)) initObserve(mo) })()