MediaWiki:Common.js: Difference between revisions

From Another Chance Wiki
Jump to navigation Jump to search
No edit summary
Tag: Reverted
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 3: Line 3:
/* Allows images within galleries to be spoiled if "spoiler:" is put at the start of its caption*/
/* Allows images within galleries to be spoiled if "spoiler:" is put at the start of its caption*/
mw.hook('wikipage.content').add(function ($content) {
mw.hook('wikipage.content').add(function ($content) {
     $content.find('ul.gallery').each(function () {
     $content.find('ul.gallery li.gallerybox').each(function () {
        var $box = $(this);
        var $caption = $box.find('.gallerytext');
        var captionText = $caption.text().trim().toLowerCase();
 
        if (captionText.startsWith('spoiler:')) {
            $box.addClass('spoiler-image thumb');
            $caption.html($caption.html().replace('spoiler: ', ''));
        }
    });
 
    $content.find('ul.mw-gallery-slideshow').each(function () {
         var $gallery = $(this);
         var $gallery = $(this);
        var isWholeGallerySpoiler = $gallery.hasClass('spoiler-image');
        var hasAnySpoiler = isWholeGallerySpoiler;


         $gallery.find('li.gallerybox').each(function () {
         function updateLargeImage() {
            var $box = $(this);
            var $current = $gallery.find('.gallerybox.slideshow-current');
            var captionText = $box.find('.gallerytext').text().trim().toLowerCase();
            if (!$current.length) {
             var imgSrc = ($box.find('img').attr('src') || '') + ' ' +
                $current = $gallery.find('.gallerybox').first();
                        ($box.find('img').attr('alt') || '');
            }
 
             var $container = $gallery.find('.mw-gallery-slideshow-img-container');


             var isIndividualSpoiler = captionText.indexOf('spoiler:') === 0;
             if ($current.hasClass('spoiler-image') && !$current.hasClass('revealed')) {
                $container.addClass('spoiler-image');
            } else {
                $container.removeClass('spoiler-image revealed');
            }
        }


            if (isWholeGallerySpoiler || isIndividualSpoiler) {
        updateLargeImage();
                $box.addClass('spoiler-image');
                hasAnySpoiler = true;


                if (isIndividualSpoiler) {
        var observer = new MutationObserver(function () {
                    $box.find('.gallerytext').html(function (i, html) {
            updateLargeImage();
                        return html.replace('spoiler: ', '');
                    });
                }
            }
         });
         });


         if (hasAnySpoiler) {
         observer.observe($gallery[0], {
             var $btn = $('<button type="button">')
             attributes: true,
                .text('Reveal all spoilers');
            attributeFilter: ['class'],
            subtree: true,
            childList: true
        });
    });


            $btn.on('click', function () {
    $content.on('click', '.gallerybox.spoiler', function () {
                $gallery.addClass('spoiler-image revealed');
        $(this).addClass('spoiler-image revealed');
                $gallery.find('.gallerybox.spoiler-image').addClass('revealed');
                $gallery.find('.mw-gallery-slideshow-img-container img')
                        .css('filter', 'none')
                        .removeClass('spoiler-image');
                $btn.remove();
            });
 
            $gallery.before($btn);
        }
     });
     });


     function applySpoilerToLargeImage($gallery) {
     $content.on('click', '.mw-gallery-slideshow-img-container.spoiler-image', function (e) {
         if ($gallery.hasClass('spoiler-image revealed')) {
         if ($(e.target).closest('.oo-ui-buttonElement, button, a.oo-ui-buttonElement-button').length) {
             return;
             return;
         }
         }


         var $current = $gallery.find('.gallerybox.slideshow-current');
         var $container = $(this);
         if (!$current.length) {
 
             $current = $gallery.find('.gallerybox').first();
         if (!$container.hasClass('revealed')) {
            e.preventDefault();
            e.stopPropagation();
 
             $container.addClass('revealed');
 
            $container.closest('ul.gallery')
                      .find('.gallerybox.slideshow-current')
                      .addClass('revealed');
         }
         }
    });
});


        var $container = $gallery.find('.mw-gallery-slideshow-img-container');
/* Displays random page on the home page */
        var $largeImg = $container.find('img');
$(function () {
    if (!mw.config.get('wgIsMainPage')) {
        return;
    }


        if ($current.hasClass('spoiler-image') && !$current.hasClass('revealed')) {
    var $container = $('#random-page-summary');
            $largeImg.addClass('spoiler-image')'
    if (!$container.length) {
        } else {
         return;
            $largeImg.removeClass('spoiler-imgage');
            $container.removeClass('spoiler-image');
         }
     }
     }


     $content.find('ul.mw-gallery-slideshow').each(function () {
    // === CONFIGURATION ===
        var $gallery = $(this);
    var EXCLUDED_TITLES = [
        'Main Page',
        'Sandbox',
        'Flora/Gallery',
        'Flora/Love',
        'Flora/Lust',
        'Isabelle/Gallery',
        'Isabelle/Love',
        'Isabelle/Lust',
        'Jacklyn/Gallery',
        'Jacklyn/Love',
        'Jacklyn/Lust'
    ];
 
    var NAMESPACE = 0;              // Main namespace
    var MAX_CANDIDATES = 6;        // Fetch a few random pages at once
    var SHOW_EXTRACT = true;        // Also show a short text summary under the infobox?
    var EXTRACT_CHARS = 300;
    // =====================
 
     $container.html('<p class="random-loading">Loading random page…</p>');
 
    function loadRandomWithInfobox() {
        // 1. Get several random page titles
        new mw.Api().get({
            action: 'query',
            generator: 'random',
            grnnamespace: NAMESPACE,
            grnfilterredir: 'nonredirects',
            grnlimit: MAX_CANDIDATES,
            prop: 'info',
            inprop: 'url'
        }).done(function (data) {
            if (!data.query || !data.query.pages) {
                $container.html('<p>No pages found.</p>');
                return;
            }
 
            var pages = Object.values(data.query.pages).filter(function (p) {
                return EXCLUDED_TITLES.indexOf(p.title) === -1;
            });


        applySpoilerToLargeImage($gallery);
            if (pages.length === 0) {
        setTimeout(function () { applySpoilerToLargeImage($gallery); }, 150);
                // All were excluded – try again
        setTimeout(function () { applySpoilerToLargeImage($gallery); }, 500);
                loadRandomWithInfobox();
                return;
            }


         var observer = new MutationObserver(function () {
            // Try the first valid page
             applySpoilerToLargeImage($gallery);
            tryPage(pages, 0);
         }).fail(function () {
             $container.html('<p>Could not load random pages.</p>');
         });
         });
        observer.observe($gallery[0], {
     }
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['class', 'src']
        });
    });
 
    $content.on('click', '.gallerybox.spoiler-image', function () {
        $(this).addClass('revealed');
        var $gallery = $(this).closest('ul.gallery');
        applySpoilerToLargeImage($gallery);
     });


     $content.on('click', '.mw-gallery-slideshow-img-container.spoiler-image, .mw-gallery-slideshow-img-container', function (e) {
     function tryPage(pages, index) {
         if ($(e.target).closest('.oo-ui-buttonElement, button').length) {
         if (index >= pages.length) {
            // None of the candidates worked – try a fresh batch
            loadRandomWithInfobox();
             return;
             return;
         }
         }


         var $container = $(this).closest('.mw-gallery-slideshow-img-container');
         var page = pages[index];
        var $gallery = $container.closest('ul.gallery');
 
        var $img = $container.find('img');
        // 2. Get the fully rendered HTML of the page
        new mw.Api().get({
            action: 'parse',
            page: page.title,
            prop: 'text',
            disablelimitreport: true,
            disableeditsection: true,
            disabletoc: true
        }).done(function (parseData) {
            var $html = $('<div>').html(parseData.parse.text['*']);
            var $infobox = $html.find('.portable-infobox').first();
 
            if ($infobox.length === 0) {
                // This page has no Portable Infobox – try the next candidate
                tryPage(pages, index + 1);
                return;
            }
 
            // 3. Build the display
            var $wrapper = $('<div class="random-infobox-wrapper"></div>');
 
            // Make the whole infobox clickable
            var $link = $('<a>')
                .attr('href', page.fullurl || mw.util.getUrl(page.title))
                .attr('title', 'Go to ' + page.title)
                .addClass('random-infobox-link');
 
            // Clone the infobox so we don't modify the original parse
            var $cloned = $infobox.clone();
 
            // Optional: make internal links inside the infobox absolute or remove them
            // (uncomment if you want to prevent nested navigation)
            // $cloned.find('a').attr('href', page.fullurl);


        if ($container.hasClass('spoiler-image')) {
            $link.append($cloned);
            e.preventDefault();
             $wrapper.append($link);
             e.stopPropagation();


             $img.removeClass('spoiler-image').css('filter', 'none');
             // Optional short extract under the infobox
            $container.removeClass('spoiler-image');
            if (SHOW_EXTRACT) {
                // Get a clean extract (requires TextExtracts extension)
                new mw.Api().get({
                    action: 'query',
                    titles: page.title,
                    prop: 'extracts',
                    exintro: true,
                    explaintext: true,
                    exchars: EXTRACT_CHARS
                }).done(function (exData) {
                    var extract = '';
                    var pagesObj = exData.query.pages;
                    for (var id in pagesObj) {
                        if (pagesObj[id].extract) {
                            extract = pagesObj[id].extract;
                        }
                    }


            $gallery.find('.gallerybox.slideshow-current').addClass('revealed');
                    if (extract) {
                        $wrapper.append(
                            $('<div class="random-extract"></div>').text(extract)
                        );
                    }


            if ($gallery.hasClass('spoiler-image')) {
                    finish($wrapper, page);
                $gallery.addClass('spoiler-image revealed');
                }).fail(function () {
                 $gallery.find('.gallerybox.spoiler-image').addClass('revealed');
                    finish($wrapper, page);
                 });
            } else {
                finish($wrapper, page);
             }
             }
         }
         }).fail(function () {
     });
            tryPage(pages, index + 1);
        });
     }
 
    function finish($content, page) {
        $content.append(
            $('<p class="random-more"></p>').html(
                '<a href="' + (page.fullurl || mw.util.getUrl(page.title)) + '">Read full page →</a> · ' +
                '<a href="#" class="random-reload">Show another</a>'
            )
        );
 
        $container.empty().append($content);
 
        $container.find('.random-reload').on('click', function (e) {
            e.preventDefault();
            $container.html('<p class="random-loading">Loading random page…</p>');
            loadRandomWithInfobox();
        });
    }
 
    loadRandomWithInfobox();
});
});

