MediaWiki:Common.js

From Dungeons and Dragons Wiki
Revision as of 03:29, 27 October 2016 by Surgo (talk | contribs) (add temporary google analytics code)
Jump to: navigation, search
/* Any JavaScript here will be loaded for all users on every page load. */

/* Source: http://www.dustindiaz.com/getelementsbyclass/ getElementsByClass,
 * which complements getElementById and getElementsByTagName, returns an array
 * of all subelements of ''node'' that are tagged with a specific CSS class
 * (''searchClass'') and are of the tag name ''tag''. If tag is null, it
 * searches for any suitable elements regardless of the tag name.  Example:
 * getElementsByClass('infobox', document.getElementById('content'), 'div')
 * selects the same elements as the CSS declaration #content div.infobox
 */
function getElementsByClass(searchClass, node, tag) {
   var classElements = new Array();
   
   if(node == null) node = document;
   
   if(tag == null) tag = '*';
   
   var els = node.getElementsByTagName(tag);
   var elsLen = els.length;
   var tester = new ClassTester(searchClass);
   
   for(i = 0, j = 0; i < elsLen; i++) {
       if(tester.isMatch(els[i])) {
           classElements[j] = els[i];
           j++;
       }
   }
   return classElements;
}
function ClassTester(className) {
   this.regex = new RegExp('(^|\\s)' + className + '(\\s|$)');
}
ClassTester.prototype.isMatch = function(element) {
   return this.regex.test(element.className);
}
// end getElementsByClass

function addAlternatingRowColors()
{
    var tables = getElementsByClass('zebra', document.getElementById('content'));

    if(tables.length == 0)
        return;

    for(var k = 0; k < tables.length; k++) {
        var table = tables[k];
        var rows = table.getElementsByTagName('tr');
        var changeColor = false;

        for(var i = 0; i < rows.length; i++)
        {
            if(rows[i].className.indexOf('noalt') != -1)
               continue;
            if(rows[i].className.indexOf('stopalt') != -1)
                break;

            var ths = rows[i].getElementsByTagName('th');

            if(ths.length > 0)
            {
                changeColor = true;
                if (table.className.indexOf('FifthEd') != -1)
                    continue;
                rows[i].className = "odd";
            }

            if(changeColor)
                rows[i].className = "odd";
            else
                rows[i].className = "even";

            changeColor = !changeColor;
        }
    }
}
addOnloadHook(addAlternatingRowColors);

// Also, make the "sortable" tables striped. This overrides wikibits.js
var ts_alternate_row_colors = true;

// Hit me baby, one more time!

if ( !Array.prototype.indexOf )
{
    Array.prototype.indexOf = function( elt /*, from*/ )
    {
        var len = this.length;
        var from = Number( arguments[1] ) || 0;
        from = from < 0 ? Math.ceil( from ) : Math.floor( from );

        if ( from < 0 )
            from += len;

        for ( ; from < len; from++ )
        {
            if ( from in this && this[from] === elt )

            return from;
        }

        return -1;
    };
}


// Collapsible tables

var hasClass = (function() {
	var reCache = {};
	return function( element, className ) {
		return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
	};
})();

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 MediaWiki: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 );
		}
	}
}

addOnloadHook( createCollapseButtons );

/**
 * Find the user navbox, which is identified by the id #dynamic_user_navbox,
 * and append an [Expand] link to the header. The [Expand] link will
 * load the navbox contents dynamically when the user clicks it.
 *
 */
jQuery(document).ready(function($) {
    var $expandSpan = $("<span>");
    $expandSpan.addClass("mw-collapsible-toggle");

    var $expandLink = $("<a>",
        {
            text: '[Expand]',
            href: '#dynamic_user_navbox',
            click: function() {
                loadUserNavboxContents();
            }
        }
    );
    $expandSpan.append($expandLink);

    $("#dynamic_user_navbox th").append($expandSpan);
});

function loadUserNavboxContents() {
    //Attach the spinner icon while the content loads
    var $loadingSpinnerRow = $("<tr>");
    var $loadingSpinnerCol = $("<td>");
    $loadingSpinnerCol.attr('colSpan', "" + 3 + "");
    $loadingSpinnerCol.attr('style', 'text-align:left; vertical-align:middle;');

    var $loadingSpinnerImage = $("<img>");
    $loadingSpinnerImage.attr('src', 'http://dnd-wiki.org/w/images/4/44/Spinner.gif');

    $loadingSpinnerCol.append($loadingSpinnerImage);
    $loadingSpinnerCol.append("  Loading...");    
    $loadingSpinnerRow.append($loadingSpinnerCol);
    $("#dynamic_user_navbox").append($loadingSpinnerRow);

    //The user navbox has an html data attribute called "data-author", which
    //is used to store the author's name. This author name corresponds directly
    //to a url for the author's fully opened navbox.
    var author = $("#dynamic_user_navbox").attr('data-author');
    var navboxPath = 'NavBox/' + author;
    var navboxUrl = '/wiki/' + navboxPath;
    $.get(navboxUrl)
        .done(function(data) {
            //The user_navbox with the full content replaces the loader navbox
            var $html = $(data);
            var navbox = $html.find("#user_navbox");
            if(navbox.length > 0) {
                $("#dynamic_user_navbox").replaceWith(navbox[0]);
            } else {
                //Detach the spinner
                $loadingSpinnerRow.detach();
                //Error condition -- no navbox found
                var $noNavboxRow = $("<tr>");
                var $noNavboxCol = $("<td>");
                $noNavboxCol.attr('colSpan', "" + 3 + "");
                $noNavboxCol.attr('style', 'text-align:left; vertical-align:middle;');
                $noNavboxCol.append("No user navbox data was found. If this is your navbox, check"
                    + " <a href='"+navboxUrl+"'>"+navboxPath+"<a> to see if it is"
                    + " configured correctly. You can also message one of the"
                    + "<a href='/w/index.php?title=Special%3AListUsers&username=&group=sysop&limit=50'>Administrators<a>"
                    + " if you have any questions.");
                $noNavboxRow.append($noNavboxCol);
                $("#dynamic_user_navbox").append($noNavboxRow);
            }
        })
        .fail(function(jqxhr, textStatus, error) {
            var errorMessage = textStatus + ", " + error;
            //Detach the spinner
            $loadingSpinnerRow.detach();
            //Error condition -- no navbox found
            var $failNavboxRow = $("<tr>");
            var $failNavboxCol = $("<td>");
            $failNavboxCol.attr('colSpan', "" + 3 + "");
            $failNavboxCol.attr('style', 'text-align:left; vertical-align:middle;');
            $failNavboxCol.append("Failed to load the user's navbox: " + errorMessage);
            $failNavboxRow.append($failNavboxCol);
            $("#dynamic_user_navbox").append($failNavboxRow);
        }
    ); 
}

/* Temporary Google Analytics code. */
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-86274219-1', 'auto');
ga('send', 'pageview');