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

MediaWiki:Common.js: Difference between revisions

MediaWiki interface page
No edit summary
No edit summary
Line 91: Line 91:
   }
   }
})();
})();
/* ===========================
/* ===========================
   Dungeon Leaderboard Script
   Dungeon Leaderboard Script
   =========================== */
   =========================== */


document.addEventListener("DOMContentLoaded", function () {
mw.hook('wikipage.content').add(function () {


     const table = document.getElementById("leaderboardTable");
     var table = document.getElementById("leaderboardTable");
     if (!table) return; // Only run on leaderboard page
     if (!table) return; // Only run on leaderboard page


     const dungeonFilter = document.getElementById("filterDungeon");
     var dungeonFilter = document.getElementById("filterDungeon");
     const typeFilter = document.getElementById("filterType");
     var typeFilter = document.getElementById("filterType");
     const addBtn = document.getElementById("addRunBtn");
     var addBtn = document.getElementById("addRunBtn");
 
    /* ---------- Time Parsing ---------- */


     function parseTime(t) {
     function parseTime(t) {
         if (!t || !t.includes(":")) return 999999;
         if (!t || t.indexOf(":") === -1) return 999999;
         const parts = t.split(":");
         var parts = t.split(":");
         return parseInt(parts[0]) * 60 + parseInt(parts[1]);
         return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
     }
     }
    /* ---------- Sorting & Ranking ---------- */


     function sortAndRank() {
     function sortAndRank() {
        const rows = Array.from(table.rows).slice(1);


         rows.sort((a, b) => {
        var rows = Array.prototype.slice.call(table.rows, 1);
             return parseTime(a.cells[6].innerText) - parseTime(b.cells[6].innerText);
 
         rows.sort(function (a, b) {
             return parseTime(a.cells[6].innerText) -
                  parseTime(b.cells[6].innerText);
         });
         });


         rows.forEach(row => table.appendChild(row));
         rows.forEach(function (row) {
            table.appendChild(row);
        });
 
        rows.forEach(function (row, index) {
            var rankCell = row.cells[0];


        rows.forEach((row, index) => {
            const rankCell = row.cells[0];
             if (index === 0) rankCell.innerHTML = "🥇 1";
             if (index === 0) rankCell.innerHTML = "🥇 1";
             else if (index === 1) rankCell.innerHTML = "🥈 2";
             else if (index === 1) rankCell.innerHTML = "🥈 2";
Line 128: Line 136:
         });
         });
     }
     }
    /* ---------- Filtering ---------- */


     function filterTable() {
     function filterTable() {
        const selectedDungeon = dungeonFilter.value;
        const selectedType = typeFilter.value;


         Array.from(table.rows).slice(1).forEach(row => {
        var selectedDungeon = dungeonFilter ? dungeonFilter.value : "All";
            const dungeon = row.cells[1].innerText.trim();
        var selectedType = typeFilter ? typeFilter.value : "All";
            const type = row.cells[2].innerText.trim();
 
         Array.prototype.slice.call(table.rows, 1).forEach(function (row) {


             const show =
             var dungeon = row.cells[1].innerText.trim();
            var type = row.cells[2].innerText.trim();
 
            var show =
                 (selectedDungeon === "All" || dungeon === selectedDungeon) &&
                 (selectedDungeon === "All" || dungeon === selectedDungeon) &&
                 (selectedType === "All" || type === selectedType);
                 (selectedType === "All" || type === selectedType);
Line 145: Line 157:
     }
     }


     dungeonFilter.addEventListener("change", filterTable);
     if (dungeonFilter)
    typeFilter.addEventListener("change", filterTable);
        dungeonFilter.addEventListener("change", filterTable);


     addBtn.addEventListener("click", function () {
     if (typeFilter)
        typeFilter.addEventListener("change", filterTable);


        const overlay = document.createElement("div");
    /* ---------- Submit Modal ---------- */
        overlay.style = `
            position:fixed;
            top:0;left:0;
            width:100%;height:100%;
            background:rgba(0,0,0,0.6);
            display:flex;
            align-items:center;
            justify-content:center;
            z-index:9999;
        `;


        const modal = document.createElement("div");
    if (addBtn) {
        modal.style = `
            background:white;
            padding:20px;
            width:420px;
            border-radius:8px;
        `;


         modal.innerHTML = `
         addBtn.addEventListener("click", function () {
            <h3>Submit Dungeon Run</h3>


             <label>Dungeon:</label><br>
             var overlay = document.createElement("div");
             <select id="runDungeon">
             overlay.style.position = "fixed";
                <option>Wolf's Den</option>
            overlay.style.top = "0";
                <option>Wolf's Den II</option>
            overlay.style.left = "0";
                <option>Wolf's Den III</option>
            overlay.style.width = "100%";
                <option>The Red Nest</option>
            overlay.style.height = "100%";
                <option>For The Eggs</option>
            overlay.style.background = "rgba(0,0,0,0.6)";
                <option>Scarlet Revenge</option>
            overlay.style.display = "flex";
                <option>Scarlet Revenge II</option>
            overlay.style.alignItems = "center";
                <option>Promised One</option>
            overlay.style.justifyContent = "center";
                <option>Promised One II</option>
             overlay.style.zIndex = "9999";
                <option>Promised One III</option>
                <option>Lost and Found</option>
                <option>The Hostage</option>
                <option>Cactus On Fire</option>
                <option>Deep Echoes</option>
                <option>Deep Echoes II</option>
                <option>Deep Echoes III</option>
             </select><br><br>


             <label>Type:</label><br>
             var modal = document.createElement("div");
             <select id="runType">
             modal.style.background = "#fff";
                <option value="Solo">Solo</option>
            modal.style.padding = "20px";
                <option value="Party">Party</option>
            modal.style.width = "420px";
             </select><br><br>
             modal.style.borderRadius = "8px";


             <div id="partySizeSection" style="display:none;">
             modal.innerHTML = `
                 <label>Party Size:</label><br>
                <h3>Submit Dungeon Run</h3>
                 <select id="runPartySize">
 
                    <option>1</option>
                 <label>Dungeon:</label><br>
                    <option>2</option>
                 <input type="text" id="runDungeon"><br><br>
                     <option>3</option>
 
                     <option>4</option>
                <label>Type:</label><br>
                <select id="runType">
                     <option value="Solo">Solo</option>
                     <option value="Party">Party</option>
                 </select><br><br>
                 </select><br><br>
            </div>


            <div id="weaponSection">
                <div id="partySizeSection" style="display:none;">
                <label>Weapon (Solo Only):</label><br>
                    <label>Party Size:</label><br>
                <select id="runWeapon">
                    <select id="runPartySize">
                    <option>Bow</option>
                        <option>1</option>
                    <option>Great Sword</option>
                        <option>2</option>
                    <option>Sword & Shield</option>
                        <option>3</option>
                </select><br><br>
                        <option>4</option>
            </div>
                    </select><br><br>
                </div>
 
                <div id="weaponSection">
                    <label>Weapon (Solo Only):</label><br>
                    <select id="runWeapon">
                        <option>Bow</option>
                        <option>Great Sword</option>
                        <option>Sword & Shield</option>
                    </select><br><br>
                </div>


            <label>Player / Party:</label><br>
                <label>Player / Party:</label><br>
            <input type="text" id="runPlayer"><br><br>
                <input type="text" id="runPlayer"><br><br>


            <label>Time (MM:SS):</label><br>
                <label>Time (MM:SS):</label><br>
            <input type="text" id="runTime"><br><br>
                <input type="text" id="runTime"><br><br>


            <label>Date:</label><br>
                <label>Date:</label><br>
            <input type="text" id="runDate"><br><br>
                <input type="text" id="runDate"><br><br>


            <label>Screenshot:</label><br>
                <label>Screenshot:</label><br>
            <small>Upload first via <a href="/wiki/Special:Upload" target="_blank">Upload File</a></small><br>
                <small>Upload first via <a href="/wiki/Special:Upload" target="_blank">Upload File</a></small><br>
            <input type="text" id="runScreenshot"><br><br>
                <input type="text" id="runScreenshot"><br><br>


            <button id="submitRun">Generate Entry</button>
                <button id="submitRun">Generate Entry</button>
            <button id="cancelRun">Cancel</button>
                <button id="cancelRun">Cancel</button>
        `;
            `;


        overlay.appendChild(modal);
            overlay.appendChild(modal);
        document.body.appendChild(overlay);
            document.body.appendChild(overlay);


        const runType = document.getElementById("runType");
            var runType = document.getElementById("runType");
        const partySizeSection = document.getElementById("partySizeSection");
            var partySizeSection = document.getElementById("partySizeSection");
        const weaponSection = document.getElementById("weaponSection");
            var weaponSection = document.getElementById("weaponSection");


        runType.addEventListener("change", function() {
            runType.addEventListener("change", function () {
            if (this.value === "Party") {
                if (this.value === "Party") {
                partySizeSection.style.display = "block";
                    partySizeSection.style.display = "block";
                weaponSection.style.display = "none";
                    weaponSection.style.display = "none";
            } else {
                } else {
                partySizeSection.style.display = "none";
                    partySizeSection.style.display = "none";
                weaponSection.style.display = "block";
                    weaponSection.style.display = "block";
            }
                }
        });
            });


        document.getElementById("cancelRun").onclick = () => {
            document.getElementById("cancelRun").onclick = function () {
            document.body.removeChild(overlay);
                document.body.removeChild(overlay);
        };
            };


        document.getElementById("submitRun").onclick = function () {
            document.getElementById("submitRun").onclick = function () {


            const dungeon = document.getElementById("runDungeon").value;
                var dungeon = document.getElementById("runDungeon").value;
            const type = runType.value;
                var type = runType.value;
            const partySize = type === "Solo" ? "1" : document.getElementById("runPartySize").value;
                var partySize = type === "Solo" ? "1" :
            const weapon = type === "Solo" ? document.getElementById("runWeapon").value : "—";
                    document.getElementById("runPartySize").value;
            const player = document.getElementById("runPlayer").value;
                var weapon = type === "Solo" ?
            const time = document.getElementById("runTime").value;
                    document.getElementById("runWeapon").value : "—";
            const date = document.getElementById("runDate").value;
                var player = document.getElementById("runPlayer").value;
            const screenshot = document.getElementById("runScreenshot").value;
                var time = document.getElementById("runTime").value;
                var date = document.getElementById("runDate").value;
                var screenshot = document.getElementById("runScreenshot").value;


            if (!player || !time || !date || !screenshot) {
                if (!player || !time || !date || !screenshot) {
                alert("All required fields must be completed.");
                    alert("All required fields must be completed.");
                return;
                    return;
            }
                }


            const row = `
                var row = `
|-
|-
|  
|  
Line 285: Line 287:
`;
`;


            alert("Copy this row and paste at bottom of table:\\n\\n" + row);
                alert("Copy this row and paste at bottom of table:\n\n" + row);
            document.body.removeChild(overlay);
                document.body.removeChild(overlay);
         };
            };
     });
         });
     }
 
    /* ---------- Init ---------- */


     sortAndRank();
     sortAndRank();
});
});

Revision as of 23:57, 28 February 2026

/* Any JavaScript here will be loaded for all users on every page load. */// Load DataTables library

mw.hook('wikipage.content').add(function ($content) {
  $content.find('.spoiler').on('click', function () {
    $(this).toggleClass('revealed');
  });
});

// Auto-embed X/Twitter status links into live tweets (no extension required)
(function () {
  'use strict';

  // Options you can tweak
  var TW_OPTIONS = {
    // theme: 'dark',            // uncomment for dark
    // conversation: 'none',     // hide reply thread
    // dnt: true,                // "Do Not Track"
    // align: 'center'           // center the embed
  };

  function loadXWidgets (cb) {
    // If the widget API is ready, go
    if (window.twttr && twttr.widgets) { cb(); return; }

    // Already loading?
    if (document.querySelector('script[src*="platform.twitter.com/widgets.js"]')) {
      // Poll until ready
      var tries = 0, t = setInterval(function () {
        if (window.twttr && twttr.widgets) { clearInterval(t); cb(); }
        else if (++tries > 40) { clearInterval(t); }
      }, 250);
      return;
    }

    // Inject the widgets.js script
    var s = document.createElement('script');
    s.async = true;
    s.src = 'https://platform.twitter.com/widgets.js';
    s.onload = function () { cb(); };
    document.head.appendChild(s);
  }

  // Find eligible links and embed them
  function embedLinks(root) {
    var scope = root || document;
    var selector = [
      'a[href^="https://x.com/"][href*="/status/"]',
      'a[href^="http://x.com/"][href*="/status/"]',
      'a[href^="https://twitter.com/"][href*="/status/"]',
      'a[href^="http://twitter.com/"][href*="/status/"]'
    ].join(',');

    var anchors = scope.querySelectorAll(selector);
    if (!anchors.length) return;

    loadXWidgets(function () {
      anchors.forEach(function (a) {
        if (a.dataset.tweetEmbedded === '1') return; // avoid duplicates
        a.dataset.tweetEmbedded = '1';

        // Extract the numeric tweet ID
        var match = a.href.match(/\/status\/(\d+)/);
        if (!match) return;
        var id = match[1];

        // Create a container after the link
        var container = document.createElement('div');
        container.className = 'tweet-embed';
        a.insertAdjacentElement('afterend', container);

        // Ask widgets API to render
        if (window.twttr && twttr.widgets && twttr.widgets.createTweet) {
          twttr.widgets.createTweet(id, container, TW_OPTIONS).catch(function(){});
        }
      });

      // Ensure any dynamically added blockquotes also render
      if (window.twttr && twttr.widgets && twttr.widgets.load) {
        twttr.widgets.load(scope);
      }
    });
  }

  // Run on page load and whenever VE/LQT/etc. inject content
  if (window.mw && mw.hook) {
    mw.hook('wikipage.content').add(function ($content) {
      embedLinks($content && $content[0]);
    });
  } else {
    document.addEventListener('DOMContentLoaded', function () { embedLinks(document); });
  }
})();
/* ===========================
   Dungeon Leaderboard Script
   =========================== */

mw.hook('wikipage.content').add(function () {

    var table = document.getElementById("leaderboardTable");
    if (!table) return; // Only run on leaderboard page

    var dungeonFilter = document.getElementById("filterDungeon");
    var typeFilter = document.getElementById("filterType");
    var addBtn = document.getElementById("addRunBtn");

    /* ---------- Time Parsing ---------- */

    function parseTime(t) {
        if (!t || t.indexOf(":") === -1) return 999999;
        var parts = t.split(":");
        return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
    }

    /* ---------- Sorting & Ranking ---------- */

    function sortAndRank() {

        var rows = Array.prototype.slice.call(table.rows, 1);

        rows.sort(function (a, b) {
            return parseTime(a.cells[6].innerText) -
                   parseTime(b.cells[6].innerText);
        });

        rows.forEach(function (row) {
            table.appendChild(row);
        });

        rows.forEach(function (row, index) {
            var rankCell = row.cells[0];

            if (index === 0) rankCell.innerHTML = "🥇 1";
            else if (index === 1) rankCell.innerHTML = "🥈 2";
            else if (index === 2) rankCell.innerHTML = "🥉 3";
            else rankCell.innerText = index + 1;
        });
    }

    /* ---------- Filtering ---------- */

    function filterTable() {

        var selectedDungeon = dungeonFilter ? dungeonFilter.value : "All";
        var selectedType = typeFilter ? typeFilter.value : "All";

        Array.prototype.slice.call(table.rows, 1).forEach(function (row) {

            var dungeon = row.cells[1].innerText.trim();
            var type = row.cells[2].innerText.trim();

            var show =
                (selectedDungeon === "All" || dungeon === selectedDungeon) &&
                (selectedType === "All" || type === selectedType);

            row.style.display = show ? "" : "none";
        });
    }

    if (dungeonFilter)
        dungeonFilter.addEventListener("change", filterTable);

    if (typeFilter)
        typeFilter.addEventListener("change", filterTable);

    /* ---------- Submit Modal ---------- */

    if (addBtn) {

        addBtn.addEventListener("click", function () {

            var overlay = document.createElement("div");
            overlay.style.position = "fixed";
            overlay.style.top = "0";
            overlay.style.left = "0";
            overlay.style.width = "100%";
            overlay.style.height = "100%";
            overlay.style.background = "rgba(0,0,0,0.6)";
            overlay.style.display = "flex";
            overlay.style.alignItems = "center";
            overlay.style.justifyContent = "center";
            overlay.style.zIndex = "9999";

            var modal = document.createElement("div");
            modal.style.background = "#fff";
            modal.style.padding = "20px";
            modal.style.width = "420px";
            modal.style.borderRadius = "8px";

            modal.innerHTML = `
                <h3>Submit Dungeon Run</h3>

                <label>Dungeon:</label><br>
                <input type="text" id="runDungeon"><br><br>

                <label>Type:</label><br>
                <select id="runType">
                    <option value="Solo">Solo</option>
                    <option value="Party">Party</option>
                </select><br><br>

                <div id="partySizeSection" style="display:none;">
                    <label>Party Size:</label><br>
                    <select id="runPartySize">
                        <option>1</option>
                        <option>2</option>
                        <option>3</option>
                        <option>4</option>
                    </select><br><br>
                </div>

                <div id="weaponSection">
                    <label>Weapon (Solo Only):</label><br>
                    <select id="runWeapon">
                        <option>Bow</option>
                        <option>Great Sword</option>
                        <option>Sword & Shield</option>
                    </select><br><br>
                </div>

                <label>Player / Party:</label><br>
                <input type="text" id="runPlayer"><br><br>

                <label>Time (MM:SS):</label><br>
                <input type="text" id="runTime"><br><br>

                <label>Date:</label><br>
                <input type="text" id="runDate"><br><br>

                <label>Screenshot:</label><br>
                <small>Upload first via <a href="/wiki/Special:Upload" target="_blank">Upload File</a></small><br>
                <input type="text" id="runScreenshot"><br><br>

                <button id="submitRun">Generate Entry</button>
                <button id="cancelRun">Cancel</button>
            `;

            overlay.appendChild(modal);
            document.body.appendChild(overlay);

            var runType = document.getElementById("runType");
            var partySizeSection = document.getElementById("partySizeSection");
            var weaponSection = document.getElementById("weaponSection");

            runType.addEventListener("change", function () {
                if (this.value === "Party") {
                    partySizeSection.style.display = "block";
                    weaponSection.style.display = "none";
                } else {
                    partySizeSection.style.display = "none";
                    weaponSection.style.display = "block";
                }
            });

            document.getElementById("cancelRun").onclick = function () {
                document.body.removeChild(overlay);
            };

            document.getElementById("submitRun").onclick = function () {

                var dungeon = document.getElementById("runDungeon").value;
                var type = runType.value;
                var partySize = type === "Solo" ? "1" :
                    document.getElementById("runPartySize").value;
                var weapon = type === "Solo" ?
                    document.getElementById("runWeapon").value : "—";
                var player = document.getElementById("runPlayer").value;
                var time = document.getElementById("runTime").value;
                var date = document.getElementById("runDate").value;
                var screenshot = document.getElementById("runScreenshot").value;

                if (!player || !time || !date || !screenshot) {
                    alert("All required fields must be completed.");
                    return;
                }

                var row = `
|-
| 
| ${dungeon}
| ${type}
| ${partySize}
| ${player}
| ${weapon}
| ${time}
| ${date}
| [[File:${screenshot}|120px]]
`;

                alert("Copy this row and paste at bottom of table:\n\n" + row);
                document.body.removeChild(overlay);
            };
        });
    }

    /* ---------- Init ---------- */

    sortAndRank();
});