// ==UserScript==
// @name BBCode Table Generator for Bitcointalk & Altcoinstalks (with Full Formatting)
// @namespace http://tampermonkey.net/
// @version 3.0
// @description Genera tabelle in BBCode con selettori a discesa per colori, font e glow per header e corpo
// @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';
function isVisible(el) {
return el && el.offsetParent !== null && window.getComputedStyle(el).display !== 'none';
}
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);
}
function loadTemplates() {
return GM_getValue('bbcodeTableTemplates', []);
}
function saveTemplates(templates) {
GM_setValue('bbcodeTableTemplates', templates);
}
function addTemplate(name, data) {
const templates = loadTemplates();
templates.push({ name, data });
saveTemplates(templates);
}
function removeTemplate(index) {
const templates = loadTemplates();
templates.splice(index, 1);
saveTemplates(templates);
}
function insertBBCode(openTag, closeTag = '') {
const textarea = document.getElementById('bbcodeDataInput');
if (!textarea) return;
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;
}
function bbcodeToHtml(bbcode) {
return bbcode
.replace(/\[b\](.*?)\[\/b\]/g, '<strong>$1</strong>')
.replace(/\[i\](.*?)\[\/i\]/g, '<em>$1</em>')
.replace(/\[u\](.*?)\[\/u\]/g, '<u>$1</u>')
.replace(/\[url=(.*?)\](.*?)\[\/url\]/g, '<a href="$1" target="_blank">$2</a>')
.replace(/\[img\](.*?)\[\/img\]/g, '<img src="$1" style="max-width: 100%; height: auto;" />')
.replace(/\[color=(.*?)\](.*?)\[\/color\]/g, '<span style="color: $1;">$2</span>')
.replace(/\[size=(.*?)\](.*?)\[\/size\]/g, '<span style="font-size: $1;">$2</span>')
.replace(/\[font=(.*?)\](.*?)\[\/font\]/g, '<span style="font-family: $1;">$2</span>')
.replace(/\[glow=(.*?),2,300\](.*?)\[\/glow\]/g, '<span style="text-shadow: 0 0 8px $1;">$2</span>');
}
window.addEventListener('load', function() {
setTimeout(function() {
const replySelectors = [
'textarea[name="message"]',
'.postingbox',
'#quick_reply',
'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>`;
});
// Opzioni per colori
const colorOptions = [
{ value: 'black', label: 'Nero' },
{ value: 'white', label: 'Bianco' },
{ value: 'red', label: 'Rosso' },
{ value: 'green', label: 'Verde' },
{ value: 'blue', label: 'Blu' },
{ value: 'yellow', label: 'Giallo' },
{ value: 'orange', label: 'Arancione' },
{ value: '#ff00ff', label: 'Magenta' },
{ value: '#00ffff', label: 'Ciano' },
{ value: '#ffa500', label: 'Arancione Scuro' },
{ value: '#800080', label: 'Viola' }
];
let colorSelectOptions = colorOptions.map(color => `<option value="${color.value}" style="color: ${color.value};">${color.label}</option>`).join('');
// Opzioni per font
const fontOptions = [
{ value: 'Arial', label: 'Arial' },
{ value: 'Verdana', label: 'Verdana' },
{ value: 'Times New Roman', label: 'Times New Roman' },
{ value: 'Courier New', label: 'Courier New' },
{ value: 'Georgia', label: 'Georgia' },
{ value: 'Impact', label: 'Impact' },
{ value: 'Comic Sans MS', label: 'Comic Sans MS' }
];
let fontSelectOptions = fontOptions.map(font => `<option value="${font.value}">${font.label}</option>`).join('');
// Opzioni per dimensioni font
const sizeOptions = [
{ value: '8pt', label: '8pt' },
{ value: '10pt', label: '10pt' },
{ value: '12pt', label: '12pt' },
{ value: '14pt', label: '14pt' },
{ value: '16pt', label: '16pt' },
{ value: '18pt', label: '18pt' },
{ value: '20pt', label: '20pt' }
];
let sizeSelectOptions = sizeOptions.map(size => `<option value="${size.value}">${size.label}</option>`).join('');
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 class="format-button" data-open="[b]" data-close="[/b]" style="margin-right: 5px; padding: 3px 8px; background-color: #4CAF50; color: white; border: none; border-radius: 3px;">Grassetto</button>
<button class="format-button" data-open="[i]" data-close="[/i]" style="margin-right: 5px; padding: 3px 8px; background-color: #2196F3; color: white; border: none; border-radius: 3px;">Corsivo</button>
<button class="format-button" data-open="[u]" data-close="[/u]" style="margin-right: 5px; padding: 3px 8px; background-color: #9C27B0; color: white; border: none; border-radius: 3px;">Sottolineato</button>
<button class="format-button" data-open="[url=" data-close="][/url]" style="margin-right: 5px; padding: 3px 8px; background-color: #FF5722; color: white; border: none; border-radius: 3px;">Link</button>
<button class="format-button" data-open="[img]" data-close="[/img]" style="margin-right: 5px; padding: 3px 8px; background-color: #FF9800; color: white; border: none; border-radius: 3px;">Immagine</button>
</div>
<div style="margin-bottom: 10px; border: 1px solid #ddd; padding: 10px; border-radius: 5px;">
<div style="margin-bottom: 5px; font-weight: bold;">Formattazione globale:</div>
<div style="margin-bottom: 10px;">
<label>Colore testo: </label>
<select id="bbcodeTextColor" style="padding: 5px; margin-right: 10px;">
${colorSelectOptions}
</select>
<label>Font: </label>
<select id="bbcodeTextFont" style="padding: 5px; margin-right: 10px;">
${fontSelectOptions}
</select>
<label>Dimensione: </label>
<select id="bbcodeTextSize" style="padding: 5px;">
${sizeSelectOptions}
</select>
</div>
<div style="margin-bottom: 10px;">
<label><input type="checkbox" id="bbcodeBoldHeaders" checked> Header in grassetto</label>
<label style="margin-left: 10px;"><input type="checkbox" id="bbcodeGlowHeaders"> Effetto Glow su Header</label>
<label style="margin-left: 10px;">Colore glow header: <input type="color" id="bbcodeGlowColorHeaders" value="#ff0000"></label>
</div>
<div style="margin-bottom: 10px;">
<label><input type="checkbox" id="bbcodeGlowBody"> Effetto Glow su Corpo</label>
<label style="margin-left: 10px;">Colore glow corpo: <input type="color" id="bbcodeGlowColorBody" value="#00ff00"></label>
</div>
</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>
<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);
// Aggiungi gestione pulsanti di formattazione
const formatButtons = modal.querySelectorAll('.format-button');
formatButtons.forEach(button => {
button.addEventListener('click', function() {
const openTag = this.getAttribute('data-open');
const closeTag = this.getAttribute('data-close') || '';
if (openTag === '[url=') {
const url = prompt("Inserisci l'URL:", "https://");
if (url) insertBBCode(`[url=${url}]`, '[/url]');
} else if (openTag === '[img]') {
const imgUrl = prompt("Inserisci l'URL dell'immagine:", "https://");
if (imgUrl) insertBBCode(`[img]${imgUrl}[/img]`, '');
} else {
insertBBCode(openTag, closeTag);
}
});
});
// Carica un modello
modal.querySelector('#bbcodeLoadTemplate').addEventListener('click', function() {
const select = modal.querySelector('#bbcodeTemplateSelect');
const index = select.value;
if (index !== "") {
const templates = loadTemplates();
modal.querySelector('#bbcodeDataInput').value = templates[index].data;
}
});
// Elimina un modello
modal.querySelector('#bbcodeDeleteTemplate').addEventListener('click', function() {
const select = modal.querySelector('#bbcodeTemplateSelect');
const index = select.value;
if (index !== "") {
removeTemplate(index);
select.remove(select.selectedIndex);
GM_notification({text: 'Modello eliminato!', title: 'Successo'});
}
});
// Salva un modello
modal.querySelector('#bbcodeSaveTemplate').addEventListener('click', function() {
const name = modal.querySelector('#bbcodeTemplateName').value.trim();
const data = modal.querySelector('#bbcodeDataInput').value.trim();
if (name && data) {
addTemplate(name, data);
GM_notification({text: 'Modello salvato!', title: 'Successo'});
} else {
alert("Inserisci un nome e dei dati per il modello.");
}
});
modal.querySelector('#bbcodeGenerateTable').addEventListener('click', generateTableFromText);
modal.querySelector('#bbcodeCopyBBCode').addEventListener('click', copyBBCode);
modal.querySelector('#bbcodeCloseModal').addEventListener('click', () => {
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 isGlowBody = document.getElementById('bbcodeGlowBody').checked;
const glowColorHeaders = document.getElementById('bbcodeGlowColorHeaders').value;
const glowColorBody = document.getElementById('bbcodeGlowColorBody').value;
const textColor = document.getElementById('bbcodeTextColor').value;
const textFont = document.getElementById('bbcodeTextFont').value;
const textSize = document.getElementById('bbcodeTextSize').value;
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 = bbcodeToHtml(cell);
// Applica formattazione globale
if (textColor) bbcodeCell = `[color=${textColor}]${bbcodeCell}[/color]`;
if (textFont) bbcodeCell = `[font=${textFont}]${bbcodeCell}[/font]`;
if (textSize) bbcodeCell = `[size=${textSize}]${bbcodeCell}[/size]`;
if (isHeader) {
if (isBoldHeaders) bbcodeCell = `[b]${bbcodeCell}[/b]`;
if (isGlowHeaders) bbcodeCell = `[glow=${glowColorHeaders},2,300]${bbcodeCell}[/glow]`;
} else if (isGlowBody) {
bbcodeCell = `[glow=${glowColorBody},2,300]${bbcodeCell}[/glow]`;
}
// Applica formattazione globale all'HTML
let style = '';
if (textColor) style += `color: ${textColor};`;
if (textFont) style += `font-family: ${textFont};`;
if (textSize) style += `font-size: ${textSize};`;
if (style) htmlCell = `<span style="${style}">${htmlCell}</span>`;
if (isHeader) {
if (isBoldHeaders) htmlCell = `<strong>${htmlCell}</strong>`;
if (isGlowHeaders) htmlCell = `<span style="text-shadow: 0 0 8px ${glowColorHeaders};">${htmlCell}</span>`;
} else if (isGlowBody) {
htmlCell = `<span style="text-shadow: 0 0 8px ${glowColorBody};">${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!");
}
}
})();