Difference between revisions of "MediaWiki:Common.js"

From Observer GigaFlow Support | VIAVI Solutions Inc.
Jump to: navigation, search
 
(3 intermediate revisions by one user 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. */
 +
 +
(function ($, mw, store) {
 +
    "use strict";
 +
    var articles;
 +
 +
    if (store && store.getItem('commonjs')) {
 +
        console.log('You have chosen to disable site-wide JavaScript ' +
 +
                    'in MediaWiki:Common.js. Please remove \'commonjs\' ' +
 +
                    'from localStorage to re-enable site-wide JavaScript.');
 +
        return;
 +
    }
 +
 +
    window.UserTagsJS = {
 +
modules: {},
 +
tags: {
 +
          heroicuser:  { u:'Most Heroic Contributor' },
 +
          imageeditor: { u:'Image Editor' },
 +
          retired: { u:'Retired Clasher' },
 +
        }
 +
    };
 +
    UserTagsJS.modules.custom        = {};
 +
    UserTagsJS.modules.inactive      = 30;
 +
    UserTagsJS.modules.newuser      = true;
 +
    UserTagsJS.modules.autoconfirmed = true;
 +
 +
    UserTagsJS.modules.mwGroups = [
 +
        'bureaucrat',
 +
        'sysop',
 +
        'chatmoderator',
 +
        'threadmoderator',
 +
        'rollback',
 +
        'patroller',
 +
        'bannedfromchat',
 +
        'bot',
 +
        'bot-global',
 +
    ];
  
$(function () {
+
    UserTagsJS.modules.metafilter = {
 +
        bureaucrat:      ['founder'],
 +
        sysop:          ['founder', 'bureaucrat'],
 +
        chatmoderator:  ['founder', 'bureaucrat', 'sysop'],
 +
        threadmoderator: ['founder', 'bureaucrat', 'sysop', 'chatmoderator'],
 +
        imageeditor:    ['founder', 'bureaucrat', 'sysop', 'chatmoderator', 'threadmoderator'],
 +
        rollback:        ['founder', 'bureaucrat', 'sysop', 'chatmoderator', 'threadmoderator',
 +
                          'imageeditor'],
 +
    };
 +
 +
    UserTagsJS.modules.custom = {
 +
        'FaceBound': ['imageeditor'], // Image Editor
 +
    };
  
  var myElement = document.getElementById('calculator');
+
    if (typeof(window.SpoilerAlert) === 'undefined') {
  myElement.innerHTML = 'any HTML';
+
        window.SpoilerAlert = {
 +
            question: 'Chief! This page contains sneak peeks. Are you sure you ' +
 +
                      'want to enter?',
 +
            yes: 'Yes, please',
 +
            no: 'No, let it be a surprise',
 +
            isSpoiler: function () {
 +
                return (-1 !== wgCategories.indexOf('Spoiler') &&
 +
                    Boolean($('.spoiler').length));
 +
            }
 +
        };
 +
    }
  
}());
+
    window.LockForums = {
 +
        expiryDays:    90,  // Number of days until forum is locked to new replies
 +
        expiryMessage: 'Forums are automatically locked when the most recent post is older than <expiryDays> days.',
 +
        warningDays:  14,  // Number of days until a warning is given to potential replies
 +
        ignoreDeletes: true, // Ignore deleted messages when calculating age of last post
 +
        warningPopup:  true, // Pop up a warning dialog that must be confirmed for posts on older forums
 +
        banners:      true, // Add a banner to the top of aged forums
 +
    };
  
$(function () {
+
    /* Articles are interwiki links so that other wikis can use them. */
  $('#calculator').html('any HTML');
+
    articles = [
}());
+
        'w:c:spottra:MediaWiki:Common.js/Numeral.js', // Defines num.format('<fmt>')
 +
        'w:c:spottra:MediaWiki:Common.js/AjaxGallery.js',
 +
        'u:dev:Countdown/code.js',
 +
        'u:dev:SpoilerAlert/code.js',
 +
        'u:dev:TopEditors/code.js',
 +
        'u:dev:WallGreetingButton/code.js',
 +
        'u:dev:ExtendedNavigation/code.js',
 +
        'u:dev:LockForums/code.js',
 +
        'u:dev:LockOldBlogs/code.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/RGBColor.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/Usernames.js',
 +
        'u:dev:UserTags/code.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/Sliders.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/GemCalculators.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/Experience.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/TroopInfo.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/BuildingInfo.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/AchievementInfo.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/Tabber2.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/ImageHover.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/CumulativeCosts.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/UnitComparator.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/ModeToggle.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/PageVerify.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/GorillaMan.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/Lugia.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/BadgeGenerator.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/Protection.js',
 +
        'w:c:clashofclans:MediaWiki:Common.js/AvailableBuildings.js',
 +
    ];
 +
    // Use Wikia's importArticles() function to load JavaScript files
 +
    window.importArticles({
 +
        type: 'script',
 +
        articles: articles
 +
    });
 +
    console.log('Site-wide JavaScript in MediaWiki:Common.js will load the ' +
 +
                'following JavaScript files:\n  ' + articles.join('\n  '));
  
 +
    // Moves Clash Royale link to page header
 +
    $('#ClashRoyaleLink').appendTo('header#WikiaPageHeader');
 +
}(jQuery, mediaWiki, window.localStorage));
  
$(function () {
+
// Change Random Page button to only go to pages in the mainspace
  $('#mw-mywiki-example').html('<div align="center">
+
    $('.wds-dropdown a[data-tracking=explore-random], ul.tools li a[data-name=random]').attr("href", "/wiki/Special:Random/main");
            <table width="80%" border="4">
+
                <tr><td colspan="2" align="center">Server Requirements</td></tr>
+
                <tr><td>Devices</td><td><input type="range" id="devices" value="10" min="10" max="1000" step="10" onchange="printSliderValue()" oninput="printSliderValue()"><input id="devicesvalue" type="text" size="5"></td></tr>
+
                <tr><td>Max Flows/second</td><td><input type="range" id="flows" value="1000" min="1000" max="50000" step="1000" onchange="printSliderValue()" oninput="printSliderValue()"><input id="flowsvalue" type="text" size="4"></td></tr>
+
            </table>
+
        </div>
+
        <div align="center">
+
            <table width="80%" border="4">
+
                <tr><td colspan="2" align="center">IO</td></tr>
+
                <tr><td><table ><thead><tr><th>Type</th><th>Requirement</th><th>Calculation</th></tr></thead>
+
                            <tr><td>Write MB/s</td><td><input type="text" id="writembps" size="6" disabled/></td><td>FlowsPerSecond*600Bytes</td></tr>
+
                            <tr><td>Write IOP/s</td><td><input type="text" id="writeiops" size="6" disabled/></td><td>20+(FlowsPerSecond/500)+(Devices/5)</td></tr>
+
                        </table></td></tr>
+
            </table>
+
        </div>
+
        <div align="center">
+
            <table width="80%" border="4">
+
                <tr><td colspan="2" align="center">Min Storage Required GB</td></tr>
+
                <tr><td><table><thead><tr><th>Type</th><th>Hour</th><th>Day</th><th>Week</th><th>Month</th><th>3 Months</th><th>Year</th></tr></thead>
+
                            <tr><td>Forensics Total</td><td><input type="text" id="forensicsh" size="6" disabled/></td><td><input type="text" id="forensicsd" size="6" disabled/></td><td><input type="text" id="forensicsw" size="6" disabled/></td><td><input type="text" id="forensicsm" size="6" disabled/></td><td><input type="text" id="forensicsq" size="6" disabled/></td><td><input type="text" id="forensicsy" size="6" disabled/></td></tr>
+
                            <tr><td>Forensics Per Device</td><td><input type="text" id="forensicshpd" size="6" disabled/></td><td><input type="text" id="forensicsdpd" size="6" disabled/></td><td><input type="text" id="forensicswpd" size="6" disabled/></td><td><input type="text" id="forensicsmpd" size="6" disabled/></td><td><input type="text" id="forensicsqpd" size="6" disabled/></td><td><input type="text" id="forensicsypd" size="6" disabled/></td></tr>
+
                        </table></td></tr>
+
            </table>
+
        </div>
+
        <div align="center">
+
            <table width="80%" border="4">
+
                <tr><td colspan="2" align="center">Min Memory Required GB</td><td><input type="text" id="memoryrequired"  size="6" disabled/></td></tr>
+
                <tr><td colspan="2" align="center">Min Cores Required</td><td><input type="text" id="coresrequired"  size="2" disabled/></td></tr>
+
  
            </table>
+
/** Collapsible tables *********************************************************
        </div>
+
*
        <script>
+
*  Description: Allows tables to be collapsed, showing only the header. See
            printSliderValue('devices', 'devicesvalue');
+
*  http://www.mediawiki.org/wiki/Manual:Collapsible_tables.
            printSliderValue('flows', 'flowsvalue');
+
*  Maintainers: [[en:User:R. Koot]]
        </script>
+
*/
');
+
var autoCollapse    = 2;
 +
var collapseCaption = 'hide';
 +
var expandCaption  = 'show';
 +
 +
function collapseTable(tableIndex) {
 +
  var Button = document.getElementById('collapseButton'   + tableIndex);
 +
  var Table  = document.getElementById('collapsibleTable' + tableIndex);
 +
 +
  if (!Table || !Button)
 +
      return false;
 +
 +
  var Rows = Table.rows;
 +
 +
  if (Button.firstChild.data == collapseCaption) {
 +
      for (var i = 1; i < Rows.length; i ++)
 +
        Rows[i].style.display = 'none';
  
 +
      Button.firstChild.data = expandCaption;
 +
  }
 +
  else {
 +
      for (var i = 1; i < Rows.length; i ++)
 +
        Rows[i].style.display = Rows[0].style.display;
  
 +
      Button.firstChild.data = collapseCaption;
 +
  }
 +
}
 +
 +
function createCollapseButtons() {
 +
  var tableIndex      = 0;
 +
  var NavigationBoxes = new Object();
 +
  var Tables          = document.getElementsByTagName('table');
 +
 +
  for (var i = 0; i < Tables.length; i ++) {
 +
      if (hasClass(Tables[i], 'collapsible')) {
 +
        /* only add button and increment count if there is a header row
 +
            to work with */
 +
        var HeaderRow = Tables[i].getElementsByTagName('tr')[0];
  
            function checkSizes() {
+
        if (!HeaderRow)
                var devices = document.getElementById("devices");
+
            continue;
                var maxallowedflows = 50000 - (25 * (parseInt(devices.value) - 20))
+
 
                var flows = document.getElementById("flows");
+
        var Header = HeaderRow.getElementsByTagName('th')[0];
                if (parseInt(flows.value) > maxallowedflows) {
+
 
                    flows.value = maxallowedflows;
+
        if (!Header)
                    document.getElementById("flowsvalue").value = maxallowedflows;
+
            continue;
                }
+
 
                if (parseInt(flows.value) > 20000 || parseInt(devices.value) > 50) {
+
        NavigationBoxes[tableIndex] = Tables[i];
                    document.getElementById("coresrequired").value = 16;
+
        Tables[i].setAttribute('id', 'collapsibleTable' + tableIndex);
                } else {
+
                    document.getElementById("coresrequired").value = 8;
+
        var Button    = document.createElement('span');
                }
+
        var ButtonLink = document.createElement('a');
            }
+
        var ButtonText = document.createTextNode(collapseCaption);
            function printSliderValue() {
+
                checkSizes();
+
        // Styles are declared in [[MediaWiki:Common.css]]
                document.getElementById("flowsvalue").value = document.getElementById("flows").value;
+
        Button.className = 'collapseButton';
                document.getElementById("devicesvalue").value = document.getElementById("devices").value;
+
                var dayrate = (parseInt(document.getElementById("flowsvalue").value)) / (1000 * 1000) * 60 * 60 * 24 * .25;
+
        ButtonLink.style.color = Header.style.color;
        document.getElementById("writembps").value = ((parseInt(flows.value)*.6)/1000).toFixed(2);      
+
        ButtonLink.setAttribute('id', 'collapseButton' + tableIndex);
        document.getElementById("writeiops").value = (20+((parseInt(flows.value)/500))+(devices.value/5)).toFixed(2);      
+
        ButtonLink.setAttribute('href',
       
+
            "javascript:collapseTable(" + tableIndex + ");" );
       
+
        ButtonLink.appendChild(ButtonText);
        document.getElementById("forensicsh").value = (Math.ceil(dayrate) / 24).toFixed(2);
+
                document.getElementById("forensicsd").value = (Math.ceil(dayrate)).toFixed(2);
+
        Button.appendChild(document.createTextNode('['));
                document.getElementById("forensicsw").value = (Math.ceil(dayrate * 7)).toFixed(2);
+
        Button.appendChild(ButtonLink);
                document.getElementById("forensicsm").value = (Math.ceil(dayrate * 31)).toFixed(2);
+
        Button.appendChild(document.createTextNode(']'));
                document.getElementById("forensicsq").value = (Math.ceil(dayrate * 92)).toFixed(2);
+
                document.getElementById("forensicsy").value = (Math.ceil(dayrate * 366)).toFixed(2);
+
        Header.insertBefore(Button, Header.childNodes[0]);
                document.getElementById("forensicshpd").value = (Math.ceil(dayrate) / 24 / devices.value).toFixed(2);
+
        tableIndex ++;
                document.getElementById("forensicsdpd").value = (Math.ceil(dayrate) / devices.value).toFixed(2);
+
      }
                document.getElementById("forensicswpd").value = (Math.ceil(dayrate * 7) / devices.value).toFixed(2);
+
  }
                document.getElementById("forensicsmpd").value = (Math.ceil(dayrate * 31) / devices.value).toFixed(2);
+
                document.getElementById("forensicsqpd").value = (Math.ceil(dayrate * 92) / devices.value).toFixed(2);
+
  for (var i = 0; i < tableIndex; i ++) {
                document.getElementById("forensicsypd").value = (Math.ceil(dayrate * 366) / devices.value).toFixed(2);
+
      if (hasClass(NavigationBoxes[i], 'collapsed') ||
                document.getElementById("memoryrequired").value = Math.ceil(4 + (0.05 * parseInt(document.getElementById("devices").value)));
+
        (tableIndex >= autoCollapse &&
 +
          hasClass(NavigationBoxes[i], 'autocollapse')))
 +
        collapseTable(i);
 +
      else if (hasClass(NavigationBoxes[i], 'innercollapse')) {
 +
        var element = NavigationBoxes[i];
 +
 
 +
        while (element = element.parentNode) {
 +
            if (hasClass(element, 'outercollapse')) {
 +
              collapseTable(i);
 +
              break;
 
             }
 
             }
 +
        }
 +
      }
 +
  }
 +
}
 +
 +
addOnloadHook(createCollapseButtons);
 +
 +
/** Test if an element has a certain class ********************************
 +
*
 +
* Description: Uses regular expressions and caching for better performance.
 +
* Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
 +
*/
 +
 +
var hasClass = (function() {
 +
  var reCache = {};
 +
  return function(element, className) {
 +
      return ( reCache[className] ? reCache[className] :
 +
        (reCache[className] = new RegExp( "(?:\\s|^)" + className +
 +
        "(?:\\s|$)" ) ) ).test(element.className);
 +
  };
 +
})();
 +
 +
function hasClassTest(element, className) {
 +
  // No reason to have two functions that do the same thing
 +
  // return element.className.indexOf(className) != -1;
 +
  return hasClass(element, className);
 +
}

Latest revision as of 11:11, 15 November 2018

/* Any JavaScript here will be loaded for all users on every page load. */
 
(function ($, mw, store) {
    "use strict";
    var articles;
 
    if (store && store.getItem('commonjs')) {
        console.log('You have chosen to disable site-wide JavaScript ' +
                    'in MediaWiki:Common.js. Please remove \'commonjs\' ' +
                    'from localStorage to re-enable site-wide JavaScript.');
        return;
    }
 
    window.UserTagsJS = {
	modules: {},
	tags: {
           heroicuser:  { u:'Most Heroic Contributor' },
           imageeditor: { u:'Image Editor' },
           retired: { u:'Retired Clasher' },
        }
    };
    UserTagsJS.modules.custom        = {};
    UserTagsJS.modules.inactive      = 30;
    UserTagsJS.modules.newuser       = true;
    UserTagsJS.modules.autoconfirmed = true;
 
    UserTagsJS.modules.mwGroups = [
        'bureaucrat',
        'sysop',
        'chatmoderator',
        'threadmoderator',
        'rollback',
        'patroller',
        'bannedfromchat',
        'bot',
        'bot-global',
    ];

    UserTagsJS.modules.metafilter = {
        bureaucrat:      ['founder'],
        sysop:           ['founder', 'bureaucrat'],
        chatmoderator:   ['founder', 'bureaucrat', 'sysop'],
        threadmoderator: ['founder', 'bureaucrat', 'sysop', 'chatmoderator'],
        imageeditor:     ['founder', 'bureaucrat', 'sysop', 'chatmoderator', 'threadmoderator'],
        rollback:        ['founder', 'bureaucrat', 'sysop', 'chatmoderator', 'threadmoderator',
                          'imageeditor'],
    };
 
    UserTagsJS.modules.custom = {
        'FaceBound': ['imageeditor'], // Image Editor
    };

    if (typeof(window.SpoilerAlert) === 'undefined') {
        window.SpoilerAlert = {
            question: 'Chief! This page contains sneak peeks. Are you sure you ' +
                      'want to enter?',
            yes: 'Yes, please',
            no: 'No, let it be a surprise',
            isSpoiler: function () {
                return (-1 !== wgCategories.indexOf('Spoiler') &&
                    Boolean($('.spoiler').length));
            }
        };
    }

    window.LockForums = {
        expiryDays:    90,  // Number of days until forum is locked to new replies
        expiryMessage: 'Forums are automatically locked when the most recent post is older than <expiryDays> days.',
        warningDays:   14,   // Number of days until a warning is given to potential replies
        ignoreDeletes: true, // Ignore deleted messages when calculating age of last post
        warningPopup:  true, // Pop up a warning dialog that must be confirmed for posts on older forums
        banners:       true, // Add a banner to the top of aged forums
    };

    /* Articles are interwiki links so that other wikis can use them. */
    articles = [
        'w:c:spottra:MediaWiki:Common.js/Numeral.js', // Defines num.format('<fmt>')
        'w:c:spottra:MediaWiki:Common.js/AjaxGallery.js',
        'u:dev:Countdown/code.js',
        'u:dev:SpoilerAlert/code.js',
        'u:dev:TopEditors/code.js',
        'u:dev:WallGreetingButton/code.js',
        'u:dev:ExtendedNavigation/code.js',
        'u:dev:LockForums/code.js',
        'u:dev:LockOldBlogs/code.js',
        'w:c:clashofclans:MediaWiki:Common.js/RGBColor.js',
        'w:c:clashofclans:MediaWiki:Common.js/Usernames.js',
        'u:dev:UserTags/code.js',
        'w:c:clashofclans:MediaWiki:Common.js/Sliders.js',
        'w:c:clashofclans:MediaWiki:Common.js/GemCalculators.js',
        'w:c:clashofclans:MediaWiki:Common.js/Experience.js',
        'w:c:clashofclans:MediaWiki:Common.js/TroopInfo.js',
        'w:c:clashofclans:MediaWiki:Common.js/BuildingInfo.js',
        'w:c:clashofclans:MediaWiki:Common.js/AchievementInfo.js',
        'w:c:clashofclans:MediaWiki:Common.js/Tabber2.js',
        'w:c:clashofclans:MediaWiki:Common.js/ImageHover.js',
        'w:c:clashofclans:MediaWiki:Common.js/CumulativeCosts.js',
        'w:c:clashofclans:MediaWiki:Common.js/UnitComparator.js',
        'w:c:clashofclans:MediaWiki:Common.js/ModeToggle.js',
        'w:c:clashofclans:MediaWiki:Common.js/PageVerify.js',
        'w:c:clashofclans:MediaWiki:Common.js/GorillaMan.js',
        'w:c:clashofclans:MediaWiki:Common.js/Lugia.js',
        'w:c:clashofclans:MediaWiki:Common.js/BadgeGenerator.js',
        'w:c:clashofclans:MediaWiki:Common.js/Protection.js',
        'w:c:clashofclans:MediaWiki:Common.js/AvailableBuildings.js',
    ];
    // Use Wikia's importArticles() function to load JavaScript files
    window.importArticles({
        type: 'script',
        articles: articles
    });
    console.log('Site-wide JavaScript in MediaWiki:Common.js will load the ' +
                'following JavaScript files:\n   ' + articles.join('\n   '));

    // Moves Clash Royale link to page header
    $('#ClashRoyaleLink').appendTo('header#WikiaPageHeader');
}(jQuery, mediaWiki, window.localStorage));

// Change Random Page button to only go to pages in the mainspace
    $('.wds-dropdown a[data-tracking=explore-random], ul.tools li a[data-name=random]').attr("href", "/wiki/Special:Random/main");

/** Collapsible tables *********************************************************
 *
 *  Description: Allows tables to be collapsed, showing only the header. See
 *  http://www.mediawiki.org/wiki/Manual:Collapsible_tables.
 *  Maintainers: [[en:User:R. Koot]]
 */
var autoCollapse    = 2;
var collapseCaption = 'hide';
var expandCaption   = 'show';
 
function collapseTable(tableIndex) {
   var Button = document.getElementById('collapseButton'   + tableIndex);
   var Table  = document.getElementById('collapsibleTable' + tableIndex);
 
   if (!Table || !Button)
      return false;
 
   var Rows = Table.rows;
 
   if (Button.firstChild.data == collapseCaption) {
      for (var i = 1; i < Rows.length; i ++)
         Rows[i].style.display = 'none';

      Button.firstChild.data = expandCaption;
   }
   else {
      for (var i = 1; i < Rows.length; i ++)
         Rows[i].style.display = Rows[0].style.display;

      Button.firstChild.data = collapseCaption;
   }
}
 
function createCollapseButtons() {
   var tableIndex      = 0;
   var NavigationBoxes = new Object();
   var Tables          = document.getElementsByTagName('table');
 
   for (var i = 0; i < Tables.length; i ++) {
      if (hasClass(Tables[i], 'collapsible')) {
         /* only add button and increment count if there is a header row
            to work with */
         var HeaderRow = Tables[i].getElementsByTagName('tr')[0];

         if (!HeaderRow)
            continue;

         var Header = HeaderRow.getElementsByTagName('th')[0];

         if (!Header)
            continue;

         NavigationBoxes[tableIndex] = Tables[i];
         Tables[i].setAttribute('id', 'collapsibleTable' + tableIndex);
 
         var Button     = document.createElement('span');
         var ButtonLink = document.createElement('a');
         var ButtonText = document.createTextNode(collapseCaption);
 
         // Styles are declared in [[MediaWiki:Common.css]]
         Button.className = 'collapseButton';
 
         ButtonLink.style.color = Header.style.color;
         ButtonLink.setAttribute('id', 'collapseButton' + tableIndex);
         ButtonLink.setAttribute('href',
            "javascript:collapseTable(" + tableIndex + ");" );
         ButtonLink.appendChild(ButtonText);
 
         Button.appendChild(document.createTextNode('['));
         Button.appendChild(ButtonLink);
         Button.appendChild(document.createTextNode(']'));
 
         Header.insertBefore(Button, Header.childNodes[0]);
         tableIndex ++;
      }
   }
 
   for (var i = 0; i < tableIndex; i ++) {
      if (hasClass(NavigationBoxes[i], 'collapsed') ||
         (tableIndex >= autoCollapse &&
          hasClass(NavigationBoxes[i], 'autocollapse')))
         collapseTable(i);
      else if (hasClass(NavigationBoxes[i], 'innercollapse')) {
         var element = NavigationBoxes[i];

         while (element = element.parentNode) {
            if (hasClass(element, 'outercollapse')) {
               collapseTable(i);
               break;
            }
         }
      }
   }
}

addOnloadHook(createCollapseButtons);
 
/** Test if an element has a certain class ********************************
 *
 * Description: Uses regular expressions and caching for better performance.
 * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
 */
 
var hasClass = (function() {
   var reCache = {};
   return function(element, className) {
      return ( reCache[className] ? reCache[className] :
         (reCache[className] = new RegExp( "(?:\\s|^)" + className +
         "(?:\\s|$)" ) ) ).test(element.className);
   };
})();

function hasClassTest(element, className) {
   // No reason to have two functions that do the same thing
   // return element.className.indexOf(className) != -1;
   return hasClass(element, className);
}