Difference between revisions of "MediaWiki:Common.js"
(Created page with '→Any JavaScript here will be loaded for all users on every page load.: /** Collapsible tables ********************************************************* * * Description…') |
m (Enable custom CSS for User:Payn) |
||
(304 intermediate revisions by 13 users not shown) | |||
Line 1: | Line 1: | ||
− | / | + | // This is the non-compressed version of MediaWiki:Common.js |
+ | |||
+ | // External links open in new windows/tabs: | ||
+ | $('a.external').attr('target', '_blank'); | ||
/** Collapsible tables ********************************************************* | /** Collapsible tables ********************************************************* | ||
Line 14: | Line 17: | ||
})(); | })(); | ||
− | + | 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 ********************************************************* | //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); | ||
+ | |||
+ | // Custom tooltip component. See Template:Tooltip | ||
+ | var wikiTooltip = { | ||
+ | init: function() { | ||
+ | var $tooltips = $('.wiki-tooltip .wiki-tooltip-content'); | ||
+ | if ($tooltips[0]) { | ||
+ | $tooltips.each(function() { | ||
+ | var $this = $(this); | ||
+ | function handler() { | ||
+ | // Check for links and handle them on handheld devices | ||
+ | if (!!$this.closest('a').attr('href')) { | ||
+ | $this.closest('a').removeAttr('title'); | ||
+ | |||
+ | widthRect <= 1000 ? wikiTooltip.hasLink($this) : wikiTooltip.removeAnchor($this); | ||
+ | } | ||
+ | |||
+ | // Prevent tooltips from overflowing the viewport | ||
+ | var bounding = $this[0].getBoundingClientRect(); | ||
+ | edgeRect = { | ||
+ | left: Math.floor(($this.width() + bounding.left + 10)), | ||
+ | right: Math.floor(($this.width() + bounding.right + 10)) | ||
+ | }; | ||
+ | |||
+ | widthRect = $(window).innerWidth(); | ||
+ | if (edgeRect.left >= (widthRect || document.documentElement.clientWidth)) { | ||
+ | $this.css('left', ''); | ||
+ | $this.css('right', '50%'); | ||
+ | } else if (edgeRect.right <= (widthRect || document.documentElement.clientWidth)) { | ||
+ | $this.css('right', ''); | ||
+ | $this.css('left', '50%'); | ||
+ | } | ||
+ | } | ||
+ | $(handler); | ||
+ | setTimeout(function() { | ||
+ | $(window).on('resize', handler); | ||
+ | }, 250); | ||
+ | }); | ||
+ | } | ||
+ | }, | ||
+ | hasLink: function(tooltip) { | ||
+ | if (tooltip.find('a').length < 1) { | ||
+ | var $a = $('<a>'); | ||
+ | var url = tooltip.closest('a'); | ||
+ | var href = url.attr('href'); | ||
+ | |||
+ | $a.attr('href', href); | ||
+ | url.attr('href', 'javascript:void(0);'); | ||
+ | tooltip.append($a); | ||
+ | } | ||
+ | }, | ||
+ | removeAnchor: function(tooltip) { | ||
+ | var url = tooltip.closest('a'); | ||
+ | var href = url.attr('href'); | ||
+ | |||
+ | innerLink = tooltip.find('a').attr('href'); | ||
+ | if (innerLink) { | ||
+ | href = innerLink; | ||
+ | url.attr('href', href); | ||
+ | tooltip.find('a').remove(); | ||
+ | } else { | ||
+ | return; | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | $(wikiTooltip.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', 'User:WindPower', 'User:MogDog66', 'User:WindPower/Main_Page', 'User:Lexar/Main_Page/Template:Benjas', 'User:Lexar/RandomPage', 'User:Lexar/responsive_infobox', 'User:Lexar/sandbox', 'User:Tark', 'User:Tark/Sandbox', 'Team_Fortress_Wiki:April_Fools\'_Day/2021/Main_Page', 'User:PhoneWave', 'User:Wookipan/Sandbox'], | ||
+ | pagesCSS: ['Main_Page', 'User:WindPower', 'User:Pilk/armory', 'User:Pilk', 'User:Esky', 'User:Lagg', 'User:MogDog66', 'User:CrushBOT', 'User:MogDog66/userpagev2', 'User:NVis', 'User:NVis/Sandbox', 'User:Lexar', 'User:MogDog66/MPR', 'User:WindPower/Main_Page', 'User:Moussekateer/3DViewer', 'User:T-Wayne', 'User:FreeXMan', 'User:Nixshadow', 'User:Ath', 'User:Carez', 'User:Lexar/Main_Page/Template:Benjas', 'User:Lexar/RandomPage', 'User:MogDog66/Sandbox', 'User:Obilisk', 'User:Lexar/itembox_tooltip', 'User:Lexar/sandbox', 'User:Lexar/responsive_infobox', 'User:Hagbard Celine', 'User:Wookipan', 'User:Wookipan/Sandbox', 'User:GrampaSwood', 'Team_Fortress_Wiki:April_Fools\'_Day/2019/Main_Page', 'User:Tark', 'User:Tark/Sandbox', 'User:Boba', 'User:Boba/Projects', 'User:FanCyy', 'User:Dan_greene', 'User:Boba/Sandbox', 'User:Ashe', 'Team_Fortress_Wiki:April_Fools\'_Day/2021/Main_Page', 'User:PhoneWave', 'User:Foxbite', 'User:Mediarch', 'User:Payn'], | ||
+ | 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); |
Revision as of 03:59, 10 May 2024
// 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); // Custom tooltip component. See Template:Tooltip var wikiTooltip = { init: function() { var $tooltips = $('.wiki-tooltip .wiki-tooltip-content'); if ($tooltips[0]) { $tooltips.each(function() { var $this = $(this); function handler() { // Check for links and handle them on handheld devices if (!!$this.closest('a').attr('href')) { $this.closest('a').removeAttr('title'); widthRect <= 1000 ? wikiTooltip.hasLink($this) : wikiTooltip.removeAnchor($this); } // Prevent tooltips from overflowing the viewport var bounding = $this[0].getBoundingClientRect(); edgeRect = { left: Math.floor(($this.width() + bounding.left + 10)), right: Math.floor(($this.width() + bounding.right + 10)) }; widthRect = $(window).innerWidth(); if (edgeRect.left >= (widthRect || document.documentElement.clientWidth)) { $this.css('left', ''); $this.css('right', '50%'); } else if (edgeRect.right <= (widthRect || document.documentElement.clientWidth)) { $this.css('right', ''); $this.css('left', '50%'); } } $(handler); setTimeout(function() { $(window).on('resize', handler); }, 250); }); } }, hasLink: function(tooltip) { if (tooltip.find('a').length < 1) { var $a = $('<a>'); var url = tooltip.closest('a'); var href = url.attr('href'); $a.attr('href', href); url.attr('href', 'javascript:void(0);'); tooltip.append($a); } }, removeAnchor: function(tooltip) { var url = tooltip.closest('a'); var href = url.attr('href'); innerLink = tooltip.find('a').attr('href'); if (innerLink) { href = innerLink; url.attr('href', href); tooltip.find('a').remove(); } else { return; } } }; $(wikiTooltip.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', 'User:WindPower', 'User:MogDog66', 'User:WindPower/Main_Page', 'User:Lexar/Main_Page/Template:Benjas', 'User:Lexar/RandomPage', 'User:Lexar/responsive_infobox', 'User:Lexar/sandbox', 'User:Tark', 'User:Tark/Sandbox', 'Team_Fortress_Wiki:April_Fools\'_Day/2021/Main_Page', 'User:PhoneWave', 'User:Wookipan/Sandbox'], pagesCSS: ['Main_Page', 'User:WindPower', 'User:Pilk/armory', 'User:Pilk', 'User:Esky', 'User:Lagg', 'User:MogDog66', 'User:CrushBOT', 'User:MogDog66/userpagev2', 'User:NVis', 'User:NVis/Sandbox', 'User:Lexar', 'User:MogDog66/MPR', 'User:WindPower/Main_Page', 'User:Moussekateer/3DViewer', 'User:T-Wayne', 'User:FreeXMan', 'User:Nixshadow', 'User:Ath', 'User:Carez', 'User:Lexar/Main_Page/Template:Benjas', 'User:Lexar/RandomPage', 'User:MogDog66/Sandbox', 'User:Obilisk', 'User:Lexar/itembox_tooltip', 'User:Lexar/sandbox', 'User:Lexar/responsive_infobox', 'User:Hagbard Celine', 'User:Wookipan', 'User:Wookipan/Sandbox', 'User:GrampaSwood', 'Team_Fortress_Wiki:April_Fools\'_Day/2019/Main_Page', 'User:Tark', 'User:Tark/Sandbox', 'User:Boba', 'User:Boba/Projects', 'User:FanCyy', 'User:Dan_greene', 'User:Boba/Sandbox', 'User:Ashe', 'Team_Fortress_Wiki:April_Fools\'_Day/2021/Main_Page', 'User:PhoneWave', 'User:Foxbite', 'User:Mediarch', 'User:Payn'], 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);