MediaWiki talk:Common.js

/*'''Click edit to see a readable version. Once done changing, copy and paste into this and throw the output in MediaWiki:Common.js'''.

Wikipedia Common.js
*/ /* Import more specific scripts if necessary */ if (wgAction == "edit" || wgAction == "submit" || wgPageName == "Special:Upload") //scripts specific to editing pages {   importScript("MediaWiki:Common.js/edit.js") } else if (wgPageName == "Special:Watchlist") //watchlist scripts {   importScript("MediaWiki:Common.js/watchlist.js") } else if (wgPageName == "Special:Search") //scripts specific to Special:Search {   importScript("MediaWiki:Common.js/search.js") } /*

Got class?
*/ /* 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);   }; }); /*

IE-specific fixes
*/ /** Internet Explorer bug fix ************************************************** * *  Description: Fixes IE horizontal scrollbar bug * Maintainers: User:Tom-? */

if (navigator.appName == "Microsoft Internet Explorer") {   var oldWidth; var docEl = document.documentElement;

function fixIEScroll {       if (!oldWidth || docEl.clientWidth > oldWidth) doFixIEScroll; else setTimeout(doFixIEScroll, 1);

oldWidth = docEl.clientWidth; }

function doFixIEScroll { docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? "hidden" : ""; }

document.attachEvent("onreadystatechange", fixIEScroll); document.attachEvent("onresize", fixIEScroll);

/**    * Remove need for CSS hacks regarding MSIE and IPA. */

if (document.createStyleSheet) { document.createStyleSheet.addRule('.IPA', 'font-family: "Doulos SIL", "Charis SIL", Gentium, "DejaVu Sans", Code2000, "TITUS Cyberbit Basic", "Arial Unicode MS", "Lucida Sans Unicode", "Chrysanthi Unicode";'); }

//Import scripts specific to Internet Explorer 6 if (navigator.appVersion.substr(22, 1) == "6") {       importScript("MediaWiki:Common.js/IE60Fixes.js") } } /*

Collapsible tables
*/ /** Collapsible tables ********************************************************* * * Description: Allows tables to be collapsed, showing only the header. See *              NavFrame. * Maintainers: 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 );

Button.className = "collapseButton"; //Styles are declared in Common.css

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 ); /*

Dynamic navigation bars
*/ /** Dynamic Navigation Bars (experimental) ************************************* * *  Description: See NavFrame. * Maintainers: UNMAINTAINED */

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

// shows and hides content and picture (if available) of navigation bars // Parameters: //    indexNavigationBar: the index of navigation bar to be toggled function toggleNavigationBar(indexNavigationBar) {   var NavToggle = document.getElementById("NavToggle" + indexNavigationBar); var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);

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

// 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 -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 isCollapsed = hasClass( NavFrame, "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 (var NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling) { if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, 'NavContent' ) ) { if ( NavChild.style.display == 'none' ) { isCollapsed = true; }               }            }            if (isCollapsed) { for (var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) { if ( hasClass( NavChild, 'NavPic' ) || hasClass( NavChild, '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 (hasClass(NavFrame.childNodes[j], "NavHead")) { NavFrame.childNodes[j].appendChild(NavToggle); }           }            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar); }   } }

addOnloadHook( createNavigationBarToggleButton ); /*

Main Page fixes
*/ /** Main Page layout fixes ********************************************************* * * Description: Adds an additional link to the complete list of languages available. * Maintainers: User:AzaToth, User:R. Koot, User:Alex Smotrov * Language list removed */

if (wgPageName == 'Main_Page' || wgPageName == 'Talk:Main_Page') addOnloadHook(function {        var nstab = document.getElementById('ca-nstab-main')        if (nstab && wgUserLanguage=='en')            nstab.firstChild.firstChild.nodeValue = 'Main Page'    } ) /*

Technical Restrictions fixes
*/

/** "Technical restrictions" title fix ***************************************** * * Description: For pages that have something like Template:Wrongtitle, replace *              the title, but only if it is cut-and-pasteable as a valid *              wikilink. For instance, "NZR WB class" can be changed to *              "NZR WB class", but C is not an equivalent wikilink, *              so C Sharp doesn't have its main title changed. * *              The function looks for a banner like this: *              ... title ...  *  Maintainers: Remember_the_dot */ if (wgAction == "view") //prevents "Editing " from disappearing during preview {   addOnloadHook(function    {        var realTitle = document.getElementById("RealTitle")        if (realTitle)        {            //normalizes a title or a namespace name (but not both)            //trims leading and trailing underscores and converts (possibly multiple) spaces and underscores to single underscores            function normalizeTitle(title)            {                return title.replace(/^_+/, "").replace(/_+$/, "").replace(/[\s_]+/g, "_")            }            if (realTitle.textContent) //everyone but IE            {                var realTitleText = realTitle.textContent            }            else //IE            {                var realTitleText = realTitle.innerText            }            var normalizedRealTitle            var normalizedPageTitle            var indexOfColon = realTitleText.indexOf(":")            var normalizedNamespaceName = normalizeTitle(realTitleText.substring(0, indexOfColon)).toLowerCase //make namespace prefix lowercase and uppercase the first letter of the title if (indexOfColon == -1 || wgCanonicalNamespace.toLowerCase != normalizedNamespaceName) //no namespace prefix - either no colon or a nonsensical namespace prefix (for example, "Foo" in "Foo: The Story of My Life") {               normalizedRealTitle = normalizeTitle(realTitleText) normalizedRealTitle = normalizedRealTitle.charAt(0).toUpperCase + normalizedRealTitle.substring(1) normalizedPageTitle = wgPageName.charAt(0).toUpperCase + wgPageName.substring(1) }           else //using a namespace prefix {               var normalizedRealPageTitle = normalizeTitle(realTitleText.substring(indexOfColon + 1)) normalizedRealTitle = normalizedNamespaceName if (normalizedNamespaceName != "") //namespace 0 is a special case where the leading colon should never be shown {                   normalizedRealTitle += ":" }               normalizedRealTitle += normalizedRealPageTitle.charAt(0).toUpperCase + normalizedRealPageTitle.substring(1) normalizedPageTitle = wgPageName.substring(0, wgPageName.indexOf(":") + 1).toLowerCase + wgPageName.substring(wgPageName.indexOf(":") + 1) }           if (normalizedRealTitle == normalizedPageTitle) //normalized titles match, so we can do full replacement {               var h1 = document.getElementsByTagName("h1")[0] //remove all child nodes, including text while (h1.firstChild) {                   h1.removeChild(h1.firstChild) }               //populate with nodes of real title while (realTitle.firstChild) //the children are moved to a new parent element {                   h1.appendChild(realTitle.firstChild) }               //correct the page title document.title = realTitleText + " - Wikipedia, the free encyclopedia" //delete the real title banner since the problem is solved var realTitleBanner = document.getElementById("RealTitleBanner") if (realTitleBanner) realTitleBanner.parentNode.removeChild(realTitleBanner) }       }    }) }

/*

Sysop-only JS
*/ /** Sysop Javascript ******************************************************* * * Description: Allows for sysop-specific Javascript at MediaWiki:Sysop.js. * Created by: User:^demon */ function sysopFunctions { if ( wgUserGroups && !window.disableSysopJS ) { for ( var g = 0; g < wgUserGroups.length; ++g ) { if ( wgUserGroups[g] == "sysop" ) { importScript( "MediaWiki:Sysop.js" ); break; }       }    } }

addOnloadHook( sysopFunctions ); /*

Featured template
*/ // Move the featured star so it's visible even when the ToC's hidden addOnloadHook(featured_template);

function featured_template { if(document.getElementById('featured_icon')) {   var bodyContent=document.getElementById('bodyContent'); bodyContent.insertBefore(document.getElementById('featured_icon'),bodyContent.childNodes[0]); } } /*

OpenSearch
*/ // OpenSearch link addOnloadHook(open_search_links); function open_search_links { // For the moment, I'll do it by ID in a span, but in future it may be a good idea to do it by class if((document.getElementById('open_search')) && (document.getElementById('open_search').nodeName=='SPAN')) { var link=document.getElementById('open_search').childNodes[0]; addHandler(link, 'click', add_open_search); } }

function add_open_search(event) { if((typeof(window.external)=="object") && ((typeof(window.external.AddSearchProvider)=="unknown") || (typeof(window.external.AddSearchProvider)=="function"))) window.external.AddSearchProvider("http://strategywiki.org/w/opensearch_desc.php"); else window.alert("You will need a browser which supports OpenSearch to install this plugin, such as Mozilla Firefox."); event.preventDefault; event.returnValue=false; return false; } /*

Check upload categories
*/ // Image upload categories addOnloadHook(upload_categories); function upload_categories { if((document.getElementById('upload')) && (document.getElementById('upload').nodeName=='FORM')) { var upload_form=document.getElementById('upload'); addHandler(upload_form, 'submit', check_upload_categories); } }

function check_upload_categories(event) { var description=document.getElementById('wpUploadDescription').value; if((description.indexOf('[[Category')==-1) && (description.indexOf('[[category')==-1)) {   window.alert('Please add some categories to the "Summary" field. Our image categorisation policy can be found at http://strategywiki.org/wiki/StrategyWiki:Images.');    event.preventDefault;    event.returnValue=false;    return false;  } } /*

Control Selector template
*/ // Created by User:Prod with help from User:DrBob function selectControlSet {   // iterate over all -elements var spans = document.getElementsByTagName("span"); for (var i=0; ControlOpt = spans[i]; i++ ) { if (hasClass(ControlOpt, "controlOpt")) { if (hasClass(ControlOpt, 'control' + document.getElementById('control_selector_select').value)) ControlOpt.style.display = 'inline' else ControlOpt.style.display = 'none' }   }  }

function createControlSelector {   var controlDiv = document.getElementById("control_selector_inner");

if (!controlDiv) return false; var ControlSelector = document.createElement("select"); ControlSelector.className = 'ControlSet'; ControlSelector.id = 'control_selector_select'; addHandler(ControlSelector, 'change', selectControlSet);

var sysText = controlDiv.textContent; if(!sysText) sysText = controlDiv.innerText; // Support IE in its backwards ways if(!sysText) return false; sysTexts = sysText.split(','); for (var i=0; i < Math.min(5, sysTexts.length); i++){ ControlSelector.options[i] = new Option(sysTexts[i].replace(/^\s+|\s+$/g, ''), i); }   if(controlDiv.textContent) controlDiv.textContent = ''; else if(controlDiv.innerText) controlDiv.innerText = ''; controlDiv.appendChild(ControlSelector); controlDiv.parentNode.style.display = 'block'; } addOnloadHook( createControlSelector ); /*

Google Calendar
*/ /************************ function displayCalendar { var cal = document.getElementById('google-calendar'); //only allow one per page if(!cal) return; var calframe = document.createElement('iframe'); calframe.src = 'http://www.google.com/calendar/embed?src=qk4t1di1u3song0vqo39o0ribo%40group.calendar.google.com'; calframe.style.border = '0'; calframe.width = '800'; calframe.height = '600'; calframe.frameborder = '0'; calframe.scrolling = 'no'; cal.appendChild(calframe); } addOnloadHook(displayCalendar); /*
 * Google Calendar  **
 * author Ryan Schmidt **

Redirect ToC edit link to /Table of Contents
*/ /****************** /* function fixToCLink{ var mainPageLink = document.getElementById('ca-nstab-main') var ToCLink = document.getElementById('editToC') if (!mainPageLink || !ToCLink) { return false; } mainPageLink = mainPageLink.getElementsByTagName('a')[0].href; ToCLink.getElementsByTagName('a')[0].href = mainPageLink.substring(mainPageLink.indexOf('/wiki/')) + '/Table_of_Contents?action=edit'; } addOnloadHook(fixToCLink); /*
 * Fix ToC Links **
 * author Prod **

Alexa Graphs
*/ /************************ function addAlexaGraphs { var wrapper = document.getElementById('alexa-graph'); //only allow one per page if(!wrapper) return; var br = document.createElement('br'); br.style.clear = "both"; var img1 = document.createElement('img'); var img2 = document.createElement('img'); var img3 = document.createElement('img'); var time = wrapper.innerHTML; wrapper.innerHTML = ''; img1.src = "http://traffic.alexa.com/graph?c=1&f=555555&u=strategywiki.org&u=&u=&u=&u=&r="+time+"&y=r&z=3&h=300&w=610" img2.src = "http://traffic.alexa.com/graph?c=1&f=555555&u=strategywiki.org&u=&u=&u=&u=&r="+time+"&y=n&z=3&h=300&w=610" img3.src = "http://traffic.alexa.com/graph?c=1&f=555555&u=strategywiki.org&u=&u=&u=&u=&r="+time+"&y=p&z=3&h=300&w=610" wrapper.appendChild(img1); wrapper.appendChild(br); wrapper.appendChild(img2); wrapper.appendChild(br); wrapper.appendChild(img3); } addOnloadHook(addAlexaGraphs); /* */
 * Alexa Graphs   **
 * author Ryan Schmidt **