ميدياويكي:Gadget-Suggest.js

    من الشعر الشيعي
    مراجعة ١٩:٢٥، ٢٢ يونيو ٢٠٢٣ بواسطة dfghjk>Admin (۱ نسخه واردشده)
    (فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

    ملاحظة: بعد النشر، أنت قد تحتاج إلى إفراغ الكاش الخاص بمتصفحك لرؤية التغييرات.

    • فايرفوكس / سافاري: أمسك Shift أثناء ضغط Reload، أو اضغط على إما Ctrl-F5 أو Ctrl-R (⌘-R على ماك)
    • جوجل كروم: اضغط Ctrl-Shift-R (⌘-Shift-R على ماك)
    • إنترنت إكسبلورر/إيدج: أمسك Ctrl أثناء ضغط Refresh، أو اضغط Ctrl-F5
    • أوبرا: اضغط Ctrl-F5.
    /*
    
    Permet de fournir des suggestions de page pour un champ de saisie
    
    Documentation : [[Projet:JavaScript/Notices/Suggest]]
    
    {{Catégorisation JS|Suggest}}
    
    */
    
    // ************************************ VARIABLES GLOBALES ***********************
    var Suggest_Params = new Array();
    
    ///////////////////////////////// Variables personnalisables
    
    Suggest_Params["ZIndex"] = 5;                                            // Propriété "z-index" de départ
    Suggest_Params["TitleCaseSensitive"] = false;                            // Première lettre du titre sensible à la casse
    Suggest_Params["ImgSrc"] = new Array(                                    // Icônes :
       "//upload.wikimedia.org/wikipedia/commons/d/d1/Icon_no.png",     // « n'existe pas »
       "//upload.wikimedia.org/wikipedia/commons/a/a7/Icon_yes.png"     // « existe »
     );
    Suggest_Params["ImgTitle"] = new Array(                                  // Pop-up :
       "La page « $1 » n'existe pas",                                        // « n'existe pas »
       "La page « $1 » existe"                                               // « existe »
     );
    
    ///////////////////////////////// Variables non personnalisables
    
    Suggest_Params["Input"] = new Array();                                   // Matrice des <input> (champ de saisie)
    Suggest_Params["Suggest"] = new Array();                                 // Matrice des <select> (liste de suggestions)
    Suggest_Params["ExistInput"] = new Array();                              // Matrice des <input> (page existe ou pas)
    Suggest_Params["ExistImg"] = new Array();                                // Matrice des <img> (page existe ou pas)
    Suggest_Params["IsRunning"] = new Array();                               // Matrice de l'état de la requête de suggestions
    Suggest_Params["NSFilter"] = new Array();                                // Matrice de l'option de filtrage par espace de noms
    Suggest_Params["StripNS"] = new Array();                                 // Matrice de l'option d'affichage de l'espace de noms
    Suggest_Params["SuggestLimit"] = new Array();                            // Matrice de la limite des suggestions
    Suggest_Params["SuggestSelectLimit"] = new Array();                      // Matrice de la taille de la liste de suggestions
    Suggest_Params["ListDown"] = new Array();                                // Matrice de l'affichage de la liste de suggestions
    Suggest_Params["AddExist"] = new Array();                                // Matrice de l'affichage de l'icône
    Suggest_Params["Prefix"] = new Array();                                  // Matrice des préfixes de filtrage
    Suggest_Params["Suffix"] = new Array();                                  // Matrice des suffixes de filtrage
    Suggest_Params["RedirectFilter"] = new Array();                          // Matrice des filtrages de redirection
    Suggest_Params["Index"] = 1;                                             // Index de départ (id)
    
    // Valeurs par défaut
    Suggest_Params["NSFilter"][0] = false;
    Suggest_Params["StripNS"][0] = false;
    Suggest_Params["SuggestLimit"][0] = 10;
    Suggest_Params["SuggestSelectLimit"][0] = 5;
    Suggest_Params["ListDown"][0] = false;
    Suggest_Params["AddExist"][0] = false;
    Suggest_Params["Prefix"][0] = false;
    Suggest_Params["Suffix"][0] = false;
    Suggest_Params["RedirectFilter"][0] = "all";
    
    
    // ************************************ CRÉATION SUGGESTION D'ESPACE DE NOMS ***********************
    
    function Suggest_AddNamespaceSuggestion(ID, CLASS){
         if(typeof(mw.config.get('wgFormattedNamespaces'))=="undefined") return;
         var AllNS = new Array();
         var Options = new Array();
         for(var NS in mw.config.get('wgFormattedNamespaces')){
              if(NS<0) continue;
              AllNS.push(NS);
              var Value = (mw.config.get('wgFormattedNamespaces')[NS]==="" ? "(Main)" : mw.config.get('wgFormattedNamespaces')[NS]);
              var Option = document.createElement('option');
              Option.value = NS;
              Option.appendChild(document.createTextNode(Value));
              Options.push(Option);
         }
         var AllOption = document.createElement('option');
         AllOption.value = AllNS.join("|");
         AllOption.appendChild(document.createTextNode("*"));
         Options.unshift(AllOption);
         var Select = document.createElement('select');
         if(ID) Select.id = ID;
         if(ID) Select.name = ID;
         if(CLASS) Select.className = CLASS;
         for(var a=0,l=Options.length;a<l;a++){
              Select.appendChild(Options[a]);
         }
         return Select;
    }
    
    // ************************************ CRÉATION SUGGESTION DE PAGE ***********************
    
    function Suggest_AddPageSuggestion(Args){
         if(!Args) return;
         var InputNode = Args["InputNode"];
         if(!InputNode) return;
         var GlobalIndex = Suggest_Params["Index"]++;
         var NSFilter = (Args["NSFilter"] ? Args["NSFilter"] : Suggest_Params["NSFilter"][0] );
         var StripNS = (Args["StripNS"] ? Args["StripNS"] : Suggest_Params["StripNS"][0] );
         var SuggestLimit = (Args["SuggestLimit"] ? Args["SuggestLimit"] : Suggest_Params["SuggestLimit"][0] );
         var SuggestListSize = (Args["SuggestListSize"] ? Args["SuggestListSize"] : Suggest_Params["SuggestSelectLimit"][0] );
         var AddExist = (Args["AddExist"] ? Args["AddExist"] : Suggest_Params["AddExist"][0] );
         var ListDown = (Args["ListDown"] ? Args["ListDown"] : Suggest_Params["ListDown"][0]);
         var Prefix = (Args["Prefix"] ? Args["Prefix"] : Suggest_Params["Prefix"][0]);
         var Suffix = (Args["Suffix"] ? Args["Suffix"] : Suggest_Params["Suffix"][0]);
         var RedirectFilter = (Args["RedirectFilter"] ? Args["RedirectFilter"] : Suggest_Params["RedirectFilter"][0]);
         Suggest_UpDateLabel(InputNode, "InputWithSuggestion_"+GlobalIndex);
         InputNode.id = "InputWithSuggestion_"+GlobalIndex;
         var ExistInputNode = document.createElement("input");
         ExistInputNode.type = "hidden";
         ExistInputNode.id = "ThisPageExist_"+GlobalIndex;
         ExistInputNode.value = "0";
         InputNode.parentNode.insertBefore(ExistInputNode, InputNode.nextSibling);
         if(AddExist===true){
              var ExistImgNode = document.createElement("img");
              ExistImgNode.id = "ThisPageExistIMG_"+GlobalIndex;
              ExistImgNode.width = 20;
              ExistImgNode.height = 20;
              ExistImgNode.src = Suggest_Params["ImgSrc"][0];
              ExistImgNode.className = "SuggestionExist";
              InputNode.parentNode.insertBefore(ExistImgNode, InputNode.nextSibling);
         }
         var SelectNode = document.createElement('select');
         SelectNode.id = "SuggestionForInput_"+GlobalIndex
         SelectNode.style.display = "none";
         SelectNode.className = "SuggestionList";
         InputNode.parentNode.insertBefore(SelectNode, InputNode.nextSibling);
         Suggest_Params["Input"][GlobalIndex] = InputNode;
         Suggest_Params["Suggest"][GlobalIndex] = SelectNode;
              Suggest_Params["ExistInput"][GlobalIndex] = ExistInputNode;
         if(AddExist===true){
              Suggest_Params["ExistImg"][GlobalIndex] = ExistImgNode;
         }
         Suggest_Params["NSFilter"][GlobalIndex] = NSFilter;
         if(!NSFilter) StripNS = false;
         if(Prefix){
              if(NSFilter){
                   var ThisNamespaceName = mw.config.get('wgFormattedNamespaces')[NSFilter];
                   var Match = new RegExp("^"+ThisNamespaceName+":", "ig");
                   if(Prefix.match(Match)!=null){
                        Prefix = Prefix.substring((ThisNamespaceName=="" ? "" : ThisNamespaceName+":").length, Prefix.length);
                   }
                   StripNS = true;
              }
         }
         Suggest_Params["StripNS"][GlobalIndex] = StripNS;
         Suggest_Params["Prefix"][GlobalIndex] = Prefix;
         Suggest_Params["Suffix"][GlobalIndex] = Suffix;
         Suggest_Params["SuggestLimit"][GlobalIndex] = SuggestLimit;
         Suggest_Params["SuggestSelectLimit"][GlobalIndex] = SuggestListSize;
         Suggest_Params["ListDown"][GlobalIndex] = ListDown;
         Suggest_Params["AddExist"][GlobalIndex] = AddExist;
         Suggest_Params["RedirectFilter"][GlobalIndex] = RedirectFilter;
         Suggest_Params["IsRunning"][GlobalIndex] = false;
         InputNode.onkeyup = function(){
              var ThisIndex = Suggest_GetSuggestionIndex(this);
              Suggest_GetSuggestions(ThisIndex);
         }
         return GlobalIndex;
    }
    
    // ************************************ MISE A JOUR DU LABEL ***********************
    
    function Suggest_UpDateLabel(InputNode, NewID){
         var OldId = InputNode.id;
         if(!OldId) return;   
         var Labels = document.getElementsByTagName('label');
         for(var a=0,l=Labels.length;a<l;a++){
              var For = Labels[a].getAttribute("for");
              if(For){
                   if(For == OldId){
                        Labels[a].setAttribute("for", NewID);
                        return;
                   }
              }
         }
    }
    
    // ************************************ LANCEMENT REQUÊTE SUGGESTIONS ***********************
    
    function Suggest_GetSuggestions(Index){
         var IsRunning = Suggest_Params["IsRunning"][Index];
         if(IsRunning===true) return;
    
         var NamespaceFilter = Suggest_Params["NSFilter"][Index];
         var StripNamespace = Suggest_Params["StripNS"][Index];
         var Limit = Suggest_Params["SuggestLimit"][Index];
         var Select = Suggest_Params["Suggest"][Index];
         var Input = Suggest_Params["Input"][Index];
         var Prefix = Suggest_Params["Prefix"][Index];
         var Suffix = Suggest_Params["Suffix"][Index];
         var RedirectFilter = Suggest_Params["RedirectFilter"][Index];
         var Page = Input.value;
         if(Page===""){
              Select.style.display = "none";
              return;
         }
         var ValueNamespace = (NamespaceFilter ? NamespaceFilter : Suggest_GetNamespaceInfoFormPage((Prefix+Page),"NamespaceNumber"));
         var ValuePageName = Suggest_GetNamespaceInfoFormPage(Page, "PageName");
         if(StripNamespace && NamespaceFilter && !Prefix){
              var ThisNamespaceName = mw.config.get('wgFormattedNamespaces')[NamespaceFilter];
              var Match = new RegExp("^"+ThisNamespaceName+":", "ig");
              if(Page.match(Match)!=null){
                   Page = ValuePageName;
              }
              Input.value = Suggest_ucFirst(Page);
         }else if(Prefix && NamespaceFilter){
              Match = new RegExp("^"+Prefix, "ig");
              if(Page.match(Match)!=null){
                   Page = Page.substring(Prefix.length, Page.length);
              }
              Input.value = Page;
              Page = Prefix+Page;
         }else if(Prefix && !NamespaceFilter){
              Page = Suggest_GetNamespaceInfoFormPage((Prefix+Page), "PageName");
         }else if(!Prefix && !NamespaceFilter){
              ValueNamespace = Suggest_GetNamespaceInfoFormPage(Page,"NamespaceNumber");
              Page = Suggest_GetNamespaceInfoFormPage(Page, "PageName");
         }
         Suggest_Params["IsRunning"][Index] = true;
         var APILimit = ( ((mw.config.get('wgUserGroups').indexOf("sysop")!=-1)||(mw.config.get('wgUserGroups').indexOf("bot")!=-1)) ? 4999 : 499 );
         if(Limit>APILimit) Limit = APILimit;
         var URL =  "/api.php?format=xml&action=query&list=allpages"
                  + "&apnamespace=" + ValueNamespace
                  + "&apprefix=" + Page.replace(/&/g, "%26")
                  + "&apfilterredir=" + RedirectFilter
                  + "&aplimit=" + Limit;
     
         var SuggestRequest = new sajax_init_object() ;
         SuggestRequest.open('GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + URL, true);
         SuggestRequest.onreadystatechange = function () {
              if (SuggestRequest.readyState != 4) return;
              var xml = SuggestRequest.responseXML ;
              if ( xml == null ) return ;
              var titles = new Array () ;
              var pages = xml.getElementsByTagName("p") ;
              for(var i=0;i<pages.length;i++){
                   var s = pages[i].getAttribute("title");
                   if(Suffix){
                        var Reg = new RegExp(Suffix+"$", "g")
                        if(s.match(Reg)==null) continue;
                   }
                   if(StripNamespace){
                        var ThisNamespaceName = mw.config.get('wgFormattedNamespaces')[NamespaceFilter];
                        var Match = new RegExp("^"+ThisNamespaceName+":", "ig");
                        if(s.match(Match)!=null){
                             s = Suggest_GetNamespaceInfoFormPage(s, "PageName");
                        }
                   }
                   if(Prefix){
                        s = s.substring(s.indexOf(Prefix)+Prefix.length, s.length);
                   }
                   if(titles.indexOf(s)==-1) titles.push(s);
              }
              Suggest_Params["IsRunning"][Index] = false;
              Suggest_ShowSuggestions(titles, Index);
         };
         SuggestRequest.send(null);
    }
    
    // ************************************ AFFICHAGE SUGGESTIONS ***********************
    
    function Suggest_ShowSuggestions(titles, Index){
         var Select = Suggest_Params["Suggest"][Index];
         var Input = Suggest_Params["Input"][Index];
         var ExistInputNode = Suggest_Params["ExistInput"][Index];
         var ExistImgNode = Suggest_Params["ExistImg"][Index];
         var ListDown = Suggest_Params["ListDown"][Index];
         var NamespaceFilter = Suggest_Params["NSFilter"][Index];
         var Prefix = Suggest_Params["Prefix"][Index];
         var TheNamespace = "";
         if(NamespaceFilter!==false){
              TheNamespace = mw.config.get('wgFormattedNamespaces')[NamespaceFilter];
              TheNamespace = (TheNamespace ==="" ? "" : TheNamespace+":");
         }
         if(Prefix){
              TheNamespace += Prefix;
         }
         var CurrentValue = Input.value;
         if(ExistInputNode) ExistInputNode.value = "0";
         if(ExistImgNode){
              ExistImgNode.src = Suggest_Params["ImgSrc"][0];
              ExistImgNode.title = Suggest_Params["ImgTitle"][0].split("$1").join(TheNamespace+CurrentValue);
              ExistImgNode.alt = Suggest_Params["ImgTitle"][0].split("$1").join(TheNamespace+CurrentValue);
         }
         if(titles.length==0){
              Select.style.display = "none" ;
              Input.title = ""; 
              return;
         }
         Select.style.display = "inline" ;
         if(ExistInputNode) ExistInputNode.value = "1";
         if(ExistImgNode){
              ExistImgNode.src = Suggest_Params["ImgSrc"][1];
              ExistImgNode.title = Suggest_Params["ImgTitle"][1].split("$1").join(TheNamespace+CurrentValue);
              ExistImgNode.alt = Suggest_Params["ImgTitle"][1].split("$1").join(TheNamespace+CurrentValue);
         }
         if(titles[0]===Input.value){
              Select.style.display = "none" ;
              Input.title = ""; 
              return;
         }
         var TailleListe = Suggest_Params["SuggestSelectLimit"][Index];
         if (titles.length < TailleListe ) TailleListe = titles.length;
         Select.size = TailleListe ;
         Select.style.align = "right" ;
         Select.style.zIndex = Suggest_Params["ZIndex"]++ ;
         Select.style.position = "relative" ;
         Select.style.width = Input.offsetWidth + "px" ;
         Select.style.height = (TailleListe * 20) + "px" ;
         while(Select.firstChild) Select.removeChild(Select.firstChild);
         for ( var i = 0 ; i < titles.length ; i++ ) {
              var opt = document.createElement("option");
              var ot = document.createTextNode(titles[i]);
              opt.appendChild(ot) ;
              opt.value = titles[i];
              Select.appendChild(opt) ;
         }
         Select.onkeyup = Suggest_ReplaceSuggestionsKeyPress;
         Select.onclick = Suggest_ReplaceSuggestions;
         if(ListDown){
              Select.style.top = parseInt(Input.offsetHeight) + "px";
              Select.style.marginBottom = "-" + ((TailleListe * 20) + parseInt(Input.offsetHeight)) + "px" ;
         }else{
              Select.style.marginTop = "-" + (TailleListe * 20) + "px" ;
         }
         Select.style.marginRight = "-" + Input.offsetWidth + "px" ;
         var suggestion = titles[0] ;
         if(suggestion.match(new RegExp("^"+CurrentValue))==null){
              Suggest_GetSuggestions(Index);
              return;
         }
         var StripNamespace = Suggest_Params["StripNS"][Index];
         var CurrentValueLength = CurrentValue.length;
         if(StripNamespace){
              var NamespaceName = Suggest_GetNamespaceInfoFormPage(CurrentValue,"NamespaceName");
              NamespaceName = ( NamespaceName==="" ? "" : NamespaceName+":");
              if(NamespaceName==TheNamespace){
                   CurrentValueLength = Suggest_GetNamespaceInfoFormPage(CurrentValue,"PageName").length + TheNamespace.length;
              }
         }else if(NamespaceFilter!==false && !Prefix){
              var NamespaceName = Suggest_GetNamespaceInfoFormPage(CurrentValue,"NamespaceName");
              NamespaceName = ( NamespaceName==="" ? "" : NamespaceName+":");
              if(NamespaceName==TheNamespace){
                   CurrentValueLength = Suggest_GetNamespaceInfoFormPage(CurrentValue,"PageName").length + TheNamespace.length;
              }else{
                   CurrentValueLength = CurrentValueLength  + TheNamespace.length;
              }
         }
         //alert("CurrentValueLength : "+CurrentValueLength+"\nsuggestion.length : "+suggestion.length);
         Input.value = suggestion;
         Input.title = TheNamespace + suggestion;
         if (Input.createTextRange) {
              var ra = Input.createTextRange();
              ra.moveStart("character", CurrentValueLength);
              ra.moveEnd("character", suggestion.length);
              ra.select();
         } else if( Input.setSelectionRange ) {
              Input.setSelectionRange( CurrentValueLength, suggestion.length );
         } else {
              Input.selectionStart = CurrentValueLength;
              Input.selectionEnd = suggestion.length ;
         }
         if(ExistImgNode){
              CurrentValue = Input.value;
              ExistImgNode.src = Suggest_Params["ImgSrc"][1];
              ExistImgNode.title = Suggest_Params["ImgTitle"][1].split("$1").join(TheNamespace+CurrentValue);
              ExistImgNode.alt = Suggest_Params["ImgTitle"][1].split("$1").join(TheNamespace+CurrentValue);
         }
    }
    
    // ************************************ SÉLECTION D'UNE SUGGESTION (CLAVIER) ***********************
    
    function Suggest_ReplaceSuggestionsKeyPress(e){
         if (!e) var e = window.event;
         if (e.keyCode != 13) return;
         Suggest_ReplaceSuggestions();
    }
    
    // ************************************ APPLICATION D'UNE SUGGESTION ***********************
    
    function Suggest_ReplaceSuggestions(){
         var Index = Suggest_GetSuggestionIndex(this);
         var Select = Suggest_Params["Suggest"][Index];
         var Input = Suggest_Params["Input"][Index];
         if(!Input|| !Select) return;
         var NamespaceFilter = Suggest_Params["NSFilter"][Index];
         var Prefix = Suggest_Params["Prefix"][Index];
         var TheNamespace = "";
         if(NamespaceFilter){
              TheNamespace = mw.config.get('wgFormattedNamespaces')[NamespaceFilter];
              TheNamespace = (TheNamespace ==="" ? "" : TheNamespace+":");
         }
         if(Prefix){
              TheNamespace += Prefix;
         }
         Select.style.zIndex = Suggest_Params["ZIndex"]++ ;
         var Options = Select.getElementsByTagName('option');
         for(var a=0;a<Options.length;a++){
              if(Options[a].selected){
                Input.value = Options[a].value;
                Input.title = TheNamespace+Options[a].value;
                Input.focus();
                Suggest_GetSuggestions(Index);
                return;
            }
        }
    }
    
    // ************************************ RÉCUPÉRATION N° D'INDEX ***********************
    
    function Suggest_GetSuggestionIndex( Element ){
        return parseInt(Element.id.replace(/[^0-9]/g, ""));
    }
    
    // ************************************ RÉCUPÉRATION INFORMATIONS NAMESPACE ***********************
    
    function Suggest_GetNamespaceInfoFormPage(Page, ToReturn){
         if(!ToReturn) ToReturn = false;
         var NamespaceNumber = 0;
         var NamespaceName = "";
         var PageName = Page;
         var Found = false;
         for(var NS in mw.config.get('wgFormattedNamespaces')){
              if(Found) continue;
              var ThisNamespaceName = mw.config.get('wgFormattedNamespaces')[NS];
              if(ThisNamespaceName==="") continue;
              var NamespaceNameRegExp = new RegExp("^"+ThisNamespaceName+":", "ig");
              var Matches = Page.match(NamespaceNameRegExp);
              if(Matches!=null && Matches.length == 1){
                   NamespaceNumber = parseInt(NS);
                   NamespaceName = ThisNamespaceName;
                   PageName = Page.replace(NamespaceNameRegExp, "");
                   Found = true;
              }
         }
    
         if(ToReturn==="NamespaceName") return NamespaceName;
         if(ToReturn==="PageName") return PageName;
         return NamespaceNumber;
    }
    
    // ************************************ PREMIÈRE LETTRE EN MAJUSCULE ***********************
     
    function Suggest_ucFirst(Text) {
        if(Suggest_Params["TitleCaseSensitive"]) return Text;
        return Text.substr(0,1).toUpperCase() + Text.substr(1,Text.length);
    }