// ==UserScript==
// @name BBCode Table Generator for Bitcointalk & Altcoinstalks (with Templates & Quick Formatting)
// @namespace http://tampermonkey.net/
// @version 2.7
// @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';
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;
}
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>`;
});
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="[url=" data-close="][/url]" style="margin-right: 5px; padding: 3px 8px; background-color: #9C27B0; 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>
<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);
// 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 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;
}
})();