Difference between revisions of "MediaWiki:Common.js"

From LIMSWiki
Jump to navigationJump to search
(Removed secondary script call.)
 
(25 intermediate revisions by 2 users not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */


/*
/* Return whether a particular class is used**************************************
* Table sorting script based on one (c) 1997-2006 Stuart Langridge and Joost
  * Description: Uses regular expressions and caching for better performance.
* de Valk:
* http://www.joostdevalk.nl/code/sortable-table/
* http://www.kryogenix.org/code/browser/sorttable/
*
* @todo don't break on colspans/rowspans (bug 8028)
* @todo language-specific digit grouping/decimals (bug 8063)
  * @todo support all accepted date formats (bug 8226)
  */
  */
var usesClass = (function () {
    var reCache = {};
    return function (element, className) {
        return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
    };
})();


window.ts_image_path = stylepath + '/common/images/';
/**
window.ts_image_up = 'sort_up.gif';
* Collapsible tables; reimplemented with mw-collapsible
window.ts_image_down = 'sort_down.gif';
* Styling is also in place to avoid FOUC
window.ts_image_none = 'sort_none.gif';
*
window.ts_europeandate = wgContentLanguage != 'en'; // The non-American-inclined can change to "true"
* Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].
window.ts_alternate_row_colors = false;
* @version 3.0.0 (2018-05-20)
window.ts_number_transform_table = null;
* @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
window.ts_number_regex = null;
* @author [[User:R. Koot]]
* @author [[User:Krinkle]]
* @author [[User:TheDJ]]
* @deprecated Since MediaWiki 1.20: Use class="mw-collapsible" instead which
* is supported in MediaWiki core. Shimmable since MediaWiki 1.32
*/
function makeCollapsibleMwCollapsible( $content ) {
var $tables = $content
.find( 'table.collapsible:not(.mw-collapsible)' )
.addClass( 'mw-collapsible' );


window.sortables_init = function() {
$.each( $tables, function( index, table ) {
var idnum = 0;
// mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');
// Find all tables with class sortable and make them sortable
if( $( table ).hasClass( 'collapsed') ) {
var tables = getElementsByClassName( document, 'table', 'sortable' );
$( table ).addClass( 'mw-collapsed' );
for ( var ti = 0; ti < tables.length ; ti++ ) {
// mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');
if ( !tables[ti].id ) {
tables[ti].setAttribute( 'id', 'sortable_table_id_' + idnum );
++idnum;
}
}
ts_makeSortable( tables[ti] );
} );
if( $tables.length > 0 ) {
mw.loader.using( 'jquery.makeCollapsible' ).then( function() {
$tables.makeCollapsible();
} );
}
}
}
}
mw.hook( 'wikipage.content' ).add( makeCollapsibleMwCollapsible );


window.ts_makeSortable = function( table ) {
/**
var firstRow;
* Add support to mw-collapsible for autocollapse, innercollapse and outercollapse
if ( table.rows && table.rows.length > 0 ) {
*
if ( table.tHead && table.tHead.rows.length > 0 ) {
* Maintainers: TheDJ
firstRow = table.tHead.rows[table.tHead.rows.length-1];
*/
} else {
function mwCollapsibleSetup( $collapsibleContent ) {
firstRow = table.rows[0];
var $element,
$toggle,
autoCollapseThreshold = 2;
$.each( $collapsibleContent, function (index, element) {
$element = $( element );
if ( $element.hasClass( 'collapsible' ) ) {
$element.find('tr:first > th:first').prepend( $element.find('tr:first > * > .mw-collapsible-toggle'));
}
}
}
if ( $collapsibleContent.length >= autoCollapseThreshold && $element.hasClass( 'autocollapse' ) ) {
if ( !firstRow ) {
$element.data( 'mw-collapsible' ).collapse();
return;
} else if ( $element.hasClass( 'innercollapse' ) ) {
}
if ( $element.parents( '.outercollapse' ).length > 0 ) {
 
$element.data( 'mw-collapsible' ).collapse();
// We have a first row: assume it's the header, and make its contents clickable links
}
for ( var i = 0; i < firstRow.cells.length; i++ ) {
}
var cell = firstRow.cells[i];
// because of colored backgrounds, style the link in the text color
if ( (' ' + cell.className + ' ').indexOf(' unsortable ') == -1 ) {
// to ensure accessible contrast
$(cell).append ( '<a href="#" class="sortheader" '
$toggle = $element.find( '.mw-collapsible-toggle' );
+ 'onclick="ts_resortTable(this);return false;">'
if ( $toggle.length ) {
+ '<span class="sortarrow">'
// Make the toggle inherit text color
+ '<img src="'
if( $toggle.parent()[0].style.color ) {
+ ts_image_path
$toggle.find( 'a' ).css( 'color', 'inherit' );
+ ts_image_none
}
+ '" alt="&darr;"/></span></a>');
}
}
}
} );
if ( ts_alternate_row_colors ) {
ts_alternate( table );
}
}
}


window.ts_getInnerText = function( el ) {
mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );
return getInnerText( el );
}


