Difference between revisions of "MediaWiki:Timeless.js"

From Medivia Online Wiki
Line 1: Line 1:
/* All JavaScript here will be loaded for users of the Timeless skin */
console.log("Timeless.js loaded");
(function () {
(function () {
   function normalizeToFileTitle(val) {
   function normalizeToFileTitle(val) {
Line 7: Line 5:
     if (!val) return "";
     if (!val) return "";


     // Allow "File:Something.png" or just "Something.png"
     // Allow users to paste [[File:...|...]]
    if (val.startsWith("[[")) val = val.replace(/^\[\[\s*/, "").replace(/\s*\]\]$/, "");
    if (val.includes("|")) val = val.split("|")[0];
 
    // Ensure File:
     if (!/^File:/i.test(val)) val = "File:" + val;
     if (!/^File:/i.test(val)) val = "File:" + val;
     return val;
     return val;
   }
   }


   function fileTitleToThumbUrl(fileTitle) {
   function fileTitleToThumbUrl(fileTitle) {
     // MediaWiki thumb URL via Special:Redirect (works without knowing upload path)
     // Works without knowing upload path
    // Example: /wiki/Special:Redirect/file/Some.png?width=64
     var name = fileTitle.replace(/^File:/i, "");
     var name = fileTitle.replace(/^File:/i, "");
     return mw.util.getUrl("Special:Redirect/file/" + name) + "?width=64";
     return mw.util.getUrl("Special:Redirect/file/" + name) + "?width=64";
   }
   }


   function hookPageFormsImagePreview() {
   function hookItemImagePreview(root) {
     // Page Forms inputs usually end up as <input name="...">
    root = root || document;
     var input =
 
      document.querySelector('input[name="image"]') ||
     // Primary: class we set in the form
       document.querySelector('input[name="Item[image]"]') ||
     var input = root.querySelector("input.pf-item-image");
      document.querySelector('input[name$="[image]"]');
 
    // Fallbacks (in case PageForms didn't apply class)
    if (!input) {
       input =
        root.querySelector('input[name="image"]') ||
        root.querySelector('input[name$="[image]"]');
    }


     var img = document.getElementById("pf-image-preview");
     var img = document.getElementById("pf-image-preview");
     var txt = document.getElementById("pf-image-preview-text");
     var txt = document.getElementById("pf-image-preview-text");
     if (!input || !img || !txt) return;
     if (!input || !img || !txt) return;
    function setEmpty(msgHtml) {
      img.style.display = "none";
      img.removeAttribute("src");
      txt.style.display = "";
      txt.innerHTML = msgHtml;
    }


     function update() {
     function update() {
       var fileTitle = normalizeToFileTitle(input.value);
       var fileTitle = normalizeToFileTitle(input.value);
       if (!fileTitle) {
       if (!fileTitle) return setEmpty("<i>No image selected.</i>");
        img.style.display = "none";
        txt.style.display = "";
        txt.innerHTML = "<i>No image selected.</i>";
        img.removeAttribute("src");
        return;
      }


       var url = fileTitleToThumbUrl(fileTitle);
       var url = fileTitleToThumbUrl(fileTitle);
       img.onload = function () {
       img.onload = function () {
         img.style.display = "";
         img.style.display = "";
Line 46: Line 56:
       };
       };
       img.onerror = function () {
       img.onerror = function () {
         img.style.display = "none";
         setEmpty("<i>Image not found.</i>");
        txt.style.display = "";
        txt.innerHTML = "<i>Image not found.</i>";
       };
       };
       img.src = url;
       img.src = url;
     }
     }


    // Update while typing + when autocomplete fills
     input.addEventListener("input", update);
     input.addEventListener("input", update);
     input.addEventListener("change", update);
     input.addEventListener("change", update);
    update();
  }


     // Initial
  function run(root) {
     update();
     // Delay helps on Special:FormEdit where inputs may appear after initial render
     setTimeout(function () { hookItemImagePreview(root); }, 150);
   }
   }


   mw.hook("wikipage.content").add(function () {
   if (window.mw && mw.hook) {
    // Run on formedit pages
    mw.hook("wikipage.content").add(run);
    hookPageFormsImagePreview();
  }
  });
  document.addEventListener("DOMContentLoaded", function () { run(document); });
})();
})();

Revision as of 20:16, 17 January 2026

(function () {
  function normalizeToFileTitle(val) {
    if (!val) return "";
    val = val.trim();
    if (!val) return "";

    // Allow users to paste [[File:...|...]]
    if (val.startsWith("[[")) val = val.replace(/^\[\[\s*/, "").replace(/\s*\]\]$/, "");
    if (val.includes("|")) val = val.split("|")[0];

    // Ensure File:
    if (!/^File:/i.test(val)) val = "File:" + val;

    return val;
  }

  function fileTitleToThumbUrl(fileTitle) {
    // Works without knowing upload path
    var name = fileTitle.replace(/^File:/i, "");
    return mw.util.getUrl("Special:Redirect/file/" + name) + "?width=64";
  }

  function hookItemImagePreview(root) {
    root = root || document;

    // Primary: class we set in the form
    var input = root.querySelector("input.pf-item-image");

    // Fallbacks (in case PageForms didn't apply class)
    if (!input) {
      input =
        root.querySelector('input[name="image"]') ||
        root.querySelector('input[name$="[image]"]');
    }

    var img = document.getElementById("pf-image-preview");
    var txt = document.getElementById("pf-image-preview-text");
    if (!input || !img || !txt) return;

    function setEmpty(msgHtml) {
      img.style.display = "none";
      img.removeAttribute("src");
      txt.style.display = "";
      txt.innerHTML = msgHtml;
    }

    function update() {
      var fileTitle = normalizeToFileTitle(input.value);
      if (!fileTitle) return setEmpty("<i>No image selected.</i>");

      var url = fileTitleToThumbUrl(fileTitle);

      img.onload = function () {
        img.style.display = "";
        txt.style.display = "none";
      };
      img.onerror = function () {
        setEmpty("<i>Image not found.</i>");
      };

      img.src = url;
    }

    input.addEventListener("input", update);
    input.addEventListener("change", update);
    update();
  }

  function run(root) {
    // Delay helps on Special:FormEdit where inputs may appear after initial render
    setTimeout(function () { hookItemImagePreview(root); }, 150);
  }

  if (window.mw && mw.hook) {
    mw.hook("wikipage.content").add(run);
  }
  document.addEventListener("DOMContentLoaded", function () { run(document); });
})();