Jump to content

User:Ainali/blur.js

From Wikipedia, the free encyclopedia
This is the current revision of this page, as edited by Ainali (talk | contribs) at 08:31, 16 July 2025. The present address (URL) is a permanent link to this version.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// 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 = '<strong>Media hidden</strong><br><span>Click to show</span>';
        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 = '<strong>Media hidden</strong><br><span>Click to show</span>';
            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();