Utente:Codicorumus/Fix colore collapseButton.js

Questa pagina definisce alcuni parametri di aspetto e comportamento generale di tutte le pagine. Per personalizzarli vedi Aiuto:Stile utente.


Nota: dopo aver salvato è necessario pulire la cache del proprio browser per vedere i cambiamenti (per le pagine globali è comunque necessario attendere qualche minuto). Per Mozilla / Firefox / Safari: fare clic su Ricarica tenendo premuto il tasto delle maiuscole, oppure premere Ctrl-F5 o Ctrl-R (Command-R su Mac); per Chrome: premere Ctrl-Shift-R (Command-Shift-R su un Mac); per Konqueror: premere il pulsante Ricarica o il tasto F5; per Opera può essere necessario svuotare completamente la cache dal menù Strumenti → Preferenze; per Internet Explorer: mantenere premuto il tasto Ctrl mentre si preme il pulsante Aggiorna o premere Ctrl-F5.

/**
 *   Fix del colore dei link [mostra/nascondi] e V-D-M
 *  - - - - - - - - - - - - - - - - - - - - - - - - - -
 *                 nei box richiudibili
 *            gestiti da Mediawiki:Common.js
 *
 *  Documentazione sullo script e le sue opzioni
 *  è disponibile alla pagina
 *  //it.wikipedia.org/wiki/Utente:Codicorumus/Fix_colore_collapseButton
 *
 *  Usa il plugin jQuery descritto in
 *     //it.wikipedia.org/wiki/Utente:Codicorumus/$.fn.fittingColor
 *
 *  Identifica le combinazioni incompatibili
 *  seguendo le raccomandazioni in
 *  http://www.w3.org/TR/AERT#color-contrast
 *
 *
 *  Crea l'oggetto
 *      window.CollapsibleBoxes
 *  che contiene funzioni e dati pubblici dello script
 *
 *  Introduce la classe:
 *      header-color-for-links
 *  che, unita a .collapsible o .NavFrame,
 *  fa sì che per i link venga usata la stessa
 *  proprietà color dell'elemento di testata
 *  invece di una calcolata in base allo sfondo
 *
 *  Altre classi sono a solo uso interno
 *  vedi nell'oggetto z in init()
 *
 *  Introduce il parametro url:
 *      no-collapsibles-fix
 *  che impedisce allo script la modifica della pagina
 *
 *  -------------------------------------
 *   visualizzazione ottimale del codice
 *   con folding delle funzioni con nome
 *  -------------------------------------
 *
 **/

/*global $, mw, console, importScript */

importScript( 'Utente:Codicorumus/$.fn.fittingColor.js' );

