Widget:C.Translator

De Wiki Gla
Ir para navegação Ir para pesquisar

<script>

 (() => {
   let __langReqSeq = 0;
   // ---------- helpers ----------
   const normalizeLang = (s) => {
     s = (s || "").toLowerCase();
     if (s === "pt-br" || s === "pt_br" || s === "ptbr") return "pt";
     return s.split("-")[0] || "pt";
   };
   const markActive = (langFull) => {
     const lang = (langFull || "pt-br").toLowerCase();
     document.querySelectorAll(".char-flag[data-lang]").forEach((b) => {
       b.classList.toggle("active", b.dataset.lang === lang);
     });
   };
   const updateSkillsTabLabel = (norm) => {
     const map = {
       en: "Skills",
       pt: "Habilidades",
       es: "Habilidades",
       pl: "Umiejętności",
     };
     const btn =
       document.querySelector('.character-tabs .tab-btn[data-tab="skills"]') ||
       Array.from(document.querySelectorAll(".character-tabs .tab-btn")).find(
         (b) => /skill|habil|umiej/i.test(b.textContent || "")
       );
     if (btn) btn.textContent = map[norm] || map.pt;
   };
   // ---------- skills ----------
   const pickDescFor = (icon, norm) => {
     const keyMap = { pt: "descPt", en: "descEn", es: "descEs", pl: "descPl" };
     const order = [
       keyMap[norm],
       "descPt",
       "descEn",
       "descEs",
       "descPl",
     ].filter(Boolean);
     for (const k of order) {
       const v = (icon.dataset[k] || "").trim();
       if (v) return v;
     }
     return "";
   };
   const updateAllSkillDescs = (norm) => {
     document.querySelectorAll(".icon-bar .skill-icon").forEach((icon) => {
       icon.dataset.desc = pickDescFor(icon, norm);
     });
   };
   // ---------- tier & tags ----------
   const updateTierAndTags = (norm) => {
     const cont = document.querySelector(".class-tags");
     if (!cont) return;
     const tier = cont.querySelector(".class-tag.tier");
     if (tier) {
       const t =
         tier.getAttribute("data-tier-" + norm) ||
         tier.getAttribute("data-tier-pt") ||
         tier.getAttribute("data-tier-en") ||
         tier.getAttribute("data-tier-es") ||
         tier.getAttribute("data-tier-pl") ||
         "";
       if (t) tier.textContent = t;
     }
     let tags = [];
     const pack = cont.getAttribute("data-tags-i18n");
     if (pack) {
       try {
         const obj = JSON.parse(pack);
         const arr =
           obj?.[norm] || obj?.pt || obj?.en || obj?.es || obj?.pl || [];
         if (Array.isArray(arr)) tags = arr;
       } catch (e) { }
     }
     if (!tags.length) {
       const raw =
         cont.getAttribute("data-tags-" + norm) ||
         cont.getAttribute("data-tags-pt") ||
         cont.getAttribute("data-tags-en") ||
         cont.getAttribute("data-tags-es") ||
         cont.getAttribute("data-tags-pl") ||
         "";
       if (raw) {
         try {
           const maybe = JSON.parse(raw);
           if (Array.isArray(maybe)) tags = maybe;
         } catch (e) { }
         if (!tags.length && typeof raw === "string") {
           tags = raw
             .split(",")
             .map((s) => s.trim())
             .filter(Boolean);
         }
       }
     }
     if (!tags.length) return;
     // Tags invisíveis (não devem ser exibidas na wiki)
     const HIDDEN_TAGS = {
       mulher: true,
       woman: true,
       mujer: true,
       kobieta: true,
     };
     cont
       .querySelectorAll(".class-tag:not(.tier)")
       .forEach((el) => el.remove());
     tags.forEach((t) => {
       // Filtra tags invisíveis
       const normalized = (t || "").toLowerCase().trim();
       if (HIDDEN_TAGS[normalized]) return;
       const chip = document.createElement("span");
       chip.className = "class-tag";
       chip.textContent = t;
       cont.appendChild(chip);
     });
   };
   // ---------- FLAGS: tooltips i18n ----------
   const updateFlagTooltips = (norm) => {
     const skillsRoot = document.querySelector("#skills");
     if (!skillsRoot) return;
     let pack = {};
     try {
       pack = JSON.parse(skillsRoot.dataset.i18nFlags || "{}");
     } catch (e) { }
     const dict = pack[norm] || pack.pt || {};
     const tooltip = window.__globalSkillTooltip;
     if (!tooltip) return;
     document
       .querySelectorAll(".skill-flags .skill-flag[data-flag]")
       .forEach((el) => {
         delete el.dataset.flagTipWired;
       });
     const descBoxes = document.querySelectorAll(".desc-box");
     descBoxes.forEach((box) => {
       if (box.querySelector(".skill-flags")) {
         const flags = box.querySelectorAll(
           ".skill-flags .skill-flag[data-flag]"
         );
         flags.forEach((el) => {
           const key = el.getAttribute("data-flag");
           const tip = (dict && dict[key]) || "";
           if (!tip) return;
           delete el.dataset.flagTipWired;
           el.setAttribute("aria-label", tip);
           if (el.hasAttribute("title")) el.removeAttribute("title");
           el.addEventListener("mouseenter", () => {
             const tipEl = document.querySelector(".skill-tooltip");
             if (tipEl) tipEl.classList.add("flag-tooltip");
             tooltip.show(el, tip);
           });
           el.addEventListener("mousemove", () => {
             if (performance.now() >= tooltip.lockUntil.value) {
               tooltip.measureAndPos(el);
             }
           });
           el.addEventListener("click", () => {
             tooltip.lockUntil.value = performance.now() + 240;
             tooltip.measureAndPos(el);
           });
           el.addEventListener("mouseleave", () => {
             const tipEl = document.querySelector(".skill-tooltip");
             if (tipEl) tipEl.classList.remove("flag-tooltip");
             tooltip.hide();
           });
           el.dataset.flagTipWired = "1";
         });
       }
     });
   };
   // ---------- SKINS: tooltips i18n ----------
   const updateSkinTooltips = (norm) => {
     const root = document.querySelector("#skins");
     if (!root) return;
     const slots = root.querySelectorAll(".podium-slot");
     if (!slots.length) return;
     slots.forEach((slot) => {
       const title = slot.getAttribute("data-skin-title") || "";
       const pack = slot.getAttribute("data-skin-tooltip-i18n");
       const titleHtml = title

 ? '

' +
         title +
"

"

         : "";
       if (pack) {
         let chosen = "";
         try {
           const obj = JSON.parse(pack);
           chosen = (
             obj[norm] ||
             obj.pt ||
             obj.en ||
             obj.es ||
             obj.pl ||
             ""
           ).trim();
         } catch (e) { }
         if (chosen) {
           let bodyHtml = chosen
             .replace(/([^']+)/g, "$1")
             .replace(/\n/g, "
"); bodyHtml = "" + bodyHtml + ""; slot.setAttribute("data-skin-tooltip", titleHtml + bodyHtml); } return; }
       if (title) {
         const current = slot.getAttribute("data-skin-tooltip") || "";
         if (!/skin-tooltip-title/.test(current)) {
           let bodyHtml = current;
           if (!/^[\s\S]*<\/b>$/.test(bodyHtml)) {
             bodyHtml = "" + bodyHtml + "";
           }
           slot.setAttribute("data-skin-tooltip", titleHtml + bodyHtml);
         }
       }
     });
     const hovered = root.querySelector(".podium-slot.hovered");
     const liveTip = document.querySelector(
       '.skin-tooltip[aria-hidden="false"], .skin-tooltip.show'
     );
     if (hovered && liveTip) {
       liveTip.innerHTML = hovered.getAttribute("data-skin-tooltip") || "";
     }
   };
   // ---------- APPLY ----------
   const applyLang = (langFull) => {
     const myReq = ++__langReqSeq;
     const norm = normalizeLang(langFull);
     const langTag = (langFull || "pt-br").toLowerCase();
     markActive(langFull);
     document.documentElement.lang = langTag;
     try {
       localStorage.setItem("glaLang", langTag);
     } catch (e) { }
     updateSkillsTabLabel(norm);
     updateAllSkillDescs(norm);
     updateTierAndTags(norm);
     updateSkinTooltips(norm);
     updateFlagTooltips(norm);
     try {
       window.dispatchEvent(
         new CustomEvent("gla:langChanged", { detail: { norm } })
       );
     } catch (e) { }
     document.body.dataset.suppressSkillPlay = "1";
     requestAnimationFrame(() => {
       if (myReq !== __langReqSeq) {
         delete document.body.dataset.suppressSkillPlay;
         return;
       }
       const lastIcon = window.__lastActiveSkillIcon;
       if (lastIcon && typeof lastIcon.click === "function") {
         lastIcon.click();
       }
       setTimeout(() => {
         if (myReq === __langReqSeq)
           delete document.body.dataset.suppressSkillPlay;
       }, 120);
     });
   };
   // ---------- BOOT ----------
   const ensureControlsPosition = () => {
     const controls = document.querySelector(".character-header-controls");
     const header = document.querySelector(".character-header");
     if (controls && header && !header.contains(controls)) {
       header.appendChild(controls);
       return true;
     }
     return false;
   };
   const boot = () => {
     // Tenta mover o character-header-controls para dentro do character-header
     // Se não conseguir, tenta novamente após um delay
     const tryMove = () => {
       const controls = document.querySelector(".character-header-controls");
       const header = document.querySelector(".character-header");
       if (controls && header) {
         if (!header.contains(controls)) {
           header.appendChild(controls);
         }
         return true;
       }
       return false;
     };
     if (!tryMove()) {
       let attempts = 0;
       const maxAttempts = 20;
       const checkInterval = setInterval(() => {
         attempts++;
         if (tryMove() || attempts >= maxAttempts) {
           clearInterval(checkInterval);
         }
       }, 100);
     }
     document.addEventListener("click", (ev) => {
       const btn = ev.target.closest(".char-flag[data-lang]");
       if (!btn) return;
       ev.preventDefault();
       applyLang(btn.dataset.lang || "pt-br");
     });
     let start = "pt-br";
     try {
       const saved = localStorage.getItem("glaLang");
       if (saved) start = saved;
     } catch (e) { }
     applyLang(start);
   };
   if (document.readyState === "loading") {
     document.addEventListener("DOMContentLoaded", boot);
   } else {
     boot();
   }
 })();

</script>

   <button class="char-flag" data-lang="pt-br" title="Português (Brasil)" aria-label="Português (Brasil)">
     <img src="https://wiki.gla.com.br/images/8/8c/Brazil.png" alt="Português (Brasil)" />
   </button>
   <button class="char-flag" data-lang="en" title="English" aria-label="English">
     <img src="https://wiki.gla.com.br/images/0/0a/Usa.png" alt="English" />
   </button>
   <button class="char-flag" data-lang="es" title="Español" aria-label="Español">
     <img src="https://wiki.gla.com.br/images/5/58/Spain.png" alt="Español" />
   </button>
   <button class="char-flag" data-lang="pl" title="Polski" aria-label="Polski">
     <img src="https://wiki.gla.com.br/images/9/99/Poland.png" alt="Polski" />
   </button>

<style>

 :root {
   --ct-bg: rgba(0, 0, 0, 0.35);
   --ct-bd: rgba(255, 255, 255, 0.15);
   --ct-active: #3b82f6;
   --ct-active-bg: rgba(59, 130, 246, 0.14);
   --ct-active-bd: rgba(59, 130, 246, 0.45);
   --ct-hover-bd: rgba(255, 255, 255, 0.3);
 }
 .character-box .character-header {
   position: relative;
 }
 /* Container para organizar translator e weapon toggle em blocos separados */
 .character-header-controls {
   position: absolute;
   top: 8px;
   right: 8px;
   display: flex;
   flex-direction: column;
   gap: 8px;
   z-index: 10;
   align-items: flex-end;
 }
 .char-translator {
   display: flex;
   gap: 6px;
   background: var(--ct-bg);
   padding: 4px;
   border-radius: 8px;
   border: 1px solid var(--ct-bd);
   -webkit-backdrop-filter: blur(2px);
   backdrop-filter: blur(2px);
   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
 }
 .char-flag {
   width: 32px;
   height: 24px;
   padding: 0;
   border-radius: 6px;
   border: 1px solid rgba(255, 255, 255, 0.18);
   background: rgba(255, 255, 255, 0.06);
   display: flex;
   align-items: center;
   justify-content: center;
   cursor: pointer;
   overflow: hidden;
   transition: transform 0.08s ease, border-color 0.15s ease,
     background 0.15s ease, outline-color 0.15s ease;
   outline: 2px solid transparent;
   box-sizing: border-box;
 }
 .char-flag:hover {
   border-color: var(--ct-hover-bd);
   transform: translateY(-1px);
 }
 .char-flag:focus-visible {
   outline-color: var(--ct-active);
   outline-offset: 2px;
 }
 .char-flag img {
   width: 100%;
   height: 100%;
   object-fit: cover;
   display: block;
   pointer-events: none;
 }
 .char-flag.active {
   outline-color: var(--ct-active);
   background: var(--ct-active-bg);
   border-color: var(--ct-active-bd);
 }
 @media (max-width: 600px) {
   .character-header-controls {
     top: 6px;
     right: 6px;
     gap: 6px;
   }
   .char-translator {
     gap: 4px;
     padding: 3px;
   }
   .char-flag {
     width: 28px;
     height: 20px;
     padding: 0;
     border-radius: 5px;
   }
 }

</style>