element parse

Select elements, outline them in red, expand/shrink selection, and show a small copy box.

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Violentmonkey installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Violentmonkey installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Userscripts installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey installieren.

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

(Ich habe bereits einen Benutzerstil Verwaltung, ich möchte ihn installieren!)

// ==UserScript==
// @name element parse
// @namespace https://viayoo.com/
// @version 0.1
// @description Select elements, outline them in red, expand/shrink selection, and show a small copy box.
// @author You
// @run-at document-end
// @license me
// @match *://*/*
// @grant GM_registerMenuCommand
// @grant GM_setClipboard
// ==/UserScript==

(function() {
    'use strict';

    let isActive = false; // State of the selector (Active / Inactive)
    let currentElement = null;
    let elementHistory = [];

    // Inject CSS for the panel, outline, and the small Copy Box
    const style = document.createElement('style');
    style.innerHTML = `
        /* Top control panel */
        .custom-selector-panel {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            background: rgba(255, 255, 255, 0.95);
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 999999;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 8px 0;
            font-family: Arial, sans-serif;
            font-size: 14px;
        }
        .custom-selector-info {
            color: #555;
            margin-bottom: 6px;
            font-weight: bold;
            font-size: 12px;
            max-width: 90%;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .custom-selector-buttons {
            display: flex;
            gap: 15px;
        }
        .custom-selector-btn {
            background: none;
            border: none;
            font-size: 16px;
            font-weight: bold;
            color: #333;
            cursor: pointer;
            padding: 5px 10px;
        }
        .custom-selector-btn:active {
            color: red;
        }

        /* Small Copy Box Modal */
        .custom-copy-box {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            width: 90%;
            max-width: 400px;
            background: rgba(30, 30, 30, 0.95);
            color: #f4f4f4;
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.4);
            z-index: 1000000;
            display: flex;
            flex-direction: column;
            padding: 10px;
            gap: 8px;
            font-family: Arial, sans-serif;
            border: 1px solid #444;
        }
        .custom-copy-input {
            width: 100%;
            background: #121212;
            color: #a5d6a7;
            border: 1px solid #333;
            border-radius: 4px;
            padding: 6px;
            font-size: 12px;
            font-family: monospace;
            box-sizing: border-box;
        }
        .custom-copy-actions {
            display: flex;
            justify-content: flex-end;
            gap: 8px;
        }
        .custom-copy-btn {
            background: #00e676;
            color: #121212;
            border: none;
            padding: 6px 12px;
            border-radius: 4px;
            font-size: 12px;
            cursor: pointer;
            font-weight: bold;
        }
        .custom-copy-btn:active {
            background: #00b555;
        }
        .custom-close-btn {
            background: #ff5252;
            color: white;
            border: none;
            padding: 6px 12px;
            border-radius: 4px;
            font-size: 12px;
            cursor: pointer;
            font-weight: bold;
        }
        .custom-close-btn:active {
            background: #d32f2f;
        }
    `;
    document.head.appendChild(style);

    // Create physical external outline box
    const outline = document.createElement('div');
    outline.style.cssText = `
        position: absolute;
        border: 4px solid red;
        outline: none;
        pointer-events: none;
        z-index: 999998;
        display: none;
        box-sizing: border-box;
        transition: all 0.1s ease;
    `;
    document.body.appendChild(outline);

    // Create top control panel
    const panel = document.createElement('div');
    panel.className = 'custom-selector-panel';
    panel.style.display = 'none';

    const infoLabel = document.createElement('div');
    infoLabel.className = 'custom-selector-info';

    const btnContainer = document.createElement('div');
    btnContainer.className = 'custom-selector-buttons';

    const expandBtn = document.createElement('button');
    expandBtn.className = 'custom-selector-btn';
    expandBtn.innerText = 'Expand';

    const shrinkBtn = document.createElement('button');
    shrinkBtn.className = 'custom-selector-btn';
    shrinkBtn.innerText = 'Shrink';

    const saveBtn = document.createElement('button');
    saveBtn.className = 'custom-selector-btn';
    saveBtn.innerText = 'Save';

    const cancelBtn = document.createElement('button');
    cancelBtn.className = 'custom-selector-btn';
    cancelBtn.innerText = 'Cancel';

    btnContainer.appendChild(expandBtn);
    btnContainer.appendChild(shrinkBtn);
    btnContainer.appendChild(saveBtn);
    btnContainer.appendChild(cancelBtn);
    panel.appendChild(infoLabel);
    panel.appendChild(btnContainer);
    document.body.appendChild(panel);

    // Create Small Copy Box
    const copyBox = document.createElement('div');
    copyBox.className = 'custom-copy-box';
    copyBox.style.display = 'none';

    const copyInput = document.createElement('input');
    copyInput.type = 'text';
    copyInput.className = 'custom-copy-input';
    copyInput.readOnly = true;

    const actionContainer = document.createElement('div');
    actionContainer.className = 'custom-copy-actions';

    const copyBtn = document.createElement('button');
    copyBtn.className = 'custom-copy-btn';
    copyBtn.innerText = 'Copy to Clipboard';

    const closeBtn = document.createElement('button');
    closeBtn.className = 'custom-close-btn';
    closeBtn.innerText = 'Close';

    actionContainer.appendChild(copyBtn);
    actionContainer.appendChild(closeBtn);
    copyBox.appendChild(copyInput);
    copyBox.appendChild(actionContainer);
    document.body.appendChild(copyBox);

    // Close Copy Box
    function hideCopyBox() {
        copyBox.style.display = 'none';
        copyInput.value = '';
    }
    closeBtn.addEventListener('click', hideCopyBox);

    // Clipboard Copy Helper
    function secureCopy(text) {
        function fallbackCopy(str) {
            const textArea = document.createElement('textarea');
            textArea.value = str;
            textArea.style.position = 'fixed';
            textArea.style.top = '0';
            textArea.style.left = '0';
            textArea.style.opacity = '0';
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            try {
                document.execCommand('copy');
            } catch (err) {
                console.error('Fallback copy failed: ', err);
            }
            document.body.removeChild(textArea);
        }

        if (typeof GM_setClipboard !== 'undefined') {
            try {
                GM_setClipboard(text);
                return;
            } catch (e) {}
        }

        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).catch(function() {
                fallbackCopy(text);
            });
        } else {
            fallbackCopy(text);
        }
    }

    copyBtn.addEventListener('click', function() {
        if (copyInput.value) {
            secureCopy(copyInput.value);
            alert('HTML Copied! 🎉');
            hideCopyBox();
        }
    });

    // Positions our external outline directly over the targeted element
    function highlightElement(el) {
        if (el && el !== document.body && el !== document.documentElement && !panel.contains(el) && !copyBox.contains(el)) {
            currentElement = el;
            
            const rect = el.getBoundingClientRect();
            const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
            const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
            
            outline.style.top = (rect.top + scrollTop) + 'px';
            outline.style.left = (rect.left + scrollLeft) + 'px';
            outline.style.width = rect.width + 'px';
            outline.style.height = rect.height + 'px';
            outline.style.display = 'block';
            
            let className = el.className && typeof el.className === 'string' ? '.' + Array.from(el.classList).join('.') : '';
            infoLabel.innerText = `${el.tagName.toLowerCase()}${className}`;
            panel.style.display = 'flex';
        } else {
            outline.style.display = 'none';
            panel.style.display = 'none';
        }
    }

    // Keep outline aligned with the element during scrolls
    window.addEventListener('scroll', function() {
        if (isActive && currentElement) {
            highlightElement(currentElement);
        }
    }, { passive: true });

    // Capture and highlight clicked element instantly if script is active
    document.addEventListener('click', function(e) {
        if (!isActive) return;
        if (panel.contains(e.target) || copyBox.contains(e.target)) return;

        e.preventDefault();
        e.stopPropagation();

        elementHistory = []; 
        highlightElement(e.target);
    }, true);

    // Expand button
    expandBtn.addEventListener('click', function() {
        if (currentElement && currentElement.parentElement && currentElement.parentElement !== document.body) {
            elementHistory.push(currentElement);
            highlightElement(currentElement.parentElement);
        }
    });

    // Shrink button
    shrinkBtn.addEventListener('click', function() {
        if (elementHistory.length > 0) {
            const previousElement = elementHistory.pop();
            highlightElement(previousElement);
        }
    });

    // Save button (Now opens the small, neat copy box)
    saveBtn.addEventListener('click', function() {
        if (currentElement) {
            const htmlContent = currentElement.outerHTML;
            copyInput.value = htmlContent;
            copyBox.style.display = 'flex';
            clearSelection();
        }
    });

    // Cancel button
    cancelBtn.addEventListener('click', function() {
        clearSelection();
    });

    function clearSelection() {
        outline.style.display = 'none';
        panel.style.display = 'none';
        currentElement = null;
        elementHistory = [];
        isActive = false;
    }

    // Register a static, crash-proof menu command for Via Browser
    if (typeof GM_registerMenuCommand !== 'undefined') {
        GM_registerMenuCommand('🔍 Toggle Element Selector', function() {
            isActive = !isActive;
            if (isActive) {
                alert('Element Selector: ACTIVE 🟢\nClick any element on the page to highlight it.');
            } else {
                clearSelection();
                alert('Element Selector: INACTIVE ⚪');
            }
        });
    }
})();