window.ts_resortTable = function( lnk ) {
/**
// get the span
* Dynamic Navigation Bars (experimental)
var span = lnk.getElementsByTagName('span')[0];
*
* Description: See [[Wikipedia:NavFrame]].
* Maintainers: UNMAINTAINED
*/
var collapseCaption = 'hide';
var expandCaption = 'show';


var td = lnk.parentNode;
// Set up the words in your language
var tr = td.parentNode;
var navigationBarHide = '[' + collapseCaption + ']';
var column = td.cellIndex;
var navigationBarShow = '[' + expandCaption + ']';


var table = tr.parentNode;
/**
while ( table && !( table.tagName && table.tagName.toLowerCase() == 'table' ) ) {
* Shows and hides content and picture (if available) of navigation bars.
table = table.parentNode;
*
}
* @param {number} indexNavigationBar The index of navigation bar to be toggled
if ( !table ) {
* @param {jQuery.Event} event Event object
return;
*/
}
function toggleNavigationBar( indexNavigationBar, event ) {
var navToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
var navFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
var navChild;


if ( table.rows.length <= 1 ) {
if ( !navFrame || !navToggle ) {
return;
return false;
}
}


// Generate the number transform table if it's not done already
// If shown now
if ( ts_number_transform_table === null ) {
if ( navToggle.firstChild.data === navigationBarHide ) {
ts_initTransformTable();
for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
}
if ( $( navChild ).hasClass( 'NavContent' ) ) {
 
navChild.style.display = 'none';
// Work out a type for the column
}
// Skip the first row if that's where the headings are
var rowStart = ( table.tHead && table.tHead.rows.length > 0 ? 0 : 1 );
var bodyRows = 0;
if (rowStart == 0 && table.tBodies) {
for (var i=0; i < table.tBodies.length; i++ ) {
bodyRows += table.tBodies[i].rows.length;
}
}
if (bodyRows < table.rows.length)
navToggle.firstChild.data = navigationBarShow;
rowStart = 1;
}
var itm = '';
// If hidden now
for ( var i = rowStart; i < table.rows.length; i++ ) {
} else if ( navToggle.firstChild.data === navigationBarShow ) {
if ( table.rows[i].cells.length > column ) {
for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
itm = ts_getInnerText(table.rows[i].cells[column]);
if ( $( navChild ).hasClass( 'NavContent' ) ) {
itm = itm.replace(/^[\s\xa0]+/, '').replace(/[\s\xa0]+$/, '');
navChild.style.display = 'block';
if ( itm != '' ) {
break;
}
}
}
}
navToggle.firstChild.data = navigationBarHide;
}
}


// TODO: bug 8226, localised date formats
event.preventDefault();
var sortfn = ts_sort_generic;
}
var preprocessor = ts_toLowerCase;
if ( /^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/.test( itm ) ) {
preprocessor = ts_dateToSortKey;
} else if ( /^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/.test( itm ) ) {
preprocessor = ts_dateToSortKey;
} else if ( /^\d\d[\/.-]\d\d[\/.-]\d\d$/.test( itm ) ) {
preprocessor = ts_dateToSortKey;
// (minus sign)([pound dollar euro yen currency]|cents)
} else if ( /(^([-\u2212] *)?[\u00a3$\u20ac\u00a4\u00a5]|\u00a2$)/.test( itm ) ) {
preprocessor = ts_currencyToSortKey;
} else if ( ts_number_regex.test( itm ) ) {
preprocessor = ts_parseFloat;
}


var reverse = ( span.getAttribute( 'sortdir' ) == 'down' );
/**
* Adds show/hide-button to navigation bars.
*
* @param {jQuery} $content
*/
function createNavigationBarToggleButton( $content ) {
var i, j, navChild, navToggle, navToggleText, isCollapsed,
indexNavigationBar = 0;
// Iterate over all < div >-elements
var $divs = $content.find( 'div.NavFrame:not(.mw-collapsible)' );
$divs.each( function ( i, navFrame ) {
indexNavigationBar++;
navToggle = document.createElement( 'a' );
navToggle.className = 'NavToggle';
navToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
navToggle.setAttribute( 'href', '#' );
$( navToggle ).on( 'click', $.proxy( toggleNavigationBar, null, indexNavigationBar ) );


var newRows = new Array();
isCollapsed = $( navFrame ).hasClass( 'collapsed' );
var staticRows = new Array();
/**
for ( var j = rowStart; j < table.rows.length; j++ ) {
* Check if any children are already hidden.  This loop is here for backwards compatibility:
var row = table.rows[j];
* the old way of making NavFrames start out collapsed was to manually add style="display:none"
if( (' ' + row.className + ' ').indexOf(' unsortable ') < 0 ) {
* to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
var keyText = ts_getInnerText( row.cells[column] );
* the content visible without JavaScript support), the new recommended way is to add the class
if( keyText === undefined ) {
* "collapsed" to the NavFrame itself, just like with collapsible tables.
keyText = '';  
*/
for ( navChild = navFrame.firstChild; navChild !== null && !isCollapsed; navChild = navChild.nextSibling ) {
if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
if ( navChild.style.display === 'none' ) {
isCollapsed = true;
}
}
}
var oldIndex = ( reverse ? -j : j );
}
var preprocessed = preprocessor( keyText.replace(/^[\s\xa0]+/, '').replace(/[\s\xa0]+$/, '') );
if ( isCollapsed ) {
for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
navChild.style.display = 'none';
}
}
}
navToggleText = document.createTextNode( isCollapsed ? navigationBarShow : navigationBarHide );
navToggle.appendChild( navToggleText );


newRows[newRows.length] = new Array( row, preprocessed, oldIndex );
// Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
} else {
for ( j = 0; j < navFrame.childNodes.length; j++ ) {
staticRows[staticRows.length] = new Array( row, false, j-rowStart );
if ( $( navFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
navToggle.style.color = navFrame.childNodes[j].style.color;
navFrame.childNodes[j].appendChild( navToggle );
}
}
}
}
navFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
} );
}


newRows.sort( sortfn );
mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );


