MediaWiki:Gadget-PossiblesErrors.js

Nota: Després de publicar, possiblement necessitareu refrescar la memòria cau del vostre navegador per a veure'n els canvis.

  • Firefox / Safari: Premeu Majús i alhora cliqueu el botó Actualitzar, o pressioneu Ctrl+F5 o Ctrl+R (⌘+R en un Mac)
  • Google Chrome: Premeu Ctrl+Majús+R (⌘+Shift+R en un Mac)
  • Internet Explorer / Edge: Premeu Ctrl i alhora cliqueu a Actualitza o pressioneu Ctrl+F5
  • Opera: Premeu Ctrl-F5.
/*Ressalta possibles errors tipogràfics de color rosa i crea una opció al menú esquerre semblant a l'opció de detecció d'errates. Tot i els falsos positius, és una bona eina per a usuaris acostumats a revisar pàgines.*/
/*Basat en [[:fr:MediaWiki:Gadget-Erreurs-communes.js]], de [[:fr:User:Phe]]*/

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.Erreurs-communes').each(function (index, el) {
            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) {//mode edició
            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>'+ 'Error(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='Erreurs-communes'>" + 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 que 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='Erreurs-communes' 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;

        if (mw.config.get("wgNamespaceNumber") != 0 && mw.config.get("wgNamespaceNumber") != 102) return false;

        return true;
    },

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

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

        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"))
           .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.Erreurs-communes').length;

        if (error_count) {
            if (!select_multiple_text.portlet_link_added) {
                mw.util.addPortletLink ("p-tb", "javascript:select_multiple_text.open_popup();",
                                "", "option-commons-errors", "");
            }
            $('#option-commons-errors a').text('Error(s) possible' + " (" + error_count + ")");
            select_multiple_text.portlet_link_added = true;
        }
    },

    default_select : function() {
     var char_min = 'a-zéèàùâêîôûŷäëïöüÿçœæſñ';
     var char_maj = 'A-ZÉÈÀÂÙÊÎÔÛŶÄËÏÖÏŸÇŒÆÑ';
     var char = char_min + char_maj;
     var ch = '[' + char + ']';
     select_multiple_text.exec(/.*/,
      [
 "[ ]-" + "^[ ]",
 "^[ ]" + "-[ ]",
 "[abcdf-z]" + "[A-Z]",//aB, fals positiu ePub
 "[A-Z]" + "[A-Z]" + "[a-z]",//ABc
 "■","►","-\n[a-zéèçà]",
 "aha ","ahan ","a[ïíìl!1I]x",
 "accc","acceu","aece[un]","acee[nu]",
 " corn ",//possible fals positiu
 " moit ","ì","diuben",
 //combinacions inexistents
"aixd","bdl","brd","dcl","drt","frn","lll","[mst]cn","gcr","nln","prc","rcm","sds","trcs","vfs","Dcu"," bd "," rm","rcst"," ds ","scd","scg"," cs","xlr","chp",
 "[0-9]" + ch + "^m",//exc. {{gap|2em}}
 ch + "[0-9]",
 " cc"," ee"," oem",//ce,ec
 "cntr","ntrc","outra","nlr",
 //"[li][il]ug[uü]", dóna falsos positius en belluguessis
 "ma[nu]li[nu]g",//mantingut
 "p[ceo]usa","pcns","p[ceo]saut","p[ceo][un]saut",
 " eu "," nb ", " uu "," nn ","[pq]nn",//en,un
 " in[ce] ",//me
 "dsf",//dís
 " sc "," ae ",//se
 " t[il][nu]e ",//tinc
 "tr[eo]ha",
 "tü",//tu
 "Uo","Ui",//llo,lli
 "(li|il)[nu][nu]",//lluny
 "Qn","q[nu]c","g[un]c"," gne "," gni ","qn","qae",//que, qui
 "[0-9][’*'´\\^]","[’*'´\\^][0-9]"
      ]);
    }
};

if (window.jQuery) {window.jQuery(document).ready(select_multiple_text.default_select);}
else {$(document).ready(select_multiple_text.default_select);}