This page you are viewing is part of the SEVA Wiki Archive, Please visit the new Official Website!
NOTICE: Visit the Maillist page for help joining the new google groups email list, the old maillist is no more.
SEVA meetings are held every second Tuesday.


Difference between revisions of "MediaWiki:Common.js"

From SeattleEVA
Jump to navigation Jump to search
(forcePreview)
(Undo revision 9857 by Rjf (talk))
Tag: Undo
 
(2 intermediate revisions by the same 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. */
//<source lang="javascript">
+
 
 +
/*<source lang="javascript">*/
  
 
/* per http://www.mediawiki.org/wiki/Manual:Force_preview */
 
/* per http://www.mediawiki.org/wiki/Manual:Force_preview */
 
function forcePreview() {
 
function forcePreview() {
   if (wgUserGroups == "user" || wgAction != "edit") return;
+
   if (wgUserGroups == "sysop" || wgAction != "edit") return;
 
   saveButton = document.getElementById("wpSave");
 
   saveButton = document.getElementById("wpSave");
 
   if (!saveButton) return;
 
   if (!saveButton) return;
Line 14: Line 15:
 
addOnloadHook(forcePreview);
 
addOnloadHook(forcePreview);
  
/** Tooltips and access keys ***************************************************
 
  *
 
  *  Description: Adds tooltips and access keys to links part of the MediaWiki
 
  *              interface.
 
  *  Maintainers: [[User:Gwicke|Gwicke]]?, [[User:Simetrical|Simetrical]]?, [[User:Ruud Koot|Ruud Koot]]
 
  */
 
 
ta = new Object();
 
ta["n-mainpage"]            = new Array("z","Visit the main page");
 
ta["n-Main-page"]          = new Array("z","Visit the main page");
 
ta["n-Featured-content"]    = new Array("","Featured content — the best of Wikipedia");
 
ta["n-help"]                = new Array("","The place to find out about Wikipedia");
 
ta["n-contact"]            = new Array("","How to contact Wikipedia");
 
ta["n-sitesupport"]        = new Array("","Help keep Wikipedia running");
 
ta["t-print"]              = new Array("","Printable version of this page");
 
ta["t-permalink"]          = new Array("","Permanent link to this version of the page");
 
ta["t-cite"]                = new Array("","Cite this Wikipedia article");
 
ta["ca-nstab-project"]      = new Array("c","View the project page");
 
ta["n-Contents"]            = new Array("","Guides to browsing Wikipedia");
 
  
/** Import module *************************************************************
+
//Overrides the function with the same name in http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
  *
+
//Fixes a bug: for the sorting order, takes the whole number, not the number before the second comma.
  *  Description: Includes a raw wiki page as javascript or CSS,  
+
//Also, removes spaces. See [[Help:Sorting]].
  *              used for including user made modules.
+
function ts_parseFloat(num) {
  *  Maintainers: [[User:AzaToth]]
+
if (!num) return 0;
  */
+
    num = removeSpaces(num);
importedScripts = {}; // object keeping track of included scripts, so a script ain't included twice
+
num = parseFloat(num.replace(/,/g, ""));
function importScript( page ) {
+
return (isNaN(num) ? 0 : num);
    if( importedScripts[page] ) {
+
}
        return;
+
 
     }
+
//Keep spaces in "currency" mode, to sort a range "70 to 80" at 70, not 7080
     importedScripts[page] = true;
+
function ts_parseFloat_ks(num) {
     var url = wgScriptPath
+
if (!num) return 0;
            + '/index.php?title='
+
num = parseFloat(num.replace(/,/g, ""));
            + encodeURIComponent( page.replace( ' ', '_' ) )
+
return (isNaN(num) ? 0 : num);
            + '&action=raw&ctype=text/javascript';
+
}
     var scriptElem = document.createElement( 'script' );
+
 
     scriptElem.setAttribute( 'src' , url );
+
//Auxiliary function for function ts_resortTable(lnk)
     scriptElem.setAttribute( 'type' , 'text/javascript' );
+
function removeSpaces(string) {
    document.getElementsByTagName( 'head' )[0].appendChild( scriptElem );
+
        var tstring = "";
}
+
        string = '' + string;
+
        splitstring = string.split(" ");
function importStylesheet( page ) {
+
        for(i = 0; i < splitstring.length; i++)
    var sheet = '@import "'
+
        tstring += splitstring[i];
              + wgScriptPath
+
        return tstring;
              + '/index.php?title='
+
}
              + encodeURIComponent( page.replace( ' ', '_' ) )
+
 
              + '&action=raw&ctype=text/css";'
+
//Overrides the function with the same name in http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
    var styleElem = document.createElement( 'style' );
+
//Changes the criteria for various sorting modes, see [[Help:Sorting]].
    styleElem.setAttribute( 'type' , 'text/css' );
+
//For easy maintenance the difference with wikibits.js is kept limited to a few lines.
    styleElem.appendChild( document.createTextNode( sheet ) );
+
function ts_resortTable(lnk) {
    document.getElementsByTagName( 'head' )[0].appendChild( styleElem );
+
// get the span
}
+
var span = lnk.getElementsByTagName('span')[0];
 +
 
 +
var td = lnk.parentNode;
 +
var tr = td.parentNode;
 +
var column = td.cellIndex;
 +
 
 +
var table = tr.parentNode;
 +
while (table && !(table.tagName && table.tagName.toLowerCase() == 'table'))
 +
table = table.parentNode;
 +
if (!table) return;
 +
 
 +
// Work out a type for the column
 +
if (table.rows.length <= 1) return;
 +
 
 +
// Skip the first row if that's where the headings are
 +
var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1);
 +
 
 +
var itm = "";
 +
for (var i = rowStart; i < table.rows.length; i++) {
 +
if (table.rows[i].cells.length > column) {
 +
itm = ts_getInnerText(table.rows[i].cells[column]);
 +
itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, "");
 +
if (itm != "") break;
 +
}
 +
}
 +
 
 +
sortfn = ts_sort_caseinsensitive;
 +
     itmns = removeSpaces(itm);
 +
     if (itmns.match(/^[\d\.\,\-\+]+\%?$/)) sortfn = ts_sort_numeric;
 +
     if (itmns.match(/^[\d\.\,\-\+]+[eE][\d\-\+]+\%?$/)) sortfn = ts_sort_numeric;
 +
    if (itmns.match(/^[\d\.\,\-\+]+e[\d\-\+]+\u00d710[\d\-\+]+\%?$/)) sortfn = ts_sort_numeric;
 +
if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/))
 +
sortfn = ts_sort_date;
 +
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/))
 +
sortfn = ts_sort_date;
 +
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/))
 +
sortfn = ts_sort_date;
 +
if (itm.match(/^[\u00a3$\u20ac\u00a5]/)) // pound dollar euro yen
 +
sortfn = ts_sort_currency;
 +
     if (itm.match(/sm=c$/)) sortfn = ts_sort_currency;
 +
     if (itm.match(/sm=d$/)) sortfn = ts_sort_date;
 +
     if (itm.match(/sm=n$/)) sortfn = ts_sort_numeric;
 +
 
 +
var reverse = (span.getAttribute("sortdir") == 'down');
 +
 
 +
var newRows = new Array();
 +
for (var j = rowStart; j < table.rows.length; j++) {
 +
var row = table.rows[j];
 +
var keyText = ts_getInnerText(row.cells[column]);
 +
var oldIndex = (reverse ? -j : j);
 +
 
 +
newRows[newRows.length] = new Array(row, keyText, oldIndex);
 +
}
 +
 
 +