var arrowHTML;
/* JavaScript for rounding borders
if ( reverse ) {
  Source: http://webdesign.html.it/articoli/leggi/528/more-nifty-corners */
arrowHTML = '<img src="' + ts_image_path + ts_image_down + '" alt="&darr;"/>';
newRows.reverse();
span.setAttribute( 'sortdir', 'up' );
} else {
arrowHTML = '<img src="' + ts_image_path + ts_image_up + '" alt="&uarr;"/>';
span.setAttribute( 'sortdir', 'down' );
}


for ( var i = 0; i < staticRows.length; i++ ) {
function NiftyCheck(){
var row = staticRows[i];
if(!document.getElementById || !document.createElement)
newRows.splice( row[2], 0, row );
    return(false);
}
isXHTML=/html\:/.test(document.getElementsByTagName('body')[0].nodeName);
if(Array.prototype.push==null){Array.prototype.push=function(){
      this[this.length]=arguments[0]; return(this.length);}}
return(true);
}


// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
function Rounded(selector, wich, bk, color, opt) {
// don't do sortbottom rows
    var i, prefixt, prefixb, cn = "r", ecolor = "", edges = !1, eclass = "", b = !1, t = !1;
for ( var i = 0; i < newRows.length; i++ ) {
    if (color == "transparent") {
if ( ( ' ' + newRows[i][0].className + ' ').indexOf(' sortbottom ') == -1 ) {
        cn = cn + "x";
table.tBodies[0].appendChild( newRows[i][0] );
        ecolor = bk;
}
        bk = "transparent";
}
    } else if (opt && opt.indexOf("border") >= 0) {
// do sortbottom rows only
        var optar = opt.split(" ");
for ( var i = 0; i < newRows.length; i++ ) {
        for (i = 0; i < optar.length; i++)
if ( ( ' ' + newRows[i][0].className + ' ').indexOf(' sortbottom ') != -1 ) {
            if (optar[i].indexOf("#") >= 0)
table.tBodies[0].appendChild( newRows[i][0] );
                ecolor = optar[i];
}
        if (ecolor == "")
}
            ecolor = "#666";
        cn += "e";
        edges = !0;
    } else if (opt && opt.indexOf("smooth") >= 0) {
        cn += "a";
        ecolor = Mix(bk, color);
    }
    if (opt && opt.indexOf("small") >= 0)
        cn += "s";
    prefixt = cn;
    prefixb = cn;
    if (wich.indexOf("all") >= 0) {
        t = !0;
        b = !0;
    } else if (wich.indexOf("top") >= 0)
        t = "true";
    else if (wich.indexOf("tl") >= 0) {
        t = "true";
        if (wich.indexOf("tr") < 0)
            prefixt += "l";
    } else if (wich.indexOf("tr") >= 0) {
        t = "true";
        prefixt += "r";
    }
    if (wich.indexOf("bottom") >= 0)
        b = !0;
    else if (wich.indexOf("bl") >= 0) {
        b = "true";
        if (wich.indexOf("br") < 0)
            prefixb += "l";
    } else if (wich.indexOf("br") >= 0) {
        b = "true";
        prefixb += "r";
    }
    var v = getElementsBySelector(selector);
    var l = v.length;
    for (i = 0; i < l; i++) {
        if (edges)
            AddBorder(v[i], ecolor);
        if (t)
            AddTop(v[i], bk, color, ecolor, prefixt);
        if (b)
            AddBottom(v[i], bk, color, ecolor, prefixb);
    }
}
function AddBorder(el, bc) {
    var i;
    if (!el.passed) {
        if (el.childNodes.length == 1 && el.childNodes[0].nodeType == 3) {
            var t = el.firstChild.nodeValue;
            el.removeChild(el.lastChild);
            var d = CreateEl("span");
            d.style.display = "block";
            d.appendChild(document.createTextNode(t));
            el.appendChild(d);
        }
        for (i = 0; i < el.childNodes.length; i++) {
            if (el.childNodes[i].nodeType == 1) {
                el.childNodes[i].style.borderLeft = "1px solid " + bc;
                el.childNodes[i].style.borderRight = "1px solid " + bc;
            }
        }
    }
    el.passed = !0;
}
function AddTop(el, bk, color, bc, cn) {
    var i, lim = 4, d = CreateEl("b");
    if (cn.indexOf("s") >= 0)
        lim = 2;
    if (bc)
        d.className = "artop";
    else
        d.className = "rtop";
    d.style.backgroundColor = bk;
    for (i = 1; i <= lim; i++) {
        var x = CreateEl("b");
        x.className = cn + i;
        x.style.backgroundColor = color;
        if (bc)
            x.style.borderColor = bc;
        d.appendChild(x);
    }
    el.style.paddingTop = 0;
    el.insertBefore(d, el.firstChild);
}
function AddBottom(el, bk, color, bc, cn) {
    var i, lim = 4, d = CreateEl("b");
    if (cn.indexOf("s") >= 0)
        lim = 2;
    if (bc)
        d.className = "artop";
    else
        d.className = "rtop";
    d.style.backgroundColor = bk;
    for (i = lim; i > 0; i--) {
        var x = CreateEl("b");
        x.className = cn + i;
        x.style.backgroundColor = color;
        if (bc)
            x.style.borderColor = bc;
        d.appendChild(x);
    }
    el.style.paddingBottom = 0;
    el.appendChild(d);
}
function CreateEl(x) {
    if (isXHTML)
        return (document.createElementNS('http://www.w3.org/1999/xhtml', x));
    else
        return (document.createElement(x));
}
function getElementsBySelector(selector) {
    var i, selid = "", selclass = "", tag = selector, f, s = [], objlist = [];
    if (selector.indexOf(" ") > 0) {
        s = selector.split(" ");
        var fs = s[0].split("#");
        if (fs.length == 1)
            return (objlist);
        f = document.getElementById(fs[1]);
        if (f)
            return (f.getElementsByTagName(s[1]));
        return (objlist);
    }
    if (selector.indexOf("#") > 0) {
        s = selector.split("#");
        tag = s[0];
        selid = s[1];
    }
    if (selid != "") {
        f = document.getElementById(selid);
        if (f)
            objlist.push(f);
        return (objlist);
    }
    if (selector.indexOf(".") > 0) {
        s = selector.split(".");
        tag = s[0];
        selclass = s[1];
    }
    var v = document.getElementsByTagName(tag);
    if (selclass == "")
        return (v);
    for (i = 0; i < v.length; i++) {
        if (v[i].className.indexOf(selclass) >= 0) {
            objlist.push(v[i]);
        }
    }
    return (objlist);
}
function Mix(c1, c2) {
    var i, step1, step2, x, y, r = new Array(3);
    if (c1.length == 4)
        step1 = 1;
    else
        step1 = 2;
    if (c2.length == 4)
        step2 = 1;
    else
        step2 = 2;
    for (i = 0; i < 3; i++) {
        x = parseInt(c1.substr(1 + step1 * i, step1), 16);
        if (step1 == 1)
            x = 16 * x + x;
        y = parseInt(c2.substr(1 + step2 * i, step2), 16);
        if (step2 == 1)
            y = 16 * y + y;
        r[i] = Math.floor((x * 50 + y * 50) / 100);
    }
    return ("#" + r[0].toString(16) + r[1].toString(16) + r[2].toString(16));
}
function doRoundEdges() {
    if (!NiftyCheck())
        return;
    Rounded("div#nifty", "all", "#FFF", "#D4DDFF", "smooth");
}
jQuery(doRoundEdges);
function setStyleById(i, p, v) {
    var n = document.getElementById(i);
    n.style[p] = v;
}
jQuery(performIE);
function performIE() {
    if (-1 != navigator.userAgent.indexOf("MSIE")) {
        var Divs = document.getElementsByTagName("div");
        var divCnt = 0;
        var divID = "";
        if (Divs.length > 0) {
            var CurrDiv = Divs[0];
            var s = "";
            while (Divs.length > divCnt) {
                s = eval("CurrDiv.style.ietop");
                if ((s != "") && (s != null)) {
                    divID = "mapDiv" + divCnt;
                    CurrDiv.setAttribute("id", divID);
                    setStyleById(divID, "top", CurrDiv.style.ietop);
                }
                divCnt++;
                CurrDiv = Divs[divCnt];
            }
        }
    }
}
/**
* Dynamic Navigation Bars (experimental)
*
* Description: See [[Wikipedia:NavFrame]].
* Maintainers: UNMAINTAINED
*/


