MediaWiki:Common.js
From Dungeons and Dragons Wiki
/* 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; } } } $(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 ); } } } $(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');