newRows.sort(sortfn);
 +
 
 +
var arrowHTML;
 +
if (reverse) {
 +
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');
 +
}
 +
 
 +
// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
 +
// don't do sortbottom rows
 +
for (var i = 0; i < newRows.length; i++) {
 +
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1)
 +
table.tBodies[0].appendChild(newRows[i][0]);
 +
}
 +
// do sortbottom rows only
 +
for (var i = 0; i < newRows.length; i++) {
 +
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1)
 +
table.tBodies[0].appendChild(newRows[i][0]);
 +
}
 +
 
 +
// Delete any other arrows there may be showing
 +
var spans = getElementsByClassName(tr, "span", "sortarrow");
 +
for (var i = 0; i < spans.length; i++) {
 +
spans[i].innerHTML = '<img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/>';
 +
}
 +
span.innerHTML = arrowHTML;
  
/* Test if an element has a certain class **************************************
+
ts_alternate(table);
  *
+
}
  * 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);
 
    };
 
})();
 
  
/** Internet Explorer bug fix **************************************************
+
function ts_dateToSortKey(date) {
  *
+
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
  *  Description: UNDOCUMENTED
+
if (date.length > 10) {
  *  Maintainers: [[User:Tom-]]?
+
switch (date.substr(3,3).toLowerCase()) {
  */
+
case "jan": var month = "01"; break;
+
case "feb": var month = "02"; break;
if (window.showModalDialog && document.compatMode && document.compatMode == "CSS1Compat")
+
case "mar": var month = "03"; break;
{
+
case "apr": var month = "04"; break;
  var oldWidth;
+
case "may": var month = "05"; break;
  var docEl = document.documentElement;
+
case "jun": var month = "06"; break;
+
case "jul": var month = "07"; break;
  function fixIEScroll()
+
case "aug": var month = "08"; break;
  {
+
case "sep": var month = "09"; break;
    if (!oldWidth || docEl.clientWidth > oldWidth)
+
case "oct": var month = "10"; break;
      doFixIEScroll();
+
case "nov": var month = "11"; break;
    else
+
case "dec": var month = "12"; break;
      setTimeout(doFixIEScroll, 1);
+
// default: var month = "00";
 
+
}
    oldWidth = docEl.clientWidth;
+
return date.substr(7,4)+month+date.substr(0,2);
  }
+
} else if (date.length == 10) {
+
return date.substr(6,4)+date.substr(3,2)+date.substr(0,2);
  function doFixIEScroll() {
+
} else if (date.length == 8) {
    docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? "hidden" : "";
+
yr = date.substr(6,2);
  }
+
if (parseInt(yr) < 50) {
+
yr = '20'+yr;  
  document.attachEvent("onreadystatechange", fixIEScroll);
+
} else {  
  attachEvent("onresize", fixIEScroll);
+
yr = '19'+yr;  
}
+
}
 +
return yr+date.substr(3,2)+date.substr(0,2);
 +
}
 +
return "00000000";
 +
}
  
/** Interwiki links to featured articles ***************************************
+
function ts_sort_currency(a,b) {
  *
+
var aa = ts_parseFloat_ks(a[1].replace(/[\u00a3$\u20ac\u00a5a-zA-Z]/g,''));
  *  Description: Highlights interwiki links to featured articles (or
+
var bb = ts_parseFloat_ks(b[1].replace(/[\u00a3$\u20ac\u00a5a-zA-Z]/g,''));
  *              equivalents) by changing the bullet before the interwiki link
+
return (aa != bb ? aa - bb : a[2] - b[2]);
  *              into a star.
+
}
  *  Maintainers: [[User:R. Koot]]
 
  */
 
 
function LinkFA()
 
{
 
    if ( document.getElementById( "p-lang" ) ) {
 
        var InterwikiLinks = document.getElementById( "p-lang" ).getElementsByTagName( "li" );
 
 
        for ( var i = 0; i < InterwikiLinks.length; i++ ) {
 
            if ( document.getElementById( InterwikiLinks[i].className + "-fa" ) ) {
 
                InterwikiLinks[i].className += " FA"
 
                InterwikiLinks[i].title = "This is a featured article in another language.";
 
            }
 
        }
 
    }
 
}
 
 
addOnloadHook( LinkFA );
 
  
 
  /** Collapsible tables *********************************************************
 
  /** Collapsible tables *********************************************************
Line 138: Line 179:
 
   *  Description: Allows tables to be collapsed, showing only the header. See
 
   *  Description: Allows tables to be collapsed, showing only the header. See
 
   *              [[Wikipedia:NavFrame]].
 
   *              [[Wikipedia:NavFrame]].
   *  Maintainers: [[User:R. Koot]]
+
   *  Maintainer on Wikipedia: [[User:R. Koot]]
 
   */
 
   */
 
   
 
   
Line 145: Line 186:
 
  var expandCaption = "show";
 
  var expandCaption = "show";
 
   
 
   
 +