// Delete any other arrows there may be showing
/* set up the words in your language */
var spans = getElementsByClassName( tr, 'span', 'sortarrow' );
var NavigationBarHide = '[' + collapseCaption + ']';
for ( var i = 0; i < spans.length; i++ ) {
var NavigationBarShow = '[' + expandCaption + ']';
spans[i].innerHTML = '<img src="' + ts_image_path + ts_image_none + '" alt="&darr;"/>';
var indexNavigationBar = 0;
}
span.innerHTML = arrowHTML;
 
if ( ts_alternate_row_colors ) {
ts_alternate( table );
}
}


window.ts_initTransformTable = function() {
/**
if ( typeof wgSeparatorTransformTable == 'undefined'
* Shows and hides content and picture (if available) of navigation bars
|| ( wgSeparatorTransformTable[0] == '' && wgDigitTransformTable[2] == '' ) )
* Parameters:
{
*    indexNavigationBar: the index of navigation bar to be toggled
var digitClass = "[0-9,.]";
**/
ts_number_transform_table = false;
window.toggleNavigationBar = function ( indexNavigationBar, event ) {
} else {
    var NavToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
ts_number_transform_table = {};
    var NavFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
// Unpack the transform table
    var NavChild;
// Separators
var ascii = wgSeparatorTransformTable[0].split("\t");
var localised = wgSeparatorTransformTable[1].split("\t");
for ( var i = 0; i < ascii.length; i++ ) {
ts_number_transform_table[localised[i]] = ascii[i];
}
// Digits
ascii = wgDigitTransformTable[0].split("\t");
localised = wgDigitTransformTable[1].split("\t");
for ( var i = 0; i < ascii.length; i++ ) {
ts_number_transform_table[localised[i]] = ascii[i];
}


// Construct regex for number identification
    if ( !NavFrame || !NavToggle ) {
var digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '\\.'];
        return false;
var maxDigitLength = 1;
    }
for ( var digit in ts_number_transform_table ) {
// Escape regex metacharacters
digits.push(
digit.replace( /[\\\\$\*\+\?\.\(\)\|\{\}\[\]\-]/,
function( s ) { return '\\' + s; } )
);
if ( digit.length > maxDigitLength ) {
maxDigitLength = digit.length;
}
}
if ( maxDigitLength > 1 ) {
var digitClass = '[' + digits.join( '', digits ) + ']';
} else {
var digitClass = '(' + digits.join( '|', digits ) + ')';
}
}


// We allow a trailing percent sign, which we just strip.  This works fine
    /* if shown now */
