element parse

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

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==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 ⚪');
            }
        });
    }
})();