MediaWiki:Common.js: Difference between revisions
MediaWiki interface page
More actions
No edit summary |
No edit summary |
||
| Line 97: | Line 97: | ||
Per-Dungeon Ranking + Filters | Per-Dungeon Ranking + Filters | ||
=========================== */ | =========================== */ | ||
mw.hook('wikipage.content').add(function () { | mw.hook('wikipage.content').add(function () { | ||
// | // ===== SOLO TABLE ===== | ||
const table = document.getElementById("leaderboardTable"); | const table = document.getElementById("leaderboardTable"); | ||
if ( | if (table) { | ||
const container = document.getElementById("filterContainer"); | |||
if (container) { | |||
const wrapper = document.createElement("div"); | |||
wrapper.style.marginBottom = "15px"; | |||
const dungeonLabel = document.createElement("strong"); | |||
dungeonLabel.innerText = "Dungeon: "; | |||
wrapper.appendChild(dungeonLabel); | |||
const dungeonSelect = document.createElement("select"); | |||
dungeonSelect.style.marginRight = "20px"; | |||
const dungeons = [ | |||
"All", | |||
"Wolf's Den", "Wolf's Den II", "Wolf's Den III", | |||
"The Red Nest", "For The Eggs", | |||
"Scarlet Revenge", "Scarlet Revenge II", | |||
"Promised One", "Promised One II", "Promised One III", | |||
"Lost and Found", "The Hostage", "Cactus On Fire", | |||
"Deep Echoes", "Deep Echoes II", "Deep Echoes III", | |||
"Hall of Daggers", | |||
]; | |||
dungeons.forEach(name => { | |||
const option = document.createElement("option"); | |||
option.value = name; | |||
option.textContent = name; | |||
dungeonSelect.appendChild(option); | |||
}); | |||
wrapper.appendChild(dungeonSelect); | |||
const playerLabel = document.createElement("strong"); | |||
playerLabel.innerText = "Player: "; | |||
wrapper.appendChild(playerLabel); | |||
const playerInput = document.createElement("input"); | |||
playerInput.type = "text"; | |||
playerInput.placeholder = "Search player name..."; | |||
playerInput.style.padding = "4px"; | |||
wrapper.appendChild(playerInput); | |||
container.appendChild(wrapper); | |||
function parseTime(t) { | |||
if (!t || !t.includes(":")) return 999999; | |||
const parts = t.trim().split(":"); | |||
return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10); | |||
} | |||
function sortAndRank() { | |||
const rows = Array.from(table.querySelectorAll("tr")).slice(1); | |||
rows.sort((a, b) => { | |||
const dungeonA = a.cells[1].innerText.trim(); | |||
const dungeonB = b.cells[1].innerText.trim(); | |||
if (dungeonA < dungeonB) return -1; | |||
if (dungeonA > dungeonB) return 1; | |||
return parseTime(a.cells[4].innerText) - parseTime(b.cells[4].innerText); | |||
}); | |||
rows.forEach(row => table.appendChild(row)); | |||
let currentDungeon = ""; | |||
let dungeonRank = 0; | |||
rows.forEach(row => { | |||
if (row.style.display === "none") return; | |||
const dungeon = row.cells[1].innerText.trim(); | |||
const rankCell = row.cells[0]; | |||
if (dungeon !== currentDungeon) { currentDungeon = dungeon; dungeonRank = 1; } | |||
else { dungeonRank++; } | |||
if (dungeonRank === 1) rankCell.innerHTML = "🥇 1"; | |||
else if (dungeonRank === 2) rankCell.innerHTML = "🥈 2"; | |||
else if (dungeonRank === 3) rankCell.innerHTML = "🥉 3"; | |||
else rankCell.innerText = dungeonRank; | |||
}); | |||
} | |||
function filterTable() { | |||
const selectedDungeon = dungeonSelect.value; | |||
const playerSearch = playerInput.value.toLowerCase(); | |||
const rows = Array.from(table.querySelectorAll("tr")).slice(1); | |||
rows.forEach(row => { | |||
const dungeon = row.cells[1].innerText.trim(); | |||
const player = row.cells[2].innerText.toLowerCase(); | |||
row.style.display = | |||
(selectedDungeon === "All" || dungeon === selectedDungeon) && | |||
player.includes(playerSearch) ? "" : "none"; | |||
}); | |||
sortAndRank(); | |||
} | |||
dungeonSelect.addEventListener("change", filterTable); | |||
playerInput.addEventListener("input", filterTable); | |||
sortAndRank(); | |||
} | |||
} | } | ||
// ===== PARTY TABLE ===== | |||
const | const partyTable = document.getElementById("partyLeaderboardTable"); | ||
if (partyTable) { | |||
const partyContainer = document.getElementById("partyFilterContainer"); | |||
if (partyContainer) { | |||
const wrapper = document.createElement("div"); | |||
wrapper.style.marginBottom = "15px"; | |||
const | |||
const dungeonLabel = document.createElement("strong"); | |||
dungeonLabel.innerText = "Dungeon: "; | |||
wrapper.appendChild(dungeonLabel); | |||
const dungeonSelect = document.createElement("select"); | |||
dungeonSelect.style.marginRight = "20px"; | |||
const dungeons = [ | |||
"All", | |||
"Wolf's Den", "Wolf's Den II", "Wolf's Den III", | |||
"The Red Nest", "For The Eggs", | |||
"Scarlet Revenge", "Scarlet Revenge II", | |||
"Promised One", "Promised One II", "Promised One III", | |||
"Lost and Found", "The Hostage", "Cactus On Fire", | |||
"Deep Echoes", "Deep Echoes II", "Deep Echoes III", | |||
"Hall of Daggers", | |||
]; | |||
dungeons.forEach(name => { | |||
const option = document.createElement("option"); | |||
option.value = name; | |||
option.textContent = name; | |||
dungeonSelect.appendChild(option); | |||
}); | |||
wrapper.appendChild(dungeonSelect); | |||
const | const playerLabel = document.createElement("strong"); | ||
playerLabel.innerText = "Players: "; | |||
wrapper.appendChild(playerLabel); | |||
const playerInput = document.createElement("input"); | |||
playerInput.type = "text"; | |||
playerInput.placeholder = "Search player name..."; | |||
playerInput.style.padding = "4px"; | |||
wrapper.appendChild(playerInput); | |||
partyContainer.appendChild(wrapper); | |||
function parseTime(t) { | |||
if (!t || !t.includes(":")) return 999999; | |||
const parts = t.trim().split(":"); | |||
return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10); | |||
} | |||
function sortAndRankParty() { | |||
const rows = Array.from(partyTable.querySelectorAll("tr")).slice(1); | |||
rows.sort((a, b) => { | |||
const dungeonA = a.cells[1].innerText.trim(); | |||
const dungeonB = b.cells[1].innerText.trim(); | |||
if (dungeonA < dungeonB) return -1; | |||
if (dungeonA > dungeonB) return 1; | |||
// Time is now column 5 (0-indexed) because of the extra Party Size column | |||
return parseTime(a.cells[5].innerText) - parseTime(b.cells[5].innerText); | |||
}); | |||
rows.forEach(row => partyTable.appendChild(row)); | |||
let currentDungeon = ""; | |||
let dungeonRank = 0; | |||
rows.forEach(row => { | |||
if (row.style.display === "none") return; | |||
const dungeon = row.cells[1].innerText.trim(); | |||
const rankCell = row.cells[0]; | |||
if (dungeon !== currentDungeon) { currentDungeon = dungeon; dungeonRank = 1; } | |||
else { dungeonRank++; } | |||
if (dungeonRank === 1) rankCell.innerHTML = "🥇 1"; | |||
else if (dungeonRank === 2) rankCell.innerHTML = "🥈 2"; | |||
else if (dungeonRank === 3) rankCell.innerHTML = "🥉 3"; | |||
else rankCell.innerText = dungeonRank; | |||
}); | |||
} | |||
const | function filterPartyTable() { | ||
selectedDungeon === "All" || dungeon === selectedDungeon; | const selectedDungeon = dungeonSelect.value; | ||
const playerSearch = playerInput.value.toLowerCase(); | |||
const rows = Array.from(partyTable.querySelectorAll("tr")).slice(1); | |||
rows.forEach(row => { | |||
const dungeon = row.cells[1].innerText.trim(); | |||
// Players column is now index 3 | |||
const player = row.cells[3].innerText.toLowerCase(); | |||
row.style.display = | |||
(selectedDungeon === "All" || dungeon === selectedDungeon) && | |||
player.includes(playerSearch) ? "" : "none"; | |||
}); | |||
sortAndRankParty(); | |||
} | |||
dungeonSelect.addEventListener("change", filterPartyTable); | |||
playerInput.addEventListener("input", filterPartyTable); | |||
sortAndRankParty(); | |||
} | |||
} | } | ||
}); | |||
/* Open YouTube links in new tab */ | /* Open YouTube links in new tab */ | ||
mw.hook('wikipage.content').add(function ($content) { | mw.hook('wikipage.content').add(function ($content) { | ||
$content.find('a[href*="youtube.com"], a[href*="youtu.be"]').each(function () { | $content.find('a[href*="youtube.com"], a[href*="youtu.be"]').each(function () { | ||
this.setAttribute("target", "_blank"); | this.setAttribute("target", "_blank"); | ||
this.setAttribute("rel", "noopener noreferrer"); | this.setAttribute("rel", "noopener noreferrer"); | ||
}); | }); | ||
}); | }); | ||