// if percents and regular numbers aren't being mixed.
    if ( NavToggle.firstChild.data === NavigationBarHide ) {
ts_number_regex = new RegExp(
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
"^(" +
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
"[-+\u2212]?[0-9][0-9,]*(\\.[0-9,]*)?(E[-+\u2212]?[0-9][0-9,]*)?" + // Fortran-style scientific
                NavChild.style.display = 'none';
"|" +
            }
"[-+\u2212]?" + digitClass + "+%?" + // Generic localised
        }
")$", "i"
    NavToggle.firstChild.data = NavigationBarShow;
);
}


window.ts_toLowerCase = function( s ) {
    /* if hidden now */
return s.toLowerCase();
    } else if ( NavToggle.firstChild.data === NavigationBarShow ) {
}
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
                NavChild.style.display = 'block';
            }
        }
        NavToggle.firstChild.data = NavigationBarHide;
    }


window.ts_dateToSortKey = function( date ) {
    event.preventDefault();
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
};
if ( date.length == 11 ) {
switch ( date.substr( 3, 3 ).toLowerCase() ) {
case 'jan':
var month = '01';
break;
case 'feb':
var month = '02';
break;
case 'mar':
var month = '03';
break;
case 'apr':
var month = '04';
break;
case 'may':
var month = '05';
break;
case 'jun':
var month = '06';
break;
case 'jul':
var month = '07';
break;
case 'aug':
var month = '08';
break;
case 'sep':
var month = '09';
break;
case 'oct':
var month = '10';
break;
case 'nov':
var month = '11';
break;
case 'dec':
var month = '12';
break;
// default: var month = '00';
}
return date.substr( 7, 4 ) + month + date.substr( 0, 2 );
} else if ( date.length == 10 ) {
if ( ts_europeandate == false ) {
return date.substr( 6, 4 ) + date.substr( 0, 2 ) + date.substr( 3, 2 );
} else {
return date.substr( 6, 4 ) + date.substr( 3, 2 ) + date.substr( 0, 2 );
}
} else if ( date.length == 8 ) {
var yr = date.substr( 6, 2 );
if ( parseInt( yr ) < 50 ) {
yr = '20' + yr;
} else {
yr = '19' + yr;
}
if ( ts_europeandate == true ) {
return yr + date.substr( 3, 2 ) + date.substr( 0, 2 );
} else {
return yr + date.substr( 0, 2 ) + date.substr( 3, 2 );
}
}
return '00000000';
}


window.ts_parseFloat = function( s ) {
/* adds show/hide-button to navigation bars */
if ( !s ) {
function createNavigationBarToggleButton( $content ) {
return 0;
    var NavChild;
}
    /* iterate over all < div >-elements */
if ( ts_number_transform_table != false ) {
    var $divs = $content.find( 'div' );
var newNum = '', c;
    $divs.each( function ( i, NavFrame ) {
        /* if found a navigation bar */
        if ( $( NavFrame ).hasClass( 'NavFrame' ) ) {


for ( var p = 0; p < s.length; p++ ) {
            indexNavigationBar++;
c = s.charAt( p );
            var NavToggle = document.createElement( 'a' );
if ( c in ts_number_transform_table ) {
            NavToggle.className = 'NavToggle';
newNum += ts_number_transform_table[c];
            NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
} else {
            NavToggle.setAttribute( 'href', '#' );
newNum += c;
            $( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );
}
}
s = newNum;
}
var num = parseFloat( s.replace(/[, ]/g, '').replace("\u2212", '-') );
return ( isNaN( num ) ? -Infinity : num );
}


window.ts_currencyToSortKey = function( s ) {
            var isCollapsed = $( NavFrame ).hasClass( 'collapsed' );
return ts_parseFloat(s.replace(/[^-\u22120-9.,]/g,''));
            /**
}
            * Check if any children are already hidden.  This loop is here for backwards compatibility:
            * the old way of making NavFrames start out collapsed was to manually add style="display:none"
            * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
            * the content visible without JavaScript support), the new recommended way is to add the class
            * "collapsed" to the NavFrame itself, just like with collapsible tables.
            */
            for ( NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling ) {
                if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
                    if ( NavChild.style.display === 'none' ) {
                        isCollapsed = true;
                    }
                }
            }
            if ( isCollapsed ) {
                for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
                    if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
                        NavChild.style.display = 'none';
                    }
                }
            }
            var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide );
            NavToggle.appendChild( NavToggleText );


window.ts_sort_generic = function( a, b ) {
            /* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */
return a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2];
            for( var j = 0; j < NavFrame.childNodes.length; j++ ) {
                if ( $( NavFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
                    NavToggle.style.color = NavFrame.childNodes[j].style.color;
                    NavFrame.childNodes[j].appendChild( NavToggle );
                }
            }
            NavFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
        }
    } );
}
}


window.ts_alternate = function( table ) {
mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );
// Take object table and get all it's tbodies.
var tableBodies = table.getElementsByTagName( 'tbody' );
// Loop through these tbodies
for ( var i = 0; i < tableBodies.length; i++ ) {
// Take the tbody, and get all it's rows
var tableRows = tableBodies[i].getElementsByTagName( 'tr' );
// Loop through these rows
// Start at 1 because we want to leave the heading row untouched
for ( var j = 0; j < tableRows.length; j++ ) {
// Check if j is even, and apply classes for both possible results
var oldClasses = tableRows[j].className.split(' ');
var newClassName = '';
for ( var k = 0; k < oldClasses.length; k++ ) {
if ( oldClasses[k] != '' && oldClasses[k] != 'even' && oldClasses[k] != 'odd' ) {
newClassName += oldClasses[k] + ' ';
}
}
tableRows[j].className = newClassName + ( j % 2 == 0 ? 'even' : 'odd' );
}
}
}


