MediaWiki:Gadget-Erori-comuni.js

Da Wikipedia, l'ençiclopedia libara.

Ocio: Daspò ver salvà, podaria esare neçesario snetare ła cache dal propio navegadore web par vedare i canbiamenti.

  • Firefox / Safari: tegner strucà el boton de łe letare grande Shift e schiciare sora Ricarga, o se nò struca Ctrl-F5 o Ctrl-R (⌘-R so Mac)
  • Google Chrome: strucare Ctrl-Shift-R (⌘-Shift-R so on Mac)
  • Internet Explorer / Edge: tegner strucà el boton Ctrl e schiciare so Ajorna, o sinò Ctrl-F5
  • Opera: Va in tel Menu → Inpostasion (Opera → Prefarense so on Mac) e pò in Privacy & sicuresa → Sneta dati del navegadore → Imajini e file in te ła cache.
/* Adatà da fr.wikisource.org/wiki/MediaWiki:Gadget-Erreurs-communes.js*/
/*
 * Permet de montrer dans un texte les erreurs les plus communes.
 *
 * Auteur: Phe
 *
 * TODO:
 *
 * Permettre des auto-corrections.
 *
 * Le support en mode édition est très expérimental, il manque un bouton refresh à
 * la liste des erreurs pour éviter d'avoir à faire un preview quand on a corrigé.
 * Certaines erreurs ne seront visible que dans le html, « . <minuscule> » par
 * exemple s'il y a y un \n dans le wikicode entre le . et la minuscule.
 * Le wikicode n'est pas strippé ce qui doit produire des tas de faux positifs.
 *
 * En mode édition cliquer sur un lien se positionne toujours sur la première
 * erreur.
 *
 * En mode édition il arrive fréquemment qu'une erreur détecté ne puisse
 * être localisé dans la boîte d'édition.
 *
 * Le contenu d'une textarea est un nœud texte qui est splitter en plusieurs
 * nœud html, le browser à l'air assez futé pour comprendre qu'un textarea ne
 * peut contenir qu'un nœud texte et ignore les trucs insérer mais ça ne
 * va pas du tout (incompatibilité avec le gadget auteur form par exemple -->
 * ns:104 ignoré pour l'instant).
 *
 */

/*
 * http://stackoverflow.com/questions/5458655/jquery-scroll-textarea-to-given-position 
 *
 * Construit un div avec la même font que la textarea pouvoir calculer la position de scroll.
 */
jQuery.fn.scrollToText = function(search) {
    var text = $(this).text();
    var charNo = text.indexOf(search);
    var anch = '<span id="anch"></span>';
    text = text.substring(0, charNo) + anch + text.substring(charNo);

    var copyDiv = $('<div></div>')
                    .append(text.replace(/\n/g, '<br />'))
                    .css('width', $(this).innerWidth()) // width without scrollbar
                    .css('font-size', $(this).css('font-size'))
                    .css('font-family', $(this).css('font-family'))
                    .css('padding', $(this).css('padding'));

    copyDiv.insertAfter($(this));
    var pos = copyDiv.find('SPAN#anch').offset().top - copyDiv.find('SPAN#anch').closest('DIV').offset().top;
    pos = pos - Math.round($(this).innerHeight() / 2);
    $(this).scrollTop(pos);
    copyDiv.remove();
};

