TomatoMTL Auto Copy Cleaner (Button Fix)

Automatically removes boilerplate when copying text via button or selection on tomatomtl.com.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         TomatoMTL Auto Copy Cleaner (Button Fix)
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Automatically removes boilerplate when copying text via button or selection on tomatomtl.com.
// @author       tertium
// @match        *://tomatomtl.com/*
// @license      MIT
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // Use unsafeWindow to access the page's native navigator object
    const realNavigator = typeof unsafeWindow !== 'undefined' ? unsafeWindow.navigator : window.navigator;

    if (!realNavigator.clipboard || !realNavigator.clipboard.writeText) {
        console.warn('TomatoMTL Cleaner: navigator.clipboard.writeText is not available. Script cannot function.');
        return;
    }

    // --- Your Cleaning Logic ---
    const boilerplateRegex = /TomatoMTL – Simple MTL Reading Assist Tool[\s\S]*?URL: [\s\S]*(?=\n|$)/g;
    const extraNewlinesRegex = /\n{3,}/g;

    function cleanText(text) {
        if (typeof text !== 'string') {
            return text; // Don't process non-strings
        }
        console.log("Original text length:", text.length); // Debug: See original
        let cleaned = text.replace(boilerplateRegex, '').replace(extraNewlinesRegex, '\n\n').trim();
        console.log("Cleaned text length:", cleaned.length); // Debug: See cleaned
        // Debug: Check if cleaning actually happened
        // if (text.length !== cleaned.length) {
        //    console.log("TomatoMTL Cleaner: Text was modified.");
        // } else {
        //     console.log("TomatoMTL Cleaner: Text was NOT modified (boilerplate likely not found).");
        // }
        return cleaned;
    }
    // --- End Cleaning Logic ---


    // --- Intercept clipboard.writeText ---

    // Store the original function safely, ensuring 'this' context is preserved
    const originalWriteText = realNavigator.clipboard.writeText.bind(realNavigator.clipboard);

    // Create our wrapper function
    const modifiedWriteText = async function(text) {
        // console.log('TomatoMTL Cleaner: Intercepting writeText...'); // Debug
        const cleanedText = cleanText(text);
        // Call the original function with the cleaned text
        return originalWriteText(cleanedText);
    };

    // Replace the original function with our modified one
    // We need to make the property writable first on some browsers/strict modes
    try {
         Object.defineProperty(realNavigator.clipboard, 'writeText', {
             value: modifiedWriteText,
             writable: true, // Keep it potentially replaceable by other scripts if needed
             configurable: true,
         });
         console.log('TomatoMTL Cleaner: Successfully intercepted navigator.clipboard.writeText.');
    } catch (e) {
        console.error('TomatoMTL Cleaner: Failed to intercept navigator.clipboard.writeText.', e);
         // Fallback attempt (less robust)
         try {
              realNavigator.clipboard.writeText = modifiedWriteText;
              console.log('TomatoMTL Cleaner: Successfully intercepted navigator.clipboard.writeText (fallback method).');
         } catch (e2) {
               console.error('TomatoMTL Cleaner: Fallback interception failed too.', e2);
         }
    }


    // --- Optional: Also keep the 'copy' event listener as a fallback/complement ---
    // This might help if some copy actions DON'T use writeText, though less likely for custom buttons.
    document.addEventListener('copy', function(event) {
        const selectedText = unsafeWindow.getSelection().toString(); // Use unsafeWindow here too
        if (selectedText) {
            const cleanedSelectedText = cleanText(selectedText);
            // Only intervene if cleaning actually changed something OR if clipboardData is available
            if (cleanedSelectedText !== selectedText && event.clipboardData) {
                event.preventDefault();
                event.clipboardData.setData('text/plain', cleanedSelectedText);
                // console.log('TomatoMTL Cleaner: Cleaned text via "copy" event.'); // Debug
            }
        }
    }, true); // Use capture phase


    // console.log('TomatoMTL Auto Copy Cleaner (Button Fix) script loaded.'); // Debug

})();