MediaWiki:Common.js: Difference between revisions

From koreapedia
No edit summary
No edit summary
 
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */
/* Google Translate widget for Chameleon skin (selected languages only) */
/* Google Translate widget for Chameleon skin (selected languages only) — SAFE FOR VE */


(function () {
(function () {
   var LANGS = 'ko,ja,es,de,zh-CN,zh-TW,fr,ar,hi,pt,ru'; // note: no 'en' (it's pageLanguage)
   // ---- guards: never run on editor/VE or without Chameleon navbar ----
  var CONTAINER_ID = 'google_translate_element';
  mw.loader.using(['mediawiki.util']).then(function () {
    var isVE = mw.util.getParamValue('veaction') === 'edit';
    var isEdit = mw.config.get('wgAction') === 'edit';
    var isChameleon = mw.config.get('skin') === 'chameleon';
    var hasNavbar = !!document.querySelector('.navbar-collapse');


  // Ensure container exists before init
     if (isVE || isEdit || !isChameleon || !hasNavbar) {
  function ensureContainer() {
       return; // bail out: do not touch DOM or load scripts while editing / wrong skin
     if (!document.getElementById(CONTAINER_ID)) {
      var host = document.querySelector('.navbar-collapse') || document.body;
      var el = document.createElement('div');
       el.id = CONTAINER_ID;
      el.style.marginLeft = '15px';
      host.appendChild(el);
     }
     }
  }


  // NEW callback name to bust any stale init
    var LANGS = 'ko,ja,es,de,zh-CN,zh-TW,fr,ar,hi,pt,ru';
  window.koreapediaGTEInit = function () {
     var CONTAINER_ID = 'google_translate_element';
    ensureContainer();
    new google.translate.TranslateElement({
      pageLanguage: 'en',
      includedLanguages: LANGS,
      layout: google.translate.TranslateElement.InlineLayout.SIMPLE
     }, CONTAINER_ID);
  };


  // Load script only if needed; otherwise call init directly
    function ensureContainer() {
  function loadOrInit() {
      // only attach inside the Chameleon navbar; never fall back to <body> on VE
    // If library is already there, just init with our options
      var host = document.querySelector('.navbar-collapse');
    if (window.google && google.translate && google.translate.TranslateElement) {
      if (!host) return;
      window.koreapediaGTEInit();
      if (!document.getElementById(CONTAINER_ID)) {
       return;
        var el = document.createElement('div');
        el.id = CONTAINER_ID;
        el.style.marginLeft = '15px';
        host.appendChild(el);
       }
     }
     }
    // Avoid adding duplicate script tags
    if (!document.querySelector('script[src*="translate_a/element.js"]')) {
      var s = document.createElement('script');
      s.src = '//translate.google.com/translate_a/element.js?cb=koreapediaGTEInit';
      document.head.appendChild(s);
    }
  }


  mw.loader.using('mediawiki.util', function () {
    // dedicated init
     $(function () {
     window.koreapediaGTEInit = function () {
       ensureContainer();
       ensureContainer();
       loadOrInit();
       if (!(window.google && google.translate && google.translate.TranslateElement)) return;
    });
      new google.translate.TranslateElement({
  });
        pageLanguage: 'en',
})();
        includedLanguages: LANGS,
        layout: google.translate.TranslateElement.InlineLayout.SIMPLE
      }, CONTAINER_ID);
    };
 
    function loadOrInit() {
      if (window.google && google.translate && google.translate.TranslateElement) {
        window.koreapediaGTEInit();
        return;
      }
      if (!document.querySelector('script[src*="translate_a/element.js"]')) {
        var s = document.createElement('script');
        s.src = 'https://translate.google.com/translate_a/element.js?cb=koreapediaGTEInit';
        document.head.appendChild(s);
      }
    }


/* ==== Force single-column Google Translate menu (robust) ==== */
    // ---- Only attach styling logic when the widget can actually appear (read view) ----
(function () {
    (function () {
  var RIGHT_INSET = 160;   // how much of the right side to hide (px)
      var RIGHT_INSET = 160;
  var FRAME_WIDTH = 500;   // visible width (px)
      var FRAME_WIDTH = 500;


  function styleMenuFrame(f) {
      function styleMenuFrame(f) {
    try {
        try {
      f.style.setProperty('width', FRAME_WIDTH + 'px', 'important');
          f.style.setProperty('width', FRAME_WIDTH + 'px', 'important');
      f.style.setProperty('maxWidth', FRAME_WIDTH + 'px', 'important');
          f.style.setProperty('maxWidth', FRAME_WIDTH + 'px', 'important');
      f.style.setProperty('borderRadius', '8px', 'important');
          f.style.setProperty('borderRadius', '8px', 'important');
      f.style.setProperty('boxShadow', '0 8px 24px rgba(0,0,0,.18)', 'important');
          f.style.setProperty('boxShadow', '0 8px 24px rgba(0,0,0,.18)', 'important');
      f.style.setProperty('clip-path', 'inset(0 ' + RIGHT_INSET + 'px 0 0)', 'important');
          f.style.setProperty('clip-path', 'inset(0 ' + RIGHT_INSET + 'px 0 0)', 'important');
      f.style.setProperty('-webkit-clip-path', 'inset(0 ' + RIGHT_INSET + 'px 0 0)', 'important');
          f.style.setProperty('-webkit-clip-path', 'inset(0 ' + RIGHT_INSET + 'px 0 0)', 'important');
      f.style.setProperty('overflow', 'hidden', 'important');
          f.style.setProperty('overflow', 'hidden', 'important');
      f.style.setProperty('zIndex', '999999', 'important');
          f.style.setProperty('zIndex', '999999', 'important');
    } catch (e) {}
        } catch (e) {}
  }
      }


  function findAndStyle() {
      function findAndStyle() {
    var frames = document.querySelectorAll(
        var frames = document.querySelectorAll(
      'iframe.goog-te-menu-frame, iframe[id*="goog-te-menu"], iframe[src*="translate.googleapis.com"], iframe[src*="translate.google.com"]'
          'iframe.goog-te-menu-frame, iframe[id*="goog-te-menu"], iframe[src*="translate.googleapis.com"], iframe[src*="translate.google.com"]'
    );
        );
    frames.forEach(styleMenuFrame);
        frames.forEach(styleMenuFrame);
  }
      }


  // Style when user opens the dropdown
      document.addEventListener('click', function (e) {
  document.addEventListener('click', function (e) {
        var el = e.target.closest && e.target.closest('#google_translate_element');
    if (e.target.closest('#google_translate_element')) {
        if (el) {
      setTimeout(findAndStyle, 120);
          setTimeout(findAndStyle, 120);
      setTimeout(findAndStyle, 400); // second pass for late loads
          setTimeout(findAndStyle, 400);
    }
        }
  });
      });


  // Also style on resize (menu can reflow)
      window.addEventListener('resize', function () {
  window.addEventListener('resize', function () {
        setTimeout(findAndStyle, 150);
    setTimeout(findAndStyle, 150);
      });
  });


  // Watch the DOM for when Google injects the iframe
      // scope the observer only on read view; avoid observing whole document in editors
  var mo = new MutationObserver(function () { setTimeout(findAndStyle, 50); });
      var mo = new MutationObserver(function () { setTimeout(findAndStyle, 50); });
  mo.observe(document.documentElement, { childList: true, subtree: true });
      mo.observe(document.body, { childList: true, subtree: true });


  // One initial attempt
      // init
  findAndStyle();
      $(function () {
        ensureContainer();
        loadOrInit();
        findAndStyle();
      });
    })();
  });
})();
})();

