User:CannonProductions/monacobookbeta.js

From MediaWiki
Revision as of 12:17, 30 December 2025 by CannonProductions (talk | contribs)
Jump to navigationJump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* User:CannonProductions/monacobookbeta.js
   - Dynamically scales #top-ad iframe banner to fit available width on mobile
   - Adds/removes html.tf-nav-open when the sidebar (#column-one) is open
*/

(function () {
  "use strict";

  // === SETTINGS ===
  var MOBILE_MAX_WIDTH = 720;

  // Banner creative’s native size
  var BASE_W = 468;
  var BASE_H = 60;

  // Banner scale limits
  var MIN_SCALE = 0.55;
  var MAX_SCALE = 1.0;

  function onReady(fn) {
    if (document.readyState === "loading") {
      document.addEventListener("DOMContentLoaded", fn);
    } else {
      fn();
    }
  }

  function isMobileWidth() {
    return window.matchMedia("(max-width: " + MOBILE_MAX_WIDTH + "px)").matches;
  }

  // ===== Banner scaling =====
  function resetBannerStyles(ad, iframe) {
    if (ad) {
      ad.style.height = "";
      ad.style.overflow = "";
      ad.style.width = "";
    }
    if (iframe) {
      iframe.style.transform = "";
      iframe.style.transformOrigin = "";
      iframe.style.width = "";
      iframe.style.height = "";
      iframe.style.border = "";
      iframe.style.display = "";
    }
  }

  function rescaleBanner() {
    var ad = document.getElementById("top-ad");
    if (!ad) return;

    var iframe = ad.querySelector("iframe");
    if (!iframe) return;

    if (!isMobileWidth()) {
      resetBannerStyles(ad, iframe);
      return;
    }

    iframe.style.width = BASE_W + "px";
    iframe.style.height = BASE_H + "px";
    iframe.style.border = "0";
    iframe.style.display = "block";
    iframe.style.transformOrigin = "top left";

    var available = ad.getBoundingClientRect().width || window.innerWidth;

    var scale = available / BASE_W;
    if (scale > MAX_SCALE) scale = MAX_SCALE;
    if (scale < MIN_SCALE) scale = MIN_SCALE;

    iframe.style.transform = "scale(" + scale.toFixed(4) + ")";

    ad.style.width = "100%";
    ad.style.overflow = "hidden";
    ad.style.height = (BASE_H * scale) + "px";
  }

  // ===== Nav open/closed detection =====
  function isNavOpen() {
    var nav = document.getElementById("column-one");
    if (!nav) return false;

    var cs = window.getComputedStyle(nav);
    if (!cs || cs.display === "none" || cs.visibility === "hidden") return false;

    var r = nav.getBoundingClientRect();
    return r.width > 40 && r.height > 40;
  }

  function updateNavClass() {
    // Only care on mobile
    if (!isMobileWidth()) {
      document.documentElement.classList.remove("tf-nav-open");
      return;
    }

    if (isNavOpen()) {
      document.documentElement.classList.add("tf-nav-open");
    } else {
      document.documentElement.classList.remove("tf-nav-open");
    }
  }

  // ===== Plumbing =====
  var t = null;
  function scheduleAll() {
    if (t) clearTimeout(t);
    t = setTimeout(function () {
      rescaleBanner();
      updateNavClass();
    }, 60);
  }

  function installObservers() {
    // Run once now
    rescaleBanner();
    updateNavClass();

    window.addEventListener("resize", scheduleAll);
    window.addEventListener("orientationchange", scheduleAll);

    if (window.mw && mw.hook) {
      mw.hook("wikipage.content").add(function () {
        scheduleAll();
      });
    }

    // Watch for DOM + style changes (menu open/close)
    var obs = new MutationObserver(function () {
      scheduleAll();
    });
    obs.observe(document.documentElement, {
      childList: true,
      subtree: true,
      attributes: true
    });

    // Extra safety: tapping hamburger triggers class update
    document.addEventListener("click", function () {
      setTimeout(updateNavClass, 0);
    });
  }

  onReady(function () {
    installObservers();
  });
})();