Greasy Fork is available in English.

MyAnimeList Synopsis Auto-Translator

Traduce la descripción del anime y manga en MyAnimeList de manera automática.

// ==UserScript==
// @name         MyAnimeList Synopsis Auto-Translator
// @namespace    https://greasyfork.org/scripts/463192
// @version      2.5
// @description:en Automatically translates MyAnimeList anime and manga descriptions.
// @description:es Traduce automáticamente las descripciones de anime y manga en MyAnimeList.
// @author       Shu2Ouma
// @icon         https://cdn.myanimelist.net/images/favicon.ico
// @match        https://myanimelist.net/anime/*
// @match        https://myanimelist.net/manga/*
// @grant        GM_xmlhttpRequest
// @license      MIT
// @description Traduce la descripción del anime y manga en MyAnimeList de manera automática.
// ==/UserScript==

// Define los idiomas disponibles
const idiomas = [
  { codigo: "af", nombre: "Afrikaans" }, // Afrikaans
  { codigo: "am", nombre: "አማርኛ" }, // Amharic
  { codigo: "ar", nombre: "العربية" }, // Arabic
  { codigo: "az", nombre: "Azərbaycanca" }, // Azerbaijani
  { codigo: "be", nombre: "Беларуская" }, // Belarusian
  { codigo: "bg", nombre: "Български" }, // Bulgarian
  { codigo: "bn", nombre: "বাংলা" }, // Bengali
  { codigo: "bs", nombre: "Bosanski" }, // Bosnian
  { codigo: "ca", nombre: "Català" }, // Catalan
  { codigo: "ceb", nombre: "Cebuano" }, // Cebuano
  { codigo: "cs", nombre: "Čeština" }, // Czech
  { codigo: "cy", nombre: "Cymraeg" }, // Welsh
  { codigo: "da", nombre: "Dansk" }, // Danish
  { codigo: "de", nombre: "Deutsch" }, // German
  { codigo: "el", nombre: "Ελληνικά" }, // Greek
  { codigo: "en", nombre: "English" }, // English
  { codigo: "eo", nombre: "Esperanto" }, // Esperanto
  { codigo: "es", nombre: "Español" }, // Spanish
  { codigo: "et", nombre: "Eesti" }, // Estonian
  { codigo: "eu", nombre: "Euskara" }, // Basque
  { codigo: "fa", nombre: "فارسی" }, // Persian
  { codigo: "fi", nombre: "Suomi" }, // Finnish
  { codigo: "fil", nombre: "Filipino" }, // Filipino
  { codigo: "fr", nombre: "Français" }, // French
  { codigo: "fy", nombre: "Frysk" }, // Frisian
  { codigo: "ga", nombre: "Gaeilge" }, // Irish
  { codigo: "gd", nombre: "Gàidhlig" }, // Scottish Gaelic
  { codigo: "gl", nombre: "Galego" }, // Galician
  { codigo: "gu", nombre: "ગુજરાતી" }, // Gujarati
  { codigo: "ha", nombre: "Hausa" }, // Hausa
  { codigo: "haw", nombre: "ʻŌlelo Hawaiʻi" }, // Hawaiian
  { codigo: "hi", nombre: "हिन्दी" }, // Hindi
  { codigo: "hmn", nombre: "Hmong" }, // Hmong
  { codigo: "hr", nombre: "Hrvatski" }, // Croatian
  { codigo: "ht", nombre: "Kreyòl Ayisyen" }, // Haitian Creole
  { codigo: "hu", nombre: "Magyar" }, // Hungarian
  { codigo: "hy", nombre: "Հայերեն" }, // Armenian
  { codigo: "id", nombre: "Bahasa Indonesia" }, // Indonesian
  { codigo: "ig", nombre: "Igbo" }, // Igbo
  { codigo: "is", nombre: "Íslenska" }, // Icelandic
  { codigo: "it", nombre: "Italiano" }, // Italian
  { codigo: "ja", nombre: "日本語" }, // Japanese
  { codigo: "jv", nombre: "Basa Jawa" }, // Javanese
  { codigo: "ka", nombre: "ქართული" }, // Georgian
  { codigo: "kk", nombre: "Қазақ Тілі" }, // Kazakh
  { codigo: "km", nombre: "ភាសាខ្មែរ" }, // Khmer
  { codigo: "kn", nombre: "ಕನ್ನಡ" }, // Kannada
  { codigo: "ko", nombre: "한국어" }, // Korean
  { codigo: "ku", nombre: "Kurdî" }, // Kurdish
  { codigo: "ky", nombre: "Кыргызча" }, // Kyrgyz
  { codigo: "la", nombre: "Latina" }, // Latin
  { codigo: "lb", nombre: "Lëtzebuergesch" }, // Luxembourgish
  { codigo: "lo", nombre: "ພາສາລາວ" }, // Lao
  { codigo: "lt", nombre: "Lietuvių" }, // Lithuanian
  { codigo: "lv", nombre: "Latviešu" }, // Latvian
  { codigo: "mg", nombre: "Malagasy" }, // Malagasy
  { codigo: "mi", nombre: "Māori" }, // Māori
  { codigo: "mk", nombre: "Македонски" }, // Macedonian
  { codigo: "ml", nombre: "മലയാളം" }, // Malayalam
  { codigo: "mn", nombre: "Монгол" }, // Mongolian
  { codigo: "mr", nombre: "मराठी" }, // Marathi
  { codigo: "ms", nombre: "Bahasa Melayu" }, // Malay
  { codigo: "mt", nombre: "Malti" }, // Maltese
  { codigo: "my", nombre: "မြန်မာ" }, // Burmese
  { codigo: "ne", nombre: "नेपाली" }, // Nepali
  { codigo: "nl", nombre: "Nederlands" }, // Dutch
  { codigo: "no", nombre: "Norsk" }, // Norwegian
  { codigo: "ny", nombre: "Chichewa" }, // Chichewa
  { codigo: "or", nombre: "ଓଡ଼ିଆ" }, // Oriya
  { codigo: "pa", nombre: "ਪੰਜਾਬੀ" }, // Punjabi
  { codigo: "pl", nombre: "Polski" }, // Polish
  { codigo: "ps", nombre: "پښتو" }, // Pashto
  { codigo: "pt", nombre: "Português" }, // Portuguese
  { codigo: "ro", nombre: "Română" }, // Romanian
  { codigo: "ru", nombre: "Русский" }, // Russian
  { codigo: "sd", nombre: "سنڌي" }, // Sindhi
  { codigo: "si", nombre: "සිංහල" }, // Sinhala
  { codigo: "sk", nombre: "Slovenčina" }, // Slovak
  { codigo: "sl", nombre: "Slovenščina" }, // Slovenian
  { codigo: "sm", nombre: "Gagana Samoa" }, // Samoan
  { codigo: "sn", nombre: "ChiShona" }, // Shona
  { codigo: "so", nombre: "Soomaaliga" }, // Somali
  { codigo: "sq", nombre: "Shqip" }, // Albanian
  { codigo: "sr", nombre: "Српски" }, // Serbian
  { codigo: "st", nombre: "Sesotho" }, // Sesotho
  { codigo: "su", nombre: "Basa Sunda" }, // Sundanese
  { codigo: "sv", nombre: "Svenska" }, // Swedish
  { codigo: "sw", nombre: "Kiswahili" }, // Swahili
  { codigo: "ta", nombre: "தமிழ்" }, // Tamil
  { codigo: "te", nombre: "తెలుగు" }, // Telugu
  { codigo: "tg", nombre: "Тоҷикӣ" }, // Tajik
  { codigo: "th", nombre: "ไทย" }, // Thai
  { codigo: "tl", nombre: "Tagalog" }, // Filipino (Tagalog)
  { codigo: "tr", nombre: "Türkçe" }, // Turkish
  { codigo: "uk", nombre: "Українська" }, // Ukrainian
  { codigo: "ur", nombre: "اردو" }, // Urdu
  { codigo: "uz", nombre: "Oʻzbekcha" }, // Uzbek
  { codigo: "vi", nombre: "Tiếng Việt" }, // Vietnamese
  { codigo: "xh", nombre: "isiXhosa" }, // Xhosa
  { codigo: "yi", nombre: "ייִדיש" }, // Yiddish
  { codigo: "yo", nombre: "Yorùbá" }, // Yoruba
  { codigo: "zh-CN", nombre: "中文 (简体)" }, // Chinese Simplified
  { codigo: "zh-TW", nombre: "中文 (繁體)" }, // Chinese Traditional
  { codigo: "zu", nombre: "isiZulu" }, // Zulu
];

