User:B700465189a9/Gadget-Palette.js
From the Super Mario Wiki, the Mario encyclopedia
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)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
$(function() {
const paletteData = JSON.parse("[{\"colors\":[4278190080,4281545984,4283833600,4285269760,4278994944,4278210312,4278211072,4285230336,4285399104,4284219518,4278206541,4283387727,4284900966,4290064672,4288237056,4290190971,4279079680,4281894656,4278226738,4284277808,4290559488,4293565986,4287158272,4294934896,4278200968,4279505575,4282056868,4278221965,4285868030,4279590873,4282532095,4288682700,4294930124,4291196671,4294077183,4282769538,4284788991,4282961374,4289572269,4290295992,4290639019,4291817366,4293191060,4294432933,4287795455,4289983436,4290112498,4294954181,4290830335,4292072191,4294952170,4293445887,4294623999,4294967295],\"name\":\"15° Canonical\"}]");
const palettes = new Set();
paletteData.forEach(palette => palettes.add({
colors: new Set(palette.colors),
deprecation: palette.deprecation,
name: palette.name,
}));
function checkData(data) {
if (data.width > 0 && data.height > 0) {
const possiblePalettes = new Set(palettes);
let alpha = false;
for (let y = 0; y < data.height; y++) {
for (let x = 0; x < data.width; x++) {
const index = (y * data.width + x) * 4;
const r = data.data[index];
const g = data.data[index + 1];
const b = data.data[index + 2];
const a = data.data[index + 3];
if (a === 0xFF) {
alpha = true;
} else {
const color = ((a << 24) | (r << 16) | (g << 8) | b) >>> 0;
for (const palette of possiblePalettes) {
if (!palette.colors.has(color)) {
possiblePalettes.delete(palette);
}
}
if (possiblePalettes.size === 0) {
return { possiblePalettes: false, alpha: false };
}
}
}
}
return { possiblePalettes, alpha };
}
return { possiblePalettes: false, alpha: false };
}
function hover(text, hoverText) {
const span = document.createElement("span");
span.textContent = text;
span.className = "explain";
span.title = hoverText;
return span;
}
function check(url, cell) {
const image = new Image();
image.addEventListener("error", function () {
cell.textContent = "Error";
URL.revokeObjectURL(url);
});
image.addEventListener("load", function () {
const canvas = new OffscreenCanvas(image.width, image.height);
const context = canvas.getContext("2d");
context.drawImage(image, 0, 0);
const data = context.getImageData(0, 0, image.width, image.height);
const { possiblePalettes, alpha } = checkData(data);
cell.textContent = "";
if (!possiblePalettes) {
cell.append(hover("Unknown", "Image uses a color that isn't in the list of known palettes."));
} else {
let index = 0;
for (const palette of possiblePalettes) {
if (palette.deprecation) {
cell.append(hover(palette.name, palette.deprecation));
} else {
cell.append(palette.name);
}
if ((index + 1) < possiblePalettes.length) {
cell.append(", ");
}
index += 1;
}
if (alpha) {
cell.append(" (+ transparency)")
}
}
URL.revokeObjectURL(url);
});
image.crossOrigin = "Anonymous";
image.src = url;
cell.textContent = "Loading...";
}
function checkRow(row, cell) {
const originalImage = row.querySelector("td:nth-child(2) a");
if (!originalImage) return;
const url = new URL(originalImage.href);
if (!url.pathname.endsWith(".png")) {
cell.textContent = "";
cell.append(hover("Unsupported", "Only PNG files can be checked for palette."));
return;
}
check(url, cell);
}
for (const table of document.querySelectorAll("table.filehistory")) {
const dimensions = [...table.querySelectorAll("th")].findIndex(cell => cell.textContent === "Dimensions");
for (const row of table.rows) {
const header = row.cells[0].tagName === "TH";
const cell = document.createElement(header ? "th" : "td");
cell.textContent = header ? "Palette" : "-";
row.insertBefore(cell, row.cells[dimensions].nextSibling);
if (!header) {
checkRow(row, cell);
}
}
}
const upload = document.querySelector("#wpUploadFile");
if (upload) {
const row = document.createElement("tr");
const cell = document.createElement("td");
row.textContent = "Palette: ";
const text = document.createElement("span");
text.textContent = "-";
cell.append(text);
row.append(cell);
document.querySelector("#mw-htmlform-source tbody").append(row);
upload.addEventListener("change", () => {
if (upload.files && upload.files[0]) {
const url = URL.createObjectURL(upload.files[0]);
check(url, text);
} else {
text.textContent = "-";
}
});
}
});