Enjoy DeepL Unlimited

Enjoy use Unlimited DeepL.

// ==UserScript==
// @name         Enjoy DeepL Unlimited
// @namespace    http://tampermonkey.net/
// @version      0.1.0
// @description  Enjoy use Unlimited DeepL.
// @author       fleey
// @match        https://*.deepl.com/translator
// @match        https://*.deepl.com/*/translator
// @grant        GM_setClipboard
// @icon         https://www.deepl.com/favicon.ico
// @license      MIT
// @run-at       document-idle
// ==/UserScript==


(function() {
    'use strict';

    let isResetting = false;

    const config = {
        keywords: ['300,000', 'unlimited characters'],
        cookies: ['dapSid', 'LMTBID', 'dapUid'],
        sourceTextSelector: 'div[aria-labelledby="translation-source-heading"] d-textarea',
    };

    const i18n = {
        translations: {
            en: {
                copied_alert: "DeepL limit detected. Your source text has been copied to the clipboard.",
                confirm_reload: "Cookies have been cleared. Do you want to reload the page now to reset the limit?"
            },
            zh: {
                copied_alert: "检测到DeepL使用限制。您的原文已复制到剪贴板。",
                confirm_reload: "相关Cookie已被清除。是否立即刷新页面以重置额度?"
            }
        },
        getLang: function() {
            const lang = navigator.language || navigator.userLanguage;
            if (lang.startsWith('zh')) {
                return 'zh';
            }
            return 'en';
        },
        getString: function(key) {
            const lang = this.getLang();
            return this.translations[lang][key] || this.translations['en'][key];
        }
    };

    function deleteCookies() {
        config.cookies.forEach(name => {
            document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.deepl.com;`;
        });
    }

    function copySourceText() {
        const sourceTextArea = document.querySelector(config.sourceTextSelector);
        if (sourceTextArea) {
            const paragraphs = sourceTextArea.querySelectorAll('p');
            const textToCopy = Array.from(paragraphs).map(p => p.innerText).join('\n');
            if (textToCopy) {
                GM_setClipboard(textToCopy);
                return true;
            }
        }
        return false;
    }

    function triggerResetProcess() {
        if (isResetting) return;
        isResetting = true;

        deleteCookies();
        copySourceText();

        alert(i18n.getString('copied_alert'));

        if (confirm(i18n.getString('confirm_reload'))) {
            window.location.reload();
        }
    }

    function checkForLimit(text) {
        if (!text) return false;
        return config.keywords.every(keyword => text.includes(keyword));
    }

    const observer = new MutationObserver((mutationsList, obs) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                for (const node of mutation.addedNodes) {
                    if (node.nodeType === Node.ELEMENT_NODE && checkForLimit(node.innerText)) {
                        triggerResetProcess();
                        obs.disconnect();
                        return;
                    }
                }
            }
        }
    });

    observer.observe(document.body, { childList: true, subtree: true });

})();