function hasClass( element, className ) {
 +
  var Classes = element.className.split( " " );
 +
  for ( var i = 0; i < Classes.length; i++ ) {
 +
    if ( Classes[i] == className ) {
 +
      return ( true );
 +
    }
 +
  }
 +
  return ( false );
 +
}
 +
 
  function collapseTable( tableIndex )
 
  function collapseTable( tableIndex )
 
  {
 
  {
Line 216: Line 267:
 
  addOnloadHook( createCollapseButtons );
 
  addOnloadHook( createCollapseButtons );
  
/** Dynamic Navigation Bars (experimental) *************************************
+
//Shuffle for election candidates
  *
+
function dshuf(){
  *  Description: See [[Wikipedia:NavFrame]].
+
                var shufsets=new Object()
  *  Maintainers: UNMAINTAINED
+
                var rx=new RegExp('dshuf'+'\\s+(dshufset\\d+)', 'i')  
  */
+
                var divs=document.getElementsByTagName("div")
+
                for (var i=0; i<divs.length; i++){
  // set up the words in your language
+
                        if (rx.test(divs[i].className)){
  var NavigationBarHide = '[' + collapseCaption + ']';
+
                                if (typeof shufsets[RegExp.$1]=="undefined"){  
  var NavigationBarShow = '[' + expandCaption + ']';
+
                                        shufsets[RegExp.$1]=new Object()  
 
+
                                        shufsets[RegExp.$1].inner=[]
  // set up max count of Navigation Bars on page,
+
                                        shufsets[RegExp.$1].member=[]
  // if there are more, all will be hidden
+
                                }
  // NavigationBarShowDefault = 0; // all bars will be hidden
+
                                        shufsets[RegExp.$1].inner.push(divs[i].innerHTML)  
  // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden
+
                                        shufsets[RegExp.$1].member.push(divs[i])
  var NavigationBarShowDefault = autoCollapse;
+
                        }
 
+
                }
 
+
                for (shufset in shufsets){
  // shows and hides content and picture (if available) of navigation bars
+
                        shufsets[shufset].inner.sort(function() {return 0.5 - Math.random()})
  // Parameters:
+
                        for (var i=0; i<shufsets[shufset].member.length; i++){
  //    indexNavigationBar: the index of navigation bar to be toggled
+
                                shufsets[shufset].member[i].innerHTML=shufsets[shufset].inner[i]
  function toggleNavigationBar(indexNavigationBar)
+
                                shufsets[shufset].member[i].style.display="block"
  {
+
                        }
    var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
+
                }
    var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);
+
 
 
+
}
    if (!NavFrame || !NavToggle) {
+
 
        return false;
+
addOnloadHook(dshuf);
    }
 
 
 
    // if shown now
 
    if (NavToggle.firstChild.data == NavigationBarHide) {
 
        for (
 
                var NavChild = NavFrame.firstChild;
 
                NavChild != null;
 
                NavChild = NavChild.nextSibling
 
            ) {
 
            if ( hasClass( NavChild, 'NavPic' ) ) {
 
                NavChild.style.display = 'none';
 
            }
 
            if ( hasClass( NavChild, 'NavContent') ) {
 
                NavChild.style.display = 'none';
 
            }
 
        }
 
    NavToggle.firstChild.data = NavigationBarShow;
 
 
 
    // if hidden now
 
    } else if (NavToggle.firstChild.data == NavigationBarShow) {
 
        for (
 
                var NavChild = NavFrame.firstChild;
 
                NavChild != null;
 
                NavChild = NavChild.nextSibling
 
            ) {
 
            if (hasClass(NavChild, 'NavPic')) {
 
                NavChild.style.display = 'block';
 
            }
 
            if (hasClass(NavChild, 'NavContent')) {
 
                NavChild.style.display = 'block';
 
            }
 
        }
 
    NavToggle.firstChild.data = NavigationBarHide;
 
    }
 
  }
 
 
 
  // adds show/hide-button to navigation bars
 
  function createNavigationBarToggleButton()
 
  {
 
    var indexNavigationBar = 0;
 
    // iterate over all < div >-elements
 
    var divs = document.getElementsByTagName("div");
 
    for(
 
            var i=0;
 
            NavFrame = divs[i];
 
            i++
 
        ) {
 
        // if found a navigation bar
 
        if (hasClass(NavFrame, "NavFrame")) {
 
 
 
            indexNavigationBar++;
 
            var NavToggle = document.createElement("a");
 
            NavToggle.className = 'NavToggle';
 
            NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
 
            NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
 
           
 
            var NavToggleText = document.createTextNode(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 (hasClass(NavFrame.childNodes[j], "NavHead")) {
 
                NavFrame.childNodes[j].appendChild(NavToggle);
 
              }
 
            }
 
            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
 
        }
 
    }
 
    // if more Navigation Bars found than Default: hide all
 
    if (NavigationBarShowDefault < indexNavigationBar) {
 
        for(
 
                var i=1;
 
                i<=indexNavigationBar;
 
                i++
 
        ) {
 
            toggleNavigationBar(i);
 
        }
 
    }
 
 
 
  }
 
 
 
  addOnloadHook( createNavigationBarToggleButton );
 
  
/** Main Page layout fixes *********************************************************
+
/*************
  *
+
*** AJAX transclusion table <http://meta.wikimedia.org/wiki/User:Pathoschild/Scripts/AJAX_transclusion_table>
  *  Description:        Various layout fixes for the main page, including an
+
*** by [[m:user:Pathoschild]]
  *                      additional link to the complete list of languages available
+
*************/
  *                      and the renaming of the 'Article' to to 'Main Page'.
+
function attLoader() {
  *  Maintainers:        [[User:AzaToth]], [[User:R. Koot]]
+
if(getElementsByClassName(document.getElementsByTagName('body')[0],'table','attable').length) {
  */
+
        document.write('<script type="text/javascript" src="'
+
          + 'http://meta.wikimedia.org/w/index.php?title=User:Pathoschild/Scripts/AJAX_transclusion_table.js'  
function mainPageRenameNamespaceTab() {
+
          + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');
    try {
+
}
        var Node = document.getElementById( 'ca-nstab-main' ).firstChild;
+
}
        if ( Node.textContent ) {      // Per DOM Level 3
+
addOnloadHook(attLoader);
            Node.textContent = 'Main Page';
 
        } else if ( Node.innerText ) { // IE doesn't handle .textContent
 
            Node.innerText = 'Main Page';
 
        } else {                      // Fallback
 
            Node.replaceChild( Node.firstChild, document.createTextNode( 'Main Page' ) );
 
        }
 
    } catch(e) {
 
        // bailing out!
 
    }
 
}
 
 
function mainPageAppendCompleteListLink() {
 
    try {
 
        var node = document.getElementById( "p-lang" )
 
                            .getElementsByTagName('div')[0]
 
                            .getElementsByTagName('ul')[0];
 
 
        var aNode = document.createElement( 'a' );
 
        var liNode = document.createElement( 'li' );
 
 
        aNode.appendChild( document.createTextNode( 'Complete list' ) );
 
        aNode.setAttribute( 'href' , 'http://meta.wikimedia.org/wiki/List_of_Wikipedias' );
 
        liNode.appendChild( aNode );
 
        liNode.className = 'interwiki-completelist';
 
        node.appendChild( liNode );
 
      } catch(e) {
 
        // lets just ignore what's happened
 
        return;
 
    }
 
}
 
 
if ( wgTitle == 'Main Page' && ( wgNamespaceNumber == 0 || wgNamespaceNumber == 1 ) ) {
 
        addOnloadHook( mainPageRenameNamespaceTab );
 
}
 
 
if ( wgTitle == 'Main Page' && wgNamespaceNumber == 0 ) {
 
        addOnloadHook( mainPageAppendCompleteListLink );
 
}
 
  
/** Extra toolbar options ****************************************************** <nowiki>
+
/** JSconfig ************
  *
+
* Global configuration options to enable/disable and configure
  * Description: UNDOCUMENTED
+
* specific script features from [[MediaWiki:Common.js]] and
  * Maintainers: [[User:MarkS]]?, [[User:Voice of All]], [[User:R. Koot]]
+
* [[MediaWiki:Monobook.js]]
  */
+
* This framework adds config options (saved as cookies) to [[Special:Preferences]]
 +
* For a more permanent change you can override the default settings in your
 +
* [[Special:Mypage/monobook.js]]
 +
* for Example: JSconfig.keys[loadAutoInformationTemplate] = false;
 +
*
 +
*  Maintainer: [[User:Dschwen]]
 +
*/
 
   
 
   
  //This is a modified copy of a script by User:MarkS for extra features added by User:Voice of All.
+
var JSconfig =
  // This is based on the original code on Wikipedia:Tools/Editing tools
+
{
  // To disable this script, add <code>mwCustomEditButtons = [];<code> to [[Special:Mypage/monobook.js]]
+
  prefix : 'jsconfig_',
 +
  keys : {},
 +
  meta : {},
 
   
 
   
  if (mwCustomEditButtons) {
+
  //
  mwCustomEditButtons[mwCustomEditButtons.length] = {
+
// Register a new configuration item
     "imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c8/Button_redirect.png",
+
//  * name          : String, internal name
    "speedTip": "Redirect",
+
//  * default_value : String or Boolean (type determines configuration widget)
    "tagOpen": "#REDIRECT [[",
+
//  * description  : String, text appearing next to the widget in the preferences
    "tagClose": "]]",
+
//  * prefpage     : Integer (optional), section in the preferences to insert the widget:
    "sampleText": "Insert text"};
+
//                    0 : User profile
 +
//                    1 : Skin
 +
//                    2 : Math
 +
//                     3 : Files
 +
//                     4 : Date and time
 +
//                     5 : Editing
 +
//                     6 : Recent changes
 +
//                    7 : Watchlist
 +
//                    8 : Search
 +
//                    9 : Misc
 +
//
 +
// Access keys through JSconfig.keys[name]
 +
//
 +
registerKey : function( name, default_value, description, prefpage )
 +
{
 +
  if( typeof(JSconfig.keys[name]) == 'undefined' )
 +
  JSconfig.keys[name] = default_value;
 +
  else {
 
   
 
   
   mwCustomEditButtons[mwCustomEditButtons.length] = {
+
   // all cookies are read as strings,
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c9/Button_strike.png",
+
  // convert to the type of the default value
    "speedTip": "Strike",
+
  switch( typeof(default_value) )
    "tagOpen": "<s>",
+
  {
    "tagClose": "</s>",
+
    case 'boolean' : JSconfig.keys[name] = ( JSconfig.keys[name] == 'true' ); break;
    "sampleText": "Strike-through text"};
+
    case 'number'  : JSconfig.keys[name] = JSconfig.keys[name]/1; break;
 +
  }
 
   
 
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
+
  }
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/1/13/Button_enter.png",
 
    "speedTip": "Line break",
 
    "tagOpen": "<br />",
 
    "tagClose": "",
 
    "sampleText": ""};
 
 
   
 
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
+
  JSconfig.meta[name] = { 'description' : description, 'page' : prefpage || 0, 'default_value' : default_value };
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/8/80/Button_upper_letter.png",
+
},
    "speedTip": "Superscript",
 
    "tagOpen": "<sup>",
 
    "tagClose": "</sup>",
 
    "sampleText": "Superscript text"};
 
 
   
 
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
+
readCookies : function()
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/7/70/Button_lower_letter.png",
+
  {
    "speedTip": "Subscript",
+
  var cookies = document.cookie.split("; ");
    "tagOpen": "<sub>",
+
  var p =JSconfig.prefix.length;
    "tagClose": "</sub>",
+
  var i;
    "sampleText": "Subscript text"};
 
   
 
  mwCustomEditButtons[mwCustomEditButtons.length] = {
 
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/5/58/Button_small.png",
 
    "speedTip": "Small",
 
    "tagOpen": "<small>",
 
    "tagClose": "</small>",
 
    "sampleText": "Small Text"};
 
 
  mwCustomEditButtons[mwCustomEditButtons.length] = {
 
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/3/34/Button_hide_comment.png",
 
    "speedTip": "Insert hidden Comment",
 
    "tagOpen": "<!-- ",
 
    "tagClose": " -->",
 
    "sampleText": "Comment"};
 
 
  mwCustomEditButtons[mwCustomEditButtons.length] = {
 
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/1/12/Button_gallery.png",
 
    "speedTip": "Insert a picture gallery",
 
    "tagOpen": "\n<gallery>\n",
 
    "tagClose": "\n</gallery>",
 
    "sampleText": "Image:Example.jpg|Caption1\nImage:Example.jpg|Caption2"};
 
 
   
 
   
  mwCustomEditButtons[mwCustomEditButtons.length] = {
+
   for( var key in cookies )
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/f/fd/Button_blockquote.png",
 
    "speedTip": "Insert block of quoted text",
 
    "tagOpen": "<blockquote>\n",
 
    "tagClose": "\n</blockquote>",
 
    "sampleText": "Block quote"};
 
 
  mwCustomEditButtons[mwCustomEditButtons.length] = {
 
    "imageFile": "http://upload.wikimedia.org/wikipedia/en/6/60/Button_insert_table.png",
 
    "speedTip": "Insert a table",
 
    "tagOpen": '{| class="wikitable"\n|-\n',
 
    "tagClose": "\n|}",
 
    "sampleText": "! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3"};
 
}
 
 
/*</nowiki>*/
 
 
 