Latest revision as of 19:45, 1 September 2026

/* Any JavaScript here will be loaded for all users on every page load. */

/* Allows images within galleries to be spoiled if "spoiler:" is put at the start of its caption*/
mw.hook('wikipage.content').add(function ($content) {
    $content.find('ul.gallery li.gallerybox').each(function () {
        var $box = $(this);
        var $caption = $box.find('.gallerytext');
        var captionText = $caption.text().trim().toLowerCase();

        if (captionText.startsWith('spoiler:')) {
            $box.addClass('spoiler-image thumb');
            $caption.html($caption.html().replace('spoiler: ', ''));
        }
    });

    $content.find('ul.mw-gallery-slideshow').each(function () {
        var $gallery = $(this);

        function updateLargeImage() {
            var $current = $gallery.find('.gallerybox.slideshow-current');
            if (!$current.length) {
                $current = $gallery.find('.gallerybox').first();
            }

            var $container = $gallery.find('.mw-gallery-slideshow-img-container');

            if ($current.hasClass('spoiler-image') && !$current.hasClass('revealed')) {
                $container.addClass('spoiler-image');
            } else {
                $container.removeClass('spoiler-image revealed');
            }
        }

        updateLargeImage();

        var observer = new MutationObserver(function () {
            updateLargeImage();
        });

        observer.observe($gallery[0], {
            attributes: true,
            attributeFilter: ['class'],
            subtree: true,
            childList: true
        });
    });

    $content.on('click', '.gallerybox.spoiler', function () {
        $(this).addClass('spoiler-image revealed');
    });

    $content.on('click', '.mw-gallery-slideshow-img-container.spoiler-image', function (e) {
        if ($(e.target).closest('.oo-ui-buttonElement, button, a.oo-ui-buttonElement-button').length) {
            return;
        }

        var $container = $(this);

        if (!$container.hasClass('revealed')) {
            e.preventDefault();
            e.stopPropagation();

            $container.addClass('revealed');

            $container.closest('ul.gallery')
                      .find('.gallerybox.slideshow-current')
                      .addClass('revealed');
        }
    });
});

