Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MediaWiki:Gadget-gallery-gif-animate.js

MediaWiki interface page

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.
(function () {
  'use strict';

  /* Add this class to gallery to disable animation swapping:
  ** gallery class="gif-noanimate" ... gallery */
  var NO_ANIMATE_CLASS = 'gif-noanimate';

  function thumbToOriginal(src) {
    /* https://.../uploads/thumb/e/e2/Foo.gif/120px-Foo.gif
    ** -> https://.../uploads/e/e2/Foo.gif */
    try {
      var u = new URL(src, location.origin);
      var path = u.pathname;
      if (!/\/thumb\//.test(path)) return null;
      if (!/\.gif$/i.test(path)) return null;

      var parts = path.split('/').filter(Boolean);
      var i = parts.indexOf('thumb');
      if (i < 0 || parts.length < i + 5) return null;

      var base = parts.slice(0, i);
      var h1 = parts[i + 1];
      var h2 = parts[i + 2];
      var file = parts[i + 3];

      if (!/\.gif$/i.test(file)) return null;

      u.pathname = '/' + base.concat([h1, h2, file]).join('/');
      u.search = '';
      u.hash = '';
      return u.toString();
    } catch (e) {
      return null;
    }
  }

  function run(root) {
    var gallery = root.querySelector('ul.gallery');
    if (!gallery) return;

    var imgs = root.querySelectorAll('ul.gallery img.mw-file-element');
    imgs.forEach(function (img) {
      if (img.closest('.' + NO_ANIMATE_CLASS)) return;

      var src = img.currentSrc || img.src || '';
      if (!/\.gif(\?|#|$)/i.test(src)) return;
      img.setAttribute('loading', 'lazy');
      var original = thumbToOriginal(src);
      if (!original) return;

      // Swap after thumb loads (keeps width/height layout stable).
      if (img.complete && img.naturalWidth) {
        img.src = original;
      } else {
        img.addEventListener('load', function () {
          img.src = original;
        }, { once: true });
      }
    });
  }

  mw.hook('wikipage.content').add(function ($content) {
    run($content[0]);
  });
})();