/** pageview counter ***********************************************************
 
   *
 
  *  Description: Please talk to de:User:LeonWeber before changing anything or
 
  *              if there are any issues with that.
 
  *  Maintainers: [[:de:User:LeonWeber]]?
 
  */
 
 
 
  // this should be adjusted to a good value.
 
  // BE CAREFUL, you will break zedler if it's too low!
 
  // And then DaB. will kill Leon :-(
 
  var disable_counter = 0;
 
  var counter_factor = 6000;
 
 
 
  function pgcounter_setup()
 
 
   {
 
   {
  if(disable_counter == 0)
+
  if( cookies[key].substring(0,p) == JSconfig.prefix )
  {
+
  {
  var url = window.location.href;
+
    i = cookies[key].indexOf('=');
  if(Math.floor(Math.random()*counter_factor)==42) // the probability thing
+
    //alert( cookies[key] + ',' + key + ',' + cookies[key].substring(p,i) );
  {
+
    JSconfig.keys[cookies[key].substring(p,i)] = cookies[key].substring(i+1);
  if(wgIsArticle==true || wgArticleId==0) // do not count history pages etc.
+
  }
  {
 
  var pgcountNs = wgCanonicalNamespace;
 
  if(wgCanonicalNamespace=="")
 
  {
 
  pgcountNs = "0";
 
  }
 
  var cnt_url = "http://pgcount.wikimedia.de/index.png?ns=" + pgcountNs + "&title=" + encodeURI(wgTitle) + "&factor=" + counter_factor +"&wiki=enwiki";
 
  var img = new Image();  
 
  img.src = cnt_url;
 
  }
 
  }
 
  }
 
 
   }
 
   }
  // Do not use aOnloadFunctions[aOnloadFunctions.length] = pgcounter_setup;, some browsers don't like that.
+
  },
  pgcounter_setup();
 
 
 
/** "Technical restrictions" title fix *****************************************
 
*
 
* Description:
 
* Maintainers: User:Interiot, User:Mets501, User:Freakofnurture
 
*/
 
//
 
// For pages that have something like Template:Lowercase, replace the title, but only if it is cut-and-pasteable as a valid wikilink.
 
// (for instance iPod's title is updated. But [[C#]] is not an equivalent
 
// wikilink, so [[C Sharp]] doesn't have its main title changed)
 
// Likewise for users who have selected the U.K. date format ("1 March") the 
 
// titles of day-of-the-year articles will appear in that style. Users with any
 
// other date setting are not affected.
 
//
 
// The function looks for a banner like this:
 
// &lt;div id="RealTitleBanner"&gt;  ... &lt;span id="RealTitle"&gt;title&lt;/span&gt; ... &lt;/div&gt;
 
// An element with id=DisableRealTitle disables the function.
 
//
 
  var disableRealTitle = 0; // users can set disableRealTitle = 1 locally to disable.
 
