MediaWiki:Common.js

From LIMSWiki
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */

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

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

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

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

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

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

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

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

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

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

	event.preventDefault();
}

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

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

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

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

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

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

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

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

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

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

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

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

    event.preventDefault();
};

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

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

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

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

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

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