// Función para crear la lista desplegable de idiomas
const crearListaDesplegable = () => {
  const selectIdioma = document.createElement('select');
  selectIdioma.id = 'selectIdioma';
  selectIdioma.style.cssText = 'background-color: #fff; border: #0400fe 1.5px solid; border-radius: 4px; color: #323232; display: inline-block; font-family: Avenir,lucida grande,tahoma,verdana,arial,sans-serif; font-size: 11px; padding: 3.5px 8px; text-align: left; text-decoration: none; vertical-align: middle; margin-left: 8px;';

  // Ordena los idiomas alfabéticamente
  idiomas.sort((a, b) => a.nombre.localeCompare(b.nombre));

  // Agrega los idiomas a la lista desplegable
  idiomas.forEach(idioma => {
    const option = document.createElement('option');
    option.value = idioma.codigo;
    option.text = idioma.nombre;
    selectIdioma.appendChild(option);
  });

  // Establece el idioma seleccionado
  const idiomaGuardado = localStorage.getItem('idiomaSeleccionado');
  if (idiomaGuardado) {
    selectIdioma.value = idiomaGuardado;
  }

  return selectIdioma;
};

// Función para manejar el evento de cambio de idioma
const manejarCambioIdioma = () => {
  const idiomaSeleccionado = selectIdioma.value;
  localStorage.setItem('idiomaSeleccionado', idiomaSeleccionado);
  traducirDescripciones(idiomaSeleccionado);
};

