Untranslator

костыльная отмена автоперевода

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

Advertisement:

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

Advertisement:

// ==UserScript==
// @name         Untranslator
// @namespace    нету
// @version      0.1
// @description  костыльная отмена автоперевода
// @author       жди
// @match        *://lolz.live/*
// @match        *://zelenka.guru/*
// @match        *://lolz.guru/*
// @license      MIT
// @grant        GM_getValue
// @grant        GM_setValue
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    const STORAGE_KEY = 'translated';
    const SHOW_ORIGINAL = 'Показать исходный текст';
    const TRANSLATE_TO_RUSSIAN = 'Перевести на Русский';

    function getTranslated() {
        try {
            const translated = JSON.parse(GM_getValue(STORAGE_KEY, '[]'));
            return Array.isArray(translated) ? translated : [];
        } catch (e) {
            return [];
        }
    }

    function setTranslated(arr) {
        GM_setValue(STORAGE_KEY, JSON.stringify(arr));
    }

    function getOwnerBlock(button) {
        return button.closest('li.comment, li.message');
    }

    function getBlockId(block) {
        return block?.id || '';
    }

    function addTranslated(blockId) {
        if (!blockId) return;

        const translated = getTranslated();

        if (!translated.includes(blockId)) {
            translated.push(blockId);
            setTranslated(translated);
        }
    }

    function removeTranslated(blockId) {
        if (!blockId) return;

        const translated = getTranslated();

        if (translated.includes(blockId)) setTranslated(translated.filter(id => id !== blockId));
    }

    function init() {
        const messageList = document.getElementById('messageList');

        if (!messageList) return;

        function untranslatePosts() {
            const translated = getTranslated();

            const translateButtons = messageList.querySelectorAll(`.TranslateButton[data-cachedtitle="${SHOW_ORIGINAL}"]`);

            for (const translateButton of translateButtons) {
                const block = getOwnerBlock(translateButton);
                const blockId = getBlockId(block);

                if (!blockId || translated.includes(blockId)) continue;

                translateButton.click();
            }
        }

        messageList.addEventListener('click', function (event) {
            const translateButton = event.target.closest('.TranslateButton');

            if (!translateButton || !event.isTrusted) return;

            const block = getOwnerBlock(translateButton);
            const blockId = getBlockId(block);

            if (!blockId) return;

            if (translateButton.getAttribute('data-cachedtitle') === TRANSLATE_TO_RUSSIAN) addTranslated(blockId);
            else removeTranslated(blockId);

        }, true);

        const observer = new MutationObserver(function (mutations) {
            for (const mutation of mutations) {
                if (mutation.type === 'childList' || (mutation.type === 'attributes' && mutation.attributeName === 'data-cachedtitle')) {
                    untranslatePosts();
                    break;
                }
            }
        });

        observer.observe(messageList, {
            childList: true, subtree: true, attributes: true, attributeFilter: ['data-cachedtitle']
        });

        untranslatePosts();
    }

    if (document.readyState === 'loading') window.addEventListener('load', init, {once: true}); else init();
})();