MediaWiki:Common.js

From UAPedia
Revision as of 01:30, 7 February 2026 by Administrator (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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.
// UAPedia: File-page helper to generate & copy a 100px-wide thumbnail direct URL
mw.hook('wikipage.content').add(function ($content) {
  // File namespace only
  if (mw.config.get('wgNamespaceNumber') !== 6) return;

  var fileTitle = mw.config.get('wgPageName'); // e.g. "File:Silouette-portrait.webp"
  if (!fileTitle) return;

  var targetWidth = 100; // your desired thumb width (=> ~133px tall for 440x587)

  var api = new mw.Api();

  function setStatus($box, msg) {
    $box.find('.uap-thumb-status').text(msg);
  }

  function copyText(text, $box) {
    if (navigator.clipboard && navigator.clipboard.writeText) {
      return navigator.clipboard.writeText(text).then(function () {
        setStatus($box, 'Copied!');
        setTimeout(function () { setStatus($box, ''); }, 1200);
      });
    }
    // fallback
    var $tmp = $('<textarea readonly></textarea>').val(text).css({
      position: 'absolute', left: '-9999px', top: '-9999px'
    }).appendTo(document.body);
    $tmp[0].select();
    try { document.execCommand('copy'); } catch (e) {}
    $tmp.remove();
    setStatus($box, 'Copied!');
    setTimeout(function () { setStatus($box, ''); }, 1200);
    return Promise.resolve();
  }

  function fetchImageInfo() {
    // Get original URL + thumb URL at width=100
    return api.get({
      action: 'query',
      titles: fileTitle,
      prop: 'imageinfo',
      iiprop: 'url',
      iiurlwidth: targetWidth,
      format: 'json'
    }).then(function (data) {
      var pages = data && data.query && data.query.pages;
      if (!pages) throw new Error('No API pages returned');

      var pageId = Object.keys(pages)[0];
      var page = pages[pageId];
      if (!page || !page.imageinfo || !page.imageinfo.length) {
        throw new Error('No imageinfo found (is this a file page?)');
      }
      var ii = page.imageinfo[0];
      return {
        originalUrl: ii.url || '',
        thumbUrl: ii.thumburl || '',
        thumbWidth: ii.thumbwidth || null,
        thumbHeight: ii.thumbheight || null
      };
    });
  }

  function forceGenerateThumb(thumbUrl, $box) {
    // Preload the thumb URL; this usually forces thumb generation if it wasn’t created yet.
    return new Promise(function (resolve, reject) {
      if (!thumbUrl) return reject(new Error('No thumb URL to generate'));
      var img = new Image();
      img.onload = function () { resolve(); };
      img.onerror = function () { reject(new Error('Thumb load failed')); };
      // cache-bust to ensure a request actually happens
      img.src = thumbUrl + (thumbUrl.indexOf('?') === -1 ? '?' : '&') + 'uapgen=' + Date.now();
    });
  }

  // UI
  var $box = $(
    '<div class="uap-thumb-linkbox">' +
      '<div class="uap-thumb-title"><b>Thumbnail helper</b> <span class="uap-thumb-status"></span></div>' +

      '<div class="uap-thumb-row">' +
        '<div class="uap-thumb-label">Original file URL</div>' +
        '<input class="uap-thumb-input uap-original" type="text" readonly />' +
        '<button class="uap-thumb-copy-original mw-ui-button">Copy</button>' +
      '</div>' +

      '<div class="uap-thumb-row">' +
        '<div class="uap-thumb-label">Generate ' + targetWidth + 'px thumb</div>' +
        '<button class="uap-thumb-generate mw-ui-button mw-ui-progressive">Generate / Refresh</button>' +
        '<span class="uap-thumb-dims"></span>' +
      '</div>' +

      '<div class="uap-thumb-row">' +
        '<div class="uap-thumb-label">Direct thumb URL (' + targetWidth + 'px wide)</div>' +
        '<input class="uap-thumb-input uap-thumb" type="text" readonly />' +
        '<button class="uap-thumb-copy-thumb mw-ui-button">Copy</button>' +
      '</div>' +

      '<div class="uap-thumb-note">' +
        'Use the <b>Direct thumb URL</b> in external <code>&lt;img src=""&gt;</code> tags. ' +
        'It points into <code>/wiki/images/thumb/...</code> and avoids Special-page redirects.' +
      '</div>' +
    '</div>'
  );

  // Insert somewhere stable across skins
  var $container = $('#mw-content-text');
  ($container.length ? $container : $content).prepend($box);

  // Wire buttons
  var state = { originalUrl: '', thumbUrl: '' };

  function refreshUI(info) {
    state.originalUrl = info.originalUrl || '';
    state.thumbUrl = info.thumbUrl || '';

    $box.find('input.uap-original').val(state.originalUrl);
    $box.find('input.uap-thumb').val(state.thumbUrl);

    if (info.thumbWidth && info.thumbHeight) {
      $box.find('.uap-thumb-dims').text('(' + info.thumbWidth + '×' + info.thumbHeight + ')');
    } else {
      $box.find('.uap-thumb-dims').text('');
    }
  }

  function loadOnce() {
    setStatus($box, 'Loading…');
    return fetchImageInfo()
      .then(function (info) {
        refreshUI(info);
        setStatus($box, '');
      })
      .catch(function (err) {
        setStatus($box, 'Error: ' + err.message);
      });
  }

  $box.find('.uap-thumb-copy-original').on('click', function () {
    if (!state.originalUrl) return setStatus($box, 'No original URL yet');
    copyText(state.originalUrl, $box);
  });

  $box.find('.uap-thumb-copy-thumb').on('click', function () {
    if (!state.thumbUrl) return setStatus($box, 'No thumb URL yet');
    copyText(state.thumbUrl, $box);
  });

  $box.find('.uap-thumb-generate').on('click', function () {
    setStatus($box, 'Generating…');
    fetchImageInfo()
      .then(function (info) {
        refreshUI(info);
        return forceGenerateThumb(info.thumbUrl, $box).then(function () {
          // Re-fetch in case the thumb URL/dims change after generation
          return fetchImageInfo().then(function (info2) {
            refreshUI(info2);
            setStatus($box, 'Generated');
            setTimeout(function () { setStatus($box, ''); }, 1200);
          });
        });
      })
      .catch(function (err) {
        setStatus($box, 'Error: ' + err.message);
      });
  });

  // Initial load
  loadOnce();
});