select_multiple_text = {

    precompile_regexp : function (search) {
        var temp = [];
        for (var i in search)
            temp.push(new RegExp("(" + search[i] + ")", "g"));
        return temp;
    },

    build_popup : function() {
        var html = "";
        $('span.erori-comuni').each(function (index, el) {
            //$(this).removeAttr('id');
            html += "<li><a href='javascript:select_multiple_text.scroll_to_pos(" + index + ");'>" + $(this).text() + "</a></li>";
            $(this).attr('id', 'Err-' + index);
        });
        
        return html;
    },

    last_scroll_pos : 0,

    scroll_to_pos : function(index) {
        var found = false;
        if ($.inArray(mw.config.get('wgAction'), [ 'submit', 'edit' ]) != -1) {
            var textbox = document.getElementById("wpTextbox1");
            if (textbox) {
                 var text = $("#Err-" + index).text();
                 var pos = textbox.value.indexOf(text);
                 if (pos != -1) {
                    textbox.selectionStart = pos;
                    textbox.selectionEnd = pos + text.length;
                    textbox.focus();
                    $('#wpTextbox1').scrollToText(text);
                    found = true;
                }
            }
        }
        if (!found) {
            $("#Err-" + select_multiple_text.last_scroll_pos).css("background-color", "");
            window.location.hash = "#Err-" + index;
            $("#Err-" + index).css("background-color", "#00FF00");
            select_multiple_text.last_scroll_pos = index;
            // index * 2 + 1 is voodoo making assumption on the html struct of the
            // popup, see build_popup(), there is surely a simpler and safer way.
            $('#err-communes-popup').find('*:eq(' + (index * 2 + 1) + ')').focus();
        }
    },

    close_popup : function() {
        $("#err_summary").remove();
        return;
    },

    open_popup : function() {
        if ($("#err_summary").remove().length)
            return;

        var elt = $("<div id='err_summary'></div>");
        elt.css({ 
            "position" : "fixed",
            "min-width" : "16em",
            "max-width" : "35em",
            "max-height" : "35em",
            "right" : "0.5em",
            "background-color" : "#FFFFFF",
            "z-index" : 1,
            "border" : "1px solid",
            "padding" : "8px"
        });

        var str = '<div style="float:right;"><a href="javascript:select_multiple_text.close_popup();"><img src="//upload.wikimedia.org/wikipedia/commons/9/97/WikEd_close.png"/></a></div><h4>'+ 'Erreur(s) possible' + ' :</h4><div style="overflow:auto;min-width:16em;max-width:35em;max-height:32em;"><ul id="err-communes-popup">' + select_multiple_text.build_popup() + '</ul></div>'; 

        elt.html(str);

        $("#bodyContent").prepend(elt);
    },

    match : function (text, regexp) {
        var m = text.match(regexp);
        if (m) {
            var start_match = text.search(regexp);
            var end_match = start_match + m[0].length;
            return [ start_match, end_match, m[0] ];
        }
        return null;
    },

    change_text_node : function(el, search, first) {
        for (var cur = first; cur < search.length; ++cur) {
            var match = this.match(el.nodeValue, search[cur]);
            if (match) {
                var tail = $(el).clone()[0];

                el.nodeValue = el.nodeValue.substring(0, match[0]);
                tail.nodeValue = tail.nodeValue.substring(match[1]);

                // FIXME: how to setup the text part of the span w/o injecting it in html ?
                $(el).after(tail).after($("<span class='erori-comuni'>" + match[2] + "</span>"));

                select_multiple_text.change_text_node(el, search, cur + 1);
                select_multiple_text.change_text_node(tail, search, cur);
            }
        }
    },

    match_text : function (text, search) {
        // Il faut faire ressembler le wikicode à du html, il manque plein de
        // truc encore...
        text = text.replace(/'''/g, "");
        text = text.replace(/''/g, "");
        // Kludge
        text = text.replace(/\n\n/g, "#<foo>#");
        text = text.replace(/\n/g, " ");
        text = text.replace(/#<foo>#/g, "\n\n");

        // Indispensable pour éviter un timeout du script sur une grosse page contenant
        // beaucoup de wikicode.
        var new_text = '';
        var last_match = 0;
        var splitter = new RegExp("<math>.*</math>|<[a-zA-z0-9 =\"']>|[</[a-zA-z0-9 =\"']+>|style=\".*\"|&nbsp;|&mdash;|<!--.*-->|\n:[:]*|\n;[;]*|[[][[].*]]", "gm");
        while ((result = splitter.exec(text)) != null) {
            new_text += text.slice(last_match, splitter.lastIndex - result[0].length);
            for (var i = 0; i < result[0].length; ++i)
                new_text += ' ';
            last_match = splitter.lastIndex;
        }
        new_text += text.slice(last_match);

        text = new_text;

        // Les nœud invisible servent à stocker à stocker les erreurs trouvés de
        // façon à réutiliser le même code que lorsque wgAction == submit.
        var $node = $('#bodyContent');
        for (var i = 0; i < search.length; ++i) {
            var pos = 0;
            while ((match = this.match(text.slice(pos), search[i])) != null) {
                pos += match[1];
                $node.append($("<span class='erori-comuni' style='display:none;'>" + match[2] + "</span>"));
            }
        }
    },

    // Predicate to filter page we act on based upon a user filter and some other criteria.
    filter_page : function(user_filter) {
        if ($.inArray(mw.config.get("wgAction"), [ 'view', 'submit', 'edit' ]) == -1)
            return false;

        if (!user_filter.test(mw.config.get("wgPageName")))
            return false;

        if (/\.(css|js)$/.test(mw.config.get("wgPageName")))
            return false;

        if (/^Wikisource:/.test(mw.config.get("wgPageName")))
            return false;

        if ($("#wikiDiff").length)
            return false;

        /* FIXME: filtre les cats à cause de Page:pagename et Livre:livre.djvu
         * mais c'est trop drastique comme solution */
        if (mw.config.get("wgNamespaceNumber") == 14)
            return false;

        if (mw.config.get("wgNamespaceNumber") == 6)
            return false;

        if (mw.config.get("wgNamespaceNumber") == 112)
            return false;

        if (mw.config.get("wgNamespaceNumber") == 828)
            return false;

        if (mw.config.get("wgNamespaceNumber") == 2600) // Topic ou Sujet
            return false;

        if (mw.config.get("wgNamespaceNumber") == 2 && mw.config.get("wgPageName").indexOf('/') == -1)
            return false;

        if (mw.config.get("wgNamespaceNumber") % 2 != 0)
            return false;

        /* Incompatibilité avec le gadget auteur form, voir plus haut. */
        if (mw.config.get("wgNamespaceNumber") == 102 && mw.config.get("wgAction") == 'edit')
            return false;

        return true;
    },

    filter_node : function() {
        if ($(this).parent().hasClass('erori-comuni'))
            return false;
        return this.nodeType == 3;
    },

    get_text_nodes : function () {
        var content_id = "#bodyContent";
        if ($("#wikiPreview").length)
            content_id = "#wikiPreview";

        // TODO: Bencher sur //fr.wikisource.org/wiki/L’Encyclopédie/Volume_1
        // ou tout autre page qui contient un grand nombre de nœud.
        return $(content_id)
                   .find("*")
                   .not($(".no_erreurs_communes *"))
                   .not($(".diff *"))
                   .not($(".printfooter *"))
                   .not($(".previewnote *"))
                   .not($("#modernisations *"))
                   .not($("#authorityControl *"))    
                   .not($("#dynamic_links *"))
                   .not($("#contentSub *"))
                   .not($("#ws-data *"))
                   .not($("pre"))
                   .not($("script"))
                   .not($("style")) // TemplateStyles
                   .not($(".mwe-math-element *"))
                   .not($(":not(:lang(fr))"))
                   .contents()
                   .filter(select_multiple_text.filter_node);
    },

    portlet_link_added : false,

    exec : function(user_filter, search) {
        if (!select_multiple_text.filter_page(user_filter))
            return;

        search = select_multiple_text.precompile_regexp(search);

        if (mw.config.get('wgAction') == 'edit') {
            if ($('#wpTextbox1').length) {
                this.match_text($('#wpTextbox1')[0].value, search);
            }
        } else {
            var text_nodes = select_multiple_text.get_text_nodes();

            $.each(text_nodes, function(i, el) {
                select_multiple_text.change_text_node(el, search, 0);
            });
        }

        var error_count = $('span.erori-comuni').length;

        if (error_count) {
            if (!select_multiple_text.portlet_link_added) {
            	mw.loader.using('mediawiki.util', function() {
                mw.util.addPortletLink ("p-tb", "javascript:select_multiple_text.open_popup();",
                                "", "option-commons-errors", "");
            	});
            }

            $('#option-commons-errors a').text('Erreur(s) possible' + " (" + error_count + ")");

            select_multiple_text.portlet_link_added = true;
        }
    },

    default_select : function() {
        /* il faut une var qui définissent une espace, sécable, non sécable
         * etc. et qui fonctionne avec les entités html comme &nbsp;
         */
        var char_min = 'a-zéèàùâêîôûŷäëïöüÿçœæſñ';
        var char_maj = 'A-ZÉÈÀÂÙÊÎÔÛŶÄËÏÖÏŸÇŒÆÑ';
        var char = char_min + char_maj;

        var bw = '([^' + char + ']|^)';
        var ew = '([^' + char + ']|$)';
        var ch = '[' + char + ']';

        select_multiple_text.exec(/.*/,
            [
            "[^.][.][.][.](?![.])",
            "'", "‘",
            /* devrait inclure \\. mais match etc., et toutes les abbrevs, trop de
             * faux positifs */
            "[!:,;?][,;]+",
            "[" + char_min + "][!?:;]",
            "[!?;:.,][" + char + "]",
            "[ ][\\.,]",
            "[\\.?!] 11[^0-9]",
            "[0-9]" + ch,
            ch + "[0-9]",
            "1e[^r]", "[!1][a]",
            // caractères isolés non existant en français.
            bw + "[ù]" + ew,
            "[íì~fffiflffifflſtst]",
            bw + "carie",
            bw + "entant",
            "celte[^s,.]",
            bw + "clans",
            "\\. Gela",
            "\\. Gomme",
            bw + "[mM]ôme" + ew,
            bw + "[mM]émo" + ew,
            bw + "[DdcCLlNnSsTtMmNn]o" + '([^' + char + '-' + ']|$)',
            bw + "[CcLlSsTtMm]os" + ew,
            bw + "quo" + ew,
            "[ \n-]i[[t][ ,.]",
            /* mot d'au moins 3 lettres suivant par un . et sans majuscule */
            "[" + char_min + "-][" + char_min + "][^0-9A-Zpvcgm°.][.] [" + char_min + "]",
            /* la même chose pour les mots de deux lettres les plus courant */
            "(ma|ta|sa|ce|se|ni|va|pu|et|le|la|de|du|un|te|je|tu|il|me|ne|ou|où|ok|à|y|a)[.] [" + char_min + "]",
            "[  ][bB][éè]te[, ]",
            bw + "tète" + ew,
            "(^A | A )",
            "([^vmhp]\\. |[?!:] |^)(II|ll)(?!([Ie.]|$))",
            "1’" + ch,
            "(\\. |^)(Tun|Tune)" + ew,
            "est-a-dire",
            "[^  \n]—",
            "—[^  \n]",
            "[ ]-",
            "-[ ]",
            "[ ]’",
            "’[ ]",
            ]);
    }
};

$(document).ready(select_multiple_text.default_select);
Traesto fora da Wikipèdia - L'ençiclopedia łìbara e cołaboradiva in łéngua Vèneta "https://vec.wikipedia.org/w/index.php?title=MediaWiki:Gadget-Erori-comuni.js&oldid=1071155"