User:CannonProductions/monacobookbeta.js: Difference between revisions
From MediaWiki
Jump to navigationJump to search
No edit summary |
No edit summary |
||
| Line 50: | Line 50: | ||
// ===== Remove the redundant mobile logo portlet ===== | // ===== Remove the redundant mobile logo portlet ===== | ||
function removeMobileLogoPortlet() { | function removeMobileLogoPortlet() { | ||
var p = document.getElementById("p-m- | var p = document.getElementById("p-m-logo"); | ||
if (p && p.parentNode) p.parentNode.removeChild(p); | |||
} | |||
// ===== Banner scaling ===== | |||
function resetBannerStyles(ad, iframe) { | |||
if (ad) { | |||
ad.style.height = ""; | |||
ad.style.overflow = ""; | |||
ad.style.width = ""; | |||
} | |||
if (iframe) { | |||
iframe.style.transform = ""; | |||
iframe.style.transformOrigin = ""; | |||
iframe.style.width = ""; | |||
iframe.style.height = ""; | |||
iframe.style.border = ""; | |||
iframe.style.display = ""; | |||
} | |||
} | |||
function rescaleBanner() { | |||
var ad = document.getElementById("top-ad"); | |||
if (!ad) return; | |||
var iframe = ad.querySelector("iframe"); | |||
if (!iframe) return; | |||
if (!isMobileWidth()) { | |||
resetBannerStyles(ad, iframe); | |||
return; | |||
} | |||
iframe.style.width = BASE_W + "px"; | |||
iframe.style.height = BASE_H + "px"; | |||
iframe.style.border = "0"; | |||
iframe.style.display = "block"; | |||
iframe.style.transformOrigin = "top left"; | |||
var available = ad.getBoundingClientRect().width || window.innerWidth; | |||
var scale = available / BASE_W; | |||
if (scale > MAX_SCALE) scale = MAX_SCALE; | |||
if (scale < MIN_SCALE) scale = MIN_SCALE; | |||
iframe.style.transform = "scale(" + scale.toFixed(4) + ")"; | |||
ad.style.width = "100%"; | |||
ad.style.overflow = "hidden"; | |||
ad.style.height = (BASE_H * scale) + "px"; | |||
} | |||
// ===== Nav open detection (more reliable) ===== | |||
function isNavOpen() { | |||
var nav = document.getElementById("column-one"); | |||
if (!nav) return false; | |||
var cs = window.getComputedStyle(nav); | |||
if (!cs) return false; | |||
// Some skins don’t toggle visibility, just move/resize it. | |||
if (cs.display === "none") return false; | |||
var r = nav.getBoundingClientRect(); | |||
// Must have real size | |||
if (r.width < 20 || r.height < 20) return false; | |||
// Must intersect the viewport (prevents “off-canvas but present” false positives) | |||
if (r.right <= 0 || r.bottom <= 0) return false; | |||
if (r.left >= window.innerWidth || r.top >= window.innerHeight) return false; | |||
return true; | |||
} | |||
// ===== Nav scroll locking + html class ===== | |||
function setScrollLocked(locked) { | |||
if (locked) { | |||
document.documentElement.style.overflow = "hidden"; | |||
document.body.style.overflow = "hidden"; | |||
document.body.setAttribute("data-nav-locked", "1"); | |||
} else { | |||
if (document.body.getAttribute("data-nav-locked") === "1") { | |||
document.documentElement.style.overflow = ""; | |||
document.body.style.overflow = ""; | |||
document.body.removeAttribute("data-nav-locked"); | |||
} | |||
} | |||
} | |||
function updateNavLockAndClass() { | |||
if (!isMobileWidth()) { | |||
setScrollLocked(false); | |||
document.documentElement.classList.remove("tf-nav-open"); | |||
return; | |||
} | |||
var open = isNavOpen(); | |||
setScrollLocked(open); | |||
if (open) { | |||
document.documentElement.classList.add("tf-nav-open"); | |||
} else { | |||
document.documentElement.classList.remove("tf-nav-open"); | |||
} | |||
} | |||
// ===== Plumbing ===== | |||
var t = null; | |||
function scheduleAll() { | |||
if (t) clearTimeout(t); | |||
t = setTimeout(function () { | |||
removeMobileLogoPortlet(); | |||
rescaleBanner(); | |||
updateNavLockAndClass(); | |||
}, 60); | |||
} | |||
function installObservers() { | |||
removeMobileLogoPortlet(); | |||
rescaleBanner(); | |||
updateNavLockAndClass(); | |||
window.addEventListener("resize", scheduleAll); | |||
window.addEventListener("orientationchange", scheduleAll); | |||
if (window.mw && mw.hook) { | |||
mw.hook("wikipage.content").add(function () { | |||
scheduleAll(); | |||
}); | |||
} | |||
var obs = new MutationObserver(function () { | |||
scheduleAll(); | |||
}); | |||
obs.observe(document.documentElement, { childList: true, subtree: true, attributes: true }); | |||
document.addEventListener("click", function () { | |||
setTimeout(updateNavLockAndClass, 0); | |||
}); | |||
} | |||
onReady(function () { | |||
addBadge(); | |||
installObservers(); | |||
}); | |||
})(); | |||
Revision as of 13:02, 30 December 2025
/* User:CannonProductions/monacobookbeta.js
- Dynamically scales #top-ad iframe banner to fit available width on mobile
- Locks background scroll when the sidebar (#column-one) is open on mobile
- Adds html.tf-nav-open while the sidebar is open (for CSS styling)
- Removes the redundant mobile logo portlet (#p-m-logo) so it doesn’t waste space
*/
(function () {
"use strict";
// === SETTINGS ===
var DEBUG_BADGE = false;
var MOBILE_MAX_WIDTH = 720;
// Banner creative’s native size
var BASE_W = 468;
var BASE_H = 60;
// Banner scale limits
var MIN_SCALE = 0.55;
var MAX_SCALE = 1.0;
function onReady(fn) {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", fn);
} else {
fn();
}
}
function addBadge() {
if (!DEBUG_BADGE) return;
if (!document.body) return;
if (document.getElementById("js-test-badge")) return;
var d = document.createElement("div");
d.id = "js-test-badge";
d.textContent = "User JS RUNNING";
d.style.cssText =
"position:fixed;top:0;left:0;z-index:999999;" +
"padding:6px 10px;background:#e11;color:#fff;" +
"font:12px sans-serif";
document.body.prepend(d);
}
function isMobileWidth() {
return window.matchMedia("(max-width: " + MOBILE_MAX_WIDTH + "px)").matches;
}
// ===== Remove the redundant mobile logo portlet =====
function removeMobileLogoPortlet() {
var p = document.getElementById("p-m-logo");
if (p && p.parentNode) p.parentNode.removeChild(p);
}
// ===== Banner scaling =====
function resetBannerStyles(ad, iframe) {
if (ad) {
ad.style.height = "";
ad.style.overflow = "";
ad.style.width = "";
}
if (iframe) {
iframe.style.transform = "";
iframe.style.transformOrigin = "";
iframe.style.width = "";
iframe.style.height = "";
iframe.style.border = "";
iframe.style.display = "";
}
}
function rescaleBanner() {
var ad = document.getElementById("top-ad");
if (!ad) return;
var iframe = ad.querySelector("iframe");
if (!iframe) return;
if (!isMobileWidth()) {
resetBannerStyles(ad, iframe);
return;
}
iframe.style.width = BASE_W + "px";
iframe.style.height = BASE_H + "px";
iframe.style.border = "0";
iframe.style.display = "block";
iframe.style.transformOrigin = "top left";
var available = ad.getBoundingClientRect().width || window.innerWidth;
var scale = available / BASE_W;
if (scale > MAX_SCALE) scale = MAX_SCALE;
if (scale < MIN_SCALE) scale = MIN_SCALE;
iframe.style.transform = "scale(" + scale.toFixed(4) + ")";
ad.style.width = "100%";
ad.style.overflow = "hidden";
ad.style.height = (BASE_H * scale) + "px";
}
// ===== Nav open detection (more reliable) =====
function isNavOpen() {
var nav = document.getElementById("column-one");
if (!nav) return false;
var cs = window.getComputedStyle(nav);
if (!cs) return false;
// Some skins don’t toggle visibility, just move/resize it.
if (cs.display === "none") return false;
var r = nav.getBoundingClientRect();
// Must have real size
if (r.width < 20 || r.height < 20) return false;
// Must intersect the viewport (prevents “off-canvas but present” false positives)
if (r.right <= 0 || r.bottom <= 0) return false;
if (r.left >= window.innerWidth || r.top >= window.innerHeight) return false;
return true;
}
// ===== Nav scroll locking + html class =====
function setScrollLocked(locked) {
if (locked) {
document.documentElement.style.overflow = "hidden";
document.body.style.overflow = "hidden";
document.body.setAttribute("data-nav-locked", "1");
} else {
if (document.body.getAttribute("data-nav-locked") === "1") {
document.documentElement.style.overflow = "";
document.body.style.overflow = "";
document.body.removeAttribute("data-nav-locked");
}
}
}
function updateNavLockAndClass() {
if (!isMobileWidth()) {
setScrollLocked(false);
document.documentElement.classList.remove("tf-nav-open");
return;
}
var open = isNavOpen();
setScrollLocked(open);
if (open) {
document.documentElement.classList.add("tf-nav-open");
} else {
document.documentElement.classList.remove("tf-nav-open");
}
}
// ===== Plumbing =====
var t = null;
function scheduleAll() {
if (t) clearTimeout(t);
t = setTimeout(function () {
removeMobileLogoPortlet();
rescaleBanner();
updateNavLockAndClass();
}, 60);
}
function installObservers() {
removeMobileLogoPortlet();
rescaleBanner();
updateNavLockAndClass();
window.addEventListener("resize", scheduleAll);
window.addEventListener("orientationchange", scheduleAll);
if (window.mw && mw.hook) {
mw.hook("wikipage.content").add(function () {
scheduleAll();
});
}
var obs = new MutationObserver(function () {
scheduleAll();
});
obs.observe(document.documentElement, { childList: true, subtree: true, attributes: true });
document.addEventListener("click", function () {
setTimeout(updateNavLockAndClass, 0);
});
}
onReady(function () {
addBadge();
installObservers();
});
})();

