MediaWiki:Gadget-DeferredDisplay.js

From JoJo's Bizarre Encyclopedia - JoJo Wiki
Revision as of 12:24, 26 July 2024 by Vish (talk | contribs)
Jump to navigation Jump to search

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * Deferred display of {{tl|nsfw}}-tagged images.
 * jshint validation
 * @author Dschwen, 2013 / Vish, 2023
 */

$(document).ready(function() {
    function applyNSFWOverlay() {
        $('.nsfwelement').each(function() {
            var nsfwElement = $(this);
            var container = nsfwElement.closest('.thumbinner, .gallerybox');

            if (container.length) {
                var img = container.find('img').not('.image-lazy-loaded'); // Find non-lazy-loaded images
                var lazyImg = container.find('img.image-lazy-loaded');

                // Set initial styles for container
                container.css({
                    backgroundImage: 'url("https://static.jojowiki.com/images/customizations/Dialog-warning-yellow.png")',
                    backgroundRepeat: 'no-repeat',
                    backgroundPosition: 'center'
                });

                img.css('visibility', 'hidden');

                // Click event to reveal image and remove background
                container.one('click', function(e) {
                    $(this).css('backgroundImage', '').find('img').css('visibility', '');
                    e.preventDefault();
                });

                // Handle lazy-loaded images
                lazyImg.on('load', function() {
                    if (nsfwElement.length) {
                        $(this).css('visibility', 'hidden');
                        container.css({
                            backgroundImage: 'url("https://static.jojowiki.com/images/customizations/Dialog-warning-yellow.png")',
                            backgroundRepeat: 'no-repeat',
                            backgroundPosition: 'center'
                        });
                    }
                });

                // If the image is already loaded and visible, hide it
                if (lazyImg.length && lazyImg.css('visibility') !== 'hidden') {
                    lazyImg.css('visibility', 'hidden');
                }
            }
        });
    }

    // Apply overlay initially
    applyNSFWOverlay();

    // Set up a MutationObserver to handle lazy-loaded images
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList') {
                $(mutation.addedNodes).find('.image-lazy-loaded').each(function() {
                    var container = $(this).closest('.thumbinner, .gallerybox');
                    if (container.find('.nsfwelement').length > 0) {
                        $(this).css('visibility', 'hidden');
                        container.css({
                            backgroundImage: 'url("https://static.jojowiki.com/images/customizations/Dialog-warning-yellow.png")',
                            backgroundRepeat: 'no-repeat',
                            backgroundPosition: 'center'
                        });
                    }
                });
            } else if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                var target = $(mutation.target);
                if (target.hasClass('image-lazy-loaded')) {
                    var container = target.closest('.thumbinner, .gallerybox');
                    if (container.find('.nsfwelement').length > 0) {
                        target.css('visibility', 'hidden');
                        container.css({
                            backgroundImage: 'url("https://static.jojowiki.com/images/customizations/Dialog-warning-yellow.png")',
                            backgroundRepeat: 'no-repeat',
                            backgroundPosition: 'center'
                        });
                    }
                }
            }
        });
    });

    // Observe changes in the entire document
    observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['class']
    });

    // Re-apply overlay on window load to handle any remaining lazy-loaded images
    $(window).on('load', function() {
        applyNSFWOverlay();
    });
});