if (wgIsArticle) { // don't display the RealTitle when editing, since it is apparently inconsistent (doesn't show when editing sections, doesn't show when not previewing)
 
  addOnloadHook(function() {
 
    try {
 
        var realTitleBanner = document.getElementById("RealTitleBanner");
 
        if (realTitleBanner && !document.getElementById("DisableRealTitle") && !disableRealTitle ) {
 
            var realTitle = document.getElementById("RealTitle");
 
            if (realTitle) {
 
                var realTitleHTML = realTitle.innerHTML;
 
                realTitleText = pickUpText(realTitle);
 
 
 
                var isPasteable = 0;
 
                //var containsHTML = /</.test(realTitleHTML);    // contains ANY HTML
 
                var containsTooMuchHTML = /</.test( realTitleHTML.replace(/<\/?(sub|sup|small|big)>/gi, "") ); // contains HTML that will be ignored when cut-n-pasted as a wikilink
 
                // calculate whether the title is pasteable
 
                var verifyTitle = realTitleText.replace(/^ +/, "");      // trim left spaces
 
                verifyTitle = verifyTitle.charAt(0).toUpperCase() + verifyTitle.substring(1, verifyTitle.length);    // uppercase first character
 
 
 
                // if the namespace prefix is there, remove it on our verification copy. If it isn't there, add it to the original realValue copy.
 
                if (wgNamespaceNumber != 0) {
 
                    if (wgCanonicalNamespace == verifyTitle.substr(0, wgCanonicalNamespace.length).replace(/ /g, "_") && verifyTitle.charAt(wgCanonicalNamespace.length) == ":") {
 
                        verifyTitle = verifyTitle.substr(wgCanonicalNamespace.length + 1);
 
                    } else {
 
                        realTitleText = wgCanonicalNamespace.replace(/_/g, " ") + ":" + realTitleText;
 
                        realTitleHTML = wgCanonicalNamespace.replace(/_/g, " ") + ":" + realTitleHTML;
 
                    }
 
                }
 
 
 
                // verify whether wgTitle matches
 
                verifyTitle = verifyTitle.replace(/[\s_]+/g, " ");      // underscores and multiple spaces to single spaces
 
                verifyTitle = verifyTitle.replace(/^\s+/, "").replace(/\s+$/, "");        // trim left and right spaces
 
                verifyTitle = verifyTitle.charAt(0).toUpperCase() + verifyTitle.substring(1, verifyTitle.length);    // uppercase first character
 
                if ( (verifyTitle == wgTitle) || (verifyTitle == wgTitle.replace(/^(.+)?(January|February|March|April|May|June|July|August|September|October|November|December)\s+([12]?[0-9]|3[0123])([^\d].*)?$/g, "$1$3 $2$4") )) isPasteable = 1;
 
                var h1 = document.getElementsByTagName("h1")[0];
 
                if (h1 && isPasteable) {
 
                    h1.innerHTML = containsTooMuchHTML ? realTitleText : realTitleHTML;
 
                    if (!containsTooMuchHTML)
 
                        realTitleBanner.style.display = "none";
 
                }
 
                document.title = realTitleText + " - Wikipedia, the free encyclopedia";
 
            }
 
        }
 
    } catch (e) {
 
        /* Something went wrong. */
 
    }
 
  });
 
}
 
 
 
// similar to innerHTML, but only returns the text portions of the insides, excludes HTML
 
function pickUpText(aParentElement) {
 
var str = "";
 
 
 
function pickUpTextInternal(aElement) {
 
  var child = aElement.firstChild;
 
  while (child) {
 
  if (child.nodeType == 1)    // ELEMENT_NODE
 
    pickUpTextInternal(child);
 
  else if (child.nodeType == 3)  // TEXT_NODE
 
    str += child.nodeValue;
 
 
 
  child = child.nextSibling;
 
  }
 
}
 
 
 
  pickUpTextInternal(aParentElement);
 
  return str;
 
}
 
 
 
//fix edit summary prompt for undo
 
//this code fixes the fact that the undo function combined with the "no edit summary prompter" causes problems if leaving the
 
//edit summary unchanged
 
//this was added by [[User:Deskana]], code by [[User:Tra]]
 
addOnloadHook(function () {
 
  if (document.location.search.indexOf("undo=") != -1
 
  && document.getElementsByName('wpAutoSummary')[0]) {
 
    document.getElementsByName('wpAutoSummary')[0].value='';
 
  }
 
})
 
 
 
/** Add dismiss button to watchlist-message *************************************
 
  *
 
  *  Description: Hide the watchlist message for one week.
 
  *  Maintainers: [[User:Ruud Koot|Ruud Koot]]
 
  */
 
 
   
 
   
  function addDismissButton() {
+
  writeCookies : function()
    var watchlistMessage = document.getElementById("watchlist-message");
+
{
    if ( watchlistMessage == null ) return;
+
  for( var key in JSconfig.keys )
 +
  document.cookie = JSconfig.prefix + key + '=' + JSconfig.keys[key] + '; path=/; expires=Thu, 2 Aug 2009 10:10:10 UTC';
 +
},
 
   
 
   
    if ( document.cookie.indexOf( "hidewatchlistmessage=yes" ) != -1 ) {
+
evaluateForm : function()
        watchlistMessage.style.display = "none";
+
{
 +
  var w_ctrl,wt;
 +
  //alert('about to save JSconfig');
 +
  for( var key in JSconfig.meta ) {
 +
  w_ctrl = document.getElementById( JSconfig.prefix + key )
 +
  if( w_ctrl )
 +
  {
 +
    wt = typeof( JSconfig.meta[key].default_value );
 +
    switch( wt ) {
 +
    case 'boolean' : JSconfig.keys[key] = w_ctrl.checked; break;
 +
    case 'string' : JSconfig.keys[key] = w_ctrl.value; break;
 
     }
 
     }
 +
  }
 +
  }
 
   
 
   
    var Button    = document.createElement( "span" );
+
  JSconfig.writeCookies();
    var ButtonLink = document.createElement( "a" );
+
  return true;
    var ButtonText = document.createTextNode( "dismiss" );
+
},
 
   
 
   
    ButtonLink.setAttribute( "id", "dismissButton" );
+
setUpForm : function()
    ButtonLink.setAttribute( "href", "javascript:dismissWatchlistMessage();" );
+
{
    ButtonLink.setAttribute( "title", "Hide this message for one week" );
+
  var prefChild = document.getElementById('preferences');
    ButtonLink.appendChild( ButtonText );
+
  if( !prefChild ) return;
 +
  prefChild = prefChild.childNodes;
 
   
 
   
    Button.appendChild( document.createTextNode( "[" ) );
+
  //
    Button.appendChild( ButtonLink );
+
  // make a list of all preferences sections
    Button.appendChild( document.createTextNode( "]" ) );
+
  //
+
  var tabs = new Array;
     watchlistMessage.appendChild( Button );
+
  var len = prefChild.length;
}
+
  for( var key = 0; key < len; key++ ) {
 +
  if( prefChild[key].tagName &&
 +
      prefChild[key].tagName.toLowerCase() == 'fieldset' )  
 +
     tabs.push(prefChild[key]);
 +
  }
 
   
 
   
function dismissWatchlistMessage() {
+
  //
    var e = new Date();
+
  // Create Widgets for all registered config keys
    e.setTime( e.getTime() + (7*24*60*60*1000) );
+
  //
    document.cookie = "hidewatchlistmessage=yes; expires=" + e.toGMTString() + "; path=/";
+
  var w_div, w_label, w_ctrl, wt;
    var watchlistMessage = document.getElementById("watchlist-message");
+
  for( var key in JSconfig.meta ) {
    watchlistMessage.style.display = "none";
+
  w_div = document.createElement( 'DIV' );
}
 
 
   
 
   
addOnloadHook( addDismissButton );
+
  w_label = document.createElement( 'LABEL' );
 
+
  w_label.appendChild( document.createTextNode( JSconfig.meta[key].description ) )
/** Numeric sorting ***************************************************
+
   w_label.htmlFor = JSconfig.prefix + key;
  *
 
  *  Description: Fixes a bug (part of [[bugzilla:8115]])
 
  *  in http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
 
  *  regarding [[Help:Sorting|table sorting]]:
 
  *  it allows sorting of numbers with more than one comma (thousands separator).
 
  *  Maintainer: [[User:Patrick|Patrick]]
 
  */
 
function ts_parseFloat(num) {
 
if (!num) return 0;
 
num = parseFloat(num.replace(/,/g, ""));
 
return (isNaN(num) ? 0 : num);
 
}
 
 
 
/** Main Page deletion image *******************************************************
 
   *
 
  *  Description: If the Main Page does not exist (i.e., it's been deleted) then insert an image
 
  *              instead of showing the "page does not exist" text.
 
  *  Created by: [[User:Mark]], with invaluable help from [[User:Pathoschild]]
 
  */
 
 
   
 
   
function MainPageDeletedImage() {
+
  wt = typeof( JSconfig.meta[key].default_value );
  try {
 
 
   
 
   
    //If the article does not exist and it is the Main Page, proceed
+
  w_ctrl = document.createElement( 'INPUT' );
    if ( document.getElementById( "noarticletext" ) && wgTitle == 'Main Page' ) {
+
  w_ctrl.id = JSconfig.prefix + key;
 
   
 
   
      // Insert a protected commons image at the end of the document explaining it.
+
  // before insertion into the DOM tree
      var contentbox = document.getElementById('content');
+
  switch( wt ) {
      var newimg = document.createElement('img');
+
    case 'boolean' : w_ctrl.type = 'checkbox'; break;
      newimg.setAttribute('src','http://upload.wikimedia.org/wikipedia/commons/9/99/WikipediaTechnical.png');
+
    case 'string' : w_ctrl.type = 'text'; break;
      contentbox.appendChild(newimg);
+
  }
 
   
 
   
      // Hide the article-does-not-exist text
+
  w_div.appendChild( w_label );
      var NoArticleMessage = document.getElementById('noarticletext');
+
  w_div.appendChild( w_ctrl );
      NoArticleMessage.style.display="none";
+
  tabs[JSconfig.meta[key].page].appendChild( w_div );
 
   
 
   
      // Hide the edit button
+
  // after insertion into the DOM tree
      var EditThisPageButton = document.getElementById('ca-edit');
+
  switch( wt ) {
      EditThisPageButton.style.display="none";
+
    case 'boolean' : w_ctrl.defaultChecked = w_ctrl.checked = JSconfig.keys[key]; break;
    }
+
    case 'string' : w_ctrl.defaultValue = w_ctrl.value = JSconfig.keys[key]; break;
  } catch(e) {
 
      // In case it does not work, do nothing
 
      return;
 
 
   }
 
   }
 +
 +
  }
 +
  addHandler(document.getElementById('preferences').parentNode, 'submit', JSconfig.evaluateForm );
 
  }
 
  }
 +
}
 
   
 
   
addOnloadHook( MainPageDeletedImage );
+
JSconfig.readCookies();
 +
