Webpage Source Viewer and Text Replacer

Fetch, display, improve, and replace text in the HTML, CSS, and JavaScript of a webpage with a clean white theme.

Verzia zo dňa 07.12.2024. Pozri najnovšiu verziu.

// ==UserScript==
// @name         Webpage Source Viewer and Text Replacer
// @namespace    https://greasyfork.org/users/123456-ramen-sukuna
// @version      1.0
// @description  Fetch, display, improve, and replace text in the HTML, CSS, and JavaScript of a webpage with a clean white theme.
// @author       Ramen Sukuna🍜
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @icon         https://attic.sh/nvbu08kd47uzl3mf9cpisiazptio
// ==/UserScript==

(function () {
    'use strict';

    const guiHTML = `
        <div id="sourceViewer" style="position:fixed; top:10%; left:10%; width:80%; height:80%; background:white; color:black; border:2px solid black; z-index:9999; overflow:auto; padding:10px; display:none; font-family: Arial, sans-serif;">
            <button id="closeSourceViewer" style="position:absolute; top:5px; right:5px; background:white; color:black; border:1px solid black;">Close</button>
            <h3>Webpage Source Viewer</h3>
            <label>Enter URL:</label>
            <input type="text" id="sourceUrl" style="width:50%; color:black; background:white; border:1px solid black;" placeholder="e.g., https://example.com">
            <br><br>
            <label>Find:</label>
            <input type="text" id="findText" style="width:30%; color:black; background:white; border:1px solid black;" placeholder="Text to find">
            <span style="margin:0 10px;">to</span>
            <label>Replace:</label>
            <input type="text" id="replaceText" style="width:30%; color:black; background:white; border:1px solid black;" placeholder="Text to replace with">
            <br><br>
            <button id="fetchSource" style="background:white; color:black; border:1px solid black;">Fetch Source</button>
            <button id="replaceSourceText" style="background:white; color:black; border:1px solid black;">Replace Text</button>
            <button id="improveSource" style="background:white; color:black; border:1px solid black;">Improve💪</button>
            <hr>
            <div id="sourceResults">
                <h4>HTML</h4>
                <textarea id="htmlSource" style="width:100%; height:150px; background:white; color:black; border:1px solid black;" readonly></textarea>
                <button class="copyButton" data-target="htmlSource" style="background:white; color:black; border:1px solid black;">Copy HTML</button>
                <h4>CSS</h4>
                <textarea id="cssSource" style="width:100%; height:150px; background:white; color:black; border:1px solid black;" readonly></textarea>
                <button class="copyButton" data-target="cssSource" style="background:white; color:black; border:1px solid black;">Copy CSS</button>
                <h4>JavaScript</h4>
                <textarea id="jsSource" style="width:100%; height:150px; background:white; color:black; border:1px solid black;" readonly></textarea>
                <button class="copyButton" data-target="jsSource" style="background:white; color:black; border:1px solid black;">Copy JavaScript</button>
            </div>
        </div>
        <button id="openSourceViewer" style="position:fixed; bottom:10px; right:10px; background:white; color:black; border:1px solid black; z-index:9999;">View Source</button>
    `;
    document.body.insertAdjacentHTML('beforeend', guiHTML);

    GM_addStyle(`
        #sourceViewer textarea {
            font-family: monospace;
        }
        #sourceViewer button {
            margin: 5px;
        }
    `);

    const sourceViewer = document.getElementById('sourceViewer');
    const openButton = document.getElementById('openSourceViewer');
    const closeButton = document.getElementById('closeSourceViewer');
    const fetchButton = document.getElementById('fetchSource');
    const replaceButton = document.getElementById('replaceSourceText');
    const improveButton = document.getElementById('improveSource');

    openButton.addEventListener('click', () => {
        sourceViewer.style.display = 'block';
    });

    closeButton.addEventListener('click', () => {
        sourceViewer.style.display = 'none';
    });

    fetchButton.addEventListener('click', () => {
        const url = document.getElementById('sourceUrl').value;
        if (!url) {
            alert('Please enter a URL!');
            return;
        }

        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function (response) {
                const parser = new DOMParser();
                const doc = parser.parseFromString(response.responseText, 'text/html');
                document.getElementById('htmlSource').value = response.responseText;
                const stylesheets = Array.from(doc.querySelectorAll('link[rel="stylesheet"], style'));
                const css = stylesheets.map(sheet => sheet.outerHTML).join('\n');
                document.getElementById('cssSource').value = css;
                const scripts = Array.from(doc.querySelectorAll('script')).map(script => script.outerHTML).join('\n');
                document.getElementById('jsSource').value = scripts;
            },
            onerror: function () {
                alert('Failed to fetch the webpage. Please check the URL and try again.');
            }
        });
    });

    replaceButton.addEventListener('click', () => {
        const findText = document.getElementById('findText').value;
        const replaceText = document.getElementById('replaceText').value;

        if (!findText) {
            alert('Please enter text to find!');
            return;
        }

        ['htmlSource', 'cssSource', 'jsSource'].forEach((id) => {
            const textarea = document.getElementById(id);
            textarea.value = textarea.value.split(findText).join(replaceText);
        });

        alert(`Replaced all occurrences of "${findText}" with "${replaceText}".`);
    });

    improveButton.addEventListener('click', () => {
        const htmlSource = document.getElementById('htmlSource').value;
        const cssSource = document.getElementById('cssSource').value;
        const jsSource = document.getElementById('jsSource').value;

        const formatCode = (code, type) => {
            try {
                if (type === 'html') {
                    return new DOMParser().parseFromString(code, 'text/html').documentElement.outerHTML;
                } else if (type === 'css') {
                    return code.replace(/\s+/g, ' ').trim();
                } else if (type === 'js') {
                    return js_beautify(code); // Use js-beautify if available
                }
            } catch (error) {
                return code;
            }
        };

        document.getElementById('htmlSource').value = formatCode(htmlSource, 'html');
        document.getElementById('cssSource').value = formatCode(cssSource, 'css');
        document.getElementById('jsSource').value = formatCode(jsSource, 'js');
        alert('Source improved successfully!');
    });

    document.querySelectorAll('.copyButton').forEach(button => {
        button.addEventListener('click', () => {
            const target = document.getElementById(button.dataset.target);
            target.select();
            document.execCommand('copy');
            alert(`${button.dataset.target.toUpperCase()} copied to clipboard!`);
        });
    });
})();