BBCode Table Generator for Bitcointalk & Altcoinstalks (with Templates & Quick Formatting)

Genera tabelle in BBCode con salvataggio modelli e pulsanti di formattazione rapida

Устаревшая версия за 06.09.2025. Перейдите к последней версии.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         BBCode Table Generator for Bitcointalk & Altcoinstalks (with Templates & Quick Formatting)
// @namespace    http://tampermonkey.net/
// @version      2.5
// @description  Genera tabelle in BBCode con salvataggio modelli e pulsanti di formattazione rapida
// @author       Ace D.Portugal
// @match        *://bitcointalk.org/*
// @match        *://altcoinstalks.com/*
// @match        *://www.altcoinstalks.com/*
// @grant        GM_setClipboard
// @grant        GM_notification
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// ==/UserScript==

(function() {
    'use strict';

    // Funzione per verificare se un elemento è visibile
    function isVisible(el) {
        return el && el.offsetParent !== null && window.getComputedStyle(el).display !== 'none';
    }

    // Funzione per attendere che un elemento sia pronto
    function waitForElement(selectors, callback, maxAttempts = 40, interval = 500) {
        let attempts = 0;
        const checkInterval = setInterval(() => {
            for (const selector of selectors) {
                const element = document.querySelector(selector);
                if (element && isVisible(element)) {
                    clearInterval(checkInterval);
                    callback(element);
                    return;
                }
            }
            if (attempts++ >= maxAttempts) {
                clearInterval(checkInterval);
                console.error("Nessun elemento visibile trovato con i selettori:", selectors);
            }
        }, interval);
    }

    // Carica i modelli salvati
    function loadTemplates() {
        return GM_getValue('bbcodeTableTemplates', []);
    }

    // Salva i modelli
    function saveTemplates(templates) {
        GM_setValue('bbcodeTableTemplates', templates);
    }

    // Aggiungi un modello
    function addTemplate(name, data) {
        const templates = loadTemplates();
        templates.push({ name, data });
        saveTemplates(templates);
    }

    // Rimuovi un modello
    function removeTemplate(index) {
        const templates = loadTemplates();
        templates.splice(index, 1);
        saveTemplates(templates);
    }

    window.addEventListener('load', function() {
        setTimeout(function() {
            const replySelectors = [
                // Bitcointalk
                'textarea[name="message"]',
                '.postingbox',
                '#quick_reply',
                // Altcoinstalks
                'form#postmodify textarea[name="message"]',
                '#vB_Editor_QR_textarea',
                '#fast_reply',
                '#message',
                'textarea.editor',
            ];

            waitForElement(replySelectors, function(replyBox) {
                const button = document.createElement('button');
                button.textContent = 'Genera Tabella da Testo';
                button.style.margin = '10px';
                button.style.padding = '5px 10px';
                button.style.backgroundColor = '#4CAF50';
                button.style.color = 'white';
                button.style.border = 'none';
                button.style.borderRadius = '4px';
                button.style.cursor = 'pointer';
                button.onclick = openTableGenerator;
                replyBox.parentNode.insertBefore(button, replyBox);
                console.log("Pulsante aggiunto con successo!");
            });
        }, 2000);
    });

    function openTableGenerator(e) {
        e.preventDefault();
        e.stopPropagation();

        const oldOverlay = document.getElementById('bbcodeTableOverlay');
        if (oldOverlay) oldOverlay.remove();
        const oldModal = document.getElementById('bbcodeTableModal');
        if (oldModal) oldModal.remove();

        const overlay = document.createElement('div');
        overlay.id = 'bbcodeTableOverlay';
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0,0,0,0.7)';
        overlay.style.zIndex = '9998';
        overlay.style.display = 'flex';
        overlay.style.justifyContent = 'center';
        overlay.style.alignItems = 'center';

        const modal = document.createElement('div');
        modal.id = 'bbcodeTableModal';
        modal.style.background = 'white';
        modal.style.padding = '20px';
        modal.style.borderRadius = '5px';
        modal.style.maxWidth = '80%';
        modal.style.maxHeight = '80%';
        modal.style.overflow = 'auto';
        modal.style.zIndex = '9999';

        const templates = loadTemplates();
        let templateOptions = '<option value="">-- Seleziona un modello --</option>';
        templates.forEach((template, index) => {
            templateOptions += `<option value="${index}">${template.name}</option>`;
        });

        modal.innerHTML = `
            <h3 style="margin-top: 0;">Genera Tabella da Testo</h3>

            <div style="margin-bottom: 10px;">
                <label>Modelli salvati: </label>
                <select id="bbcodeTemplateSelect" style="padding: 5px;">
                    ${templateOptions}
                </select>
                <button id="bbcodeLoadTemplate" style="margin-left: 5px; padding: 5px 10px; background-color: #2196F3; color: white; border: none; border-radius: 4px;">Carica</button>
                <button id="bbcodeDeleteTemplate" style="margin-left: 5px; padding: 5px 10px; background-color: #f44336; color: white; border: none; border-radius: 4px;">Elimina</button>
            </div>

            <div style="margin-bottom: 10px;">
                <label>Nome modello: </label>
                <input type="text" id="bbcodeTemplateName" style="padding: 5px; width: 200px;" placeholder="Nome del modello">
                <button id="bbcodeSaveTemplate" style="margin-left: 5px; padding: 5px 10px; background-color: #4CAF50; color: white; border: none; border-radius: 4px;">Salva Modello</button>
            </div>

            <p>Inserisci i dati separando le colonne con una virgola (,) e le righe con un a capo.</p>

            <div style="margin-bottom: 10px;">
                <div style="margin-bottom: 5px; font-weight: bold;">Pulsanti di formattazione rapida:</div>
                <button onclick="insertBBCode('[b]', '[/b]')" style="margin-right: 5px; padding: 3px 8px; background-color: #4CAF50; color: white; border: none; border-radius: 3px;">Grassetto</button>
                <button onclick="insertBBCode('[i]', '[/i]')" style="margin-right: 5px; padding: 3px 8px; background-color: #2196F3; color: white; border: none; border-radius: 3px;">Corsivo</button>
                <button onclick="insertBBCode('[url=', '[/url]')" style="margin-right: 5px; padding: 3px 8px; background-color: #9C27B0; color: white; border: none; border-radius: 3px;">Link</button>
                <button onclick="insertBBCode('[img]', '[/img]')" style="margin-right: 5px; padding: 3px 8px; background-color: #FF9800; color: white; border: none; border-radius: 3px;">Immagine</button>
            </div>

            <textarea id="bbcodeDataInput" style="width: 100%; height: 100px; margin: 10px 0; padding: 8px; box-sizing: border-box;" placeholder="Esempio:
Match, Date, Odds
Inter vs Juventus, 13/08/24, X
Milan vs Roma, 14/08/24, 2"></textarea>

            <div style="margin: 10px 0;">
                <label><input type="checkbox" id="bbcodeBoldHeaders" checked> Header in grassetto</label>
                <label style="margin-left: 10px;"><input type="checkbox" id="bbcodeGlowHeaders"> Effetto Glow</label>
                <label style="margin-left: 10px;">Colore glow: <input type="color" id="bbcodeGlowColor" value="#ff0000"></label>
            </div>

            <button id="bbcodeGenerateTable" style="margin: 5px; padding: 5px 10px; background-color: #4CAF50; color: white; border: none; border-radius: 4px;">Genera Tabella</button>

            <div id="bbcodeTablePreview" style="margin: 10px 0; border: 1px solid #ddd; padding: 10px; min-height: 50px;"></div>

            <div>
                <button id="bbcodeCopyBBCode" style="margin: 5px; padding: 5px 10px; background-color: #2196F3; color: white; border: none; border-radius: 4px;">Copia BBCode</button>
                <button id="bbcodeCloseModal" style="margin: 5px; padding: 5px 10px; background-color: #f44336; color: white; border: none; border-radius: 4px;">Chiudi</button>
            </div>
        `;

        overlay.appendChild(modal);
        document.body.appendChild(overlay);

        // Funzione per inserire BBCode nel textarea
        window.insertBBCode = function(openTag, closeTag = '') {
            const textarea = document.getElementById('bbcodeDataInput');
            const start = textarea.selectionStart;
            const end = textarea.selectionEnd;
            const selectedText = textarea.value.substring(start, end);
            const newText = textarea.value.substring(0, start) + openTag + selectedText + closeTag + textarea.value.substring(end);
            textarea.value = newText;
            textarea.focus();
            textarea.selectionStart = start + openTag.length;
            textarea.selectionEnd = end + openTag.length;
        };

        // Carica un modello
        document.getElementById('bbcodeLoadTemplate').onclick = function() {
            const select = document.getElementById('bbcodeTemplateSelect');
            const index = select.value;
            if (index !== "") {
                const templates = loadTemplates();
                document.getElementById('bbcodeDataInput').value = templates[index].data;
            }
        };

        // Elimina un modello
        document.getElementById('bbcodeDeleteTemplate').onclick = function() {
            const select = document.getElementById('bbcodeTemplateSelect');
            const index = select.value;
            if (index !== "") {
                removeTemplate(index);
                select.remove(select.selectedIndex);
                GM_notification({text: 'Modello eliminato!', title: 'Successo'});
            }
        };

        // Salva un modello
        document.getElementById('bbcodeSaveTemplate').onclick = function() {
            const name = document.getElementById('bbcodeTemplateName').value.trim();
            const data = document.getElementById('bbcodeDataInput').value.trim();
            if (name && data) {
                addTemplate(name, data);
                GM_notification({text: 'Modello salvato!', title: 'Successo'});
                // Aggiorna la lista dei modelli
                location.reload();
            } else {
                alert("Inserisci un nome e dei dati per il modello.");
            }
        };

        document.getElementById('bbcodeGenerateTable').onclick = generateTableFromText;
        document.getElementById('bbcodeCopyBBCode').onclick = copyBBCode;
        document.getElementById('bbcodeCloseModal').onclick = () => {
            overlay.remove();
            modal.remove();
        };
    }

    function generateTableFromText() {
        const inputText = document.getElementById('bbcodeDataInput').value.trim();
        const lines = inputText.split('\n');
        if (lines.length < 2) {
            alert("Inserisci almeno due righe di dati (intestazione + almeno una riga).");
            return;
        }

        const isBoldHeaders = document.getElementById('bbcodeBoldHeaders').checked;
        const isGlowHeaders = document.getElementById('bbcodeGlowHeaders').checked;
        const glowColorHex = document.getElementById('bbcodeGlowColor').value;
        const glowColorName = hexToColorName(glowColorHex) || glowColorHex.replace('#', '');

        let bbcode = '[table]';
        let tableHTML = '<table border="1" style="border-collapse: collapse; width: 100%; margin-top: 10px;">';

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i].trim();
            if (line === '') continue;
            const cells = line.split(',').map(cell => cell.trim());
            if (cells.length === 0) continue;

            tableHTML += '<tr>';
            bbcode += '[tr]';

            for (let j = 0; j < cells.length; j++) {
                const cell = cells[j];
                const isHeader = (i === 0);
                let bbcodeCell = cell;
                let htmlCell = cell;

                if (isHeader) {
                    if (isBoldHeaders) bbcodeCell = `[b]${bbcodeCell}[/b]`;
                    if (isGlowHeaders) bbcodeCell = `[glow=${glowColorName},2,300]${bbcodeCell}[/glow]`;
                    htmlCell = isBoldHeaders ? `<b>${htmlCell}</b>` : htmlCell;
                    if (isGlowHeaders) htmlCell = `<span style="text-shadow: 0 0 8px ${glowColorHex};">${htmlCell}</span>`;
                }

                tableHTML += `<td style="border: 1px solid #ddd; padding: 5px;">${htmlCell}</td>`;
                bbcode += `[td]${bbcodeCell}[/td]`;
            }

            tableHTML += '</tr>';
            bbcode += '[/tr]';
        }

        tableHTML += '</table>';
        bbcode += '[/table]';

        const preview = document.getElementById('bbcodeTablePreview');
        preview.innerHTML = tableHTML;
        preview.setAttribute('data-bbcode', bbcode);
    }

    function copyBBCode() {
        const preview = document.getElementById('bbcodeTablePreview');
        const bbcode = preview.getAttribute('data-bbcode');
        if (bbcode) {
            GM_setClipboard(bbcode, 'text');
            GM_notification({text: 'BBCode copiato negli appunti!', title: 'Successo'});
        } else {
            alert("Genera prima la tabella!");
        }
    }

    function hexToColorName(hex) {
        const colorMap = {
            '#ff0000': 'red',
            '#00ff00': 'green',
            '#0000ff': 'blue',
            '#ffff00': 'yellow',
            '#ff00ff': 'magenta',
            '#00ffff': 'cyan',
            '#ffffff': 'white',
            '#000000': 'black',
            '#ffa500': 'orange',
            '#800080': 'purple'
        };
        return colorMap[hex.toLowerCase()] || null;
    }
})();