MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
/* ========================================================================= | /* ========================================================================= | ||
aslimona.xyz — inline lightbox for gallery / thumbnail images | aslimona.xyz — inline lightbox for gallery / thumbnail images | ||
| Line 257: | Line 256: | ||
} | } | ||
var scheme = h % SCHEMES; | var scheme = h % SCHEMES; | ||
// One of 3 background images, picked at RANDOM on every page load. | |||
var bg = Math.floor( Math.random() * 3 ); | |||
if ( document.body ) { | if ( document.body ) { | ||
document.body.classList.add( 'crazy-scheme-' + scheme ); | document.body.classList.add( 'crazy-scheme-' + scheme ); | ||
document.body.classList.add( 'crazy-bg-' + bg ); | |||
} | } | ||
} | } | ||
Revision as of 13:02, 20 July 2026
/* =========================================================================
aslimona.xyz — inline lightbox for gallery / thumbnail images
Paste this ENTIRE file into: Special:MyLanguage/MediaWiki:Common.js
(as an admin: go to https://aslimona.xyz/index.php/MediaWiki:Common.js
click "Edit", paste, save.)
Fixes the "click image -> File page -> back -> click next" problem:
clicking any gallery or thumbnail image now opens a big in-page viewer
with Prev/Next arrows and keyboard navigation, on every article,
automatically. No per-page changes needed.
========================================================================= */
( function () {
'use strict';
function onReady( fn ) {
if ( document.readyState !== 'loading' ) {
fn();
} else {
document.addEventListener( 'DOMContentLoaded', fn );
}
}
// Convert a MediaWiki thumbnail URL to the full-resolution original URL.
// e.g. .../images/a/a1/Foo.jpg/800px-Foo.jpg -> .../images/a/a1/Foo.jpg
// .../images/thumb/a/a1/Foo.jpg/800px-Foo.jpg -> .../images/a/a1/Foo.jpg
function originalFromThumb( src ) {
var m = src.match( /^(.*\/thumb\/([0-9a-f])\/([0-9a-f]{2})\/([^\/]+))\/\d+px-[^\/]+$/i );
if ( m ) {
return src.replace( '/thumb/', '/' ).replace( /\/\d+px-[^\/]+$/, '' );
}
var m2 = src.match( /^(.*\/[0-9a-f]\/[0-9a-f]{2}\/[^\/]+)\/\d+px-[^\/]+$/i );
if ( m2 ) {
return m2[ 1 ];
}
return src;
}
function injectStyles() {
var css = [
'.aslimona-lb-overlay{position:fixed;inset:0;background:rgba(6,6,7,0.94);',
'z-index:100000;display:flex;flex-direction:column;align-items:center;',
'justify-content:center;padding:4vh 4vw;box-sizing:border-box;}',
'.aslimona-lb-overlay[hidden]{display:none;}',
'.aslimona-lb-img{max-width:92vw;max-height:80vh;object-fit:contain;',
'border:1px solid #3a372f;background:#111;}',
'.aslimona-lb-caption{color:#a89f8c;font-family:"IBM Plex Mono","Courier New",monospace;',
'font-size:0.8rem;margin-top:14px;text-align:center;max-width:80vw;}',
'.aslimona-lb-counter{color:#6e6858;font-family:"IBM Plex Mono","Courier New",monospace;',
'font-size:0.7rem;margin-top:4px;letter-spacing:0.08em;}',
'.aslimona-lb-close,.aslimona-lb-prev,.aslimona-lb-next{position:fixed;',
'background:transparent;border:1px solid #3a372f;color:#e9e4d8;',
'font-family:Georgia,serif;cursor:pointer;transition:background .2s,color .2s;}',
'.aslimona-lb-close:hover,.aslimona-lb-prev:hover,.aslimona-lb-next:hover{',
'background:#c9a15a;color:#0c0c0d;}',
'.aslimona-lb-close{top:24px;right:24px;width:40px;height:40px;font-size:20px;',
'line-height:38px;text-align:center;}',
'.aslimona-lb-prev,.aslimona-lb-next{top:50%;transform:translateY(-50%);',
'width:48px;height:64px;font-size:22px;}',
'.aslimona-lb-prev{left:16px;}',
'.aslimona-lb-next{right:16px;}',
'@media (max-width:600px){',
'.aslimona-lb-prev,.aslimona-lb-next{width:36px;height:52px;font-size:18px;}',
'.aslimona-lb-close{width:34px;height:34px;font-size:17px;line-height:32px;}',
'}'
].join( '' );
var style = document.createElement( 'style' );
style.textContent = css;
document.head.appendChild( style );
}
function buildOverlay() {
var overlay = document.createElement( 'div' );
overlay.className = 'aslimona-lb-overlay';
overlay.hidden = true;
var img = document.createElement( 'img' );
img.className = 'aslimona-lb-img';
overlay.appendChild( img );
var caption = document.createElement( 'div' );
caption.className = 'aslimona-lb-caption';
overlay.appendChild( caption );
var counter = document.createElement( 'div' );
counter.className = 'aslimona-lb-counter';
overlay.appendChild( counter );
var closeBtn = document.createElement( 'button' );
closeBtn.className = 'aslimona-lb-close';
closeBtn.setAttribute( 'aria-label', 'Close' );
closeBtn.textContent = '×';
overlay.appendChild( closeBtn );
var prevBtn = document.createElement( 'button' );
prevBtn.className = 'aslimona-lb-prev';
prevBtn.setAttribute( 'aria-label', 'Previous image' );
prevBtn.textContent = '‹';
overlay.appendChild( prevBtn );
var nextBtn = document.createElement( 'button' );
nextBtn.className = 'aslimona-lb-next';
nextBtn.setAttribute( 'aria-label', 'Next image' );
nextBtn.textContent = '›';
overlay.appendChild( nextBtn );
document.body.appendChild( overlay );
return {
overlay: overlay,
img: img,
caption: caption,
counter: counter,
closeBtn: closeBtn,
prevBtn: prevBtn,
nextBtn: nextBtn
};
}
onReady( function () {
var content = document.querySelector( '.mw-parser-output' );
if ( !content ) {
return;
}
// Collect every lightbox-able image link on the page, in document order:
// - <gallery> thumbnails: li.gallerybox a.image
// - inline [[File:x|thumb]]: div.thumb a.image
var links = Array.prototype.slice.call(
content.querySelectorAll( 'li.gallerybox a.image, div.thumb a.image, a.image' )
);
if ( !links.length ) {
return;
}
// de-duplicate while preserving order
var seen = {};
links = links.filter( function ( a ) {
if ( seen[ a.href ] ) {
return false;
}
seen[ a.href ] = true;
return true;
} );
var items = links.map( function ( a ) {
var thumbImg = a.querySelector( 'img' );
var full = thumbImg ? originalFromThumb( thumbImg.src ) : a.href;
var captionEl = null;
var gallerytext = a.closest( 'li.gallerybox' );
if ( gallerytext ) {
captionEl = gallerytext.querySelector( '.gallerytext' );
} else {
var thumbinner = a.closest( '.thumbinner' );
if ( thumbinner ) {
captionEl = thumbinner.querySelector( '.thumbcaption' );
}
}
return {
full: full,
caption: captionEl ? captionEl.textContent.trim() : ( thumbImg ? thumbImg.alt : '' ),
link: a
};
} );
injectStyles();
var ui = buildOverlay();
var currentIndex = 0;
function show( index ) {
currentIndex = ( index + items.length ) % items.length;
var item = items[ currentIndex ];
ui.img.src = item.full;
ui.caption.textContent = item.caption || '';
ui.counter.textContent = ( currentIndex + 1 ) + ' / ' + items.length;
}
function open( index ) {
show( index );
ui.overlay.hidden = false;
document.body.style.overflow = 'hidden';
}
function close() {
ui.overlay.hidden = true;
document.body.style.overflow = '';
}
items.forEach( function ( item, index ) {
item.link.addEventListener( 'click', function ( ev ) {
// let ctrl/cmd/shift/middle-clicks behave normally (open in new tab etc.)
if ( ev.ctrlKey || ev.metaKey || ev.shiftKey || ev.button === 1 ) {
return;
}
ev.preventDefault();
open( index );
} );
} );
ui.closeBtn.addEventListener( 'click', close );
ui.prevBtn.addEventListener( 'click', function () {
show( currentIndex - 1 );
} );
ui.nextBtn.addEventListener( 'click', function () {
show( currentIndex + 1 );
} );
ui.overlay.addEventListener( 'click', function ( ev ) {
if ( ev.target === ui.overlay ) {
close();
}
} );
document.addEventListener( 'keydown', function ( ev ) {
if ( ui.overlay.hidden ) {
return;
}
if ( ev.key === 'Escape' ) {
close();
} else if ( ev.key === 'ArrowLeft' ) {
show( currentIndex - 1 );
} else if ( ev.key === 'ArrowRight' ) {
show( currentIndex + 1 );
}
} );
} );
}() );
/* =========================================================================
CRAZY VERSION — per-page color scheme picker.
Works together with the CRAZY VERSION block in MediaWiki:Common.css.
Reads the current page name and picks ONE of 10 schemes
(.crazy-scheme-0 … .crazy-scheme-9). Deterministic: the same page
ALWAYS gets the same look, but different pages (Digital Twin, Homes of
the Internet, Köçek Pisti …) look completely different from each other.
To turn the crazy version off: delete this block AND the CRAZY VERSION
block in MediaWiki:Common.css. The lightbox code above is unaffected.
========================================================================= */
( function () {
'use strict';
var SCHEMES = 10;
function pageName() {
if ( window.mw && mw.config && mw.config.get ) {
var n = mw.config.get( 'wgPageName' );
if ( n ) {
return n;
}
}
return document.title || 'Main_Page';
}
function apply() {
var name = pageName();
var h = 0;
for ( var i = 0; i < name.length; i++ ) {
h = ( h * 31 + name.charCodeAt( i ) ) >>> 0;
}
var scheme = h % SCHEMES;
// One of 3 background images, picked at RANDOM on every page load.
var bg = Math.floor( Math.random() * 3 );
if ( document.body ) {
document.body.classList.add( 'crazy-scheme-' + scheme );
document.body.classList.add( 'crazy-bg-' + bg );
}
}
if ( document.readyState !== 'loading' ) {
apply();
} else {
document.addEventListener( 'DOMContentLoaded', apply );
}
}() );