User:Stumblean/common.js
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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
(function () {
const iconURL = "https://files.catbox.moe/wk78nl.jpg";
// === MENU CONTAINER ===
const menu = document.createElement("div");
Object.assign(menu.style, {
position: "fixed",
top: "20px",
right: "20px",
background: "#7889B2",
color: "#fff",
border: "2px solid #fff",
borderRadius: "10px",
padding: "10px",
fontFamily: "monospace",
zIndex: "99999",
boxShadow: "0 0 10px black",
touchAction: "none",
width: "180px",
});
// === MINIMIZED ICON ===
const minimizedIcon = document.createElement("img");
minimizedIcon.src = iconURL;
minimizedIcon.width = 30;
minimizedIcon.height = 30;
Object.assign(minimizedIcon.style, {
position: "fixed",
top: "20px",
right: "20px",
display: "none",
cursor: "pointer",
zIndex: "99999"
});
minimizedIcon.addEventListener("click", () => {
menu.style.display = "block";
minimizedIcon.style.display = "none";
});
// === HEADER WITH MINIMIZE BUTTON ===
const header = document.createElement("div");
header.style.display = "flex";
header.style.alignItems = "center";
header.style.justifyContent = "space-between";
header.style.marginBottom = "8px";
header.style.cursor = "grab";
const titleWrap = document.createElement("div");
titleWrap.style.display = "flex";
titleWrap.style.gap = "6px";
titleWrap.style.alignItems = "center";
const img1 = document.createElement("img");
img1.src = iconURL;
img1.width = 15;
img1.height = 15;
const title = document.createElement("div");
title.textContent = "Mahito Menu";
title.style.fontWeight = "bold";
title.style.color = "#fff";
const img2 = document.createElement("img");
img2.src = iconURL;
img2.width = 15;
img2.height = 15;
titleWrap.appendChild(img1);
titleWrap.appendChild(title);
titleWrap.appendChild(img2);
const minimizeBtn = document.createElement("button");
minimizeBtn.textContent = "–";
Object.assign(minimizeBtn.style, {
background: "#45A8C5",
border: "none",
color: "#fff",
cursor: "pointer",
borderRadius: "5px",
width: "25px",
height: "25px",
fontSize: "18px",
lineHeight: "20px",
});
minimizeBtn.addEventListener("click", () => {
menu.style.display = "none";
minimizedIcon.style.display = "block";
});
header.appendChild(titleWrap);
header.appendChild(minimizeBtn);
// === BUTTON FACTORY ===
function makeButton(text, onclick) {
const btn = document.createElement("button");
btn.textContent = text;
btn.onclick = onclick;
Object.assign(btn.style, {
marginBottom: "6px",
width: "100%",
cursor: "pointer",
background: "#45A8C5",
color: "#fff",
border: "none",
padding: "5px 10px",
borderRadius: "5px",
});
return btn;
}
const btnUndo = makeButton("Mass undo", () => {
prompt("Copy this into your common.js:", "mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Alexis_Jazz/Kill-It-With-Fire.js&action=raw&ctype=text/javascript');");
});
const btnExplain = makeButton("Open Explanation", () => {
alert("Open Explanation clicked");
});
const btnEncourage = makeButton("Encouragement", () => {
if (ytContainer.style.display === "none") {
ytContainer.style.display = "block";
} else {
ytContainer.style.display = "none";
ytIframe.src = ytIframe.src;
}
});
// === YOUTUBE CONTAINER ===
const ytContainer = document.createElement("div");
ytContainer.style.position = "fixed";
ytContainer.style.right = "20px";
ytContainer.style.top = "150px";
ytContainer.style.zIndex = "99998";
ytContainer.style.display = "none";
ytContainer.style.background = "#000";
ytContainer.style.padding = "5px";
ytContainer.style.borderRadius = "10px";
ytContainer.style.boxShadow = "0 0 10px black";
const ytIframe = document.createElement("iframe");
ytIframe.width = "280";
ytIframe.height = "157";
ytIframe.src = "https://www.youtube.com/embed/VKfyq_hOL0c?autoplay=1";
ytIframe.title = "Self Embodiment of Perfection OST - Mahito Theme";
ytIframe.frameBorder = "0";
ytIframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture";
ytIframe.allowFullscreen = true;
ytContainer.appendChild(ytIframe);
// === ASSEMBLE MENU ===
menu.appendChild(header);
menu.appendChild(btnUndo);
menu.appendChild(btnExplain);
menu.appendChild(btnEncourage);
document.body.appendChild(menu);
document.body.appendChild(minimizedIcon);
document.body.appendChild(ytContainer);
// === DRAGGING SUPPORT (menu + icon) ===
let isDragging = false;
let offsetX = 0, offsetY = 0;
function startDrag(x, y) {
isDragging = true;
const rect = menu.getBoundingClientRect();
offsetX = x - rect.left;
offsetY = y - rect.top;
menu.style.left = rect.left + "px";
menu.style.top = rect.top + "px";
menu.style.right = "auto";
}
function doDrag(x, y) {
if (!isDragging) return;
const left = x - offsetX;
const top = y - offsetY;
menu.style.left = left + "px";
menu.style.top = top + "px";
ytContainer.style.right = "auto";
ytContainer.style.left = left + "px";
ytContainer.style.top = top + menu.offsetHeight + 10 + "px";
minimizedIcon.style.left = left + "px";
minimizedIcon.style.top = top + "px";
minimizedIcon.style.right = "auto";
}
function stopDrag() {
isDragging = false;
}
header.addEventListener("mousedown", (e) => {
startDrag(e.clientX, e.clientY);
e.preventDefault();
});
document.addEventListener("mousemove", (e) => doDrag(e.clientX, e.clientY));
document.addEventListener("mouseup", stopDrag);
header.addEventListener("touchstart", (e) => {
const t = e.touches[0];
startDrag(t.clientX, t.clientY);
e.preventDefault();
});
document.addEventListener("touchmove", (e) => {
if (!isDragging) return;
const t = e.touches[0];
doDrag(t.clientX, t.clientY);
});
document.addEventListener("touchend", stopDrag);
})();