Hopp til innhold

MediaWiki:Gadget-linjekart.js

Fra Wikipedia, den frie encyklopedi
(Omdirigert fra «MediaWiki:Linjekart.js»)

Merk: Etter publisering vil det kanskje være nødvendig å slette mellomlageret i nettleseren din for å se endringene.

  • Firefox / Safari: Hold Shift mens du klikker på Oppdater, eller trykk enten Ctrl+F5 eller Ctrl+R (⌘+R på Mac)
  • Google Chrome: Trykk Ctrl+Shift+R (⌘+Shift+R på Mac)
  • Edge: Hold Ctrl mens du trykker på Oppdater eller trykk Ctrl+F5
 /** Collapsible tables *********************************************************
  *
  *  Description: Allows tables to be collapsed, showing only the header. See
  *               [[Wikipedia:NavFrame]].
  */

 /* Show/hide table sections *********************************
  *
  * Assosierte maler: Mal:BS-startVisSkjul, Mal:JBS-startVisSkjul, Mal:JBS2-startVisSkjul, 
  *                   Mal:JBS3-startVisSkjul, Mal:JBS4-startVisSkjul, Mal:JBS-sluttVisSkjul
  * Kommentarer: Funksjonen er svært lik collapseTableSection i MediaWiki:Visskjul.js
  *              og kan muligens flettes til denne.
  * Description: Shows or hides predefined sections of collapsible tables.
  * Maintainers: [[User:BjørnN]]
  */

 function BScollapseTable(tableIndex, rowIndex)
 {
     var Table = document.getElementById( "Linjekart" + tableIndex );
     var TableHd = document.getElementById( "LinjekartHd" + tableIndex );
     var TableRows = Table.rows;
     var TD = TableHd.rows[0].getElementsByTagName( "td" );
     var collapse = false;
     var change = false;
     var started = false;
     var collapsedView = false;
     var detailView = false;

     for ( var j = 0; j < TableRows.length; j++ ) {
       var TR = TableRows[j];

       switch (rowIndex) {
         case 0:
           if ($(TR).hasClass("startCollapse"))
             $(TR).addClass("hide");
           else if (!jQuery(TR).hasClass("endCollapse"))
             $(TR).removeClass("hide");
           detailView = true;
           break;
         case -1:
           if ($(TR).hasClass("startCollapse")) {
             $(TR).removeClass("hide");
             collapse = true;
           } else if ($(TR).hasClass("endCollapse"))
             collapse = false;
           else if (collapse)
             $(TR).addClass("hide");
           collapsedView = true;
           break;
         default:
           change = change || j == rowIndex;
           change = change && !($(TR).hasClass("endCollapse"));

           if (change)
             if ($(TR).hasClass("hide"))
               $(TR).removeClass("hide");
             else
               $(TR).addClass("hide");

           if ($(TR).hasClass("startCollapse"))
               if (! started) {
                   if ($(TR).hasClass("hide"))
                       detailView |= true
                   else
                       collapsedView |= true

                   started = true;
               }
           else
               started = false;
       }
     }

     if (collapsedView)
         $(TD[0].getElementsByTagName( "span" )[0]).removeClass("hide");
     else
         $(TD[0].getElementsByTagName( "span" )[0]).addClass("hide");

     if (detailView)
         $(TD[1].getElementsByTagName( "span" )[0]).removeClass("hide");
     else
         $(TD[1].getElementsByTagName( "span" )[0]).addClass("hide");
 }

 /* Create a button *********************************
  *
  * Description: Creates folder style navigation buttons for collapsible tables.
  * Based on function createCollapseButton, maintained by [[:en:User:R. Koot]] 
  * Maintainers: [[User:BjørnN]]
  */

 function createBScollapseButton(tableIndex, rowIndex, caption, buttonTitle)
 {
     var Button     = document.createElement( "span" );
     var ButtonLink = document.createElement( "a" );
     var ButtonText = document.createTextNode( caption );

     ButtonLink.setAttribute( "title", buttonTitle );
     ButtonLink.setAttribute( "href", "javascript:BScollapseTable(" + tableIndex + ", " + rowIndex + ");" );
     ButtonLink.appendChild( ButtonText );

     Button.className = "BSbutton";
     Button.appendChild( document.createTextNode( "[" ) );
     Button.appendChild( ButtonLink );
     Button.appendChild( document.createTextNode( "]" ) );

     return Button;
 }

 /* Create show/hide buttons for table sections *********************************
  *
  * Description: Creates folder style navigation buttons for collapsible tables.
  * Maintainers: [[User:BjørnN]]
  */

 function createBScollapseButtons( Table, TableHd, tableIndex)
 {
     TableHd.setAttribute( "id", "LinjekartHd" + tableIndex );

     var started = false;
     var displayRow = true;
     var sectionStart = 0;
     var TableRows = Table.rows;

     var TR = TableHd.rows[0];

     var detailCaption = "Vis alt";
     var overviewCaption = "Vis oversikt";
     var showCaption = "+";
     var hideCaption = "–";
     var showTitle = "Vis mer";
     var hideTitle = "Vis mindre";

     var aTD = TR.getElementsByTagName( "td" ); // fetch parameter cache
     try { detailCaption = aTD[1].firstChild.data; } catch (e) { ; }
     try { overviewCaption = aTD[2].firstChild.data; } catch (e) { ; }
     try { showCaption = aTD[3].firstChild.data; } catch (e) { ; }
     try { hideCaption = aTD[4].firstChild.data; } catch (e) { ; }
     try { showTitle = aTD[5].firstChild.data; } catch (e) { ; }
     try { hideTitle = aTD[6].firstChild.data; } catch (e) { ; }

     var TD = TR.insertCell(0); // execute after all the aTD statemens - it changes the index reference
     var Button = createBScollapseButton(tableIndex, 0, detailCaption, detailCaption);

     TD.appendChild(Button);

     TD = TR.insertCell(1);
     Button = createBScollapseButton(tableIndex, -1, overviewCaption, overviewCaption);
     $(Button).addClass("hide");
     TD.appendChild(Button);

     for ( var j = 0; j < TableRows.length; j++ ) {
         var TR = TableRows[j];
         var TD = TR.insertCell(0);

         if ($(TR).hasClass("startCollapse")) {
             if (! started) {
               sectionStart = j;
               Button = createBScollapseButton(tableIndex, sectionStart, showCaption, showTitle);
               TD.appendChild(Button);
               started = true;
               displayRow = false;
             }
             $(TR).removeClass("hide");
         } else if ($(TR).hasClass("endCollapse"))
             displayRow = true;
         else {
             if (started) {
               Button = createBScollapseButton(tableIndex, sectionStart, hideCaption, hideTitle);
               TD.appendChild(Button);
               started = false;
               $(TR).addClass("hide");
             } else
               if (! displayRow)
                 $(TR).addClass("hide");
         }
     }
 }

 function createBSbuttons()
 {
     var Tables = document.getElementsByTagName( "table" );
     var tableIndex = 0;

     for ( var i = 0; i < Tables.length; i++ ) {
         if ($(Tables[i]).hasClass("withAlternateSections")) {
           Tables[i].setAttribute( "id", "Linjekart" + tableIndex );
           createBScollapseButtons( Tables[i], Tables[i+1], tableIndex);
           tableIndex++;
         }
     }
 }

 jQuery( document ).ready( createBSbuttons );

 /* Update a ranking table column *********************************
  *
  * Description: Updates a ranking column based on sorted column data
  *              If the routine finds a sorted column in a table it will 
                 recreate the ranking column when desired 
  * Assosierte maler: Mal:Rangspalte 
  * Maintainers: [[User:BjørnN]]
  */

 var rankEmpty = "";

 function fetchNumber(node)
 {
   if (node.hasChildNodes()) {
     try {
       for (var leaf = node; leaf.firstChild; leaf = leaf.firstChild);
       return Number(leaf.data.replace(/(\d+?)\s(\d*?)/,"$1$2").replace(/(\d+?),(\d*?)/,"$1.$2"));
     } catch(e) {
       return NaN;
     }
   }

   return 0;
 }

 function findSortedCol(aTR, rankCol, showCol)
 {
   var aTH = aTR[0].getElementsByTagName("TH");
   var col = -1;

   if (showCol) $(aTH[rankCol]).removeClass("rankCol");

   for (var i = 0; i<aTH.length; i++) {
     if (!$(aTH[i]).hasClass("unsortable")) {
       var greater, less;
       var currVal;
       var prevVal = fetchNumber(aTR[1].getElementsByTagName("TD")[i]);

       for (var j = 2, up = false, down = false; j<aTR.length && !isNaN(prevVal); j++, prevVal = currVal) {
         currVal = fetchNumber(aTR[j].getElementsByTagName("TD")[i]);
         greater = currVal > prevVal;
         less = currVal < prevVal;
         up = up || greater && !(up || down);
         down = down || less && !(up || down);

         if (up && less || down && greater) break;
       }

       if (j == aTR.length && (up || down)) {
         col = i;

         if (showCol) {
           $(aTH[i]).addClass("rankCol");
           $(aTH[rankCol]).addClass("rankCol");
         }
       } else
         $(aTH[i]).removeClass("rankCol");
     }
   }

   return col;
 }

 function recreateRank(rankCol, showCol, tableIndex)
 {
   var TR = document.getElementById("Filtertabell" + tableIndex).rows;
   var dataCol = findSortedCol(TR, rankCol, showCol);

   if (dataCol < 0)
     return;

   var prevVal = fetchNumber(TR[1].getElementsByTagName("TD")[dataCol]);
   var lastVal = fetchNumber(TR[TR.length-1].getElementsByTagName("TD")[dataCol]);
   var down = prevVal > lastVal;

   for ( var i = 1, rank = 1, iRank = 1; i < TR.length; i++ ) {
     var aTD = TR[i].getElementsByTagName("TD");
     var currCell = fetchNumber(aTD[dataCol]);

     if (!$(TR[i]).hasClass("hide") && currCell != "") {
       var currVal = currCell;
       var greater = currVal > prevVal;
       var less = currVal < prevVal;

       if (down && greater || !down && less)
         return;

       if (down && less || !down && greater)
         rank = iRank;

       aTD[rankCol].innerHTML = rank+".";
       prevVal = currVal;
       iRank += 1;
     }
     else
       aTD[rankCol].innerHTML = rankEmpty;
   }
 }

 function createOneButton(caption, buttonTitle, buttonFunction, buttonId)
 {
     var Button     = document.createElement( "span" );
     var ButtonLink = document.createElement( "a" );
     var ButtonText = document.createTextNode( caption );

     ButtonLink.title = buttonTitle;
     ButtonLink.id = buttonId;
     ButtonLink.href = "javascript:"+ buttonFunction + ";";
     ButtonLink.appendChild( ButtonText );

     Button.appendChild( document.createTextNode( "[" ) );
     Button.appendChild( ButtonLink );
     Button.appendChild( document.createTextNode( "]" ) );

     return Button;
 }

 function createRankingButton(row, tableIndex)
 {
   var aTD = row.getElementsByTagName("TD");
   var rankCol = aTD[0].innerHTML-1;
   var dataCol = aTD[1].innerHTML-1;
   var caption = aTD[2].innerHTML;
   rankEmpty = aTD[3].innerHTML;
   var auto = aTD[4].innerHTML == "ja";
   var showCol = aTD[5].innerHTML != "nei";

   if (row.rowIndex > 0 || $(document.getElementById("Filtertabell" + tableIndex)).hasClass("sortable")) { // vis knapp bare hvis tabellen har filter eller er sorterbar
     var buttonFunc = "recreateRank(" + rankCol + "," + showCol + "," + tableIndex + ")";
     var Button = createOneButton(caption, "", buttonFunc, "");
     var TD = row.insertCell(0);
     TD.appendChild(Button);
   }

   if (auto)
     recreateRank( rankCol, showCol, tableIndex);
 }

 /* Display selected rows of a table *********************************
  *
  * Description: Updates the CSS class for display on selected table rows
  *              according to conditions determined in templates in front 
                 of the table 
  * Assosierte maler: Mal:Filtergruppe, Mal:Filtergrupper
  * Kommentarer: betingelsene er fastlagt i class-atributter som pseudoklasser
  *              antakelig ville det være bedre å bruke title-atributter
  *              for sikkert å unngå konflikter med CSS
  * Maintainers: [[User:BjørnN]]
  */

 var cChecked = "X";
 var cUnchecked = "_";
 var cCheckID = "filterCheck";
 var cfClass = "filterShow";

 function applyFilter(tableIndex, aClass, bChecked)
 {
     var TableRows = document.getElementById("Filtertabell" + tableIndex).rows;

     for ( var j = 0; j < TableRows.length; j++ ) {
       var TR = TableRows[j];

       if ( TR.className ) {
         var bDisplay = false, bFound = true;

         for ( var k=cfClass.length; k < TR.className.length; k++){
           var cClass = TR.className.charAt(k);

           if ( cClass == " " )
             break; // ignore class 'hide'

           if ( cClass != "-" ) {
             var bTestUnchecked = cClass != cClass.toUpperCase();
             cClass = cClass.toUpperCase();

             for ( var i=0; i < aClass.length; i++)
               if ( aClass[i] == cClass )
                   bFound = bFound && (bTestUnchecked && !bChecked[i] || !bTestUnchecked && bChecked[i]);
           } else {
             bDisplay = bDisplay || bFound;

             if ( bDisplay )
               break;
             else
               bFound = true;
           }
         }
         bDisplay = bDisplay || bFound;

         if (bDisplay)
           $(TR).removeClass("hide");
         else
           $(TR).addClass("hide");
       }
     }
 }

 function checkFilterCheckbox(tableIndex, cClass)
 {
     var Checkbox = document.getElementById( cCheckID + tableIndex + cClass );
     var TR = Checkbox.parentNode.parentNode.parentNode;

     if ($(TR).hasClass("filterRadio")) {
       var Checks = TR.getElementsByTagName( "A" );

       for ( var j=0; j < Checks.length; j++)
         Checks[j].firstChild.data = cUnchecked;

       Checkbox.lastChild.data = cChecked;
     }
     else
       Checkbox.lastChild.data = (Checkbox.lastChild.data == cUnchecked)?cChecked:cUnchecked;

     var HdTR = TR.parentNode.getElementsByTagName( "TR" );
     var aClass = new Array();
     var bChecked = new Array();

     for ( var i = 0, iCheck = 0; i < HdTR.length; i++ ) {
       if ($(HdTR[i]).hasClass("filterGroup")) {
         var bAnyChecked = false;
         var Checks = HdTR[i].getElementsByTagName( "A" );

         for ( var j=0; j < Checks.length; j++){
           aClass[iCheck + j] = Checks[j].id.charAt(Checks[j].id.length-1);
           bChecked[iCheck + j] = Checks[j].firstChild.data == cChecked;
           bAnyChecked = bAnyChecked || bChecked[iCheck + j];
         }

         if (!bAnyChecked && $(HdTR[i]).hasClass("filterAll") )
           for ( var j=0; j < Checks.length; j++)
             bChecked[iCheck + j] = true;

         iCheck += Checks.length;
       }
     }

     applyFilter(tableIndex, aClass, bChecked);
 }

 function createFilterCheckbox( tableIndex, sClass, bChecked, cCaption, cPreCaption)
 {
     var Checkbox     = document.createElement( "span" );
     var CheckboxLink = document.createElement( "a" );
     var CheckboxText = document.createTextNode( bChecked?cChecked:cUnchecked );

     Checkbox.className = "FGbutton";
     CheckboxLink.setAttribute( "id", cCheckID + tableIndex + sClass );
     CheckboxLink.setAttribute( "title", cCaption );
     CheckboxLink.setAttribute( "href", 'javascript:checkFilterCheckbox(' + tableIndex + ', "' + sClass + '" );' );
     CheckboxLink.appendChild( CheckboxText );

     Checkbox.appendChild( document.createTextNode( cPreCaption + " [" ) );
     Checkbox.appendChild( CheckboxLink );
     Checkbox.appendChild( document.createTextNode( "] " + cCaption ) );

     return Checkbox;
 }

 function createFilterCheckboxes( headerTable, tableIndex)
 {
     var aTR = headerTable.getElementsByTagName( "TR" );
     var aClass = new Array();
     var aCaption = new Array();
     var aCheck = new Array();
     var bChecked = new Array();

     for ( var i = 0, iCheck = 0; i < aTR.length; i++) {
       if ($(aTR[i]).hasClass("filterGroup")) {
         var aTD = aTR[i].getElementsByTagName( "td" );
         var cPreCaption = "";
         var k=0;
         var bAnyChecked = false;
         
         try {
           if (aTD[0].title == "t0") {
             cPreCaption = aTD[0].firstChild.data;
             k++;
           }   
 
           for ( var j = 0; j*3 < aTD.length; j++) {
             aClass[iCheck + j] = aTD[j*3+0+k].firstChild.data;
             aCaption[iCheck + j] = aTD[j*3+1+k].firstChild.data;
             try { aCheck[iCheck + j] = aTD[j*3+2+k].firstChild.data; } catch (e) { ; }
           }
         }
         catch (e) { ; }
 
         var nTuples = j;
         var TD = aTR[i].insertCell(0);
         TD.className = "FGchecks";
 
         for ( var j = 0; j < nTuples; j++) {
           var bCheck =  bChecked[iCheck + j] = aCheck[iCheck + j] == "ja";
           Checkbox = createFilterCheckbox( tableIndex, aClass[iCheck + j],  bCheck, aCaption[iCheck + j], cPreCaption);
           cPreCaption = "";
           TD.appendChild(Checkbox);
           bAnyChecked = bAnyChecked || bCheck;
         }
 
         if (!bAnyChecked && $(aTR[i]).hasClass("filterAll"))
           for ( var j=0; j < nTuples; j++)
             bChecked[iCheck + j] = true;
 
         iCheck += nTuples;
       }
     }

     applyFilter(tableIndex, aClass, bChecked);

     if ($(aTR[aTR.length-1]).hasClass("autoRank"))
       createRankingButton(aTR[aTR.length-1], tableIndex);
 }

 function createFilterButtons()
 {
   var Tables = document.getElementsByTagName( "table" );
   var tableIndex = 0;
   var groupTab;

   for ( var i = 0, bGroup = bFilter = false; i < Tables.length; i++ ) {
     if ($(Tables[i]).hasClass("filterGroups")) {
       groupTab = Tables[i];
       bGroup = true
     }
     else
     if ($(Tables[i]).hasClass("withFilter") || bGroup == true){
       Tables[i].setAttribute( "id", "Filtertabell" + tableIndex );
       bFilter = true;
     } else
       bGroup = false;

     if (bGroup && bFilter) {
       createFilterCheckboxes( groupTab, tableIndex);
       tableIndex++;
       bGroup = bFilter = false;
     }
   }
 }

 jQuery( document ).ready( createFilterButtons );