addOnloadHook(JSconfig.setUpForm);
  
/** MediaWiki media player *******************************************************
+
// ability to pull [[MediaWiki:Gadget-rtl.css]] on individual page loads by [[testwiki:User:Splarka]] and [[wm2008:User:Mr.Z-man]]
  *
+
function importStylesheet(page) {
  *  Description: A Java player for in-browser playback of media files.
+
  if (page.indexOf('http://') == -1 && page.indexOf('https://') == -1 && page.indexOf('file:///') == -1)
  *  Created by: [[User:Gmaxwell]]
+
    page = wgScript + '?action=raw&ctype=text/css&smaxage=0&title='
  */
+
    + encodeURIComponent(page.replace(/ /g,'_'))
 +
  return document.createStyleSheet ? document.createStyleSheet(page) : appendCSS('@import "' + page + '";')
 +
}
 +
 +
function appendCSS(text){
 +
var s = document.createElement('style')
 +
s.setAttribute('type', 'text/css')
 +
if (s.styleSheet) s.styleSheet.cssText = text //IE
 +
else s.appendChild(document.createTextNode(text))
 +
document.getElementsByTagName('head')[0].appendChild(s)
 +
return s
 +
}
 
   
 
   
document.write('<script type="text/javascript" src="'
+
if(document.URL.indexOf('rtl=1') != -1) importStylesheet('http://meta.wikimedia.org/w/index.php?title=MediaWiki:Gadget-rtl.css&action=raw&ctype=text/css');
            + 'http://en.wikipedia.org/w/index.php?title=Mediawiki:Wikimediaplayer.js'
 
            + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');
 
  
/** Change Special:Search to use a drop-down menu *******************************************************
+
//import module
  *
+
importedScripts = {}  
  *  Description: Change Special:Search to use a drop-down menu, with the default being
+
function importScript(page, lang) {
  *              the internal MediaWiki engine
+
page = '?title=' + encodeURIComponent(page.replace(' ','_'))
  *  Created and maintained by: [[User:Gracenotes]]
+
if (lang) page = 'http://' + lang + '.wikipedia.org/w/index.php' + page
  */
+
else page = wgScript + page
+
if (importedScripts[page]) return
if (wgPageName == "Special:Search") {
+
importedScripts[page] = true
        var searchEngines = [];
+
var s = document.createElement('script')
        addOnloadHook(SpecialSearchEnhanced);
+
s.type = 'text/javascript'
}
+
s.src = page + '&action=raw&ctype=text/javascript'
+
document.getElementsByTagName('head')[0].appendChild(s)
function SpecialSearchEnhanced() {
+
}
        var createOption = function(site, action, mainQ, addQ, addV) {
 
                var opt = document.createElement('option');
 
                opt.appendChild(document.createTextNode(site));
 
                searchEngines[searchEngines.length] = [action, mainQ, addQ, addV];
 
                return opt;
 
        }
 
        var searchForm = document.forms['search'];
 
        var selectBox = document.createElement('select');
 
        selectBox.id = 'searchEngine';
 
        searchForm.onsubmit = function() {
 
                var optSelected = searchEngines[document.getElementById('searchEngine').selectedIndex];
 
                searchForm.action = optSelected[0];
 
                searchForm.lsearchbox.name = optSelected[1];
 
                searchForm.title.value = optSelected[3];
 
                searchForm.title.name = optSelected[2];
 
        }
 
        selectBox.appendChild(createOption('MediaWiki search', wgScriptPath + '/index.php', 'search', 'title', 'Special:Search'));
 
        selectBox.appendChild(createOption('Google', 'http://www.google.com/search', 'q', 'sitesearch', 'en.wikipedia.org'));
 
        selectBox.appendChild(createOption('Yahoo', 'http://search.yahoo.com/search', 'p', 'vs', 'en.wikipedia.org'));
 
        selectBox.appendChild(createOption('Windows Live', 'http://search.live.com/results.aspx', 'q', 'q1', 'site:http://en.wikipedia.org'));
 
        selectBox.appendChild(createOption('Wikiwix', 'http://www.wikiwix.com/', 'action', 'lang', 'en'));
 
        selectBox.appendChild(createOption('Exalead', 'http://www.exalead.com/wikipedia/results', 'q', 'language', 'en'));
 
        searchForm.lsearchbox.style.marginLeft = '0px';
 
        var lStat = document.getElementById('loadStatus');
 
        lStat.parentNode.insertBefore(selectBox, lStat);
 
}
 
//</source>
 

Latest revision as of 18:59, 14 March 2024

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

/*<source lang="javascript">*/

/* per http://www.mediawiki.org/wiki/Manual:Force_preview */
function forcePreview() {
  if (wgUserGroups == "sysop" || wgAction != "edit") return;
  saveButton = document.getElementById("wpSave");
  if (!saveButton) return;
  saveButton.disabled = true;
  saveButton.value = "Save page (use preview first)";
  saveButton.style.fontWeight = "normal";
  document.getElementById("wpPreview").style.fontWeight = "bold";
}
addOnloadHook(forcePreview);


