避免google网页翻译github站点中的代码
// ==UserScript==
// @name 不要翻译github上的代码
// @namespace http://floatsyi.com/
// @version 0.6.0
// @description 避免google网页翻译github站点中的代码
// @author floatsyi
// @license MIT
// @include *://github.com*
// @include *://gist.github.com*
// @match *://github.com*
// @match *://gist.github.com*
// ==/UserScript==
/* jshint esversion: 6 */
;(function () {
'use strict'
// debug log
const isDev = false
const log = (...args) => {
isDev && console.log(args)
}
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 notranslate = (node) => void node.classList.add('notranslate')
function doNotTranslateTab() {
const tab = document.querySelector(
'.UnderlineNav-body'
)
notranslate(tab)
}
function doNotTranslateTable() {
const tables = document.querySelectorAll('#readme table')
;[...tables].forEach(notranslate)
}
function doNotTranslateGist() {
if (window.location.href.match('/gist.github.com/') !== null) {
const gist = document.querySelectorAll('.file')
const pres = document.querySelectorAll('pre')
;[...gist, ...pres].forEach(notranslate)
}
}
function doNotTranslateFilenamesAndDirectories() {
const fileAndDirectory = document.querySelectorAll(
'.Box.mb-3, .file-navigation'
)
;[...fileAndDirectory].forEach(notranslate)
}
function doNotTranslateCodeContentPages() {
const isCodeContentPages = window.location.href.match('/blob/') !== null
const isNotMD = window.location.href.match('.md') === null
if (isCodeContentPages && isNotMD) {
const main = document.querySelector('main')
notranslate(main)
}
}
function doNotTranslateReferenceCode() {
// github 会自动给 .sg-mounted 的子节点 code 加 .sg-mounted class 这里要 加个 div 排除出去
const referenceCodes = document.querySelectorAll(
'div.border.rounded-1.my-2'
)
for (const referenceCode of [...referenceCodes]) {
notranslate(referenceCode)
}
}
function doNotTranslateTitle() {
;['1', '2', '3', '4', '5', '6'].forEach((item) => {
const itemEle = document.querySelectorAll(`h${item}`)
// 没找到就退出
if (!itemEle) return false
;[...itemEle].forEach((el) => {
// 如果是 issues 标题就退出
if (el.classList.contains('gh-header-title')) return false
notranslate(el)
})
})
}
function 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(notranslate)
}
} else {
files.forEach(notranslate)
}
} else if (pres.length > 0) {
pres.forEach(notranslate)
}
}
// 监听DOM变更
const githubTV = document.querySelector('body')
const isGitHub =
window.location.href.search(/github.com/i) !== -1 && !!githubTV
const option = {
childList: true,
subtree: true,
}
let time = 0
function doNotTranslate(mutations, observer) {
// 处于过于频繁的 DOM 变更时, 暂停监听 50ms, 并放弃累积的未处理的变更事件
if (time >= 20) {
observer.disconnect()
observer.takeRecords()
time = 0
setTimeout(function () {
isGitHub && observer.observe(githubTV, option)
}, 50)
}
// 如果是编辑页就退出
if (window.location.href.match('/edit/') !== null) return false
// 不要翻译代码
doNotTranslateCode()
// 不要翻译引用代码
doNotTranslateReferenceCode()
// 不要翻译文件名与目录
doNotTranslateFilenamesAndDirectories()
// 不要翻译代码内容页
doNotTranslateCodeContentPages()
// 不要翻译标题
doNotTranslateTitle()
// 不要翻译 gist 页面的代码
doNotTranslateGist()
// 不要翻译表格
doNotTranslateTable()
// 不要翻译标签栏
doNotTranslateTab()
time++
log(`第${time}次执行: doNotTranslate`)
}
const MutationObserver =
window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver
const mo = new MutationObserver(debounce(doNotTranslate, 50))
isGitHub && mo.observe(githubTV, option)
})()