Greasy Fork is available in English.

google-translate

add a Google Translate plug-in to the page

// ==UserScript==
// @name            google-translate
// @name:zh         谷歌翻译
// @namespace       https://github.com/pansong291/
// @version         0.3.1
// @description     add a Google Translate plug-in to the page
// @description:zh  向页面添加谷歌翻译插件
// @author          paso
// @license         Apache-2.0
// @match           *://*/*
// @icon            https://ssl.gstatic.com/translate/favicon.ico
// @grant           none
// @run-at          context-menu
// ==/UserScript==

;(function () {
  'use strict'
  if (window.google?.translate?.TranslateElement) {
    console.info('%cGoogle Translate\n%chas already been inited.', 'color: #fbbc05; font-size: 22px; font-weight: bold', 'font-size: 14px')
    return
  }
  const elementId = `google-translate-element-${Math.floor(Math.random() * 100_000_000)}`
  document.head.insertAdjacentHTML('beforeend', `
    <style>
        #${elementId} {
            position: fixed;
            left: 0;
            bottom: 0;
            z-index: 99999;
            transform: translateX(calc(6px - 100%));
            transition: transform .3s;
        }
        #${elementId}.hold, #${elementId}:hover {
            transform: translateX(0);
        }
        #${elementId} > :first-child {
            background: white;
            padding: 4px;
            border-radius: 0 4px 0 0;
            box-shadow: 0 0 4px rgba(0,0,0,50%);
        }
        #${elementId} span, #${elementId} a, #${elementId} img {
            display: inline;
        }
    </style>`)

  const divElm = createElement('div', { id: elementId, class: 'hold' })
  divElm.addEventListener('mouseleave', () => divElm.classList.remove('hold'), { once: true })
  document.body.append(divElm)

  window.googleTranslateElementInit = () => {
    new window.google.translate.TranslateElement(null, elementId)
    console.log('%cGoogle Translate\n%cinit finished.', 'color: #4286F3; font-size: 22px; font-weight: bold', 'font-size: 14px')
    clearInterval(window.googleTranslateElementInitLoopId)
    delete window.googleTranslateElementInit
  }

  const jsElm = createElement('script', { src: '//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit' })
  jsElm.onload = detectGoogleTranslate
  jsElm.onerror = () => {
    divElm.append(createElement('a', {
      style: 'font-size: 16px;',
      href: 'https://greasyfork.org/scripts/493434',
      target: '_blank'
    }, ['Google Translate load failed!']))
  }
  document.head.append(jsElm)

  function detectGoogleTranslate() {
    let count = 360
    window.googleTranslateElementInitLoopId = setInterval(() => {
      if (window.google?.translate?.TranslateElement) {
        window.googleTranslateElementInit()
      } else if (count <= 0) {
        console.warn('%cGoogle Translate\n%cinit failed!', 'color: #EB4537; font-size: 22px; font-weight: bold', 'font-size: 14px')
        clearInterval(window.googleTranslateElementInitLoopId)
      }
      count--
    }, 500)
  }

  function createElement(tag, attrs, children) {
    const el = document.createElement(tag)
    if (attrs) {
      Object.entries(attrs).forEach(([k, v]) => el.setAttribute(k, v))
    }
    if (typeof children === 'string') {
      el.innerHTML = children
    } else if (Array.isArray(children)) {
      el.append.apply(el, children)
    }
    return el
  }
})()