Jump to content

User:Rusalkii/hideRelisted.js

From Wikipedia, the free encyclopedia
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.
// <nowiki>
// This should be incorporated in XFDC
(function() {
    let hidden = true; // Default to hidden

    // Check if on XfD page
    var venueHeadingLevel = '.mw-heading.mw-heading4';
    if (!(mw.config.get('wgPageName').match(/Wikipedia:Redirects_for_discussion/))) {
        return; // Exit if not on an RfD page
    }

    // A <div>, not a <button>, so its box model (padding/border/line-height) matches
    // XFDcloser's #XFDcloser-showhide div exactly — a native button's intrinsic
    // sizing differs across browsers even after resetting `appearance`.
    const button = document.createElement('div');
    button.textContent = 'Show Relisted';
    button.setAttribute('role', 'button');
    button.setAttribute('tabindex', '0');
    // Same box model as XFDcloser's showhide box, but a different (blue) background.
    // Text color is XFDcloser's actual rendered color, not `inherit`, so both stay
    // in sync regardless of skin/dark-mode instead of drifting independently.
    button.style.cssText = 'position:fixed;bottom:0;right:0;z-index:100;padding:5px;box-shadow:0 2px 4px rgb(0 0 0 / 50%);background-color:var(--background-color-progressive-subtle, #dce8fd);color:#202122;border:1px solid #aaa;border-radius:5px;font-size:85%;cursor:pointer;';

    // XFDcloser's showhide box loads asynchronously as a gadget, so its width isn't known up front
    function positionButton() {
        const closer = document.getElementById('XFDcloser-showhide');
        button.style.right = (closer ? closer.offsetWidth + 8 : 0) + 'px';
        return !!closer;
    }

    function addStyles() {
        const css = `
            .rfd-relisted {
            }
            .rfd-relisted.rfd-hidden {
                display: none;
            }
        `;

        $('<style>').text(css).appendTo('head');
    }

    function hideRelists() {
        const $ = jQuery;

        let relistedCount = 0;
        const headers = $(venueHeadingLevel);

        headers.each(function(index) {
            const header = $(this);
            const content = header.nextUntil(venueHeadingLevel);

            // Check if the relist symbol and text
            const contentClone = content.clone();
            const moveSymbol = contentClone.find('img[src*="Symbol_move_vote.svg"]');

            if (moveSymbol.length !== 0) {

	            // Add classes directly instead of wrapping
	            header.addClass('rfd-relisted');
	            content.addClass('rfd-relisted');

	            // Toggle visibility
	            if (hidden) {
	                header.addClass('rfd-hidden');
	                content.addClass('rfd-hidden');
	            } else {
	                header.removeClass('rfd-hidden');
	                content.removeClass('rfd-hidden');
	            }
                relistedCount++;
            }
        });
    }

    // XFDcloser hides a closed discussion by tagging both its body and its heading
    // `xfd-closed`, but it only recognizes the heading when the body is the heading's
    // immediate next sibling. On the main RfD page the days are transcluded, so Parsoid
    // inserts a stray <span about="#mwt..."> between the two and XFDcloser reads every
    // closed discussion as open: the heading is never tagged, and it stays behind once
    // the bodies are hidden. Log pages have no such span, hence main-page-only.
    function tagClosedHeadings() {
        $(venueHeadingLevel).each(function() {
            const header = $(this);
            const body = header.nextAll().not('span[about]').first();
            if (body.hasClass('xfd-closed')) {
                // Tagging (rather than just hiding) keeps XFDcloser's own show/hide
                // toggle working; toggle() syncs with whichever state it is in now.
                header.addClass('xfd-closed').toggle(body.is(':visible'));
            }
        });
    }

    $(document).ready(function() {
        addStyles();
        hideRelists();
        document.querySelector('#mw-content-text').prepend(button);
        // #XFDcloser-showhide appears in the same synchronous block that tags and hides
        // the discussions, so either path below runs after XFDcloser has had its turn.
        if (positionButton()) {
            tagClosedHeadings();
        } else {
            const observer = new MutationObserver(function() {
                if (positionButton()) {
                    observer.disconnect();
                    tagClosedHeadings();
                }
            });
            observer.observe(document.body, { childList: true });
        }
    });

    function toggle() {
        hidden = !hidden;
        hideRelists();
        button.textContent = hidden ? 'Show Relisted' : 'Hide Relisted';
    }
    button.onclick = toggle;
    button.onkeydown = (e) => {
        if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            toggle();
        }
    };

})();
//</nowiki>