Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;

Firefox (sur GNU/Linux) / Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.
/**
 * Vérification des renvois vers des entrées bibliographiques dans les refs.
 * auteur : https://fr.wiki.x.io/wiki/Utilisateur:Lgd
 * licence : MIT
 *
 * Aide et paramétrage : https://fr.wiki.x.io/wiki/Projet:JavaScript/Notices/refErrors
 */

if (mw.config.get('wgNamespaceNumber') >= 0) {

    mw.loader.using('mediawiki.util', function () {
        $(function ($) {

            function jsMessageSingleton(message, messageId) {
                var $messageDiv = $('#' + messageId);

                if (!$messageDiv.length) {
                    $messageDiv = $('<div>')
                        .attr('id', messageId)
                        .css({'margin': '1em 5%', 'padding': '0.5em 2.5%'});
                    $('#content').prepend($messageDiv);
                }

                if (typeof message === 'string') { // HTML string
                    $messageDiv.html(message);
                } else if (typeof message === 'object') { // DOM element or jQuery object
                    $messageDiv.empty().append(message);
                }
            }

            var refErrorLink = mw.util.addPortletLink('p-cactions', '#', 'Vérifier renvois biblio.', 'ca-check-ref');

            $(refErrorLink).click(function () {
				// il faut aussi ".mw-parser-output" car "#mw-content-text" n'est pas suffisant,
				// car dans les prévisualisations il faut éviter l'éditeur de wikicode 2010 (l'élément ".wikiEditor-ui")
				// car il inclut une section "Aide", qui contient plusieurs "sup.reference a" et il faut les éviter
				var $content = $('#mw-content-text').find('.mw-parser-output');

                var refErrorsList = '<ul>';
                var refErrorsWiki = '<div style="font-size: 0.95em;">';
                var refTab = [];
                var refYes = [];
                var refErrorsLength = 0;

                //Ferme les tooltips de Gadget-tooltipRef.js
                function closeNote() {
                    var fixOverflow = '.gallerytext, .thumbinner, h2, h3, h4, h5, h6, .overflow';
                    var tooltipRef = $('li.tooltipRef');
                    tooltipRef.prev('a.hasnote').removeClass('hasnote');
                    tooltipRef.parents(fixOverflow).first().css('overflow', 'hidden');
                    tooltipRef.remove();
                }

                // replaces special characters in id name
                function fixId(myid) {
                    // pour ne pas retourner un sélecteur invalide si jamais le href est manquant, vaut "#"...
                    if (!myid || !/^#./.test(myid)) {
                        return '';
                    }
                    return '#' + $.escapeSelector(myid.substr(1));
                }

                function refplural(nbr) {
                    if (nbr >= 2) {
                        return 's';
                    } else {
                        return '';
                    }
                }

                function noRefs() {
                    var noRef = 0;
                    var $refs = $content.find('.reference a');
                    $refs.each(function () {
                        var idfix = fixId($(this).attr('href'));
                        if (!$(idfix).length) {
                            noRef++;
                        }
                    });
                    if (noRef !== 0) {
                        refErrorsWiki += '<p><strong>Attention</strong> : ' + noRef + ' référence' + refplural(noRef)+ ' non affichée' + refplural(noRef)+ '. Vérifiez que les balises &lt;references /&gt; nécessaires sont bien présentes en fin de page et qu\'il ne manque aucune référence nommée (voir les erreurs signalées en fin de page).</p>';
                    }
                }

                function findId() {
                    // A reprendre
                    var bibList = $content.find('span.ouvrage').not('.references span.ouvrage');
                    var bibMsg = '<p>Les entrées bibliographiques suivantes ont été trouvées&nbsp;:<ul id="refBibList">';
                    if (bibList.length === 0) {
                        bibMsg = '<p>Aucune section bibliographique n\'a été trouvée.</p>';
                    } else {
                        bibList.each(function () {
                            var bibId = $(this).attr('id');
                            if (bibId) {
                                refYes.push(bibId);
                            }
                        });
                    }
                    refYes.sort();
                    for (var i = 0; i < refYes.length; i++) {
                        var prev = (i > 0) ? refYes[i-1] : null;
                        var next = (i < refYes.length - 1) ? refYes[i+1] : null;
                        if (refYes[i] === prev || refYes[i] === next) {
                            bibMsg += '<li><code><strong class="refDuplicate">' + mw.html.escape(refYes[i]) + '</strong></code>, <span class="refDuplicate">Identifiant dupliqué</span> (<a href="#'+ mw.html.escape(refYes[i]) +'" title="Aller à cette entrée bibliographique">Aller</a>)</li>';
                        } else {
                            bibMsg += '<li><code>' + mw.html.escape(refYes[i]) + '</code> (<a href="#'+ mw.html.escape(refYes[i]) +'" title="Aller à cette entrée bibliographique">Aller</a>)</li>';
                        }
                    }
                    if (bibList.length !== 0) {
                        bibMsg += '</ul>';
                    }
                    return bibMsg;
                }

                function checkNote($ref) {
                    var id = $ref.attr('href');
                    var idfix = fixId(id);
                    if ($(idfix).length !== 0) {
                        $(idfix).find('[href^="#"]').each(function () {
                            var id2 = $(this).attr('href');
                            var idfix2 = fixId(id2);
                            if ($(idfix2).length === 0) {
                                var text = $ref.text();
                                if (refTab.indexOf(text) === -1) {
                                    var id3 = $ref.parent().attr('id');
                                    refErrorsList += '<li>Entrée <code>' + mw.html.escape(id2) + '</code> appelée par la référence <a href="#' + mw.html.escape(id3) + '">' + mw.html.escape(text) + '</a> (<a href="#" class="refFind" title="Chercher dans les références présentes dans l\'article">chercher</a>)</li>';
                                    $ref.parent().after('<span class="refBroken error"> Erreur&nbsp;: renvoi bibliographique à corriger (' + mw.html.escape(id2) + ') </span>');
                                    refTab.push(text);
                                    refErrorsLength++;
                                }
                            }
                        });
                    }
                    //else {
                        //refErrorsList += '<li>' + id + '</li>';
                    //}
                }

                closeNote();
                noRefs();
                $content.find('sup.reference > a').each(function () {
                    checkNote($(this));
                });

                if (refErrorsLength === 0) {
                    refErrorsWiki += 'Aucune erreur dans les renvois bibliographiques.';
                }
                else {
                    refErrorsList += '</ul>';
                    refErrorsWiki += 'L\'article comporte ' + refErrorsLength + ' lien' + refplural(refErrorsLength) + ' de renvoi bibliographique erroné' + refplural(refErrorsLength) + '&nbsp;:';
                    refErrorsWiki += refErrorsList + findId();
                }
                refErrorsWiki += '</div>';

                jsMessageSingleton(refErrorsWiki, 'gadget-refErrors');

                $('a.refFind').click(function () {
                    $('#refBibList').find('li').css('background', 'none');
                    var text = $(this).closest('li').find('code').first().text().substr(1, 5);
                    var ok = false;
                    $('#refBibList').find('li code').each(function () {
                        if ($(this).text().substr(0, 5) === text) {
                            $(this).closest('li').css('background', 'yellow').attr('tabindex', 0).focus();
                            ok = true;
                        }
                    });
                    if (!ok) {
                        $(this).after('référence non trouvée');
                        $(this).remove();
                    }
                    return false;
                });
                var $closeLink = $('<a href="#" style="float:right; margin:5px 0 10px 10px; font-size:0.95em;">Fermer</a>').click(function () {
                    $('.refBroken').remove();
                    $(this).parent().remove();
                    $('#ca-check-ref').find('a').removeAttr('style');
                });
                var $helpLink = $('<a href="//fr.wiki.x.io/wiki/Projet:JavaScript/Notices/refErrors" target="_blank" style="float:right; margin:5px 0 10px 20px; font-size:0.95em;">Aide</a>');
                $('#gadget-refErrors').prepend($closeLink, $helpLink);
                $('#ca-check-ref').find('a').css('color', '#aaa');
            });

        });
    });
}