/*
/* Tweak to get CategoryTree extension to have trees expanded by default */
* End of table sorting code
$( document ).ready(function() { $('.CategoryTreeToggle[data-ct-state="collapsed"]').click(); });
*/

Latest revision as of 18:12, 3 August 2021

/* Any JavaScript here will be loaded for all users on every page load. */

/* Return whether a particular class is used**************************************
 * Description: Uses regular expressions and caching for better performance.
 */
 
 var usesClass = (function () {
     var reCache = {};
     return function (element, className) {
         return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
     };
 })();

/**
 * Collapsible tables; reimplemented with mw-collapsible
 * Styling is also in place to avoid FOUC
 * 
 * Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].
 * @version 3.0.0 (2018-05-20)
 * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
 * @author [[User:R. Koot]]
 * @author [[User:Krinkle]]
 * @author [[User:TheDJ]]
 * @deprecated Since MediaWiki 1.20: Use class="mw-collapsible" instead which
 * is supported in MediaWiki core. Shimmable since MediaWiki 1.32
 */
function makeCollapsibleMwCollapsible( $content ) {
	var $tables = $content
		.find( 'table.collapsible:not(.mw-collapsible)' )
		.addClass( 'mw-collapsible' );

	$.each( $tables, function( index, table ) {
		// mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');
		if( $( table ).hasClass( 'collapsed') ) {
			$( table ).addClass( 'mw-collapsed' );
			// mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');
		}
	} );
	if( $tables.length > 0 ) {
		mw.loader.using( 'jquery.makeCollapsible' ).then( function() {
			$tables.makeCollapsible();
		} );
	}
}
mw.hook( 'wikipage.content' ).add( makeCollapsibleMwCollapsible );

/**
 * Add support to mw-collapsible for autocollapse, innercollapse and outercollapse
 *
 * Maintainers: TheDJ
 */
function mwCollapsibleSetup( $collapsibleContent ) {
	var $element,
		$toggle,
		autoCollapseThreshold = 2;
	$.each( $collapsibleContent, function (index, element) {
		$element = $( element );
		if ( $element.hasClass( 'collapsible' ) ) {
			$element.find('tr:first > th:first').prepend( $element.find('tr:first > * > .mw-collapsible-toggle'));
		}
		if ( $collapsibleContent.length >= autoCollapseThreshold && $element.hasClass( 'autocollapse' ) ) {
			$element.data( 'mw-collapsible' ).collapse();
		} else if ( $element.hasClass( 'innercollapse' ) ) {
			if ( $element.parents( '.outercollapse' ).length > 0 ) {
				$element.data( 'mw-collapsible' ).collapse();
			}
		}
		// because of colored backgrounds, style the link in the text color
		// to ensure accessible contrast
		$toggle = $element.find( '.mw-collapsible-toggle' );
		if ( $toggle.length ) {
			// Make the toggle inherit text color
			if( $toggle.parent()[0].style.color ) {
				$toggle.find( 'a' ).css( 'color', 'inherit' );
			}
		}
	} );
}

mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );

/**
 * Dynamic Navigation Bars (experimental)
 *
 * Description: See [[Wikipedia:NavFrame]].
 * Maintainers: UNMAINTAINED
 */
 
var collapseCaption = 'hide';
var expandCaption = 'show';

// Set up the words in your language
var navigationBarHide = '[' + collapseCaption + ']';
var navigationBarShow = '[' + expandCaption + ']';

/**
 * Shows and hides content and picture (if available) of navigation bars.
 *
 * @param {number} indexNavigationBar The index of navigation bar to be toggled
 * @param {jQuery.Event} event Event object
 */
function toggleNavigationBar( indexNavigationBar, event ) {
	var navToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
	var navFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
	var navChild;

	if ( !navFrame || !navToggle ) {
		return false;
	}

	// If shown now
	if ( navToggle.firstChild.data === navigationBarHide ) {
		for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
			if ( $( navChild ).hasClass( 'NavContent' ) ) {
				navChild.style.display = 'none';
			}
		}
		navToggle.firstChild.data = navigationBarShow;
	
	// If hidden now
	} else if ( navToggle.firstChild.data === navigationBarShow ) {
		for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
			if ( $( navChild ).hasClass( 'NavContent' ) ) {
				navChild.style.display = 'block';
			}
		}
		navToggle.firstChild.data = navigationBarHide;
	}

	event.preventDefault();
}

/**
 * Adds show/hide-button to navigation bars.
 *
 * @param {jQuery} $content
 */
function createNavigationBarToggleButton( $content ) {
	var i, j, navChild, navToggle, navToggleText, isCollapsed,
		indexNavigationBar = 0;
	// Iterate over all < div >-elements
	var $divs = $content.find( 'div.NavFrame:not(.mw-collapsible)' );
	$divs.each( function ( i, navFrame ) {
		indexNavigationBar++;
		navToggle = document.createElement( 'a' );
		navToggle.className = 'NavToggle';
		navToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
		navToggle.setAttribute( 'href', '#' );
		$( navToggle ).on( 'click', $.proxy( toggleNavigationBar, null, indexNavigationBar ) );

		isCollapsed = $( navFrame ).hasClass( 'collapsed' );
		/**
		 * Check if any children are already hidden.  This loop is here for backwards compatibility:
		 * the old way of making NavFrames start out collapsed was to manually add style="display:none"
		 * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
		 * the content visible without JavaScript support), the new recommended way is to add the class
		 * "collapsed" to the NavFrame itself, just like with collapsible tables.
		 */
		for ( navChild = navFrame.firstChild; navChild !== null && !isCollapsed; navChild = navChild.nextSibling ) {
			if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
				if ( navChild.style.display === 'none' ) {
					isCollapsed = true;
				}
			}
		}
		if ( isCollapsed ) {
			for ( navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling ) {
				if ( $( navChild ).hasClass( 'NavPic' ) || $( navChild ).hasClass( 'NavContent' ) ) {
					navChild.style.display = 'none';
				}
			}
		}
		navToggleText = document.createTextNode( isCollapsed ? navigationBarShow : navigationBarHide );
		navToggle.appendChild( navToggleText );

		// Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
		for ( j = 0; j < navFrame.childNodes.length; j++ ) {
			if ( $( navFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
				navToggle.style.color = navFrame.childNodes[j].style.color;
				navFrame.childNodes[j].appendChild( navToggle );
			}
		}
		navFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
	} );
}

mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );

/* JavaScript for rounding borders
   Source: http://webdesign.html.it/articoli/leggi/528/more-nifty-corners */

function NiftyCheck(){
if(!document.getElementById || !document.createElement)
    return(false);
isXHTML=/html\:/.test(document.getElementsByTagName('body')[0].nodeName);
if(Array.prototype.push==null){Array.prototype.push=function(){
      this[this.length]=arguments[0]; return(this.length);}}
return(true);
}

function Rounded(selector, wich, bk, color, opt) {
    var i, prefixt, prefixb, cn = "r", ecolor = "", edges = !1, eclass = "", b = !1, t = !1;
    if (color == "transparent") {
        cn = cn + "x";
        ecolor = bk;
        bk = "transparent";
    } else if (opt && opt.indexOf("border") >= 0) {
        var optar = opt.split(" ");
        for (i = 0; i < optar.length; i++)
            if (optar[i].indexOf("#") >= 0)
                ecolor = optar[i];
        if (ecolor == "")
            ecolor = "#666";
        cn += "e";
        edges = !0;
    } else if (opt && opt.indexOf("smooth") >= 0) {
        cn += "a";
        ecolor = Mix(bk, color);
    }
    if (opt && opt.indexOf("small") >= 0)
        cn += "s";
    prefixt = cn;
    prefixb = cn;
    if (wich.indexOf("all") >= 0) {
        t = !0;
        b = !0;
    } else if (wich.indexOf("top") >= 0)
        t = "true";
    else if (wich.indexOf("tl") >= 0) {
        t = "true";
        if (wich.indexOf("tr") < 0)
            prefixt += "l";
    } else if (wich.indexOf("tr") >= 0) {
        t = "true";
        prefixt += "r";
    }
    if (wich.indexOf("bottom") >= 0)
        b = !0;
    else if (wich.indexOf("bl") >= 0) {
        b = "true";
        if (wich.indexOf("br") < 0)
            prefixb += "l";
    } else if (wich.indexOf("br") >= 0) {
        b = "true";
        prefixb += "r";
    }
    var v = getElementsBySelector(selector);
    var l = v.length;
    for (i = 0; i < l; i++) {
        if (edges)
            AddBorder(v[i], ecolor);
        if (t)
            AddTop(v[i], bk, color, ecolor, prefixt);
        if (b)
            AddBottom(v[i], bk, color, ecolor, prefixb);
    }
}
function AddBorder(el, bc) {
    var i;
    if (!el.passed) {
        if (el.childNodes.length == 1 && el.childNodes[0].nodeType == 3) {
            var t = el.firstChild.nodeValue;
            el.removeChild(el.lastChild);
            var d = CreateEl("span");
            d.style.display = "block";
            d.appendChild(document.createTextNode(t));
            el.appendChild(d);
        }
        for (i = 0; i < el.childNodes.length; i++) {
            if (el.childNodes[i].nodeType == 1) {
                el.childNodes[i].style.borderLeft = "1px solid " + bc;
                el.childNodes[i].style.borderRight = "1px solid " + bc;
            }
        }
    }
    el.passed = !0;
}
function AddTop(el, bk, color, bc, cn) {
    var i, lim = 4, d = CreateEl("b");
    if (cn.indexOf("s") >= 0)
        lim = 2;
    if (bc)
        d.className = "artop";
    else
        d.className = "rtop";
    d.style.backgroundColor = bk;
    for (i = 1; i <= lim; i++) {
        var x = CreateEl("b");
        x.className = cn + i;
        x.style.backgroundColor = color;
        if (bc)
            x.style.borderColor = bc;
        d.appendChild(x);
    }
    el.style.paddingTop = 0;
    el.insertBefore(d, el.firstChild);
}
function AddBottom(el, bk, color, bc, cn) {
    var i, lim = 4, d = CreateEl("b");
    if (cn.indexOf("s") >= 0)
        lim = 2;
    if (bc)
        d.className = "artop";
    else
        d.className = "rtop";
    d.style.backgroundColor = bk;
    for (i = lim; i > 0; i--) {
        var x = CreateEl("b");
        x.className = cn + i;
        x.style.backgroundColor = color;
        if (bc)
            x.style.borderColor = bc;
        d.appendChild(x);
    }
    el.style.paddingBottom = 0;
    el.appendChild(d);
}
function CreateEl(x) {
    if (isXHTML)
        return (document.createElementNS('http://www.w3.org/1999/xhtml', x));
    else
        return (document.createElement(x));
}
function getElementsBySelector(selector) {
    var i, selid = "", selclass = "", tag = selector, f, s = [], objlist = [];
    if (selector.indexOf(" ") > 0) {
        s = selector.split(" ");
        var fs = s[0].split("#");
        if (fs.length == 1)
            return (objlist);
        f = document.getElementById(fs[1]);
        if (f)
            return (f.getElementsByTagName(s[1]));
        return (objlist);
    }
    if (selector.indexOf("#") > 0) {
        s = selector.split("#");
        tag = s[0];
        selid = s[1];
    }
    if (selid != "") {
        f = document.getElementById(selid);
        if (f)
            objlist.push(f);
        return (objlist);
    }
    if (selector.indexOf(".") > 0) {
        s = selector.split(".");
        tag = s[0];
        selclass = s[1];
    }
    var v = document.getElementsByTagName(tag);
    if (selclass == "")
        return (v);
    for (i = 0; i < v.length; i++) {
        if (v[i].className.indexOf(selclass) >= 0) {
            objlist.push(v[i]);
        }
    }
    return (objlist);
}
function Mix(c1, c2) {
    var i, step1, step2, x, y, r = new Array(3);
    if (c1.length == 4)
        step1 = 1;
    else
        step1 = 2;
    if (c2.length == 4)
        step2 = 1;
    else
        step2 = 2;
    for (i = 0; i < 3; i++) {
        x = parseInt(c1.substr(1 + step1 * i, step1), 16);
        if (step1 == 1)
            x = 16 * x + x;
        y = parseInt(c2.substr(1 + step2 * i, step2), 16);
        if (step2 == 1)
            y = 16 * y + y;
        r[i] = Math.floor((x * 50 + y * 50) / 100);
    }
    return ("#" + r[0].toString(16) + r[1].toString(16) + r[2].toString(16));
}
function doRoundEdges() {
    if (!NiftyCheck())
        return;
    Rounded("div#nifty", "all", "#FFF", "#D4DDFF", "smooth");
}
jQuery(doRoundEdges);
function setStyleById(i, p, v) {
    var n = document.getElementById(i);
    n.style[p] = v;
}
jQuery(performIE);
function performIE() {
    if (-1 != navigator.userAgent.indexOf("MSIE")) {
        var Divs = document.getElementsByTagName("div");
        var divCnt = 0;
        var divID = "";
        if (Divs.length > 0) {
            var CurrDiv = Divs[0];
            var s = "";
            while (Divs.length > divCnt) {
                s = eval("CurrDiv.style.ietop");
                if ((s != "") && (s != null)) {
                    divID = "mapDiv" + divCnt;
                    CurrDiv.setAttribute("id", divID);
                    setStyleById(divID, "top", CurrDiv.style.ietop);
                }
                divCnt++;
                CurrDiv = Divs[divCnt];
            }
        }
    }
}
 