//Overrides the function with the same name in http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
//Fixes a bug: for the sorting order, takes the whole number, not the number before the second comma. 
//Also, removes spaces. See [[Help:Sorting]].
function ts_parseFloat(num) {
	if (!num) return 0;
     num = removeSpaces(num);
	num = parseFloat(num.replace(/,/g, ""));
	return (isNaN(num) ? 0 : num);
}

//Keep spaces in "currency" mode, to sort a range "70 to 80" at 70, not 7080
function ts_parseFloat_ks(num) {
	if (!num) return 0;
	num = parseFloat(num.replace(/,/g, ""));
	return (isNaN(num) ? 0 : num);
}

//Auxiliary function for function ts_resortTable(lnk)
function removeSpaces(string) {
        var tstring = "";
        string = '' + string;
        splitstring = string.split(" ");
        for(i = 0; i < splitstring.length; i++)
        tstring += splitstring[i];
        return tstring;
}

//Overrides the function with the same name in http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
//Changes the criteria for various sorting modes, see [[Help:Sorting]].
//For easy maintenance the difference with wikibits.js is kept limited to a few lines.
function ts_resortTable(lnk) {
	// get the span
	var span = lnk.getElementsByTagName('span')[0];

	var td = lnk.parentNode;
	var tr = td.parentNode;
	var column = td.cellIndex;

	var table = tr.parentNode;
	while (table && !(table.tagName && table.tagName.toLowerCase() == 'table'))
		table = table.parentNode;
	if (!table) return;

	// Work out a type for the column
	if (table.rows.length <= 1) return;

	// Skip the first row if that's where the headings are
	var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1);

	var itm = "";
	for (var i = rowStart; i < table.rows.length; i++) {
		if (table.rows[i].cells.length > column) {
			itm = ts_getInnerText(table.rows[i].cells[column]);
			itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, "");
			if (itm != "") break;
		}
	}

	sortfn = ts_sort_caseinsensitive;
     itmns = removeSpaces(itm);
     if (itmns.match(/^[\d\.\,\-\+]+\%?$/)) sortfn = ts_sort_numeric;
     if (itmns.match(/^[\d\.\,\-\+]+[eE][\d\-\+]+\%?$/)) sortfn = ts_sort_numeric;
     if (itmns.match(/^[\d\.\,\-\+]+e[\d\-\+]+\u00d710[\d\-\+]+\%?$/)) sortfn = ts_sort_numeric;
	if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^[\u00a3$\u20ac\u00a5]/)) // pound dollar euro yen
		sortfn = ts_sort_currency;
     if (itm.match(/sm=c$/)) sortfn = ts_sort_currency;
     if (itm.match(/sm=d$/)) sortfn = ts_sort_date;
     if (itm.match(/sm=n$/)) sortfn = ts_sort_numeric;

	var reverse = (span.getAttribute("sortdir") == 'down');

	var newRows = new Array();
	for (var j = rowStart; j < table.rows.length; j++) {
		var row = table.rows[j];
		var keyText = ts_getInnerText(row.cells[column]);
		var oldIndex = (reverse ? -j : j);

		newRows[newRows.length] = new Array(row, keyText, oldIndex);
	}

	newRows.sort(sortfn);

	var arrowHTML;
	if (reverse) {
			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');
	}

	// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
	// don't do sortbottom rows
	for (var i = 0; i < newRows.length; i++) {
		if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1)
			table.tBodies[0].appendChild(newRows[i][0]);
	}
	// do sortbottom rows only
	for (var i = 0; i < newRows.length; i++) {
		if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1)
			table.tBodies[0].appendChild(newRows[i][0]);
	}

	// Delete any other arrows there may be showing
	var spans = getElementsByClassName(tr, "span", "sortarrow");
	for (var i = 0; i < spans.length; i++) {
		spans[i].innerHTML = '<img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/>';
	}
	span.innerHTML = arrowHTML;

	ts_alternate(table);		
}

function ts_dateToSortKey(date) {	
	// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
	if (date.length > 10) {
		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) {
			return date.substr(6,4)+date.substr(3,2)+date.substr(0,2);
	} else if (date.length == 8) {
		yr = date.substr(6,2);
		if (parseInt(yr) < 50) { 
			yr = '20'+yr; 
		} else { 
			yr = '19'+yr; 
		}
			return yr+date.substr(3,2)+date.substr(0,2);
	}
	return "00000000";
}

function ts_sort_currency(a,b) {
	var aa = ts_parseFloat_ks(a[1].replace(/[\u00a3$\u20ac\u00a5a-zA-Z]/g,''));
	var bb = ts_parseFloat_ks(b[1].replace(/[\u00a3$\u20ac\u00a5a-zA-Z]/g,''));
	return (aa != bb ? aa - bb : a[2] - b[2]);
}

 /** Collapsible tables *********************************************************
  *
  *  Description: Allows tables to be collapsed, showing only the header. See
  *               [[Wikipedia:NavFrame]].
  *  Maintainer on Wikipedia: [[User:R. Koot]]
  */
 
 var autoCollapse = 2;
 var collapseCaption = "hide";
 var expandCaption = "show";
 
 function hasClass( element, className ) {
  var Classes = element.className.split( " " );
  for ( var i = 0; i < Classes.length; i++ ) {
    if ( Classes[i] == className ) {
      return ( true );
    }
  }
  return ( false );
 }

 function collapseTable( tableIndex )
 {
     var Button = document.getElementById( "collapseButton" + tableIndex );
     var Table = document.getElementById( "collapsibleTable" + tableIndex );
 
     if ( !Table || !Button ) {
         return false;
     }
 
     var Rows = Table.getElementsByTagName( "tr" ); 
 
     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" ) ) {
             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 );
 
             Button.style.styleFloat = "right";
             Button.style.cssFloat = "right";
             Button.style.fontWeight = "normal";
             Button.style.textAlign = "right";
             Button.style.width = "6em";
 
             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( "]" ) );
 
             var Header = Tables[i].getElementsByTagName( "tr" )[0].getElementsByTagName( "th" )[0];
             /* only add button and increment count if there is a header row to work with */
             if (Header) {
                 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 );
         }
     }
 }
 
 addOnloadHook( createCollapseButtons );

//Shuffle for election candidates
function dshuf(){
                var shufsets=new Object()
                var rx=new RegExp('dshuf'+'\\s+(dshufset\\d+)', 'i') 
                var divs=document.getElementsByTagName("div")
                for (var i=0; i<divs.length; i++){
                        if (rx.test(divs[i].className)){
                                if (typeof shufsets[RegExp.$1]=="undefined"){ 
                                        shufsets[RegExp.$1]=new Object() 
                                        shufsets[RegExp.$1].inner=[] 
                                        shufsets[RegExp.$1].member=[]
                                }
                                        shufsets[RegExp.$1].inner.push(divs[i].innerHTML) 
                                        shufsets[RegExp.$1].member.push(divs[i]) 
                        }
                }
                for (shufset in shufsets){
                        shufsets[shufset].inner.sort(function() {return 0.5 - Math.random()})
                        for (var i=0; i<shufsets[shufset].member.length; i++){
                                shufsets[shufset].member[i].innerHTML=shufsets[shufset].inner[i]
                                shufsets[shufset].member[i].style.display="block"
                        }
                }

}