Latest revision as of 17:04, 2 November 2025

/* Any JavaScript here will be loaded for all users on every page load. */
/* Google Translate widget for Chameleon skin (selected languages only) — SAFE FOR VE */

(function () {
  // ---- guards: never run on editor/VE or without Chameleon navbar ----
  mw.loader.using(['mediawiki.util']).then(function () {
    var isVE = mw.util.getParamValue('veaction') === 'edit';
    var isEdit = mw.config.get('wgAction') === 'edit';
    var isChameleon = mw.config.get('skin') === 'chameleon';
    var hasNavbar = !!document.querySelector('.navbar-collapse');

    if (isVE || isEdit || !isChameleon || !hasNavbar) {
      return; // bail out: do not touch DOM or load scripts while editing / wrong skin
    }

    var LANGS = 'ko,ja,es,de,zh-CN,zh-TW,fr,ar,hi,pt,ru';
    var CONTAINER_ID = 'google_translate_element';

    function ensureContainer() {
      // only attach inside the Chameleon navbar; never fall back to <body> on VE
      var host = document.querySelector('.navbar-collapse');
      if (!host) return;
      if (!document.getElementById(CONTAINER_ID)) {
        var el = document.createElement('div');
        el.id = CONTAINER_ID;
        el.style.marginLeft = '15px';
        host.appendChild(el);
      }
    }

    // dedicated init
    window.koreapediaGTEInit = function () {
      ensureContainer();
      if (!(window.google && google.translate && google.translate.TranslateElement)) return;
      new google.translate.TranslateElement({
        pageLanguage: 'en',
        includedLanguages: LANGS,
        layout: google.translate.TranslateElement.InlineLayout.SIMPLE
      }, CONTAINER_ID);
    };

    function loadOrInit() {
      if (window.google && google.translate && google.translate.TranslateElement) {
        window.koreapediaGTEInit();
        return;
      }
      if (!document.querySelector('script[src*="translate_a/element.js"]')) {
        var s = document.createElement('script');
        s.src = 'https://translate.google.com/translate_a/element.js?cb=koreapediaGTEInit';
        document.head.appendChild(s);
      }
    }

    // ---- Only attach styling logic when the widget can actually appear (read view) ----
    (function () {
      var RIGHT_INSET = 160;
      var FRAME_WIDTH = 500;

      function styleMenuFrame(f) {
        try {
          f.style.setProperty('width', FRAME_WIDTH + 'px', 'important');
          f.style.setProperty('maxWidth', FRAME_WIDTH + 'px', 'important');
          f.style.setProperty('borderRadius', '8px', 'important');
          f.style.setProperty('boxShadow', '0 8px 24px rgba(0,0,0,.18)', 'important');
          f.style.setProperty('clip-path', 'inset(0 ' + RIGHT_INSET + 'px 0 0)', 'important');
          f.style.setProperty('-webkit-clip-path', 'inset(0 ' + RIGHT_INSET + 'px 0 0)', 'important');
          f.style.setProperty('overflow', 'hidden', 'important');
          f.style.setProperty('zIndex', '999999', 'important');
        } catch (e) {}
      }

      function findAndStyle() {
        var frames = document.querySelectorAll(
          'iframe.goog-te-menu-frame, iframe[id*="goog-te-menu"], iframe[src*="translate.googleapis.com"], iframe[src*="translate.google.com"]'
        );
        frames.forEach(styleMenuFrame);
      }

      document.addEventListener('click', function (e) {
        var el = e.target.closest && e.target.closest('#google_translate_element');
        if (el) {
          setTimeout(findAndStyle, 120);
          setTimeout(findAndStyle, 400);
        }
      });

      window.addEventListener('resize', function () {
        setTimeout(findAndStyle, 150);
      });

      // scope the observer only on read view; avoid observing whole document in editors
      var mo = new MutationObserver(function () { setTimeout(findAndStyle, 50); });
      mo.observe(document.body, { childList: true, subtree: true });

      // init
      $(function () {
        ensureContainer();
        loadOrInit();
        findAndStyle();
      });
    })();
  });
})();