Greasy Fork

浏览器网页英文翻译辅助工具(按ALT显示翻译框)

按ALT键显示鼠标悬停位置的翻译框,按CTRL+S保存翻译内容和URL到 Edge浏览器中的localStorage

// ==UserScript==
// @name         浏览器网页英文翻译辅助工具(按ALT显示翻译框)
// @namespace    http://tampermonkey.net/
// @version      v1.4
// @description  按ALT键显示鼠标悬停位置的翻译框,按CTRL+S保存翻译内容和URL到 Edge浏览器中的localStorage
// @author       lyz
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    let elements = document.querySelectorAll('p, h1, h2, h3, h4, h5, h6, div');
    let inputBoxes = [];
    let lastHoveredElement = null;

    function getStorageKey() {
        let url = window.location.href;
        return url.replace(/^https?:\/\//, '').replace(/[\/:*?"<>|]/g, '_');
    }

    function loadSavedTranslations() {
        let storageKey = getStorageKey();
        let savedData = localStorage.getItem(storageKey);
        if (savedData) {
            let data = JSON.parse(savedData);
            if (data && data.translations) {
                inputBoxes.forEach((item, index) => {
                    if (data.translations[index]) {
                        item.inputBox.value = data.translations[index];
                    }
                });
            }
        }
    }

    function initializeInputBoxes() {
        elements.forEach(function(element, index) {
            let inputBox = document.createElement('textarea');
            inputBox.style.width = '100%';
            inputBox.style.height = '80px';
            inputBox.placeholder = '在此输入你的中文翻译';

            inputBox.style.backgroundColor = '#000';
            inputBox.style.color = '#00FF00';
            inputBox.style.display = 'none';

            element.parentNode.insertBefore(inputBox, element.nextSibling);

            inputBoxes.push({
                element: element,
                inputBox: inputBox
            });

            element.addEventListener('mouseenter', function() {
                lastHoveredElement = element;
            });
        });

        loadSavedTranslations();
    }

    document.addEventListener('keydown', function(event) {
        if (event.altKey) {
            event.preventDefault();

            if (lastHoveredElement) {
                inputBoxes.forEach(function(item) {
                    if (item.element === lastHoveredElement) {
                        if (item.inputBox.style.display === 'none') {
                            item.inputBox.style.display = 'block';
                        } else {
                            item.inputBox.style.display = 'none';
                        }
                    }
                });
            }
        }
    });

    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.key === 's') {
            event.preventDefault();

            let translations = [];

            inputBoxes.forEach(function(item) {
                translations.push(item.inputBox.value);
            });

            let storageKey = getStorageKey();
            let url = window.location.href;

            let fileContent = {
                url: url,
                translations: translations
            };
            localStorage.setItem(storageKey, JSON.stringify(fileContent));
            console.log('翻译内容和URL已自动保存到 localStorage');
        }
    });

    initializeInputBoxes();
})();