/* Displays random page on the home page */
$(function () {
    if (!mw.config.get('wgIsMainPage')) {
        return;
    }

    var $container = $('#random-page-summary');
    if (!$container.length) {
        return;
    }

    // === CONFIGURATION ===
    var EXCLUDED_TITLES = [
        'Main Page',
        'Sandbox',
        'Flora/Gallery',
        'Flora/Love',
        'Flora/Lust',
        'Isabelle/Gallery',
        'Isabelle/Love',
        'Isabelle/Lust',
        'Jacklyn/Gallery',
        'Jacklyn/Love',
        'Jacklyn/Lust'
    ];

    var NAMESPACE = 0;              // Main namespace
    var MAX_CANDIDATES = 6;         // Fetch a few random pages at once
    var SHOW_EXTRACT = true;        // Also show a short text summary under the infobox?
    var EXTRACT_CHARS = 300;
    // =====================

    $container.html('<p class="random-loading">Loading random page…</p>');

    function loadRandomWithInfobox() {
        // 1. Get several random page titles
        new mw.Api().get({
            action: 'query',
            generator: 'random',
            grnnamespace: NAMESPACE,
            grnfilterredir: 'nonredirects',
            grnlimit: MAX_CANDIDATES,
            prop: 'info',
            inprop: 'url'
        }).done(function (data) {
            if (!data.query || !data.query.pages) {
                $container.html('<p>No pages found.</p>');
                return;
            }

            var pages = Object.values(data.query.pages).filter(function (p) {
                return EXCLUDED_TITLES.indexOf(p.title) === -1;
            });

            if (pages.length === 0) {
                // All were excluded – try again
                loadRandomWithInfobox();
                return;
            }

            // Try the first valid page
            tryPage(pages, 0);
        }).fail(function () {
            $container.html('<p>Could not load random pages.</p>');
        });
    }

    function tryPage(pages, index) {
        if (index >= pages.length) {
            // None of the candidates worked – try a fresh batch
            loadRandomWithInfobox();
            return;
        }

        var page = pages[index];

        // 2. Get the fully rendered HTML of the page
        new mw.Api().get({
            action: 'parse',
            page: page.title,
            prop: 'text',
            disablelimitreport: true,
            disableeditsection: true,
            disabletoc: true
        }).done(function (parseData) {
            var $html = $('<div>').html(parseData.parse.text['*']);
            var $infobox = $html.find('.portable-infobox').first();

            if ($infobox.length === 0) {
                // This page has no Portable Infobox – try the next candidate
                tryPage(pages, index + 1);
                return;
            }

            // 3. Build the display
            var $wrapper = $('<div class="random-infobox-wrapper"></div>');

            // Make the whole infobox clickable
            var $link = $('<a>')
                .attr('href', page.fullurl || mw.util.getUrl(page.title))
                .attr('title', 'Go to ' + page.title)
                .addClass('random-infobox-link');

            // Clone the infobox so we don't modify the original parse
            var $cloned = $infobox.clone();

            // Optional: make internal links inside the infobox absolute or remove them
            // (uncomment if you want to prevent nested navigation)
            // $cloned.find('a').attr('href', page.fullurl);

            $link.append($cloned);
            $wrapper.append($link);

            // Optional short extract under the infobox
            if (SHOW_EXTRACT) {
                // Get a clean extract (requires TextExtracts extension)
                new mw.Api().get({
                    action: 'query',
                    titles: page.title,
                    prop: 'extracts',
                    exintro: true,
                    explaintext: true,
                    exchars: EXTRACT_CHARS
                }).done(function (exData) {
                    var extract = '';
                    var pagesObj = exData.query.pages;
                    for (var id in pagesObj) {
                        if (pagesObj[id].extract) {
                            extract = pagesObj[id].extract;
                        }
                    }

                    if (extract) {
                        $wrapper.append(
                            $('<div class="random-extract"></div>').text(extract)
                        );
                    }

                    finish($wrapper, page);
                }).fail(function () {
                    finish($wrapper, page);
                });
            } else {
                finish($wrapper, page);
            }
        }).fail(function () {
            tryPage(pages, index + 1);
        });
    }

    function finish($content, page) {
        $content.append(
            $('<p class="random-more"></p>').html(
                '<a href="' + (page.fullurl || mw.util.getUrl(page.title)) + '">Read full page →</a> · ' +
                '<a href="#" class="random-reload">Show another</a>'
            )
        );

        $container.empty().append($content);

        $container.find('.random-reload').on('click', function (e) {
            e.preventDefault();
            $container.html('<p class="random-loading">Loading random page…</p>');
            loadRandomWithInfobox();
        });
    }

    loadRandomWithInfobox();
});