// Define el estilo de texto que se aplicará a las etiquetas <p> y <span>
const estiloTexto = "font-size: 100%;"; // Cambiar el valor para ajustar el tamaño del texto

// Traduce las descripciones al idioma seleccionado
const traducirDescripciones = idiomaSeleccionado => {
  const descripciones = document.querySelectorAll('p.preline, p[itemprop="description"], span[itemprop="description"], div.synopsis.js-synopsis p, div.pt4');
  descripciones.forEach(descripcion => {
    if ((descripcion.tagName === "P" && descripcion.getAttribute("itemprop") === "description") ||
        (descripcion.tagName === "SPAN" && descripcion.getAttribute("itemprop") === "description")) {
      descripcion.style = estiloTexto;
    }
    const textoLinea = descripcion.innerHTML.trim();

    GM_xmlhttpRequest({
      method: "GET",
      url: `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${idiomaSeleccionado}&dt=t&q=${encodeURI(textoLinea)}`,
      onload: function(response) {
        const resultado = JSON.parse(response.responseText);
        const textoTraducido = resultado[0].map(function(elemento){ return elemento[0]; }).join('');
        descripcion.innerHTML = textoTraducido;
      }
    });
  });
};

// Espera a que se cargue completamente la página antes de ejecutar el script
window.addEventListener('load', () => {
  const selectIdioma = crearListaDesplegable();
  const idiomaSeleccionado = localStorage.getItem('idiomaSeleccionado');
  if (idiomaSeleccionado) {
    selectIdioma.value = idiomaSeleccionado;
    traducirDescripciones(idiomaSeleccionado);
  }

  // Agrega el evento de cambio de idioma
  selectIdioma.addEventListener('change', manejarCambioIdioma);

  // Busca el elemento donde deseamos insertar la lista de idiomas
  let divElement = document.querySelector('div.user-status-block.js-user-status-block.fn-grey6.clearfix.al.mt8.po-r[data-type="manga"]');
  if (!divElement) {
    divElement = document.querySelector('div.user-status-block.js-user-status-block.fn-grey6.clearfix.al.mt8.po-r');
  }

  if (!divElement) {
    // Si no se encuentra el elemento de destino, lo manejamos de otra manera
    const targetElement = document.querySelector('div.horiznav_nav ul');
    if (targetElement) {
      // Insertamos la lista desplegable en el lugar correspondiente
      const lastListItem = targetElement.querySelector('li:last-child');
      if (lastListItem) {
        targetElement.insertBefore(selectIdioma, lastListItem.nextSibling);
      } else {
        targetElement.prepend(selectIdioma);
      }
    } else {
      // Si no se encuentra ningún elemento de destino, manejamos la situación de otra manera
      const container = document.createElement('div');
      container.style.cssText = 'position: fixed; right: 10px; top: 50%; transform: translate(0, -50%);';
      document.body.appendChild(container);
      divElement = container;
    }
  } else {
    // Insertamos la lista desplegable en el lugar correspondiente
    divElement.appendChild(selectIdioma);
  }

  // Añadimos margen inferior al div principal
  divElement.style.marginBottom = '10px';
});