Vjs-mmb-fullscreen

VideoJS fullscreen shortcuts

Middle Mouse / MWheel click on video β†’ fullscreen

This isn’t working for me - tested it in Brave Brwoser and LibreWolf. I assume some Stash update broke it.

So I vibe coded a custom Javascript, that I added in the interface settings, which works great for me, but is much bigger. Maybe it helps someone.

(function () {
  const LOG = "[mmb-fullscreen]";

  const isMiddle = (e) => e.button === 1 || (typeof e.buttons === "number" && (e.buttons & 4) === 4);
  const isInPlayer = (el) => el && (el.closest(".video-js, .vjs-tech, video") || null);

  function getPlayers() {
    try {
      if (window.videojs && typeof window.videojs.getPlayers === "function") {
        return Object.values(window.videojs.getPlayers());
      }
    } catch (_) {}
    return [];
  }

  function getPlayerFor(el) {
    const players = getPlayers();
    if (players.length) {
      for (const p of players) {
        try {
          const pel = typeof p.el === "function" ? p.el() : p.el;
          if (pel && pel.contains(el)) return p;
        } catch (_) {}
      }
      return players[0];
    }
    if (window.videojs) {
      const container = el.closest(".video-js") || document.querySelector(".video-js");
      if (container) {
        try {
          if (typeof window.videojs.getPlayer === "function") return window.videojs.getPlayer(container);
          return window.videojs(container);
        } catch (_) {}
      }
    }
    return null;
  }

  let lastToggleAt = 0;
  function guard() {
    const now = Date.now();
    if (now - lastToggleAt < 150) return false;
    lastToggleAt = now;
    return true;
  }

  function toggleFullscreenFor(target) {
    const player = getPlayerFor(target);

    try {
      if (player && typeof player.isFullscreen === "function" && typeof player.requestFullscreen === "function") {
        if (player.isFullscreen()) player.exitFullscreen();
        else player.requestFullscreen();
        return true;
      }
    } catch (err) {
      console.warn(LOG, "video.js fullscreen failed, fallback:", err);
    }

    const container =
      (player && typeof player.el === "function" && player.el()) ||
      target.closest(".video-js") ||
      target;

    const isFS =
      document.fullscreenElement ||
      document.webkitFullscreenElement ||
      document.mozFullScreenElement ||
      document.msFullscreenElement;

    if (isFS) {
      const exit =
        document.exitFullscreen ||
        document.webkitExitFullscreen ||
        document.mozCancelFullScreen ||
        document.msExitFullscreen;
      if (exit) exit.call(document);
      return true;
    } else {
      const req =
        container.requestFullscreen ||
        container.webkitRequestFullscreen ||
        container.mozRequestFullScreen ||
        container.msRequestFullscreen;
      if (req) {
        req.call(container);
        return true;
      }
    }
    return false;
  }

  function handler(e) {
    if (!isMiddle(e)) return;
    const target = e.target;
    if (!isInPlayer(target)) return;

    e.preventDefault();
    e.stopPropagation();

    if (!guard()) return;
    toggleFullscreenFor(target);
  }

  document.addEventListener("auxclick", handler, { capture: true, passive: false });
  document.addEventListener("mousedown", handler, { capture: true, passive: false });
  document.addEventListener("pointerdown", handler, { capture: true, passive: false });

  console.log(LOG, "global middle-click fullscreen enabled");
})();