MediaWiki:CommonTranslate.js: differenze tra le versioni
Nessun oggetto della modifica Etichetta: Annullato |
Nessun oggetto della modifica Etichetta: Annullato |
||
| Riga 1: | Riga 1: | ||
/* ======================= CommonTranslate.js ( | /* ======================= CommonTranslate.js (versione stabile precedente) ======================= */ | ||
console.log("🔄 Caricamento CommonTranslate.js…"); | console.log("🔄 Caricamento CommonTranslate.js…"); | ||
// Evita | // Evita doppio caricamento | ||
if (window.__CommonTranslateLoaded) { | if (window.__CommonTranslateLoaded) { | ||
console.warn("⚠️ CommonTranslate.js è già stato caricato."); | console.warn("⚠️ CommonTranslate.js è già stato caricato."); | ||
| Riga 8: | Riga 8: | ||
window.__CommonTranslateLoaded = true; | window.__CommonTranslateLoaded = true; | ||
// | // Manteniamo la vecchia struttura con pulsante | ||
const DEFAULT_MODEL = (window.openaiModel || "gpt-4o"); | const DEFAULT_MODEL = (window.openaiModel || "gpt-4o"); | ||
const LINGUA_ORIGINE = document.documentElement.lang || "en"; | |||
// | // 🔑 QUI usi ancora la chiave diretta (come avevi prima) → se preferisci il proxy si cambia solo questo pezzo | ||
const | const API_URL = "https://api.openai.com/v1/chat/completions"; | ||
const API_KEY = window.apiKey || "INSERISCI_LA_TUA_API_KEY"; | |||
console.log("✅ CommonTranslate.js | console.log("✅ CommonTranslate.js caricato. Modello:", DEFAULT_MODEL); | ||
function getEditor() { | function getEditor() { | ||
return document.getElementById("wpTextbox1"); | return document.getElementById("wpTextbox1"); | ||
} | } | ||
function getSelectedTextInfo() { | function getSelectedTextInfo() { | ||
const area = getEditor(); | const area = getEditor(); | ||
| Riga 31: | Riga 30: | ||
return { text, start, end }; | return { text, start, end }; | ||
} | } | ||
function segmentaTesto(testo, maxChars = 3000) { | function segmentaTesto(testo, maxChars = 3000) { | ||
const re = new RegExp(`.{1,${maxChars}}(?=\\s|$)`, "gs"); | const re = new RegExp(`.{1,${maxChars}}(?=\\s|$)`, "gs"); | ||
return testo.match(re) || []; | return testo.match(re) || []; | ||
} | } | ||
async function traduciBlocco(blocco, lingua, model = DEFAULT_MODEL) { | |||
async function | |||
try { | try { | ||
const res = await fetch( | const res = await fetch(API_URL, { | ||
method: "POST", | method: "POST", | ||
headers: { "Content-Type": "application/json" }, | headers: { | ||
"Content-Type": "application/json", | |||
"Authorization": `Bearer ${API_KEY}` | |||
}, | |||
body: JSON.stringify({ | body: JSON.stringify({ | ||
model, | model, | ||
| Riga 62: | Riga 63: | ||
const data = await res.json(); | const data = await res.json(); | ||
if (!res.ok) { | if (!res.ok) { | ||
const msg = data?.error || `HTTP ${res.status}`; | const msg = data?.error?.message || `HTTP ${res.status}`; | ||
throw new Error(msg); | throw new Error(msg); | ||
} | } | ||
return data?.choices?.[0]?.message?.content ?? "[Traduzione vuota]"; | |||
} catch (err) { | } catch (err) { | ||
console.error("❌ Errore | console.error("❌ Errore traduzione:", err); | ||
return "[Errore Traduzione | return "[Errore Traduzione]"; | ||
} | } | ||
} | } | ||
| Riga 83: | Riga 83: | ||
for (let i = 0; i < blocchi.length; i++) { | for (let i = 0; i < blocchi.length; i++) { | ||
console.log(`🚀 Invio blocco ${i + 1}/${blocchi.length}…`); | console.log(`🚀 Invio blocco ${i + 1}/${blocchi.length}…`); | ||
const tradotto = await | const tradotto = await traduciBlocco(blocchi[i], lingua); | ||
risultato += tradotto.trim() + "\n\n"; | risultato += tradotto.trim() + "\n\n"; | ||
} | } | ||
| Riga 99: | Riga 99: | ||
} | } | ||
area.dispatchEvent(new Event("input", { bubbles: true })); | area.dispatchEvent(new Event("input", { bubbles: true })); | ||
area.dispatchEvent(new Event("change", { bubbles: true })); | area.dispatchEvent(new Event("change", { bubbles: true })); | ||
console.log("✅ Traduzione completata | console.log("✅ Traduzione completata."); | ||
} | } | ||
async function traduciTesto() { | async function traduciTesto() { | ||
const area = getEditor(); | const area = getEditor(); | ||
| Riga 114: | Riga 112: | ||
} | } | ||
const { text: selezione } = getSelectedTextInfo(); | const { text: selezione } = getSelectedTextInfo(); | ||
const conferma = confirm( | const conferma = confirm( | ||
" | "Vuoi tradurre SOLO il testo selezionato?\n\n✅ OK = solo selezione\n❌ Annulla = tutto il testo" | ||
); | ); | ||
if (conferma && !selezione) { | if (conferma && !selezione) { | ||
alert("⚠️ Nessuna selezione | alert("⚠️ Nessuna selezione trovata."); | ||
return; | return; | ||
} | } | ||
| Riga 129: | Riga 126: | ||
} | } | ||
const lingua = prompt("🌍 Scegli lingua di traduzione (es: it, en, fr, es, de):", "it"); | |||
const lingua = prompt( | |||
if (!lingua) return; | if (!lingua) return; | ||
const blocchi = segmentaTesto(testo); | const blocchi = segmentaTesto(testo); | ||
console.log("🧩 | console.log("🧩 Segmenti:", blocchi.length); | ||
await inviaTraduzione(blocchi, lingua, !conferma); | await inviaTraduzione(blocchi, lingua, !conferma); | ||
} | } | ||
/ | // Pulsante sotto editor | ||
function addTranslateButton() { | function addTranslateButton() { | ||
const area = getEditor(); | const area = getEditor(); | ||
| Riga 152: | Riga 143: | ||
btn.id = "btnCommonTranslate"; | btn.id = "btnCommonTranslate"; | ||
btn.className = "mw-ui-button"; | btn.className = "mw-ui-button"; | ||
btn.textContent = "🧠 Traduci contenuto | btn.textContent = "🧠 Traduci contenuto"; | ||
btn.style.margin = "8px 0"; | btn.style.margin = "8px 0"; | ||
btn.addEventListener("click", traduciTesto); | btn.addEventListener("click", traduciTesto); | ||
| Riga 159: | Riga 150: | ||
} | } | ||
if (typeof $ !== "undefined") { | if (typeof $ !== "undefined") { | ||
$(addTranslateButton); | $(addTranslateButton); | ||
Versione delle 14:17, 18 ago 2025
/* ======================= CommonTranslate.js (versione stabile precedente) ======================= */
console.log("🔄 Caricamento CommonTranslate.js…");
// Evita doppio caricamento
if (window.__CommonTranslateLoaded) {
console.warn("⚠️ CommonTranslate.js è già stato caricato.");
} else {
window.__CommonTranslateLoaded = true;
// Manteniamo la vecchia struttura con pulsante
const DEFAULT_MODEL = (window.openaiModel || "gpt-4o");
const LINGUA_ORIGINE = document.documentElement.lang || "en";
// 🔑 QUI usi ancora la chiave diretta (come avevi prima) → se preferisci il proxy si cambia solo questo pezzo
const API_URL = "https://api.openai.com/v1/chat/completions";
const API_KEY = window.apiKey || "INSERISCI_LA_TUA_API_KEY";
console.log("✅ CommonTranslate.js caricato. Modello:", DEFAULT_MODEL);
function getEditor() {
return document.getElementById("wpTextbox1");
}
function getSelectedTextInfo() {
const area = getEditor();
if (!area) return { text: "", start: 0, end: 0 };
const start = area.selectionStart;
const end = area.selectionEnd;
const text = area.value.slice(start, end);
return { text, start, end };
}
function segmentaTesto(testo, maxChars = 3000) {
const re = new RegExp(`.{1,${maxChars}}(?=\\s|$)`, "gs");
return testo.match(re) || [];
}
async function traduciBlocco(blocco, lingua, model = DEFAULT_MODEL) {
try {
const res = await fetch(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
model,
messages: [
{
role: "system",
content:
"You are a professional MediaWiki translator. Translate preserving templates, links, headings, lists and any wiki syntax. Do not add explanations."
},
{
role: "user",
content: `Translate the following text from ${LINGUA_ORIGINE} to ${lingua}:\n\n${blocco}`
}
],
temperature: 0
})
});
const data = await res.json();
if (!res.ok) {
const msg = data?.error?.message || `HTTP ${res.status}`;
throw new Error(msg);
}
return data?.choices?.[0]?.message?.content ?? "[Traduzione vuota]";
} catch (err) {
console.error("❌ Errore traduzione:", err);
return "[Errore Traduzione]";
}
}
async function inviaTraduzione(blocchi, lingua, sostituisciTutto) {
const area = getEditor();
if (!area) {
alert("❌ Campo editor non trovato (wpTextbox1).");
return;
}
let risultato = "";
for (let i = 0; i < blocchi.length; i++) {
console.log(`🚀 Invio blocco ${i + 1}/${blocchi.length}…`);
const tradotto = await traduciBlocco(blocchi[i], lingua);
risultato += tradotto.trim() + "\n\n";
}
risultato = risultato.trim();
if (sostituisciTutto) {
area.value = risultato;
} else {
const { start, end } = getSelectedTextInfo();
const prima = area.value.slice(0, start);
const dopo = area.value.slice(end);
area.value = prima + risultato + dopo;
area.selectionStart = start;
area.selectionEnd = start + risultato.length;
}
area.dispatchEvent(new Event("input", { bubbles: true }));
area.dispatchEvent(new Event("change", { bubbles: true }));
console.log("✅ Traduzione completata.");
}
async function traduciTesto() {
const area = getEditor();
if (!area) {
alert("❌ Editor non trovato.");
return;
}
const { text: selezione } = getSelectedTextInfo();
const conferma = confirm(
"Vuoi tradurre SOLO il testo selezionato?\n\n✅ OK = solo selezione\n❌ Annulla = tutto il testo"
);
if (conferma && !selezione) {
alert("⚠️ Nessuna selezione trovata.");
return;
}
const testo = conferma ? selezione : area.value;
if (!testo.trim()) {
alert("⚠️ Niente da tradurre.");
return;
}
const lingua = prompt("🌍 Scegli lingua di traduzione (es: it, en, fr, es, de):", "it");
if (!lingua) return;
const blocchi = segmentaTesto(testo);
console.log("🧩 Segmenti:", blocchi.length);
await inviaTraduzione(blocchi, lingua, !conferma);
}
// Pulsante sotto editor
function addTranslateButton() {
const area = getEditor();
if (!area) return;
if (document.getElementById("btnCommonTranslate")) return;
const btn = document.createElement("button");
btn.id = "btnCommonTranslate";
btn.className = "mw-ui-button";
btn.textContent = "🧠 Traduci contenuto";
btn.style.margin = "8px 0";
btn.addEventListener("click", traduciTesto);
area.parentNode.insertBefore(btn, area.nextSibling);
}
if (typeof $ !== "undefined") {
$(addTranslateButton);
} else {
document.addEventListener("DOMContentLoaded", addTranslateButton);
}
}