addOnloadHook(dshuf);

/*************
*** AJAX transclusion table <http://meta.wikimedia.org/wiki/User:Pathoschild/Scripts/AJAX_transclusion_table>
*** by [[m:user:Pathoschild]]
*************/
function attLoader() {
	if(getElementsByClassName(document.getElementsByTagName('body')[0],'table','attable').length) {
	        document.write('<script type="text/javascript" src="'
	          + 'http://meta.wikimedia.org/w/index.php?title=User:Pathoschild/Scripts/AJAX_transclusion_table.js' 
	          + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');
	}
}
addOnloadHook(attLoader);

/** JSconfig ************
 * Global configuration options to enable/disable and configure
 * specific script features from [[MediaWiki:Common.js]] and
 * [[MediaWiki:Monobook.js]]
 * This framework adds config options (saved as cookies) to [[Special:Preferences]]
 * For a more permanent change you can override the default settings in your 
 * [[Special:Mypage/monobook.js]]
 * for Example: JSconfig.keys[loadAutoInformationTemplate] = false;
 *
 *  Maintainer: [[User:Dschwen]]
 */
 
var JSconfig =
{
 prefix : 'jsconfig_',
 keys : {},
 meta : {},
 
 //
 // Register a new configuration item
 //  * name          : String, internal name
 //  * default_value : String or Boolean (type determines configuration widget)
 //  * description   : String, text appearing next to the widget in the preferences
 //  * prefpage      : Integer (optional), section in the preferences to insert the widget:
 //                     0 : User profile
 //                     1 : Skin
 //                     2 : Math
 //                     3 : Files
 //                     4 : Date and time
 //                     5 : Editing
 //                     6 : Recent changes
 //                     7 : Watchlist
 //                     8 : Search
 //                     9 : Misc
 //
 // Access keys through JSconfig.keys[name]
 //
 registerKey : function( name, default_value, description, prefpage )
 {
  if( typeof(JSconfig.keys[name]) == 'undefined' ) 
   JSconfig.keys[name] = default_value;
  else {
 
   // all cookies are read as strings, 
   // convert to the type of the default value
   switch( typeof(default_value) )
   {
    case 'boolean' : JSconfig.keys[name] = ( JSconfig.keys[name] == 'true' ); break;
    case 'number'  : JSconfig.keys[name] = JSconfig.keys[name]/1; break;
   }
 
  }
 
  JSconfig.meta[name] = { 'description' : description, 'page' : prefpage || 0, 'default_value' : default_value };
 },
 
 readCookies : function()
 {
  var cookies = document.cookie.split("; ");
  var p =JSconfig.prefix.length;
  var i;
 
  for( var key in cookies )
  {
   if( cookies[key].substring(0,p) == JSconfig.prefix )
   {
    i = cookies[key].indexOf('=');
    //alert( cookies[key] + ',' + key + ',' + cookies[key].substring(p,i) );
    JSconfig.keys[cookies[key].substring(p,i)] = cookies[key].substring(i+1);
   }
  }
 },
 
 writeCookies : function()
 {
  for( var key in JSconfig.keys )
   document.cookie = JSconfig.prefix + key + '=' + JSconfig.keys[key] + '; path=/; expires=Thu, 2 Aug 2009 10:10:10 UTC';
 },
 
 evaluateForm : function()
 {
  var w_ctrl,wt;
  //alert('about to save JSconfig');
  for( var key in JSconfig.meta ) {
   w_ctrl = document.getElementById( JSconfig.prefix + key )
   if( w_ctrl ) 
   {
    wt = typeof( JSconfig.meta[key].default_value );
    switch( wt ) {
     case 'boolean' : JSconfig.keys[key] = w_ctrl.checked; break;
     case 'string' : JSconfig.keys[key] = w_ctrl.value; break;
    }
   }
  }
 
  JSconfig.writeCookies();
  return true;
 },
 
 setUpForm : function()
 { 
  var prefChild = document.getElementById('preferences');
  if( !prefChild ) return;
  prefChild = prefChild.childNodes;
 
  //
  // make a list of all preferences sections
  //
  var tabs = new Array;
  var len = prefChild.length;
  for( var key = 0; key < len; key++ ) {
   if( prefChild[key].tagName &&
       prefChild[key].tagName.toLowerCase() == 'fieldset' ) 
    tabs.push(prefChild[key]);
  }
 
  //
  // Create Widgets for all registered config keys
  //
  var w_div, w_label, w_ctrl, wt;
  for( var key in JSconfig.meta ) {
   w_div = document.createElement( 'DIV' );
 
   w_label = document.createElement( 'LABEL' );
   w_label.appendChild( document.createTextNode( JSconfig.meta[key].description ) )
   w_label.htmlFor = JSconfig.prefix + key;
 
   wt = typeof( JSconfig.meta[key].default_value );
 
   w_ctrl = document.createElement( 'INPUT' );
   w_ctrl.id = JSconfig.prefix + key;
 
   // before insertion into the DOM tree
   switch( wt ) {
    case 'boolean' : w_ctrl.type = 'checkbox'; break;
    case 'string'  : w_ctrl.type = 'text'; break;
   }
 
   w_div.appendChild( w_label );
   w_div.appendChild( w_ctrl );
   tabs[JSconfig.meta[key].page].appendChild( w_div );
 
   // after insertion into the DOM tree
   switch( wt ) {
    case 'boolean' : w_ctrl.defaultChecked = w_ctrl.checked = JSconfig.keys[key]; break;
    case 'string' : w_ctrl.defaultValue = w_ctrl.value = JSconfig.keys[key]; break;
   }
 
  }
  addHandler(document.getElementById('preferences').parentNode, 'submit', JSconfig.evaluateForm );
 }
}
 
JSconfig.readCookies();
addOnloadHook(JSconfig.setUpForm);

// ability to pull [[MediaWiki:Gadget-rtl.css]] on individual page loads by [[testwiki:User:Splarka]] and [[wm2008:User:Mr.Z-man]]
function importStylesheet(page) {
  if (page.indexOf('http://') == -1 && page.indexOf('https://') == -1 && page.indexOf('file:///') == -1)
     page = wgScript + '?action=raw&ctype=text/css&smaxage=0&title='
     + encodeURIComponent(page.replace(/ /g,'_'))
  return document.createStyleSheet ? document.createStyleSheet(page) : appendCSS('@import "' + page + '";')
}
 
function appendCSS(text){
 var s = document.createElement('style')
 s.setAttribute('type', 'text/css')
 if (s.styleSheet) s.styleSheet.cssText = text //IE
 else s.appendChild(document.createTextNode(text))
 document.getElementsByTagName('head')[0].appendChild(s)
 return s
}
 
if(document.URL.indexOf('rtl=1') != -1) importStylesheet('http://meta.wikimedia.org/w/index.php?title=MediaWiki:Gadget-rtl.css&action=raw&ctype=text/css');

//import module
importedScripts = {} 
function importScript(page, lang) {
 page = '?title=' + encodeURIComponent(page.replace(' ','_'))
 if (lang) page = 'http://' + lang + '.wikipedia.org/w/index.php' + page
 else page = wgScript + page
 if (importedScripts[page]) return
 importedScripts[page] = true
 var s = document.createElement('script')
 s.type = 'text/javascript'
 s.src = page + '&action=raw&ctype=text/javascript'
 document.getElementsByTagName('head')[0].appendChild(s)
}