// ==UserScript==
// @name mz - World League Standings
// @version 3.0
// @description Display all leagues from a country or region, grouped by div, on a single view
// @author Douglas Vieira
// @match *://www.managerzone.com/?p=team
// @icon https://www.google.com/s2/favicons?sz=64&domain=managerzone.com
// @grant GM_addStyle
// @license MIT
// @namespace https://greasyfork.org/users/1088808
// ==/UserScript==
(function () {
const mainContainer = document.createElement("div");
const infoAboutTeam = document.getElementById("infoAboutTeam");
const teamStadiumWrapper = document.getElementById("team-stadium-wrapper");
const sport = new URL(
document.querySelector("#shortcut_link_thezone").href
).searchParams.get("sport");
const seniorLeagues = getSeniorLeagues();
const worldLeagues = {
World: getWorldLeaguesObj(),
};
const uxxLeagues = getUxxLeagues();
const buttonNames = [
"Senior Leagues",
"World Leagues",
"U18 World Leagues",
"U21 World Leagues",
"U23 World Leagues",
"U18 Leagues",
"U21 Leagues",
"U23 Leagues",
];
const teamId = RegExp(/\((\d+)\)/).exec(
infoAboutTeam.querySelector("dd").textContent
)[1];
if (infoAboutTeam && teamStadiumWrapper) {
appendLeagueButtonsToTeamPage();
}
function appendLeagueButtonsToTeamPage() {
for (let i = 0; i < 8; ++i) {
const button = document.createElement("button");
setupButton(
button,
`league-button-${buttonNames[i].toLocaleLowerCase()}`,
buttonNames[i]
);
mainContainer.appendChild(button);
}
teamStadiumWrapper.appendChild(
setupMainContainer(mainContainer, "league-buttons-container")
);
}
async function fetchLeagueTable(sid, leagueType, divisionCount, country) {
try {
const response = await fetch(
`https://www.managerzone.com/ajax.php?p=league&type=${leagueType}&sid=${sid}&tid=${teamId}&sport=${sport}&sub=table`
);
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const niceTable = doc.querySelector(".nice_table");
niceTable.style.margin = "16px auto";
niceTable.style.width = "60%";
const rows = niceTable.querySelectorAll('tbody tr');
for (const row of rows) {
const link = row.querySelector('a[href^="/?p=league&type="]');
if (link) {
const tid = link.href.match(/tid=(\d+)/);
if (tid) {
link.href = `/?p=team&tid=${tid[1]}`;
}
}
}
handleHelpButton(niceTable, sid, leagueType);
return {
table: niceTable,
divisionCount: divisionCount,
country: country,
};
} catch (error) {
console.error("Error: ", error);
return null;
}
}
function handleHelpButton(table, sid, leagueType) {
const secondRow = table.querySelector("tbody tr:nth-child(2)");
const helpButton = secondRow.querySelector(".help_button");
const teamLink = secondRow.querySelector("a[onclick*='purchaseChallenge']");
const tid = teamLink
? teamLink
.getAttribute("onclick")
.split(",")[2]
.replace(/[ ';)]/g, "")
: null;
if (helpButton && tid) {
helpButton.removeAttribute("onclick");
helpButton.addEventListener("click", (event) => {
event.preventDefault();
fetchExtraLeagueData(sid, leagueType, tid);
});
}
}
function createLeaguesModal(modalId, button) {
const leagueType = getLeagueTypeFromButtonId(button.id);
const leaguesModalTitle = button.textContent;
const leaguesModal = document.createElement("div");
setupModal(leaguesModal, modalId);
const leaguesModalContent = addContentToLeaguesModal(leaguesModal);
ensureContentIsCentered(leaguesModalContent);
const leagueTablesContainer =
addTablesContainerToLeaguesModal(leaguesModalContent);
const dropdownAndTablesContainer = document.createElement("div");
const countryDropdown = createCountryDropdown(
leagueType,
dropdownAndTablesContainer,
leagueTablesContainer
);
leaguesModalContent.appendChild(countryDropdown);
const selectedCountry = countryDropdown.value;
const leaguesObject = getLeaguesObjFromLeagueType(
leagueType,
selectedCountry
);
addOtherComponentsToLeaguesModal(
leaguesModal,
leaguesModalContent,
leaguesModalTitle,
leagueTablesContainer,
leagueType,
leaguesObject
);
return leaguesModal;
}
function addContentToLeaguesModal(modal) {
const modalContent = document.createElement("div");
setupLeaguesModalContent(modalContent, "leagues-modal-content");
modal.appendChild(modalContent);
return modalContent;
}
function addTablesContainerToLeaguesModal(modalContent) {
const leagueTablesContainer = document.createElement("div");
leagueTablesContainer.id = "league-tables-container";
modalContent.appendChild(leagueTablesContainer);
return leagueTablesContainer;
}
function addOtherComponentsToLeaguesModal(
modal,
modalContent,
modalTitle,
leagueTablesContainer,
leagueType,
leaguesObject
) {
const tablesContainer = document.createElement("div");
addModalTitleToLeaguesModal(modalContent, modalTitle);
addTabsToLeaguesModal(
modalContent,
leagueType,
leaguesObject,
leagueTablesContainer
);
addCloseButtonToLeaguesModal(modal, modalContent);
tablesContainer.appendChild(leagueTablesContainer);
modalContent.appendChild(tablesContainer);
}
function addModalTitleToLeaguesModal(modalContent, titleText) {
const title = document.createElement("h2");
setupLeaguesModalTitle(title, "leagues-modal-title", titleText);
modalContent.appendChild(title);
}
function addTabsToLeaguesModal(
container,
leagueType,
leaguesObj,
leagueTablesContainer
) {
const tabContainer = document.createElement("div");
setupLeaguesTabs(
tabContainer,
"leagues-tabs",
leagueType,
leaguesObj,
leagueTablesContainer
);
container.appendChild(tabContainer);
}
function addCloseButtonToLeaguesModal(modal, modalContent) {
const closeButton = document.createElement("button");
setupCloseButton(closeButton, "leagues-modal-close-button", modal);
modalContent.appendChild(closeButton);
}
function ensureContentIsCentered(modalContent) {
const initialMarginTop = Math.max(
(window.innerHeight - modalContent.offsetHeight) / 2,
0
);
modalContent.style.marginTop = initialMarginTop + "px";
window.addEventListener("scroll", function () {
const newMarginTop = Math.max(
(window.innerHeight - modalContent.offsetHeight) / 2,
0
);
modalContent.style.marginTop = newMarginTop + "px";
});
}
function setupModal(modal, id) {
modal.id = id;
modal.style.position = "fixed";
modal.style.zIndex = "1";
modal.style.left = "0";
modal.style.top = "0";
modal.style.width = "100%";
modal.style.height = "100%";
modal.style.display = "flex";
modal.style.justifyContent = "center";
modal.style.alignItems = "center";
modal.style.backgroundColor = "rgba(0,0,0,0.8)";
modal.style.opacity = "0";
modal.style.transition = "opacity 0.5s ease-in-out";
setTimeout(function () {
modal.style.opacity = "1";
}, 0);
}
function setupLeaguesModalContent(modalContent, id) {
modalContent.id = id;
modalContent.style.backgroundColor = "#fefefe";
modalContent.style.backgroundImage =
"url('https://s1.ax1x.com/2023/06/25/pCNmCSH.jpg')";
modalContent.style.backgroundSize = "cover";
modalContent.style.backgroundPosition = "center";
modalContent.style.margin = "0 auto";
modalContent.style.padding = "20px";
modalContent.style.border = "1px solid #888";
modalContent.style.width = "80%";
modalContent.style.position = "relative";
modalContent.style.overflowY = "auto";
modalContent.style.maxHeight = "80vh";
ensureContentIsCentered(modalContent);
}
function setupLeaguesModalTitle(title, id, textContent) {
title.id = id;
title.textContent = textContent;
title.style.textAlign = "center";
title.style.fontFamily = "Montserrat, sans-serif";
title.style.color = "navy";
}
function setupCloseButton(button, id, modal) {
button.id = id;
button.textContent = "X";
button.style.position = "absolute";
button.style.top = "10px";
button.style.right = "10px";
button.style.fontFamily = "Arial, sans-serif";
button.style.fontSize = "20px";
button.style.fontWeight = "bold";
button.style.color = "#000";
button.style.backgroundColor = "transparent";
button.style.border = "none";
button.style.cursor = "pointer";
button.onclick = function () {
modal.style.opacity = "0";
setTimeout(function () {
document.body.removeChild(modal);
}, 500);
};
}
function setupLeaguesTabs(
tabContainer,
id,
leagueType,
leagues,
leagueTablesContainer
) {
tabContainer.id = id;
for (const league in leagues) {
const tab = document.createElement("button");
setupTab(
tab,
`tab-${league.toLocaleLowerCase().replace(" ", "")}`,
league
);
const tabName = league;
tab.onclick = async function () {
updateLeaguesModal(leagueTablesContainer);
const selectedCountry =
document.getElementById("country-dropdown").value;
const selectedDivision = this.textContent;
const leagues = getLeaguesObjFromLeagueType(
leagueType,
selectedCountry
);
const leagueIds = leagues[selectedDivision];
const fetchPromises = leagueIds.map((sid, index) =>
fetchLeagueTable(sid, leagueType, index + 1, selectedCountry)
);
const tablesData = await Promise.all(fetchPromises);
tablesData.sort((a, b) => a.divisionCount - b.divisionCount);
tablesData.forEach((data) => {
if (data !== null) {
leagueTablesContainer.appendChild(document.createElement("hr"));
leagueTablesContainer.appendChild(
createLeagueTitle(
selectedDivision,
data.divisionCount,
leagueType,
selectedCountry,
tabName,
seniorLeagues
)
);
leagueTablesContainer.appendChild(data.table);
data.table.id = `${leagueType}-${selectedCountry
.toLocaleLowerCase()
.replace(" ", "")}-${data.divisionCount}`;
}
});
};
tabContainer.appendChild(tab);
}
}
function getLeagueTypeFromButtonId(id) {
if (id.includes("senior leagues")) {
return "senior";
} else if (id.includes("u18 world leagues")) {
return "u18_world";
} else if (id.includes("u21 world leagues")) {
return "u21_world";
} else if (id.includes("u23 world leagues")) {
return "u23_world";
} else if (id.includes("u18 leagues")) {
return "u18";
} else if (id.includes("u21 leagues")) {
return "u21";
} else if (id.includes("u23 leagues")) {
return "u23";
} else {
return "world";
}
}
function getLeaguesObjFromLeagueType(leagueType, country) {
let leagues;
switch (leagueType) {
case "senior":
leagues =
country === "All"
? getAllLeagues(seniorLeagues)
: seniorLeagues[country];
break;
case "world":
case "u18_world":
case "u21_world":
case "u23_world":
leagues = worldLeagues.World;
break;
case "u18":
case "u21":
case "u23":
leagues =
country === "All" ? getAllLeagues(uxxLeagues) : uxxLeagues[country];
break;
default:
break;
}
return leagues;
}
function getAllLeagues(leaguesObj) {
const allLeagues = {};
for (const country in leaguesObj) {
for (const league in leaguesObj[country]) {
if (!allLeagues[league]) {
allLeagues[league] = [];
}
allLeagues[league] = allLeagues[league].concat(
leaguesObj[country][league]
);
}
}
return allLeagues;
}
function getCountries(leagueType) {
let countries;
switch (leagueType) {
case "senior":
countries = Object.keys(seniorLeagues);
break;
case "world":
case "u18_world":
case "u21_world":
case "u23_world":
countries = ["World"];
break;
case "u18":
case "u21":
case "u23":
countries = Object.keys(uxxLeagues);
break;
default:
break;
}
return countries;
}
function updateLeaguesModal(leagueTablesContainer) {
while (leagueTablesContainer.firstChild) {
leagueTablesContainer.removeChild(leagueTablesContainer.firstChild);
}
}
function createLeagueTitle(
selectedLeague,
divisionCount,
type,
country,
tabName,
seniorLeagues
) {
const p = document.createElement("p");
if (!selectedLeague.startsWith("Division")) {
p.textContent = selectedLeague;
} else {
const theDivision = selectedLeague + "." + divisionCount;
p.textContent = theDivision.replace("Division", "div");
}
p.textContent += " " + type.charAt(0).toUpperCase() + type.slice(1);
if (
(type === "senior" ||
type === "u18" ||
type === "u21" ||
type === "u23") &&
country !== "All"
) {
p.textContent += " " + country;
}
if (p.textContent.includes("All")) {
p.textContent = p.textContent.replace("All", "");
}
if (p.textContent.includes("_")) {
p.textContent = p.textContent.replace("_", " ");
}
if (type === "senior" && country === "All" && tabName === "Top Division") {
const keysOfSeniorLeagues = Object.keys(seniorLeagues);
p.textContent += " " + keysOfSeniorLeagues[divisionCount - 1];
}
const tabNameEndsWithNumber = /\d$/.test(tabName);
let tabNameNumber = 0;
if (tabNameEndsWithNumber) {
tabNameNumber = parseInt(tabName.charAt(tabName.length - 1));
}
if (!type.includes("world") && tabNameEndsWithNumber) {
if (RegExp(/\.\d+/).exec(p.textContent)) {
p.textContent = p.textContent.replace(/\.\d+/, (match) => {
const number = parseInt(match.slice(1));
const divisor = Math.pow(3, tabNameNumber);
if (number > divisor) {
const replacement = number % divisor;
return `.${replacement === 0 ? divisor : replacement}`;
}
return match;
});
}
}
p.style.fontFamily = "Montserrat, sans-serif";
p.style.fontWeight = "bold";
p.style.textAlign = "center";
return p;
}
function setupButton(button, id, textContent) {
button.id = id;
button.textContent = textContent;
styleButton(button);
setupButtonAnimations(button);
button.onclick = function () {
const leaguesModal = createLeaguesModal("leagues-modal", button);
appendAndShowOrHideModal(leaguesModal);
};
}
function styleButton(button) {
button.style.margin = "4px";
button.style.padding = "8px 16px";
button.style.border = "none";
button.style.borderRadius = "12px";
button.style.backgroundColor = "#000080";
button.style.color = "white";
button.style.fontFamily = "Montserrat, sans-serif";
button.style.fontSize = "12px";
button.style.cursor = "pointer";
button.style.boxShadow = "0px 2px 6px rgba(0, 0, 0, 0.3)";
}
function setupButtonAnimations(button) {
button.onmouseover = function () {
button.style.backgroundColor = "#27285C";
button.style.transform = "scale(1.05)";
};
button.onmouseout = function () {
button.style.backgroundColor = "#000080";
button.style.transform = "scale(1)";
};
button.onmousedown = function () {
button.style.transform = "scale(0.95)";
};
button.onmouseup = function () {
button.style.transform = "scale(1)";
};
}
function appendAndShowOrHideModal(modal) {
document.body.appendChild(modal);
window.onclick = function (event) {
if (event.target == modal) {
modal.style.opacity = "0";
setTimeout(function () {
document.body.removeChild(modal);
}, 500);
}
};
}
function setupMainContainer(container, id) {
container.id = id;
container.style.display = "flex";
container.style.flexDirection = "column";
container.style.justifyContent = "center";
container.style.alignItems = "center";
container.style.marginTop = "20px";
return container;
}
function setupTab(tab, id, text) {
tab.textContent = text;
tab.id = id;
tab.style.margin = "4px";
}
function fetchExtraLeagueData(sid, leagueType, tid) {
fetch(
`https://www.managerzone.com/ajax.php?p=extraLeague&sub=division_runner_ups&type=${leagueType}&sid=${sid}&tid=${tid}&sport=soccer`
)
.then((response) => response.text())
.then((html) => {
const extraLeagueDataModal = createExtraLeagueDataModal(html);
document.body.appendChild(extraLeagueDataModal);
})
.catch((error) => console.error("Error: ", error));
}
function createExtraLeagueDataModal(html) {
const modal = document.createElement("div");
setupModal(modal, "extra-league-data-modal");
const extraDataDiv = document.createElement("div");
extraDataDiv.innerHTML = html;
extraDataDiv.style.width = "60%";
modal.appendChild(extraDataDiv);
window.addEventListener("click", function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
});
return modal;
}
function createCountryDropdown(
leagueType,
tabContainer,
leagueTablesContainer
) {
const dropdown = document.createElement("select");
dropdown.id = "country-dropdown";
addPotentialAllOpt(dropdown, leagueType);
const countries = getCountries(leagueType);
countries.forEach((country) => {
const option = document.createElement("option");
option.value = country;
option.text = country;
dropdown.appendChild(option);
});
dropdown.onchange = function () {
const selectedCountry = this.value;
const leagues = getLeaguesObjFromLeagueType(leagueType, selectedCountry);
while (tabContainer.firstChild) {
tabContainer.removeChild(tabContainer.firstChild);
}
setupLeaguesTabs(
tabContainer,
"leagues-tabs",
leagueType,
leagues,
leagueTablesContainer
);
while (leagueTablesContainer.firstChild) {
leagueTablesContainer.removeChild(leagueTablesContainer.firstChild);
}
if (tabContainer.firstChild) {
tabContainer.firstChild.click();
}
};
return dropdown;
}
function addPotentialAllOpt(dropdown, leagueType) {
if (
!["world", "u18_world", "u21_world", "u23_world"].includes(leagueType)
) {
const allOption = document.createElement("option");
allOption.value = "All";
allOption.text = "All";
dropdown.appendChild(allOption);
}
}
const myTeamLeaguesInfo = Array.from(infoAboutTeam.querySelectorAll("dd"))
.slice(5, 14)
.reduce((info, dd, index) => {
const leagueType = dd
.querySelector(".teamExpText")
.textContent.trim()
.toLowerCase();
const leagueValue = dd.querySelector("strong a").textContent.trim();
let division;
if (index === 0 || leagueType === "league") {
division = isNaN(parseInt(leagueValue[0], 10))
? "Top Division"
: `Division ${parseInt(leagueValue[0], 10)}`;
} else if (
[
"world league",
"u18 world league",
"u21 world league",
"u23 world league",
].includes(leagueType)
) {
division = leagueValue.startsWith("Top")
? "Top Series"
: `Division ${parseInt(
leagueValue.split("div")[1].split(".")[0],
10
)}`;
} else {
division = leagueValue.includes("div")
? `Division ${parseInt(
leagueValue.split("div")[1].split(".")[0],
10
)}`
: "Top Division";
}
info[leagueType] = division;
return info;
}, {});
function getSeniorLeagues() {
let countries;
if (sport === "soccer") {
countries = [
{ name: "Argentina", start: 16096 },
{ name: "Brazil", start: 26187 },
{ name: "China", start: 70847 },
{ name: "Germany", start: 12086 },
{ name: "Italy", start: 10625 },
{ name: "Netherlands", start: 15004 },
{ name: "Portugal", start: 17566 },
{ name: "Spain", start: 10746 },
{ name: "Poland", start: 13181 },
{ name: "Romania", start: 17929 },
{ name: "Sweden", start: 43 },
{ name: "Turkey", start: 20356 },
];
} else {
countries = [
{ name: "Brazil", start: 7900 },
{ name: "Sweden", start: 1 },
{ name: "Argentina", start: 2 },
{ name: "Poland", start: 23 },
{ name: "Portugal", start: 24 },
{ name: "Spain", start: 12 },
{ name: "Romania", start: 25 },
{ name: "Turkey", start: 27 },
{ name: "China", start: 13727 },
];
}
let leagues = {};
for (let country of countries) {
leagues[country.name] = {
"Top Division": [country.start],
};
}
const sortedLeagues = Object.keys(leagues)
.sort()
.reduce((result, key) => {
result[key] = leagues[key];
return result;
}, {});
return sortedLeagues;
}
function getWorldLeaguesObj() {
const leagues = {};
let start = 1;
for (let i = 0; i <= 4; ++i) {
const divisionName = i === 0 ? "Top Series" : `Division ${i}`;
leagues[divisionName] = [];
const numLeagues = Math.pow(3, i);
for (let j = 0; j < numLeagues; ++j) {
leagues[divisionName].push(start++);
}
}
return leagues;
}
function getUxxLeagues() {
let UxxRegions;
if (sport === "soccer") {
UxxRegions = [
{ name: "Argentina", start: 1 },
{ name: "Brazil", start: 122 },
{ name: "Latin America, USA and Canada", start: 727 },
{ name: "Central Europe", start: 848 },
{ name: "Iberia", start: 969 },
{ name: "Mediterranean", start: 1090 },
{ name: "Northern Europe", start: 1211 },
{ name: "Poland", start: 243 },
{ name: "Romania", start: 364 },
{ name: "Sweden", start: 485 },
{ name: "Turkey", start: 606 },
{ name: "China/Asia/Africa", start: 1332 },
];
} else {
UxxRegions = [
{ name: "Northern Europe", start: 1 },
{ name: "Southern Europe", start: 122 },
{ name: "Rest of the World", start: 243 },
];
}
let leagues = {};
for (let region of UxxRegions) {
leagues[region.name] = {
"Top Division": [region.start],
"Division 1": [],
"Division 2": [],
};
for (let i = 1; i <= 12; i++) {
if (i <= 3) {
leagues[region.name]["Division 1"].push(region.start + i);
} else {
leagues[region.name]["Division 2"].push(region.start + i);
}
}
}
return leagues;
}
})();
GM_addStyle(`
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap');
`);