User:Ainali/blur.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump.
This code will be executed when previewing this page.
This code will be executed when previewing this page.
Documentation for this user script can be added at User:Ainali/blur.
// Blur eligible images and add overlay
function blurAllImages() {
document.querySelectorAll('img').forEach(img => {
// Skip if already processed
if (img.dataset.blurProcessed) return;
const src = img.src.toLowerCase();
// Skip SVG originals, even if rendered as PNG/JPG
if (src.includes('.svg')) return;
// Skip any images served from /static/ (developer-vetted assets)
if (src.includes('/static/')) return;
// Skip small images (less than 50px in width or height)
const w = img.naturalWidth || img.width;
const h = img.naturalHeight || img.height;
if (w < 50 || h < 50) return;
// Mark as processed
img.dataset.blurProcessed = 'true';
// Wrap image in a container to hold the overlay
const wrapper = document.createElement('div');
wrapper.className = 'blurred-image-wrapper';
img.parentNode.insertBefore(wrapper, img);
wrapper.appendChild(img);
// Add overlay
const overlay = document.createElement('div');
overlay.className = 'blurred-image-overlay';
overlay.innerHTML = '<p>Media hidden</p><p>Click to show</p>';
wrapper.appendChild(overlay);
img.classList.add('blurred-image');
});
}
// Add CSS style for blurred images
mw.util.addCSS(`
.blurred-image-wrapper {
position: relative;
display: inline-block;
}
.blurred-image {
filter: blur(20px);
transition: filter 0.1s ease;
}
.blurred-image-wrapper .blurred-image-overlay {
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
display: grid;
border-radius: 8px;
justify-content: center;
align-items: center;
background: rgba(0,0,0,0.6);
color: white;
font-size: 0.8em;
text-align: center;
}
.blurred-image-wrapper .blurred-image.unblurred {
filter: none;
}
.blurred-image-wrapper .hide-button {
position: absolute;
top: 4px;
right: 4px;
background: rgba(0,0,0,0.7);
color: white;
font-size: 0.75em;
padding: 8px;
border-radius: 2px;
cursor: pointer;
z-index: 1;
}
`);
// Handle click on overlay
document.addEventListener('click', function(event) {
const overlay = event.target.closest('.blurred-image-overlay');
const hideButton = event.target.closest('.hide-button');
if (overlay) {
const wrapper = overlay.parentNode;
const img = wrapper.querySelector('img.blurred-image');
if (img) {
img.classList.add('unblurred');
overlay.remove();
// Add the "Hide" button
const hide = document.createElement('div');
hide.className = 'hide-button';
hide.textContent = 'Hide';
wrapper.appendChild(hide);
event.preventDefault();
event.stopImmediatePropagation(); // Prevent MediaViewer
}
}
if (hideButton) {
const wrapper = hideButton.parentNode;
const img = wrapper.querySelector('img.blurred-image');
if (img) {
img.classList.remove('unblurred');
hideButton.remove();
// Re-add the overlay
const overlay = document.createElement('div');
overlay.className = 'blurred-image-overlay';
overlay.innerHTML = 'Media hidden<br>Click to show';
wrapper.appendChild(overlay);
event.preventDefault();
event.stopImmediatePropagation(); // Prevent MediaViewer
}
}
}, true); // note: capture phase
// Handle dynamically loaded content
const observer = new MutationObserver(blurAllImages);
observer.observe(document.body, { childList: true, subtree: true });
// Initial blur
blurAllImages();