MediaWiki:Common.js
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: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
// This is the non-compressed version of MediaWiki:Common.js // External links open in new windows/tabs: $('a.external').attr('target', '_blank'); /** Collapsible tables ********************************************************* * * Description: Allows tables to be collapsed, showing only the header. See * [[Wikipedia:NavFrame]]. * Maintainers: [[User:R. Koot]] */ 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 collapseCaptionLang = {'ar': 'أخف', 'cs': 'sbalit', 'da': 'fold sammen', 'de': 'einklappen', 'es': 'contraer', 'fi': 'supista', 'fr': 'masquer', 'hu': 'becsuk', 'it': 'comprimi', 'ja': '折り畳む', 'ko': '접기', 'nl': 'samenvouwen', 'pl': 'zwiń', 'pt': 'ocultar', 'pt-br': 'ocultar', 'ro': 'restrânge', 'ru': 'свернуть', 'sv': 'dölj', 'tr': 'daralt', 'zh-hans': '折叠', 'zh-hant': '合併'}; var expandCaptionLang = {'ar': 'أظهر', 'cs': 'rozbalit', 'da': 'fold ud', 'de': 'ausklappen', 'es': 'expandir', 'fi': 'Laajenna', 'fr': 'afficher', 'hu': 'kinyit', 'it': 'espandi', 'ja': '展開する', 'ko': '펼치기', 'nl': 'uitvouwen', 'pl': 'rozwiń', 'pt': 'expandir', 'pt-br': 'expandir', 'ro': 'extinde', 'ru': 'развернуть', 'sv': 'visa', 'tr': 'genişlet', 'zh-hans': '展开', 'zh-hant': '展開'}; var collapseCaption = collapseCaptionLang[mw.config.get("wgPageName").split("/").pop()] || 'collapse'; var expandCaption = expandCaptionLang[mw.config.get("wgPageName").split("/").pop()] || 'expand'; window.collapseTable = function ( tableIndex ) { var Button = document.getElementById( 'collapseButton' + tableIndex ); var Table = document.getElementById( 'collapsibleTable' + tableIndex ); if ( !Table || !Button ) { return false; } var Rows = Table.rows; var i; if ( Button.firstChild.data === collapseCaption ) { for ( i = 1; i < Rows.length; i++ ) { Rows[i].style.display = 'none'; } Button.firstChild.data = expandCaption; } else { for ( 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 = {}; var Tables = document.getElementsByTagName( 'table' ); var i; function handleButtonLink( index, e ) { window.collapseTable( index ); e.preventDefault(); } for ( i = 0; i < Tables.length; i++ ) { if ( $( Tables[i] ).hasClass( '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', '#' ); $( ButtonLink ).on( 'click', $.proxy( handleButtonLink, ButtonLink, tableIndex ) ); ButtonLink.appendChild( ButtonText ); Button.appendChild( document.createTextNode( '[' ) ); Button.appendChild( ButtonLink ); Button.appendChild( document.createTextNode( ']' ) ); Header.insertBefore( Button, Header.firstChild ); tableIndex++; } } for ( i = 0; i < tableIndex; i++ ) { if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) || ( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) ) ) { window.collapseTable( i ); } else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) { var element = NavigationBoxes[i]; while ((element = element.parentNode)) { if ( $( element ).hasClass( 'outercollapse' ) ) { window.collapseTable ( i ); break; } } } } } $( createCollapseButtons ); /** Dynamic Navigation Bars (experimental) ************************************* * * Description: See [[Wikipedia: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, 'NavContent') || hasClass(NavChild, 'NavPic')) { 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, 'NavContent') || hasClass(NavChild, 'NavPic')) { 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 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")) { NavToggle.style.color = NavFrame.childNodes[j].style.color; NavFrame.childNodes[j].appendChild(NavToggle); } } NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar); } } } $( createNavigationBarToggleButton ); //END Collapsible tables ********************************************************* // PootTabs by User:WindPower~ // It puts tabs on pages. var pootTabsHere = { animationsEnabled: $.support.opacity, getTab:function(poot, index) { return $(poot.children('.poot-tabs').children('ul').children('li')[parseInt(index)]); }, changeTab:function(poot, index, duration, force) { if(index == parseInt(poot.attr('pootSelected')) && !force && duration) return; if(!pootTabsHere.animationsEnabled) { duration = 0; } poot.attr('pootSelected', index.toString()); var babies = poot.children('.poot-tabs-content').children(); babies.each(function() { $(this).fadeOut(duration, function(){ $(this).removeClass('poot-tabs-selected'); }); }); $(babies[index]).each(function() { $(this).fadeIn(duration, function(){ $(this).addClass('poot-tabs-selected'); }); }); var cowtabs = poot.children('.poot-tabs').children('ul').children('li'); cowtabs.removeClass('poot-tabs-selected'); $(cowtabs[index]).addClass('poot-tabs-selected'); pootTabsHere.updatePoot(poot, $(babies[index]).height()); }, updatePoot:function(poot, babysize) { if(poot.hasClass('poot-tabs-notitle')) { poot.find('.poot-tabs-titletext').html(pootTabsHere.getTab(poot, poot.attr('pootSelected')).html()); } else { poot.find('.poot-tabs-titletext').html(poot.attr('originalTitle') + ' — ' + pootTabsHere.getTab(poot, poot.attr('pootSelected')).html()); } if(poot.has('.poot-tabs-edittabs') && poot.has('.poot-tabs-navbar')) { try { poot.find('.poot-tabs-navbar').html($(poot.children('.poot-tabs-edittabs').children('span')[parseInt(poot.attr('pootSelected'))]).html()); } catch(e) {} } var bestHeight = Math.max(poot.children('.poot-tabs-content').height(), Math.max(poot.children('.poot-tabs').height(), babysize)).toString() + 'px'; poot.children('.poot-tabs-content').css('height', bestHeight); if(poot.attr('vertical')) { poot.children('.poot-tabs').css('height', bestHeight); } }, toggleCollapse:function(poot) { var pootLinkText = poot.children('.poot-tabs-showhide').text().split(';'); var duration = pootTabsHere.animationsEnabled ? parseInt(poot.attr('pootslideduration')) : 0; if(poot.attr('pootcollapse') != 'true') { poot.attr('pootcollapse', 'true'); poot.find('.poot-tabs-hidelink a').text(pootLinkText[0]); poot.children('.poot-tabs, .poot-tabs-content').slideUp(duration); } else { poot.attr('pootcollapse', ''); poot.find('.poot-tabs-hidelink a').text(pootLinkText[1]); poot.children('.poot-tabs, .poot-tabs-content').slideDown(duration); } }, delayHeight:function(poot, selected) { setTimeout(function() { poot.attr('pootselected', selected.toString()); pootTabsHere.changeTab(poot, selected, 0, true); if(poot.hasClass('poot-tabs-collapsed')) { pootTabsHere.toggleCollapse(poot); } }, 100); }, poot:function() { var dis = $(this); dis.removeClass('poot-tabs-nojs'); // If this thing runs, JS is on var ind = 0; dis.attr('originalTitle', dis.find('.poot-tabs-titletext').html()); var selected = /poot-tabs-selected-(\d+)/i.exec(dis.attr('class')); if(selected) { pootTabsHere.delayHeight(dis, parseInt(selected[1])-1); } else { pootTabsHere.delayHeight(dis, 0); } var duration = dis.hasClass('poot-tabs-noanimations') ? 0 : 200; dis.attr('pootslideduration', dis.hasClass('poot-tabs-noanimations') ? '0' : '75'); dis.children('.poot-tabs').children('ul').children('li').each(function(){ var thisInd = ind; $(this).click(function(){ pootTabsHere.changeTab(dis, thisInd, duration, false); $(this).blur(); $(this).find('*').blur(); return false; }); ind++; }); var isVertical = dis.hasClass('poot-tabs-vertical'); dis.attr('pootvertical', isVertical ? 'true' : ''); if(isVertical) { var teenie = dis.children('.poot-tabs').width().toString() + 'px'; dis.children('.poot-tabs-content').css('margin-left', teenie); } dis.attr('pootcollapse', ''); // False dis.find('.poot-tabs-hidelink a').click(function(){ pootTabsHere.toggleCollapse(dis); return false; }); }, init:function() { $('.poot-tabs-container').each(pootTabsHere.poot); } }; $(pootTabsHere.init); // Language support fixes var langFixes = { init: function() { // Supported list of languages (not including the default one): var langList = ['ar', 'cs', 'da', 'de', 'es', 'fi', 'fr', 'hu', 'it', 'ja', 'ko', 'nl', 'no', 'pl', 'pt', 'pt-br', 'ro', 'ru', 'sv', 'tr', 'zh-hans', 'zh-hant']; // Assumed language if the page is in none of the languages above: var defaultLang = 'en'; var lang = defaultLang; for(var i in langList) { if(mw.config.get('wgPageName').substr(mw.config.get('wgPageName').length - 1 - langList[i].length).toLowerCase() == '/' + langList[i].toLowerCase()) { lang = langList[i]; break; } } $('body').addClass('lang-' + lang); } }; $(langFixes.init); // Main Page event video embed. See documentation on Template:Main Page event var embedHeroVid = { init: function () { var $container = $('.mp-event-container'); var $image = $('.mp-event-image'); var isVideo = !!($container.data('mpEventVideo')); if ($image[0] && isVideo) { var _video = $('<video/>', { muted: true, autoplay: true, loop: true, class: 'mp-event-video' }); embedHeroVid.getSource($container) .done(function (url) { var extension = url[1]; _video.insertAfter($image); $('<source/>', { src: url[0], type: 'video/' + extension }).appendTo(_video); _video[0].oncanplaythrough = function () { $image.remove(); $container.attr('data-video-url', null); }; }); } }, getSource: function (source) { var deferred = $.Deferred(); var url = source.attr('data-video-url'); if (typeof url === 'undefined' || url === '') { throw new Error('Video URL is undefined. If it\'s blank, it is due to the internal file name being incorrect or that the "video-url" parameter is unset.'); } var extension = url.split('/').reverse()[0].split('.')[1]; $.get(url) .done(function () { deferred.resolve([url, extension]); }) .fail(function () { throw new Error('Whoops, invalid video! Please ensure the URL is right\nVideo URL: ' + url); }); return deferred.promise(); } }; $(embedHeroVid.init); // Logged-in body class injection var loggedinBodyClass = { init: function() { $('body').addClass(mw.config.get('wgUserName') == null ? 'not-logged-in' : 'logged-in'); } }; $(loggedinBodyClass.init); // Resize YouTube embed, turn HD on, etc, by User:WindPower var youtubeHelper = { chromeSize: 25, // This is the height (in pixels) of the chrome of YouTube's embedded video player. Update this whenever they release a new embedded video player maxWidth: 0.85, // Maximum fraction of the available width that the video may take infoboxes: ['.infobox', '.testchamber'], // Selectors of infobox-style boxes that should be deducted from the page's available width ratioR: /ratio-(\d+)x(\d+)/i, widthsR: /widths((?:\D+\d+)+)/i, setSize:function() { var widths = youtubeHelper.widthsR.exec($(this).attr('class')); if(widths != null) { widths = widths[1].substr(1).split(/\D+/g); var availableWidth = $('#bodyContent').width(); for(var i in youtubeHelper.infoboxes) { if($(youtubeHelper.infoboxes[i]).length) { availableWidth -= $(youtubeHelper.infoboxes[i]).width(); } } availableWidth *= youtubeHelper.maxWidth; var intWidths = []; for(var w = 0; w < widths.length; w++) { intWidths[w] = parseInt(widths[w]); } intWidths.sort(function(a, b){return b - a;}); for(var w = 0; w < intWidths.length; w++) { if(intWidths[w] <= availableWidth || w == intWidths.length-1) { youtubeHelper.setWidth(this, intWidths[w]); break; } } } else { youtubeHelper.setWidth(this, parseFloat(obj.attr('width'))); } }, setUrl:function() { var obj = $(this).children('object'); if(!obj.length) return; obj.append($('<param name="allowscriptaccess" value="true"></param>')); obj.append($('<param name="allowfullscreen" value="true"></param>')); var titleParts = mw.config.get('wgPageName').split(/\//g); var lang = 'en'; if(titleParts.length == 2 && !mw.config.get('wgCanonicalSpecialPageName')) { lang = titleParts[titleParts.length-1]; } var playerUrl = obj.children('param[name="movie"]').attr('value') + '&version=2&fs=1&theme=dark&color=white' + ($(this).hasClass('hd-on') ? '&hd=1' : '') + '&cc_load_policy=1&modestbranding=1&hl=' + lang + '&cc_lang_pref=' + lang; obj.children('param[name="movie"]').attr('value', playerUrl); obj.children('embed').attr('src', playerUrl).attr('allowscriptaccess', 'always').attr('allowfullscreen', 'true'); var resultHtml = $(this).html(); $(this).html('').html(resultHtml); }, setWidth:function(youtube, width) { var obj = $(youtube).children('object'); if(!obj) return; if($(youtube).hasClass('youtube-audio')) { obj.attr('width', width).attr('height', youtubeHelper.chromeSize); // Set <object> height obj.children('embed').attr('width', width).attr('height', youtubeHelper.chromeSize); // Set <embed> height } else { var ratio = youtubeHelper.ratioR.exec($(youtube).attr('class')); if(ratio != null) { ratio = parseFloat(ratio[1])/parseFloat(ratio[2]); var newHeight = Math.round(width / ratio + youtubeHelper.chromeSize).toString(); obj.attr('width', width).attr('height', newHeight); // Set <object> height obj.children('embed').attr('width', width).attr('height', newHeight); // Set <embed> height } } }, resizeTimer:null, resize:function() { if(youtubeHelper.resizeTimer != null) { clearTimeout(youtubeHelper.resizeTimer); } youtubeHelper.resizeTimer = setTimeout(youtubeHelper.onResize, 100); }, onResize:function() { $('.youtubebox').each(youtubeHelper.setSize); }, init:function() { $('.youtubebox').each(youtubeHelper.setUrl); $(window).resize(youtubeHelper.resize); youtubeHelper.onResize(); } }; $(youtubeHelper.init); // Edittools loader copied from http://en.wikipedia.org/wiki/MediaWiki:Common.js/edit.js?oldid=407371785 // Only slightly modified by seb26 /** * Edittools javascript loader ************************************************ * * Description: Pulls in [[MediaWiki:Edittools.js]]. Includes a cache-bypassing * version number in the URL in order to allow any changes to the edittools to * be rapidly deployed to users. * * Note that, by default, this function does nothing unless the element with * the ID "editpage-specialchars" (which contains the old edittools code in * [[MediaWiki:Edittools]], and will be retained as a placeholder in the new * implementation) has a class named "edittools-version-NNN", where NNN is a * number. If the class name has "test" before the number, the code will only * run for users who have set "window.testJsEdittools = true" in their user JS. * The "test" should be retained in the class name until the new edittools * implementation is ready and fully tested, and until at least 30 days have * passed since this loader stub was added (which will be in 27 June 2008). * * For compatibility with Alex Smotrov's original implementation, on which this * code is loosely based (see [[mw:User talk:Alex Smotrov/edittools.js]]), this * loader can also be disabled by setting "window.noDefaultEdittools = true". * * Maintainers: [[User:Ilmari Karonen]] */ if (['edit', 'submit'].indexOf(mw.config.get('wgAction')) !== -1 || mw.config.get('wgPageName') == "Special:Upload") //scripts specific to editing pages { // Prevent the static edittools from flashing before the compact edittools below is loaded. mw.util.addCSS('div.edittools-text { display:none; }'); $(function () { // needs to be deferred until the DOM has fully loaded var placeholder = document.getElementById("editpage-specialchars"); if (!placeholder || window.noDefaultEdittools) { //Show the static edittools again for users with "window.noDefaultEdittools=true". mw.util.addCSS('div.edittools-text { display:block; }'); return; } var match = /(?:^| )edittools-version-(\d+)(?: |$)/.exec(placeholder.className); // set window.testJsEdittools = true to enable testing before full deployment if (!match && window.testJsEdittools) match = /(?:^| )edittools-version-(test\d+)(?: |$)/.exec(placeholder.className); if (!match) return; var url = mw.config.get('wgScript') + '?title=MediaWiki:Edittools.js&action=raw&ctype=text/javascript&nocache=' + match[1]; mw.loader.load(url); }); } /********* MediaWiki:Valve.js *********/ function talkpageplus() { var talkpagelink = document.getElementById('ca-talk'); if (talkpagelink && talkpagelink.className == 'new') { talkpagelink.firstChild.href += '§ion=new'; } } $(talkpageplus); // Konami code easter egg by WindPower, modified by Wookipan // Constants: var spaiConstants = {}; // Editable constants: // General info: spaiConstants.spaiEnabled = true; spaiConstants.spaiImage = '/w/images/7/73/Team_Fortress_Wiki_Egg_Spy.png'; spaiConstants.spaiHeight = 196; spaiConstants.sapperClass = '--sapped'; spaiConstants.spaiSappingMahWikiWav = '/w/images/4/4a/Team_Fortress_Wiki_Egg.wav'; spaiConstants.timeStep = 40; // In milliseconds; 40 ms => 25 fps // Animation timing (all times in milliseconds): spaiConstants.anim_spaiFallDown = 2000; // Time for Spy to fall down spaiConstants.anim_spaiWait = 900; // Time Spy waits before going back up spaiConstants.anim_spaiBackUp = 2000; // Time for Spy to go back up spaiConstants.anim_sapperDestroyed = 2250; // Time until Sapper gets destroyed // End editable constants spaiConstants.theBody = function(){return document.getElementById('content');}; spaiConstants.preloadedImages = []; spaiConstants.preloadingImages = []; spaiConstants.preloadingRefs = {}; spaiConstants.toPreloadImage = spaiConstants.spaiImage; spaiConstants.self = null; spaiConstants.loadedSound = false; spaiConstants.loadedImages = false; spaiConstants.fired = false; // End constants if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (obj, fromIndex) { if (fromIndex == null) { fromIndex = 0; } else if (fromIndex < 0) { fromIndex = Math.max(0, this.length + fromIndex); } for (var i = fromIndex, j = this.length; i < j; i++) { if (this[i] === obj) return i; } return -1; }; } var spaiSappinMahWiki = { constants: spaiConstants, createImgDiv:function(image) { var self = spaiConstants.self; var div = document.createElement('div'); var img = document.createElement('img'); img.src = image; div.appendChild(img); setTimeout(function(){spaiConstants.theBody().appendChild(div);}, 1); return { 'div': div, 'img': img }; }, imagesLoaded:function() { spaiConstants.loadedImages = true; if(spaiConstants.loadedSound) { spaiConstants.self.spySappingMahWiki(); } }, soundLoaded:function() { spaiConstants.loadedSound = true; if(spaiConstants.loadedImages) { spaiConstants.self.spySappingMahWiki(); } }, preloadSound:function(sound, callback) { var self = spaiConstants.self; try { var audio = document.createElement('audio'); audio.setAttribute('src', sound); audio.setAttribute('style', 'display: none;'); audio.setAttribute('preload', 'true'); spaiConstants.theBody().appendChild(audio); audio.addEventListener('canplaythrough', callback, false); } catch(e) {} setTimeout(callback, 1000); // Fallback }, preloadImage:function(image) { var self = spaiConstants.self; if(spaiConstants.preloadingImages.indexOf(image) == -1) { spaiConstants.preloadingImages[spaiConstants.preloadingImages.length] = image; var nodes = self.createImgDiv(image); spaiConstants.preloadingRefs[image] = nodes['img']; nodes['div'].setAttribute('style', 'visibility: hidden; height: 0px; width: 0px; overflow: hidden; z-index: -10000;'); } if(spaiConstants.preloadingRefs[image].width) { spaiConstants.preloadedImages[spaiConstants.preloadedImages.length] = image; } else { setTimeout(function(){self.preloadImage(image);}, spaiConstants.timeStep); } }, preloadImages:function(callback) { var self = spaiConstants.self; var allPreloaded = true; for(var i in spaiConstants.toPreloadImages) { if(spaiConstants.preloadedImages.indexOf(spaiConstants.toPreloadImages[i]) == -1) { allPreloaded = false; } if(spaiConstants.preloadingImages.indexOf(spaiConstants.toPreloadImages[i]) == -1) { self.preloadImage(spaiConstants.toPreloadImages[i]); } } if(allPreloaded) { callback(); } else { setTimeout(function(){self.preloadImages(callback);}, spaiConstants.timeStep); } }, destroyNode:function(node) { try { node.parentNode.removeChild(node); } catch(e) { // Ze goggles, zey do nothin } }, smoothInOut:function(progress) { return (Math.sin((progress-.5)*Math.PI)+1)/2; }, inAnimation:function(func, progressTime, totalTime, callback, easing) { var self = spaiConstants.self; func(easing(progressTime / totalTime)); if(progressTime >= totalTime) { callback(); } else { setTimeout(function(){self.inAnimation(func, progressTime + spaiConstants.timeStep, totalTime, callback, easing);}, spaiConstants.timeStep); } }, animate:function(func, totalTime, callback, easing) { var self = spaiConstants.self; return self.inAnimation(func, 0.0, totalTime, callback, easing); }, playSound:function(sound) { var self = spaiConstants.self; try { var audio = document.createElement('audio'); audio.setAttribute('src', sound); audio.setAttribute('style', 'display: none;'); audio.setAttribute('autoplay', 'true'); spaiConstants.theBody().appendChild(audio); } catch(e) {} }, spyAnimationFinished:function(nodes) { var self = spaiConstants.self; for(var node in nodes) { self.destroyNode(nodes[node]); } spaiConstants.fired = false; }, spySappingMahWiki:function() { var self = spaiConstants.self; if(spaiConstants.fired) return; spaiConstants.fired = true; var spai = document.createElement('a'); spai.setAttribute('href', '/'); spai.setAttribute('style', 'display:block; position: absolute; top: 0px; left: 0px; width: 160px; height: 200px; border: 0px; background: url('+spaiConstants.spaiImage+') no-repeat 0px -50000px; z-index: 10000;'); spaiConstants.theBody().appendChild(spai); var logoPortlet = document.getElementById('p-logo'); var changeHeight = function(progress) { progress = parseInt(progress * spaiConstants.spaiHeight); spai.style.backgroundPosition = '0px ' + (-spaiConstants.spaiHeight + progress).toString() + 'px'; }; self.animate(changeHeight, spaiConstants.anim_spaiFallDown, function(){ self.playSound(spaiConstants.spaiSappingMahWikiWav); setTimeout(function(){ logoPortlet.classList.add('wiki-logo' + spaiConstants.sapperClass); self.animate(function(progress){changeHeight(1.0-progress);}, spaiConstants.anim_spaiBackUp, function(){ setTimeout(function(){ logoPortlet.removeAttribute('class'); self.spyAnimationFinished([spai]); }, spaiConstants.anim_sapperDestroyed); }, self.smoothInOut); }, spaiConstants.anim_spaiWait); }, self.smoothInOut); }, hitItDoc:function() { var self = spaiConstants.self; self.preloadImages(self.imagesLoaded); self.preloadSound(spaiConstants.spaiSappingMahWikiWav, self.soundLoaded); }, initKonami: function () { var self = spaiConstants.self; /* * Konami-JS ~ * :: Now with support for touch events and multiple instances for * :: those situations that call for multiple easter eggs! * Code: https://github.com/georgemandis/konami-js * Copyright (c) 2009 George Mandis (https://george.mand.is) * Version: 1.6.3 (11/11/2021) * Licensed under the MIT License (http://opensource.org/licenses/MIT) * Tested in: Safari 4+, Google Chrome 4+, Firefox 3+, IE7+, Mobile Safari 2.2.1+ and Android */ var Konami = function (callback) { var konami = { addEvent: function (obj, type, fn, ref_obj) { if (obj.addEventListener) obj.addEventListener(type, fn, false); else if (obj.attachEvent) { // IE obj["e" + type + fn] = fn; obj[type + fn] = function () { obj["e" + type + fn](window.event, ref_obj); } obj.attachEvent("on" + type, obj[type + fn]); } }, removeEvent: function (obj, eventName, eventCallback) { if (obj.removeEventListener) { obj.removeEventListener(eventName, eventCallback); } else if (obj.attachEvent) { obj.detachEvent(eventName); } }, input: "", pattern: "38384040373937396665", keydownHandler: function (e, ref_obj) { if (ref_obj) { konami = ref_obj; } // IE konami.input += e ? e.keyCode : event.keyCode; if (konami.input.length > konami.pattern.length) { konami.input = konami.input.substr((konami.input.length - konami.pattern.length)); } if (konami.input === konami.pattern) { konami.code(konami._currentLink); konami.input = ''; e.preventDefault(); return false; } }, load: function (link) { this._currentLink = link; this.addEvent(document, "keydown", this.keydownHandler, this); this.iphone.load(link); }, unload: function () { this.removeEvent(document, 'keydown', this.keydownHandler); this.iphone.unload(); }, code: function (link) { window.location = link }, iphone: { start_x: 0, start_y: 0, stop_x: 0, stop_y: 0, tap: false, capture: false, orig_keys: "", keys: ["UP", "UP", "DOWN", "DOWN", "LEFT", "RIGHT", "LEFT", "RIGHT", "TAP", "TAP"], input: [], code: function (link) { konami.code(link); }, touchmoveHandler: function (e) { if (e.touches.length === 1 && konami.iphone.capture === true) { var touch = e.touches[0]; konami.iphone.stop_x = touch.pageX; konami.iphone.stop_y = touch.pageY; konami.iphone.tap = false; konami.iphone.capture = false; konami.iphone.check_direction(); } }, touchendHandler: function () { konami.iphone.input.push(konami.iphone.check_direction()); if (konami.iphone.input.length > konami.iphone.keys.length) konami.iphone.input.shift(); if (konami.iphone.input.length === konami.iphone.keys.length) { var match = true; for (var i = 0; i < konami.iphone.keys.length; i++) { if (konami.iphone.input[i] !== konami.iphone.keys[i]) { match = false; } } if (match) { konami.iphone.code(konami._currentLink); } } }, touchstartHandler: function (e) { konami.iphone.start_x = e.changedTouches[0].pageX; konami.iphone.start_y = e.changedTouches[0].pageY; konami.iphone.tap = true; konami.iphone.capture = true; }, load: function (link) { this.orig_keys = this.keys; konami.addEvent(document, "touchmove", this.touchmoveHandler); konami.addEvent(document, "touchend", this.touchendHandler, false); konami.addEvent(document, "touchstart", this.touchstartHandler); }, unload: function () { konami.removeEvent(document, 'touchmove', this.touchmoveHandler); konami.removeEvent(document, 'touchend', this.touchendHandler); konami.removeEvent(document, 'touchstart', this.touchstartHandler); }, check_direction: function () { x_magnitude = Math.abs(this.start_x - this.stop_x); y_magnitude = Math.abs(this.start_y - this.stop_y); x = ((this.start_x - this.stop_x) < 0) ? "RIGHT" : "LEFT"; y = ((this.start_y - this.stop_y) < 0) ? "DOWN" : "UP"; result = (x_magnitude > y_magnitude) ? x : y; result = (this.tap === true) ? "TAP" : result; return result; } } } typeof callback === "string" && konami.load(callback); if (typeof callback === "function") { konami.code = callback; konami.load(); } return konami; }; // End of Konami-JS var konami = new Konami(); konami.code = function() { if (spaiConstants.spaiEnabled) { self.hitItDoc.apply(self); } document.dispatchEvent(new CustomEvent('konami:fire')); }; konami.load(); } }; spaiConstants.self = spaiSappinMahWiki; $(spaiSappinMahWiki.initKonami); // Dynamic background by WindPower // WindPower is secksy and makes this wiki awesome with his very breath. (- Smashman) var dynamicBg = { categories: { // Format: // 'CategoryName': 'URL of background image', ---OR--- 'title-PageTitle': 'URL of background image', // Categories don't have to be class names, they can be things like "Weapons", "Featured articles", "Maps", "Help", etc. 'Scout': '/w/images/e/ea/Background_Scout_vector.png', 'Soldier': '/w/images/5/54/Background_Soldier_vector.png', 'Pyro': '/w/images/e/ed/Background_Pyro_vector.png', 'Demoman': '/w/images/5/59/Background_Demoman_vector.png', 'Engineer': '/w/images/f/f7/Background_Engineer_vector.png', 'Heavy': '/w/images/0/03/Background_Heavy_vector.png', 'Medic': '/w/images/2/24/Background_Medic_vector.png', 'Sniper': '/w/images/e/ed/Background_Sniper_vector.png', 'Spy': '/w/images/b/b9/Background_Spy_vector.png' // (No comma at the end of the last line) }, getCategories:function() { var catlinksnode = document.getElementById('catlinks'); if(!catlinksnode) return []; var catlinks = document.getElementById('catlinks').getElementsByTagName('a'); var cats = []; var l; for(var i = 0; i < catlinks.length; i++) { l = catlinks[i].getAttribute('title'); if(l.match(/^Category:/i, '')) { cats[cats.length] = l.substr(9).replace(/\/[^/]+$/, ''); } } return cats; }, inArray:function(haystack, needle) { for(var i = 0; i < haystack.length; i++) { if(haystack[i] == needle) { return i; } } return -1; }, init:function() { if(typeof(wPrefs) != 'undefined') { if(dynamicBg.inArray(wPrefs, 'noDynamicBackground') != -1) { return; // Script disabled } } try { var cats = dynamicBg.getCategories(); var body = document.getElementsByTagName('body')[0]; } catch(e) { return; } var selectedCats = []; if(typeof(dynamicBg.categories['title-' + mw.config.get('wgTitle')]) != 'undefined') { selectedCats[0] = dynamicBg.categories['title-' + mw.config.get('wgTitle')]; } else { for(var i in dynamicBg.categories) { if(dynamicBg.inArray(cats, i) != -1) { selectedCats[selectedCats.length] = dynamicBg.categories[i]; } } } if(!selectedCats.length) return; // No match, keep default style var selectedCat = selectedCats[Math.floor(Math.random()*selectedCats.length)]; body.style.backgroundImage='url('+selectedCat+')'; } }; $(dynamicBg.init); // Page-specific JavaScript/CSS var pageScripts = { pagesJS: ["Main_Page", "Team_Fortress_Wiki:April_Fools'_Day/2021/Main_Page", "User:Lexar/Main_Page/Template:Benjas", "User:Lexar/sandbox", "User:MogDog66", "User:Tark", "User:Tark/Sandbox", "User:WindPower", "User:WindPower/Main_Page", "User:Wookipan/Sandbox"], pagesCSS: ["Main_Page", "Team_Fortress_Wiki:April_Fools'_Day/2019/Main_Page", "Team_Fortress_Wiki:April_Fools'_Day/2021/Main_Page", "User:Ashe", "User:Ath", "User:Boba", "User:Carez", "User:CrushBOT", "User:Dan_greene", "User:Esky", "User:FanCyy", "User:Foxbite", "User:FreeXMan", "User:GrampaSwood", "User:Hagbard Celine", "User:Jestie", "User:Lagg", "User:Lexar", "User:Lexar/Main_Page/Template:Benjas", "User:Lexar/sandbox", "User:Mediarch", "User:MogDog66", "User:MogDog66/MPR", "User:MogDog66/Sandbox", "User:MogDog66/userpagev2", "User:Moussekateer/3DViewer", "User:NVis", "User:NVis/Sandbox", "User:Nixshadow", "User:Obilisk", "User:PhoneWave", "User:Pilk", "User:Pilk/armory", "User:T-Wayne", "User:Tark", "User:Tark/Sandbox", "User:WindPower", "User:WindPower/Main_Page", "User:Wookipan", "User:Wookipan/Sandbox"], suffixJS: '/Page.js', suffixCSS: '/Page.css', init: function() { for(var i in pageScripts.pagesJS) { if(mw.config.get('wgPageName') == pageScripts.pagesJS[i]) { mw.loader.load(mw.config.get('wgScript') + '?title=' + encodeURIComponent(mw.config.get('wgPageName') + pageScripts.suffixJS) + '&ctype=text/javascript&action=raw'); } } for(var i in pageScripts.pagesCSS) { if(mw.config.get('wgPageName') == pageScripts.pagesCSS[i]) { mw.loader.load(mw.config.get('wgScript') + '?title=' + encodeURIComponent(mw.config.get('wgPageName') + pageScripts.suffixCSS) + '&ctype=text/css&action=raw', 'text/css'); } } } }; $(pageScripts.init); // Fancy diffs var fancyDiffs = { isBigDiff: false, isBigDiffThreshold: 72, toggle: function(element) { var expanded = element.hasClass('diff-expanded'); var contents = element.parent().children('.diff-contents'); if(expanded) { // Just collapse then element.removeClass('diff-expanded'); if(fancyDiffs.isBigDiff) { contents.hide(); } else { contents.slideUp('fast'); } } else if(element.hasClass('diff-data-loaded')) { // Stuff is already loaded, expand element.addClass('diff-expanded'); contents.slideDown('fast'); } else if(!element.hasClass('diff-data-requested')) { // Stuff is not loaded element.addClass('diff-data-requested'); var fileName = element.find('span').text().replace(/^\s+|\s+$/g); var patchName = element.closest('.diffname'); var diffName = mw.config.get('wgPageName'); if(patchName && patchName.length && patchName.attr('class')) { diffName = patchName.attr('class').substr(9); } $.get('/w/?title=Template:PatchDiff/' + encodeURIComponent(diffName.replace(/^Template:PatchDiff\//, '')) + '/' + encodeURIComponent(fileName) + '&action=raw', function(data) { contents.html(data); if(fancyDiffs.isBigDiff) { contents.show(); } else { contents.slideDown('fast'); } element.removeClass('diff-data-requested').addClass('diff-data-loaded').addClass('diff-expanded'); }); } }, init: function() { var diffText = $('.diff-name-text'); if(diffText.length) { // Preload leetle gif $('body').append($('<img/>').attr('src', '/w/images/4/43/Patch_diff_loading.gif').css('display', 'none')); diffText.find('span').each(function() { $(this).text($(this).find('a').text().replace(/^\s+|\s+$/g)); }); diffText.click(function() { fancyDiffs.toggle($(this)); return false; }); fancyDiffs.isBigDiff = $('.diff-file').length > fancyDiffs.isBigDiffThreshold; } } }; $(fancyDiffs.init); // 3D/2D viewer $('#switch-to-3d').click(function() { $('.container-2d').hide(); $('.viewer-3d, .viewer-3d-multi, .buttons-container-3d').show(); }); $('#switch-to-2d').click(function() { $('.viewer-3d, .viewer-3d-multi, .buttons-container-3d').hide(); $('.container-2d').show(); }); // 3D model viewer var viewer3d = { dragging: null, draggingFrameX: 0, draggingFrameY: 0, viewers: [], frameThresholdX: 10, frameThresholdY: 128, realMod: function(x, y) { return ((x % y) + y) % y; }, init: function() { $('.viewer-3d').each(viewer3d.bind); $(document).mouseup(viewer3d.release); $(document).mousemove(viewer3d.move); }, bind: function() { var v = $(this); var num = viewer3d.viewers.length; var allModels = []; var modelID = 0; var viewerSize = 0; while(true) { var modelMap = v.find('.viewer-3d-map-' + modelID); var urlNode = v.find('.viewer-3d-url-' + modelID); if(!modelMap.length || !urlNode.length) break; var url = $('<div/>').html(urlNode.text()).text(); var framesS = $('<div/>').html(modelMap.text()).text().replace(/^\s+|\s+$/g).split(/,/g); var frameMap = []; var heightMap = []; var leftCropMap = []; var totalW = parseInt(framesS[0]); var maxFrameW = parseInt(framesS[1]); var totalH = parseInt(framesS[2]); var verticalSteps = parseInt(framesS[3]); var midVertical = Math.floor(verticalSteps / 2); for(var f = 4; f < framesS.length; f += 3) { frameMap.push(parseInt(framesS[f])); heightMap.push(parseInt(framesS[f + 1])); leftCropMap.push(parseInt(framesS[f + 2])); } allModels.push({ imageURL: url, map: frameMap, cropMap: leftCropMap, totalWidth: totalW, totalHeight: totalH, maxFrameWidth: maxFrameW, xStep: verticalSteps }); viewerSize = Math.max(viewerSize, totalH, maxFrameW); modelID++; } if(!modelID) return; var overlayNode = $('<div class="viewer-3d-overlay"></div>'); var frameN = v.find('.viewer-3d-frame'); v.find('img').detach(); var klasses = v.attr('class').split(/ /g); var startFrame = 0; for(var k in klasses) { if(klasses[k].substr(0, 11) == 'startframe-') { startFrame = Math.max(0, parseInt(klasses[k].substr(11))); } } var viewer = { node: v, frameX: startFrame, frameY: midVertical, models: allModels, currentModel: -1, frameNode: frameN, width: viewerSize, height: viewerSize, mouseX: 0, mouseY: 0, overlay: overlayNode }; viewer3d.viewers.push(viewer); v.hover(viewer3d.hover, viewer3d.unhover).mousedown(viewer3d.drag).append(overlayNode).attr('data-id', num).css({ width: viewer.width + 'px', height: viewer.height + 'px' }); frameN.mousedown(viewer3d.drag).attr('data-id', num).css('height', viewer.height + 'px'); viewer3d.changeVersion(viewer, 0); }, getCurrentModel: function(v) { return v.models[v.currentModel]; }, changeVersion: function(v, version) { version = Math.max(0, Math.min(v.models.length - 1, version)); if(v.currentModel == version) return; v.currentModel = version; v.frameNode.css('background', 'url(' + viewer3d.getCurrentModel(v).imageURL + ') top left no-repeat'); viewer3d.display(v, v.frameX, v.frameY); }, hover: function(e) { var v = viewer3d.getViewer(this); if(viewer3d.dragging != v) { v.overlay.animate({'opacity': '1'}, 'fast'); } }, unhover: function(e) { var v = viewer3d.getViewer(this); if(viewer3d.dragging != v) { v.overlay.animate({'opacity': '0.5'}, 'fast'); } }, drag: function(e) { var v = viewer3d.getViewer(this); v.mouseX = e.pageX; v.mouseY = e.pageY; viewer3d.dragging = v; draggingFrameX = v.frameX; draggingFrameY = v.frameY; return false; }, release: function() { var v = viewer3d.dragging; viewer3d.dragging = null; if(v != null) { v.frameX = viewer3d.draggingFrameX; v.frameY = viewer3d.draggingFrameY; v.overlay.animate({'opacity': '0.5'}, 'fast'); } viewer3d.draggingFrameX = 0; viewer3d.draggingFrameY = 0; }, getViewer: function(node) { return viewer3d.viewers[parseInt($(node).attr('data-id'))]; }, display: function(v, frameX, frameY) { var model = viewer3d.getCurrentModel(v); var frameID = viewer3d.realMod(frameX * model.xStep + frameY, model.map.length); var frameOffset = model.map[frameID]; var frameWidth = 0; if(frameID == model.map.length - 1) { frameWidth = model.totalWidth - frameOffset; } else { frameWidth = model.map[frameID + 1] - frameOffset; } v.frameNode.css({ backgroundPosition: (-frameOffset - frameID) + 'px 0px', left: Math.round((v.width - model.maxFrameWidth) / 2.0 + model.cropMap[frameID]) + 'px', top: Math.round((v.height - model.totalHeight) / 2) + 'px', width: frameWidth + 'px', height: model.totalHeight + 'px' }); }, move: function(e) { if(viewer3d.dragging == null) { return; } var v = viewer3d.dragging; var model = viewer3d.getCurrentModel(v); var mouseDeltaX = e.pageX - v.mouseX; var mouseDeltaY = e.pageY - v.mouseY; var frameDeltaX = Math.round(mouseDeltaX / viewer3d.frameThresholdX); var frameDeltaY = -Math.round(mouseDeltaY / viewer3d.frameThresholdY); viewer3d.draggingFrameX = v.frameX + frameDeltaX; viewer3d.draggingFrameY = Math.max(0, Math.min(model.xStep - 1, v.frameY + frameDeltaY)); viewer3d.display(v, viewer3d.draggingFrameX, viewer3d.draggingFrameY); } }; $(viewer3d.init); var selector3d = { bind: function() { var viewer = viewer3d.getViewer($(this).find('.viewer-3d')); var keepGoing = true; var modelVariant = 0; var selector; while(keepGoing) { selector = $(this).find('.selector-' + modelVariant); if(selector.length) { selector.attr('data-variant', modelVariant).click(function() { viewer3d.changeVersion(viewer, parseInt($(this).attr('data-variant'))); return false; }); } modelVariant++; keepGoing = selector.length; } }, init: function() { $('.viewer-3d-multi, .viewer-3d-container').each(selector3d.bind); } }; $(selector3d.init); // Code to get 3D viewer drag working on touch devices // Source: http://www.jquery4u.com/mobile/jquery-add-dragtouch-support-ipad/ $.fn.addTouch = function(){ this.each(function(i,el){ $(el).bind('touchstart touchmove touchend touchcancel',function(){ //we pass the original event object because the jQuery event //object is normalized to w3c specs and does not provide the TouchList handleTouch(event); }); }); var handleTouch = function(event) { var touches = event.changedTouches, first = touches[0], type = ''; switch(event.type) { case 'touchstart': type = 'mousedown'; break; case 'touchmove': type = 'mousemove'; event.preventDefault(); break; case 'touchend': type = 'mouseup'; break; default: return; } var simulatedEvent = document.createEvent('MouseEvent'); simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null); first.target.dispatchEvent(simulatedEvent); }; }; $('.viewer-3d').addTouch(); // End 3D viewer touch device code // Start weapon wear table tabs ----- var WeaponWearTable = { tabSwitch: function($this,tab,weapons,weapon) { if (!$this.hasClass('current')) { var tabIndex = $this.index(); $this.parent().find('.current').removeClass('current'); $this.addClass('current'); weapons.find('.current').removeClass('current'); weapon.eq(tabIndex).addClass('current'); } }, init: function() { $('.weapon-wear-table').each(function(){ var $this = $(this), tabs = $this.children('.tabs'), tab = tabs.children('li'), weapons = $this.children('.weapons'), weapon = weapons.children('li'); tab.click(function(){ WeaponWearTable.tabSwitch($(this),tab,weapons,weapon); }); }); } }; $(WeaponWearTable.init); // End weapon wear table tabs ----- // Start Bilibili iframe support ----- var Bilibili = { init: function() { var $videos = $('.bilibili-video'); $videos.each(function() { var $this = $(this); var aid = parseInt($this.data('vaid')); var danmaku = parseInt($this.data('vdanmaku')); var page = parseInt($this.data('vpage')); var width = $this.data('vwidth'); var height = $this.data('vheight'); var iframeSrc = 'https://www.bilibili.com/blackboard/html5mobileplayer.html?aid=' + aid + '&high_quality=1&danmaku=' + danmaku + '&page=' + page + '&hideCoverInfo=1&hideDanmakuButton=1'; var iframe = '<iframe src="' + iframeSrc + '" width="' + width + '" height="' + height + '" frameborder="0" allowfullscreen="true"></iframe>'; $this.append(iframe); }); } }; $(Bilibili.init); // End Bilibili iframe support ----- // Start custom username highlighting ----- var uGroupHighlight = { init: function() { if ($('.mw-userlink')[0]) { var params = { action: 'query', list: 'allusers', augroup: ['sysop', 'moderator', 'bot'], auprop: 'groups', aulimit: 100, format: 'json' }; var api = new mw.Api(); api.get(params).done(function(data) { var uGroups = data.query.allusers, user; for (user in uGroups) { var name = uGroups[user].name; var group = uGroups[user].groups; $('bdi').each(function() { if ($(this).text().match('\\b' + name + '\\b')) { $(this).closest('.mw-userlink').addClass(group.includes('bot') ? 'bot' : 'staff'); } }); } }); } }, }; $(uGroupHighlight.init); // End custom username highlighting ----- // Start login icon randomizer ----- var iconRandomizer = { init: function() { var classes = [ '/w/images/3/33/Login_Scout.png', '/w/images/d/d8/Login_Soldier.png', '/w/images/7/71/Login_Pyro.png', '/w/images/5/53/Login_Demoman.png', '/w/images/3/35/Login_Heavy.png', '/w/images/a/ab/Login_Engineer.png', '/w/images/d/d4/Login_Medic.png', '/w/images/e/e4/Login_Sniper.png', '/w/images/2/27/Login_Spy.png' ]; // pick a random class image out of nine choices pickClass = classes[Math.floor(Math.random() * classes.length)]; // ensure all relative elements are hit var nodes = $('#pt-userpage, #pt-anonuserpage, #pt-login'); if (nodes.length) { for (var i = 0; i < nodes.length; i++) { nodes.css('background-image', 'url(' + pickClass + ')'); } } } }; $(iconRandomizer.init); // End login icon randomizer ----- // Start 'Audio player' var audioPlayer = { currentAudio: null, init: function () { var audioPauseImg = new Image(); var audioPlayImg = new Image(); audioPauseImg.src = '/w/images/d/d2/Pause_icon.png'; audioPlayImg.src = '/w/images/6/67/Play_icon.png'; $('.tfwiki-audio-player').each(function () { var audioPlayerElement = $(this); var audioLink = audioPlayerElement.children('a'); var audioURL = audioLink.attr('href'); var audio = null; var audioStatus = audioPlayerElement.find('.tfwiki-audio-player-action'); audioStatus.removeClass('inactive'); audioPlayerElement.on('click', function (e) { if (e.target !== audioStatus[0]) { return; } e.preventDefault(); if (!audio) { audio = new Audio(audioURL); audio.volume = 0.5; audio.addEventListener('ended', function () { audioStatus.text(audioStatus.data('text-play')); audioStatus.removeClass('playing'); }); } if (audioPlayer.currentAudio && audioPlayer.currentAudio !== audio) { audioPlayer.currentAudio.pause(); audioPlayer.currentAudio.currentTime = 0; audioPlayer.currentAudioStatus.text(audioPlayer.currentAudioStatus.data('text-play')); audioPlayer.currentAudioStatus.removeClass('playing'); } if (audio.paused) { audio.play(); audioStatus.text(audioStatus.data('text-pause')); audioPlayer.currentAudio = audio; audioPlayer.currentAudioStatus = audioStatus; audioStatus.addClass('playing'); } else { audio.pause(); audioStatus.text(audioStatus.data('text-resume')); audioPlayer.currentAudio = null; audioPlayer.currentAudioStatus = null; audioStatus.removeClass('playing'); } }); audioLink.on('click', function (e) { e.preventDefault(); window.open(audioURL, '_blank'); }); }); } }; $(audioPlayer.init); // End 'Audio player' /* Google Analytics */ var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-18260470-1']); _gaq.push(['_setDomainName', '.teamfortress.com']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); /* GoSquared analytics */ var GoSquared = {}; GoSquared.acct = "GSN-106863-S"; (function(w){ function gs(){ w._gstc_lt = +new Date; var d = document, g = d.createElement("script"); g.type = "text/javascript"; g.src = "//d1l6p2sc9645hc.cloudfront.net/tracker.js"; var s = d.getElementsByTagName("script")[0]; s.parentNode.insertBefore(g, s); } w.addEventListener ? w.addEventListener("load", gs, false) : w.attachEvent("onload", gs); })(window);