MediaWiki:Script/Tabber.js
Nota: Após gravar, terá de limpar a cache do seu navegador para ver as alterações.
- Firefox / Safari: Pressione Shift enquanto clica Recarregar, ou pressione Ctrl-F5 ou Ctrl-R (⌘-R no Mac)
- Google Chrome: Pressione Ctrl-Shift-R (⌘-Shift-R no Mac)
- Internet Explorer: Pressione Ctrl enquanto clica Recarregar, ou pressione Ctrl-F5
- Opera: Ir para Menu → Configurações (Opera → Preferências no Mac) e, em seguida, Privacidade e segurança → Limpar dados de navegação → Imagens e ficheiros em cache.
function changeDisplay(button, textContainer, method) {
button.classList[method]("tabber-active");
textContainer.children[button.dataset.position].classList[method]("tabber-active");
}
function globalChange(button, allButton, allText, toggleButton, changeUrl, bool = false) {
var activeButton = allButton.querySelector(".tabber-active");
if (toggleButton || button !== activeButton) {
if (bool && changeUrl) {
var newHash = "#"+button.id;
history.pushState({}, "", newHash);
}
changeDisplay(button, allText, "toggle");
if (button !== activeButton && activeButton !== null) {
changeDisplay(activeButton, allText, "remove");
}
}
}
function updateTabber(buttonContainer, textContainer, toggleButton, changeUrl) {
var targetButton = buttonContainer.querySelector(":target");
if (targetButton !== null && targetButton.classList.contains("button")) {
globalChange(targetButton, buttonContainer, textContainer, false, false);
}
buttonContainer.addEventListener("click", function(event) {
var target = event.target.closest(".button");
if (target) {
globalChange(target, buttonContainer, textContainer, toggleButton, changeUrl, true);
}
});
}
function updateTabberWithUrlChange() {
window.addEventListener("hashchange", function(e) {
var newHash = e.target.location.hash;
if (newHash !== "") {
var targetButton = document.getElementById(newHash.slice(1));
if (targetButton) {
if (targetButton.classList.contains("button")) {
var [buttonContainer, textContainer] = targetButton.parentElement.parentElement.children;
globalChange(targetButton, buttonContainer, textContainer, false, false);
}
}
}
});
}
(function() {
var tabberContainer = document.querySelectorAll("div.tabber-container");
tabberContainer.forEach(function(tabber) {
var [buttonContainer, textContainer] = tabber.children;
var toggleButton = tabber.dataset.toggle === "1";
var changeUrl = tabber.dataset.url === "1";
updateTabber(buttonContainer, textContainer, toggleButton, changeUrl);
});
updateTabberWithUrlChange();
})();
/* NOVO */
class SpawnLayerManager {
static SPAWN_COLOR_KEY = "mt2.spawn.color";
static OPTION_MAPPING = {
0: "🟥 Vermelho",
50: "🟫 Castanho",
140: "🟩 Verde",
230: "🟦 Azul",
290: "🟪 Roxo",
black: "⬛ Preto",
white: "⬜ Branco",
};
static STYLE_MAPPING = {
position: "absolute",
top: "0",
left: "0",
margin: "4px",
background: "#434242b3",
color: "white",
borderRadius: "5px",
cursor: "pointer",
border: "1px white solid",
};
constructor(containerSelector = ".spawn-map-container") {
this.containerSelector = containerSelector;
this.currentFilter = null;
this.selects = [];
this.spawnLayers = [];
this.isClipboardImageSupported = this._isClipboardImageSupported();
this._initialize();
}
_isClipboardImageSupported() {
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
return !!(navigator.clipboard?.write && window.ClipboardItem) && !isSafari;
}
_initialize() {
const containers = this._getContainers();
if (!containers.length) return;
containers.forEach((container) => this._setupContainer(container));
const savedColor = this._getSavedColor();
if (savedColor) this._applyColor(savedColor);
}
_getContainers() {
return document.querySelectorAll(this.containerSelector);
}
_getSavedColor() {
return localStorage.getItem(SpawnLayerManager.SPAWN_COLOR_KEY);
}
_saveColor(value) {
localStorage.setItem(SpawnLayerManager.SPAWN_COLOR_KEY, value);
}
_setupContainer(container) {
const [mapContainer, spawnContainer] = container.children;
if (!mapContainer || !spawnContainer) return;
const map = mapContainer.querySelector("img");
const spawnLayer = spawnContainer.querySelector("img");
if (!map || !spawnLayer) return;
const select = this._createColorSelect();
spawnContainer.appendChild(select);
this.selects.push(select);
this.spawnLayers.push(spawnLayer);
select.addEventListener("change", (e) => this._onColorChange(e));
if (this.isClipboardImageSupported) {
this._setupCopyButton(spawnContainer, map, spawnLayer);
}
}
_createColorSelect() {
const select = document.createElement("select");
for (const [value, label] of Object.entries(
SpawnLayerManager.OPTION_MAPPING
)) {
const option = document.createElement("option");
option.value = value;
option.textContent = label;
select.appendChild(option);
}
Object.assign(select.style, SpawnLayerManager.STYLE_MAPPING);
return select;
}
_onColorChange(event) {
const value = event.target.value;
this._applyColor(value);
}
_applyColor(value) {
if (!SpawnLayerManager.OPTION_MAPPING.hasOwnProperty(value)) return;
const filter = this._getFilterForValue(value);
this.currentFilter = filter;
this.selects.forEach((select) => (select.value = value));
this.spawnLayers.forEach((layer) => (layer.style.filter = filter));
this._saveColor(value);
}
_getFilterForValue(value) {
switch (value) {
case "black":
return "invert(1) brightness(0) contrast(100%)";
case "white":
return "invert(1) sepia(1) saturate(100%) brightness(3)";
default:
return `hue-rotate(${value}deg)`;
}
}
_setupCopyButton(spawnContainer, map, spawnLayer) {
const copyButton = spawnContainer.querySelector(".copy-to-clipboard");
if (!copyButton) return;
const defaultEmoji = copyButton.querySelector("[data-default]");
const clickedEmoji = copyButton.querySelector("[data-clicked]");
if (!defaultEmoji || !clickedEmoji) return;
showElement(copyButton);
copyButton.addEventListener("click", () => {
this._copyCombinedImageToClipboard(map, spawnLayer);
this._copyAnimation(defaultEmoji, clickedEmoji);
});
}
_copyCombinedImageToClipboard(map, spawnLayer) {
const canvas = document.createElement("canvas");
canvas.width = Math.max(map.naturalWidth, spawnLayer.naturalWidth);
canvas.height = Math.max(map.naturalHeight, spawnLayer.naturalHeight);
const ctx = canvas.getContext("2d");
ctx.drawImage(map, 0, 0);
const filteredLayer = this._drawFilteredLayer(spawnLayer);
ctx.drawImage(filteredLayer, 0, 0);
this._copyCanvasContentsToClipboard(canvas);
}
_drawFilteredLayer(layer) {
const canvas = document.createElement("canvas");
canvas.width = layer.naturalWidth;
canvas.height = layer.naturalHeight;
const ctx = canvas.getContext("2d");
ctx.filter = this.currentFilter || "none";
ctx.drawImage(layer, 0, 0);
return canvas;
}
async _getBlobFromCanvas(canvas) {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
if (blob) {
resolve(blob);
} else {
reject(new Error("Canvas toBlob failed"));
}
});
});
}
async _copyCanvasContentsToClipboard(canvas) {
try {
const blob = await this._getBlobFromCanvas(canvas);
const data = [new ClipboardItem({ [blob.type]: blob })];
await navigator.clipboard.write(data);
} catch (error) {
console.error(error);
}
}
_copyAnimation(defaultEmoji, clickedEmoji) {
hideElement(defaultEmoji);
showElement(clickedEmoji);
setTimeout(() => {
hideElement(clickedEmoji);
showElement(defaultEmoji);
}, 1500);
}
}
new SpawnLayerManager();