( function z_mainWrapper() {

    if ( window.CollapsibleBoxes && window.CollapsibleBoxes.debug ) {
        // identifica e conteggia i lanci in eccesso
        // e nel caso termina immediatamente
        window.CollapsibleBoxes.debug.reRun += 1;
        return;
    }

    var
    // oggetto contenitore generale dello script
    // può già esistere e contenere le opzioni dell'utente e/o di progetto
    t = window.CollapsibleBoxes || {},
    // contenitore di funzioni e proprietà private di servizio
    z = {};
    // per entrambi, vedi in init()

    window.CollapsibleBoxes = t;

    // codice principale
    // oltre a quelle specifiche dello script,
    // accetta anche l'opzione 'mode' di $.fn.fittingColor( 'set' )
    function fixButtonsColor( options ) {

        // aggiunge le eventuali opzioni presenti nella chiamata di funzione
        var workingOptions = $.extend( true, {}, t.options.working, options );

        // memorizza le opzioni usate in questa esecuzione della funzione
        t.options.lastRun = workingOptions;

        // processa i NavFrames
        t.navFrames.each( function z_eachNavFrame() {

            var
            navFrame = $( this ),
            navToggle = navFrame.find( '.NavToggle' ).eq(0),
            navHead = navFrame.find( '.NavHead' ).eq(0),
            //
            fittingColorOptions = {
                mode : workingOptions.mode,
                level : workingOptions.collapseButtonLevel,
                background : workingOptions.background || navHead
            },
            //
            fixColor =
            fittingColorOptions.level === 1
            || navToggle.fittingColor( 'isBadNow', fittingColorOptions );

            if ( fixColor ) {
                if (
                    navFrame.hasClass( 'header-color-for-links' )
                    || workingOptions.forceHeaderColor.navFrames
                    ) {
                    // colore per i link come in navHead
                    navToggle.css( 'color', navHead.css( 'color' ) );
                } else {
                    // colore per i link adattato allo sfondo
                    navToggle.fittingColor( 'set', fittingColorOptions );
                }
            }

            // aggiunge comandi per il controllo contemporaneo di tutti i collapsible
            // oppure ne aggiorna il colore o li elimina, se necessario
            z.updatePilotAllContainer( workingOptions.pilotAll, navFrame, navToggle, navToggle, 'div' );

        });

        // processa le CollapsibleTables
        t.collapsibleTables.each( function z_eachCollapsibleTable() {

            var
            table = $( this ),
            collapseButton = table.find( 'a[id^="collapseButton"]' ).eq(0),
            collapseButtonParent = collapseButton.parent(),
            header = collapseButtonParent.parent(),
            templateLinksSpans = header.find( 'div.noprint.plainlinks:eq(0) a span' ),
            templateLinksDiv = templateLinksSpans.eq(0).parent().parent(),
            groupToColor =
            collapseButton
            .add( collapseButtonParent )
            .add( templateLinksDiv ),
            //
            fittingColorButtonsOptions = {
                mode : workingOptions.mode,
                level : workingOptions.collapseButtonLevel,
                background : workingOptions.background
            },
            fittingColorVdmOptions = {
                mode : workingOptions.mode,
                level : workingOptions.vdmLevel,
                background : workingOptions.background
            },
            //
            fixingCollapseButton =
            fittingColorButtonsOptions.level === 1
            || collapseButton.fittingColor( 'isBadNow', fittingColorButtonsOptions ),
            //
            fixingVDM =
            fittingColorVdmOptions.level === 1
            || templateLinksSpans.fittingColor( 'oneIsBadNow', fittingColorVdmOptions );

            // verifica templateLinksSpans
            // necessaria per la mancanza di una classe identificativa
            if (
                table.hasClass( 'navbox' ) === false
                || templateLinksDiv.text().toUpperCase() !== 'V\xA0\xB7\xA0D\xA0\xB7\xA0M'
                ) {
                templateLinksDiv = templateLinksSpans = $();
            }

            if (
                table.hasClass( 'header-color-for-links' )
                || workingOptions.forceHeaderColor.collapsibleTables
                ) {
                // colore per i link come in header
                if ( fixingCollapseButton ) {
                    groupToColor.css( 'color', header.css( 'color' ) );
                }
                if ( fixingVDM ) {
                    templateLinksSpans.css( 'color', header.css( 'color' ) );
                }
            } else {
                // colore per i link adattato allo sfondo
                if ( fixingCollapseButton ) {
                    groupToColor.fittingColor( 'set', fittingColorButtonsOptions );
                }
                if ( fixingVDM ) {
                    templateLinksSpans.fittingColor( 'set', fittingColorVdmOptions );
                }
            }

            // lowercase per i link VD a pagine non esistenti
            // oppure ripristino dell'uppercase
            templateLinksSpans
            .parent()
            .filter( '.new' )
            .find( 'span' )
            .each( function() {
                if ( workingOptions.vdM ) {
                    this.textContent = this.textContent
                    .replace( 'V', 'v' )
                    .replace( 'D', 'd' );
                } else {
                    this.textContent = this.textContent
                    .replace( 'v', 'V' )
                    .replace( 'd', 'D' );
                }
            } );

            // aggiunge comandi per il controllo contemporaneo di tutti i collapsible
            // oppure aggiorna i colori o elimina, quando necessario
            z.updatePilotAllContainer( workingOptions.pilotAll, table, collapseButtonParent, collapseButton, 'span' );

        });

        z.setStatus( 'buttons fixed' );

    }

    // permettere di aprire o chiudere tutti i collapsible contemporaneamente
    // o di invertire il loro stato
    // quando il parametro è un elemento, è la classe di questo a determinare l'azione
    // altrimenti accetta le stesse classi come stringa
    function pilotAllCollapsibles( actionOrElement ) {

        var action = null;

        // interpretazione parametro
        switch ( typeof actionOrElement ) {
            case 'object':
                // ricava il comando dalla classe dell'elemento
                action = actionOrElement.className;
                if ( typeof action !== 'string' ) {
                    return;
                } else {
                    // estrae la classe indicante l'azione
                    action = action.replace( new RegExp( '\\s*' + z.pilotAllClass + '\\s*' ), '' );
                }
                break;
            case 'string':
                action = actionOrElement;
                break;
            default:
                // parametro actionOrElement di tipo non ammesso
                return;
        }

        t.navFrames
        .add( t.collapsibleTables )
        .each( function z_eachPilot() {

            var
            id = this.id,
            idNumber = id.replace( /NavFrame|collapsibleTable/, '' ),
            isTableBox = id.indexOf( 'NavFrame' ) === -1,
            //
            toggleFunction =
            isTableBox
            ? window.collapseTable
            : window.toggleNavigationBar,
            //
            buttonText = $( this ).find( '.NavToggle, #collapseButton' + idNumber ).eq( 0 ).text(),
            //
            isOpen =
            isTableBox
            ? buttonText === window.collapseCaption
            : buttonText === window.NavigationBarHide;

            if (
                action === z.invertAllClass
                || ( action === z.openAllClass && !isOpen )
                || ( action === z.closeAllClass && isOpen )
                ) {
                // cambia lo stato di apertura del box
                toggleFunction( idNumber );
            }

        } );

    }

    if (
        false === ( function init() {

            var scriptPage = '//it.wikipedia.org/wiki/Utente:Codicorumus/Fix_colore_collapseButton.js';

            // funzioni e proprietà non pubbliche
            z = {
                logMessage : function ( text ) {

                    console.log( scriptPage + '\n: ' + text );

                },
                setStatus : function ( status ) {
                    // imposta l'indicatore di stato t.debug.status
                    // verificando che si tratti di uno degli stati previsti

                    var statuses = [
                    'init', 'no boxes', 'boxes found',
                    'waiting dependencies', 'dependencies checked',
                    'dependencies timeout', 'no-collapsibles-fix in url',
                    'buttons fixed'
                    ];

                    if ( statuses.indexOf( status ) !== -1 ) {
                        t.debug.status = status;
                    } else {
                        this.logMessage(
                            'Lo status <' + status + '> non esiste.\n'
                            + 'Lo stato corrente è <' + t.debug.status + '>' );
                    }

                },
                pilotAllClass : 'pilot-all-collapsibles',
                openAllClass : 'open',
                closeAllClass : 'close',
                invertAllClass : 'invert',
                updatePilotAllContainer : function( pilotAll, topContainer, after, modelLink, containerType ) {

                    if ( 2 > t.navFrames.length + t.collapsibleTables.length ) {
                        // 1 solo collapsible, i comandi aggiuntivi non servono
                        return;
                    }

                    var pilotAllContainer = after.next( '.' + this.pilotAllClass );

                    if ( pilotAllContainer.length === 1 ) {
                        // i pulsanti sono già presenti
                        // aggiorna i colori o elimina
                        if ( pilotAll ) {
                            // aggiorna i colori
                            pilotAllContainer
                            .find( 'a' )
                            .css( 'color', modelLink.css( 'color' ) );
                        } else {
                            // elimina
                            pilotAllContainer.remove();
                        }
                    } else if ( pilotAll ) {
                        // i pulsanti non sono presenti
                        // quindi li crea

                        $( '<' + containerType + '>'
                            + '<!-- ' + containerType + ' aggiunto da script, vedi window.CollapsibleBoxes -->'
                            + '<a class="' + this.openAllClass + '">&dArr;</a>&nbsp;'
                            + '<a class="' + this.closeAllClass + '">&uArr;</a>&nbsp;'
                            + '<a class="' + this.invertAllClass + '">&sim;</a>&nbsp;'
                            + '</' + containerType + '>' )
                        .addClass( this.pilotAllClass )
                        .css( 'font-size', modelLink.css( 'font-size' ) )
                        .css( 'float', 'right' )
                        .insertAfter( after )
                        .hide()
                        //
                        .find( 'a' )
                        .addClass( this.pilotAllClass )
                        .attr( 'href', '#' + topContainer.attr( 'id' ) )
                        .css( 'color', modelLink.css( 'color' ) )
                        .each( function () {
                            $( this ).click( function () {
                                t.pilotAllCollapsibles( this );
                            });
                        } );

                        if ( containerType === 'span' ) {
                            // elimina 'width:7em', che interferisce con i nuovi pulsanti
                            after.css( 'width', 'auto' );
                        }

                        // se manca, aggiunge lo stile per visualizzare i pulsanti on hover
                        if ( $( 'style#pilotAllStyle' ).length === 0 ) {
                            $( 'head' )
                            .append(
                                '<style id="pilotAllStyle">'
                                + 'a.NavToggle:hover + div.pilot-all-collapsibles,'
                                + 'span:hover + span.pilot-all-collapsibles,'
                                + 'div.pilot-all-collapsibles:hover,'
                                + 'span.pilot-all-collapsibles:hover'
                                + '{ display: block !important; }'
                                + '</style>'
                                );
                        }

                    }

                },
                removePilotAllContainers : function() {

                    $( t.navFrames )
                    .add( t.collapsibleTables)
                    .find( '.' + this.pilotAllClass ).remove();

                }
            };

            t.scriptPage = scriptPage;
            t.info = 'Oggetto creato dallo script ' + scriptPage + '. '
            + 'Script che esegue il fix del colore del testo dei pulsanti '
            + 'dei div.NavFrame e delle table.collapsible, '
            + 'in modo da adattarlo al colore dello sfondo.';

            t.debug = {
                // stato di avanzamento dell'esecuzione
                status : '',
                // numero corrente e massimo di tentativi
                // in attesa del caricamento di $.fn.fittingColor.js
                // e della costruzione dei pulsanti mostra/nascondi
                currentTry : 0,
                maxTries : 20,
                // lanci in eccesso
                reRun : 0
            };

            z.setStatus( 'init' );

            // i collapsible della pagina
            t.navFrames = $( 'div.NavFrame' );
            t.collapsibleTables = $( 'table.collapsible' );

            // rende pubbliche le funzioni per eventuali chiamate dirette
            t.fixButtonsColor = fixButtonsColor;
            t.pilotAllCollapsibles = pilotAllCollapsibles;

            // opzioni di default
            $.extend( true, t, {
                options: {
                    'default' : {
                        collapseButtonLevel : 1,
                        vdmLevel : 0.3,
                        mode : 'smooth',
                        forceHeaderColor : {
                            navFrames : false,
                            collapsibleTables : false
                        },
                        vdM : true,
                        pilotAll : true
                    },
                    working : {}
                }
            } );

            // composizione, in working, dei tre livelli di opzioni : default < project < user
            $.extend( true, t.options.working,
                t.options['default'],
                t.options.project,
                t.options.user
                );

            if ( 0 === t.navFrames.lenght + t.collapsibleTables.lenght ) {
                // finito, non ci sono collapsible
                z.setStatus( 'no boxes' );
                return false;
            } else {

                z.setStatus( 'boxes found' );

                if ( new RegExp( '[\\?&]no-collapsibles-fix$' ).test( window.location.href ) ) {
                    // interruzione richiesta tramite parametro url
                    z.setStatus( 'no-collapsibles-fix in url' );
                    return false;
                } else {
                    return true;
                }

            }

        }() )
        ) {
        // finito, non ci sono collapsible
        // oppure interruzione richiesta tramite parametro url
        return;
    }

    // attende la costruzione dei pulsanti mostra/nascondi
    // e il caricamento di $.fn.fittingColor.js
    ( function waitFor( condition, callback ) {

        function waitForCondition() {

            if ( ++t.debug.currentTry <= t.debug.maxTries ) {

                if ( condition() ) {
                    z.setStatus( 'dependencies checked' );
                    callback();
                // finito
                }
                else {
                    // attendere le dipendenze
                    setTimeout( waitForCondition, 200 );
                }

            } else {
                z.setStatus( 'dependencies timeout' );
            // finito
            }

        }

        z.setStatus( 'waiting dependencies' );
        waitForCondition();

    }(
        function waitingCondition() {

            return $.fn.fittingColor
            && t.navFrames.length === $( '.NavToggle' ).length
            && t.collapsibleTables.length === $( 'table[id^="collapsibleTable"]' ).length;

        },
        fixButtonsColor
        )
    );

}() );