/**
 * Dynamic Navigation Bars (experimental)
 *
 * Description: See [[Wikipedia:NavFrame]].
 * Maintainers: UNMAINTAINED
 */

/* set up the words in your language */
var NavigationBarHide = '[' + collapseCaption + ']';
var NavigationBarShow = '[' + expandCaption + ']';
var indexNavigationBar = 0;

/**
 * Shows and hides content and picture (if available) of navigation bars
 * Parameters:
 *     indexNavigationBar: the index of navigation bar to be toggled
 **/
window.toggleNavigationBar = function ( indexNavigationBar, event ) {
    var NavToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
    var NavFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
    var NavChild;

    if ( !NavFrame || !NavToggle ) {
        return false;
    }

    /* if shown now */
    if ( NavToggle.firstChild.data === NavigationBarHide ) {
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
                NavChild.style.display = 'none';
            }
        }
    NavToggle.firstChild.data = NavigationBarShow;

    /* if hidden now */
    } else if ( NavToggle.firstChild.data === NavigationBarShow ) {
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
                NavChild.style.display = 'block';
            }
        }
        NavToggle.firstChild.data = NavigationBarHide;
    }

    event.preventDefault();
};

/* adds show/hide-button to navigation bars */
function createNavigationBarToggleButton( $content ) {
    var NavChild;
    /* iterate over all < div >-elements */
    var $divs = $content.find( 'div' );
    $divs.each( function ( i, NavFrame ) {
        /* if found a navigation bar */
        if ( $( NavFrame ).hasClass( 'NavFrame' ) ) {

            indexNavigationBar++;
            var NavToggle = document.createElement( 'a' );
            NavToggle.className = 'NavToggle';
            NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
            NavToggle.setAttribute( 'href', '#' );
            $( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );

            var isCollapsed = $( NavFrame ).hasClass( 'collapsed' );
            /**
             * Check if any children are already hidden.  This loop is here for backwards compatibility:
             * the old way of making NavFrames start out collapsed was to manually add style="display:none"
             * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
             * the content visible without JavaScript support), the new recommended way is to add the class
             * "collapsed" to the NavFrame itself, just like with collapsible tables.
             */
            for ( NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling ) {
                if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
                    if ( NavChild.style.display === 'none' ) {
                        isCollapsed = true;
                    }
                }
            }
            if ( isCollapsed ) {
                for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
                    if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
                        NavChild.style.display = 'none';
                    }
                }
            }
            var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide );
            NavToggle.appendChild( NavToggleText );

            /* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */
            for( var j = 0; j < NavFrame.childNodes.length; j++ ) {
                if ( $( NavFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
                    NavToggle.style.color = NavFrame.childNodes[j].style.color;
                    NavFrame.childNodes[j].appendChild( NavToggle );
                }
            }
            NavFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
        }
    } );
}

mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );

/* Tweak to get CategoryTree extension to have trees expanded by default */
$( document ).ready(function() { $('.CategoryTreeToggle[data-ct-state="collapsed"]').click(); });